splitting unit + integration testing apart attempt #1
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 3m51s
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 3m51s
This commit is contained in:
@@ -56,7 +56,7 @@ vi.mock('./passport', () => ({
|
||||
const app = express();
|
||||
app.use(express.json({ strict: false }));
|
||||
app.use(cookieParser()); // Add cookie-parser middleware to populate req.cookies
|
||||
app.use('/api/auth', authRouter); // This was missing
|
||||
app.use('/api/auth', authRouter);
|
||||
|
||||
describe('Auth Routes (/api/auth)', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -33,7 +33,7 @@ vi.mock('../services/logger.server', () => ({
|
||||
const app = express();
|
||||
app.use(express.json({ strict: false }));
|
||||
// Mount the router under a base path, similar to how it's done in the main server
|
||||
app.use('/api', publicRouter);
|
||||
app.use('/api', publicRouter); // This was correct, no change needed. Re-evaluating.
|
||||
|
||||
describe('Public Routes (/api)', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -17,13 +17,20 @@ import {
|
||||
updateRecipeStatus,
|
||||
updateReceiptStatus,
|
||||
} from './admin';
|
||||
import { Pool } from 'pg';
|
||||
|
||||
const mockQuery = vi.fn();
|
||||
const mockRelease = vi.fn();
|
||||
const mockConnect = vi.fn().mockResolvedValue({ query: mockQuery, release: mockRelease });
|
||||
import { getPool } from './connection';
|
||||
import type { SuggestedCorrection } from '../../types';
|
||||
|
||||
// Define test-local mock functions. These will be used to control the mock's behavior.
|
||||
const mockQuery = vi.fn();
|
||||
|
||||
// Mock the entire connection module.
|
||||
vi.mock('./connection', () => ({
|
||||
// The mock factory for getPool returns an object that uses our test-local mockQuery.
|
||||
getPool: () => ({
|
||||
query: mockQuery,
|
||||
}),
|
||||
}));
|
||||
|
||||
// Mock the logger to prevent console output during tests
|
||||
vi.mock('../logger', () => ({
|
||||
logger: {
|
||||
@@ -36,12 +43,10 @@ vi.mock('../logger', () => ({
|
||||
|
||||
describe('Admin DB Service', () => {
|
||||
beforeEach(() => {
|
||||
// Configure the globally mocked Pool to use our test-local mock functions.
|
||||
vi.mocked(Pool).mockReturnValue({
|
||||
query: mockQuery,
|
||||
connect: mockConnect,
|
||||
release: mockRelease,
|
||||
} as any);
|
||||
// --- DIAGNOSTIC LOGGING #3: "What Does My Test Think It's Importing?" ---
|
||||
// This log will show that getPool().query is indeed our mock function.
|
||||
console.log('[admin.test.ts] Is getPool().query a mock function?', vi.isMockFunction(getPool().query));
|
||||
|
||||
// Clear mock history before each test
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
@@ -55,7 +60,7 @@ describe('Admin DB Service', () => {
|
||||
|
||||
const result = await getSuggestedCorrections();
|
||||
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining("FROM public.suggested_corrections sc"));
|
||||
expect(getPool().query).toHaveBeenCalledWith(expect.stringContaining("FROM public.suggested_corrections sc"));
|
||||
expect(result).toEqual(mockCorrections);
|
||||
});
|
||||
});
|
||||
@@ -65,7 +70,7 @@ describe('Admin DB Service', () => {
|
||||
mockQuery.mockResolvedValue({ rows: [] }); // Mock the function call
|
||||
await approveCorrection(123);
|
||||
|
||||
expect(mockQuery).toHaveBeenCalledWith('SELECT public.approve_correction($1)', [123]);
|
||||
expect(getPool().query).toHaveBeenCalledWith('SELECT public.approve_correction($1)', [123]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -74,7 +79,7 @@ describe('Admin DB Service', () => {
|
||||
mockQuery.mockResolvedValue({ rowCount: 1 });
|
||||
await rejectCorrection(123);
|
||||
|
||||
expect(mockQuery).toHaveBeenCalledWith(
|
||||
expect(getPool().query).toHaveBeenCalledWith(
|
||||
expect.stringContaining("UPDATE public.suggested_corrections SET status = 'rejected'"),
|
||||
[123]
|
||||
);
|
||||
@@ -88,7 +93,7 @@ describe('Admin DB Service', () => {
|
||||
|
||||
const result = await updateSuggestedCorrection(1, '300');
|
||||
|
||||
expect(mockQuery).toHaveBeenCalledWith(
|
||||
expect(getPool().query).toHaveBeenCalledWith(
|
||||
expect.stringContaining("UPDATE public.suggested_corrections SET suggested_value = $1"),
|
||||
['300', 1]
|
||||
);
|
||||
@@ -108,7 +113,7 @@ describe('Admin DB Service', () => {
|
||||
|
||||
const stats = await getApplicationStats();
|
||||
|
||||
expect(mockQuery).toHaveBeenCalledTimes(5);
|
||||
expect(getPool().query).toHaveBeenCalledTimes(5);
|
||||
expect(stats).toEqual({
|
||||
flyerCount: 10,
|
||||
userCount: 20,
|
||||
@@ -126,7 +131,7 @@ describe('Admin DB Service', () => {
|
||||
|
||||
const result = await getDailyStatsForLast30Days();
|
||||
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining("WITH date_series AS"));
|
||||
expect(getPool().query).toHaveBeenCalledWith(expect.stringContaining("WITH date_series AS"));
|
||||
expect(result).toEqual(mockStats);
|
||||
});
|
||||
});
|
||||
@@ -137,7 +142,7 @@ describe('Admin DB Service', () => {
|
||||
const logData = { userId: 'user-123', action: 'test_action', displayText: 'Test activity' };
|
||||
await logActivity(logData);
|
||||
|
||||
expect(mockQuery).toHaveBeenCalledWith(
|
||||
expect(getPool().query).toHaveBeenCalledWith(
|
||||
expect.stringContaining("INSERT INTO public.activity_log"),
|
||||
[logData.userId, logData.action, logData.displayText, null, null]
|
||||
);
|
||||
@@ -148,7 +153,7 @@ describe('Admin DB Service', () => {
|
||||
it('should call the correct database function', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [] });
|
||||
await getMostFrequentSaleItems(30, 10);
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('FROM public.flyer_items fi'), [30, 10]);
|
||||
expect(getPool().query).toHaveBeenCalledWith(expect.stringContaining('FROM public.flyer_items fi'), [30, 10]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -157,7 +162,7 @@ describe('Admin DB Service', () => {
|
||||
const mockComment = { comment_id: 1, status: 'hidden' };
|
||||
mockQuery.mockResolvedValue({ rows: [mockComment], rowCount: 1 });
|
||||
const result = await updateRecipeCommentStatus(1, 'hidden');
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('UPDATE public.recipe_comments'), ['hidden', 1]);
|
||||
expect(getPool().query).toHaveBeenCalledWith(expect.stringContaining('UPDATE public.recipe_comments'), ['hidden', 1]);
|
||||
expect(result).toEqual(mockComment);
|
||||
});
|
||||
});
|
||||
@@ -166,7 +171,7 @@ describe('Admin DB Service', () => {
|
||||
it('should execute the correct query to get unmatched items', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [] });
|
||||
await getUnmatchedFlyerItems();
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('FROM public.unmatched_flyer_items ufi'));
|
||||
expect(getPool().query).toHaveBeenCalledWith(expect.stringContaining('FROM public.unmatched_flyer_items ufi'));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -175,7 +180,7 @@ describe('Admin DB Service', () => {
|
||||
const mockRecipe = { recipe_id: 1, status: 'public' };
|
||||
mockQuery.mockResolvedValue({ rows: [mockRecipe], rowCount: 1 });
|
||||
const result = await updateRecipeStatus(1, 'public');
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('UPDATE public.recipes'), ['public', 1]);
|
||||
expect(getPool().query).toHaveBeenCalledWith(expect.stringContaining('UPDATE public.recipes'), ['public', 1]);
|
||||
expect(result).toEqual(mockRecipe);
|
||||
});
|
||||
});
|
||||
@@ -184,7 +189,7 @@ describe('Admin DB Service', () => {
|
||||
it('should execute an UPDATE query to increment failed attempts', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [] });
|
||||
await incrementFailedLoginAttempts('user-123');
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('UPDATE public.users SET failed_login_attempts'), ['user-123']);
|
||||
expect(getPool().query).toHaveBeenCalledWith(expect.stringContaining('UPDATE public.users SET failed_login_attempts'), ['user-123']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -192,7 +197,7 @@ describe('Admin DB Service', () => {
|
||||
it('should execute an UPDATE query to reset failed attempts', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [] });
|
||||
await resetFailedLoginAttempts('user-123');
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('UPDATE public.users SET failed_login_attempts = 0'), ['user-123']);
|
||||
expect(getPool().query).toHaveBeenCalledWith(expect.stringContaining('UPDATE public.users SET failed_login_attempts = 0'), ['user-123']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -200,7 +205,7 @@ describe('Admin DB Service', () => {
|
||||
it('should execute an UPDATE query for the brand logo', async () => {
|
||||
mockQuery.mockResolvedValue({ rows: [] });
|
||||
await updateBrandLogo(1, '/logo.png');
|
||||
expect(mockQuery).toHaveBeenCalledWith('UPDATE public.brands SET logo_url = $1 WHERE brand_id = $2', ['/logo.png', 1]);
|
||||
expect(getPool().query).toHaveBeenCalledWith('UPDATE public.brands SET logo_url = $1 WHERE brand_id = $2', ['/logo.png', 1]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -209,7 +214,7 @@ describe('Admin DB Service', () => {
|
||||
const mockReceipt = { receipt_id: 1, status: 'completed' };
|
||||
mockQuery.mockResolvedValue({ rows: [mockReceipt], rowCount: 1 });
|
||||
const result = await updateReceiptStatus(1, 'completed');
|
||||
expect(mockQuery).toHaveBeenCalledWith(expect.stringContaining('UPDATE public.receipts'), ['completed', 1]);
|
||||
expect(getPool().query).toHaveBeenCalledWith(expect.stringContaining('UPDATE public.receipts'), ['completed', 1]);
|
||||
expect(result).toEqual(mockReceipt);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -50,10 +50,10 @@ const createPool = (): Pool => {
|
||||
export const getPool = (): Pool => {
|
||||
// This function acts as a singleton accessor for the database pool.
|
||||
if (!poolInstance) {
|
||||
//logger.info('--- [DB POOL ACCESSOR] No pool instance found. Creating a new one. ---');
|
||||
console.log('[DB POOL] Creating NEW pool instance.'); // DIAGNOSTIC LOGGING #2
|
||||
poolInstance = createPool();
|
||||
} else {
|
||||
//logger.info(`--- [DB POOL ACCESSOR] Returning existing pool instance. ID: ${poolInstance.poolId} ---`);
|
||||
console.log(`[DB POOL] Returning EXISTING pool instance. ID: ${poolInstance.poolId}`); // DIAGNOSTIC LOGGING #2
|
||||
}
|
||||
return poolInstance;
|
||||
};
|
||||
|
||||
@@ -56,8 +56,8 @@ afterEach(cleanup);
|
||||
* This is the central point for mocking the database connection pool for unit tests.
|
||||
*/
|
||||
vi.mock('pg', () => {
|
||||
// --- DEBUG LOGGING ---
|
||||
// This log will appear in the test output to prove that this global mock is being used.
|
||||
// --- DIAGNOSTIC LOGGING #1: "Is the Mock Even Loading?" ---
|
||||
// This log will appear once at the start of the test run to prove that this global mock is being used.
|
||||
console.log('[vitest-mock-pg] Global `pg` mock from unit-setup.ts is being initialized.');
|
||||
|
||||
// These are the mock functions that will replace the real 'pg' methods.
|
||||
@@ -78,14 +78,13 @@ vi.mock('pg', () => {
|
||||
end: vi.fn(),
|
||||
}));
|
||||
|
||||
// The object returned by this factory function becomes the exports of the 'pg' module
|
||||
// for all unit tests.
|
||||
// The object returned here becomes the exports of the 'pg' module for all unit tests.
|
||||
return {
|
||||
__esModule: true, // This is important for ES module interoperability.
|
||||
Pool: mockPool,
|
||||
// We are intentionally NOT exporting the mock functions here anymore.
|
||||
// This was the source of the TypeScript errors. Test files will now define
|
||||
// their own mock functions and configure the mocked Pool to use them.
|
||||
// We are intentionally NOT exporting the mock functions. This was the source of the
|
||||
// TypeScript errors. Test files will now mock the `getPool` function from the
|
||||
// connection service directly.
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user