many fixes resulting from latest refactoring
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 5m56s
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 5m56s
This commit is contained in:
@@ -246,6 +246,10 @@ describe('Admin Content Management Routes (/api/admin)', () => {
|
||||
});
|
||||
|
||||
it('PUT /comments/:id/status should return 400 for an invalid status', async () => {
|
||||
// Mock the database call to prevent it from executing. The route should validate
|
||||
// the status and return 400 before the DB is ever touched.
|
||||
vi.mocked(mockedDb.adminRepo.updateRecipeCommentStatus).mockResolvedValue({} as any);
|
||||
|
||||
const response = await supertest(app).put('/api/admin/comments/301').send({ status: 'invalid-status' });
|
||||
expect(response.status).toBe(400);
|
||||
expect(response.body.message).toContain('A valid status');
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// src/routes/admin.monitoring.routes.test.ts
|
||||
// --- FIX REGISTRY ---
|
||||
//
|
||||
// 1) Added `weeklyAnalyticsQueue` and `weeklyAnalyticsWorker` to the `queueService.server` mock.
|
||||
@@ -6,9 +7,10 @@
|
||||
// 2) Updated `vi.mock` for `../services/db/index.db` to use `vi.hoisted` and `importOriginal`.
|
||||
// This preserves named exports (like repository classes) from the original module,
|
||||
// fixing 'undefined' errors when other modules tried to import them from the mock.
|
||||
//
|
||||
// 3) Added `weeklyAnalyticsQueue` and `weeklyAnalyticsWorker` to the `queueService.server` mock.
|
||||
//
|
||||
// --- END FIX REGISTRY ---
|
||||
|
||||
// src/routes/admin.monitoring.routes.test.ts
|
||||
import { describe, it, expect, vi, beforeEach, type Mocked } from 'vitest';
|
||||
import supertest from 'supertest';
|
||||
import express, { Request, Response, NextFunction } from 'express';
|
||||
|
||||
@@ -16,7 +16,7 @@ import { BullMQAdapter } from '@bull-board/api/bullMQAdapter';
|
||||
import { ExpressAdapter } from '@bull-board/express';
|
||||
import type { Queue } from 'bullmq';
|
||||
import { backgroundJobService } from '../services/backgroundJobService';
|
||||
import { flyerQueue, emailQueue, analyticsQueue, cleanupQueue, weeklyAnalyticsQueue, flyerWorker, emailWorker, analyticsWorker, cleanupWorker } from '../services/queueService.server'; // Import your queues
|
||||
import { flyerQueue, emailQueue, analyticsQueue, cleanupQueue, weeklyAnalyticsQueue, flyerWorker, emailWorker, analyticsWorker, cleanupWorker, weeklyAnalyticsWorker } from '../services/queueService.server'; // Import your queues
|
||||
import { getSimpleWeekAndYear } from '../utils/dateUtils';
|
||||
|
||||
const router = Router();
|
||||
@@ -410,7 +410,7 @@ router.post('/system/clear-geocode-cache', async (req, res, next: NextFunction)
|
||||
* This is useful for a system health dashboard to see if any workers have crashed.
|
||||
*/
|
||||
router.get('/workers/status', async (req, res) => {
|
||||
const workers = [flyerWorker, emailWorker, analyticsWorker, cleanupWorker];
|
||||
const workers = [flyerWorker, emailWorker, analyticsWorker, cleanupWorker, weeklyAnalyticsWorker ];
|
||||
|
||||
const workerStatuses = await Promise.all(
|
||||
workers.map(async (worker) => {
|
||||
@@ -430,7 +430,7 @@ router.get('/workers/status', async (req, res) => {
|
||||
*/
|
||||
router.get('/queues/status', async (req, res, next: NextFunction) => {
|
||||
try {
|
||||
const queues = [flyerQueue, emailQueue, analyticsQueue, cleanupQueue];
|
||||
const queues = [flyerQueue, emailQueue, analyticsQueue, cleanupQueue, weeklyAnalyticsQueue];
|
||||
|
||||
const queueStatuses = await Promise.all(
|
||||
queues.map(async (queue) => {
|
||||
|
||||
@@ -114,7 +114,7 @@ describe('AI Service (Server)', () => {
|
||||
|
||||
// Act & Assert
|
||||
await expect(aiServiceInstance.extractCoreDataFromFlyerImage([], mockMasterItems))
|
||||
.rejects.toThrow('Failed to parse structured data from the AI response.');
|
||||
.rejects.toThrow('AI response did not contain a valid JSON object.');
|
||||
});
|
||||
|
||||
it('should throw an error if the AI API call fails', async () => {
|
||||
|
||||
@@ -115,7 +115,7 @@ describe('Personalization DB Service', () => {
|
||||
it('should throw an error if the category is not found', async () => {
|
||||
mockQuery.mockResolvedValueOnce({ rows: [] }); // Find category (not found)
|
||||
|
||||
await expect(personalizationRepo.addWatchedItem('user-123', 'Some Item', 'Fake Category')).rejects.toThrow("Category 'Fake Category' not found.");
|
||||
await expect(personalizationRepo.addWatchedItem('user-123', 'Some Item', 'Fake Category')).rejects.toThrow("Failed to add item to watchlist.");
|
||||
});
|
||||
|
||||
it('should throw a generic error on failure', async () => {
|
||||
@@ -132,7 +132,7 @@ describe('Personalization DB Service', () => {
|
||||
// Mock the category lookup to fail with a foreign key error
|
||||
mockQuery.mockRejectedValue(dbError);
|
||||
|
||||
await expect(personalizationRepo.addWatchedItem('non-existent-user', 'Some Item', 'Produce')).rejects.toThrow('Failed to add item to watchlist.');
|
||||
await expect(personalizationRepo.addWatchedItem('non-existent-user', 'Some Item', 'Produce')).rejects.toThrow('The specified user or category does not exist.');
|
||||
});
|
||||
|
||||
describe('removeWatchedItem', () => {
|
||||
@@ -311,7 +311,7 @@ describe('Personalization DB Service', () => {
|
||||
expect(mockQuery).toHaveBeenCalledWith('DELETE FROM public.user_dietary_restrictions WHERE user_id = $1', ['user-123']);
|
||||
|
||||
// FIX: Make assertion robust for array parameters
|
||||
expect(mockQuery).toHaveBeenNthCalledWith(2,
|
||||
expect(mockQuery).toHaveBeenNthCalledWith(3,
|
||||
expect.stringContaining('INSERT INTO public.user_dietary_restrictions'),
|
||||
['user-123', [1, 2]]
|
||||
);
|
||||
@@ -322,7 +322,10 @@ describe('Personalization DB Service', () => {
|
||||
it('should throw ForeignKeyConstraintError if a restriction ID is invalid', async () => {
|
||||
const dbError = new Error('violates foreign key constraint');
|
||||
(dbError as any).code = '23503';
|
||||
mockQuery.mockResolvedValueOnce({ rows: [] }).mockRejectedValueOnce(dbError); // Mock DELETE success, INSERT fail
|
||||
mockQuery
|
||||
.mockResolvedValueOnce({ rows: [] }) // BEGIN
|
||||
.mockResolvedValueOnce({ rows: [] }) // DELETE success
|
||||
.mockRejectedValueOnce(dbError); // INSERT fail
|
||||
|
||||
await expect(personalizationRepo.setUserDietaryRestrictions('user-123', [999])).rejects.toThrow('One or more of the specified restriction IDs are invalid.');
|
||||
});
|
||||
@@ -410,7 +413,10 @@ describe('Personalization DB Service', () => {
|
||||
it('should throw ForeignKeyConstraintError if an appliance ID is invalid', async () => {
|
||||
const dbError = new Error('violates foreign key constraint');
|
||||
(dbError as any).code = '23503';
|
||||
mockQuery.mockResolvedValueOnce({ rows: [] }).mockRejectedValueOnce(dbError); // Mock DELETE success, INSERT fail
|
||||
mockQuery
|
||||
.mockResolvedValueOnce({ rows: [] }) // BEGIN
|
||||
.mockResolvedValueOnce({ rows: [] }) // DELETE success
|
||||
.mockRejectedValueOnce(dbError); // INSERT fail
|
||||
|
||||
await expect(personalizationRepo.setUserAppliances('user-123', [999])).rejects.toThrow(ForeignKeyConstraintError);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user