import { describe, it, expect } from 'vitest'; import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import { MessagingProvider } from '../provider'; import { Messenger } from './messenger'; import { MockAdapter } from '../adapters/mock'; function mount() { return render( , ); } describe('channels (mock adapter)', () => { it('browse returns public channels + private ones I am in, with a joined flag', async () => { const a = new MockAdapter(); const list = await a.browseChannels(); const byId = new Map(list.map((c) => [c.threadId, c])); expect(byId.get('th_ch_general')?.joined).toBe(true); // public, I'm in expect(byId.get('th_ch_random')?.joined).toBe(false); // public, I'm NOT in expect(byId.get('th_ch_deals')?.joined).toBe(true); // private, I'm in // A private channel I'm not in must never surface in browse — none seeded, so all private here are mine. expect(list.every((c) => c.visibility === 'public' || c.joined)).toBe(true); }); it('join adds me and the channel then appears in my conversation list', async () => { const a = new MockAdapter(); expect((await a.listConversations()).some((c) => c.threadId === 'th_ch_random')).toBe(false); await a.joinChannel('th_ch_random'); expect((await a.listConversations()).some((c) => c.threadId === 'th_ch_random')).toBe(true); expect((await a.browseChannels()).find((c) => c.threadId === 'th_ch_random')?.joined).toBe(true); }); it('create makes a channel I am a member of', async () => { const a = new MockAdapter(); const { threadId } = await a.createChannel({ name: 'design', topic: 'UI stuff', visibility: 'public' }); const conv = (await a.listConversations()).find((c) => c.threadId === threadId); expect(conv?.membership).toBe('channel'); expect(conv?.topic).toBe('UI stuff'); }); it('UI: browse, then join a channel — it moves into the Channels section', async () => { mount(); // Open the browser via the Channels section "+". fireEvent.click(await screen.findByTitle('Browse channels')); // #random is browse-only (not joined) → has a Join button. expect(await screen.findByText('random')).toBeTruthy(); const joinButtons = screen.getAllByText('Join'); fireEvent.click(joinButtons[0]!); // After joining, we jump to the thread and the browser closes → composer is shown. await waitFor(() => expect(screen.getByLabelText('Message')).toBeTruthy()); }); });