debugging the flyer integration issue
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 27m54s
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 27m54s
This commit is contained in:
@@ -63,7 +63,7 @@ export class FlyerRepository {
|
|||||||
* @returns The newly created flyer record with its ID.
|
* @returns The newly created flyer record with its ID.
|
||||||
*/
|
*/
|
||||||
async insertFlyer(flyerData: FlyerDbInsert, logger: Logger): Promise<Flyer> {
|
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 {
|
try {
|
||||||
const query = `
|
const query = `
|
||||||
INSERT INTO flyers (
|
INSERT INTO flyers (
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import { cleanupFiles } from '../utils/cleanupFiles';
|
|||||||
import piexif from 'piexifjs';
|
import piexif from 'piexifjs';
|
||||||
import exifParser from 'exif-parser';
|
import exifParser from 'exif-parser';
|
||||||
import sharp from 'sharp';
|
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(),
|
mockExtractCoreData: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Mock the AI service to prevent real API calls during integration tests.
|
// REMOVED: vi.mock('../../services/aiService.server', ...)
|
||||||
// This is crucial for making the tests reliable and fast. We don't want to
|
// The previous mock was not effectively intercepting the singleton instance used by the worker.
|
||||||
// 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;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Mock the main DB service to allow for simulating transaction failures.
|
// Mock the main DB service to allow for simulating transaction failures.
|
||||||
// By default, it will use the real implementation.
|
// 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');
|
vi.stubEnv('FRONTEND_URL', 'https://example.com');
|
||||||
console.log('[TEST SETUP] FRONTEND_URL stubbed to:', process.env.FRONTEND_URL);
|
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 appModule = await import('../../../server');
|
||||||
const app = appModule.default;
|
const app = appModule.default;
|
||||||
request = supertest(app);
|
request = supertest(app);
|
||||||
@@ -72,9 +70,9 @@ describe('Flyer Processing Background Job Integration Test', () => {
|
|||||||
mockExtractCoreData.mockReset();
|
mockExtractCoreData.mockReset();
|
||||||
mockExtractCoreData.mockResolvedValue({
|
mockExtractCoreData.mockResolvedValue({
|
||||||
store_name: 'Mock Store',
|
store_name: 'Mock Store',
|
||||||
valid_from: null,
|
valid_from: '2025-01-01',
|
||||||
valid_to: null,
|
valid_to: '2025-01-07',
|
||||||
store_address: null,
|
store_address: '123 Mock St',
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
item: 'Mocked Integration Item',
|
item: 'Mocked Integration Item',
|
||||||
@@ -96,6 +94,7 @@ describe('Flyer Processing Background Job Integration Test', () => {
|
|||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
vi.unstubAllEnvs(); // Clean up env stubs
|
vi.unstubAllEnvs(); // Clean up env stubs
|
||||||
|
vi.restoreAllMocks(); // Restore the AI spy
|
||||||
|
|
||||||
// Use the centralized cleanup utility.
|
// Use the centralized cleanup utility.
|
||||||
await cleanupDb({
|
await cleanupDb({
|
||||||
@@ -395,6 +394,7 @@ it(
|
|||||||
async () => {
|
async () => {
|
||||||
// Arrange: Mock the AI service to throw an error for this specific test.
|
// Arrange: Mock the AI service to throw an error for this specific test.
|
||||||
const aiError = new Error('AI model failed to extract data.');
|
const aiError = new Error('AI model failed to extract data.');
|
||||||
|
// Update the spy implementation to reject
|
||||||
mockExtractCoreData.mockRejectedValue(aiError);
|
mockExtractCoreData.mockRejectedValue(aiError);
|
||||||
|
|
||||||
// Arrange: Prepare a unique flyer file for upload.
|
// Arrange: Prepare a unique flyer file for upload.
|
||||||
|
|||||||
Reference in New Issue
Block a user