Skip to content

Commit

Permalink
implementing order tracking and order managment issue
Browse files Browse the repository at this point in the history
implementing order tracking and order managment issue

implementing order tracking and order managment issue

implementing order tracking and order managment issue

adding documentation and tests

writing tests
  • Loading branch information
UwicyezaG authored and aimedivin committed May 28, 2024
1 parent 66c5d2c commit cdd388a
Show file tree
Hide file tree
Showing 72 changed files with 2,260 additions and 970 deletions.
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ env:
CLOUDINARY_API_SECRET: ${{secrets.CLOUDINARY_API_SECRET}}
GOOGLE_CLIENT_ID: ${{secrets.GOOGLE_CLIENT_ID}}
GOOGLE_CLIENT_SECRET: ${{secrets.GOOGLE_CLIENT_SECRET}}


jobs:
build-lint-test-coverage:
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"passport-google-oauth20": "^2.0.0",
"pg": "^8.11.5",
"reflect-metadata": "^0.2.2",
"socket.io": "^4.7.5",
"source-map-support": "^0.5.21",
"superagent": "^9.0.1",
"swagger-jsdoc": "^6.2.8",
Expand Down Expand Up @@ -78,6 +79,7 @@
"@types/nodemailer": "^6.4.15",
"@types/passport-google-oauth20": "^2.0.16",
"@types/reflect-metadata": "^0.1.0",
"@types/socket.io": "^3.0.2",
"@types/supertest": "^6.0.2",
"@types/uuid": "^9.0.8",
"@types/winston": "^2.4.4",
Expand Down
17 changes: 6 additions & 11 deletions src/__test__/cart.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import request from 'supertest';
import jwt from 'jsonwebtoken';
import { app, server } from '../index';
Expand Down Expand Up @@ -171,8 +170,9 @@ beforeAll(async () => {
});

afterAll(async () => {
await cleanDatabase()
await cleanDatabase();

server.close();
});

describe('Cart management for guest/buyer', () => {
Expand Down Expand Up @@ -524,12 +524,12 @@ describe('Order management tests', () => {
city: 'Test City',
street: 'Test Street',
},
}).set('Authorization', `Bearer ${getAccessToken(buyer1Id, sampleBuyer1.email)}`);
})
.set('Authorization', `Bearer ${getAccessToken(buyer1Id, sampleBuyer1.email)}`);
expect(response.status).toBe(400);
});

it('should create a new order', async () => {

const response = await request(app)
.post('/product/orders')
.send({
Expand All @@ -547,7 +547,6 @@ describe('Order management tests', () => {
});

it('should insert a new order', async () => {

const response = await request(app)
.post('/product/orders')
.send({
Expand All @@ -570,9 +569,8 @@ describe('Order management tests', () => {
const response = await request(app)
.get('/product/client/orders')
.set('Authorization', `Bearer ${getAccessToken(buyer2Id, sampleBuyer2.email)}`);
expect(response.status).toBe(404);
expect(response.status).toBe(404);
expect(response.body.message).toBeUndefined;

});

it('should return 404 if the buyer has no orders', async () => {
Expand All @@ -586,13 +584,11 @@ describe('Order management tests', () => {

describe('Get transaction history', () => {
it('should return transaction history for the buyer', async () => {

const response = await request(app)
.get('/product/orders/history')
.set('Authorization', `Bearer ${getAccessToken(buyer1Id, sampleBuyer1.email)}`);
expect(response.status).toBe(404);
expect(response.body.message).toBe('No transaction history found');

});

it('should return 400 when user ID is not provided', async () => {
Expand All @@ -605,12 +601,11 @@ describe('Order management tests', () => {

describe('Update order', () => {
it('should update order status successfully', async () => {

const response = await request(app)
.put(`/product/client/orders/${orderId}`)
.send({ orderStatus: 'delivered' })
.set('Authorization', `Bearer ${getAccessToken(buyer1Id, sampleBuyer1.email)}`);
expect(response.status).toBe(500);
expect(response.status).toBe(500);
});
});
});
80 changes: 41 additions & 39 deletions src/__test__/coupon.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const product2Id = uuid();
const couponCode = 'DISCOUNT20';
const couponCode1 = 'DISCOUNT10';
const couponCode2 = 'DISCOUNT99';
const couponCode3 = 'DISCOUNT22'
const couponCode3 = 'DISCOUNT22';
const expiredCouponCode = 'EXPIRED';
const finishedCouponCode = 'FINISHED';
const moneyCouponCode = 'MONEY';
Expand Down Expand Up @@ -199,11 +199,10 @@ beforeAll(async () => {

const cartItemRepository = connection?.getRepository(CartItem);
await cartItemRepository?.save({ ...sampleCartItem1 });

});

afterAll(async () => {
await cleanDatabase()
await cleanDatabase();

server.close();
});
Expand Down Expand Up @@ -340,84 +339,87 @@ describe('Coupon Management System', () => {
});

describe('Buyer Coupon Application', () => {
describe('Checking Coupon Conditions', () =>{
describe('Checking Coupon Conditions', () => {
it('should return 400 when no coupon submitted', async () => {
const response = await request(app)
.post(`/coupons/apply`)
.set('Authorization', `Bearer ${getAccessToken(buyer1Id, sampleBuyer1.email)}`);

expect(response.status).toBe(400);
expect(response.body.message).toBe('Coupon Code is required');
})
expect(response.status).toBe(400);
expect(response.body.message).toBe('Coupon Code is required');
});
it('should return 404 if coupon code is not found in the database', async () => {
const response = await request(app)
.post(`/coupons/apply`)
.set('Authorization', `Bearer ${getAccessToken(buyer1Id, sampleBuyer1.email)}`)
.send({
couponCode: "InvalidCode",
couponCode: 'InvalidCode',
});

expect(response.status).toBe(404);
expect(response.body.message).toBe('Invalid Coupon Code');
})
expect(response.status).toBe(404);
expect(response.body.message).toBe('Invalid Coupon Code');
});
it('should not allow use of expired tokens', async () => {
const response = await request(app)
.post(`/coupons/apply`)
.post(`/coupons/apply`)
.set('Authorization', `Bearer ${getAccessToken(buyer1Id, sampleBuyer1.email)}`)
.send({
couponCode: expiredCoupon.code,
});

expect(response.status).toBe(400);
expect(response.body.message).toBe('Coupon is expired');
})
expect(response.status).toBe(400);
expect(response.body.message).toBe('Coupon is expired');
});
it('should not allow use of coupon that reach maximum users', async () => {
const response = await request(app)
.post(`/coupons/apply`)
.post(`/coupons/apply`)
.set('Authorization', `Bearer ${getAccessToken(buyer1Id, sampleBuyer1.email)}`)
.send({
couponCode: finishedCoupon.code,
});

expect(response.status).toBe(400);
expect(response.body.message).toBe('Coupon Discount Ended');
})
expect(response.status).toBe(400);
expect(response.body.message).toBe('Coupon Discount Ended');
});
it('Should not work when the product is not in cart', async () => {
const response = await request(app)
.post(`/coupons/apply`)
.set('Authorization', `Bearer ${getAccessToken(buyer1Id, sampleBuyer1.email)}`)
.send({
.post(`/coupons/apply`)
.set('Authorization', `Bearer ${getAccessToken(buyer1Id, sampleBuyer1.email)}`)
.send({
couponCode: sampleCoupon3.code,
});

expect(response.status).toBe(404);
expect(response.body.message).toBe("No product in Cart with that coupon code");
})
})
expect(response.body.message).toBe('No product in Cart with that coupon code');
});
});

describe("Giving discount according the the product coupon", () => {
describe('Giving discount according the the product coupon', () => {
it('Should give discont when discount-type is percentage', async () => {
const response = await request(app)
.post(`/coupons/apply`)
.set('Authorization', `Bearer ${getAccessToken(buyer1Id, sampleBuyer1.email)}`)
.send({
.post(`/coupons/apply`)
.set('Authorization', `Bearer ${getAccessToken(buyer1Id, sampleBuyer1.email)}`)
.send({
couponCode: sampleCoupon2.code,
});

expect(response.status).toBe(200);
expect(response.body.message).toBe(`Coupon Code successfully activated discount on product: ${sampleProduct1.name}`);
})
expect(response.body.message).toBe(
`Coupon Code successfully activated discount on product: ${sampleProduct1.name}`
);
});
it('Should give discont when discount-type is money', async () => {
const response = await request(app)
.post(`/coupons/apply`)
.set('Authorization', `Bearer ${getAccessToken(buyer1Id, sampleBuyer1.email)}`)
.send({
.post(`/coupons/apply`)
.set('Authorization', `Bearer ${getAccessToken(buyer1Id, sampleBuyer1.email)}`)
.send({
couponCode: moneyCoupon.code,
});

expect(response.status).toBe(200);
expect(response.body.message).toBe(`Coupon Code successfully activated discount on product: ${sampleProduct1.name}`);
})
})

})
expect(response.body.message).toBe(
`Coupon Code successfully activated discount on product: ${sampleProduct1.name}`
);
});
});
});
78 changes: 39 additions & 39 deletions src/__test__/errorHandler.test.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,47 @@
import { Request, Response } from 'express';
import { CustomError, errorHandler } from '../middlewares/errorHandler'
import { CustomError, errorHandler } from '../middlewares/errorHandler';

describe('CustomError', () => {
it('should create a CustomError object with statusCode and status properties', () => {
const message = 'Test error message';
const statusCode = 404;
const customError = new CustomError(message, statusCode);
expect(customError.message).toBe(message);
expect(customError.statusCode).toBe(statusCode);
expect(customError.status).toBe('fail');
});
it('should create a CustomError object with statusCode and status properties', () => {
const message = 'Test error message';
const statusCode = 404;
const customError = new CustomError(message, statusCode);
expect(customError.message).toBe(message);
expect(customError.statusCode).toBe(statusCode);
expect(customError.status).toBe('fail');
});
});

describe('errorHandler', () => {
it('should send correct response with status code and message', () => {
const err = new CustomError('Test error message', 404);
const req = {} as Request;
const res = {
status: jest.fn().mockReturnThis(),
json: jest.fn(),
} as unknown as Response;
const next = jest.fn();
errorHandler(err, req, res, next);
expect(res.status).toHaveBeenCalledWith(404);
expect(res.json).toHaveBeenCalledWith({
status: 404,
message: 'Test error message',
});
describe('errorHandler', () => {
it('should send correct response with status code and message', () => {
const err = new CustomError('Test error message', 404);
const req = {} as Request;
const res = {
status: jest.fn().mockReturnThis(),
json: jest.fn(),
} as unknown as Response;
const next = jest.fn();
errorHandler(err, req, res, next);
expect(res.status).toHaveBeenCalledWith(404);
expect(res.json).toHaveBeenCalledWith({
status: 404,
message: 'Test error message',
});
it('should handle errors with status code 500', () => {
const err = new CustomError('something went wrong', 500);
const req = {} as Request;
const res = {
status: jest.fn().mockReturnThis(),
json: jest.fn(),
} as unknown as Response;
const next = jest.fn();
errorHandler(err, req, res, next);
});
it('should handle errors with status code 500', () => {
const err = new CustomError('something went wrong', 500);
const req = {} as Request;
const res = {
status: jest.fn().mockReturnThis(),
json: jest.fn(),
} as unknown as Response;
const next = jest.fn();
errorHandler(err, req, res, next);

expect(res.status).toHaveBeenCalledWith(500);
expect(res.json).toHaveBeenCalledWith({
status: 500,
message: 'something went wrong',
});
expect(res.status).toHaveBeenCalledWith(500);
expect(res.json).toHaveBeenCalledWith({
status: 500,
message: 'something went wrong',
});
});
});
});
2 changes: 1 addition & 1 deletion src/__test__/getProduct.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ beforeAll(async () => {
});

afterAll(async () => {
await cleanDatabase()
await cleanDatabase();

server.close();
});
Expand Down
29 changes: 14 additions & 15 deletions src/__test__/isAllowed.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,23 @@ beforeAll(async () => {
});

afterAll(async () => {
await cleanDatabase()

await cleanDatabase();
});

describe('Middleware - checkUserStatus', () => {
beforeEach(() => {
reqMock = {};
resMock = {
status: jest.fn().mockReturnThis(),
json: jest.fn()
};
nextMock = jest.fn();
});

it('should return 401 if user is not authenticated', async () => {
await checkUserStatus(reqMock as Request, resMock as Response, nextMock);
expect(responseError).toHaveBeenCalledWith(resMock, 401, 'Authentication required');
});
beforeEach(() => {
reqMock = {};
resMock = {
status: jest.fn().mockReturnThis(),
json: jest.fn(),
};
nextMock = jest.fn();
});

it('should return 401 if user is not authenticated', async () => {
await checkUserStatus(reqMock as Request, resMock as Response, nextMock);
expect(responseError).toHaveBeenCalledWith(resMock, 401, 'Authentication required');
});

it('should return 401 if user is not found', async () => {
reqMock = { user: { id: uuid() } };
Expand Down
3 changes: 1 addition & 2 deletions src/__test__/logout.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ beforeAll(async () => {
});

afterAll(async () => {
await cleanDatabase()

await cleanDatabase();

server.close();
});
Expand Down
Loading

0 comments on commit cdd388a

Please sign in to comment.