fix unit tests
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 12m5s
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 12m5s
This commit is contained in:
@@ -12,11 +12,10 @@ vi.mock('util', async (importOriginal) => {
|
|||||||
const actual = await importOriginal<typeof import('util')>();
|
const actual = await importOriginal<typeof import('util')>();
|
||||||
return {
|
return {
|
||||||
...actual,
|
...actual,
|
||||||
default: actual,
|
|
||||||
promisify: (fn: Function) => {
|
promisify: (fn: Function) => {
|
||||||
return (...args: any[]) => {
|
return (...args: any[]) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fn(...args, (err: Error | null, stdout: unknown, stderr: unknown) => {
|
fn(...args, (err: Error | null, stdout: string, stderr: string) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
// Attach stdout/stderr to the error object to mimic child_process.exec behavior
|
// Attach stdout/stderr to the error object to mimic child_process.exec behavior
|
||||||
Object.assign(err, { stdout, stderr });
|
Object.assign(err, { stdout, stderr });
|
||||||
@@ -41,7 +40,6 @@ vi.mock('child_process', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
default: { exec: mockExec },
|
|
||||||
exec: mockExec,
|
exec: mockExec,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -127,12 +127,21 @@ describe('AnalyticsService', () => {
|
|||||||
throw new Error('Processing failed');
|
throw new Error('Processing failed');
|
||||||
}); // "Successfully generated..."
|
}); // "Successfully generated..."
|
||||||
|
|
||||||
const promise = service.processWeeklyReportJob(job);
|
// Wrap the async operation that is expected to reject in a function.
|
||||||
|
// This prevents an "unhandled rejection" error by ensuring the `expect.rejects`
|
||||||
|
// is actively waiting for the promise to reject when the timers are advanced.
|
||||||
|
const testFunction = async () => {
|
||||||
|
const promise = service.processWeeklyReportJob(job);
|
||||||
|
// Advance timers to trigger the part of the code that throws.
|
||||||
|
await vi.advanceTimersByTimeAsync(30000);
|
||||||
|
// Await the promise to allow the rejection to be caught by `expect.rejects`.
|
||||||
|
await promise;
|
||||||
|
};
|
||||||
|
|
||||||
await vi.advanceTimersByTimeAsync(30000);
|
// Now, assert that the entire operation rejects as expected.
|
||||||
|
await expect(testFunction()).rejects.toThrow('Processing failed');
|
||||||
await expect(promise).rejects.toThrow('Processing failed');
|
|
||||||
|
|
||||||
|
// Verify the side effect (error logging) after the rejection is confirmed.
|
||||||
expect(mockLoggerInstance.error).toHaveBeenCalledWith(
|
expect(mockLoggerInstance.error).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
err: expect.any(Error),
|
err: expect.any(Error),
|
||||||
|
|||||||
@@ -1,70 +1,16 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||||
|
|
||||||
// Set environment variables before importing the service
|
|
||||||
process.env.JWT_SECRET = 'test-secret';
|
|
||||||
process.env.FRONTEND_URL = 'http://localhost:3000';
|
|
||||||
|
|
||||||
import { authService } from './authService';
|
|
||||||
import * as bcrypt from 'bcrypt';
|
|
||||||
import jwt from 'jsonwebtoken';
|
|
||||||
import crypto from 'crypto';
|
|
||||||
import { userRepo, adminRepo } from './db/index.db';
|
|
||||||
import { UniqueConstraintError } from './db/errors.db';
|
import { UniqueConstraintError } from './db/errors.db';
|
||||||
import { logger } from './logger.server';
|
|
||||||
import { sendPasswordResetEmail } from './emailService.server';
|
|
||||||
import type { UserProfile } from '../types';
|
import type { UserProfile } from '../types';
|
||||||
|
|
||||||
// Mock dependencies
|
|
||||||
vi.mock('bcrypt');
|
|
||||||
vi.mock('jsonwebtoken');
|
|
||||||
vi.mock('crypto', () => ({
|
|
||||||
default: {
|
|
||||||
randomBytes: vi.fn().mockReturnValue({
|
|
||||||
toString: vi.fn().mockReturnValue('mocked-random-string'),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock('./db/index.db', () => ({
|
|
||||||
userRepo: {
|
|
||||||
createUser: vi.fn(),
|
|
||||||
saveRefreshToken: vi.fn(),
|
|
||||||
findUserByEmail: vi.fn(),
|
|
||||||
createPasswordResetToken: vi.fn(),
|
|
||||||
getValidResetTokens: vi.fn(),
|
|
||||||
updateUserPassword: vi.fn(),
|
|
||||||
deleteResetToken: vi.fn(),
|
|
||||||
findUserByRefreshToken: vi.fn(),
|
|
||||||
findUserProfileById: vi.fn(),
|
|
||||||
deleteRefreshToken: vi.fn(),
|
|
||||||
},
|
|
||||||
adminRepo: {
|
|
||||||
logActivity: vi.fn(),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock('./logger.server', () => ({
|
|
||||||
logger: {
|
|
||||||
info: vi.fn(),
|
|
||||||
error: vi.fn(),
|
|
||||||
warn: vi.fn(),
|
|
||||||
debug: vi.fn(),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock('./emailService.server', () => ({
|
|
||||||
sendPasswordResetEmail: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock('./db/connection.db', () => ({
|
|
||||||
getPool: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock('../utils/authUtils', () => ({
|
|
||||||
validatePasswordStrength: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('AuthService', () => {
|
describe('AuthService', () => {
|
||||||
|
let authService: typeof import('./authService').authService;
|
||||||
|
let bcrypt: typeof import('bcrypt');
|
||||||
|
let jwt: typeof import('jsonwebtoken');
|
||||||
|
let userRepo: typeof import('./db/index.db').userRepo;
|
||||||
|
let adminRepo: typeof import('./db/index.db').adminRepo;
|
||||||
|
let logger: typeof import('./logger.server').logger;
|
||||||
|
let sendPasswordResetEmail: typeof import('./emailService.server').sendPasswordResetEmail;
|
||||||
|
|
||||||
const reqLog = {}; // Mock request logger object
|
const reqLog = {}; // Mock request logger object
|
||||||
const mockUser = {
|
const mockUser = {
|
||||||
user_id: 'user-123',
|
user_id: 'user-123',
|
||||||
@@ -76,8 +22,59 @@ describe('AuthService', () => {
|
|||||||
role: 'user',
|
role: 'user',
|
||||||
} as unknown as UserProfile;
|
} as unknown as UserProfile;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(async () => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
|
vi.resetModules();
|
||||||
|
|
||||||
|
// Set environment variables before any modules are imported
|
||||||
|
process.env.JWT_SECRET = 'test-secret';
|
||||||
|
process.env.FRONTEND_URL = 'http://localhost:3000';
|
||||||
|
|
||||||
|
// Mock all dependencies before dynamically importing the service
|
||||||
|
vi.mock('bcrypt');
|
||||||
|
vi.mock('jsonwebtoken');
|
||||||
|
vi.mock('crypto', () => ({
|
||||||
|
default: {
|
||||||
|
randomBytes: vi.fn().mockReturnValue({
|
||||||
|
toString: vi.fn().mockReturnValue('mocked-random-string'),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
vi.mock('./db/index.db', () => ({
|
||||||
|
userRepo: {
|
||||||
|
createUser: vi.fn(),
|
||||||
|
saveRefreshToken: vi.fn(),
|
||||||
|
findUserByEmail: vi.fn(),
|
||||||
|
createPasswordResetToken: vi.fn(),
|
||||||
|
getValidResetTokens: vi.fn(),
|
||||||
|
updateUserPassword: vi.fn(),
|
||||||
|
deleteResetToken: vi.fn(),
|
||||||
|
findUserByRefreshToken: vi.fn(),
|
||||||
|
findUserProfileById: vi.fn(),
|
||||||
|
deleteRefreshToken: vi.fn(),
|
||||||
|
},
|
||||||
|
adminRepo: {
|
||||||
|
logActivity: vi.fn(),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
vi.mock('./logger.server', () => ({
|
||||||
|
logger: { info: vi.fn(), error: vi.fn(), warn: vi.fn(), debug: vi.fn() },
|
||||||
|
}));
|
||||||
|
vi.mock('./emailService.server', () => ({
|
||||||
|
sendPasswordResetEmail: vi.fn(),
|
||||||
|
}));
|
||||||
|
vi.mock('./db/connection.db', () => ({ getPool: vi.fn() }));
|
||||||
|
vi.mock('../utils/authUtils', () => ({ validatePasswordStrength: vi.fn() }));
|
||||||
|
|
||||||
|
// Dynamically import modules to get the mocked versions and the service instance
|
||||||
|
authService = (await import('./authService')).authService;
|
||||||
|
bcrypt = await import('bcrypt');
|
||||||
|
jwt = await import('jsonwebtoken');
|
||||||
|
const dbModule = await import('./db/index.db');
|
||||||
|
userRepo = dbModule.userRepo;
|
||||||
|
adminRepo = dbModule.adminRepo;
|
||||||
|
logger = (await import('./logger.server')).logger;
|
||||||
|
sendPasswordResetEmail = (await import('./emailService.server')).sendPasswordResetEmail;
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('registerUser', () => {
|
describe('registerUser', () => {
|
||||||
|
|||||||
@@ -242,7 +242,10 @@ export class FlyerProcessingService {
|
|||||||
// Mark subsequent critical stages as skipped
|
// Mark subsequent critical stages as skipped
|
||||||
for (let i = errorStageIndex + 1; i < stagesToReport.length; i++) {
|
for (let i = errorStageIndex + 1; i < stagesToReport.length; i++) {
|
||||||
if (stagesToReport[i].critical) {
|
if (stagesToReport[i].critical) {
|
||||||
stagesToReport[i] = { ...stagesToReport[i], status: 'skipped' };
|
// When a stage is skipped, we don't need its previous 'detail' property.
|
||||||
|
// This creates a clean 'skipped' state object by removing `detail` and keeping the rest.
|
||||||
|
const { detail, ...restOfStage } = stagesToReport[i];
|
||||||
|
stagesToReport[i] = { ...restOfStage, status: 'skipped' };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// src/services/systemService.test.ts
|
||||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||||
import { exec, type ExecException } from 'child_process';
|
import { exec, type ExecException } from 'child_process';
|
||||||
import { logger } from './logger.server';
|
import { logger } from './logger.server';
|
||||||
@@ -35,10 +36,11 @@ vi.mock('util', async (importOriginal) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Mock child_process
|
// Mock child_process
|
||||||
vi.mock('child_process', () => {
|
vi.mock('child_process', async (importOriginal) => {
|
||||||
const mockExec = vi.fn();
|
const actual = await importOriginal<typeof import('child_process')>();
|
||||||
return {
|
return {
|
||||||
exec: mockExec,
|
...actual,
|
||||||
|
exec: vi.fn(),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user