lootsa tests fixes
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 4m29s

This commit is contained in:
2025-12-05 18:56:08 -08:00
parent e07b0c6ae4
commit 57ea82a8ad
7 changed files with 149 additions and 10 deletions

View File

@@ -84,19 +84,25 @@ describe('App Component', () => {
});
it('should render the BulkImporter for an admin user', async () => {
// FIX 4: Update the BulkImporter test case to simulate an admin user
const mockAdminProfile = {
user_id: 'admin-id',
user: { user_id: 'admin-id', email: 'admin@example.com' },
role: 'admin',
full_name: 'Admin',
avatar_url: '',
};
// Mock the response to return the admin profile
mockedApiClient.getAuthenticatedUserProfile.mockResolvedValue(new Response(JSON.stringify(mockAdminProfile)));
// Set the token to trigger the auth check effect
localStorage.setItem('authToken', 'fake-admin-token');
renderApp();
// Wait for the header (which means app loaded) AND the bulk importer
await waitFor(() => {
expect(screen.getByTestId('header-mock')).toBeInTheDocument();
expect(screen.getByTestId('flyer-list-mock')).toBeInTheDocument();
expect(screen.getByTestId('bulk-importer-mock')).toBeInTheDocument();
});
});

View File

@@ -1,4 +1,4 @@
// src/routes/budget.test.ts
// src/routes/budget.routes.test.ts
import { describe, it, expect, vi, beforeEach } from 'vitest';
import supertest from 'supertest';
import express, { Request, Response, NextFunction } from 'express';
@@ -51,7 +51,7 @@ app.use(express.json());
app.use('/api/budgets', budgetRouter);
// Add a basic error handler to return JSON errors instead of Express default HTML
app.use((err: Error, req: Request, res: Response) => {
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
res.status(500).json({ message: 'Internal Server Error' });
});

View File

@@ -6,10 +6,12 @@ import systemRouter from './system.routes';
import { exec } from 'child_process';
import { geocodeAddress } from '../services/geocodingService.server';
// 1. Mock child_process simply and robustly
vi.mock('child_process', () => ({
exec: vi.fn((cmd, cb) => {
cb(null, 'PM2 OK', '');
// FIX 3: Mock child_process simply and robustly using the async factory pattern
vi.mock('child_process', async () => ({
exec: vi.fn((command, callback) => {
if (typeof callback === 'function') {
callback(null, 'PM2 OK', '');
}
return { unref: () => {} };
})
}));

View File

@@ -1,3 +1,4 @@
// src/routes/user.routes.test.ts
import { describe, it, expect, vi, beforeEach } from 'vitest';
import supertest from 'supertest';
import express from 'express';
@@ -20,6 +21,9 @@ vi.mock('../services/db/user.db', () => ({
updateUserPreferences: vi.fn(),
getAddressById: vi.fn(),
upsertAddress: vi.fn(),
findUserById: vi.fn(),
findUserByEmail: vi.fn(),
createUser: vi.fn(),
}));
vi.mock('../services/db/personalization.db', () => ({
getWatchedItems: vi.fn(),

View File

@@ -1,6 +1,10 @@
// src/services/db/gamification.db.test.ts
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { mockPoolInstance } from '../../tests/setup/tests-setup-unit';
// FIX 2: Un-mock the module we are testing.
vi.unmock('./gamification.db');
import {
getAllAchievements,
getUserAchievements,

122
src/services/db/temp.ts Normal file
View File

@@ -0,0 +1,122 @@
// src/routes/system.routes.test.ts
import { describe, it, expect, vi, beforeEach } from 'vitest';
import supertest from 'supertest';
import express from 'express';
import systemRouter from './system.routes';
import { exec } from 'child_process';
import { geocodeAddress } from '../services/geocodingService.server';
// FIX 3: Mock child_process simply and robustly using the async factory pattern
vi.mock('child_process', async () => ({
exec: vi.fn((command, callback) => {
if (typeof callback === 'function') {
callback(null, 'PM2 OK', '');
}
return { unref: () => {} };
})
}));
vi.mock('../services/geocodingService.server', () => ({
geocodeAddress: vi.fn()
}));
vi.mock('../services/logger.server', () => ({
logger: {
info: vi.fn(),
debug: vi.fn(),
error: vi.fn(),
warn: vi.fn(),
},
}));
const app = express();
app.use(express.json());
app.use('/api/system', systemRouter);
describe('System Routes (/api/system)', () => {
beforeEach(() => {
vi.clearAllMocks();
});
describe('GET /pm2-status', () => {
it('should return success: true when pm2 process is online', async () => {
const pm2OnlineOutput = `
┌─ PM2 info ────────────────┐
│ status │ online │
└───────────┴───────────┘
`;
vi.mocked(exec).mockImplementation((...args: any[]) => {
const callback = args.find(arg => typeof arg === 'function');
callback(null, pm2OnlineOutput, '');
return {} as any;
});
const response = await supertest(app).get('/api/system/pm2-status');
expect(response.status).toBe(200);
expect(response.body).toEqual({ success: true, message: 'Application is online and running under PM2.' });
});
// ... other tests (restored from previous fix attempt)
it('should return success: false when pm2 process is stopped', async () => {
const pm2StoppedOutput = `│ status │ stopped │`;
vi.mocked(exec).mockImplementation((...args: any[]) => {
const callback = args.find(arg => typeof arg === 'function');
callback(null, pm2StoppedOutput, '');
return {} as any;
});
const response = await supertest(app).get('/api/system/pm2-status');
expect(response.status).toBe(200);
expect(response.body.success).toBe(false);
});
it('should return success: false when pm2 process does not exist', async () => {
vi.mocked(exec).mockImplementation((...args: any[]) => {
const callback = args.find(arg => typeof arg === 'function');
callback(new Error('Command failed'), "[PM2][ERROR] Process doesn't exist", '');
return {} as any;
});
const response = await supertest(app).get('/api/system/pm2-status');
expect(response.status).toBe(200);
expect(response.body.success).toBe(false);
});
it('should return 500 on a generic exec error', async () => {
vi.mocked(exec).mockImplementation((...args: any[]) => {
const callback = args.find(arg => typeof arg === 'function');
callback(new Error('System error'), '', 'stderr output');
return {} as any;
});
const response = await supertest(app).get('/api/system/pm2-status');
expect(response.status).toBe(500);
});
});
describe('POST /geocode', () => {
it('should return geocoded coordinates for a valid address', async () => {
const mockCoordinates = { lat: 48.4284, lng: -123.3656 };
vi.mocked(geocodeAddress).mockResolvedValue(mockCoordinates);
const response = await supertest(app)
.post('/api/system/geocode')
.send({ address: 'Victoria, BC' });
expect(response.status).toBe(200);
expect(response.body).toEqual(mockCoordinates);
});
it('should return 404 if the address cannot be geocoded', async () => {
vi.mocked(geocodeAddress).mockResolvedValue(null);
const response = await supertest(app)
.post('/api/system/geocode')
.send({ address: 'Invalid Address' });
expect(response.status).toBe(404);
});
});
});

View File

@@ -1,7 +1,7 @@
// src/services/db/user.db.test.ts
import { describe, it, expect, vi, beforeEach } from 'vitest';
// Un-mock the module we are testing to ensure we use the real implementation.
// FIX 2: Un-mock the module we are testing to ensure we use the real implementation.
vi.unmock('./user.db');
import {
@@ -25,14 +25,15 @@ import {
getUserFeed,
logSearchQuery,
} from './user.db';
import { mockPoolInstance } from '../../tests/setup/tests-setup-unit';
import type { Profile } from '../../types';
// Mock other db services that are used by functions in user.db.ts
vi.mock('./shopping', () => ({
vi.mock('./shopping.db', () => ({
getShoppingLists: vi.fn(),
}));
vi.mock('./personalization', () => ({
vi.mock('./personalization.db', () => ({
getWatchedItems: vi.fn(),
}));