import { expect, tap } from '@git.zone/tstest/tapbundle'; import * as smartfeed from '../ts/index.js'; let testSmartFeed: smartfeed.Smartfeed; tap.test('setup', async () => { testSmartFeed = new smartfeed.Smartfeed(); }); tap.test('should validate required feed options', async () => { let errorThrown = false; try { testSmartFeed.createFeed({ domain: '', title: '', description: '', category: '', company: '', companyEmail: '', companyDomain: '', } as any); } catch (error) { errorThrown = true; expect(error.message).toInclude('validation failed'); } expect(errorThrown).toEqual(true); }); tap.test('should validate domain format', async () => { let errorThrown = false; try { testSmartFeed.createFeed({ domain: 'not a domain!', title: 'Test', description: 'Test', category: 'Test', company: 'Test Inc', companyEmail: 'test@example.com', companyDomain: 'https://example.com', }); } catch (error) { errorThrown = true; expect(error.message).toInclude('Invalid domain format'); } expect(errorThrown).toEqual(true); }); tap.test('should validate email format', async () => { let errorThrown = false; try { testSmartFeed.createFeed({ domain: 'example.com', title: 'Test', description: 'Test', category: 'Test', company: 'Test Inc', companyEmail: 'not-an-email', companyDomain: 'https://example.com', }); } catch (error) { errorThrown = true; expect(error.message).toInclude('Invalid email'); } expect(errorThrown).toEqual(true); }); tap.test('should validate company domain URL', async () => { let errorThrown = false; try { testSmartFeed.createFeed({ domain: 'example.com', title: 'Test', description: 'Test', category: 'Test', company: 'Test Inc', companyEmail: 'test@example.com', companyDomain: 'not-a-url', }); } catch (error) { errorThrown = true; expect(error.message).toInclude('Invalid or relative URL'); } expect(errorThrown).toEqual(true); }); tap.test('should validate item URLs', async () => { const feed = testSmartFeed.createFeed({ domain: 'example.com', title: 'Test Feed', category: 'Test', company: 'Test Inc', companyDomain: 'https://example.com', companyEmail: 'test@example.com', description: 'Test description', }); let errorThrown = false; try { feed.addItem({ title: 'Test', authorName: 'John', imageUrl: 'not-a-url', timestamp: Date.now(), url: 'also-not-a-url', content: 'content', }); } catch (error) { errorThrown = true; expect(error.message).toInclude('Invalid or relative URL'); } expect(errorThrown).toEqual(true); }); tap.test('should validate relative URLs', async () => { const feed = testSmartFeed.createFeed({ domain: 'example.com', title: 'Test Feed', category: 'Test', company: 'Test Inc', companyDomain: 'https://example.com', companyEmail: 'test@example.com', description: 'Test description', }); let errorThrown = false; try { feed.addItem({ title: 'Test', authorName: 'John', imageUrl: '/images/test.jpg', timestamp: Date.now(), url: '/posts/test', content: 'content', }); } catch (error) { errorThrown = true; expect(error.message).toInclude('Invalid or relative URL'); } expect(errorThrown).toEqual(true); }); tap.test('should validate duplicate IDs', async () => { const feed = testSmartFeed.createFeed({ domain: 'example.com', title: 'Test Feed', category: 'Test', company: 'Test Inc', companyDomain: 'https://example.com', companyEmail: 'test@example.com', description: 'Test description', }); const itemData = { title: 'Test Article', authorName: 'John', imageUrl: 'https://example.com/image.png', timestamp: Date.now(), url: 'https://example.com/article/test', content: 'content', }; feed.addItem(itemData); // Try to add same item again (same URL = same ID) let errorThrown = false; try { feed.addItem(itemData); } catch (error) { errorThrown = true; expect(error.message).toInclude('Duplicate item ID'); } expect(errorThrown).toEqual(true); }); tap.test('should validate duplicate custom IDs', async () => { const feed = testSmartFeed.createFeed({ domain: 'example.com', title: 'Test Feed', category: 'Test', company: 'Test Inc', companyDomain: 'https://example.com', companyEmail: 'test@example.com', description: 'Test description', }); feed.addItem({ title: 'First Article', authorName: 'John', imageUrl: 'https://example.com/image1.png', timestamp: Date.now(), url: 'https://example.com/article/first', content: 'first content', id: 'custom-id-1', }); // Try to add another item with same custom ID let errorThrown = false; try { feed.addItem({ title: 'Second Article', authorName: 'Jane', imageUrl: 'https://example.com/image2.png', timestamp: Date.now(), url: 'https://example.com/article/second', content: 'second content', id: 'custom-id-1', }); } catch (error) { errorThrown = true; expect(error.message).toInclude('Duplicate item ID'); } expect(errorThrown).toEqual(true); }); tap.test('should validate timestamp', async () => { const feed = testSmartFeed.createFeed({ domain: 'example.com', title: 'Test Feed', category: 'Test', company: 'Test Inc', companyDomain: 'https://example.com', companyEmail: 'test@example.com', description: 'Test description', }); let errorThrown = false; try { feed.addItem({ title: 'Test', authorName: 'John', imageUrl: 'https://example.com/image.png', timestamp: -1, url: 'https://example.com/article/test', content: 'content', }); } catch (error) { errorThrown = true; expect(error.message).toInclude('cannot be negative'); } expect(errorThrown).toEqual(true); }); tap.test('should validate required item fields', async () => { const feed = testSmartFeed.createFeed({ domain: 'example.com', title: 'Test Feed', category: 'Test', company: 'Test Inc', companyDomain: 'https://example.com', companyEmail: 'test@example.com', description: 'Test description', }); let errorThrown = false; try { feed.addItem({ title: '', authorName: '', imageUrl: '', timestamp: Date.now(), url: '', content: '', } as any); } catch (error) { errorThrown = true; expect(error.message).toInclude('validation failed'); } expect(errorThrown).toEqual(true); }); export default tap.start();