New mail in the other signed-in accounts: counts, a dot, and a notification
ci / node (pull_request) Skipped
ci / version (pull_request) Skipped
ci / docker-build (pull_request) Skipped
ci / publish (pull_request) Skipped
github/ci (branch) GitHub Actions
ci / github (pull_request) Successful in 2m24s
ci / announce (pull_request) Skipped
ci / node (pull_request) Skipped
ci / version (pull_request) Skipped
ci / docker-build (pull_request) Skipped
ci / publish (pull_request) Skipped
github/ci (branch) GitHub Actions
ci / github (pull_request) Successful in 2m24s
ci / announce (pull_request) Skipped
With more than one account signed in (#49), mail arriving in one that isn't in front went unseen until someone switched to it (multi-account spec, MA-8). - GET /api/auth/accounts/unread answers the Inbox unread count of each account not in front, asked through that account's own session (its OAuth token renewed first if due), kept a minute per account. - The web app asks every two minutes while another account is signed in. The account menu shows each one's count beside its name, and the avatar carries a dot when any of them has unread mail. - When a count rises while the app is open and desktop notifications are on, a notification names the account ("New mail for [email protected]"); clicking it switches to that account. An account seen for the first time doesn't notify: its mail was already there. Not in this change: notifications with the app closed, which need each added account's own Web Push subscription. New strings (3, English only in the other ten catalogs): "New mail for {name}", "Unread in the Inbox: {count}", "Account: new mail in another account". Tests: the server answers the other account's count and nothing when alone; the client keeps the counts, notifies only on a rise and only with notifications on. Checked in Chrome against the mock. typecheck, tests (web 1541, server 277) and build pass.
This commit is contained in:
1 parent
68c91a1ad4
commit
5f27923ce6
6 files changed
+234
-2
No files matched your search
@@ -0,0 +1,68 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
/** inbuxa MA-8: new mail in the accounts not in front. */
|
||||
|
||||
const shown: { title: string; opts: Record<string, unknown> }[] = [];
|
||||
vi.mock("@/lib/notify/notify", () => ({
|
||||
showNotification: (title: string, opts: Record<string, unknown>) => shown.push({ title, opts }),
|
||||
}));
|
||||
|
||||
const { risen, pollOtherUnread, useOtherUnread } = await import("@/lib/otherAccounts");
|
||||
const { useSession } = await import("@/store/session");
|
||||
const { useSettings } = await import("@/store/settings");
|
||||
|
||||
let counts: Record<string, number>;
|
||||
|
||||
beforeEach(() => {
|
||||
shown.length = 0;
|
||||
counts = { b: 3 };
|
||||
vi.stubGlobal(
|
||||
"fetch",
|
||||
vi.fn(async () => {
|
||||
const body = { accounts: Object.entries(counts).map(([id, unread]) => ({ id, unread })) };
|
||||
return { ok: true, status: 200, json: async () => body, text: async () => JSON.stringify(body) } as Response;
|
||||
}),
|
||||
);
|
||||
useOtherUnread.getState().set({});
|
||||
useSession.setState({
|
||||
signedIn: [
|
||||
{ id: "a", username: "[email protected]", front: true },
|
||||
{ id: "b", username: "[email protected]", front: false },
|
||||
],
|
||||
});
|
||||
useSettings.setState((s) => ({ settings: { ...s.settings, desktopNotifications: true } }));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
describe("other accounts' unread mail", () => {
|
||||
it("counts only a rise, and never an account seen for the first time", () => {
|
||||
expect(risen({}, { b: 4 })).toEqual([]);
|
||||
expect(risen({ b: 4 }, { b: 4 })).toEqual([]);
|
||||
expect(risen({ b: 4 }, { b: 2 })).toEqual([]);
|
||||
expect(risen({ b: 4, c: 1 }, { b: 5, c: 1 })).toEqual(["b"]);
|
||||
});
|
||||
|
||||
it("keeps the counts, and names the account when new mail arrives", async () => {
|
||||
await pollOtherUnread();
|
||||
expect(useOtherUnread.getState().unread).toEqual({ b: 3 });
|
||||
expect(shown).toEqual([]);
|
||||
|
||||
counts = { b: 5 };
|
||||
await pollOtherUnread();
|
||||
expect(shown).toHaveLength(1);
|
||||
expect(shown[0]!.title).toContain("[email protected]");
|
||||
expect(shown[0]!.opts.tag).toBe("other-account-b");
|
||||
});
|
||||
|
||||
it("stays quiet when desktop notifications are off", async () => {
|
||||
useSettings.setState((s) => ({ settings: { ...s.settings, desktopNotifications: false } }));
|
||||
await pollOtherUnread();
|
||||
counts = { b: 9 };
|
||||
await pollOtherUnread();
|
||||
expect(shown).toEqual([]);
|
||||
expect(useOtherUnread.getState().unread).toEqual({ b: 9 });
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user