chore: initialize project repository with core extension files

- Add .gitignore to exclude node_modules, dist, logs, and system files
- Add comprehensive project documentation including README, deployment guide, and development setup
- Add .kiro project specifications for amazon-product-bar-extension, appwrite-cloud-storage, appwrite-userid-repair, blacklist-feature, and enhanced-item-management
- Add .kiro steering documents for product, structure, styling, and tech guidelines
- Add VSCode settings configuration for consistent development environment
- Add manifest.json and babel/vite configuration for extension build setup
- Add complete source code implementation including AppWrite integration, storage managers, UI components, and services
- Add comprehensive test suite with Jest configuration and 30+ test files covering all major modules
- Add test HTML files for integration testing and validation
- Add coverage reports and build validation scripts
- Add AppWrite setup and repair documentation for database schema management
- Add migration guides and responsive accessibility implementation documentation
- Establish foundation for Amazon product bar extension with full feature set including blacklist management, enhanced item workflows, and real-time synchronization
This commit is contained in:
2026-01-12 17:46:42 +01:00
commit 216a972fef
180 changed files with 88019 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
/**
* ErrorHandler Tests - Core functionality tests
* Requirements: 7.1, 7.2, 7.3, 7.4, 7.5, 7.6
*/
import { jest, describe, test, expect, beforeAll, beforeEach, afterEach } from '@jest/globals';
describe('ErrorHandler', () => {
let ErrorHandler;
let errorHandler;
let handler;
beforeAll(async () => {
const module = await import('../ErrorHandler.js');
ErrorHandler = module.ErrorHandler;
errorHandler = module.errorHandler;
});
beforeEach(() => {
handler = new ErrorHandler();
jest.clearAllMocks();
jest.spyOn(console, 'error').mockImplementation(() => {});
jest.spyOn(console, 'warn').mockImplementation(() => {});
});
afterEach(() => {
jest.restoreAllMocks();
});
describe('Error Classification', () => {
test('should classify network errors correctly', () => {
const networkError = new Error('Network request failed');
const processed = handler.handleError(networkError, { component: 'test' });
expect(processed.type).toBe(handler.errorTypes.NETWORK);
});
test('should classify API key errors correctly', () => {
const apiKeyError = new Error('Invalid API key');
const processed = handler.handleError(apiKeyError, { component: 'test' });
expect(processed.type).toBe(handler.errorTypes.API_KEY);
});
test('should classify timeout errors correctly', () => {
const timeoutError = new Error('Request timeout');
const processed = handler.handleError(timeoutError, { component: 'test' });
expect(processed.type).toBe(handler.errorTypes.TIMEOUT);
});
});
describe('Error Processing', () => {
test('should process Error objects correctly', () => {
const error = new Error('Test error message');
const processed = handler.handleError(error, {
component: 'TestComponent',
operation: 'testOperation'
});
expect(processed.originalMessage).toBe('Test error message');
expect(processed.component).toBe('TestComponent');
expect(processed.operation).toBe('testOperation');
});
});
describe('Retry Logic', () => {
test('should execute operation successfully on first try', async () => {
const mockOperation = jest.fn().mockResolvedValue('success');
const result = await handler.executeWithRetry(mockOperation, {
component: 'test',
operationName: 'testOp'
});
expect(result.success).toBe(true);
expect(result.data).toBe('success');
expect(result.attempts).toBe(1);
});
});
describe('AI Service Fallback', () => {
test('should provide fallback title suggestions', () => {
const originalTitle = 'Samsung Galaxy S21 Ultra 5G Smartphone 128GB';
const aiError = new Error('Mistral AI unavailable');
const fallback = handler.handleAIServiceFallback(originalTitle, aiError);
expect(fallback.success).toBe(false);
expect(fallback.usedFallback).toBe(true);
expect(fallback.titleSuggestions).toHaveLength(3);
});
});
describe('Extraction Fallback', () => {
test('should provide extraction fallback with manual input option', () => {
const url = 'https://amazon.de/dp/B08N5WRWNW';
const extractionError = new Error('Could not extract product data');
const fallback = handler.handleExtractionFallback(url, extractionError);
expect(fallback.success).toBe(false);
expect(fallback.requiresManualInput).toBe(true);
expect(fallback.url).toBe(url);
});
});
describe('Singleton Instance', () => {
test('should export singleton instance', () => {
expect(errorHandler).toBeInstanceOf(ErrorHandler);
});
});
});