fix(ui): return to current document revision preview

This commit is contained in:
Devin Foley committed 2026-04-10 16:46:39 -07:00
1 parent 55594b47b0
commit 38e17071af
2 files changed
+107 -4

No files matched your search

@@ -119,6 +119,35 @@ vi.mock("@/components/ui/dropdown-menu", async () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(globalThis as any).IS_REACT_ACT_ENVIRONMENT = true;
const localStorageEntries = new Map<string, string>();
function ensureLocalStorageMock() {
if (
typeof window.localStorage?.getItem === "function"
&& typeof window.localStorage?.setItem === "function"
&& typeof window.localStorage?.removeItem === "function"
&& typeof window.localStorage?.clear === "function"
) {
return;
}
Object.defineProperty(window, "localStorage", {
configurable: true,
value: {
getItem: (key: string) => localStorageEntries.get(key) ?? null,
setItem: (key: string, value: string) => {
localStorageEntries.set(key, value);
},
removeItem: (key: string) => {
localStorageEntries.delete(key);
},
clear: () => {
localStorageEntries.clear();
},
},
});
}
function deferred<T>() {
let resolve!: (value: T) => void;
const promise = new Promise<T>((res) => {
@@ -221,6 +250,7 @@ describe("IssueDocumentsSection", () => {
beforeEach(() => {
container = document.createElement("div");
document.body.appendChild(container);
ensureLocalStorageMock();
window.localStorage.clear();
vi.clearAllMocks();
markdownEditorMockState.emitMountEmptyChange = false;
@@ -311,6 +341,79 @@ describe("IssueDocumentsSection", () => {
queryClient.clear();
});
it("returns from a historical preview when the current revision only exists in derived state", async () => {
const currentDocument = createIssueDocument({
body: "Current plan body",
latestRevisionId: "revision-4",
latestRevisionNumber: 4,
updatedAt: new Date("2026-03-31T12:05:00.000Z"),
});
const issue = createIssue();
const root = createRoot(container);
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
mutations: {
retry: false,
},
},
});
mockIssuesApi.listDocuments.mockResolvedValue([currentDocument]);
queryClient.setQueryData(
queryKeys.issues.documentRevisions(issue.id, "plan"),
[
createRevision({
id: "revision-3",
revisionNumber: 3,
body: "Historical plan body",
createdAt: new Date("2026-03-31T11:00:00.000Z"),
}),
],
);
await act(async () => {
root.render(
<QueryClientProvider client={queryClient}>
<IssueDocumentsSection issue={issue} canDeleteDocuments={false} />
</QueryClientProvider>,
);
});
await flush();
await flush();
expect(container.textContent).toContain("Current plan body");
const revisionButtons = Array.from(container.querySelectorAll("button"));
const historicalRevisionButton = revisionButtons.find((button) => button.textContent?.includes("rev 3"));
expect(historicalRevisionButton).toBeTruthy();
await act(async () => {
historicalRevisionButton?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
});
expect(container.textContent).toContain("Viewing revision 3");
expect(container.textContent).toContain("Historical plan body");
const currentRevisionButton = Array.from(container.querySelectorAll("button"))
.find((button) => button.textContent?.includes("rev 4"));
expect(currentRevisionButton).toBeTruthy();
await act(async () => {
currentRevisionButton?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
});
expect(container.textContent).not.toContain("Viewing revision 3");
expect(container.textContent).toContain("Current plan body");
await act(async () => {
root.unmount();
});
queryClient.clear();
});
it("ignores mount-time editor change noise before a document is actively being edited", async () => {
markdownEditorMockState.emitMountEmptyChange = true;
+4 -4
View File
@@ -537,13 +537,13 @@ export function IssueDocumentsSection({
}, []);
const previewRevision = useCallback((doc: IssueDocument, revisionId: string) => {
const revisions = getDocumentRevisions(doc.key);
const selectedRevision = revisions.find((revision) => revision.id === revisionId);
if (!selectedRevision) return;
if (selectedRevision.id === doc.latestRevisionId) {
if (revisionId === doc.latestRevisionId) {
returnToLatestRevision(doc.key);
return;
}
const revisions = getDocumentRevisions(doc.key);
const selectedRevision = revisions.find((revision) => revision.id === revisionId);
if (!selectedRevision) return;
if (documentConflict?.key === doc.key || documentHasUnsavedChanges(doc, draft)) {
setError("Save or cancel your local changes before viewing an older revision.");
return;