mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-01 00:13:37 +00:00
fix(push): show each login's real push state in the all-accounts panel
Push state is stored under the JMAP account id the server assigned (enableWebPush keys it on client.getAccountId()), but the all-accounts panel looked it up under the login's own id, so every account read "notifications off" even right after enabling them. Read it back under the JMAP account id.
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { render, waitFor } from '@testing-library/react';
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { MultiAccountPushSettings } from '../multi-account-push';
|
||||
import { useAccountStore } from '@/stores/account-store';
|
||||
import { useAuthStore } from '@/stores/auth-store';
|
||||
import * as webPush from '@/lib/web-push';
|
||||
|
||||
vi.mock('next-intl', () => ({
|
||||
useTranslations: () => (key: string) => key,
|
||||
}));
|
||||
|
||||
vi.mock('../settings-section', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof import('../settings-section')>()),
|
||||
SettingsSection: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||
}));
|
||||
|
||||
// Push state is stored under the JMAP account id the server assigned: only
|
||||
// "jmap-a" has a registration here.
|
||||
vi.mock('@/lib/web-push', () => ({
|
||||
isWebPushSupported: () => true,
|
||||
isWebPushEnabled: vi.fn(async (id: string) => id === 'jmap-a'),
|
||||
enableWebPushForAccounts: vi.fn(),
|
||||
disableWebPush: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('MultiAccountPushSettings', () => {
|
||||
it('reads each login\'s push state under its JMAP account id', async () => {
|
||||
const clients: Record<string, { getAccountId: () => string }> = {
|
||||
'a@mail.example.com': { getAccountId: () => 'jmap-a' },
|
||||
'b@mail.example.com': { getAccountId: () => 'jmap-b' },
|
||||
};
|
||||
useAccountStore.setState({
|
||||
accounts: [
|
||||
{ id: 'a@mail.example.com', username: 'a', email: 'a@example.com', isConnected: true },
|
||||
{ id: 'b@mail.example.com', username: 'b', email: 'b@example.com', isConnected: true },
|
||||
] as never,
|
||||
});
|
||||
useAuthStore.setState({ getClientForAccount: ((id: string) => clients[id]) as never });
|
||||
|
||||
const { container } = render(<MultiAccountPushSettings />);
|
||||
|
||||
await waitFor(() => expect(container.textContent).toContain('a@example.com · state_on'));
|
||||
expect(container.textContent).toContain('b@example.com · state_off');
|
||||
expect(webPush.isWebPushEnabled).toHaveBeenCalledWith('jmap-a');
|
||||
expect(webPush.isWebPushEnabled).not.toHaveBeenCalledWith('a@mail.example.com');
|
||||
});
|
||||
});
|
||||
@@ -31,8 +31,13 @@ export function MultiAccountPushSettings({ relayBaseUrl }: { relayBaseUrl?: stri
|
||||
const connected = accounts.filter(a => a.isConnected && useAuthStore.getState().getClientForAccount(a.id));
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
// Push state is stored under the JMAP account id the server assigned (see
|
||||
// enableWebPush), not under the login's own id: read it back the same way.
|
||||
const entries = await Promise.all(
|
||||
useAccountStore.getState().accounts.map(async a => [a.id, await isWebPushEnabled(a.id)] as const),
|
||||
useAccountStore.getState().accounts.map(async (a) => {
|
||||
const jmapAccountId = useAuthStore.getState().getClientForAccount(a.id)?.getAccountId();
|
||||
return [a.id, jmapAccountId ? await isWebPushEnabled(jmapAccountId) : false] as const;
|
||||
}),
|
||||
);
|
||||
setEnabled(Object.fromEntries(entries));
|
||||
}, []);
|
||||
|
||||
Reference in New Issue
Block a user