mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-07 17:04:42 +00:00
fix(plugins): a Combobox shows a failed refresh instead of the old results
The query keeps its cached data when a reopened list fails to refresh, so the old items stayed selectable and the error never showed. A failed search now clears the list so its error shows. The migration guide maps addNewWorkspaceItem, which its registration-coverage test requires, and the superseded-search test waits on a later search instead of sleeping.
This commit is contained in:
@@ -21,6 +21,7 @@ interface Issue extends ComboboxItem {
|
||||
|
||||
const ONE: Issue = { id: "1", label: "Slow sidebar", branch: "one" };
|
||||
const TWO: Issue = { id: "2", label: "Crash on resume", branch: "two" };
|
||||
const THREE: Issue = { id: "3", label: "Crash on launch", branch: "three" };
|
||||
|
||||
interface Search {
|
||||
query: string;
|
||||
@@ -40,7 +41,8 @@ function controlledSearch() {
|
||||
if (!found) throw new Error(`No search for "${query}" yet`);
|
||||
return found;
|
||||
};
|
||||
return { search, forQuery, queries: () => searches.map((candidate) => candidate.query) };
|
||||
const reject = (index: number, error: Error) => searches[index]?.reject(error);
|
||||
return { search, forQuery, reject, queries: () => searches.map((candidate) => candidate.query) };
|
||||
}
|
||||
|
||||
const toast = { error: vi.fn() } as unknown as ToastApi;
|
||||
@@ -124,8 +126,28 @@ describe("plugin Combobox", () => {
|
||||
await waitFor(() => expect(screen.queryByText("Slow sidebar")).toBeNull());
|
||||
controlled.forQuery("c").resolve([ONE]);
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
expect(screen.getByText("Crash on resume")).toBeTruthy();
|
||||
// Searches settle in order, so once a later one has landed the stale one has been handled.
|
||||
fireEvent.change(input, { target: { value: "cra" } });
|
||||
await waitFor(() => expect(controlled.queries()).toEqual(["", "c", "cr", "cra"]));
|
||||
controlled.forQuery("cra").resolve([THREE]);
|
||||
await screen.findByText("Crash on launch");
|
||||
expect(screen.queryByText("Slow sidebar")).toBeNull();
|
||||
});
|
||||
|
||||
it("shows the error and not the previous results when a reopened list fails to refresh", async () => {
|
||||
const controlled = controlledSearch();
|
||||
renderCombobox({ search: controlled.search });
|
||||
await waitFor(() => expect(controlled.queries()).toEqual([""]));
|
||||
controlled.forQuery("").resolve([ONE]);
|
||||
await screen.findByText("Slow sidebar");
|
||||
|
||||
fireEvent.keyDown(screen.getByRole("textbox"), { key: "Escape" });
|
||||
await waitFor(() => expect(screen.queryByRole("textbox")).toBeNull());
|
||||
fireEvent.click(screen.getByRole("button", { name: "Issue" }));
|
||||
await waitFor(() => expect(controlled.queries()).toEqual(["", ""]));
|
||||
controlled.reject(1, new Error("tracker is down"));
|
||||
|
||||
expect(await screen.findByText("Search failed: tracker is down")).toBeTruthy();
|
||||
expect(screen.queryByText("Slow sidebar")).toBeNull();
|
||||
});
|
||||
|
||||
|
||||
@@ -148,7 +148,8 @@ export function Combobox<Item extends ComboboxItem>({
|
||||
gcTime: 0,
|
||||
retry: false,
|
||||
});
|
||||
const items: readonly Item[] = results.data ?? NO_RESULTS;
|
||||
// A failed search shows its error, not the results of an earlier one.
|
||||
const items: readonly Item[] = results.isError ? NO_RESULTS : (results.data ?? NO_RESULTS);
|
||||
const item = useMemo<ComposerControlItem>(() => {
|
||||
const choices = items.map(({ id, label, description }) => ({ value: id, label, description }));
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user