Repository navigation
Hosted account page: refetch after every mutation, wait out approvals #1266
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 3 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
d97ad4a
Move the enrollment poll interval into policy-constants
nedtwigg 197bf45
Refetch the account after every mutation and wait out approvals
nedtwigg 4d12459
Keep a mutation's success when the refetch after it fails
nedtwigg 3fa0edb
Let a newer read replace a status an older one wrote
nedtwigg 42cff4a
Show the pre-launch notice only after a lookup found no login
nedtwigg File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| import { describe, expect, it, vi } from "vitest"; | ||
| import { approvalShows, reread, settle, type AccountState } from "../../src/settle"; | ||
|
|
||
| const computer = (burrowId: string) => ({ burrowId, enrolledAt: "2026-10-20" }); | ||
| const state = (on: boolean | null, ids: string[] | null): AccountState => ({ | ||
| voice: on === null ? null : { entitled: true, on }, | ||
| computers: ids && ids.map(computer), | ||
| }); | ||
|
|
||
| describe("approvalShows", () => { | ||
| it("waits on a voice approval until Natural Voice is on", () => { | ||
| const shows = approvalShows("voice", state(false, []))!; | ||
| expect(shows(state(false, []))).toBe(false); | ||
| expect(shows(state(null, []))).toBe(false); | ||
| expect(shows(state(true, []))).toBe(true); | ||
| }); | ||
|
|
||
| it("has nothing to wait on when Natural Voice is already on", () => { | ||
| expect(approvalShows("voice", state(true, []))).toBeNull(); | ||
| }); | ||
|
|
||
| it("waits on a remote approval until a computer not listed before appears", () => { | ||
| const shows = approvalShows("remote", state(false, ["a", "b"]))!; | ||
| expect(shows(state(false, ["a", "b"]))).toBe(false); | ||
| expect(shows(state(false, ["a"]))).toBe(false); | ||
| expect(shows(state(false, null))).toBe(false); | ||
| expect(shows(state(false, ["c", "a"]))).toBe(true); | ||
| }); | ||
|
|
||
| it("has nothing to compare a remote approval with when no list was read", () => { | ||
| expect(approvalShows("remote", state(false, null))).toBeNull(); | ||
| }); | ||
| }); | ||
|
|
||
| describe("reread", () => { | ||
| it("resolves the read, telling nothing failed", async () => { | ||
| const failed = vi.fn(); | ||
| await expect(reread(async () => 1, failed)).resolves.toBe(1); | ||
| expect(failed).not.toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| it("reports a failed read itself and resolves, so the mutation stays a success", async () => { | ||
| const failed = vi.fn(); | ||
| await expect( | ||
| reread(() => Promise.reject(new Error("offline")), failed), | ||
| ).resolves.toBeUndefined(); | ||
| expect(failed).toHaveBeenCalledOnce(); | ||
| }); | ||
| }); | ||
|
|
||
| describe("settle", () => { | ||
| const options = (cancelled = () => false) => ({ | ||
| intervalMs: 5000, | ||
| timeoutMs: 20_000, | ||
| cancelled, | ||
| wait: vi.fn(async () => {}), | ||
| }); | ||
|
|
||
| it("reads after each interval until a read shows the change", async () => { | ||
| const read = vi | ||
| .fn<() => Promise<number | undefined>>() | ||
| .mockRejectedValueOnce(new Error("offline")) | ||
| .mockResolvedValueOnce(undefined) | ||
| .mockResolvedValueOnce(1) | ||
| .mockResolvedValueOnce(2); | ||
| const opts = options(); | ||
| // Never handed a missed read: `toFixed` throws on one. | ||
| const done = (value: number) => value.toFixed() === "2"; | ||
| await expect(settle(read, done, opts)).resolves.toBe("done"); | ||
| expect(read).toHaveBeenCalledTimes(4); | ||
| expect(opts.wait).toHaveBeenCalledTimes(4); | ||
| expect(opts.wait).toHaveBeenCalledWith(5000); | ||
| }); | ||
|
|
||
| it("gives up once the timeout's reads all missed", async () => { | ||
| const read = vi.fn(async () => 0); | ||
| await expect(settle(read, () => false, options())).resolves.toBe("timeout"); | ||
| expect(read).toHaveBeenCalledTimes(4); | ||
| }); | ||
|
|
||
| it("stops without reading again once cancelled", async () => { | ||
| const unread = vi.fn(async () => 1); | ||
| await expect(settle(unread, () => true, options(() => true))).resolves.toBe( | ||
| "cancelled", | ||
| ); | ||
| expect(unread).not.toHaveBeenCalled(); | ||
| let cancelled = false; | ||
| const read = vi.fn(async () => { | ||
| cancelled = true; | ||
| return 1; | ||
| }); | ||
| await expect( | ||
| settle(read, () => true, options(() => cancelled)), | ||
| ).resolves.toBe("cancelled"); | ||
| expect(read).toHaveBeenCalledTimes(1); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.