Skip to content

Commit 8c42f8d

Browse files
authored
chore: Address publisher code coverage warnings from TiCS (canonical#5099)
1 parent 45835bf commit 8c42f8d

4 files changed

Lines changed: 239 additions & 16 deletions

File tree

static/js/publisher/pages/RegisterNameDispute/RegisterNameDisputeForm.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,8 @@ function RegisterNameDisputeForm({
5252
throw new Error("Unable to register name dispute");
5353
}
5454

55-
setTimeout(() => {
56-
setIsSending(false);
57-
setClaimSubmitted(true);
58-
}, 1000);
55+
setIsSending(false);
56+
setClaimSubmitted(true);
5957
}}
6058
>
6159
<Row>
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { BrowserRouter } from "react-router-dom";
2+
import { RecoilRoot } from "recoil";
3+
import { render, screen } from "@testing-library/react";
4+
import userEvent from "@testing-library/user-event";
5+
import "@testing-library/jest-dom";
6+
7+
import { RecoilObserver, storesResponse } from "../../../test-utils";
8+
9+
import { brandStoresState } from "../../../state/brandStoreState";
10+
11+
import RegisterNameDisputeForm from "../RegisterNameDisputeForm";
12+
13+
import type { MutableSnapshot } from "recoil";
14+
15+
const testSnapName = "test-snap-name";
16+
const testStoreName = "Test store";
17+
18+
function renderComponent() {
19+
render(
20+
<BrowserRouter>
21+
<RecoilRoot
22+
initializeState={(snapshot: MutableSnapshot) => {
23+
return snapshot.set(brandStoresState, storesResponse);
24+
}}
25+
>
26+
<RecoilObserver node={brandStoresState} event={jest.fn()} />
27+
<RegisterNameDisputeForm
28+
snapName={testSnapName}
29+
store={testStoreName}
30+
setClaimSubmitted={jest.fn()}
31+
/>
32+
</RecoilRoot>
33+
</BrowserRouter>,
34+
);
35+
}
36+
37+
jest.mock("react-router-dom", () => {
38+
return {
39+
...jest.requireActual("react-router-dom"),
40+
useSearchParams: () => [
41+
new URLSearchParams({
42+
snap_name: testSnapName,
43+
store: testStoreName,
44+
}),
45+
],
46+
};
47+
});
48+
49+
describe("RegisterNameDisputeForm", () => {
50+
test("shows snap name in heading", () => {
51+
renderComponent();
52+
const el = screen.getByText("Claim the name", { exact: false });
53+
expect(el.textContent).toEqual(`Claim the name ${testSnapName}`);
54+
});
55+
56+
test("shows store name in form field", () => {
57+
renderComponent();
58+
expect(screen.getByLabelText("Store")).toHaveValue(testStoreName);
59+
});
60+
61+
test("shows snap name in form field", () => {
62+
renderComponent();
63+
expect(screen.getByLabelText("Snap name")).toHaveValue(testSnapName);
64+
});
65+
66+
test("CTA button is disabled by default", () => {
67+
renderComponent();
68+
expect(
69+
screen.getByRole("button", { name: "Submit name claim" }),
70+
).toHaveAttribute("aria-disabled", "true");
71+
});
72+
73+
test("CTA button is enabled if comment is present", async () => {
74+
const user = userEvent.setup();
75+
76+
renderComponent();
77+
78+
await user.type(screen.getByLabelText("Comment"), "This is a test comment");
79+
80+
expect(
81+
screen.getByRole("button", { name: "Submit name claim" }),
82+
).not.toHaveAttribute("aria-disabled");
83+
});
84+
});

static/js/publisher/pages/RequestReservedName/RequestReservedName.tsx

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useState } from "react";
2-
import { Link } from "react-router-dom";
2+
import { Link, useSearchParams } from "react-router-dom";
33
import { useRecoilValue } from "recoil";
44
import {
55
Form,
@@ -21,9 +21,9 @@ function RequestReservedName(): React.JSX.Element {
2121
useState<boolean>(false);
2222
const [errorNotification, setErrorNotification] = useState<string>();
2323
const stores = useRecoilValue(brandStoresState);
24-
const params = new URLSearchParams(document.location.search);
25-
const snapName = params.get("snap_name");
26-
const store = params.get("store");
24+
const [searchParams] = useSearchParams();
25+
const snapName = searchParams.get("snap_name");
26+
const store = searchParams.get("store");
2727

2828
const selectedStore = stores.find((s) => s.name === store) || {
2929
name: "Global",
@@ -78,15 +78,13 @@ function RequestReservedName(): React.JSX.Element {
7878

7979
const responseData = await response.json();
8080

81-
setTimeout(() => {
82-
if (!responseData.success) {
83-
setErrorNotification(responseData.message);
84-
} else {
85-
setShowSuccessNotification(true);
86-
}
81+
if (!responseData.success) {
82+
setErrorNotification(responseData.message);
83+
} else {
84+
setShowSuccessNotification(true);
85+
}
8786

88-
setIsSubmitting(false);
89-
}, 1500);
87+
setIsSubmitting(false);
9088
}}
9189
>
9290
<Row>
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import { BrowserRouter } from "react-router-dom";
2+
import { RecoilRoot } from "recoil";
3+
import { http, HttpResponse } from "msw";
4+
import { setupServer } from "msw/node";
5+
import { render, screen, waitFor } from "@testing-library/react";
6+
import userEvent from "@testing-library/user-event";
7+
import "@testing-library/jest-dom";
8+
9+
import { RecoilObserver, storesResponse } from "../../../test-utils";
10+
11+
import { brandStoresState } from "../../../state/brandStoreState";
12+
13+
import RequestReservedName from "../RequestReservedName";
14+
15+
import type { MutableSnapshot } from "recoil";
16+
17+
const testSnapName = "test-snap-name";
18+
const testStoreName = "Test store";
19+
20+
window.CSRF_TOKEN = "test-csrf-token";
21+
22+
function renderComponent() {
23+
render(
24+
<BrowserRouter>
25+
<RecoilRoot
26+
initializeState={(snapshot: MutableSnapshot) => {
27+
return snapshot.set(brandStoresState, storesResponse);
28+
}}
29+
>
30+
<RecoilObserver node={brandStoresState} event={jest.fn()} />
31+
<RequestReservedName />
32+
</RecoilRoot>
33+
</BrowserRouter>,
34+
);
35+
}
36+
37+
jest.mock("react-router-dom", () => {
38+
return {
39+
...jest.requireActual("react-router-dom"),
40+
useSearchParams: () => [
41+
new URLSearchParams({
42+
snap_name: testSnapName,
43+
store: testStoreName,
44+
}),
45+
],
46+
};
47+
});
48+
49+
const server = setupServer();
50+
51+
beforeAll(() => {
52+
server.listen();
53+
});
54+
55+
afterEach(() => {
56+
server.resetHandlers();
57+
});
58+
59+
afterAll(() => {
60+
server.close();
61+
});
62+
63+
describe("RequestReservedName", () => {
64+
test("shows snap name in heading", () => {
65+
renderComponent();
66+
const el = screen.getByText("Request reserved name", { exact: false });
67+
expect(el.textContent).toEqual(`Request reserved name ${testSnapName}`);
68+
});
69+
70+
test("shows store name in form field", () => {
71+
renderComponent();
72+
expect(screen.getByLabelText("Store")).toHaveValue(testStoreName);
73+
});
74+
75+
test("shows snap name in form field", () => {
76+
renderComponent();
77+
expect(screen.getByLabelText("Snap name")).toHaveValue(testSnapName);
78+
});
79+
80+
test("CTA button is disabled by default", () => {
81+
renderComponent();
82+
expect(
83+
screen.getByRole("button", { name: "Yes, I am sure" }),
84+
).toHaveAttribute("aria-disabled", "true");
85+
});
86+
87+
test("CTA button is enabled if comment is present", async () => {
88+
const user = userEvent.setup();
89+
90+
renderComponent();
91+
92+
await user.type(screen.getByLabelText("Comment"), "This is a test comment");
93+
94+
expect(
95+
screen.getByRole("button", { name: "Yes, I am sure" }),
96+
).not.toHaveAttribute("aria-disabled");
97+
});
98+
99+
test("shows notification if form submitted successfully", async () => {
100+
const user = userEvent.setup();
101+
102+
server.use(
103+
http.post("/api/register-name-dispute", () => {
104+
return HttpResponse.json({
105+
success: true,
106+
});
107+
}),
108+
);
109+
110+
renderComponent();
111+
112+
await user.type(screen.getByLabelText("Comment"), "This is a test comment");
113+
await user.click(screen.getByRole("button", { name: "Yes, I am sure" }));
114+
115+
await waitFor(() => {
116+
expect(
117+
screen.getByText("Your claim has been submitted and will be reviewed"),
118+
).toBeInTheDocument();
119+
});
120+
});
121+
122+
test("shows notification if error when submitting form", async () => {
123+
const user = userEvent.setup();
124+
125+
server.use(
126+
http.post("/api/register-name-dispute", () => {
127+
return HttpResponse.json({
128+
success: false,
129+
message: "Test error message",
130+
});
131+
}),
132+
);
133+
134+
renderComponent();
135+
136+
await user.type(screen.getByLabelText("Comment"), "This is a test comment");
137+
await user.click(screen.getByRole("button", { name: "Yes, I am sure" }));
138+
139+
await waitFor(() => {
140+
expect(screen.getByText("Test error message")).toBeInTheDocument();
141+
});
142+
});
143+
});

0 commit comments

Comments
 (0)