diff --git a/public/pages/CreateSnapshotPolicy/containers/CreateSnapshotPolicy/CreateSnapshotPolicy.test.tsx b/public/pages/CreateSnapshotPolicy/containers/CreateSnapshotPolicy/CreateSnapshotPolicy.test.tsx new file mode 100644 index 000000000..0c2b825d4 --- /dev/null +++ b/public/pages/CreateSnapshotPolicy/containers/CreateSnapshotPolicy/CreateSnapshotPolicy.test.tsx @@ -0,0 +1,199 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from "react"; +import "@testing-library/jest-dom/extend-expect"; +import { render, waitFor } from "@testing-library/react"; +import { MemoryRouter as Router, Redirect, Route, Switch, RouteComponentProps } from "react-router-dom"; +import { CoreStart } from "opensearch-dashboards/public"; +import CreateSnapshotPolicy from "./CreateSnapshotPolicy"; +import { browserServicesMock, coreServicesMock } from "../../../../../test/mocks"; +import { ROUTES } from "../../../../utils/constants"; +import { ServicesConsumer, ServicesContext } from "../../../../services"; +import { ModalProvider, ModalRoot } from "../../../../components/Modal"; +import { CoreServicesConsumer, CoreServicesContext } from "../../../../components/core_services"; +import { getApplication, getNavigationUI, getUISettings } from "../../../../services/Services"; +import { BrowserServices } from "../../../../models/interfaces"; + +jest.mock("../../../../services/Services", () => ({ + ...jest.requireActual("../../../../services/Services"), + getUISettings: jest.fn(), + getApplication: jest.fn(), + getNavigationUI: jest.fn(), +})); + +beforeEach(() => { + (getUISettings as jest.Mock).mockReturnValue({ + get: jest.fn().mockReturnValue(false), + }); + (getApplication as jest.Mock).mockReturnValue({}); + (getNavigationUI as jest.Mock).mockReturnValue({}); +}); + +function renderCreateSnapshotPolicyWithRouter(initialEntries = ["/"], isEdit = false) { + return { + ...render( + + + + + {(services: BrowserServices | null) => + services && ( + + {(core: CoreStart | null) => + core && ( + + + + ( + + )} + /> + ( + + )} + /> + Testing Snapshot Policies} /> + + + + ) + } + + ) + } + + + + + ), + }; +} + +describe(" spec", () => { + it("renders the component", async () => { + const { container } = renderCreateSnapshotPolicyWithRouter(); + await waitFor(() => {}); + expect(container.firstChild).toMatchSnapshot(); + }); + + it("sets breadcrumbs when mounting", async () => { + renderCreateSnapshotPolicyWithRouter(); + expect(coreServicesMock.chrome.setBreadcrumbs).toHaveBeenCalledTimes(1); + }); + + it("handles indices as array format when editing policy", async () => { + // Mock the getPolicy response with indices as array + browserServicesMock.snapshotManagementService.getPolicy = jest.fn().mockResolvedValue({ + ok: true, + response: { + id: "test-policy", + seqNo: 0, + primaryTerm: 1, + policy: { + name: "test-policy", + description: "Test policy", + snapshot_config: { + indices: ["index1", "index2", "index3"], + repository: "test-repo" + }, + creation: { + schedule: { + cron: { + expression: "0 0 * * *", + timezone: "UTC" + } + } + }, + enabled: true + } + } + }); + + const { getByText } = renderCreateSnapshotPolicyWithRouter(["/edit-snapshot-policy?id=test-policy"], true); + + await waitFor(() => { + // Wait for the policy to load without error + expect(browserServicesMock.snapshotManagementService.getPolicy).toHaveBeenCalledWith("test-policy"); + // No error toasts should be shown + expect(coreServicesMock.notifications.toasts.addDanger).not.toHaveBeenCalled(); + }); + }); + + it("handles indices as string format when editing policy", async () => { + // Mock the getPolicy response with indices as string + browserServicesMock.snapshotManagementService.getPolicy = jest.fn().mockResolvedValue({ + ok: true, + response: { + id: "test-policy", + seqNo: 0, + primaryTerm: 1, + policy: { + name: "test-policy", + description: "Test policy", + snapshot_config: { + indices: "index1,index2,index3", + repository: "test-repo" + }, + creation: { + schedule: { + cron: { + expression: "0 0 * * *", + timezone: "UTC" + } + } + }, + enabled: true + } + } + }); + + const { getByText } = renderCreateSnapshotPolicyWithRouter(["/edit-snapshot-policy?id=test-policy"], true); + + await waitFor(() => { + expect(browserServicesMock.snapshotManagementService.getPolicy).toHaveBeenCalledWith("test-policy"); + expect(coreServicesMock.notifications.toasts.addDanger).not.toHaveBeenCalled(); + }); + }); + + it("handles policy loading error gracefully", async () => { + browserServicesMock.snapshotManagementService.getPolicy = jest.fn().mockResolvedValue({ + ok: false, + error: "Policy not found" + }); + + const { getByText } = renderCreateSnapshotPolicyWithRouter(["/edit-snapshot-policy?id=test-policy"], true); + + await waitFor(() => getByText("Testing Snapshot Policies")); + expect(coreServicesMock.notifications.toasts.addDanger).toHaveBeenCalledWith( + "Could not load the policy: Policy not found" + ); + }); + + it("handles policy loading exception gracefully", async () => { + browserServicesMock.snapshotManagementService.getPolicy = jest.fn().mockRejectedValue(new Error("Network error")); + + const { getByText } = renderCreateSnapshotPolicyWithRouter(["/edit-snapshot-policy?id=test-policy"], true); + + await waitFor(() => getByText("Testing Snapshot Policies")); + expect(coreServicesMock.notifications.toasts.addDanger).toHaveBeenCalledWith("Could not load the policy"); + }); +}); \ No newline at end of file diff --git a/public/pages/CreateSnapshotPolicy/containers/CreateSnapshotPolicy/CreateSnapshotPolicy.tsx b/public/pages/CreateSnapshotPolicy/containers/CreateSnapshotPolicy/CreateSnapshotPolicy.tsx index 6b7012cdc..455a16180 100644 --- a/public/pages/CreateSnapshotPolicy/containers/CreateSnapshotPolicy/CreateSnapshotPolicy.tsx +++ b/public/pages/CreateSnapshotPolicy/containers/CreateSnapshotPolicy/CreateSnapshotPolicy.tsx @@ -234,14 +234,23 @@ export class CreateSnapshotPolicy extends MDSEnabledComponent !!index) - .map((label: string) => ({ label })); + + // Handle both array and string format for indices + let selectedIndexOptions: { label: string }[] = []; + if (Array.isArray(indices)) { + selectedIndexOptions = indices + .filter((index: string) => !!index) + .map((label: string) => ({ label })); + } else if (typeof indices === 'string') { + selectedIndexOptions = indices + .split(",") + .filter((index: string) => !!index) + .map((label: string) => ({ label })); + } const selectedRepoValue = _.get(policy, "snapshot_config.repository", ""); const { frequencyType: creationScheduleFrequencyType } = parseCronExpression(_.get(policy, "creation.schedule.cron.expression"));