mirror of
https://github.com/prymitive/karma
synced 2026-08-28 11:17:28 +00:00
fix(ui): update fetch
This commit is contained in:
committed by
Łukasz Mierzwa
parent
675e687dd7
commit
dc5a640bb7
+3
-3
@@ -1,6 +1,6 @@
|
||||
import { render, within } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { mockMatchMedia } from "__fixtures__/matchMedia";
|
||||
import { EmptyAPIResponse } from "__fixtures__/Fetch";
|
||||
@@ -39,8 +39,8 @@ beforeEach(() => {
|
||||
}));
|
||||
global.ResizeObserverEntry = jest.fn();
|
||||
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify(EmptyAPIResponse()),
|
||||
});
|
||||
});
|
||||
|
||||
+24
-19
@@ -2,11 +2,11 @@ import { CommonOptions, FetchGet, FetchRetryConfig } from "./Fetch";
|
||||
|
||||
import merge from "lodash.merge";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
beforeEach(() => {
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
status: 200,
|
||||
body: "ok",
|
||||
});
|
||||
@@ -14,7 +14,7 @@ beforeEach(() => {
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
fetchMock.reset();
|
||||
fetchMock.mockReset();
|
||||
});
|
||||
|
||||
describe("Fetch", () => {
|
||||
@@ -23,15 +23,15 @@ describe("Fetch", () => {
|
||||
};
|
||||
|
||||
const methodOptions: { [key: string]: RequestInit } = {
|
||||
FetchGet: { method: "GET", mode: "cors" },
|
||||
FetchGet: { method: "get", mode: "cors" },
|
||||
};
|
||||
|
||||
for (const [name, func] of Object.entries(tests)) {
|
||||
it(`${name}: passes '{credentials: include}' to all requests`, async () => {
|
||||
const request = func("http://example.com/", {}, jest.fn());
|
||||
await expect(request).resolves.toMatchObject({ status: 200 });
|
||||
expect(fetchMock.lastUrl()).toBe("http://example.com/");
|
||||
expect(fetchMock.lastOptions()).toEqual(
|
||||
expect(fetchMock.callHistory.lastCall()?.url).toBe("http://example.com/");
|
||||
expect(fetchMock.callHistory.lastCall()?.options).toEqual(
|
||||
merge({}, CommonOptions, methodOptions[name]),
|
||||
);
|
||||
});
|
||||
@@ -45,8 +45,8 @@ describe("Fetch", () => {
|
||||
() => {},
|
||||
);
|
||||
await expect(request).resolves.toMatchObject({ status: 200 });
|
||||
expect(fetchMock.lastUrl()).toBe("http://example.com/");
|
||||
expect(fetchMock.lastOptions()).toEqual(
|
||||
expect(fetchMock.callHistory.lastCall()?.url).toBe("http://example.com/");
|
||||
expect(fetchMock.callHistory.lastCall()?.options).toEqual(
|
||||
merge(
|
||||
{},
|
||||
CommonOptions,
|
||||
@@ -67,8 +67,8 @@ describe("Fetch", () => {
|
||||
() => {},
|
||||
);
|
||||
await expect(request).resolves.toMatchObject({ status: 200 });
|
||||
expect(fetchMock.lastUrl()).toBe("http://example.com/");
|
||||
expect(fetchMock.lastOptions()).toEqual(
|
||||
expect(fetchMock.callHistory.lastCall()?.url).toBe("http://example.com/");
|
||||
expect(fetchMock.callHistory.lastCall()?.options).toEqual(
|
||||
merge({}, CommonOptions, methodOptions[name], {
|
||||
credentials: "omit",
|
||||
redirect: "follow",
|
||||
@@ -78,36 +78,41 @@ describe("Fetch", () => {
|
||||
}
|
||||
|
||||
it("FetchGet switches to no-cors for the last retry", async () => {
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
throws: new Error("Fetch error"),
|
||||
});
|
||||
|
||||
const request = FetchGet("http://example.com", {}, jest.fn());
|
||||
await expect(request).rejects.toThrow("Fetch error");
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(FetchRetryConfig.retries + 1);
|
||||
expect(fetchMock.calls().map((r) => r[1])).toMatchObject(
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(
|
||||
FetchRetryConfig.retries + 1,
|
||||
);
|
||||
expect(fetchMock.callHistory.calls().map((r) => r?.options)).toMatchObject(
|
||||
Array.from(Array(FetchRetryConfig.retries + 1).keys(), (i) => ({
|
||||
mode: i < FetchRetryConfig.retries ? "cors" : "no-cors",
|
||||
credentials: "include",
|
||||
})),
|
||||
);
|
||||
// ensure that the the second to last call was with cors
|
||||
expect(fetchMock.calls()[fetchMock.calls().length - 2][1]).toMatchObject({
|
||||
expect(
|
||||
fetchMock.callHistory.calls()[fetchMock.callHistory.calls().length - 2]
|
||||
?.options,
|
||||
).toMatchObject({
|
||||
mode: "cors",
|
||||
credentials: "include",
|
||||
});
|
||||
// ensure that the last call was with no-cors
|
||||
expect(fetchMock.lastOptions()).toMatchObject({
|
||||
expect(fetchMock.callHistory.lastCall()?.options).toMatchObject({
|
||||
mode: "no-cors",
|
||||
credentials: "include",
|
||||
});
|
||||
});
|
||||
|
||||
it("FetchGet calls beforeRetry before each retry", async () => {
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
throws: new Error("Fetch error"),
|
||||
});
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { act } from "react-dom/test-utils";
|
||||
|
||||
import { render, fireEvent, screen, waitFor } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { MockAlertGroup, MockAlert } from "__fixtures__/Alerts";
|
||||
import type { APIAlertT, APIAlertGroupT } from "Models/APITypes";
|
||||
@@ -70,8 +70,8 @@ beforeEach(() => {
|
||||
foo: ["bar", "baz"],
|
||||
};
|
||||
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mock(
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route(
|
||||
"*",
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -84,7 +84,7 @@ beforeEach(() => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mockReset();
|
||||
jest.clearAllTimers();
|
||||
jest.clearAllMocks();
|
||||
jest.restoreAllMocks();
|
||||
@@ -106,7 +106,7 @@ const renderAndClick = async () => {
|
||||
const badge = screen.getByRole("img", { hidden: true }).parentElement;
|
||||
if (badge) fireEvent.click(badge);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -133,21 +133,16 @@ describe("<AlertAck />", () => {
|
||||
});
|
||||
|
||||
it("uses faExclamationCircle after failed fetch", async () => {
|
||||
fetchMock.mock(
|
||||
"*",
|
||||
{
|
||||
status: 500,
|
||||
body: "error message",
|
||||
},
|
||||
{
|
||||
overwriteRoutes: true,
|
||||
},
|
||||
);
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
status: 500,
|
||||
body: "error message",
|
||||
});
|
||||
renderAlertAck();
|
||||
const badge = screen.getByRole("img", { hidden: true }).parentElement;
|
||||
if (badge) fireEvent.click(badge);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("img", { hidden: true })).toHaveClass(
|
||||
@@ -157,21 +152,16 @@ describe("<AlertAck />", () => {
|
||||
});
|
||||
|
||||
it("resets faExclamationCircle after 20s", async () => {
|
||||
fetchMock.mock(
|
||||
"*",
|
||||
{
|
||||
status: 500,
|
||||
body: "error message",
|
||||
},
|
||||
{
|
||||
overwriteRoutes: true,
|
||||
},
|
||||
);
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
status: 500,
|
||||
body: "error message",
|
||||
});
|
||||
renderAlertAck();
|
||||
const badge = screen.getByRole("img", { hidden: true }).parentElement;
|
||||
if (badge) fireEvent.click(badge);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("img", { hidden: true })).toHaveClass(
|
||||
@@ -195,7 +185,7 @@ describe("<AlertAck />", () => {
|
||||
const badge = screen.getByRole("img", { hidden: true }).parentElement;
|
||||
if (badge) fireEvent.click(badge);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole("img", { hidden: true })).toHaveClass(
|
||||
@@ -206,10 +196,10 @@ describe("<AlertAck />", () => {
|
||||
|
||||
it("sends a POST request on click", async () => {
|
||||
await renderAndClick();
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.lastOptions()).toMatchObject({
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.lastCall()?.options).toMatchObject({
|
||||
method: "post",
|
||||
headers: { "content-type": "application/json" },
|
||||
});
|
||||
});
|
||||
|
||||
@@ -238,22 +228,22 @@ describe("<AlertAck />", () => {
|
||||
};
|
||||
|
||||
await renderAndClick();
|
||||
expect(fetchMock.calls()).toHaveLength(2);
|
||||
expect(fetchMock.calls()[0][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(2);
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toBe(
|
||||
"http://m1.example.com/api/v2/silences",
|
||||
);
|
||||
expect(fetchMock.calls()[0][1]).toMatchObject({
|
||||
method: "POST",
|
||||
expect(fetchMock.callHistory.calls()[0]?.options).toMatchObject({
|
||||
method: "post",
|
||||
credentials: "same-origin",
|
||||
headers: { "X-Cluster": "c1" },
|
||||
headers: { "x-cluster": "c1" },
|
||||
});
|
||||
expect(fetchMock.calls()[1][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()[1]?.url).toBe(
|
||||
"http://m3.example.com/api/v2/silences",
|
||||
);
|
||||
expect(fetchMock.calls()[1][1]).toMatchObject({
|
||||
method: "POST",
|
||||
expect(fetchMock.callHistory.calls()[1]?.options).toMatchObject({
|
||||
method: "post",
|
||||
credentials: "include",
|
||||
headers: { "X-Cluster": "c2" },
|
||||
headers: { "x-cluster": "c2" },
|
||||
});
|
||||
});
|
||||
|
||||
@@ -282,11 +272,11 @@ describe("<AlertAck />", () => {
|
||||
};
|
||||
|
||||
await renderAndClick();
|
||||
expect(fetchMock.calls()).toHaveLength(2);
|
||||
expect(fetchMock.calls()[0][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(2);
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toBe(
|
||||
"http://m2.example.com/api/v2/silences",
|
||||
);
|
||||
expect(fetchMock.calls()[1][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()[1]?.url).toBe(
|
||||
"http://m4.example.com/api/v2/silences",
|
||||
);
|
||||
});
|
||||
@@ -297,16 +287,16 @@ describe("<AlertAck />", () => {
|
||||
|
||||
fireEvent.click(button!);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
|
||||
fireEvent.click(button!);
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("sends correct payload", async () => {
|
||||
fetchMock.mock(
|
||||
fetchMock.route(
|
||||
"*",
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -319,7 +309,9 @@ describe("<AlertAck />", () => {
|
||||
|
||||
silenceFormStore.data.setAuthor("karma/ui");
|
||||
await renderAndClick();
|
||||
expect(JSON.parse((fetchMock.lastOptions() as any).body)).toEqual({
|
||||
expect(
|
||||
JSON.parse((fetchMock.callHistory.lastCall()?.options as any).body),
|
||||
).toEqual({
|
||||
comment: "COMMENT",
|
||||
createdBy: "karma/ui",
|
||||
endsAt: "2000-02-01T00:02:03.000Z",
|
||||
@@ -349,7 +341,9 @@ describe("<AlertAck />", () => {
|
||||
},
|
||||
});
|
||||
await renderAndClick();
|
||||
expect(JSON.parse((fetchMock.lastOptions() as any).body)).toEqual({
|
||||
expect(
|
||||
JSON.parse((fetchMock.callHistory.lastCall()?.options as any).body),
|
||||
).toEqual({
|
||||
comment: "comment",
|
||||
createdBy: "me",
|
||||
endsAt: "2000-02-01T00:03:57.000Z",
|
||||
@@ -379,7 +373,9 @@ describe("<AlertAck />", () => {
|
||||
},
|
||||
});
|
||||
await renderAndClick();
|
||||
expect(JSON.parse((fetchMock.lastOptions() as any).body)).toEqual({
|
||||
expect(
|
||||
JSON.parse((fetchMock.callHistory.lastCall()?.options as any).body),
|
||||
).toEqual({
|
||||
comment:
|
||||
"ACK! This alert was acknowledged using karma on Tue, 01 Feb 2000 00:00:00 GMT",
|
||||
createdBy: "me",
|
||||
@@ -410,7 +406,9 @@ describe("<AlertAck />", () => {
|
||||
},
|
||||
});
|
||||
await renderAndClick();
|
||||
const comment = JSON.parse((fetchMock.lastOptions() as any).body).comment;
|
||||
const comment = JSON.parse(
|
||||
(fetchMock.callHistory.lastCall()?.options as any).body,
|
||||
).comment;
|
||||
expect(comment).not.toEqual(
|
||||
"ACK! This alert was acknowledged using karma on Tue Feb 01 2000 00:00:00 GMT",
|
||||
);
|
||||
@@ -433,7 +431,9 @@ describe("<AlertAck />", () => {
|
||||
},
|
||||
});
|
||||
await renderAndClick();
|
||||
expect(JSON.parse((fetchMock.lastOptions() as any).body)).toEqual({
|
||||
expect(
|
||||
JSON.parse((fetchMock.callHistory.lastCall()?.options as any).body),
|
||||
).toEqual({
|
||||
comment: "FOO: bar",
|
||||
createdBy: "auth@example.com",
|
||||
endsAt: "2000-02-01T00:03:42.000Z",
|
||||
@@ -465,7 +465,9 @@ describe("<AlertAck />", () => {
|
||||
});
|
||||
silenceFormStore.data.setAuthor("bob@example.com");
|
||||
await renderAndClick();
|
||||
expect(JSON.parse((fetchMock.lastOptions() as any).body)).toEqual({
|
||||
expect(
|
||||
JSON.parse((fetchMock.callHistory.lastCall()?.options as any).body),
|
||||
).toEqual({
|
||||
comment: "FOO: bar",
|
||||
createdBy: "bob@example.com",
|
||||
endsAt: "2000-02-01T00:03:42.000Z",
|
||||
@@ -496,7 +498,9 @@ describe("<AlertAck />", () => {
|
||||
});
|
||||
silenceFormStore.data.setAuthor("");
|
||||
await renderAndClick();
|
||||
expect(JSON.parse((fetchMock.lastOptions() as any).body)).toEqual({
|
||||
expect(
|
||||
JSON.parse((fetchMock.callHistory.lastCall()?.options as any).body),
|
||||
).toEqual({
|
||||
comment: "FOO: bar",
|
||||
createdBy: "me",
|
||||
endsAt: "2000-02-01T00:03:42.000Z",
|
||||
@@ -515,25 +519,25 @@ describe("<AlertAck />", () => {
|
||||
|
||||
it("sends POST request to /api/v2/silences", async () => {
|
||||
await renderAndClick();
|
||||
const uri = fetchMock.calls()[0][0];
|
||||
const uri = fetchMock.callHistory.calls()[0]?.url;
|
||||
expect(uri).toBe("http://localhost/api/v2/silences");
|
||||
});
|
||||
|
||||
it("will retry on another cluster member after 500 response", async () => {
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("http://m1.example.com/api/v2/silences", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("http://m1.example.com/api/v2/silences", {
|
||||
status: 500,
|
||||
body: "error message",
|
||||
});
|
||||
fetchMock.mock("http://m2.example.com/api/v2/silences", {
|
||||
fetchMock.route("http://m2.example.com/api/v2/silences", {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ silenceID: "123" }),
|
||||
});
|
||||
fetchMock.mock("http://m3.example.com/api/v2/silences", {
|
||||
fetchMock.route("http://m3.example.com/api/v2/silences", {
|
||||
status: 500,
|
||||
body: "error message",
|
||||
});
|
||||
fetchMock.mock("http://m4.example.com/api/v2/silences", {
|
||||
fetchMock.route("http://m4.example.com/api/v2/silences", {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ silenceID: "456" }),
|
||||
});
|
||||
@@ -564,36 +568,36 @@ describe("<AlertAck />", () => {
|
||||
const button = container.querySelector("span.badge");
|
||||
fireEvent.click(button!);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(4);
|
||||
expect(fetchMock.calls()[0][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(4);
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toBe(
|
||||
"http://m1.example.com/api/v2/silences",
|
||||
);
|
||||
expect(fetchMock.calls()[1][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()[1]?.url).toBe(
|
||||
"http://m2.example.com/api/v2/silences",
|
||||
);
|
||||
expect(fetchMock.calls()[2][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()[2]?.url).toBe(
|
||||
"http://m3.example.com/api/v2/silences",
|
||||
);
|
||||
expect(fetchMock.calls()[3][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()[3]?.url).toBe(
|
||||
"http://m4.example.com/api/v2/silences",
|
||||
);
|
||||
});
|
||||
|
||||
it("will retry on another cluster member after fetch failure", async () => {
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("http://m1.example.com/api/v2/silences", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("http://m1.example.com/api/v2/silences", {
|
||||
throws: new TypeError("failed to fetch"),
|
||||
});
|
||||
fetchMock.mock("http://m2.example.com/api/v2/silences", {
|
||||
fetchMock.route("http://m2.example.com/api/v2/silences", {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ silenceID: "123" }),
|
||||
});
|
||||
fetchMock.mock("http://m3.example.com/api/v2/silences", {
|
||||
fetchMock.route("http://m3.example.com/api/v2/silences", {
|
||||
throws: new TypeError("failed to fetch"),
|
||||
});
|
||||
fetchMock.mock("http://m4.example.com/api/v2/silences", {
|
||||
fetchMock.route("http://m4.example.com/api/v2/silences", {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ silenceID: "123" }),
|
||||
});
|
||||
@@ -624,22 +628,22 @@ describe("<AlertAck />", () => {
|
||||
const button = container.querySelector("span.badge");
|
||||
fireEvent.click(button!);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(4);
|
||||
expect(fetchMock.calls()[0][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(4);
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toBe(
|
||||
"http://m1.example.com/api/v2/silences",
|
||||
);
|
||||
expect(fetchMock.calls()[1][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()[1]?.url).toBe(
|
||||
"http://m2.example.com/api/v2/silences",
|
||||
);
|
||||
expect(fetchMock.calls()[2][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()[2]?.url).toBe(
|
||||
"http://m3.example.com/api/v2/silences",
|
||||
);
|
||||
expect(fetchMock.calls()[3][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()[3]?.url).toBe(
|
||||
"http://m4.example.com/api/v2/silences",
|
||||
);
|
||||
});
|
||||
@@ -671,10 +675,10 @@ describe("<AlertAck />", () => {
|
||||
const button = container.querySelector("span.badge");
|
||||
fireEvent.click(button!);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.calls()[0][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toBe(
|
||||
"http://am1.example.com/api/v2/silences",
|
||||
);
|
||||
expect(consoleSpy).toHaveBeenCalledTimes(1);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { act } from "react-dom/test-utils";
|
||||
|
||||
import { render } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { useInView } from "react-intersection-observer";
|
||||
|
||||
@@ -73,15 +73,15 @@ beforeEach(() => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.reset();
|
||||
fetchMock.mockClear();
|
||||
fetchMock.mockReset();
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
describe("<AlertHistory />", () => {
|
||||
it("send a correct payload with empty grid", async () => {
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mock(
|
||||
fetchMock.mockClear();
|
||||
fetchMock.route(
|
||||
"*",
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -99,10 +99,10 @@ describe("<AlertHistory />", () => {
|
||||
<AlertHistory group={group} grid={grid}></AlertHistory>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.calls()[0][1]?.body).toStrictEqual(
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()[0]?.options?.body).toStrictEqual(
|
||||
JSON.stringify({
|
||||
sources: [
|
||||
"https://secure.example.com/graph",
|
||||
@@ -115,8 +115,8 @@ describe("<AlertHistory />", () => {
|
||||
});
|
||||
|
||||
it("send a correct payload with non-empty grid", async () => {
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mock(
|
||||
fetchMock.mockClear();
|
||||
fetchMock.route(
|
||||
"*",
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -132,10 +132,10 @@ describe("<AlertHistory />", () => {
|
||||
<AlertHistory group={group} grid={grid}></AlertHistory>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.calls()[0][1]?.body).toStrictEqual(
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()[0]?.options?.body).toStrictEqual(
|
||||
JSON.stringify({
|
||||
sources: [
|
||||
"https://secure.example.com/graph",
|
||||
@@ -148,8 +148,8 @@ describe("<AlertHistory />", () => {
|
||||
});
|
||||
|
||||
it("send a correct payload with @cluster grid", async () => {
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mock(
|
||||
fetchMock.mockClear();
|
||||
fetchMock.route(
|
||||
"*",
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -167,10 +167,10 @@ describe("<AlertHistory />", () => {
|
||||
<AlertHistory group={group} grid={grid}></AlertHistory>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.calls()[0][1]?.body).toStrictEqual(
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()[0]?.options?.body).toStrictEqual(
|
||||
JSON.stringify({
|
||||
sources: [
|
||||
"https://secure.example.com/graph",
|
||||
@@ -183,8 +183,8 @@ describe("<AlertHistory />", () => {
|
||||
});
|
||||
|
||||
it("send a correct payload with shared labels", async () => {
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mock(
|
||||
fetchMock.mockClear();
|
||||
fetchMock.route(
|
||||
"*",
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -204,10 +204,10 @@ describe("<AlertHistory />", () => {
|
||||
<AlertHistory group={group} grid={grid}></AlertHistory>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.calls()[0][1]?.body).toStrictEqual(
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()[0]?.options?.body).toStrictEqual(
|
||||
JSON.stringify({
|
||||
sources: [
|
||||
"https://secure.example.com/graph",
|
||||
@@ -226,8 +226,8 @@ describe("<AlertHistory />", () => {
|
||||
});
|
||||
|
||||
it("matches snapshot with empty response", async () => {
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mock(
|
||||
fetchMock.mockClear();
|
||||
fetchMock.route(
|
||||
"*",
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -243,16 +243,16 @@ describe("<AlertHistory />", () => {
|
||||
<AlertHistory group={group} grid={grid}></AlertHistory>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
|
||||
it("matches snapshot with rainbow response", async () => {
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mock(
|
||||
fetchMock.mockClear();
|
||||
fetchMock.route(
|
||||
"*",
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -268,17 +268,17 @@ describe("<AlertHistory />", () => {
|
||||
<AlertHistory group={group} grid={grid}></AlertHistory>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
|
||||
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(
|
||||
fetchMock.mockClear();
|
||||
fetchMock.route(
|
||||
"*",
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -299,17 +299,17 @@ describe("<AlertHistory />", () => {
|
||||
<AlertHistory group={group} grid={grid}></AlertHistory>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
unmount();
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(0);
|
||||
expect(fetchMock.callHistory.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(
|
||||
fetchMock.mockClear();
|
||||
fetchMock.route(
|
||||
"*",
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -330,9 +330,9 @@ describe("<AlertHistory />", () => {
|
||||
<AlertHistory group={group} grid={grid}></AlertHistory>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(0);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(0);
|
||||
|
||||
(useInView as jest.MockedFunction<typeof useInView>).mockReturnValue([
|
||||
jest.fn(),
|
||||
@@ -341,16 +341,16 @@ describe("<AlertHistory />", () => {
|
||||
|
||||
rerender(<AlertHistory group={group} grid={grid}></AlertHistory>);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
|
||||
unmount();
|
||||
});
|
||||
|
||||
it("fetches an update after 300 seconds", async () => {
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mock(
|
||||
fetchMock.mockClear();
|
||||
fetchMock.route(
|
||||
"*",
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -372,28 +372,28 @@ describe("<AlertHistory />", () => {
|
||||
<AlertHistory group={group} grid={grid}></AlertHistory>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
|
||||
await act(async () => {
|
||||
jest.advanceTimersByTime(1000 * 299);
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
|
||||
await act(async () => {
|
||||
jest.advanceTimersByTime(1000 * 2);
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(2);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(2);
|
||||
|
||||
unmount();
|
||||
});
|
||||
|
||||
it("handles responses with errors", async () => {
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mock(
|
||||
fetchMock.mockClear();
|
||||
fetchMock.route(
|
||||
"*",
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -409,16 +409,16 @@ describe("<AlertHistory />", () => {
|
||||
<AlertHistory group={group} grid={grid}></AlertHistory>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
|
||||
it("handles fetch errors", async () => {
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mock(
|
||||
fetchMock.mockClear();
|
||||
fetchMock.route(
|
||||
"*",
|
||||
{
|
||||
status: 500,
|
||||
@@ -434,9 +434,9 @@ describe("<AlertHistory />", () => {
|
||||
<AlertHistory group={group} grid={grid}></AlertHistory>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(asFragment()).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
@@ -567,8 +567,8 @@ describe("<AlertHistory />", () => {
|
||||
};
|
||||
|
||||
it(`${testCase.title}`, async () => {
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mock(
|
||||
fetchMock.mockClear();
|
||||
fetchMock.route(
|
||||
"*",
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -583,7 +583,7 @@ describe("<AlertHistory />", () => {
|
||||
<AlertHistory group={g} grid={gr}></AlertHistory>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
|
||||
const rects = Array.from(container.querySelectorAll("rect")).map(
|
||||
|
||||
@@ -2,7 +2,7 @@ import { act } from "react-dom/test-utils";
|
||||
|
||||
import { render, fireEvent } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { EmptyAPIResponse } from "__fixtures__/Fetch";
|
||||
|
||||
@@ -48,14 +48,14 @@ afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.restoreAllMocks();
|
||||
jest.useRealTimers();
|
||||
fetchMock.reset();
|
||||
fetchMock.mockReset();
|
||||
});
|
||||
|
||||
const MockEmptyAPIResponseWithoutFilters = () => {
|
||||
const response = EmptyAPIResponse();
|
||||
response.filters = [];
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
status: 200,
|
||||
body: JSON.stringify(response),
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ import { act } from "react-dom/test-utils";
|
||||
|
||||
import { render, fireEvent } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { MockAlert, MockAlertGroup } from "__fixtures__/Alerts";
|
||||
import {
|
||||
@@ -465,8 +465,8 @@ describe("<AlertGroup /> renderConfig", () => {
|
||||
});
|
||||
|
||||
it("uses 'z-index: 100' style after setIsMenuOpen() is called on any Alert", async () => {
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", { body: "" });
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", { body: "" });
|
||||
|
||||
const promise = Promise.resolve();
|
||||
MockAlerts(5, 5);
|
||||
@@ -555,8 +555,8 @@ describe("<AlertGroup /> card theme", () => {
|
||||
});
|
||||
|
||||
it("renders AlertHistory when enabled", async () => {
|
||||
fetchMock.reset();
|
||||
fetchMock.mock(
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route(
|
||||
"/history.json",
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -574,11 +574,11 @@ describe("<AlertGroup /> card theme", () => {
|
||||
group.stateCount = { active: 5, suppressed: 0, unprocessed: 0 };
|
||||
const { container } = renderAlertGroup(jest.fn());
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(container.innerHTML).toMatch(/alert-history/);
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.calls()[0][0]).toBe("/history.json");
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toContain("/history.json");
|
||||
});
|
||||
|
||||
it("doesn't render AlertHistory when disabled", () => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { act } from "react-dom/test-utils";
|
||||
|
||||
import { render, fireEvent } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { MockGrid } from "__fixtures__/Stories";
|
||||
import { MockThemeContextWithoutAnimations } from "__fixtures__/Theme";
|
||||
@@ -25,8 +25,8 @@ declare let document: any;
|
||||
declare let window: any;
|
||||
|
||||
beforeEach(() => {
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify([]),
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { render, screen, fireEvent } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { MockThemeContext } from "__fixtures__/Theme";
|
||||
import { useFetchGetMock } from "__fixtures__/useFetchGet";
|
||||
@@ -10,8 +10,8 @@ import { MultiGridConfiguration } from "./MultiGridConfiguration";
|
||||
|
||||
let settingsStore: Settings;
|
||||
beforeEach(() => {
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify([]),
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { render } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { MockThemeContext } from "__fixtures__/Theme";
|
||||
import { Settings } from "Stores/Settings";
|
||||
@@ -8,8 +8,8 @@ import { ThemeContext } from "Components/Theme";
|
||||
import { Configuration } from ".";
|
||||
|
||||
beforeEach(() => {
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
status: 200,
|
||||
body: JSON.stringify([]),
|
||||
});
|
||||
@@ -17,7 +17,7 @@ beforeEach(() => {
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
fetchMock.reset();
|
||||
fetchMock.mockReset();
|
||||
});
|
||||
|
||||
describe("<Configuration />", () => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { render, screen, fireEvent } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { MockThemeContext } from "__fixtures__/Theme";
|
||||
import { AlertStore } from "Stores/AlertStore";
|
||||
@@ -16,15 +16,15 @@ beforeEach(() => {
|
||||
alertStore = new AlertStore([]);
|
||||
settingsStore = new Settings(null);
|
||||
onHide.mockClear();
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify([]),
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
fetchMock.reset();
|
||||
fetchMock.mockReset();
|
||||
});
|
||||
|
||||
const renderModalContent = () => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { act } from "react-dom/test-utils";
|
||||
|
||||
import { render, screen, fireEvent } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { MockThemeContext } from "__fixtures__/Theme";
|
||||
import { AlertStore } from "Stores/AlertStore";
|
||||
@@ -18,15 +18,15 @@ beforeEach(() => {
|
||||
settingsStore = new Settings(null);
|
||||
|
||||
jest.useFakeTimers();
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify([]),
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
fetchMock.reset();
|
||||
fetchMock.mockReset();
|
||||
document.body.className = "";
|
||||
});
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { act } from "react-dom/test-utils";
|
||||
|
||||
import { render, screen } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { useIdleTimer } from "react-idle-timer";
|
||||
|
||||
@@ -73,8 +73,8 @@ beforeEach(() => {
|
||||
clusters: { dev: ["dev"] },
|
||||
});
|
||||
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify(EmptyAPIResponse()),
|
||||
});
|
||||
});
|
||||
@@ -84,7 +84,7 @@ afterEach(() => {
|
||||
jest.runOnlyPendingTimers();
|
||||
jest.useRealTimers();
|
||||
});
|
||||
fetchMock.reset();
|
||||
fetchMock.mockReset();
|
||||
});
|
||||
|
||||
const renderNavbar = (fixedTop?: boolean) => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { act } from "react-dom/test-utils";
|
||||
|
||||
import { render, fireEvent } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { useFetchGetMock } from "__fixtures__/useFetchGet";
|
||||
import { MockSilence } from "__fixtures__/Alerts";
|
||||
@@ -63,7 +63,7 @@ afterEach(() => {
|
||||
localStorage.setItem("fetchConfig.interval", "");
|
||||
global.window.innerWidth = 1024;
|
||||
|
||||
fetchMock.reset();
|
||||
fetchMock.mockReset();
|
||||
});
|
||||
|
||||
const MockSilenceList = (count: number): APIManagedSilenceT[] => {
|
||||
@@ -523,7 +523,7 @@ describe("<SilenceDelete />", () => {
|
||||
cancelGet: jest.fn(),
|
||||
});
|
||||
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.route("*", {
|
||||
status: 200,
|
||||
body: "ok",
|
||||
});
|
||||
@@ -554,10 +554,10 @@ describe("<SilenceDelete />", () => {
|
||||
|
||||
await act(async () => {
|
||||
jest.advanceTimersByTime(2 * 60);
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(3);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(3);
|
||||
|
||||
const closeBtn = container.querySelector(".btn-close");
|
||||
if (closeBtn) fireEvent.click(closeBtn);
|
||||
@@ -611,7 +611,7 @@ describe("<SilenceDelete />", () => {
|
||||
cancelGet: jest.fn(),
|
||||
});
|
||||
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.route("*", {
|
||||
status: 200,
|
||||
body: "ok",
|
||||
});
|
||||
@@ -662,10 +662,10 @@ describe("<SilenceDelete />", () => {
|
||||
|
||||
await act(async () => {
|
||||
jest.advanceTimersByTime(2 * 60);
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(2);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(2);
|
||||
|
||||
const closeBtn = container.querySelector(".btn-close");
|
||||
if (closeBtn) fireEvent.click(closeBtn);
|
||||
@@ -693,7 +693,7 @@ describe("<SilenceDelete />", () => {
|
||||
cancelGet: jest.fn(),
|
||||
});
|
||||
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.route("*", {
|
||||
status: 200,
|
||||
body: "ok",
|
||||
});
|
||||
@@ -715,7 +715,7 @@ describe("<SilenceDelete />", () => {
|
||||
|
||||
await act(async () => {
|
||||
jest.advanceTimersByTime(60);
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
|
||||
PressKey("Escape", 27);
|
||||
@@ -781,30 +781,30 @@ describe("<SilenceDelete />", () => {
|
||||
clusters: { am: ["am1", "am2", "am3"], failed: ["am4"] },
|
||||
});
|
||||
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("http://m1.example.com/api/v2/silence/1", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("http://m1.example.com/api/v2/silence/1", {
|
||||
throws: new TypeError("failed to fetch"),
|
||||
});
|
||||
fetchMock.mock("http://m2.example.com/api/v2/silence/1", {
|
||||
fetchMock.route("http://m2.example.com/api/v2/silence/1", {
|
||||
status: 502,
|
||||
body: "Bad Gateway",
|
||||
});
|
||||
fetchMock.mock("http://m3.example.com/api/v2/silence/1", {
|
||||
fetchMock.route("http://m3.example.com/api/v2/silence/1", {
|
||||
status: 200,
|
||||
body: "OK",
|
||||
});
|
||||
fetchMock.mock("http://m1.example.com/api/v2/silence/2", {
|
||||
fetchMock.route("http://m1.example.com/api/v2/silence/2", {
|
||||
throws: "error text",
|
||||
});
|
||||
fetchMock.mock("http://m2.example.com/api/v2/silence/2", {
|
||||
fetchMock.route("http://m2.example.com/api/v2/silence/2", {
|
||||
status: 200,
|
||||
body: "OK",
|
||||
});
|
||||
fetchMock.mock("http://m4.example.com/api/v2/silence/3", {
|
||||
fetchMock.route("http://m4.example.com/api/v2/silence/3", {
|
||||
status: 400,
|
||||
body: "Bad Request",
|
||||
});
|
||||
fetchMock.mock("http://m4.example.com/api/v2/silence/4", {
|
||||
fetchMock.route("http://m4.example.com/api/v2/silence/4", {
|
||||
throws: new TypeError("failed to fetch"),
|
||||
});
|
||||
|
||||
@@ -866,11 +866,11 @@ describe("<SilenceDelete />", () => {
|
||||
|
||||
await act(async () => {
|
||||
jest.advanceTimersByTime(10 * 60);
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(7);
|
||||
const uris = fetchMock.calls().map((c) => c[0]);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(7);
|
||||
const uris = fetchMock.callHistory.calls().map((c) => c?.url);
|
||||
expect(uris).toContainEqual("http://m1.example.com/api/v2/silence/1");
|
||||
expect(uris).toContainEqual("http://m1.example.com/api/v2/silence/2");
|
||||
expect(uris).toContainEqual("http://m4.example.com/api/v2/silence/3");
|
||||
@@ -905,8 +905,8 @@ describe("<SilenceDelete />", () => {
|
||||
clusters: { am: ["am1"] },
|
||||
});
|
||||
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("http://m1.example.com/api/v2/silence/1", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("http://m1.example.com/api/v2/silence/1", {
|
||||
status: 500,
|
||||
body: "Internal Server Error",
|
||||
});
|
||||
@@ -948,7 +948,7 @@ describe("<SilenceDelete />", () => {
|
||||
|
||||
await act(async () => {
|
||||
jest.advanceTimersByTime(10 * 60);
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
|
||||
const errorDisplay = document.body.querySelector(".bg-dark.text-white");
|
||||
|
||||
@@ -2,7 +2,7 @@ import { act } from "react-dom/test-utils";
|
||||
|
||||
import { render } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { AlertStore } from "Stores/AlertStore";
|
||||
import { SilenceFormStore, NewClusterRequest } from "Stores/SilenceFormStore";
|
||||
@@ -43,8 +43,8 @@ beforeEach(() => {
|
||||
]),
|
||||
});
|
||||
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mock(
|
||||
fetchMock.mockClear();
|
||||
fetchMock.route(
|
||||
"*",
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -58,7 +58,7 @@ beforeEach(() => {
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mockClear();
|
||||
});
|
||||
|
||||
const renderSilenceSubmitProgress = () => {
|
||||
@@ -83,29 +83,28 @@ describe("<SilenceSubmitProgress />", () => {
|
||||
it("sends a request on mount", async () => {
|
||||
renderSilenceSubmitProgress();
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("appends /api/v2/silences to the passed URI", async () => {
|
||||
renderSilenceSubmitProgress();
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
const uri = fetchMock.calls()[0][0];
|
||||
const uri = fetchMock.callHistory.calls()[0]?.url;
|
||||
expect(uri).toBe("http://localhost/api/v2/silences");
|
||||
});
|
||||
|
||||
it("sends correct JSON payload", async () => {
|
||||
renderSilenceSubmitProgress();
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
const payload = fetchMock.calls()[0][1];
|
||||
const payload = fetchMock.callHistory.calls()[0]?.options;
|
||||
expect(payload).toMatchObject({
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", foo: "bar" },
|
||||
method: "post",
|
||||
body: JSON.stringify({
|
||||
matchers: [],
|
||||
startsAt: "now",
|
||||
@@ -114,6 +113,10 @@ describe("<SilenceSubmitProgress />", () => {
|
||||
comment: "fake payload",
|
||||
}),
|
||||
});
|
||||
// Check headers - stored as plain object
|
||||
const headers = payload?.headers as Record<string, string>;
|
||||
expect(headers["content-type"]).toBe("application/json");
|
||||
expect(headers["foo"]).toBe("bar");
|
||||
});
|
||||
|
||||
it("uses CORS credentials from alertmanager config", async () => {
|
||||
@@ -122,21 +125,23 @@ describe("<SilenceSubmitProgress />", () => {
|
||||
alertStore.data.setUpstreams(upstreams);
|
||||
renderSilenceSubmitProgress();
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()[0][0]).toBe("http://localhost/api/v2/silences");
|
||||
expect(fetchMock.calls()[0][1]).toMatchObject({
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toBe(
|
||||
"http://localhost/api/v2/silences",
|
||||
);
|
||||
expect(fetchMock.callHistory.calls()[0]?.options).toMatchObject({
|
||||
credentials: "same-origin",
|
||||
method: "POST",
|
||||
method: "post",
|
||||
});
|
||||
});
|
||||
|
||||
it("will retry on another cluster member after fetch failure", async () => {
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("http://am2.example.com/api/v2/silences", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("http://am2.example.com/api/v2/silences", {
|
||||
throws: new TypeError("failed to fetch"),
|
||||
});
|
||||
fetchMock.mock("http://am1.example.com/api/v2/silences", {
|
||||
fetchMock.route("http://am1.example.com/api/v2/silences", {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ silenceID: "123456789" }),
|
||||
});
|
||||
@@ -190,23 +195,23 @@ describe("<SilenceSubmitProgress />", () => {
|
||||
/>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()[0][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toBe(
|
||||
"http://am2.example.com/api/v2/silences",
|
||||
);
|
||||
expect(fetchMock.calls()).toHaveLength(2);
|
||||
expect(fetchMock.calls()[1][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(2);
|
||||
expect(fetchMock.callHistory.calls()[1]?.url).toBe(
|
||||
"http://am1.example.com/api/v2/silences",
|
||||
);
|
||||
});
|
||||
|
||||
it("will use error message from last failed cluster member", async () => {
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("http://am2.example.com/api/v2/silences", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("http://am2.example.com/api/v2/silences", {
|
||||
throws: new TypeError("failed to fetch from am2"),
|
||||
});
|
||||
fetchMock.mock("http://am1.example.com/api/v2/silences", {
|
||||
fetchMock.route("http://am1.example.com/api/v2/silences", {
|
||||
throws: new TypeError("failed to fetch from am1"),
|
||||
});
|
||||
alertStore.data.setUpstreams({
|
||||
@@ -259,9 +264,9 @@ describe("<SilenceSubmitProgress />", () => {
|
||||
/>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(2);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(2);
|
||||
expect(silenceFormStore.data.requestsByCluster.ha).toMatchObject({
|
||||
isDone: true,
|
||||
error: "failed to fetch from am1",
|
||||
@@ -310,9 +315,9 @@ describe("<SilenceSubmitProgress />", () => {
|
||||
/>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()[0][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toBe(
|
||||
"http://am1.example.com/api/v2/silences",
|
||||
);
|
||||
expect(consoleSpy).toHaveBeenCalledTimes(1);
|
||||
@@ -347,9 +352,9 @@ describe("<SilenceSubmitProgress />", () => {
|
||||
/>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(0);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(0);
|
||||
expect(consoleSpy).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
@@ -411,10 +416,10 @@ describe("<SilenceSubmitProgress />", () => {
|
||||
/>,
|
||||
);
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.calls()[0][0]).toBe(
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toBe(
|
||||
"http://am1.example.com/api/v2/silences",
|
||||
);
|
||||
expect(logs).toEqual(['Alertmanager instance "am2" is read-only']);
|
||||
@@ -478,7 +483,7 @@ describe("<SilenceSubmitProgress />", () => {
|
||||
silenceFormStore={silenceFormStore}
|
||||
/>,
|
||||
);
|
||||
expect(fetchMock.calls()).toHaveLength(0);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(0);
|
||||
expect(logs).toEqual([
|
||||
'Alertmanager instance "am2" is read-only',
|
||||
'Alertmanager instance "am1" is read-only',
|
||||
@@ -489,7 +494,7 @@ describe("<SilenceSubmitProgress />", () => {
|
||||
it("renders silence link on successful fetch", async () => {
|
||||
renderSilenceSubmitProgress();
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(
|
||||
silenceFormStore.data.requestsByCluster.mockAlertmanager,
|
||||
@@ -502,14 +507,14 @@ describe("<SilenceSubmitProgress />", () => {
|
||||
});
|
||||
|
||||
it("sets error icon on failed fetch", async () => {
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
status: 500,
|
||||
body: "error message",
|
||||
});
|
||||
renderSilenceSubmitProgress();
|
||||
await act(async () => {
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
expect(
|
||||
silenceFormStore.data.requestsByCluster.mockAlertmanager,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { act } from "react-dom/test-utils";
|
||||
|
||||
import { render, fireEvent } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { MockThemeContext } from "__fixtures__/Theme";
|
||||
import { ThemeContext } from "Components/Theme";
|
||||
@@ -21,15 +21,15 @@ beforeEach(() => {
|
||||
silenceFormStore = new SilenceFormStore();
|
||||
|
||||
jest.useFakeTimers();
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify([]),
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
fetchMock.reset();
|
||||
fetchMock.mockReset();
|
||||
document.body.className = "";
|
||||
});
|
||||
|
||||
|
||||
@@ -3,43 +3,40 @@ import { act } from "react-dom/test-utils";
|
||||
import { renderHook } from "@testing-library/react-hooks";
|
||||
import { render } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { useFetchAny, UpstreamT } from "./useFetchAny";
|
||||
|
||||
describe("useFetchAny", () => {
|
||||
beforeAll(() => {
|
||||
fetchMock.mock("http://localhost/ok", "body ok");
|
||||
fetchMock.mock("http://localhost/ok/json", {
|
||||
beforeEach(() => {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("http://localhost/ok", "body ok");
|
||||
fetchMock.route("http://localhost/ok/json", {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ status: "ok" }),
|
||||
});
|
||||
fetchMock.mock("http://localhost/500", {
|
||||
fetchMock.route("http://localhost/500", {
|
||||
status: 500,
|
||||
body: "fake error",
|
||||
});
|
||||
fetchMock.mock("http://localhost/401", 401);
|
||||
fetchMock.mock("http://localhost/error", {
|
||||
fetchMock.route("http://localhost/401", 401);
|
||||
fetchMock.route("http://localhost/error", {
|
||||
throws: new TypeError("failed to fetch"),
|
||||
});
|
||||
fetchMock.mock("http://localhost/unknown", {
|
||||
throws: "foo",
|
||||
fetchMock.route("http://localhost/unknown", {
|
||||
throws: new Error("foo"),
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fetchMock.resetHistory();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mockClear();
|
||||
});
|
||||
|
||||
it("does nothing on empty upstream list", async () => {
|
||||
const upstreams: UpstreamT[] = [];
|
||||
const { result } = renderHook(() => useFetchAny(upstreams));
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(0);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(0);
|
||||
expect(result.current.inProgress).toBe(false);
|
||||
});
|
||||
|
||||
@@ -49,10 +46,10 @@ describe("useFetchAny", () => {
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.lastUrl()).toBe("http://localhost/ok");
|
||||
expect(fetchMock.lastOptions()).toMatchObject({
|
||||
method: "GET",
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.lastCall()?.url).toBe("http://localhost/ok");
|
||||
expect(fetchMock.callHistory.lastCall()?.options).toMatchObject({
|
||||
method: "get",
|
||||
credentials: "include",
|
||||
mode: "cors",
|
||||
redirect: "follow",
|
||||
@@ -63,17 +60,17 @@ describe("useFetchAny", () => {
|
||||
const upstreams: UpstreamT[] = [
|
||||
{
|
||||
uri: "http://localhost/ok",
|
||||
options: { method: "POST", credentials: "same-origin" },
|
||||
options: { method: "post", credentials: "same-origin" },
|
||||
},
|
||||
];
|
||||
const { waitForNextUpdate } = renderHook(() => useFetchAny(upstreams));
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.lastUrl()).toBe("http://localhost/ok");
|
||||
expect(fetchMock.lastOptions()).toMatchObject({
|
||||
method: "POST",
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.lastCall()?.url).toBe("http://localhost/ok");
|
||||
expect(fetchMock.callHistory.lastCall()?.options).toMatchObject({
|
||||
method: "post",
|
||||
credentials: "same-origin",
|
||||
mode: "cors",
|
||||
redirect: "follow",
|
||||
@@ -86,9 +83,9 @@ describe("useFetchAny", () => {
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.lastUrl()).toBe("http://localhost/ok");
|
||||
expect(fetchMock.lastOptions()).toMatchObject({
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.lastCall()?.url).toBe("http://localhost/ok");
|
||||
expect(fetchMock.callHistory.lastCall()?.options).toMatchObject({
|
||||
mode: "cors",
|
||||
credentials: "include",
|
||||
redirect: "follow",
|
||||
@@ -204,13 +201,13 @@ describe("useFetchAny", () => {
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.response).toBe(null);
|
||||
expect(result.current.error).toBe("unknown error: foo");
|
||||
expect(result.current.error).toBe("foo");
|
||||
expect(result.current.inProgress).toBe(false);
|
||||
expect(result.current.responseURI).toBe(null);
|
||||
});
|
||||
|
||||
it("doesn't update response after cleanup", async () => {
|
||||
fetchMock.mock(
|
||||
fetchMock.route(
|
||||
"http://localhost/slow/ok",
|
||||
new Promise((res) => setTimeout(() => res("ok"), 1000)),
|
||||
);
|
||||
@@ -230,11 +227,11 @@ describe("useFetchAny", () => {
|
||||
const { unmount } = render(<Component />);
|
||||
unmount();
|
||||
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
|
||||
it("doesn't update error on 500 response after cleanup", async () => {
|
||||
fetchMock.mock("http://localhost/slow/500", {
|
||||
fetchMock.route("http://localhost/slow/500", {
|
||||
delay: 1000,
|
||||
status: 500,
|
||||
body: "error",
|
||||
@@ -257,11 +254,11 @@ describe("useFetchAny", () => {
|
||||
unmount();
|
||||
});
|
||||
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
|
||||
it("doesn't update error on failed response after cleanup", async () => {
|
||||
fetchMock.mock("http://localhost/slow/error", {
|
||||
fetchMock.route("http://localhost/slow/error", {
|
||||
delay: 1000,
|
||||
throws: new TypeError("failed to fetch"),
|
||||
});
|
||||
@@ -283,7 +280,7 @@ describe("useFetchAny", () => {
|
||||
unmount();
|
||||
});
|
||||
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
|
||||
it("doesn't retry on success", async () => {
|
||||
@@ -298,8 +295,8 @@ describe("useFetchAny", () => {
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.calls()[0][0]).toBe("http://localhost/ok");
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toBe("http://localhost/ok");
|
||||
|
||||
expect(result.current.response).toBe("body ok");
|
||||
expect(result.current.error).toBe(null);
|
||||
@@ -319,10 +316,12 @@ describe("useFetchAny", () => {
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(3);
|
||||
expect(fetchMock.calls()[0][0]).toBe("http://localhost/500");
|
||||
expect(fetchMock.calls()[1][0]).toBe("http://localhost/error");
|
||||
expect(fetchMock.calls()[2][0]).toBe("http://localhost/ok");
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(3);
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toBe("http://localhost/500");
|
||||
expect(fetchMock.callHistory.calls()[1]?.url).toBe(
|
||||
"http://localhost/error",
|
||||
);
|
||||
expect(fetchMock.callHistory.calls()[2]?.url).toBe("http://localhost/ok");
|
||||
|
||||
expect(result.current.response).toBe("body ok");
|
||||
expect(result.current.error).toBe(null);
|
||||
@@ -342,9 +341,11 @@ describe("useFetchAny", () => {
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(2);
|
||||
expect(fetchMock.calls()[0][0]).toBe("http://localhost/500");
|
||||
expect(fetchMock.calls()[1][0]).toBe("http://localhost/ok/json");
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(2);
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toBe("http://localhost/500");
|
||||
expect(fetchMock.callHistory.calls()[1]?.url).toBe(
|
||||
"http://localhost/ok/json",
|
||||
);
|
||||
|
||||
expect(result.current.response).toMatchObject({ status: "ok" });
|
||||
expect(result.current.error).toBe(null);
|
||||
|
||||
@@ -3,32 +3,29 @@ import { act } from "react-dom/test-utils";
|
||||
import { renderHook } from "@testing-library/react-hooks";
|
||||
import { render } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { useFetchDelete } from "./useFetchDelete";
|
||||
|
||||
describe("useFetchDelete", () => {
|
||||
beforeAll(() => {
|
||||
fetchMock.mock("http://localhost/ok", "body ok");
|
||||
fetchMock.mock("http://localhost/401", 401);
|
||||
fetchMock.mock("http://localhost/500", {
|
||||
beforeEach(() => {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("http://localhost/ok", "body ok");
|
||||
fetchMock.route("http://localhost/401", 401);
|
||||
fetchMock.route("http://localhost/500", {
|
||||
status: 500,
|
||||
body: "fake error",
|
||||
});
|
||||
fetchMock.mock("http://localhost/error", {
|
||||
fetchMock.route("http://localhost/error", {
|
||||
throws: new TypeError("failed to fetch"),
|
||||
});
|
||||
fetchMock.mock("http://localhost/unknown", {
|
||||
throws: "foo",
|
||||
fetchMock.route("http://localhost/unknown", {
|
||||
throws: new Error("foo"),
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fetchMock.resetHistory();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mockClear();
|
||||
});
|
||||
|
||||
const EmptyOptions = {};
|
||||
@@ -40,10 +37,10 @@ describe("useFetchDelete", () => {
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.lastUrl()).toBe("http://localhost/ok");
|
||||
expect(fetchMock.lastOptions()).toMatchObject({
|
||||
method: "DELETE",
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.lastCall()?.url).toBe("http://localhost/ok");
|
||||
expect(fetchMock.callHistory.lastCall()?.options).toMatchObject({
|
||||
method: "delete",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -54,9 +51,9 @@ describe("useFetchDelete", () => {
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.lastUrl()).toBe("http://localhost/ok");
|
||||
expect(fetchMock.lastOptions()).toMatchObject({
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.lastCall()?.url).toBe("http://localhost/ok");
|
||||
expect(fetchMock.callHistory.lastCall()?.options).toMatchObject({
|
||||
mode: "cors",
|
||||
credentials: "include",
|
||||
redirect: "follow",
|
||||
@@ -139,12 +136,12 @@ describe("useFetchDelete", () => {
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.response).toBe(null);
|
||||
expect(result.current.error).toBe("unknown error: foo");
|
||||
expect(result.current.error).toBe("foo");
|
||||
expect(result.current.isDeleting).toBe(false);
|
||||
});
|
||||
|
||||
it("doesn't update response after cleanup", async () => {
|
||||
fetchMock.mock(
|
||||
fetchMock.route(
|
||||
"http://localhost/slow/ok",
|
||||
new Promise((res) => setTimeout(() => res("ok"), 1000)),
|
||||
);
|
||||
@@ -166,11 +163,11 @@ describe("useFetchDelete", () => {
|
||||
const { unmount } = render(<Component />);
|
||||
unmount();
|
||||
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
|
||||
it("doesn't update error on 500 response after cleanup", async () => {
|
||||
fetchMock.mock("http://localhost/slow/500", {
|
||||
fetchMock.route("http://localhost/slow/500", {
|
||||
delay: 1000,
|
||||
status: 500,
|
||||
body: "error",
|
||||
@@ -195,11 +192,11 @@ describe("useFetchDelete", () => {
|
||||
unmount();
|
||||
});
|
||||
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
|
||||
it("doesn't update error on failed response after cleanup", async () => {
|
||||
fetchMock.mock("http://localhost/slow/error", {
|
||||
fetchMock.route("http://localhost/slow/error", {
|
||||
delay: 1000,
|
||||
throws: new TypeError("failed to fetch"),
|
||||
});
|
||||
@@ -223,6 +220,6 @@ describe("useFetchDelete", () => {
|
||||
unmount();
|
||||
});
|
||||
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@ import { act as actReact } from "react-dom/test-utils";
|
||||
import { renderHook, act } from "@testing-library/react-hooks";
|
||||
import { render } from "@testing-library/react";
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { FetchRetryConfig } from "Common/Fetch";
|
||||
import { useFetchGet } from "./useFetchGet";
|
||||
@@ -11,27 +11,24 @@ import { useFetchGet } from "./useFetchGet";
|
||||
jest.unmock("./useFetchGet");
|
||||
|
||||
describe("useFetchGet", () => {
|
||||
beforeAll(() => {
|
||||
fetchMock.mock("http://localhost/ok", {
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("http://localhost/ok", {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ status: "ok" }),
|
||||
});
|
||||
fetchMock.mock("http://localhost/401", 401);
|
||||
fetchMock.mock("http://localhost/error", {
|
||||
fetchMock.route("http://localhost/401", 401);
|
||||
fetchMock.route("http://localhost/error", {
|
||||
throws: new TypeError("failed to fetch"),
|
||||
});
|
||||
fetchMock.mock("http://localhost/unknown", {
|
||||
throws: "foo",
|
||||
fetchMock.route("http://localhost/unknown", {
|
||||
throws: new Error("foo"),
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
fetchMock.resetHistory();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fetchMock.resetHistory();
|
||||
fetchMock.mockClear();
|
||||
});
|
||||
|
||||
it("sends a GET request", async () => {
|
||||
@@ -41,10 +38,10 @@ describe("useFetchGet", () => {
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.lastUrl()).toBe("http://localhost/ok");
|
||||
expect(fetchMock.lastOptions()).toMatchObject({
|
||||
method: "GET",
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.lastCall()?.url).toBe("http://localhost/ok");
|
||||
expect(fetchMock.callHistory.lastCall()?.options).toMatchObject({
|
||||
method: "get",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -55,9 +52,9 @@ describe("useFetchGet", () => {
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.lastUrl()).toBe("http://localhost/ok");
|
||||
expect(fetchMock.lastOptions()).toMatchObject({
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.lastCall()?.url).toBe("http://localhost/ok");
|
||||
expect(fetchMock.callHistory.lastCall()?.options).toMatchObject({
|
||||
mode: "cors",
|
||||
credentials: "include",
|
||||
redirect: "follow",
|
||||
@@ -69,15 +66,15 @@ describe("useFetchGet", () => {
|
||||
useFetchGet<string>("http://localhost/ok", { autorun: false }),
|
||||
);
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(0);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(0);
|
||||
|
||||
act(() => {
|
||||
result.current.get();
|
||||
});
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.lastUrl()).toBe("http://localhost/ok");
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.lastCall()?.url).toBe("http://localhost/ok");
|
||||
});
|
||||
|
||||
it("will retry failed requests", async () => {
|
||||
@@ -121,12 +118,16 @@ describe("useFetchGet", () => {
|
||||
expect(result.current.isRetrying).toBe(false);
|
||||
expect(result.current.retryCount).toBe(FetchRetryConfig.retries + 1);
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(FetchRetryConfig.retries + 1);
|
||||
expect(fetchMock.lastUrl()).toBe("http://localhost/error");
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(
|
||||
FetchRetryConfig.retries + 1,
|
||||
);
|
||||
expect(fetchMock.callHistory.lastCall()?.url).toBe(
|
||||
"http://localhost/error",
|
||||
);
|
||||
|
||||
//verify headers for each request
|
||||
for (let i = 0; i <= FetchRetryConfig.retries; i++) {
|
||||
expect(fetchMock.calls()[i][1]).toMatchObject({
|
||||
expect(fetchMock.callHistory.calls()[i]?.options).toMatchObject({
|
||||
mode: i < FetchRetryConfig.retries ? "cors" : "no-cors",
|
||||
credentials: "include",
|
||||
redirect: "follow",
|
||||
@@ -153,7 +154,7 @@ describe("useFetchGet", () => {
|
||||
});
|
||||
|
||||
it("error is updated after 500 response with JSON body", async () => {
|
||||
fetchMock.mock("http://localhost/500/json", {
|
||||
fetchMock.route("http://localhost/500/json", {
|
||||
status: 500,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ status: "error" }),
|
||||
@@ -172,7 +173,7 @@ describe("useFetchGet", () => {
|
||||
});
|
||||
|
||||
it("error is updated after 500 response with plain body", async () => {
|
||||
fetchMock.mock("http://localhost/500/text", {
|
||||
fetchMock.route("http://localhost/500/text", {
|
||||
status: 500,
|
||||
body: "error",
|
||||
});
|
||||
@@ -245,13 +246,13 @@ describe("useFetchGet", () => {
|
||||
}
|
||||
|
||||
expect(result.current.response).toBe(null);
|
||||
expect(result.current.error).toBe("unknown error: foo");
|
||||
expect(result.current.error).toBe("foo");
|
||||
expect(result.current.isLoading).toBe(false);
|
||||
expect(result.current.isRetrying).toBe(false);
|
||||
});
|
||||
|
||||
it("error is updated on uparsable JSON", async () => {
|
||||
fetchMock.mock("http://localhost/json/invalid", {
|
||||
fetchMock.route("http://localhost/json/invalid", {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: "this is not a valid JSON body",
|
||||
});
|
||||
@@ -270,14 +271,14 @@ describe("useFetchGet", () => {
|
||||
|
||||
expect(result.current.response).toBe(null);
|
||||
expect(result.current.error).toBe(
|
||||
"invalid json response body at http://localhost/json/invalid reason: Unexpected token 'h', \"this is not\"... is not valid JSON",
|
||||
"unknown error: SyntaxError: Unexpected token 'h', \"this is not\"... is not valid JSON",
|
||||
);
|
||||
expect(result.current.isLoading).toBe(false);
|
||||
expect(result.current.isRetrying).toBe(false);
|
||||
});
|
||||
|
||||
it("doesn't update response on 200 response after cleanup", async () => {
|
||||
fetchMock.mock("http://localhost/slow/ok", {
|
||||
fetchMock.route("http://localhost/slow/ok", {
|
||||
delay: 1000,
|
||||
body: JSON.stringify({ status: "ok" }),
|
||||
});
|
||||
@@ -302,12 +303,12 @@ describe("useFetchGet", () => {
|
||||
|
||||
for (let i = 0; i <= FetchRetryConfig.retries; i++) {
|
||||
jest.runOnlyPendingTimers();
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
}
|
||||
});
|
||||
|
||||
it("doesn't update error on 500 response after cleanup", async () => {
|
||||
fetchMock.mock("http://localhost/slow/500", {
|
||||
fetchMock.route("http://localhost/slow/500", {
|
||||
delay: 1000,
|
||||
status: 500,
|
||||
body: JSON.stringify({ status: "error" }),
|
||||
@@ -333,12 +334,12 @@ describe("useFetchGet", () => {
|
||||
|
||||
for (let i = 0; i <= FetchRetryConfig.retries; i++) {
|
||||
jest.runOnlyPendingTimers();
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
}
|
||||
});
|
||||
|
||||
it("doesn't update error on failed response after cleanup", async () => {
|
||||
fetchMock.mock("http://localhost/slow/error", {
|
||||
fetchMock.route("http://localhost/slow/error", {
|
||||
delay: 1000,
|
||||
throws: new TypeError("failed to fetch"),
|
||||
});
|
||||
@@ -363,12 +364,12 @@ describe("useFetchGet", () => {
|
||||
|
||||
for (let i = 0; i <= FetchRetryConfig.retries; i++) {
|
||||
jest.runOnlyPendingTimers();
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
}
|
||||
});
|
||||
|
||||
it("doesn't update error on unparsable JSON after cleanup", async () => {
|
||||
fetchMock.mock("http://localhost/slow/json/invalid", {
|
||||
fetchMock.route("http://localhost/slow/json/invalid", {
|
||||
delay: 1000,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: "this is not a valid JSON body",
|
||||
@@ -393,11 +394,11 @@ describe("useFetchGet", () => {
|
||||
});
|
||||
|
||||
jest.runOnlyPendingTimers();
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
|
||||
it("doesn't update response after cleanup", async () => {
|
||||
fetchMock.mock("http://localhost/slow/text", {
|
||||
fetchMock.route("http://localhost/slow/text", {
|
||||
delay: 1000,
|
||||
body: "ok",
|
||||
});
|
||||
@@ -421,7 +422,7 @@ describe("useFetchGet", () => {
|
||||
});
|
||||
|
||||
jest.runOnlyPendingTimers();
|
||||
await fetchMock.flush(true);
|
||||
await fetchMock.callHistory.flush(true);
|
||||
});
|
||||
|
||||
it("doesn't update response after cleanup on slow body read", async () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { EmptyAPIResponse } from "__fixtures__/Fetch";
|
||||
import { MockGroup } from "__fixtures__/Stories";
|
||||
@@ -14,12 +14,12 @@ import {
|
||||
declare let global: any;
|
||||
|
||||
beforeEach(() => {
|
||||
fetchMock.reset();
|
||||
fetchMock.mockReset();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
fetchMock.reset();
|
||||
fetchMock.mockReset();
|
||||
});
|
||||
|
||||
describe("AlertStore.data", () => {
|
||||
@@ -530,8 +530,8 @@ describe("AlertStore.fetch", () => {
|
||||
|
||||
it("fetch() works with valid response", async () => {
|
||||
const response = EmptyAPIResponse();
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify(response),
|
||||
});
|
||||
|
||||
@@ -540,14 +540,14 @@ describe("AlertStore.fetch", () => {
|
||||
store.fetch("", false, "", "", false, {}, 5, {}),
|
||||
).resolves.toBeUndefined();
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(store.status.value).toEqual(AlertStoreStatuses.Idle);
|
||||
expect(store.info.version).toBe("fakeVersion");
|
||||
});
|
||||
|
||||
it("fetch() handles response with error correctly", async () => {
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify({ error: "Fetch error" }),
|
||||
});
|
||||
|
||||
@@ -556,7 +556,7 @@ describe("AlertStore.fetch", () => {
|
||||
store.fetch("", false, "", "", false, {}, 5, {}),
|
||||
).resolves.toBeUndefined();
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
expect(store.status.value).toEqual(AlertStoreStatuses.Failure);
|
||||
expect(store.info.version).toBe("unknown");
|
||||
});
|
||||
@@ -565,8 +565,8 @@ describe("AlertStore.fetch", () => {
|
||||
const consoleSpy = jest
|
||||
.spyOn(console, "trace")
|
||||
.mockImplementation(() => {});
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
throws: new Error("fetch error"),
|
||||
});
|
||||
|
||||
@@ -575,7 +575,7 @@ describe("AlertStore.fetch", () => {
|
||||
store.fetch("", false, "", "", false, {}, 5, {}),
|
||||
).resolves.toHaveProperty("error");
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(10);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(10);
|
||||
expect(store.status.value).toEqual(AlertStoreStatuses.Failure);
|
||||
expect(store.info.version).toBe("unknown");
|
||||
// there should be a trace of the error
|
||||
@@ -586,51 +586,51 @@ describe("AlertStore.fetch", () => {
|
||||
jest.spyOn(console, "trace").mockImplementation(() => {});
|
||||
const store = new AlertStore([]);
|
||||
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
throws: new Error("fetch error"),
|
||||
});
|
||||
|
||||
await expect(
|
||||
store.fetch("", false, "", "", false, {}, 5, {}),
|
||||
).resolves.toHaveProperty("error");
|
||||
expect(fetchMock.calls()).toHaveLength(10);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(10);
|
||||
});
|
||||
|
||||
it("fetch() retry counter is reset after successful fetch", async () => {
|
||||
jest.spyOn(console, "trace").mockImplementation(() => {});
|
||||
const store = new AlertStore(["label=value"]);
|
||||
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
throws: new Error("fetch error"),
|
||||
});
|
||||
|
||||
await expect(
|
||||
store.fetch("", false, "", "", false, {}, 5, {}),
|
||||
).resolves.toHaveProperty("error");
|
||||
expect(fetchMock.calls()).toHaveLength(10);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(10);
|
||||
|
||||
const response = EmptyAPIResponse();
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify(response),
|
||||
});
|
||||
|
||||
await expect(
|
||||
store.fetch("", false, "", "", false, {}, 5, {}),
|
||||
).resolves.toBeUndefined();
|
||||
expect(fetchMock.calls()).toHaveLength(1);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(1);
|
||||
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
throws: new Error("fetch error"),
|
||||
});
|
||||
|
||||
await expect(
|
||||
store.fetch("", false, "", "", false, {}, 5, {}),
|
||||
).resolves.toHaveProperty("error");
|
||||
expect(fetchMock.calls()).toHaveLength(10);
|
||||
expect(fetchMock.callHistory.calls()).toHaveLength(10);
|
||||
});
|
||||
|
||||
it("fetch() reloads the page after if auth middleware is detected", async () => {
|
||||
@@ -659,8 +659,8 @@ describe("AlertStore.fetch", () => {
|
||||
store.filters.setFilterValues([NewUnappliedFilter("foo")]);
|
||||
|
||||
jest.spyOn(console, "trace").mockImplementation(() => {});
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
throws: new Error("fetch error"),
|
||||
});
|
||||
|
||||
@@ -672,8 +672,8 @@ describe("AlertStore.fetch", () => {
|
||||
|
||||
it("stored settings are updated if needed after fetch", async () => {
|
||||
const response = EmptyAPIResponse();
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify(response),
|
||||
});
|
||||
|
||||
@@ -717,8 +717,8 @@ describe("AlertStore.fetch", () => {
|
||||
|
||||
it("wants to reload page after new version is returned in the API", async () => {
|
||||
const response = EmptyAPIResponse();
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify(response),
|
||||
});
|
||||
const store = new AlertStore(["label=value"]);
|
||||
@@ -728,8 +728,8 @@ describe("AlertStore.fetch", () => {
|
||||
expect(store.info.upgradeReady).toBe(false);
|
||||
|
||||
response.version = "newFakeVersion";
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify(response),
|
||||
});
|
||||
await expect(
|
||||
@@ -793,17 +793,19 @@ describe("AlertStore.fetch", () => {
|
||||
|
||||
it("uses correct query args with gridSortReverse=false", async () => {
|
||||
const response = EmptyAPIResponse();
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify(response),
|
||||
});
|
||||
const store = new AlertStore(["label=value"]);
|
||||
await expect(
|
||||
store.fetch("", false, "sortOrder", "sortLabel", false, {}, 5, {}),
|
||||
).resolves.toBeUndefined();
|
||||
expect(fetchMock.calls().length).toEqual(1);
|
||||
expect(fetchMock.calls()[0][0]).toBe("/alerts.json");
|
||||
expect(JSON.parse(fetchMock.calls()[0][1]?.body as string)).toStrictEqual({
|
||||
expect(fetchMock.callHistory.calls().length).toEqual(1);
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toContain("/alerts.json");
|
||||
expect(
|
||||
JSON.parse(fetchMock.callHistory.calls()[0]?.options?.body as string),
|
||||
).toStrictEqual({
|
||||
filters: ["label=value"],
|
||||
gridLabel: "",
|
||||
gridLimits: {},
|
||||
@@ -818,17 +820,19 @@ describe("AlertStore.fetch", () => {
|
||||
|
||||
it("uses correct query args with gridSortReverse=true", async () => {
|
||||
const response = EmptyAPIResponse();
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify(response),
|
||||
});
|
||||
const store = new AlertStore(["label=value"]);
|
||||
await expect(
|
||||
store.fetch("cluster", true, "sortOrder", "sortLabel", true, {}, 5, {}),
|
||||
).resolves.toBeUndefined();
|
||||
expect(fetchMock.calls().length).toEqual(1);
|
||||
expect(fetchMock.calls()[0][0]).toBe("/alerts.json");
|
||||
expect(JSON.parse(fetchMock.calls()[0][1]?.body as string)).toStrictEqual({
|
||||
expect(fetchMock.callHistory.calls().length).toEqual(1);
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toContain("/alerts.json");
|
||||
expect(
|
||||
JSON.parse(fetchMock.callHistory.calls()[0]?.options?.body as string),
|
||||
).toStrictEqual({
|
||||
filters: ["label=value"],
|
||||
gridLabel: "cluster",
|
||||
gridLimits: {},
|
||||
@@ -843,8 +847,8 @@ describe("AlertStore.fetch", () => {
|
||||
|
||||
it("uses correct query args with limits", async () => {
|
||||
const response = EmptyAPIResponse();
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify(response),
|
||||
});
|
||||
const store = new AlertStore(["label=value"]);
|
||||
@@ -866,9 +870,11 @@ describe("AlertStore.fetch", () => {
|
||||
{ "1234567890": 7, "1234567891": 1 },
|
||||
),
|
||||
).resolves.toBeUndefined();
|
||||
expect(fetchMock.calls().length).toEqual(1);
|
||||
expect(fetchMock.calls()[0][0]).toBe("/alerts.json");
|
||||
expect(JSON.parse(fetchMock.calls()[0][1]?.body as string)).toStrictEqual({
|
||||
expect(fetchMock.callHistory.calls().length).toEqual(1);
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toContain("/alerts.json");
|
||||
expect(
|
||||
JSON.parse(fetchMock.callHistory.calls()[0]?.options?.body as string),
|
||||
).toStrictEqual({
|
||||
filters: ["label=value"],
|
||||
gridLabel: "cluster",
|
||||
gridLimits: { bar: 7 },
|
||||
@@ -904,8 +910,8 @@ describe("AlertStore.fetch", () => {
|
||||
stateCount: { unprocessed: 0, active: 3, suppressed: 0 },
|
||||
},
|
||||
];
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify(response),
|
||||
});
|
||||
|
||||
@@ -923,9 +929,11 @@ describe("AlertStore.fetch", () => {
|
||||
{ g1: 7, g2: 1, g4: 6 },
|
||||
),
|
||||
).resolves.toBeUndefined();
|
||||
expect(fetchMock.calls().length).toEqual(1);
|
||||
expect(fetchMock.calls()[0][0]).toBe("/alerts.json");
|
||||
expect(JSON.parse(fetchMock.calls()[0][1]?.body as string)).toStrictEqual({
|
||||
expect(fetchMock.callHistory.calls().length).toEqual(1);
|
||||
expect(fetchMock.callHistory.calls()[0]?.url).toContain("/alerts.json");
|
||||
expect(
|
||||
JSON.parse(fetchMock.callHistory.calls()[0]?.options?.body as string),
|
||||
).toStrictEqual({
|
||||
filters: ["label=value"],
|
||||
gridLabel: "cluster",
|
||||
gridLimits: { bar: 7 },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { EmptyAPIResponse } from "__fixtures__/Fetch";
|
||||
import { DefaultsBase64 } from "__fixtures__/Defaults";
|
||||
@@ -34,8 +34,8 @@ it("renders without crashing with missing defaults div", () => {
|
||||
const response = EmptyAPIResponse();
|
||||
response.filters = [];
|
||||
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify(response),
|
||||
});
|
||||
|
||||
@@ -62,8 +62,8 @@ it("renders without crashing with defaults present", () => {
|
||||
const response = EmptyAPIResponse();
|
||||
response.filters = [];
|
||||
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify(response),
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { EmptyAPIResponse } from "__fixtures__/Fetch";
|
||||
import { mockMatchMedia } from "__fixtures__/matchMedia";
|
||||
@@ -37,8 +37,8 @@ it("loads ResizeObserver polyfill if needed", () => {
|
||||
const response = EmptyAPIResponse();
|
||||
response.filters = [];
|
||||
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify(response),
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import fetchMock from "fetch-mock";
|
||||
import fetchMock from "@fetch-mock/jest";
|
||||
|
||||
import { EmptyAPIResponse } from "__fixtures__/Fetch";
|
||||
import { mockMatchMedia } from "__fixtures__/matchMedia";
|
||||
@@ -46,8 +46,8 @@ it("doesn't load ResizeObserver polyfill if not needed", () => {
|
||||
const response = EmptyAPIResponse();
|
||||
response.filters = [];
|
||||
|
||||
fetchMock.reset();
|
||||
fetchMock.mock("*", {
|
||||
fetchMock.mockReset();
|
||||
fetchMock.route("*", {
|
||||
body: JSON.stringify(response),
|
||||
});
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ import React from "react";
|
||||
|
||||
import "@testing-library/jest-dom";
|
||||
|
||||
import fetchMock, { manageFetchMockGlobally } from "@fetch-mock/jest";
|
||||
|
||||
import { useInView } from "react-intersection-observer";
|
||||
|
||||
import { createMocks as createIdleTimerMocks } from "react-idle-timer";
|
||||
@@ -15,6 +17,10 @@ import { useFetchGet } from "Hooks/useFetchGet";
|
||||
|
||||
createIdleTimerMocks();
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
manageFetchMockGlobally(jest as any);
|
||||
fetchMock.mockGlobal();
|
||||
|
||||
configure({
|
||||
enforceActions: "always",
|
||||
//computedRequiresReaction: true,
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { TestEnvironment } from "jest-environment-jsdom";
|
||||
|
||||
export default class CustomTestEnvironment extends TestEnvironment {
|
||||
async setup() {
|
||||
await super.setup();
|
||||
this.global.Request = Request;
|
||||
this.global.Response = Response;
|
||||
this.global.ReadableStream = ReadableStream;
|
||||
this.global.fetch = fetch;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user