fix(ci): update tests

This commit is contained in:
Lukasz Mierzwa
2026-02-23 09:24:52 +00:00
committed by Łukasz Mierzwa
parent 656760a7fd
commit 77cba5ec47
6 changed files with 219 additions and 2 deletions

View File

@@ -26,7 +26,7 @@ exports[`<AlertHistory /> handles fetch errors 1`] = `
</DocumentFragment>
`;
exports[`<AlertHistory /> handles reponses with errors 1`] = `
exports[`<AlertHistory /> handles responses with errors 1`] = `
<DocumentFragment>
<div
class="w-100 d-flex"

View File

@@ -276,6 +276,7 @@ describe("<AlertHistory />", () => {
});
it("doesn't fetch when not in view", async () => {
// Verifies that react-intersection-observer prevents fetch when component is outside viewport
fetchMock.resetHistory();
fetchMock.mock(
"*",
@@ -305,6 +306,48 @@ describe("<AlertHistory />", () => {
expect(fetchMock.calls()).toHaveLength(0);
});
it("fetches when component transitions from out-of-view to in-view", async () => {
// Verifies that react-intersection-observer triggers fetch when component becomes visible
fetchMock.resetHistory();
fetchMock.mock(
"*",
{
headers: { "Content-Type": "application/json" },
body: JSON.stringify(RainbowHistoryResponse),
},
{
overwriteRoutes: true,
},
);
(useInView as jest.MockedFunction<typeof useInView>).mockReturnValue([
jest.fn(),
false,
] as any);
MockAlerts(3);
const { rerender, unmount } = render(
<AlertHistory group={group} grid={grid}></AlertHistory>,
);
await act(async () => {
await fetchMock.flush(true);
});
expect(fetchMock.calls()).toHaveLength(0);
(useInView as jest.MockedFunction<typeof useInView>).mockReturnValue([
jest.fn(),
true,
] as any);
rerender(<AlertHistory group={group} grid={grid}></AlertHistory>);
await act(async () => {
await fetchMock.flush(true);
});
expect(fetchMock.calls()).toHaveLength(1);
unmount();
});
it("fetches an update after 300 seconds", async () => {
fetchMock.resetHistory();
fetchMock.mock(
@@ -348,7 +391,7 @@ describe("<AlertHistory />", () => {
unmount();
});
it("handles reponses with errors", async () => {
it("handles responses with errors", async () => {
fetchMock.resetHistory();
fetchMock.mock(
"*",

View File

@@ -671,4 +671,36 @@ describe("<AlertGrid />", () => {
const { unmount } = renderAlertGrid();
unmount();
});
it("alt+space hotkey toggles pause state", () => {
// Verifies that pressing alt+space triggers alertStore.status.togglePause
MockGroupList(1, 1);
renderAlertGrid();
expect(alertStore.status.paused).toBe(false);
act(() => {
document.dispatchEvent(
new KeyboardEvent("keydown", {
key: " ",
code: "Space",
altKey: true,
} as KeyboardEventInit),
);
});
expect(alertStore.status.paused).toBe(true);
act(() => {
document.dispatchEvent(
new KeyboardEvent("keydown", {
key: " ",
code: "Space",
altKey: true,
} as KeyboardEventInit),
);
});
expect(alertStore.status.paused).toBe(false);
});
});

View File

@@ -174,6 +174,32 @@ describe("<FilterInputLabel /> onChange", () => {
NewUnappliedFilter("bar=baz"),
);
});
it("editing filter to new value replaces it in alertStore", () => {
// Verifies that onChange replaces filter when edited to new value
const filter = createFilter("=", true, true, 1);
alertStore.filters.setFilterValues([filter]);
const { container } = render(
<FilterInputLabel
alertStore={alertStore}
filter={alertStore.filters.values[0]}
/>,
);
const editSpan = container.querySelector(
".components-filteredinputlabel-text span",
);
fireEvent.click(editSpan!);
const input = container.querySelector("input");
fireEvent.change(input!, { target: { value: "foo=newvalue" } });
fireEvent.keyDown(input!, { keyCode: 13 });
expect(alertStore.filters.values).toHaveLength(1);
expect(alertStore.filters.values[0].raw).toBe("foo=newvalue");
});
});
describe("<FilterInputLabel /> render", () => {

View File

@@ -90,6 +90,46 @@ const renderNavbar = (fixedTop?: boolean) => {
};
describe("<NavBar />", () => {
it("sets isIdle to true after idle timeout", () => {
// Verifies that react-idle-timer triggers onIdle callback after timeout period
renderNavbar();
expect(alertStore.ui.isIdle).toBe(false);
act(() => {
jest.advanceTimersByTime(1000 * 60 * 3 + 1000);
});
expect(alertStore.ui.isIdle).toBe(true);
});
it("navbar becomes invisible when idle", () => {
// Verifies that navbar container class changes to invisible when idle
const { container } = renderNavbar();
expect(container.querySelector(".visible")).toBeInTheDocument();
expect(container.querySelector(".invisible")).not.toBeInTheDocument();
act(() => {
jest.advanceTimersByTime(1000 * 60 * 3 + 1000);
});
expect(alertStore.ui.isIdle).toBe(true);
expect(container.querySelector(".invisible")).toBeInTheDocument();
});
it("pauses idle timer when alertStore.status.paused is true", () => {
// Verifies that idle timer is paused when alerts are paused
renderNavbar();
alertStore.status.pause();
act(() => {
jest.advanceTimersByTime(1000 * 60 * 3 + 1000);
});
expect(alertStore.ui.isIdle).toBe(false);
});
it("renders null with no upstreams", () => {
alertStore.data.setUpstreams({
counters: { total: 0, healthy: 0, failed: 0 },

View File

@@ -881,4 +881,80 @@ describe("<SilenceDelete />", () => {
await act(() => promise);
});
it("displays errors when delete requests fail on all cluster members", async () => {
// Verifies that MassDelete shows error messages when all retries fail
const promise = Promise.resolve();
alertStore.data.setUpstreams({
counters: { total: 1, healthy: 1, failed: 0 },
instances: [
{
name: "am1",
cluster: "am",
clusterMembers: ["am1"],
uri: "http://m1.example.com",
publicURI: "http://example.com",
readonly: false,
error: "",
version: "0.24.0",
headers: {},
corsCredentials: "include",
},
],
clusters: { am: ["am1"] },
});
fetchMock.reset();
fetchMock.mock("http://m1.example.com/api/v2/silence/1", {
status: 500,
body: "Internal Server Error",
});
const newSilence = (id: string): APISilenceT => {
const s = MockSilence();
s.id = id;
return s;
};
useFetchGetMock.fetch.setMockedData({
response: [
{
cluster: cluster,
alertCount: 1,
silence: newSilence("1"),
isExpired: false,
},
],
error: null,
isLoading: false,
isRetrying: false,
retryCount: 0,
get: jest.fn(),
cancelGet: jest.fn(),
});
const { container } = renderBrowser();
const checkboxes = container.querySelectorAll(
"input.form-check-input[type='checkbox']",
);
act(() => {
fireEvent.click(checkboxes[1]);
});
const del = container.querySelector(".btn.btn-danger");
fireEvent.click(del!);
await act(async () => {
jest.advanceTimersByTime(10 * 60);
await fetchMock.flush(true);
});
const errorDisplay = document.body.querySelector(".bg-dark.text-white");
expect(errorDisplay).toBeInTheDocument();
expect(errorDisplay?.querySelector("samp")).toBeInTheDocument();
await act(() => promise);
});
});