// src/routes/admin.system.routes.test.ts import { describe, it, expect, vi, beforeEach } from 'vitest'; import supertest from 'supertest'; import type { Request, Response, NextFunction } from 'express'; import { createMockUserProfile } from '../tests/utils/mockFactories'; import { createTestApp } from '../tests/utils/createTestApp'; // Mock dependencies vi.mock('../services/geocodingService.server', () => ({ geocodingService: { clearGeocodeCache: vi.fn(), }, })); // Mock other dependencies that are part of the adminRouter setup but not directly tested here vi.mock('../services/db/index.db', () => ({ adminRepo: {}, flyerRepo: {}, recipeRepo: {}, userRepo: {}, personalizationRepo: {}, notificationRepo: {}, })); vi.mock('../services/db/flyer.db'); vi.mock('../services/db/recipe.db'); vi.mock('../services/db/user.db'); vi.mock('node:fs/promises'); vi.mock('../services/backgroundJobService', () => ({ backgroundJobService: { runDailyDealCheck: vi.fn(), }, })); vi.mock('../services/queueService.server'); vi.mock('../services/queues.server'); vi.mock('../services/workers.server'); vi.mock('../services/monitoringService.server'); vi.mock('../services/cacheService.server'); vi.mock('../services/userService'); vi.mock('../services/brandService'); vi.mock('../services/receiptService.server'); vi.mock('../services/aiService.server'); vi.mock('../config/env', () => ({ config: { database: { host: 'localhost', port: 5432, user: 'test', password: 'test', name: 'test' }, redis: { url: 'redis://localhost:6379' }, auth: { jwtSecret: 'test-secret' }, server: { port: 3000, host: 'localhost' }, }, isAiConfigured: vi.fn().mockReturnValue(false), parseConfig: vi.fn(), })); vi.mock('@bull-board/api'); vi.mock('@bull-board/api/bullMQAdapter'); vi.mock('@bull-board/express', () => ({ ExpressAdapter: class { setBasePath = vi.fn(); getRouter = vi .fn() .mockReturnValue((req: Request, res: Response, next: NextFunction) => next()); }, })); // Import the router AFTER all mocks are defined. import adminRouter from './admin.routes'; // Import the mocked modules to control them import { geocodingService } from '../services/geocodingService.server'; // Mock the logger vi.mock('../services/logger.server', async () => { const { mockLogger, createMockLogger } = await import('../tests/utils/mockLogger'); return { logger: mockLogger, createScopedLogger: vi.fn(() => createMockLogger()), }; }); // Mock the passport middleware // Note: admin.routes.ts imports from '../config/passport', so we mock that path vi.mock('../config/passport', () => ({ default: { authenticate: vi.fn(() => (req: Request, res: Response, next: NextFunction) => { req.user = createMockUserProfile({ role: 'admin', user: { user_id: 'admin-user-id', email: 'admin@test.com' }, }); next(); }), }, isAdmin: (req: Request, res: Response, next: NextFunction) => next(), })); describe('Admin System Routes (/api/admin/system)', () => { const adminUser = createMockUserProfile({ role: 'admin', user: { user_id: 'admin-user-id', email: 'admin@test.com' }, }); const app = createTestApp({ router: adminRouter, basePath: '/api/admin', authenticatedUser: adminUser, }); beforeEach(() => { vi.clearAllMocks(); }); describe('POST /system/clear-geocode-cache', () => { it('should return 200 on successful cache clear', async () => { vi.mocked(geocodingService.clearGeocodeCache).mockResolvedValue(10); const response = await supertest(app).post('/api/admin/system/clear-geocode-cache'); expect(response.status).toBe(200); expect(response.body.data.message).toContain('10 keys were removed'); }); it('should return 500 if clearing the cache fails', async () => { vi.mocked(geocodingService.clearGeocodeCache).mockRejectedValue(new Error('Redis is down')); const response = await supertest(app).post('/api/admin/system/clear-geocode-cache'); expect(response.status).toBe(500); expect(response.body.error.message).toContain('Redis is down'); }); }); });