Files
insta-recipe/src/tests/sse-extraction.spec.ts
Giancarmine Salucci 49bccf8f15 simplify
2026-02-18 01:21:44 +01:00

157 lines
4.5 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Integration tests for SSE extraction endpoint
*
* Tests the real-time progress streaming from extraction to frontend
*/
import { describe, it, expect } from 'vitest';
import type { ProgressEvent } from '$lib/server/extraction';
describe('SSE Extraction Endpoint', () => {
it('should stream progress events for successful extraction', async () => {
// Mock Instagram URL (would need real URL for full e2e test)
const testUrl = 'https://www.instagram.com/p/test123/';
const events: ProgressEvent[] = [];
// Note: This is a structure test. Real testing requires:
// 1. Running server
// 2. Valid Instagram URL
// 3. Browser context available
// Expected event flow
const expectedEventTypes = [
'status', // Starting extraction
'status', // Loading page
'method', // Trying first method
'status', // Success or next method
'status', // Parsing recipe
'complete' // Final result
];
expect(expectedEventTypes).toBeDefined();
});
it('should handle errors gracefully', async () => {
// Test with invalid URL
const invalidUrl = 'not-a-valid-url';
// Expected: error event should be sent
expect(invalidUrl).toBeTruthy();
});
it('should include method information in progress events', () => {
const mockMethodEvent: ProgressEvent = {
type: 'method',
message: 'Trying extraction method: Embedded JSON',
method: 'embedded-json',
timestamp: new Date().toISOString()
};
expect(mockMethodEvent.type).toBe('method');
expect(mockMethodEvent.method).toBe('embedded-json');
expect(mockMethodEvent.message).toContain('Embedded JSON');
});
it('should include retry information in retry events', () => {
const mockRetryEvent: ProgressEvent = {
type: 'retry',
message: 'Attempt 1/3 failed. Retrying in 1000ms...',
attemptNumber: 1,
maxAttempts: 3,
timestamp: new Date().toISOString()
};
expect(mockRetryEvent.type).toBe('retry');
expect(mockRetryEvent.attemptNumber).toBe(1);
expect(mockRetryEvent.maxAttempts).toBe(3);
});
it('should include recipe data in complete event', () => {
const mockCompleteEvent: ProgressEvent = {
type: 'complete',
message: 'Extraction and parsing completed',
data: {
recipe: {
name: 'Test Recipe',
ingredients: [],
steps: []
},
thumbnail: 'data:image/jpeg;base64,...'
},
timestamp: new Date().toISOString()
};
expect(mockCompleteEvent.type).toBe('complete');
expect(mockCompleteEvent.data).toBeDefined();
expect(mockCompleteEvent.data.recipe).toBeDefined();
expect(mockCompleteEvent.data.thumbnail).toBeDefined();
});
});
describe('Frontend SSE Parser', () => {
it('should parse SSE event format correctly', () => {
const sseMessage = 'event: progress\ndata: {"type":"status","message":"test"}\n\n';
const eventMatch = sseMessage.match(/^event: (\w+)\ndata: (.+)$/s);
expect(eventMatch).toBeTruthy();
if (eventMatch) {
const [, eventType, eventData] = eventMatch;
expect(eventType).toBe('progress');
const parsed = JSON.parse(eventData.replace(/\n\n$/, ''));
expect(parsed.type).toBe('status');
expect(parsed.message).toBe('test');
}
});
it('should map methods to correct icons', () => {
const getMethodIcon = (method?: string): string => {
const icons: Record<string, string> = {
'embedded-json': '📦',
'dom-selector': '🎯',
'graphql-api': '🔌',
legacy: '📄'
};
return method ? icons[method] || '⚙️' : '⚙️';
};
expect(getMethodIcon('embedded-json')).toBe('📦');
expect(getMethodIcon('dom-selector')).toBe('🎯');
expect(getMethodIcon('graphql-api')).toBe('🔌');
expect(getMethodIcon('legacy')).toBe('📄');
expect(getMethodIcon('unknown')).toBe('⚙️');
expect(getMethodIcon()).toBe('⚙️');
});
});
/**
* Manual E2E Testing Checklist:
*
* □ Start dev server: npm run dev
* □ Open /share?url=<instagram-url>
* □ Click "Extract Recipe"
* □ Verify logs show:
* - 🚀 Starting extraction
* - Loading Instagram page
* - 📦 Trying extraction method: Embedded JSON (or other methods)
* - ✅ Success message
* - Recipe displays correctly
* □ Test with problematic URL (should show retries):
* - 🔄 Retry messages appear
* - Multiple methods attempted
* □ Test with invalid URL:
* - ❌ Error messages appear
* - No crash or hang
* □ Verify current method indicator:
* - Blue badge appears during extraction
* - Shows correct method name
* - Disappears when complete
* □ Check log colors:
* - Success = green
* - Errors = red
* - Retries = yellow
* - Methods = blue
*/