mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-22 23:30:10 +00:00
307 lines
9.6 KiB
TypeScript
307 lines
9.6 KiB
TypeScript
import DuplicateModel from "../../../UI/Components/DuplicateModel/DuplicateModel";
|
|
import { ModelField } from "../../../UI/Components/Forms/ModelForm";
|
|
import Select from "../../../UI/Utils/BaseDatabase/Select";
|
|
import { describe, expect, it, jest } from "@jest/globals";
|
|
import {
|
|
fireEvent,
|
|
render,
|
|
screen,
|
|
waitFor,
|
|
within,
|
|
} from "@testing-library/react";
|
|
import BaseModel from "Common/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
import Route from "Common/Types/API/Route";
|
|
import CrudApiEndpoint from "Common/Types/Database/CrudApiEndpoint";
|
|
import TableMetaData from "Common/Types/Database/TableMetadata";
|
|
import IconProp from "Common/Types/Icon/IconProp";
|
|
import ObjectID from "Common/Types/ObjectID";
|
|
import React from "react";
|
|
import { act } from "react-test-renderer";
|
|
|
|
@TableMetaData({
|
|
tableName: "Foo",
|
|
singularName: "Foo",
|
|
pluralName: "Foos",
|
|
icon: IconProp.Wrench,
|
|
tableDescription: "A test model",
|
|
})
|
|
@CrudApiEndpoint(new Route("/testModel"))
|
|
class TestModel extends BaseModel {
|
|
public changeThis?: string = "original";
|
|
}
|
|
|
|
jest.mock("../../../UI/Utils/ModelAPI/ModelAPI", () => {
|
|
return {
|
|
getItem: (jest.fn() as jest.Mock)
|
|
.mockResolvedValueOnce({
|
|
changeThis: "changed",
|
|
setValue: function (key: "changeThis", value: string) {
|
|
this[key] = value;
|
|
},
|
|
removeValue: jest.fn(),
|
|
})
|
|
.mockResolvedValueOnce({
|
|
changeThis: "changed",
|
|
setValue: function (key: "changeThis", value: string) {
|
|
this[key] = value;
|
|
},
|
|
removeValue: jest.fn(),
|
|
})
|
|
.mockResolvedValueOnce(undefined),
|
|
create: (jest.fn() as jest.Mock)
|
|
.mockResolvedValueOnce({
|
|
data: {
|
|
id: "foobar",
|
|
changeThis: "changed",
|
|
},
|
|
})
|
|
.mockResolvedValueOnce(undefined),
|
|
};
|
|
});
|
|
|
|
jest.mock("../../../UI/Utils/Navigation", () => {
|
|
return {
|
|
navigate: jest.fn(),
|
|
};
|
|
});
|
|
|
|
describe("DuplicateModel", () => {
|
|
const fieldsToDuplicate: Select<TestModel> = {};
|
|
const fieldsToChange: Array<ModelField<TestModel>> = [
|
|
{
|
|
field: {
|
|
changeThis: true,
|
|
},
|
|
title: "Change This",
|
|
required: false,
|
|
placeholder: "You can change this",
|
|
},
|
|
];
|
|
it("renders correctly", () => {
|
|
render(
|
|
<DuplicateModel
|
|
modelType={TestModel}
|
|
modelId={new ObjectID("foo")}
|
|
fieldsToDuplicate={fieldsToDuplicate}
|
|
fieldsToChange={fieldsToChange}
|
|
/>,
|
|
);
|
|
expect(screen.getByTestId("card-details-heading")?.textContent).toBe(
|
|
"Duplicate Foo",
|
|
);
|
|
expect(screen.getByTestId("card-description")?.textContent).toBe(
|
|
"Duplicating this foo will create another foo exactly like this one.",
|
|
);
|
|
expect(screen.getByTestId("card-button")?.textContent).toBe(
|
|
"Duplicate Foo",
|
|
);
|
|
});
|
|
it("shows confirmation modal when duplicate button is clicked", () => {
|
|
render(
|
|
<DuplicateModel
|
|
modelType={TestModel}
|
|
modelId={new ObjectID("foo")}
|
|
fieldsToDuplicate={fieldsToDuplicate}
|
|
fieldsToChange={fieldsToChange}
|
|
/>,
|
|
);
|
|
const button: HTMLElement = screen.getByRole("button", {
|
|
name: "Duplicate Foo",
|
|
});
|
|
fireEvent.click(button);
|
|
expect(screen.getByRole("dialog")).toBeDefined();
|
|
const confirmDialog: HTMLElement = screen.getByRole("dialog");
|
|
expect(within(confirmDialog).getByTestId("modal-title")?.textContent).toBe(
|
|
"Duplicate Foo",
|
|
);
|
|
expect(
|
|
within(confirmDialog).getByTestId("modal-description")?.textContent,
|
|
).toBe("Are you sure you want to duplicate this foo?");
|
|
expect(
|
|
within(confirmDialog).getByTestId("modal-footer-submit-button")
|
|
?.textContent,
|
|
).toBe("Duplicate Foo");
|
|
expect(
|
|
within(confirmDialog).getByTestId("modal-footer-close-button")
|
|
?.textContent,
|
|
).toBe("Close");
|
|
});
|
|
it("duplicates item when confirmation button is clicked", async () => {
|
|
const onDuplicateSuccess: (item: TestModel) => void = jest.fn();
|
|
render(
|
|
<DuplicateModel
|
|
modelType={TestModel}
|
|
modelId={new ObjectID("foo")}
|
|
fieldsToDuplicate={fieldsToDuplicate}
|
|
fieldsToChange={fieldsToChange}
|
|
onDuplicateSuccess={onDuplicateSuccess}
|
|
navigateToOnSuccess={new Route("/done")}
|
|
/>,
|
|
);
|
|
const button: HTMLElement = screen.getByRole("button", {
|
|
name: "Duplicate Foo",
|
|
});
|
|
void act(() => {
|
|
fireEvent.click(button);
|
|
});
|
|
const dialog: HTMLElement = screen.getByRole("dialog");
|
|
const confirmationButton: HTMLElement = within(dialog).getByRole("button", {
|
|
name: "Duplicate Foo",
|
|
});
|
|
void act(() => {
|
|
fireEvent.click(confirmationButton);
|
|
});
|
|
await waitFor(() => {
|
|
return expect(onDuplicateSuccess).toBeCalledWith({
|
|
id: "foobar",
|
|
changeThis: "changed",
|
|
});
|
|
});
|
|
await waitFor(() => {
|
|
return expect(
|
|
require("../../../UI/Utils/Navigation").navigate,
|
|
).toBeCalledWith(new Route("/done/foobar"), {
|
|
forceNavigate: true,
|
|
});
|
|
});
|
|
});
|
|
it("closes confirmation dialog when close button is clicked", () => {
|
|
const onDuplicateSuccess: (item: TestModel) => void = jest.fn();
|
|
render(
|
|
<DuplicateModel
|
|
modelType={TestModel}
|
|
modelId={new ObjectID("foo")}
|
|
fieldsToDuplicate={fieldsToDuplicate}
|
|
fieldsToChange={fieldsToChange}
|
|
onDuplicateSuccess={onDuplicateSuccess}
|
|
navigateToOnSuccess={new Route("/done")}
|
|
/>,
|
|
);
|
|
const button: HTMLElement = screen.getByRole("button", {
|
|
name: "Duplicate Foo",
|
|
});
|
|
void act(() => {
|
|
fireEvent.click(button);
|
|
});
|
|
const dialog: HTMLElement = screen.getByRole("dialog");
|
|
const closeButton: HTMLElement = within(dialog).getByRole("button", {
|
|
name: "Close",
|
|
});
|
|
void act(() => {
|
|
fireEvent.click(closeButton);
|
|
});
|
|
expect(screen.queryByRole("dialog")).toBeFalsy();
|
|
});
|
|
it("handles could not create error correctly", async () => {
|
|
const onDuplicateSuccess: (item: TestModel) => void = jest.fn();
|
|
render(
|
|
<DuplicateModel
|
|
modelType={TestModel}
|
|
modelId={new ObjectID("foo")}
|
|
fieldsToDuplicate={fieldsToDuplicate}
|
|
fieldsToChange={fieldsToChange}
|
|
onDuplicateSuccess={onDuplicateSuccess}
|
|
navigateToOnSuccess={new Route("/done")}
|
|
/>,
|
|
);
|
|
const button: HTMLElement = screen.getByRole("button", {
|
|
name: "Duplicate Foo",
|
|
});
|
|
void act(() => {
|
|
fireEvent.click(button);
|
|
});
|
|
const dialog: HTMLElement = screen.getByRole("dialog");
|
|
const confirmationButton: HTMLElement = within(dialog).getByRole("button", {
|
|
name: "Duplicate Foo",
|
|
});
|
|
void act(() => {
|
|
fireEvent.click(confirmationButton);
|
|
});
|
|
await screen.findByText("Duplicate Error");
|
|
const errorDialog: HTMLElement = screen.getByRole("dialog");
|
|
expect(within(errorDialog).getByTestId("modal-title")?.textContent).toBe(
|
|
"Duplicate Error",
|
|
);
|
|
expect(
|
|
within(errorDialog).getByTestId("confirm-modal-description")?.textContent,
|
|
).toBe("Error: Could not create Foo");
|
|
expect(
|
|
within(errorDialog).getByTestId("modal-footer-submit-button")
|
|
?.textContent,
|
|
).toBe("Close");
|
|
});
|
|
it("handles item not found error correctly", async () => {
|
|
const onDuplicateSuccess: (item: TestModel) => void = jest.fn();
|
|
render(
|
|
<DuplicateModel
|
|
modelType={TestModel}
|
|
modelId={new ObjectID("foo")}
|
|
fieldsToDuplicate={fieldsToDuplicate}
|
|
fieldsToChange={fieldsToChange}
|
|
onDuplicateSuccess={onDuplicateSuccess}
|
|
navigateToOnSuccess={new Route("/done")}
|
|
/>,
|
|
);
|
|
const button: HTMLElement = screen.getByRole("button", {
|
|
name: "Duplicate Foo",
|
|
});
|
|
void act(() => {
|
|
fireEvent.click(button);
|
|
});
|
|
const dialog: HTMLElement = screen.getByRole("dialog");
|
|
const confirmationButton: HTMLElement = within(dialog).getByRole("button", {
|
|
name: "Duplicate Foo",
|
|
});
|
|
void act(() => {
|
|
fireEvent.click(confirmationButton);
|
|
});
|
|
await screen.findByText("Duplicate Error");
|
|
const errorDialog: HTMLElement = screen.getByRole("dialog");
|
|
expect(within(errorDialog).getByTestId("modal-title")?.textContent).toBe(
|
|
"Duplicate Error",
|
|
);
|
|
expect(
|
|
within(errorDialog).getByTestId("confirm-modal-description")?.textContent,
|
|
).toBe("Error: Could not find Foo with id foo");
|
|
expect(
|
|
within(errorDialog).getByTestId("modal-footer-submit-button")
|
|
?.textContent,
|
|
).toBe("Close");
|
|
});
|
|
it("closes error dialog when close button is clicked", async () => {
|
|
const onDuplicateSuccess: (item: TestModel) => void = jest.fn();
|
|
render(
|
|
<DuplicateModel
|
|
modelType={TestModel}
|
|
modelId={new ObjectID("foo")}
|
|
fieldsToDuplicate={fieldsToDuplicate}
|
|
fieldsToChange={fieldsToChange}
|
|
onDuplicateSuccess={onDuplicateSuccess}
|
|
navigateToOnSuccess={new Route("/done")}
|
|
/>,
|
|
);
|
|
const button: HTMLElement = screen.getByRole("button", {
|
|
name: "Duplicate Foo",
|
|
});
|
|
void act(() => {
|
|
fireEvent.click(button);
|
|
});
|
|
const dialog: HTMLElement = screen.getByRole("dialog");
|
|
const confirmationButton: HTMLElement = within(dialog).getByRole("button", {
|
|
name: "Duplicate Foo",
|
|
});
|
|
void act(() => {
|
|
fireEvent.click(confirmationButton);
|
|
});
|
|
await screen.findByText("Duplicate Error");
|
|
const errorDialog: HTMLElement = screen.getByRole("dialog");
|
|
const closeButton: HTMLElement = within(errorDialog).getByRole("button", {
|
|
name: "Close",
|
|
});
|
|
void act(() => {
|
|
fireEvent.click(closeButton);
|
|
});
|
|
expect(screen.queryByRole("dialog")).toBeFalsy();
|
|
});
|
|
});
|