import { runInAction } from "mobx"; import { screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import PickedFeatures from "../../lib/Map/PickedFeatures/PickedFeatures"; import CompositeCatalogItem from "../../lib/Models/Catalog/CatalogItems/CompositeCatalogItem"; import CommonStrata from "../../lib/Models/Definition/CommonStrata"; import TerriaFeature from "../../lib/Models/Feature/Feature"; import Terria from "../../lib/Models/Terria"; import ViewState from "../../lib/ReactViewModels/ViewState"; import { FeatureInfoPanel, determineCatalogItem } from "../../lib/ReactViews/FeatureInfo/FeatureInfoPanel"; import SimpleCatalogItem from "../Helpers/SimpleCatalogItem"; import { renderWithContexts } from "./withContext"; describe("FeatureInfoPanel", function () { let terria: Terria; let viewState: ViewState; beforeEach(function () { terria = new Terria({ baseUrl: "./" }); viewState = new ViewState({ terria: terria, catalogSearchProvider: undefined }); }); it("has isVisible class when viewState.featureInfoPanelIsVisible is true", function () { runInAction(() => { viewState.featureInfoPanelIsVisible = true; }); const { container } = renderWithContexts( key} />, viewState ); expect(container.querySelector('[class*="is-visible"]')).toBeTruthy(); }); it("displays loader while asychronously loading feature information", function () { const pickedFeatures = new PickedFeatures(); pickedFeatures.allFeaturesAvailablePromise = Promise.resolve(); runInAction(() => { terria.pickedFeatures = pickedFeatures; }); renderWithContexts( key} />, viewState ); // Loader renders a spinning icon (svg) and optional message text expect(screen.getByText("loader.loadingMessage")).toBeInTheDocument(); }); it("does not have isVisible class when viewState.featureInfoPanelIsVisible is false", function () { runInAction(() => { viewState.featureInfoPanelIsVisible = false; }); const { container } = renderWithContexts( key} />, viewState ); expect(container.querySelector('[class*="is-visible"]')).toBeNull(); }); it("shows a feature info sections", async function () { const simple1 = new SimpleCatalogItem("simple1", terria); const feature1 = new TerriaFeature({ name: "Foo" }); feature1._catalogItem = simple1; const feature2 = new TerriaFeature({ name: "Bar" }); const simple2 = new SimpleCatalogItem("simple2", terria); feature2._catalogItem = simple2; const pickedFeatures = new PickedFeatures(); pickedFeatures.allFeaturesAvailablePromise = Promise.resolve(); runInAction(() => { pickedFeatures.features = [feature1, feature2]; pickedFeatures.isLoading = false; }); terria.pickedFeatures = pickedFeatures; terria.workbench.items = [simple1, simple2]; renderWithContexts( key} />, viewState ); await waitFor(() => expect( screen.queryByText("loader.loadingMessage") ).not.toBeInTheDocument() ); expect(screen.queryByText("loader.loadingMessage")).not.toBeInTheDocument(); expect(screen.getByRole("button", { name: "simple1 - Foo" })).toBeVisible(); expect(screen.getByRole("button", { name: "simple2 - Bar" })).toBeVisible(); }); it('opens a feature info section with "featureInfo.noInfoAvailable" message when the feature has no properties', async function () { const feature = new TerriaFeature({ name: "Foo" }); const simple = new SimpleCatalogItem("simple", terria); feature._catalogItem = simple; const pickedFeatures = new PickedFeatures(); pickedFeatures.allFeaturesAvailablePromise = Promise.resolve(); runInAction(() => { pickedFeatures.features = [feature]; pickedFeatures.isLoading = false; }); terria.pickedFeatures = pickedFeatures; terria.workbench.items = [simple]; renderWithContexts( {}} />, viewState ); await waitFor(() => expect( screen.queryByText("loader.loadingMessage") ).not.toBeInTheDocument() ); const button = screen.getByRole("button", { name: "simple - Foo" }); expect(button).toBeVisible(); await userEvent.click(button); expect(screen.getByText("featureInfo.noInfoAvailable")).toBeInTheDocument(); }); it("opens a feature info section with feature properties", async function () { const feature = new TerriaFeature({ name: "Foo", properties: { prop1: "Value 1", prop2: "Value 2" } }); const simple = new SimpleCatalogItem("simple", terria); feature._catalogItem = simple; const pickedFeatures = new PickedFeatures(); pickedFeatures.allFeaturesAvailablePromise = Promise.resolve(); runInAction(() => { pickedFeatures.features = [feature]; pickedFeatures.isLoading = false; }); terria.pickedFeatures = pickedFeatures; terria.workbench.items = [simple]; renderWithContexts( {}} />, viewState ); await waitFor(() => expect( screen.queryByText("loader.loadingMessage") ).not.toBeInTheDocument() ); const button = screen.getByRole("button", { name: "simple - Foo" }); expect(button).toBeVisible(); await userEvent.click(button); expect(screen.getByText("prop1")).toBeInTheDocument(); expect(screen.getByText("Value 1")).toBeInTheDocument(); expect(screen.getByText("prop2")).toBeInTheDocument(); expect(screen.getByText("Value 2")).toBeInTheDocument(); }); describe("determineCatalogItem", function () { let simple1: SimpleCatalogItem, simple2: SimpleCatalogItem, composite: CompositeCatalogItem; let feature1: TerriaFeature, feature2: TerriaFeature; beforeEach(function () { feature1 = new TerriaFeature({}); simple1 = new SimpleCatalogItem("simple1", terria); feature1._catalogItem = simple1; feature2 = new TerriaFeature({}); simple2 = new SimpleCatalogItem("simple2", terria); feature2._catalogItem = simple2; composite = new CompositeCatalogItem("composite", terria); composite.add(CommonStrata.definition, simple1); composite.add(CommonStrata.definition, simple2); }); it("determines which catalog item a feature belongs to", function () { terria.workbench.items = [simple1, simple2]; expect(determineCatalogItem(terria.workbench, feature1)).toBe(simple1); expect(determineCatalogItem(terria.workbench, feature2)).toBe(simple2); }); it("special cases features from composite models", function () { terria.workbench.items = [composite]; expect(determineCatalogItem(terria.workbench, feature1)).toBe(simple1); expect(determineCatalogItem(terria.workbench, feature2)).toBe(simple2); }); }); });