fix(settings): keep the language and save settings one after the other

This commit is contained in:
lobo committed 2026-09-29 13:27:31 +02:00
1 parent 14dd59f9e0
commit f605917874
25 files changed
+423 -98

No files matched your search

+33 -1
View File
@@ -1,6 +1,6 @@
// @vitest-environment jsdom
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
import {cleanup, fireEvent, render, screen, waitFor, within} from '@testing-library/react';
import {act, cleanup, fireEvent, render, screen, waitFor, within} from '@testing-library/react';
import {MemoryRouter} from 'react-router-dom';
import SettingsPage from './SettingsPage.jsx';
import {PreferencesProvider} from '../context/PreferencesContext.jsx';
@@ -29,6 +29,24 @@ function renderPage(me) {
render(<MemoryRouter><PreferencesProvider><SettingsPage/></PreferencesProvider></MemoryRouter>);
}
/**
* Auth with PUT /api/users/settings answered one by one through answer(); GET /api/users/me shows what was saved.
*/
function fakeAuth(me) {
const saved = structuredClone(me);
const open = [];
globalThis.fetch = vi.fn((url, init) => {
if (init?.method !== 'PUT') return Promise.resolve({ok: true, status: 200, json: async () => structuredClone(saved)});
return new Promise((resolve) => open.push(() => {
const body = JSON.parse(init.body);
saved.displayName = body.displayName;
Object.assign(saved.settings, {useDarkTheme: body.useDarkTheme, language: body.language, publicProfile: body.publicProfile});
resolve({ok: true, status: 204, json: async () => { throw new SyntaxError('no body'); }});
}));
});
return {answer: () => open.shift()()};
}
describe('SettingsPage public profile', () => {
beforeEach(() => localStorage.setItem('tbp_session', '1'));
@@ -46,6 +64,20 @@ describe('SettingsPage public profile', () => {
expect(puts()[0].publicProfile).toBe(true);
});
it('builds a save on the one before it, also while that one is still open', async () => {
const auth = fakeAuth(profile());
render(<MemoryRouter><PreferencesProvider><SettingsPage/></PreferencesProvider></MemoryRouter>);
fireEvent.click(await screen.findByRole('switch', {name: 'SETTINGS.PUBLIC_PROFILE'}));
await waitFor(() => expect(puts()).toHaveLength(1));
fireEvent.click(screen.getByRole('switch', {name: 'SETTINGS.DARK_THEME'}));
await act(async () => auth.answer());
await waitFor(() => expect(puts()).toHaveLength(2));
expect(puts()[1]).toMatchObject({publicProfile: false, useDarkTheme: false, displayName: 'Lobo'});
await act(async () => auth.answer());
});
it('turns the public profile off and shows the link while it is on', async () => {
renderPage(profile());