mirror of
https://github.com/prymitive/karma
synced 2026-08-19 11:36:24 +00:00
fix(ui): fix tests
This commit is contained in:
committed by
Łukasz Mierzwa
parent
0be1fff69e
commit
0329093114
@@ -2,9 +2,8 @@ import { act, createRef } from "react";
|
||||
|
||||
import { render, fireEvent } from "@testing-library/react";
|
||||
|
||||
import copy from "copy-to-clipboard";
|
||||
|
||||
import { MockAlertGroup, MockAlert } from "__fixtures__/Alerts";
|
||||
import { mockClipboard } from "__fixtures__/Clipboard";
|
||||
import type {
|
||||
APIAlertGroupT,
|
||||
APIAlertT,
|
||||
@@ -22,6 +21,7 @@ let group: APIAlertGroupT;
|
||||
|
||||
let MockAfterClick: () => void;
|
||||
let MockSetIsMenuOpen: () => void;
|
||||
let writeText: jest.Mock;
|
||||
|
||||
const generateUpstreams = (): APIAlertsResponseUpstreamsT => ({
|
||||
counters: { total: 1, healthy: 1, failed: 0 },
|
||||
@@ -68,6 +68,7 @@ const generateUpstreams = (): APIAlertsResponseUpstreamsT => ({
|
||||
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
writeText = mockClipboard();
|
||||
|
||||
alertStore = new AlertStore([]);
|
||||
silenceFormStore = new SilenceFormStore();
|
||||
@@ -286,7 +287,10 @@ describe("<MenuContent />", () => {
|
||||
const { container } = renderMenuContent(group);
|
||||
const buttons = container.querySelectorAll(".dropdown-item");
|
||||
fireEvent.click(buttons[1]);
|
||||
expect(copy).toHaveBeenCalledWith(
|
||||
// flush async clipboard write from copy-to-clipboard
|
||||
await act(() => jest.advanceTimersByTimeAsync(0));
|
||||
expect(writeText).toHaveBeenCalledTimes(1);
|
||||
expect(writeText).toHaveBeenCalledWith(
|
||||
JSON.stringify(alertToJSON(group, alert)),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -127,7 +127,7 @@ const MenuContent = observer(
|
||||
<div
|
||||
className="dropdown-item cursor-pointer"
|
||||
onClick={() => {
|
||||
copy(JSON.stringify(alertToJSON(group, alert)));
|
||||
void copy(JSON.stringify(alertToJSON(group, alert)));
|
||||
afterClick();
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -2,9 +2,8 @@ import { act } from "react";
|
||||
|
||||
import { render, fireEvent } from "@testing-library/react";
|
||||
|
||||
import copy from "copy-to-clipboard";
|
||||
|
||||
import { MockAlertGroup } from "__fixtures__/Alerts";
|
||||
import { mockClipboard } from "__fixtures__/Clipboard";
|
||||
import type {
|
||||
APIAlertGroupT,
|
||||
APIAlertsResponseUpstreamsT,
|
||||
@@ -18,6 +17,7 @@ let silenceFormStore: SilenceFormStore;
|
||||
|
||||
let MockAfterClick: () => void;
|
||||
let MockSetIsMenuOpen: () => void;
|
||||
let writeText: jest.Mock;
|
||||
|
||||
const generateUpstreams = (): APIAlertsResponseUpstreamsT => ({
|
||||
counters: { total: 3, healthy: 3, failed: 0 },
|
||||
@@ -68,6 +68,7 @@ beforeEach(() => {
|
||||
|
||||
jest.useFakeTimers();
|
||||
jest.clearAllMocks();
|
||||
writeText = mockClipboard();
|
||||
MockAfterClick = jest.fn();
|
||||
MockSetIsMenuOpen = jest.fn();
|
||||
|
||||
@@ -188,7 +189,7 @@ const renderMenuContent = (group: APIAlertGroupT) => {
|
||||
};
|
||||
|
||||
describe("<MenuContent />", () => {
|
||||
it("clicking on 'Copy' icon copies the link to clickboard", () => {
|
||||
it("clicking on 'Copy' icon copies the link to clickboard", async () => {
|
||||
const group = MockAlertGroup(
|
||||
[{ name: "alertname", value: "Fake Alert" }],
|
||||
[],
|
||||
@@ -199,7 +200,9 @@ describe("<MenuContent />", () => {
|
||||
const { container } = renderMenuContent(group);
|
||||
const buttons = container.querySelectorAll(".dropdown-item");
|
||||
fireEvent.click(buttons[0]);
|
||||
expect(copy).toHaveBeenCalledTimes(1);
|
||||
// flush async clipboard write from copy-to-clipboard
|
||||
await act(() => jest.advanceTimersByTimeAsync(0));
|
||||
expect(writeText).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("clicking on 'Silence' icon opens the silence form modal", () => {
|
||||
|
||||
@@ -118,7 +118,7 @@ const MenuContent: FC<{
|
||||
<div
|
||||
className="dropdown-item cursor-pointer"
|
||||
onClick={() => {
|
||||
copy(groupLink);
|
||||
void copy(groupLink);
|
||||
afterClick();
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
import { act } from "react";
|
||||
|
||||
import { render, screen, fireEvent } from "@testing-library/react";
|
||||
|
||||
import copy from "copy-to-clipboard";
|
||||
|
||||
import { AlertStore, NewUnappliedFilter } from "Stores/AlertStore";
|
||||
import { mockClipboard } from "__fixtures__/Clipboard";
|
||||
|
||||
import FilteringLabel from ".";
|
||||
|
||||
let alertStore: AlertStore;
|
||||
let writeText: jest.Mock;
|
||||
|
||||
beforeEach(() => {
|
||||
alertStore = new AlertStore([]);
|
||||
writeText = mockClipboard();
|
||||
});
|
||||
|
||||
const renderFilteringLabel = (name: string, value: string) => {
|
||||
@@ -60,9 +63,12 @@ describe("<FilteringLabel />", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("calling onClick() while holding Shift key copies label value to clipboard", () => {
|
||||
it("calling onClick() while holding Shift key copies label value to clipboard", async () => {
|
||||
renderAndClick("foo", "bar", { shiftKey: true });
|
||||
expect(copy).toHaveBeenCalledWith("bar");
|
||||
// flush async clipboard write from copy-to-clipboard
|
||||
await act(async () => {});
|
||||
expect(writeText).toHaveBeenCalledTimes(1);
|
||||
expect(writeText).toHaveBeenCalledWith("bar");
|
||||
});
|
||||
|
||||
it("label with dark background color should have 'components-label-dark' class", () => {
|
||||
|
||||
@@ -23,7 +23,7 @@ const FilteringLabel: FC<{
|
||||
event.preventDefault();
|
||||
|
||||
if (event.shiftKey) {
|
||||
copy(value);
|
||||
void copy(value);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { act } from "react";
|
||||
|
||||
import { render, fireEvent } from "@testing-library/react";
|
||||
|
||||
import copy from "copy-to-clipboard";
|
||||
|
||||
import { MockSilence } from "__fixtures__/Alerts";
|
||||
import { mockClipboard } from "__fixtures__/Clipboard";
|
||||
import type { APIAlertsResponseUpstreamsT, APISilenceT } from "Models/APITypes";
|
||||
import { AlertStore } from "Stores/AlertStore";
|
||||
import { SilenceFormStore } from "Stores/SilenceFormStore";
|
||||
@@ -12,6 +13,7 @@ let alertStore: AlertStore;
|
||||
let silenceFormStore: SilenceFormStore;
|
||||
let cluster: string;
|
||||
let silence: APISilenceT;
|
||||
let writeText: jest.Mock;
|
||||
|
||||
const MockEditSilence = jest.fn();
|
||||
|
||||
@@ -43,6 +45,7 @@ beforeEach(() => {
|
||||
alertStore.data.setUpstreams(generateUpstreams());
|
||||
|
||||
jest.restoreAllMocks();
|
||||
writeText = mockClipboard();
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
@@ -86,12 +89,14 @@ describe("<SilenceDetails />", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("clicking on the copy button copies silence ID to the clipboard", () => {
|
||||
it("clicking on the copy button copies silence ID to the clipboard", async () => {
|
||||
const { container } = renderSilenceDetails();
|
||||
const button = container.querySelector("span.badge.bg-secondary");
|
||||
fireEvent.click(button!);
|
||||
expect(copy).toHaveBeenCalledTimes(1);
|
||||
expect(copy).toHaveBeenCalledWith(silence.id);
|
||||
// flush async clipboard write from copy-to-clipboard
|
||||
await act(() => jest.advanceTimersByTimeAsync(0));
|
||||
expect(writeText).toHaveBeenCalledTimes(1);
|
||||
expect(writeText).toHaveBeenCalledWith(silence.id);
|
||||
});
|
||||
|
||||
it("Edit silence button is disabled when all alertmanager instances are read-only", () => {
|
||||
|
||||
@@ -39,7 +39,7 @@ const SilenceIDCopyButton: FC<{
|
||||
ref={ref}
|
||||
className="badge bg-secondary px-1 me-1 components-label cursor-pointer"
|
||||
onClick={() => {
|
||||
copy(id);
|
||||
void copy(id);
|
||||
setClickCount(clickCount + 1);
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { act } from "react";
|
||||
|
||||
import { render, fireEvent } from "@testing-library/react";
|
||||
|
||||
import copy from "copy-to-clipboard";
|
||||
|
||||
import { mockClipboard } from "__fixtures__/Clipboard";
|
||||
import { MockThemeContext } from "__fixtures__/Theme";
|
||||
import { AlertStore, NewUnappliedFilter } from "Stores/AlertStore";
|
||||
import { Settings } from "Stores/Settings";
|
||||
@@ -14,6 +15,7 @@ import type { APIAlertsResponseUpstreamsT } from "Models/APITypes";
|
||||
let alertStore: AlertStore;
|
||||
let settingsStore: Settings;
|
||||
let silenceFormStore: SilenceFormStore;
|
||||
let writeText: jest.Mock;
|
||||
|
||||
const generateUpstreams = (
|
||||
version = "0.24.0",
|
||||
@@ -47,6 +49,7 @@ beforeEach(() => {
|
||||
settingsStore = new Settings(null);
|
||||
silenceFormStore = new SilenceFormStore();
|
||||
alertStore.data.setUpstreams(generateUpstreams());
|
||||
writeText = mockClipboard();
|
||||
});
|
||||
|
||||
const renderSilenceForm = () => {
|
||||
@@ -510,7 +513,7 @@ describe("<SilenceForm /> preview", () => {
|
||||
expect(container.querySelector(".mt-4")).toBeNull();
|
||||
});
|
||||
|
||||
it("clicking on the copy button copies form link to the clipboard", () => {
|
||||
it("clicking on the copy button copies form link to the clipboard", async () => {
|
||||
const matcher = NewEmptyMatcher();
|
||||
matcher.name = "job";
|
||||
matcher.values = [
|
||||
@@ -531,7 +534,9 @@ describe("<SilenceForm /> preview", () => {
|
||||
);
|
||||
expect(button?.innerHTML).toMatch(/fa-copy/);
|
||||
fireEvent.click(button!);
|
||||
expect(copy).toHaveBeenCalledTimes(1);
|
||||
// flush async clipboard write from copy-to-clipboard
|
||||
await act(async () => {});
|
||||
expect(writeText).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("silence form share link doesn't change on new input", () => {
|
||||
|
||||
@@ -92,7 +92,7 @@ const ShareButton: FC<{
|
||||
ref={ref}
|
||||
className="input-group-text text-muted cursor-pointer"
|
||||
onClick={() => {
|
||||
copy(`${baseURL}?m=${silenceFormStore.data.toBase64}`);
|
||||
void copy(`${baseURL}?m=${silenceFormStore.data.toBase64}`);
|
||||
setClickCount(clickCount + 1);
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// jsdom lacks navigator.clipboard and window.isSecureContext,
|
||||
// mock both so copy-to-clipboard uses the async clipboard API path.
|
||||
const mockClipboard = (): jest.Mock => {
|
||||
const writeText = jest.fn(() => Promise.resolve());
|
||||
|
||||
Object.defineProperty(window, "isSecureContext", {
|
||||
value: true,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
});
|
||||
|
||||
Object.defineProperty(navigator, "clipboard", {
|
||||
value: { writeText },
|
||||
writable: true,
|
||||
configurable: true,
|
||||
});
|
||||
|
||||
return writeText;
|
||||
};
|
||||
|
||||
export { mockClipboard };
|
||||
@@ -1,6 +0,0 @@
|
||||
// mock copy-to-clipboard since it throws errors in tests
|
||||
// and we don't really need to copy anything, only ensure we're calling it
|
||||
|
||||
const copy = jest.fn();
|
||||
|
||||
export default copy;
|
||||
Reference in New Issue
Block a user