import type { ThreadPullRequestLink } from "@t3tools/contracts";import { ProjectId } from "@t3tools/contracts";import { describe, expect, it } from "vite-plus/test";import { savedPullRequestStack, pullRequestStackView } from "./pullRequestStackSnapshot"; const reference = { projectId: ProjectId.make("project"), host: "github.com", repository: "acme/web", number: 2,};const link: ThreadPullRequestLink = { host: "github.com", repository: "acme/web", number: 2, url: "https://github.com/acme/web/pull/2", source: "manual", linkedAt: "2026-09-09T10:00:00Z", snapshot: { title: "Top layer", headBranch: "top", baseBranch: "bottom", state: "open", isDraft: false, updatedAt: null, syncedAt: "2026-09-09T10:00:00Z", }, stack: { kind: "native", id: "stack", number: 3, url: "https://github.com/acme/web/pull/3", base: "main", layers: [ { number: 1, headBranch: "bottom", state: "open" }, { number: 2, headBranch: "top", state: "open" }, ], },}; describe("saved stack navigation", () => { it("preserves all native layers even when only one has a linked snapshot, without action SHAs", () => { const saved = savedPullRequestStack([link], reference); expect(saved?.layers).toEqual([ { number: 1, headBranch: "bottom", state: "open" }, { number: 2, headBranch: "top", state: "open", title: "Top layer", isDraft: false }, ]); expect(savedPullRequestStack([link], { ...reference, number: 1 })?.number).toBe(3); }); it("does not borrow stacks across hosts or repositories", () => { expect(savedPullRequestStack([link], { ...reference, host: "enterprise.example" })).toBeNull(); expect(savedPullRequestStack([link], { ...reference, repository: "other/web" })).toBeNull(); expect(savedPullRequestStack([link], { ...reference, host: undefined })).toBeNull(); }); it("honors a newer saved removal across linked threads", () => { expect( savedPullRequestStack( [ link, { ...link, stack: null, snapshot: { ...link.snapshot!, syncedAt: "2026-09-09T11:00:00Z" }, }, ], reference, ), ).toBeNull(); }); it("shows saved data during loading and marks a failed refresh stale", () => { const saved = savedPullRequestStack([link], reference); const query = { data: null, isSuccess: false, isPending: true, error: null }; expect(pullRequestStackView(query, saved)).toMatchObject({ data: saved, isFresh: false, notice: expect.stringContaining("Refreshing"), }); expect( pullRequestStackView({ ...query, isPending: false, error: "Rate limited" }, saved), ).toMatchObject({ data: saved, isFresh: false, notice: expect.stringContaining("stale") }); }); it("prefers refreshed data and honors a successful absence", () => { const saved = savedPullRequestStack([link], reference); const query = { data: saved, isSuccess: true, isPending: false, error: null }; expect(pullRequestStackView(query, null)).toEqual({ data: saved, isFresh: true, notice: null }); expect(pullRequestStackView({ ...query, data: null }, saved)).toEqual({ data: null, isFresh: true, notice: null, }); expect(pullRequestStackView({ ...query, isPending: true }, saved).isFresh).toBe(false); });});
import type { ThreadPullRequestLink } from "@t3tools/contracts";
import { ProjectId } from "@t3tools/contracts";
import { describe, expect, it } from "vite-plus/test";
import { savedPullRequestStack, pullRequestStackView } from "./pullRequestStackSnapshot";
const reference = {
projectId: ProjectId.make("project"),
host: "github.com",
repository: "acme/web",
number: 2,
};
const link: ThreadPullRequestLink = {
host: "github.com",
repository: "acme/web",
number: 2,
url: "https://github.com/acme/web/pull/2",
source: "manual",
linkedAt: "2026-09-09T10:00:00Z",
snapshot: {
title: "Top layer",
headBranch: "top",
baseBranch: "bottom",
state: "open",
isDraft: false,
updatedAt: null,
syncedAt: "2026-09-09T10:00:00Z",
},
stack: {
kind: "native",
id: "stack",
number: 3,
url: "https://github.com/acme/web/pull/3",
base: "main",
layers: [
{ number: 1, headBranch: "bottom", state: "open" },
{ number: 2, headBranch: "top", state: "open" },
],
},
};
describe("saved stack navigation", () => {
it("preserves all native layers even when only one has a linked snapshot, without action SHAs", () => {
const saved = savedPullRequestStack([link], reference);
expect(saved?.layers).toEqual([
{ number: 1, headBranch: "bottom", state: "open" },
{ number: 2, headBranch: "top", state: "open", title: "Top layer", isDraft: false },
]);
expect(savedPullRequestStack([link], { ...reference, number: 1 })?.number).toBe(3);
});
it("does not borrow stacks across hosts or repositories", () => {
expect(savedPullRequestStack([link], { ...reference, host: "enterprise.example" })).toBeNull();
expect(savedPullRequestStack([link], { ...reference, repository: "other/web" })).toBeNull();
expect(savedPullRequestStack([link], { ...reference, host: undefined })).toBeNull();
});
it("honors a newer saved removal across linked threads", () => {
expect(
savedPullRequestStack(
[
link,
{
...link,
stack: null,
snapshot: { ...link.snapshot!, syncedAt: "2026-09-09T11:00:00Z" },
},
],
reference,
),
).toBeNull();
});
it("shows saved data during loading and marks a failed refresh stale", () => {
const saved = savedPullRequestStack([link], reference);
const query = { data: null, isSuccess: false, isPending: true, error: null };
expect(pullRequestStackView(query, saved)).toMatchObject({
data: saved,
isFresh: false,
notice: expect.stringContaining("Refreshing"),
});
expect(
pullRequestStackView({ ...query, isPending: false, error: "Rate limited" }, saved),
).toMatchObject({ data: saved, isFresh: false, notice: expect.stringContaining("stale") });
});
it("prefers refreshed data and honors a successful absence", () => {
const saved = savedPullRequestStack([link], reference);
const query = { data: saved, isSuccess: true, isPending: false, error: null };
expect(pullRequestStackView(query, null)).toEqual({ data: saved, isFresh: true, notice: null });
expect(pullRequestStackView({ ...query, data: null }, saved)).toEqual({
data: null,
isFresh: true,
notice: null,
});
expect(pullRequestStackView({ ...query, isPending: true }, saved).isFresh).toBe(false);
});
});