Files
dbx/apps/desktop/src/lib/sidebar/__tests__/sidebarSearchLoadingTracker.spec.ts
T

44 lines
1.7 KiB
TypeScript
Vendored

import { describe, expect, it } from "vitest";
import { createSidebarSearchLoadingTracker } from "@/lib/sidebar/sidebarSearchLoadingTracker";
describe("sidebar search loading tracker", () => {
it("is idle until a search dispatch begins", () => {
const tracker = createSidebarSearchLoadingTracker();
expect(tracker.isLoading).toBe(false);
});
it("reports loading while a dispatch is in flight and clears on matching end", () => {
const tracker = createSidebarSearchLoadingTracker();
const generation = tracker.begin();
expect(tracker.isLoading).toBe(true);
expect(tracker.end(generation)).toBe(true);
expect(tracker.isLoading).toBe(false);
});
it("ignores a stale end() from a superseded dispatch (fast typing race)", () => {
// This is the exact race in ConnectionTree.vue's search watcher: each keystroke
// (after debounce) re-dispatches expansion tasks; a slow earlier dispatch must not
// clear the spinner set by a newer, still-in-flight dispatch.
const tracker = createSidebarSearchLoadingTracker();
const firstGeneration = tracker.begin();
const secondGeneration = tracker.begin();
expect(tracker.isLoading).toBe(true);
expect(tracker.end(firstGeneration)).toBe(false);
expect(tracker.isLoading).toBe(true);
expect(tracker.end(secondGeneration)).toBe(true);
expect(tracker.isLoading).toBe(false);
});
it("cancel() immediately clears loading and invalidates any pending end()", () => {
const tracker = createSidebarSearchLoadingTracker();
const generation = tracker.begin();
tracker.cancel();
expect(tracker.isLoading).toBe(false);
expect(tracker.end(generation)).toBe(false);
expect(tracker.isLoading).toBe(false);
});
});