Files
buzz/desktop/src/app/communityViewTransition.test.mjs
Kalvin C 95478919fc feat: remember per-community navigation location (#2629)
Signed-off-by: npub1dccv64krpcpse5cmkzfeh998cftungyatw3djt8jwdw6g43f7fyqzzmrf7 <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Co-authored-by: npub1dccv64krpcpse5cmkzfeh998cftungyatw3djt8jwdw6g43f7fyqzzmrf7 <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
2026-07-23 22:52:25 +00:00

110 lines
3.2 KiB
JavaScript

import assert from "node:assert/strict";
import test, { afterEach, mock } from "node:test";
import {
completeCommunityViewTransition,
replaceCommunityDestinationRoute,
runCommunityViewTransition,
} from "./communityViewTransition.ts";
const originalDocument = globalThis.document;
const originalWindow = globalThis.window;
afterEach(() => {
globalThis.document = originalDocument;
globalThis.window = originalWindow;
mock.restoreAll();
});
function installBrowser(startViewTransition) {
globalThis.window = { clearTimeout, setTimeout };
globalThis.document = { startViewTransition };
}
function transitionFor(callback) {
return { updateCallbackDone: Promise.resolve().then(callback) };
}
test("replaceCommunityDestinationRoute uses router history and encodes the channel id", () => {
const replacements = [];
replaceCommunityDestinationRoute("channel/with spaces", {
replace: (href) => replacements.push(href),
});
assert.deepEqual(replacements, ["/channels/channel%2Fwith%20spaces"]);
});
test("unsupported browsers execute the update and contain rejection", async () => {
installBrowser(undefined);
const expected = new Error("navigation failed");
const error = mock.method(console, "error", () => {});
await assert.doesNotReject(() =>
runCommunityViewTransition(async () => {
throw expected;
}),
);
assert.equal(error.mock.callCount(), 1);
assert.equal(error.mock.calls[0].arguments[1], expected);
});
test("supported transitions wait for target readiness", async () => {
let updateFinished = false;
let transitionFinished = false;
installBrowser((callback) => transitionFor(callback));
const pending = runCommunityViewTransition(async () => {
updateFinished = true;
}).then(() => {
transitionFinished = true;
});
await new Promise((resolve) => setTimeout(resolve, 0));
assert.equal(updateFinished, true);
assert.equal(transitionFinished, false);
completeCommunityViewTransition();
await pending;
assert.equal(transitionFinished, true);
});
test("a newer transition releases the previous transition", async () => {
installBrowser((callback) => transitionFor(callback));
let firstFinished = false;
const first = runCommunityViewTransition(() => {}).then(() => {
firstFinished = true;
});
await new Promise((resolve) => setTimeout(resolve, 0));
const second = runCommunityViewTransition(() => {});
await first;
assert.equal(firstFinished, true);
completeCommunityViewTransition();
await second;
});
test("timeout releases a transition whose target never reports ready", async () => {
installBrowser((callback) => transitionFor(callback));
await assert.doesNotReject(() =>
runCommunityViewTransition(() => {}, { timeoutMs: 1 }),
);
});
test("view-transition callback rejection is contained", async () => {
installBrowser((callback) => transitionFor(callback));
const expected = new Error("route rejected");
const error = mock.method(console, "error", () => {});
await assert.doesNotReject(() =>
runCommunityViewTransition(async () => {
throw expected;
}),
);
assert.equal(error.mock.callCount(), 1);
assert.equal(error.mock.calls[0].arguments[1], expected);
});