unit tests fixin
Some checks failed
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Failing after 36s
Some checks failed
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Failing after 36s
This commit is contained in:
@@ -4,11 +4,10 @@
|
||||
* The `.server.ts` naming convention helps enforce this separation.
|
||||
*/
|
||||
|
||||
import { GoogleGenAI, Type } from '@google/genai';
|
||||
import { GoogleGenAI } from '@google/genai';
|
||||
import fs from 'fs/promises';
|
||||
import { logger } from './logger';
|
||||
import { parsePriceToCents } from '../utils/priceParser';
|
||||
import type { FlyerItem, MasterGroceryItem, RawFlyerItem } from '../types';
|
||||
import type { FlyerItem, MasterGroceryItem } from '../types';
|
||||
|
||||
// Use the secure, server-side API key.
|
||||
const apiKey = process.env.GEMINI_API_KEY;
|
||||
@@ -87,8 +86,8 @@ export const extractItemsFromReceiptImage = async (
|
||||
* @returns A promise that resolves to the extracted core data.
|
||||
*/
|
||||
export const extractCoreDataFromFlyerImage = async (
|
||||
imagePaths: { path: string; mimetype: string }[],
|
||||
masterItems: MasterGroceryItem[]
|
||||
_imagePaths: { path: string; mimetype: string }[],
|
||||
_masterItems: MasterGroceryItem[]
|
||||
): Promise<{
|
||||
store_name: string;
|
||||
valid_from: string | null;
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
|
||||
// This file is intended for client-side Gemini helper functions.
|
||||
// Currently, most AI logic is handled on the server via `aiService.server.ts`
|
||||
// and exposed through the API, so this file is largely a placeholder for future features.
|
||||
|
||||
import type { FlyerItem, MasterGroceryItem, Store } from "../types";
|
||||
import { logger } from "./logger";
|
||||
import { apiFetch } from './apiClient';
|
||||
// import { logger } from "./logger";
|
||||
|
||||
|
||||
/**
|
||||
* Parses a JSON string from a Gemini response, robustly handling markdown fences.
|
||||
* @param responseText The raw text from the AI response.
|
||||
* @returns The parsed JSON object.
|
||||
*/
|
||||
function parseGeminiJson<T>(responseText: string): T {
|
||||
let cleanedText = responseText.trim();
|
||||
// /**
|
||||
// * Parses a JSON string from a Gemini response, robustly handling markdown fences.
|
||||
// * @param responseText The raw text from the AI response.
|
||||
// * @returns The parsed JSON object.
|
||||
// */
|
||||
// function parseGeminiJson<T>(responseText: string): T {
|
||||
// let cleanedText = responseText.trim();
|
||||
|
||||
// Remove markdown fences ` ```json ... ``` `
|
||||
const jsonRegex = /```json\s*([\s\S]*?)\s*```/;
|
||||
const match = cleanedText.match(jsonRegex);
|
||||
if (match && match[1]) {
|
||||
cleanedText = match[1];
|
||||
}
|
||||
// // Remove markdown fences ` ```json ... ``` `
|
||||
// const jsonRegex = /```json\s*([\s\S]*?)\s*```/;
|
||||
// const match = cleanedText.match(jsonRegex);
|
||||
// if (match && match[1]) {
|
||||
// cleanedText = match[1];
|
||||
// }
|
||||
|
||||
try {
|
||||
return JSON.parse(cleanedText) as T;
|
||||
} catch (e) {
|
||||
// Ensure we handle different types of thrown errors gracefully.
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
logger.error("Failed to parse JSON response from AI.", {
|
||||
originalResponse: responseText,
|
||||
cleanedJSON: cleanedText,
|
||||
error: errorMessage,
|
||||
});
|
||||
// try {
|
||||
// return JSON.parse(cleanedText) as T;
|
||||
// } catch (e) {
|
||||
// // Ensure we handle different types of thrown errors gracefully.
|
||||
// const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
// logger.error("Failed to parse JSON response from AI.", {
|
||||
// originalResponse: responseText,
|
||||
// cleanedJSON: cleanedText,
|
||||
// error: errorMessage,
|
||||
// });
|
||||
|
||||
// Re-throw with more context.
|
||||
throw new Error(`Failed to parse JSON response from AI. Error: ${errorMessage}. The AI may have returned malformed data.`);
|
||||
}
|
||||
}
|
||||
// // Re-throw with more context.
|
||||
// throw new Error(`Failed to parse JSON response from AI. Error: ${errorMessage}. The AI may have returned malformed data.`);
|
||||
// }
|
||||
// }
|
||||
|
||||
// ============================================================================
|
||||
// STUBS FOR FUTURE AI FEATURES
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { exec } from 'child_process';
|
||||
import { promisify } from 'util';
|
||||
import { setup as globalSetup } from './global-setup';
|
||||
import { pingBackend } from '../../services/apiClient'; // Import the ping function
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
import { logger } from '../../services/logger';
|
||||
|
||||
/**
|
||||
* This setup function is specifically for integration tests that need a running backend.
|
||||
@@ -29,7 +27,7 @@ export async function setup() {
|
||||
return; // Server is ready, exit setup.
|
||||
}
|
||||
} catch (e) {
|
||||
// Ignore connection errors while waiting
|
||||
logger.debug('Ping failed while waiting for server, this is expected.', { error: e });
|
||||
}
|
||||
console.log(`Waiting for backend server... (attempt ${i + 1}/${maxRetries})`);
|
||||
await new Promise(resolve => setTimeout(resolve, retryDelay));
|
||||
|
||||
Reference in New Issue
Block a user