Skip to content

Commit 22d2a14

Browse files
Merge pull request #25 from Eric-Zhang-Developer/test/try-again-button
Write new integration test for full user flow for try again button
2 parents ba2323a + 0743b69 commit 22d2a14

File tree

2 files changed

+119
-37
lines changed

2 files changed

+119
-37
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ You can try out the application here: [https://follow-diff.vercel.app/](https://
2727
* **Robust Type-Safety**: Employs TypeScript and Zod for schema validation to ensure the data from Instagram's export files is correctly parsed and handled, preventing runtime errors and improving maintainability.
2828

2929
* **Comprehensive Testing**: Includes a suite of tests using Jest and React Testing Library to ensure the reliability of core logic and UI components. The test suites achieve the following coverage:
30-
* **Statements**: 96.25%
30+
* **Statements**: 97.50%
3131
* **Branches**: 100.00%
32-
* **Functions**: 82.35%
33-
* **Lines**: 98.64%
32+
* **Functions**: 88.23%
33+
* **Lines**: 100.00%
3434

3535

3636
## Setup

src/app/__tests__/page.test.tsx

Lines changed: 116 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ import { render, screen, waitFor } from "@testing-library/react";
22
import userEvent from "@testing-library/user-event";
33
import Home from "../page";
44
// fs and path are for the malformed json so Jest does not freak out and throw a syntax error
5-
import fs from 'fs';
6-
import path from 'path';
5+
import fs from "fs";
6+
import path from "path";
77

88
import mockFollowers from "./__fixtures__/followers.json";
99
import mockFollowing from "./__fixtures__/following.json";
10-
import nonConformingData from "./__fixtures__/nonConformingData.json"
11-
10+
import nonConformingData from "./__fixtures__/nonConformingData.json";
1211

1312
// Since we are testing similar user flows the initial code is almost line for like the same
1413

@@ -18,12 +17,20 @@ describe("User Flow", () => {
1817
// Assemble
1918
render(<Home></Home>);
2019
const user = userEvent.setup();
21-
const followers = new File([JSON.stringify(mockFollowers)], "followers.json", {
22-
type: "application/json",
23-
});
24-
const following = new File([JSON.stringify(mockFollowing)], "following.json", {
25-
type: "application/json",
26-
});
20+
const followers = new File(
21+
[JSON.stringify(mockFollowers)],
22+
"followers.json",
23+
{
24+
type: "application/json",
25+
},
26+
);
27+
const following = new File(
28+
[JSON.stringify(mockFollowing)],
29+
"following.json",
30+
{
31+
type: "application/json",
32+
},
33+
);
2734

2835
// Act
2936
const fileInput = screen.getByTestId("file-input");
@@ -34,13 +41,19 @@ describe("User Flow", () => {
3441
});
3542

3643
// Assert
37-
const nonFollowerFriend = await screen.findByRole("listitem", { name: /ex_friend_dorthy/i });
44+
const nonFollowerFriend = await screen.findByRole("listitem", {
45+
name: /ex_friend_dorthy/i,
46+
});
3847
expect(nonFollowerFriend).toBeInTheDocument();
3948

40-
const nonFollowerOrganization = await screen.findByRole("listitem", { name: /NASA/i });
49+
const nonFollowerOrganization = await screen.findByRole("listitem", {
50+
name: /NASA/i,
51+
});
4152
expect(nonFollowerOrganization).toBeInTheDocument();
4253

43-
const mutualFollowerItem = screen.queryByRole("listitem", { name: /friend_alice/i });
54+
const mutualFollowerItem = screen.queryByRole("listitem", {
55+
name: /friend_alice/i,
56+
});
4457
expect(mutualFollowerItem).not.toBeInTheDocument();
4558
});
4659

@@ -52,16 +65,22 @@ describe("User Flow", () => {
5265
// Assemble
5366
render(<Home></Home>);
5467
const user = userEvent.setup();
55-
const followers = new File([JSON.stringify(mockFollowers)], "followers.json", {
56-
type: "application/json",
57-
});
68+
const followers = new File(
69+
[JSON.stringify(mockFollowers)],
70+
"followers.json",
71+
{
72+
type: "application/json",
73+
},
74+
);
5875

5976
// Act
6077
const fileInput = screen.getByTestId("file-input");
6178
await user.upload(fileInput, [followers]);
6279

6380
// Assert
64-
const followersListUploaded = await screen.findByText("Followers List Uploaded!");
81+
const followersListUploaded = await screen.findByText(
82+
"Followers List Uploaded!",
83+
);
6584
expect(followersListUploaded).toBeInTheDocument();
6685
});
6786

@@ -70,16 +89,22 @@ describe("User Flow", () => {
7089
// Assemble
7190
render(<Home></Home>);
7291
const user = userEvent.setup();
73-
const following = new File([JSON.stringify(mockFollowing)], "following.json", {
74-
type: "application/json",
75-
});
92+
const following = new File(
93+
[JSON.stringify(mockFollowing)],
94+
"following.json",
95+
{
96+
type: "application/json",
97+
},
98+
);
7699

77100
// Act
78101
const fileInput = screen.getByTestId("file-input");
79102
await user.upload(fileInput, [following]);
80103

81104
// Assert
82-
const followingListUploaded = await screen.findByText("Following List Uploaded!");
105+
const followingListUploaded = await screen.findByText(
106+
"Following List Uploaded!",
107+
);
83108
expect(followingListUploaded).toBeInTheDocument();
84109
});
85110

@@ -91,9 +116,13 @@ describe("User Flow", () => {
91116
// Assemble
92117
render(<Home></Home>);
93118
const user = userEvent.setup();
94-
const nonConforming = new File([JSON.stringify(nonConformingData)], "following.json", {
95-
type: "application/json",
96-
});
119+
const nonConforming = new File(
120+
[JSON.stringify(nonConformingData)],
121+
"following.json",
122+
{
123+
type: "application/json",
124+
},
125+
);
97126

98127
// Act
99128
const fileInput = screen.getByTestId("file-input");
@@ -110,9 +139,15 @@ describe("User Flow", () => {
110139
const user = userEvent.setup();
111140

112141
// This is the test case where we need fs and path due to syntax error
113-
const malformedFilePath = path.join(__dirname, '__fixtures__', 'malformed.json');
114-
const malformedFileContent = fs.readFileSync(malformedFilePath, 'utf-8');
115-
const malformedFile = new File([malformedFileContent], 'malformed.json', { type: 'application/json' });
142+
const malformedFilePath = path.join(
143+
__dirname,
144+
"__fixtures__",
145+
"malformed.json",
146+
);
147+
const malformedFileContent = fs.readFileSync(malformedFilePath, "utf-8");
148+
const malformedFile = new File([malformedFileContent], "malformed.json", {
149+
type: "application/json",
150+
});
116151

117152
// Act
118153
const fileInput = screen.getByTestId("file-input");
@@ -128,19 +163,29 @@ describe("User Flow", () => {
128163
it("should return me back to the drop / default section when I hit the reset button", async () => {
129164
render(<Home></Home>);
130165
const user = userEvent.setup();
131-
const followers = new File([JSON.stringify(mockFollowers)], "followers.json", {
132-
type: "application/json",
133-
});
134-
const following = new File([JSON.stringify(mockFollowing)], "following.json", {
135-
type: "application/json",
136-
});
166+
const followers = new File(
167+
[JSON.stringify(mockFollowers)],
168+
"followers.json",
169+
{
170+
type: "application/json",
171+
},
172+
);
173+
const following = new File(
174+
[JSON.stringify(mockFollowing)],
175+
"following.json",
176+
{
177+
type: "application/json",
178+
},
179+
);
137180

138181
// Act (Part 1)
139182
const fileInput = screen.getByTestId("file-input");
140183
await user.upload(fileInput, [followers, following]);
141184

142185
// Assert (Intermediate)
143-
const resetButton = await screen.findByRole("button", { name: /Reset Button/i });
186+
const resetButton = await screen.findByRole("button", {
187+
name: /Reset Button/i,
188+
});
144189
expect(resetButton).toBeInTheDocument();
145190

146191
// Act (Part 2)
@@ -151,4 +196,41 @@ describe("User Flow", () => {
151196
expect(fileInputAfterReset).toBeInTheDocument();
152197
});
153198
});
199+
200+
describe("Try Again Button", () => {
201+
it("should reset the to the dropbox when the button is clicked", async () => {
202+
// This logic is almost the exact same for the error button check but we do another step which is clicking to complete the user flow
203+
// Honestly could be bundled in with the other test but not for clarity
204+
205+
// Assemble
206+
render(<Home></Home>);
207+
const user = userEvent.setup();
208+
209+
// This is the test case where we need fs and path due to syntax error
210+
const malformedFilePath = path.join(
211+
__dirname,
212+
"__fixtures__",
213+
"malformed.json",
214+
);
215+
const malformedFileContent = fs.readFileSync(malformedFilePath, "utf-8");
216+
const malformedFile = new File([malformedFileContent], "malformed.json", {
217+
type: "application/json",
218+
});
219+
220+
// Act (Intermediate)
221+
const fileInput = screen.getByTestId("file-input");
222+
await user.upload(fileInput, [malformedFile]);
223+
224+
// Assert (Intermediate)
225+
const tryAgainButton = await screen.findByText("Try Again");
226+
expect(tryAgainButton).toBeInTheDocument();
227+
228+
// Act (Final)
229+
await user.click(tryAgainButton);
230+
231+
// Assert (Final)
232+
const fileInputAfterTryAgain = await screen.findByTestId("file-input");
233+
expect(fileInputAfterTryAgain).toBeInTheDocument();
234+
});
235+
});
154236
});

0 commit comments

Comments
 (0)