Skip to content

Commit

Permalink
* fix(create-review): fix failing create review function (#109)
Browse files Browse the repository at this point in the history
-add validation before processing data

[Fixes #116]

* fix(create-review): fix failing create review function

-add validation before processing data

[Fixes #116]

Co-authored-by: Joslyn Manzi Karenzi <[email protected]>
  • Loading branch information
ambroisegithub and jkarenzi authored Jun 5, 2024
1 parent de5f934 commit 84f8458
Show file tree
Hide file tree
Showing 25 changed files with 1,989 additions and 56 deletions.
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,16 @@
],
"coveragePathIgnorePatterns": [
"/node_modules/",
"/src/emails/"
"/src/emails/",
"/src/utilis/"

],
"testPathIgnorePatterns": [
"/node_modules/",
"/src/emails/",
"/src/middlewares/"
"/src/middlewares/",
"/src/utilis/"

]
},
"devDependencies": {
Expand Down
4 changes: 0 additions & 4 deletions src/__test__/cartController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,6 @@ describe('Checkout Tests', () => {
.set('Authorization', `Bearer ${buyerToken}`)
.send({
deliveryInfo: '',
paymentInfo: '',
couponCode: 'DISCOUNT10',
});

Expand All @@ -244,7 +243,6 @@ describe('Checkout Tests', () => {
.set('Authorization', `Bearer ${buyerToken}`)
.send({
deliveryInfo: '123 Delivery St.',
paymentInfo: 'VISA 1234',
couponCode: 'DISCOUNT10',
});

Expand Down Expand Up @@ -283,7 +281,6 @@ describe('Checkout Tests', () => {
.set('Authorization', invalidUserToken)
.send({
deliveryInfo: '123 Delivery St.',
paymentInfo: 'VISA 1234',
couponCode: 'DISCOUNT10',
});

Expand All @@ -309,7 +306,6 @@ describe('Checkout Tests', () => {
.set('Authorization', `Bearer ${buyerToken}`)
.send({
deliveryInfo: '123 Delivery St.',
paymentInfo: 'VISA 1234',
couponCode: 'DISCOUNT10',
});

Expand Down
42 changes: 42 additions & 0 deletions src/__test__/chatbot.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import request from 'supertest';
import app from '../app';
import { afterAllHook, beforeAllHook, getBuyerToken } from './testSetup';

beforeAll(beforeAllHook);
afterAll(afterAllHook);
let buyerToken: string;

describe('Chatbot Interactions', () => {
beforeAll(async () => {
buyerToken = await getBuyerToken();
});

describe('Ask Question Endpoint', () => {
it('should respond to a valid question with the correct answer for logged-in users', async () => {
const chatData = {
message: 'What do you sell?',
};

const response = await request(app)
.post('/api/v1/chat')
.set('Authorization', `Bearer ${buyerToken}`)
.send(chatData);

expect(response.statusCode).toEqual(200);
expect(response.body.message).toContain(
'We sell the following products:'
);
});
});

describe('Fetch All Chat History', () => {
it('should return the full chat history for the authenticated user', async () => {
const response = await request(app)
.get('/api/v1/chat/history')
.set('Authorization', `Bearer ${buyerToken}`);

expect(response.statusCode).toEqual(200);
expect(Array.isArray(response.body.history)).toBeTruthy();
});
});
});
224 changes: 224 additions & 0 deletions src/__test__/chatbotService.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
import { analyzeMessage, generateResponse } from '../utilis/nlp';
import Chat from '../database/models/chatbotModel';
import User from '../database/models/userModel';
import dbConnection from '../database';
import {
getProducts,
getProductByName,
getOrderStatusByTrackingNumber,
getServices,
getServiceByName,
getChatHistory,
getProductDetails,
getProductReviews,
} from '../service/chatbotService';
import { processMessage } from '../service/chatbotService';
jest.mock('../database');
jest.mock('../utilis/nlp');

describe('Chatbot Service', () => {
beforeEach(() => {
jest.clearAllMocks();
});

describe('processMessage', () => {
const userId = 1;
const user = { id: userId, firstName: 'John', lastName: 'Doe' } as User;

const mockDate = (hour: number) => {
const RealDate = Date;
const mockDate = new RealDate();
jest.spyOn(global, 'Date').mockImplementation(() => {
mockDate.setHours(hour);
return mockDate;
});
};

const setupMocks = () => {
const userRepoMock = {
findOne: jest.fn().mockResolvedValue(user),
};
const chatRepoMock = {
save: jest.fn().mockImplementation(async (chat: Chat) => chat),
};
(dbConnection.getRepository as jest.Mock).mockImplementation((entity) => {
if (entity === User) return userRepoMock;
if (entity === Chat) return chatRepoMock;
});
(analyzeMessage as jest.Mock).mockReturnValue('analyzed message');
(generateResponse as jest.Mock).mockResolvedValue('response');
};

it('should return a complete response with a morning greeting', async () => {
mockDate(9);
setupMocks();

const expectedGreeting = 'response';
const result = await processMessage(userId, 'test message');

expect(result.trim()).toEqual(expectedGreeting.trim());
});

it('should return a complete response with an afternoon greeting', async () => {
mockDate(15);
setupMocks();

const expectedGreeting = 'response';
const result = await processMessage(userId, 'test message');

expect(result.trim()).toEqual(expectedGreeting.trim());
});

it('should return a complete response with an evening greeting', async () => {
mockDate(20);
setupMocks();

const expectedGreeting = 'response';
const result = await processMessage(userId, 'test message');

expect(result.trim()).toEqual(expectedGreeting.trim());
});

it('should throw an error if user is not found', async () => {
const userRepoMock = {
findOne: jest.fn().mockResolvedValue(null),
};
(dbConnection.getRepository as jest.Mock).mockReturnValue(userRepoMock);

await expect(processMessage(userId, 'test message')).rejects.toThrow(
'User not found'
);

expect(userRepoMock.findOne).toHaveBeenCalledWith({
where: { id: userId },
});
});
});

it('should return a list of products', async () => {
const productRepo = {
find: jest.fn().mockResolvedValue([{ name: 'Product1' }]),
};
dbConnection.getRepository = jest.fn().mockReturnValue(productRepo);

const products = await getProducts();
expect(products).toEqual([{ name: 'Product1' }]);
});

describe('getProductByName', () => {
it('should return a product by name', async () => {
const productRepo = {
findOne: jest.fn().mockResolvedValue({ name: 'Product1' }),
};
dbConnection.getRepository = jest.fn().mockReturnValue(productRepo);

const product = await getProductByName('Product1');
expect(product).toEqual({ name: 'Product1' });
});
});

describe('getOrderStatusByTrackingNumber', () => {
it('should return the status of an order by tracking number', async () => {
const orderRepo = {
findOne: jest.fn().mockResolvedValue({ status: 'Shipped' }),
};
dbConnection.getRepository = jest.fn().mockReturnValue(orderRepo);

const status = await getOrderStatusByTrackingNumber('12345');
expect(status).toBe('Shipped');
});

it('should return "Tracking number not found" if order is not found', async () => {
const orderRepo = { findOne: jest.fn().mockResolvedValue(null) };
dbConnection.getRepository = jest.fn().mockReturnValue(orderRepo);

const status = await getOrderStatusByTrackingNumber('12345');
expect(status).toBe('Tracking number not found');
});
});

describe('getServices', () => {
it('should return a list of services', async () => {
const serviceRepo = {
find: jest.fn().mockResolvedValue([{ name: 'Service1' }]),
};
dbConnection.getRepository = jest.fn().mockReturnValue(serviceRepo);

const services = await getServices();
expect(services).toEqual([{ name: 'Service1' }]);
});
});

describe('getServiceByName', () => {
it('should return a service by name', async () => {
const serviceRepo = {
findOne: jest.fn().mockResolvedValue({ name: 'Service1' }),
};
dbConnection.getRepository = jest.fn().mockReturnValue(serviceRepo);

const service = await getServiceByName('Service1');
expect(service).toEqual({ name: 'Service1' });
});
});

describe('getChatHistory', () => {
it('should return chat history for a user', async () => {
const userId = 1;
const chatRepo = {
find: jest
.fn()
.mockResolvedValue([{ message: 'Hello', createdAt: '2024-05-31' }]),
};
dbConnection.getRepository = jest.fn().mockReturnValue(chatRepo);

const chatHistory = await getChatHistory(userId);
expect(chatHistory).toEqual([
{ message: 'Hello', createdAt: '2024-05-31' },
]);
});
});

describe('getProductDetails', () => {
it('should return product details by name', async () => {
const productRepo = {
findOne: jest
.fn()
.mockResolvedValue({ name: 'Product1', details: 'Product details' }),
};
dbConnection.getRepository = jest.fn().mockReturnValue(productRepo);

const productDetails = await getProductDetails('Product1');
expect(productDetails).toEqual({
name: 'Product1',
details: 'Product details',
});
});
});

describe('getProductReviews', () => {
it('should return reviews for a product', async () => {
const productRepo = {
findOne: jest.fn().mockResolvedValue({
name: 'Product1',
reviews: [{ rating: 5, comment: 'Excellent' }],
}),
};
dbConnection.getRepository = jest.fn().mockReturnValue(productRepo);

const reviews = await getProductReviews('Product1');
expect(reviews).toEqual([{ rating: 5, comment: 'Excellent' }]);
});

it('should return null if product is not found', async () => {
const productRepo = {
findOne: jest.fn().mockResolvedValue(null),
};
dbConnection.getRepository = jest.fn().mockReturnValue(productRepo);

const reviews = await getProductReviews('Product1');
expect(reviews).toBeNull();
});
});
});


Loading

0 comments on commit 84f8458

Please sign in to comment.