diff --git a/frontend/src/metabase-types/api/search.ts b/frontend/src/metabase-types/api/search.ts index 0cbd5a568b13b4ebae5e1414ef344dbf3b2af00e..dde0ac57465ca15a0a67dd4dbbc31e7d96524048 100644 --- a/frontend/src/metabase-types/api/search.ts +++ b/frontend/src/metabase-types/api/search.ts @@ -1,6 +1,6 @@ import { CardId } from "./card"; import { Collection } from "./collection"; -import { DatabaseId } from "./database"; +import { DatabaseId, InitialSyncStatus } from "./database"; import { FieldReference } from "./query"; import { TableId } from "./table"; @@ -66,7 +66,7 @@ export interface SearchResult { model_name: string | null; table_description: string | null; table_name: string | null; - initial_sync_status: "complete" | "incomplete" | null; + initial_sync_status: InitialSyncStatus | null; dashboard_count: number | null; context: any; // this might be a dead property scores: SearchScore[]; diff --git a/frontend/src/metabase/search/components/SearchResult.tsx b/frontend/src/metabase/search/components/SearchResult.tsx index 5c2b98044f11a7084ac69d9c53978ec0a495172f..4f1c6299a825270f55e3bcc9d567dfadbed639e7 100644 --- a/frontend/src/metabase/search/components/SearchResult.tsx +++ b/frontend/src/metabase/search/components/SearchResult.tsx @@ -128,7 +128,7 @@ export function SearchResult({ active={active} compact={compact} to={!onClick ? result.getUrl() : ""} - onClick={onClick ? () => onClick(result) : undefined} + onClick={onClick && active ? () => onClick(result) : undefined} data-testid="search-result-item" > <ResultLinkContent> diff --git a/frontend/src/metabase/search/components/SearchResult.unit.spec.tsx b/frontend/src/metabase/search/components/SearchResult.unit.spec.tsx index e6e835e72a4ca3888083aa42cf1f787d455044d3..622c0f9f3182e246d28c1e60a2f8718b7892e9a3 100644 --- a/frontend/src/metabase/search/components/SearchResult.unit.spec.tsx +++ b/frontend/src/metabase/search/components/SearchResult.unit.spec.tsx @@ -1,8 +1,18 @@ +import userEvent from "@testing-library/user-event"; import { render, screen } from "@testing-library/react"; import { setupEnterpriseTest } from "__support__/enterprise"; -import { createMockSearchResult } from "metabase-types/api/mocks"; -import { getIcon, queryIcon } from "__support__/ui"; - +import { + setupTableEndpoints, + setupDatabaseEndpoints, +} from "__support__/server-mocks"; +import { + createMockSearchResult, + createMockTable, + createMockDatabase, +} from "metabase-types/api/mocks"; +import { getIcon, renderWithProviders, queryIcon } from "__support__/ui"; + +import { InitialSyncStatus } from "metabase-types/api"; import type { WrappedResult } from "./types"; import { SearchResult } from "./SearchResult"; @@ -55,6 +65,59 @@ describe("SearchResult", () => { }); }); +describe("SearchResult > Tables", () => { + interface SetupOpts { + name: string; + initial_sync_status: InitialSyncStatus; + } + + const setup = (setupOpts: SetupOpts) => { + const TEST_TABLE = createMockTable(setupOpts); + const TEST_DATABASE = createMockDatabase(); + setupTableEndpoints(TEST_TABLE); + setupDatabaseEndpoints(TEST_DATABASE); + const result = createWrappedSearchResult({ + model: "table", + table_id: TEST_TABLE.id, + database_id: TEST_DATABASE.id, + getUrl: () => `/table/${TEST_TABLE.id}`, + getIcon: () => ({ name: "table" }), + ...setupOpts, + }); + const onClick = jest.fn(); + renderWithProviders(<SearchResult result={result} onClick={onClick} />); + const link = screen.getByText(result.name); + return { link, onClick }; + }; + + it("tables with initial_sync_status='complete' are clickable", () => { + const { link, onClick } = setup({ + name: "Complete Table", + initial_sync_status: "complete", + }); + userEvent.click(link); + expect(onClick).toHaveBeenCalled(); + }); + + it("tables with initial_sync_status='incomplete' are not clickable", () => { + const { link, onClick } = setup({ + name: "Incomplete Table", + initial_sync_status: "incomplete", + }); + userEvent.click(link); + expect(onClick).not.toHaveBeenCalled(); + }); + + it("tables with initial_sync_status='aborted' are not clickable", () => { + const { link, onClick } = setup({ + name: "Aborted Table", + initial_sync_status: "aborted", + }); + userEvent.click(link); + expect(onClick).not.toHaveBeenCalled(); + }); +}); + describe("SearchResult > Collections", () => { const resultInRegularCollection = createWrappedSearchResult({ name: "My Regular Item",