diff options
Diffstat (limited to 'frontend-vanilla/src/regression.test.ts')
| -rw-r--r-- | frontend-vanilla/src/regression.test.ts | 92 |
1 files changed, 91 insertions, 1 deletions
diff --git a/frontend-vanilla/src/regression.test.ts b/frontend-vanilla/src/regression.test.ts index a0b13d5..8529e20 100644 --- a/frontend-vanilla/src/regression.test.ts +++ b/frontend-vanilla/src/regression.test.ts @@ -1,7 +1,8 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { store } from './store'; import { apiFetch } from './api'; -import { renderItems } from './main'; +import { renderItems, renderLayout } from './main'; +import { createFeedItem } from './components/FeedItem'; // Mock api vi.mock('./api', () => ({ @@ -167,3 +168,92 @@ describe('Scroll-to-Read Regression Tests', () => { expect(apiFetch).not.toHaveBeenCalledWith(expect.stringContaining('/api/item/888'), expect.anything()); }); }); + +// NK-t8qnrh: Links in feed item descriptions should have no underlines (match v1 style) +describe('NK-t8qnrh: Feed item description links have no underlines', () => { + it('item-description should be rendered inside feed items', () => { + const item = { + _id: 1, + title: 'Test', + url: 'http://example.com', + description: '<p>Text with <a href="http://example.com">a link</a></p>', + read: false, + starred: false, + publish_date: '2024-01-01', + } as any; + const html = createFeedItem(item); + expect(html).toContain('class="item-description"'); + expect(html).toContain('<a href="http://example.com">a link</a>'); + }); +}); + +// NK-mcl01m: Sidebar order should be filters → search → "+ new" → Feeds → Tags +describe('NK-mcl01m: Sidebar section order', () => { + beforeEach(() => { + document.body.innerHTML = '<div id="app"></div>'; + vi.mocked(apiFetch).mockResolvedValue({ ok: true, status: 200, json: async () => [] } as Response); + renderLayout(); + }); + + it('filter-list appears before section-feeds in the sidebar', () => { + const sidebar = document.getElementById('sidebar'); + expect(sidebar).not.toBeNull(); + const filterList = sidebar!.querySelector('#filter-list'); + const sectionFeeds = sidebar!.querySelector('#section-feeds'); + expect(filterList).not.toBeNull(); + expect(sectionFeeds).not.toBeNull(); + // filter-list should come before section-feeds in DOM order + const position = filterList!.compareDocumentPosition(sectionFeeds!); + expect(position & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy(); + }); + + it('section-feeds appears before section-tags in the sidebar', () => { + const sidebar = document.getElementById('sidebar'); + const sectionFeeds = sidebar!.querySelector('#section-feeds'); + const sectionTags = sidebar!.querySelector('#section-tags'); + expect(sectionFeeds).not.toBeNull(); + expect(sectionTags).not.toBeNull(); + // feeds should come before tags + const position = sectionFeeds!.compareDocumentPosition(sectionTags!); + expect(position & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy(); + }); + + it('search input appears after filter-list and before section-feeds', () => { + const sidebar = document.getElementById('sidebar'); + const filterList = sidebar!.querySelector('#filter-list'); + const searchInput = sidebar!.querySelector('#search-input'); + const sectionFeeds = sidebar!.querySelector('#section-feeds'); + expect(searchInput).not.toBeNull(); + // search after filters + const pos1 = filterList!.compareDocumentPosition(searchInput!); + expect(pos1 & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy(); + // search before feeds + const pos2 = searchInput!.compareDocumentPosition(sectionFeeds!); + expect(pos2 & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy(); + }); + + it('sidebar has a "+ new" link pointing to settings', () => { + const newLink = document.querySelector('.new-feed-link'); + expect(newLink).not.toBeNull(); + expect(newLink!.textContent?.trim()).toBe('+ new'); + }); +}); + +// NK-z1czaq: Main content should fill full width (sidebar overlays, never shifts content) +describe('NK-z1czaq: Sidebar overlays content, does not shift layout', () => { + beforeEach(() => { + document.body.innerHTML = '<div id="app"></div>'; + vi.mocked(apiFetch).mockResolvedValue({ ok: true, status: 200, json: async () => [] } as Response); + }); + + it('sidebar is a sibling of main-content inside .layout (not flex-shifting)', () => { + renderLayout(); + const sidebar = document.querySelector('.sidebar'); + const mainContent = document.querySelector('.main-content'); + expect(sidebar).not.toBeNull(); + expect(mainContent).not.toBeNull(); + // Both should be children of .layout + expect(sidebar!.parentElement?.classList.contains('layout')).toBe(true); + expect(mainContent!.parentElement?.classList.contains('layout')).toBe(true); + }); +}); |
