Public Access
feat(stats): add stats page and pile trend
Show the stat groups on /stats, the pile trend on the dashboard card, one switch per group in the settings, and the shared groups on the public profile.
This commit is contained in:
1 parent
83bbc2730d
commit
9d1c7bb40d
31 files changed
+978
-11
No files matched your search
@@ -55,6 +55,57 @@ describe('SettingsPage public profile', () => {
|
||||
await waitFor(() => expect(screen.queryByText(/\/u\/Lobo$/)).toBeNull());
|
||||
});
|
||||
|
||||
it('saves the stat groups the public profile shows, in a fixed order', async () => {
|
||||
renderPage(profile({settings: {useDarkTheme: true, language: 'de', publicProfile: true, profileStats: ['TREND']}}));
|
||||
|
||||
fireEvent.click(await screen.findByRole('switch', {name: 'STATS.PILE.TITLE'}));
|
||||
|
||||
await waitFor(() => expect(puts()).toHaveLength(1));
|
||||
expect(puts()[0]).toEqual({groups: ['PILE', 'TREND']});
|
||||
const [url] = fetch.mock.calls.find(([, init]) => init?.method === 'PUT');
|
||||
expect(url).toMatch(/\/api\/users\/settings\/profile-stats$/);
|
||||
await waitFor(() => expect(screen.getByRole('switch', {name: 'STATS.PILE.TITLE'}).getAttribute('aria-checked'))
|
||||
.toBe('true'));
|
||||
});
|
||||
|
||||
it('waits for a save before the next switch click', async () => {
|
||||
const answers = [];
|
||||
const me = profile({settings: {useDarkTheme: true, language: 'de', publicProfile: true, profileStats: []}});
|
||||
globalThis.fetch = vi.fn((url, init) => (init?.method === 'PUT'
|
||||
? new Promise((resolve) => answers.push(() => resolve({ok: true, status: 204, json: async () => ({})})))
|
||||
: Promise.resolve({ok: true, status: 200, json: async () => me})));
|
||||
render(<MemoryRouter><PreferencesProvider><SettingsPage/></PreferencesProvider></MemoryRouter>);
|
||||
|
||||
fireEvent.click(await screen.findByRole('switch', {name: 'STATS.PILE.TITLE'}));
|
||||
await waitFor(() => expect(screen.getByRole('switch', {name: 'STATS.TASTE.TITLE'}).disabled).toBe(true));
|
||||
answers.forEach((answer) => answer());
|
||||
await waitFor(() => expect(screen.getByRole('switch', {name: 'STATS.TASTE.TITLE'}).disabled).toBe(false));
|
||||
fireEvent.click(screen.getByRole('switch', {name: 'STATS.TASTE.TITLE'}));
|
||||
|
||||
await waitFor(() => expect(puts()).toHaveLength(2));
|
||||
expect(puts()[1]).toEqual({groups: ['PILE', 'TASTE']});
|
||||
});
|
||||
|
||||
it('switches the group back when the save fails', async () => {
|
||||
const me = profile({settings: {useDarkTheme: true, language: 'de', publicProfile: true, profileStats: []}});
|
||||
globalThis.fetch = vi.fn(async (url, init) => (init?.method === 'PUT'
|
||||
? {ok: false, status: 500, json: async () => ({})}
|
||||
: {ok: true, status: 200, json: async () => me}));
|
||||
render(<MemoryRouter><PreferencesProvider><SettingsPage/></PreferencesProvider></MemoryRouter>);
|
||||
|
||||
fireEvent.click(await screen.findByRole('switch', {name: 'STATS.PILE.TITLE'}));
|
||||
|
||||
await waitFor(() => expect(screen.getByRole('switch', {name: 'STATS.PILE.TITLE'}).getAttribute('aria-checked'))
|
||||
.toBe('false'));
|
||||
});
|
||||
|
||||
it('offers the stat groups only while the profile is public', async () => {
|
||||
renderPage(profile({settings: {useDarkTheme: true, language: 'de', publicProfile: false}}));
|
||||
|
||||
expect((await screen.findByRole('switch', {name: 'STATS.PILE.TITLE'})).disabled).toBe(true);
|
||||
expect(screen.getByText('SETTINGS.PROFILE_STATS_NEEDS_PUBLIC')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('needs a display name first', async () => {
|
||||
renderPage(profile({displayName: null, settings: {useDarkTheme: true, language: 'de', publicProfile: false}}));
|
||||
|
||||
|
||||
Reference in new issue
Block a user