Barazo default frontend barazo.forum
at main 121 lines 3.7 kB view raw
1import { describe, it, expect } from 'vitest' 2import { render, screen } from '@testing-library/react' 3import { TopicList } from './topic-list' 4import { mockTopics } from '@/mocks/data' 5import type { Topic } from '@/lib/api/types' 6 7const baseTopic: Topic = { ...mockTopics[0]! } 8 9describe('TopicList', () => { 10 it('renders all topics', () => { 11 render(<TopicList topics={mockTopics} />) 12 const articles = screen.getAllByRole('article') 13 expect(articles).toHaveLength(mockTopics.length) 14 }) 15 16 it('renders topic titles', () => { 17 render(<TopicList topics={mockTopics} />) 18 for (const topic of mockTopics) { 19 expect(screen.getByRole('link', { name: topic.title })).toBeInTheDocument() 20 } 21 }) 22 23 it('renders empty state when no topics', () => { 24 render(<TopicList topics={[]} />) 25 expect(screen.getByText(/no topics yet/i)).toBeInTheDocument() 26 }) 27 28 it('renders with heading', () => { 29 render(<TopicList topics={mockTopics} heading="Recent Topics" />) 30 expect(screen.getByRole('heading', { name: 'Recent Topics' })).toBeInTheDocument() 31 }) 32 33 it('should render "Pinned" heading when there are pinned topics', () => { 34 const topics: Topic[] = [ 35 { 36 ...baseTopic, 37 uri: 'at://did:plc:test/forum.barazo.topic.post/p1', 38 rkey: 'p1', 39 isPinned: true, 40 pinnedScope: 'category', 41 pinnedAt: '2026-03-01T00:00:00Z', 42 }, 43 { 44 ...baseTopic, 45 uri: 'at://did:plc:test/forum.barazo.topic.post/r1', 46 rkey: 'r1', 47 isPinned: false, 48 pinnedScope: null, 49 pinnedAt: null, 50 }, 51 ] 52 render(<TopicList topics={topics} />) 53 expect(screen.getByText('Pinned')).toBeInTheDocument() 54 expect(screen.getByText('Topics')).toBeInTheDocument() 55 }) 56 57 it('should not render section headings when no pinned topics', () => { 58 const topics: Topic[] = [ 59 { 60 ...baseTopic, 61 uri: 'at://did:plc:test/forum.barazo.topic.post/r1', 62 rkey: 'r1', 63 isPinned: false, 64 pinnedScope: null, 65 pinnedAt: null, 66 }, 67 ] 68 render(<TopicList topics={topics} />) 69 expect(screen.queryByText('Pinned')).not.toBeInTheDocument() 70 expect(screen.queryByText('Topics')).not.toBeInTheDocument() 71 }) 72 73 it('should render a separator between pinned and regular topics', () => { 74 const topics: Topic[] = [ 75 { 76 ...baseTopic, 77 uri: 'at://did:plc:test/forum.barazo.topic.post/p1', 78 rkey: 'p1', 79 isPinned: true, 80 pinnedScope: 'category', 81 pinnedAt: '2026-03-01T00:00:00Z', 82 }, 83 { 84 ...baseTopic, 85 uri: 'at://did:plc:test/forum.barazo.topic.post/r1', 86 rkey: 'r1', 87 isPinned: false, 88 pinnedScope: null, 89 pinnedAt: null, 90 }, 91 ] 92 render(<TopicList topics={topics} />) 93 expect(screen.getByRole('separator')).toBeInTheDocument() 94 }) 95 96 it('should render only pinned section when all topics are pinned', () => { 97 const topics: Topic[] = [ 98 { 99 ...baseTopic, 100 uri: 'at://did:plc:test/forum.barazo.topic.post/p1', 101 rkey: 'p1', 102 isPinned: true, 103 pinnedScope: 'category', 104 pinnedAt: '2026-03-01T00:00:00Z', 105 }, 106 { 107 ...baseTopic, 108 uri: 'at://did:plc:test/forum.barazo.topic.post/p2', 109 rkey: 'p2', 110 isPinned: true, 111 pinnedScope: 'forum', 112 pinnedAt: '2026-03-02T00:00:00Z', 113 }, 114 ] 115 render(<TopicList topics={topics} />) 116 expect(screen.getByText('Pinned')).toBeInTheDocument() 117 // No regular topics section needed, but separator and "Topics" heading still render for consistency 118 const articles = screen.getAllByRole('article') 119 expect(articles).toHaveLength(2) 120 }) 121})