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();
});
});
});