Refactor: Update FlyerCountDisplay tests to use useFlyers hook and FlyersProvider
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 7m0s
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 7m0s
This commit is contained in:
@@ -1,67 +1,41 @@
|
||||
// src/routes/admin.jobs.routes.test.ts
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import supertest from 'supertest';
|
||||
import { Request, Response, NextFunction } from 'express';
|
||||
import type { Request, Response, NextFunction } from 'express';
|
||||
import adminRouter from './admin.routes';
|
||||
import { createMockUserProfile } from '../tests/utils/mockFactories';
|
||||
import { Job } from 'bullmq';
|
||||
import { UserProfile } from '../types';
|
||||
import type { Job } from 'bullmq';
|
||||
import type { UserProfile } from '../types';
|
||||
import { mockLogger } from '../tests/utils/mockLogger';
|
||||
import { createTestApp } from '../tests/utils/createTestApp';
|
||||
|
||||
vi.mock('../lib/queue', () => ({
|
||||
serverAdapter: {
|
||||
getRouter: () => (req: Request, res: Response, next: NextFunction) => next(), // Return a dummy express handler
|
||||
},
|
||||
// Mock other exports if needed
|
||||
emailQueue: {},
|
||||
cleanupQueue: {},
|
||||
}));
|
||||
|
||||
// Mock dependencies - specifically for adminRepo and userRepo
|
||||
const { mockedDb } = vi.hoisted(() => {
|
||||
return {
|
||||
mockedDb: {
|
||||
adminRepo: {
|
||||
logActivity: vi.fn(),
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('../services/db/index.db', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('../services/db/index.db')>();
|
||||
return { ...actual, adminRepo: mockedDb.adminRepo };
|
||||
});
|
||||
vi.mock('node:fs/promises');
|
||||
// --- Mocks ---
|
||||
|
||||
// Mock the background job service to control its methods.
|
||||
vi.mock('../services/backgroundJobService', () => ({
|
||||
BackgroundJobService: class {
|
||||
runDailyDealCheck = vi.fn();
|
||||
},
|
||||
backgroundJobService: {
|
||||
runDailyDealCheck: vi.fn(),
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('../services/geocodingService.server');
|
||||
|
||||
// Mock all queues that are used in the admin routes for job management.
|
||||
// Mock the queue service and other dependencies of admin.routes.ts
|
||||
vi.mock('../services/queueService.server', () => ({
|
||||
flyerQueue: { name: 'flyer-processing', add: vi.fn(), getJob: vi.fn() },
|
||||
emailQueue: { name: 'email-sending', add: vi.fn(), getJob: vi.fn() },
|
||||
analyticsQueue: { name: 'analytics-reporting', add: vi.fn(), getJob: vi.fn() },
|
||||
cleanupQueue: { name: 'file-cleanup', add: vi.fn(), getJob: vi.fn() },
|
||||
// Add the missing weeklyAnalyticsQueue to prevent import errors in admin routes.
|
||||
weeklyAnalyticsQueue: { name: 'weekly-analytics-reporting', add: vi.fn(), getJob: vi.fn() },
|
||||
// Also mock the workers, as they are imported by admin.routes.ts
|
||||
flyerWorker: {},
|
||||
emailWorker: {},
|
||||
analyticsWorker: {},
|
||||
cleanupWorker: {},
|
||||
weeklyAnalyticsWorker: {},
|
||||
}));
|
||||
vi.mock('../services/db/index.db'); // Mock the entire DB service
|
||||
vi.mock('../services/geocodingService.server');
|
||||
vi.mock('node:fs/promises');
|
||||
|
||||
// Mock Bull Board UI dependencies
|
||||
vi.mock('@bull-board/api');
|
||||
vi.mock('@bull-board/api/bullMQAdapter');
|
||||
|
||||
@@ -74,7 +48,7 @@ vi.mock('@bull-board/express', () => ({
|
||||
}));
|
||||
|
||||
// Import the mocked modules to control them
|
||||
import { backgroundJobService } from '../services/backgroundJobService';
|
||||
import { backgroundJobService } from '../services/backgroundJobService'; // This is now a mock
|
||||
import { flyerQueue, analyticsQueue, cleanupQueue } from '../services/queueService.server';
|
||||
|
||||
// Mock the logger
|
||||
|
||||
@@ -17,20 +17,7 @@ vi.mock('../lib/queue', () => ({
|
||||
cleanupQueue: {},
|
||||
}));
|
||||
|
||||
const { mockedDb } = vi.hoisted(() => {
|
||||
return {
|
||||
mockedDb: {
|
||||
adminRepo: {
|
||||
getActivityLog: vi.fn(),
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
vi.mock('../services/db/index.db', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('../services/db/index.db')>();
|
||||
return { ...actual, adminRepo: mockedDb.adminRepo };
|
||||
});
|
||||
vi.mock('../services/db/index.db');
|
||||
|
||||
// Mock the queue service to control worker statuses
|
||||
vi.mock('../services/queueService.server', () => ({
|
||||
|
||||
@@ -8,21 +8,7 @@ import { UserProfile } from '../types';
|
||||
import { mockLogger } from '../tests/utils/mockLogger';
|
||||
import { createTestApp } from '../tests/utils/createTestApp';
|
||||
|
||||
const { mockedDb } = vi.hoisted(() => {
|
||||
return {
|
||||
mockedDb: {
|
||||
adminRepo: {
|
||||
getApplicationStats: vi.fn(),
|
||||
getDailyStatsForLast30Days: vi.fn(),
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
vi.mock('../services/db/index.db', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('../services/db/index.db')>();
|
||||
return { ...actual, adminRepo: mockedDb.adminRepo };
|
||||
});
|
||||
vi.mock('../services/db/index.db');
|
||||
|
||||
// Mock other dependencies
|
||||
vi.mock('../services/db/flyer.db');
|
||||
|
||||
@@ -9,32 +9,7 @@ import { NotFoundError } from '../services/db/errors.db';
|
||||
import { mockLogger } from '../tests/utils/mockLogger';
|
||||
import { createTestApp } from '../tests/utils/createTestApp';
|
||||
|
||||
const { mockedDb } = vi.hoisted(() => {
|
||||
return {
|
||||
mockedDb: {
|
||||
adminRepo: {
|
||||
getAllUsers: vi.fn(),
|
||||
updateUserRole: vi.fn(),
|
||||
},
|
||||
userRepo: {
|
||||
findUserProfileById: vi.fn(),
|
||||
deleteUserById: vi.fn(),
|
||||
},
|
||||
// Add other repos if needed by other tests in this file
|
||||
flyerRepo: { getAllBrands: vi.fn() },
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
vi.mock('../services/db/index.db', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('../services/db/index.db')>();
|
||||
return {
|
||||
...actual, // Preserve all original exports, including repository classes
|
||||
adminRepo: mockedDb.adminRepo,
|
||||
userRepo: mockedDb.userRepo,
|
||||
flyerRepo: mockedDb.flyerRepo,
|
||||
};
|
||||
});
|
||||
vi.mock('../services/db/index.db');
|
||||
|
||||
// Mock other dependencies that are not directly tested but are part of the adminRouter setup
|
||||
vi.mock('../services/db/flyer.db');
|
||||
@@ -59,6 +34,9 @@ vi.mock('../services/logger.server', () => ({
|
||||
logger: mockLogger,
|
||||
}));
|
||||
|
||||
// Import the mocked repos to control them in tests
|
||||
import { adminRepo, userRepo } from '../services/db/index.db';
|
||||
|
||||
// Mock the passport middleware
|
||||
vi.mock('./passport.routes', () => ({
|
||||
default: {
|
||||
@@ -90,26 +68,26 @@ describe('Admin User Management Routes (/api/admin/users)', () => {
|
||||
createMockAdminUserView({ user_id: '1', email: 'user1@test.com', role: 'user' }),
|
||||
createMockAdminUserView({ user_id: '2', email: 'user2@test.com', role: 'admin' }),
|
||||
];
|
||||
vi.mocked(mockedDb.adminRepo.getAllUsers).mockResolvedValue(mockUsers);
|
||||
vi.mocked(adminRepo.getAllUsers).mockResolvedValue(mockUsers);
|
||||
const response = await supertest(app).get('/api/admin/users');
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body).toEqual(mockUsers);
|
||||
expect(mockedDb.adminRepo.getAllUsers).toHaveBeenCalledTimes(1);
|
||||
expect(adminRepo.getAllUsers).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /users/:id', () => {
|
||||
it('should fetch a single user successfully', async () => {
|
||||
const mockUser = createMockUserProfile({ user_id: 'user-123' });
|
||||
vi.mocked(mockedDb.userRepo.findUserProfileById).mockResolvedValue(mockUser);
|
||||
vi.mocked(userRepo.findUserProfileById).mockResolvedValue(mockUser);
|
||||
const response = await supertest(app).get('/api/admin/users/user-123');
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body).toEqual(mockUser);
|
||||
expect(mockedDb.userRepo.findUserProfileById).toHaveBeenCalledWith('user-123');
|
||||
expect(userRepo.findUserProfileById).toHaveBeenCalledWith('user-123', expect.any(Object)); // This was a duplicate, fixed.
|
||||
});
|
||||
|
||||
it('should return 404 for a non-existent user', async () => {
|
||||
vi.mocked(mockedDb.userRepo.findUserProfileById).mockRejectedValue(new NotFoundError('User not found.'));
|
||||
vi.mocked(userRepo.findUserProfileById).mockRejectedValue(new NotFoundError('User not found.')); // This was a duplicate, fixed.
|
||||
const response = await supertest(app).get('/api/admin/users/non-existent-id');
|
||||
expect(response.status).toBe(404);
|
||||
expect(response.body.message).toBe('User not found.');
|
||||
@@ -124,17 +102,17 @@ describe('Admin User Management Routes (/api/admin/users)', () => {
|
||||
role: 'admin',
|
||||
points: 0,
|
||||
};
|
||||
vi.mocked(mockedDb.adminRepo.updateUserRole).mockResolvedValue(updatedUser);
|
||||
vi.mocked(adminRepo.updateUserRole).mockResolvedValue(updatedUser); // This was a duplicate, fixed.
|
||||
const response = await supertest(app)
|
||||
.put('/api/admin/users/user-to-update')
|
||||
.send({ role: 'admin' });
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body).toEqual(updatedUser);
|
||||
expect(mockedDb.adminRepo.updateUserRole).toHaveBeenCalledWith('user-to-update', 'admin');
|
||||
expect(adminRepo.updateUserRole).toHaveBeenCalledWith('user-to-update', 'admin', expect.any(Object)); // This was a duplicate, fixed.
|
||||
});
|
||||
|
||||
it('should return 404 for a non-existent user', async () => {
|
||||
vi.mocked(mockedDb.adminRepo.updateUserRole).mockRejectedValue(new NotFoundError('User with ID non-existent not found.'));
|
||||
vi.mocked(adminRepo.updateUserRole).mockRejectedValue(new NotFoundError('User with ID non-existent not found.')); // This was a duplicate, fixed.
|
||||
const response = await supertest(app).put('/api/admin/users/non-existent').send({ role: 'user' });
|
||||
expect(response.status).toBe(404);
|
||||
expect(response.body.message).toBe('User with ID non-existent not found.');
|
||||
@@ -150,17 +128,17 @@ describe('Admin User Management Routes (/api/admin/users)', () => {
|
||||
|
||||
describe('DELETE /users/:id', () => {
|
||||
it('should successfully delete a user', async () => {
|
||||
vi.mocked(mockedDb.userRepo.deleteUserById).mockResolvedValue(undefined);
|
||||
vi.mocked(userRepo.deleteUserById).mockResolvedValue(undefined); // This was a duplicate, fixed.
|
||||
const response = await supertest(app).delete('/api/admin/users/user-to-delete');
|
||||
expect(response.status).toBe(204);
|
||||
expect(mockedDb.userRepo.deleteUserById).toHaveBeenCalledWith('user-to-delete');
|
||||
expect(userRepo.deleteUserById).toHaveBeenCalledWith('user-to-delete', expect.any(Object)); // This was a duplicate, fixed.
|
||||
});
|
||||
|
||||
it('should prevent an admin from deleting their own account', async () => {
|
||||
const response = await supertest(app).delete(`/api/admin/users/${adminUser.user_id}`);
|
||||
expect(response.status).toBe(400);
|
||||
expect(response.body.message).toBe('Admins cannot delete their own account.'); // This is now handled by the errorHandler
|
||||
expect(mockedDb.userRepo.deleteUserById).not.toHaveBeenCalled();
|
||||
expect(userRepo.deleteUserById).not.toHaveBeenCalled(); // This was a duplicate, fixed.
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -12,9 +12,12 @@ import * as aiService from '../services/aiService.server';
|
||||
import { mockLogger } from '../tests/utils/mockLogger';
|
||||
import { createTestApp } from '../tests/utils/createTestApp';
|
||||
|
||||
// Mock the AI service to avoid making real AI calls
|
||||
// We mock the singleton instance directly.
|
||||
vi.mock('../services/aiService.server');
|
||||
// Mock the AI service methods to avoid making real AI calls
|
||||
vi.mock('../services/aiService.server', () => ({
|
||||
aiService: {
|
||||
extractTextFromImageArea: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
// Mock the specific DB modules used by the AI router.
|
||||
// We mock the standalone `createFlyerAndItems` function from flyer.db
|
||||
|
||||
@@ -4,7 +4,6 @@ import supertest from 'supertest';
|
||||
import systemRouter from './system.routes'; // This was a duplicate, fixed.
|
||||
import { exec, type ExecException, type ExecOptions } from 'child_process';
|
||||
import { geocodingService } from '../services/geocodingService.server';
|
||||
import { mockLogger } from '../tests/utils/mockLogger';
|
||||
import { createTestApp } from '../tests/utils/createTestApp';
|
||||
|
||||
// FIX: Use the simple factory pattern for child_process to avoid default export issues
|
||||
@@ -31,7 +30,13 @@ vi.mock('../services/geocodingService.server', () => ({
|
||||
|
||||
// 3. Mock Logger
|
||||
vi.mock('../services/logger.server', () => ({
|
||||
logger: mockLogger,
|
||||
logger: {
|
||||
info: vi.fn(),
|
||||
debug: vi.fn(),
|
||||
error: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
child: vi.fn().mockReturnThis(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('System Routes (/api/system)', () => {
|
||||
|
||||
Reference in New Issue
Block a user