From 0fd97e5d71d5f48168a4b90cb4291f7da17cd131 Mon Sep 17 00:00:00 2001 From: th Date: Wed, 15 Apr 2026 20:15:55 +0200 Subject: [PATCH] tests + version bump: group chat surface Extends chat.test.js to cover the new conversation shape (kind/key fields), the /api/chat/rooms endpoint, the thread-settings round-trip, and the group-creation pick-view toggle. Room-info view DOM is structurally checked. Bumps to 1.9.4. Co-Authored-By: Claude Opus 4.6 (1M context) --- config.php | 2 +- electron/package.json | 2 +- public/plugins/tests/chat.test.js | 75 ++++++++++++++++++++++++++++++- 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/config.php b/config.php index 31e33de..830d282 100644 --- a/config.php +++ b/config.php @@ -1,7 +1,7 @@ { const res = await fetch('api/chat/conversations').then(r => r.json()); expect(Array.isArray(res.conversations)).toBe(true); expect(typeof res.total_unread).toBe('number'); + // Every entry carries kind + key so the UI can route 1:1 vs. room. + for (const c of res.conversations) { + expect(c.kind === 'peer' || c.kind === 'room').toBe(true); + expect(typeof c.key).toBe('string'); + } }); - it('/api/chat/messages without peer returns 400', async () => { + it('/api/chat/messages without peer or room_uid returns 400', async () => { const r = await fetch('api/chat/messages'); expect(r.status).toBe(400); }); @@ -99,4 +104,72 @@ describe('Chat: API', () => { expect(Array.isArray(res.messages)).toBe(true); expect(res.messages.length).toBe(0); }); + + it('/api/chat/messages with unknown room returns empty array', async () => { + const res = await fetch('api/chat/messages?room_uid=__no_such_room__') + .then(r => r.json()); + expect(Array.isArray(res.messages)).toBe(true); + expect(res.messages.length).toBe(0); + }); + + it('/api/chat/rooms returns rooms array', async () => { + const res = await fetch('api/chat/rooms').then(r => r.json()); + expect(res.ok).toBe(true); + expect(Array.isArray(res.rooms)).toBe(true); + }); + + it('/api/chat/thread-settings round-trips disposable flag', async () => { + const peer = '__test_disposable_flip__'; + // Default: 0 + const initial = await fetch('api/chat/thread-settings?peer=' + encodeURIComponent(peer)) + .then(r => r.json()); + expect(initial.disposable).toBe(0); + // Set to 1 + const csrf = document.querySelector('meta[name="csrf"]')?.content || ''; + const set = await fetch('api/chat/thread-settings', { + method: 'POST', + headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrf }, + body: JSON.stringify({ peer, disposable: true }), + }).then(r => r.json()); + expect(set.disposable).toBe(1); + // Verify + const after = await fetch('api/chat/thread-settings?peer=' + encodeURIComponent(peer)) + .then(r => r.json()); + expect(after.disposable).toBe(1); + }); +}); + +describe('Chat: group creation UI', () => { + const ensureFlyoutClosed = async () => { + const f = $('#chat-flyout'); + if (!f) return; + if (!f.classList.contains('hidden')) { + click('#chat-close-btn'); + await waitFor(() => f.classList.contains('hidden')); + } + }; + + it('pick view has 1:1 / group mode switch', async () => { + await ensureFlyoutClosed(); + click('#chat-footer-btn'); + await waitFor(() => !$('#chat-flyout').classList.contains('hidden')); + await sleep(80); + click('#chat-new-btn'); + await sleep(60); + const mode = document.querySelectorAll('.chat-pick-mode-btn'); + expect(mode.length).toBe(2); + // Toggling to group reveals the name input and action bar. + const groupBtn = document.querySelector('.chat-pick-mode-btn[data-mode="group"]'); + click(groupBtn); + await sleep(30); + expect($('#chat-group-name').classList.contains('hidden')).toBe(false); + expect($('#chat-group-actions').classList.contains('hidden')).toBe(false); + await ensureFlyoutClosed(); + }); + + it('room-info view element exists', () => { + expect($('#chat-room-info-view')).toExist(); + expect($('#chat-room-info-back')).toExist(); + expect($('#chat-room-info-body')).toExist(); + }); });