feat: persist settings and enrich conversation context

This commit is contained in:
jjbrunton committed 2026-08-08 18:18:28 +01:00
1 parent a36723a325
commit 2c100d72b6
84 files changed
+2248 -644

No files matched your search

+56
View File
@@ -15,6 +15,7 @@ interface ChatFixtureOptions {
unread?: boolean;
isFromUs?: boolean;
lastMessageSnippet?: string;
hasReceivedImages?: boolean;
}
function chatFixture(options: ChatFixtureOptions) {
@@ -27,6 +28,7 @@ function chatFixture(options: ChatFixtureOptions) {
lastMessageSnippet: options.lastMessageSnippet ?? `Latest from ${options.username}`,
isFromUs: options.isFromUs ?? false,
unread: options.unread ?? false,
...(options.hasReceivedImages === undefined ? {} : { hasReceivedImages: options.hasReceivedImages }),
};
}
@@ -45,6 +47,7 @@ function detailFixture(chat = alice) {
subreddit: 'casualconversation',
title: 'Looking for a chat',
url: 'https://reddit.com/r/casualconversation/comments/post-1',
imageUrl: 'https://i.redd.it/source-post.jpg',
sentAt: 1_785_999_800_000,
},
syncInProgress: null,
@@ -123,8 +126,59 @@ describe('ConversationsPage', () => {
await user.click(screen.getByRole('button', { name: /u\/alice/ }));
expect(await screen.findByRole('heading', { name: 'u/alice' })).toBeInTheDocument();
expect(screen.getAllByRole('link', { name: 'u/alice' })).not.toHaveLength(0);
for (const profileLink of screen.getAllByRole('link', { name: 'u/alice' })) {
expect(profileLink).toHaveAttribute('href', 'https://www.reddit.com/u/alice');
}
expect(screen.getByText('Good to hear from you')).toBeInTheDocument();
expect(screen.getByRole('link', { name: 'Looking for a chat' })).toHaveAttribute('href', expect.stringContaining('post-1'));
expect(screen.getByRole('img', { name: 'Source post: Looking for a chat' })).toHaveAttribute(
'src',
'https://i.redd.it/source-post.jpg',
);
});
it('marks and filters conversations with received images and renders the images in chat', async () => {
const imageChat = chatFixture({
username: 'alice',
roomId: 'room-alice',
hasReceivedImages: true,
lastMessageSnippet: '[Image]',
});
server.use(
http.get('/api/conversations', () => HttpResponse.json([imageChat, bob])),
http.get('/api/conversations/room-alice', () => HttpResponse.json({
...detailFixture(imageChat),
messages: [
{
sender: 'alice',
text: '[Image]',
timestamp: 1_786_000_000_000,
isSelf: false,
media: [{
originalUrl: 'mxc://reddit.com/image-one',
localPath: 'received image.jpg',
fileName: 'received image.jpg',
}],
},
],
})),
);
const user = userEvent.setup();
renderConversations();
const aliceItem = await screen.findByRole('button', { name: /u\/alice/ });
expect(screen.getByText('Image received')).toBeInTheDocument();
await user.selectOptions(screen.getByRole('combobox', { name: 'Filter conversations' }), 'received-images');
expect(screen.getByRole('button', { name: /u\/alice/ })).toBeInTheDocument();
expect(screen.queryByRole('button', { name: /u\/bob/ })).not.toBeInTheDocument();
await user.click(screen.getByRole('button', { name: /u\/alice/ }));
expect(await screen.findByRole('img', { name: 'Image received from u/alice' })).toHaveAttribute(
'src',
'/media/received%20image.jpg',
);
});
it('turns a suggestion into an editable draft and confirms sending without losing failed input', async () => {
@@ -230,6 +284,8 @@ describe('ConversationsPage', () => {
);
await user.click(screen.getByRole('button', { name: 'Start conversation' }));
expect(await screen.findByRole('status', { name: 'Conversation started' })).toHaveTextContent('Conversation started with u/charlie');
expect(within(screen.getByRole('status', { name: 'Conversation started' })).getByRole('link', { name: 'u/charlie' }))
.toHaveAttribute('href', 'https://www.reddit.com/u/charlie');
expect(username).toHaveValue('');
expect(message).toHaveValue('');
expect(startRequests).toBe(2);