All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 33m19s
122 lines
4.8 KiB
TypeScript
122 lines
4.8 KiB
TypeScript
// src/routes/personalization.routes.test.ts
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import supertest from 'supertest';
|
|
import {
|
|
createMockMasterGroceryItem,
|
|
createMockDietaryRestriction,
|
|
createMockAppliance,
|
|
} from '../tests/utils/mockFactories';
|
|
import { createTestApp } from '../tests/utils/createTestApp';
|
|
|
|
// 1. Mock the Service Layer directly.
|
|
vi.mock('../services/db/index.db', () => ({
|
|
personalizationRepo: {
|
|
getAllMasterItems: vi.fn(),
|
|
getDietaryRestrictions: vi.fn(),
|
|
getAppliances: vi.fn(),
|
|
},
|
|
}));
|
|
|
|
// Import the router and mocked DB AFTER all mocks are defined.
|
|
import personalizationRouter from './personalization.routes';
|
|
import * as db from '../services/db/index.db';
|
|
import { mockLogger } from '../tests/utils/mockLogger';
|
|
|
|
// Mock the logger to keep test output clean
|
|
vi.mock('../services/logger.server', async () => ({
|
|
// Use async import to avoid hoisting issues with mockLogger
|
|
logger: (await import('../tests/utils/mockLogger')).mockLogger,
|
|
}));
|
|
|
|
describe('Personalization Routes (/api/personalization)', () => {
|
|
const app = createTestApp({ router: personalizationRouter, basePath: '/api/personalization' });
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe('GET /master-items', () => {
|
|
it('should return a list of master items', async () => {
|
|
const mockItems = [createMockMasterGroceryItem({ master_grocery_item_id: 1, name: 'Milk' })];
|
|
vi.mocked(db.personalizationRepo.getAllMasterItems).mockResolvedValue(mockItems);
|
|
|
|
const response = await supertest(app).get('/api/personalization/master-items').set('x-test-rate-limit-enable', 'true');
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.body).toEqual(mockItems);
|
|
});
|
|
|
|
it('should return 500 if the database call fails', async () => {
|
|
const dbError = new Error('DB Error');
|
|
vi.mocked(db.personalizationRepo.getAllMasterItems).mockRejectedValue(dbError);
|
|
const response = await supertest(app).get('/api/personalization/master-items').set('x-test-rate-limit-enable', 'true');
|
|
expect(response.status).toBe(500);
|
|
expect(response.body.message).toBe('DB Error');
|
|
expect(mockLogger.error).toHaveBeenCalledWith(
|
|
{ error: dbError },
|
|
'Error fetching master items in /api/personalization/master-items:',
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('GET /dietary-restrictions', () => {
|
|
it('should return a list of all dietary restrictions', async () => {
|
|
const mockRestrictions = [createMockDietaryRestriction({ name: 'Gluten-Free' })];
|
|
vi.mocked(db.personalizationRepo.getDietaryRestrictions).mockResolvedValue(mockRestrictions);
|
|
|
|
const response = await supertest(app).get('/api/personalization/dietary-restrictions');
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.body).toEqual(mockRestrictions);
|
|
});
|
|
|
|
it('should return 500 if the database call fails', async () => {
|
|
const dbError = new Error('DB Error');
|
|
vi.mocked(db.personalizationRepo.getDietaryRestrictions).mockRejectedValue(dbError);
|
|
const response = await supertest(app).get('/api/personalization/dietary-restrictions');
|
|
expect(response.status).toBe(500);
|
|
expect(response.body.message).toBe('DB Error');
|
|
expect(mockLogger.error).toHaveBeenCalledWith(
|
|
{ error: dbError },
|
|
'Error fetching dietary restrictions in /api/personalization/dietary-restrictions:',
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('GET /appliances', () => {
|
|
it('should return a list of all appliances', async () => {
|
|
const mockAppliances = [createMockAppliance({ name: 'Air Fryer' })];
|
|
vi.mocked(db.personalizationRepo.getAppliances).mockResolvedValue(mockAppliances);
|
|
|
|
const response = await supertest(app).get('/api/personalization/appliances');
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.body).toEqual(mockAppliances);
|
|
});
|
|
|
|
it('should return 500 if the database call fails', async () => {
|
|
const dbError = new Error('DB Error');
|
|
vi.mocked(db.personalizationRepo.getAppliances).mockRejectedValue(dbError);
|
|
const response = await supertest(app).get('/api/personalization/appliances');
|
|
expect(response.status).toBe(500);
|
|
expect(response.body.message).toBe('DB Error');
|
|
expect(mockLogger.error).toHaveBeenCalledWith(
|
|
{ error: dbError },
|
|
'Error fetching appliances in /api/personalization/appliances:',
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('Rate Limiting', () => {
|
|
it('should apply publicReadLimiter to GET /master-items', async () => {
|
|
vi.mocked(db.personalizationRepo.getAllMasterItems).mockResolvedValue([]);
|
|
const response = await supertest(app)
|
|
.get('/api/personalization/master-items')
|
|
.set('X-Test-Rate-Limit-Enable', 'true');
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.headers).toHaveProperty('ratelimit-limit');
|
|
});
|
|
});
|
|
});
|