import { render, screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import i18next from "i18next"; import { runInAction } from "mobx"; import CatalogMemberMixin from "../../../lib/ModelMixins/CatalogMemberMixin"; import WebMapServiceCatalogItem from "../../../lib/Models/Catalog/Ows/WebMapServiceCatalogItem"; import WebProcessingServiceCatalogFunction from "../../../lib/Models/Catalog/Ows/WebProcessingServiceCatalogFunction"; import CommonStrata from "../../../lib/Models/Definition/CommonStrata"; import Terria from "../../../lib/Models/Terria"; import ViewState from "../../../lib/ReactViewModels/ViewState"; import DataCatalogItem from "../../../lib/ReactViews/DataCatalog/DataCatalogItem"; import { withThemeContext } from "../withContext"; describe("DataCatalogItem", () => { let terria: Terria; let viewState: ViewState; let item: CatalogMemberMixin.Instance; let wmsItem: WebMapServiceCatalogItem; let removable: boolean; beforeAll(async () => { await i18next.changeLanguage("en"); }); beforeEach(async () => { terria = new Terria({ baseUrl: "./" }); viewState = new ViewState({ terria: terria, catalogSearchProvider: undefined }); wmsItem = new WebMapServiceCatalogItem("test", terria); runInAction(() => { viewState.explorerPanelIsVisible = true; viewState.mobileView = viewState.mobileViewOptions.data; wmsItem.setTrait("definition", "url", "test/WMS/single_metadata_url.xml"); }); // Use wmsItem for most tests, except for a couple that need to use a WPS item item = wmsItem; removable = false; spyOn(viewState, "viewCatalogMember").and.callThrough(); spyOn(viewState, "switchMobileView"); }); afterAll(async function () { await i18next.changeLanguage("cimode"); }); it("text click", async () => { render( withThemeContext( ) ); await userEvent.click(screen.getByRole("button", { name: item.name })); expect(viewState.viewCatalogMember).toHaveBeenCalledWith(item); expect(viewState.switchMobileView).toHaveBeenCalledWith( viewState.mobileViewOptions.preview ); expect(terria.workbench.contains(item)).toBe(false); }); describe("button click", () => { it("when not on mobile and with a non-invokeable layer and not user supplied", async () => { render( withThemeContext( ) ); await userEvent.click(screen.getByRole("button", { name: "Add" })); expect(terria.workbench.contains(item)).toBe(true); }); it("when on mobile and not user supplied", async () => { runInAction(() => { viewState.useSmallScreenInterface = true; }); render( withThemeContext( ) ); await userEvent.click(screen.getByRole("button", { name: "Preview" })); expect(viewState.viewCatalogMember).toHaveBeenCalledWith(item); expect(viewState.switchMobileView).toHaveBeenCalledWith( viewState.mobileViewOptions.preview ); expect(terria.workbench.contains(item)).toBe(false); }); it("when with an invokeable layer", async () => { item = new WebProcessingServiceCatalogFunction("test-wps", terria); render( withThemeContext( ) ); await userEvent.click(screen.getByRole("button", { name: "" })); expect(viewState.viewCatalogMember).toHaveBeenCalledWith(item); expect(viewState.switchMobileView).toHaveBeenCalledWith( viewState.mobileViewOptions.preview ); expect(terria.workbench.contains(item)).toBe(false); }); describe("close modal after added data when not user supplied", () => { it("closes the explorer panel visible", async () => { render( withThemeContext( ) ); await userEvent.click(screen.getByRole("button", { name: "Add" })); await waitFor(() => { expect(viewState.explorerPanelIsVisible).toBe(false); }); }); it("doesn't close the explorer panel if keepCatalogOpen is set", async () => { runInAction(() => { terria.configParameters.keepCatalogOpen = true; }); render( withThemeContext( ) ); await userEvent.click(screen.getByRole("button", { name: "Add" })); await waitFor(() => expect(viewState.explorerPanelIsVisible).toBe(true) ); }); }); describe("does not close modal", () => { it("when control key pressed", async () => { const user = userEvent.setup(); render( withThemeContext( ) ); await user.keyboard("{Control>}"); await user.click(screen.getByRole("button", { name: "Add" })); await user.keyboard("{/Control}"); expect(viewState.explorerPanelIsVisible).toBe(true); expect(viewState.mobileView).not.toBeNull(); }); it("when shift key pressed", async () => { const user = userEvent.setup(); render( withThemeContext( ) ); await user.keyboard("{Shift>}"); await user.click(screen.getByRole("button", { name: "Add" })); await user.keyboard("{/Shift}"); expect(viewState.explorerPanelIsVisible).toBe(true); expect(viewState.mobileView).not.toBeNull(); }); }); }); describe("renders", () => { it("a single ", () => { render( withThemeContext( ) ); expect(screen.getAllByRole("button", { name: "Add" }).length).toBe(1); }); describe("btnState prop as", () => { it('"loading" if item is loading', () => { runInAction(() => { (wmsItem as any)._metadataLoader._isLoading = true; viewState.useSmallScreenInterface = true; }); render( withThemeContext( ) ); expect(screen.getAllByRole("button").length).toBe(2); expect( screen.getByRole("button", { name: "Loading..." }) ).toBeVisible(); }); it('"preview" if on mobile and not loading', () => { runInAction(() => { viewState.useSmallScreenInterface = true; }); render( withThemeContext( ) ); expect(screen.getAllByRole("button").length).toBe(2); expect(screen.getByRole("button", { name: "Preview" })).toBeVisible(); }); it('"remove" if item is enabled and not loading and not on mobile', async () => { // user supplied data does not have add/remove button, regardless // if they have trash button await terria.workbench.add(wmsItem); render( withThemeContext( ) ); expect(screen.getAllByRole("button").length).toBe(2); expect( screen.getByRole("button", { name: "Remove from map" }) ).toBeVisible(); }); it('"add" if item removable but NOT enabled', () => { // If removable, btnstate should still be add or remove removable = true; render( withThemeContext( ) ); expect(screen.getAllByRole("button").length).toBe(3); expect(screen.getByRole("button", { name: "Add" })).toBeVisible(); expect( screen.queryByRole("button", { name: "Remove from catalogue" }) ).toBeVisible(); }); it('"remove" if item removable but enabled', async () => { // If removable, btnstate should still be add or remove await terria.workbench.add(wmsItem); removable = true; render( withThemeContext( ) ); expect(screen.getAllByRole("button").length).toBe(3); expect( screen.getByRole("button", { name: "Remove from map" }) ).toBeVisible(); expect( screen.queryByRole("button", { name: "Remove from catalogue" }) ).toBeVisible(); }); it('"add" if item is not invokeable, not enabled and not loading and not on mobile', () => { render( withThemeContext( ) ); expect(screen.getAllByRole("button").length).toBe(2); expect(screen.getByRole("button", { name: "Add" })).toBeVisible(); }); it('"stats" if item is invokeable, not user-supplied, not enabled and not loading and not on mobile', () => { item = new WebProcessingServiceCatalogFunction("test-wps", terria); render( withThemeContext( ) ); expect(screen.getAllByRole("button").length).toBe(2); expect(screen.getByRole("button", { name: "" })).toBeVisible(); }); }); it("sets the CatalogItem text as the item name", () => { wmsItem.setTrait(CommonStrata.definition, "name", "TEST!!!"); render( withThemeContext( ) ); expect(screen.getByText("TEST!!!")).toBeVisible(); }); }); });