153 lines
3.7 KiB
TypeScript
153 lines
3.7 KiB
TypeScript
/**
|
|
* @vitest-environment jsdom
|
|
*/
|
|
import {
|
|
cleanup,
|
|
fireEvent,
|
|
render,
|
|
screen,
|
|
waitFor,
|
|
} from "@testing-library/react";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import PriceForm from "./price-form";
|
|
|
|
globalThis.ResizeObserver = class ResizeObserver {
|
|
observe() {
|
|
return;
|
|
}
|
|
unobserve() {
|
|
return;
|
|
}
|
|
disconnect() {
|
|
return;
|
|
}
|
|
};
|
|
Element.prototype.scrollIntoView = function scrollIntoView() {
|
|
return;
|
|
};
|
|
|
|
vi.mock("react-i18next", () => ({
|
|
useTranslation: () => ({
|
|
t: (_key: string, fallback: string): string => fallback,
|
|
}),
|
|
}));
|
|
|
|
const rules: API.PromoRule[] = [
|
|
{
|
|
id: 1,
|
|
name: "Campaign Rule",
|
|
type: "campaign",
|
|
params: {},
|
|
priority: 1,
|
|
enabled: true,
|
|
},
|
|
];
|
|
|
|
const subscribes: API.SubscribeItem[] = [
|
|
{
|
|
id: 8,
|
|
name: "Monthly Plan",
|
|
unit_price: 1200,
|
|
unit_time: "Month",
|
|
sold: 0,
|
|
discount: [
|
|
{
|
|
quantity: 3,
|
|
discount: 90,
|
|
},
|
|
],
|
|
},
|
|
];
|
|
const subscribesWithoutDiscounts: API.SubscribeItem[] = [
|
|
{
|
|
id: 8,
|
|
name: "Monthly Plan",
|
|
unit_price: 1200,
|
|
unit_time: "Month",
|
|
sold: 0,
|
|
discount: [],
|
|
},
|
|
];
|
|
|
|
async function selectCombobox(index: number, option: string) {
|
|
const combobox = screen.getAllByRole("combobox")[index];
|
|
if (!combobox) throw new Error(`Combobox ${index} not found`);
|
|
fireEvent.click(combobox);
|
|
fireEvent.click(await screen.findByText(option));
|
|
}
|
|
|
|
afterEach(() => {
|
|
cleanup();
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe("PriceForm", () => {
|
|
it("submits promo price with promo_rule_id and selected quantity item", async () => {
|
|
const onSubmit = vi.fn().mockResolvedValue(true);
|
|
render(
|
|
<PriceForm onSubmit={onSubmit} rules={rules} subscribes={subscribes} />
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: "Create Promo Price" }));
|
|
await selectCombobox(0, "Campaign Rule");
|
|
await selectCombobox(1, "Monthly Plan");
|
|
await selectCombobox(2, "3 x Month");
|
|
fireEvent.change(screen.getByPlaceholderText("Enter price"), {
|
|
target: { value: "20" },
|
|
});
|
|
fireEvent.click(screen.getByRole("button", { name: "Confirm" }));
|
|
|
|
await waitFor(() =>
|
|
expect(onSubmit).toHaveBeenCalledWith({
|
|
promo_rule_id: 1,
|
|
items: [{ subscribe_id: 8, quantity: 3, promo_price: 2000 }],
|
|
})
|
|
);
|
|
});
|
|
|
|
it("blocks submit when subscribe has no discount quantities", async () => {
|
|
const onSubmit = vi.fn();
|
|
render(
|
|
<PriceForm
|
|
onSubmit={onSubmit}
|
|
rules={rules}
|
|
subscribes={subscribesWithoutDiscounts}
|
|
/>
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: "Create Promo Price" }));
|
|
await selectCombobox(1, "Monthly Plan");
|
|
|
|
expect(
|
|
screen.getByText(
|
|
"This subscribe has no discount quantities and cannot be configured."
|
|
)
|
|
).not.toBeNull();
|
|
expect(screen.getByRole("button", { name: "Confirm" })).toHaveProperty(
|
|
"disabled",
|
|
true
|
|
);
|
|
});
|
|
|
|
it("keeps the form open and shows an error when promo price reaches original price", async () => {
|
|
const onSubmit = vi.fn();
|
|
render(
|
|
<PriceForm onSubmit={onSubmit} rules={rules} subscribes={subscribes} />
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: "Create Promo Price" }));
|
|
await selectCombobox(0, "Campaign Rule");
|
|
await selectCombobox(1, "Monthly Plan");
|
|
await selectCombobox(2, "3 x Month");
|
|
fireEvent.change(screen.getByPlaceholderText("Enter price"), {
|
|
target: { value: "36" },
|
|
});
|
|
fireEvent.click(screen.getByRole("button", { name: "Confirm" }));
|
|
|
|
expect(
|
|
await screen.findByText("Promo price must be lower than original price")
|
|
).not.toBeNull();
|
|
expect(onSubmit).not.toHaveBeenCalled();
|
|
});
|
|
});
|