Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c25b79251 | ||
| 0b0fa8294d |
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "flyer-crawler",
|
||||
"version": "0.9.44",
|
||||
"version": "0.9.45",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "flyer-crawler",
|
||||
"version": "0.9.44",
|
||||
"version": "0.9.45",
|
||||
"dependencies": {
|
||||
"@bull-board/api": "^6.14.2",
|
||||
"@bull-board/express": "^6.14.2",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "flyer-crawler",
|
||||
"private": true,
|
||||
"version": "0.9.44",
|
||||
"version": "0.9.45",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "concurrently \"npm:start:dev\" \"vite\"",
|
||||
|
||||
@@ -63,7 +63,7 @@ export class FlyerRepository {
|
||||
* @returns The newly created flyer record with its ID.
|
||||
*/
|
||||
async insertFlyer(flyerData: FlyerDbInsert, logger: Logger): Promise<Flyer> {
|
||||
console.log('[DEBUG] FlyerRepository.insertFlyer called with:', JSON.stringify(flyerData, null, 2));
|
||||
console.error('[DEBUG] FlyerRepository.insertFlyer called with:', JSON.stringify(flyerData, null, 2));
|
||||
try {
|
||||
const query = `
|
||||
INSERT INTO flyers (
|
||||
|
||||
@@ -15,6 +15,8 @@ import { cleanupFiles } from '../utils/cleanupFiles';
|
||||
import piexif from 'piexifjs';
|
||||
import exifParser from 'exif-parser';
|
||||
import sharp from 'sharp';
|
||||
// FIX: Import the singleton instance directly to spy on it
|
||||
import { aiService } from '../../services/aiService.server';
|
||||
|
||||
|
||||
/**
|
||||
@@ -25,16 +27,8 @@ const { mockExtractCoreData } = vi.hoisted(() => ({
|
||||
mockExtractCoreData: vi.fn(),
|
||||
}));
|
||||
|
||||
// Mock the AI service to prevent real API calls during integration tests.
|
||||
// This is crucial for making the tests reliable and fast. We don't want to
|
||||
// depend on the external Gemini API.
|
||||
vi.mock('../../services/aiService.server', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('../../services/aiService.server')>();
|
||||
// To preserve the class instance methods of `aiService`, we must modify the
|
||||
// instance directly rather than creating a new plain object with spread syntax.
|
||||
actual.aiService.extractCoreDataFromFlyerImage = mockExtractCoreData;
|
||||
return actual;
|
||||
});
|
||||
// REMOVED: vi.mock('../../services/aiService.server', ...)
|
||||
// The previous mock was not effectively intercepting the singleton instance used by the worker.
|
||||
|
||||
// Mock the main DB service to allow for simulating transaction failures.
|
||||
// By default, it will use the real implementation.
|
||||
@@ -59,6 +53,10 @@ describe('Flyer Processing Background Job Integration Test', () => {
|
||||
vi.stubEnv('FRONTEND_URL', 'https://example.com');
|
||||
console.log('[TEST SETUP] FRONTEND_URL stubbed to:', process.env.FRONTEND_URL);
|
||||
|
||||
// FIX: Spy on the actual singleton instance. This ensures that when the worker
|
||||
// imports 'aiService', it gets the instance we are controlling here.
|
||||
vi.spyOn(aiService, 'extractCoreDataFromFlyerImage').mockImplementation(mockExtractCoreData);
|
||||
|
||||
const appModule = await import('../../../server');
|
||||
const app = appModule.default;
|
||||
request = supertest(app);
|
||||
@@ -72,9 +70,9 @@ describe('Flyer Processing Background Job Integration Test', () => {
|
||||
mockExtractCoreData.mockReset();
|
||||
mockExtractCoreData.mockResolvedValue({
|
||||
store_name: 'Mock Store',
|
||||
valid_from: null,
|
||||
valid_to: null,
|
||||
store_address: null,
|
||||
valid_from: '2025-01-01',
|
||||
valid_to: '2025-01-07',
|
||||
store_address: '123 Mock St',
|
||||
items: [
|
||||
{
|
||||
item: 'Mocked Integration Item',
|
||||
@@ -96,6 +94,7 @@ describe('Flyer Processing Background Job Integration Test', () => {
|
||||
|
||||
afterAll(async () => {
|
||||
vi.unstubAllEnvs(); // Clean up env stubs
|
||||
vi.restoreAllMocks(); // Restore the AI spy
|
||||
|
||||
// Use the centralized cleanup utility.
|
||||
await cleanupDb({
|
||||
@@ -395,6 +394,7 @@ it(
|
||||
async () => {
|
||||
// Arrange: Mock the AI service to throw an error for this specific test.
|
||||
const aiError = new Error('AI model failed to extract data.');
|
||||
// Update the spy implementation to reject
|
||||
mockExtractCoreData.mockRejectedValue(aiError);
|
||||
|
||||
// Arrange: Prepare a unique flyer file for upload.
|
||||
|
||||
Reference in New Issue
Block a user