/* * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ import React from "react"; import "@testing-library/jest-dom/extend-expect"; import { render, fireEvent, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import RetryModal from "./RetryModal"; import { browserServicesMock, coreServicesMock } from "../../../../../test/mocks"; import { ManagedIndexItem } from "../../../../../models/interfaces"; import { CoreServicesContext } from "../../../../components/core_services"; const retryItems: ManagedIndexItem[] = [ { index: "some_index", indexUuid: "some-index-uuid", policyId: "some_policy", policySeqNo: 1, policyPrimaryTerm: 1, policy: { description: "some description", default_state: "one", states: [ { name: "one", actions: [{ delete: {} }], transitions: [] }, { name: "two", actions: [{ delete: {} }], transitions: [] }, ], }, enabled: false, managedIndexMetaData: null, }, ]; describe(" spec", () => { it("renders the component", () => { render( {}} />); // EuiOverlayMask appends an element to the body so we should have three (used to be two, after upgrading appears to have 3 now), an empty div from react-test-library // and our EuiOverlayMask element expect(document.body.children).toHaveLength(3); expect(document.body.children[2]).toMatchSnapshot(); }); it("calls close when close button clicked", () => { const onClose = jest.fn(); const { getByTestId } = render(); fireEvent.click(getByTestId("retryModalCloseButton")); expect(onClose).toHaveBeenCalled(); }); it("disables select from state when no common states", () => { const retryItems: ManagedIndexItem[] = [ { index: "some_index_1", indexUuid: "some-index-uuid-1", policyId: "some_policy_1", policySeqNo: 1, policyPrimaryTerm: 1, policy: { description: "some description", default_state: "one", states: [ { name: "one", actions: [{ delete: {} }], transitions: [] }, { name: "two", actions: [{ delete: {} }], transitions: [] }, { name: "three", actions: [{ delete: {} }], transitions: [] }, ], }, enabled: false, managedIndexMetaData: null, }, { index: "some_index_2", indexUuid: "some-index-uuid-2", policyId: "some_policy_2", policySeqNo: 1, policyPrimaryTerm: 1, policy: { description: "some description", default_state: "five", states: [{ name: "five", actions: [{ delete: {} }], transitions: [] }], }, enabled: false, managedIndexMetaData: null, }, { index: "some_index_3", indexUuid: "some-index-uuid-3", policyId: "some_policy_3", policySeqNo: 1, policyPrimaryTerm: 1, policy: { description: "some description", default_state: "two", states: [ { name: "two", actions: [{ delete: {} }], transitions: [] }, { name: "three", actions: [{ delete: {} }], transitions: [] }, ], }, enabled: false, managedIndexMetaData: null, }, ]; const { getByLabelText } = render( {}} core={coreServicesMock} /> ); expect(getByLabelText("Retry failed policy from")).toBeDisabled(); }); it("disables select from state when item has no policy", () => { const retryItems: ManagedIndexItem[] = [ { index: "some_index_1", indexUuid: "some-index-uuid-1", policyId: "some_policy_1", policySeqNo: 1, policyPrimaryTerm: 1, policy: { description: "some description", default_state: "one", states: [ { name: "one", actions: [{ delete: {} }], transitions: [] }, { name: "two", actions: [{ delete: {} }], transitions: [] }, { name: "three", actions: [{ delete: {} }], transitions: [] }, ], }, enabled: false, managedIndexMetaData: null, }, { index: "some_index_2", indexUuid: "some-index-uuid-2", policyId: "some_policy_2", policySeqNo: 1, policyPrimaryTerm: 1, policy: { description: "some description", default_state: "two", states: [ { name: "two", actions: [{ delete: {} }], transitions: [] }, { name: "three", actions: [{ delete: {} }], transitions: [] }, ], }, enabled: false, managedIndexMetaData: null, }, { index: "some_index_3", indexUuid: "some-index-uuid-3", policyId: "some_policy_3", policySeqNo: 1, policyPrimaryTerm: 1, policy: null, enabled: false, managedIndexMetaData: null, }, ]; const { getByLabelText } = render( {}} /> ); expect(getByLabelText("Retry failed policy from")).toBeDisabled(); }); it("can select a different state to retry from", async () => { browserServicesMock.managedIndexService.retryManagedIndexPolicy = jest .fn() .mockResolvedValue({ ok: true, response: { updatedIndices: 1, failedIndices: [], failures: false } }); const { getByLabelText, getByTestId, getByText } = render( {" "} {}} /> ); fireEvent.click(getByLabelText("Retry policy from selected state")); // @ts-ignore expect(getByText("two").selected).toBe(false); userEvent.selectOptions(getByLabelText("Retry failed policy from"), ["two"]); // trigger change until this is merged in: https://github.com/testing-library/user-event/pull/131 fireEvent.change(getByLabelText("Retry failed policy from")); // @ts-ignore expect(getByText("two").selected).toBe(true); fireEvent.click(getByTestId("retryModalRetryButton")); await waitFor(() => {}); expect(browserServicesMock.managedIndexService.retryManagedIndexPolicy).toHaveBeenCalledWith(["some_index"], "two"); expect(coreServicesMock.notifications.toasts.addSuccess).toHaveBeenCalledTimes(1); expect(coreServicesMock.notifications.toasts.addSuccess).toHaveBeenCalledWith("Retried 1 managed indices"); }); it("shows error toaster when error is thrown", async () => { browserServicesMock.managedIndexService.retryManagedIndexPolicy = jest.fn().mockRejectedValue(new Error("this is an error")); const { getByTestId } = render( {}} /> ); fireEvent.click(getByTestId("retryModalRetryButton")); await waitFor(() => {}); expect(coreServicesMock.notifications.toasts.addDanger).toHaveBeenCalledTimes(1); expect(coreServicesMock.notifications.toasts.addDanger).toHaveBeenCalledWith("this is an error"); }); it("shows error toaster when error is returned", async () => { browserServicesMock.managedIndexService.retryManagedIndexPolicy = jest.fn().mockResolvedValue({ ok: false, error: "some error" }); const { getByTestId } = render( {}} /> ); fireEvent.click(getByTestId("retryModalRetryButton")); await waitFor(() => {}); expect(coreServicesMock.notifications.toasts.addDanger).toHaveBeenCalledTimes(1); expect(coreServicesMock.notifications.toasts.addDanger).toHaveBeenCalledWith("some error"); }); it("shows error toaster with each failed reason", async () => { browserServicesMock.managedIndexService.retryManagedIndexPolicy = jest.fn().mockResolvedValue({ ok: true, response: { updatedIndices: 0, failures: true, failedIndices: [{ indexName: "index_a", reason: "some reason" }] }, }); const { getByTestId } = render( {}} /> ); fireEvent.click(getByTestId("retryModalRetryButton")); await waitFor(() => {}); expect(coreServicesMock.notifications.toasts.addDanger).toHaveBeenCalledTimes(1); expect(coreServicesMock.notifications.toasts.addDanger).toHaveBeenCalledWith("Failed to retry: [index_a, some reason]"); }); });