Skip to content

Commit 132166b

Browse files
committed
refactor: remove duplication on test files
1 parent d6e0d99 commit 132166b

7 files changed

Lines changed: 263 additions & 471 deletions

File tree

src/2024/Talks/LiveView.test.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
11
import LiveView from "./LiveView";
2-
import {QueryClient, QueryClientProvider} from "react-query";
3-
import {render, screen} from "@testing-library/react";
42
import React from "react";
3+
import { renderWithQueryClient, screen } from "../../utils/testing/testUtils";
54

65
describe("Live view component", () => {
76
it("renders without crashing", () => {
8-
const queryClient = new QueryClient();
9-
render(
10-
<QueryClientProvider client={queryClient}>
11-
<LiveView/>
12-
</QueryClientProvider>,
13-
);
7+
renderWithQueryClient(<LiveView />);
148
const titleElement = screen.getByText(/Live Schedule/);
159
expect(titleElement).toBeInTheDocument();
1610
});

src/2024/Talks/Talks.test.tsx

Lines changed: 8 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,40 @@
11
import React from "react";
2-
import {render, screen} from "@testing-library/react";
2+
import { screen } from "@testing-library/react";
33
import Talks2024 from "./Talks2024";
4-
import {QueryClient, QueryClientProvider} from "react-query";
4+
import { renderWithQueryClient } from "../../utils/testing/testUtils";
55

66
describe("Talks", () => {
77
it("renders without errors", () => {
8-
const queryClient = new QueryClient();
9-
render(
10-
<QueryClientProvider client={queryClient}>
11-
<Talks2024/>
12-
</QueryClientProvider>
13-
);
8+
renderWithQueryClient(<Talks2024 />);
149
});
1510

1611
it("renders the correct title", () => {
17-
const queryClient = new QueryClient();
18-
render(
19-
<QueryClientProvider client={queryClient}>
20-
<Talks2024/>
21-
</QueryClientProvider>
22-
);
12+
renderWithQueryClient(<Talks2024 />);
2313
const titleElement = screen.getByText(/TALKS/);
2414
expect(titleElement).toBeInTheDocument();
2515
});
2616

2717
it("renders the correct subtitle", () => {
28-
const queryClient = new QueryClient();
29-
render(
30-
<QueryClientProvider client={queryClient}>
31-
<Talks2024/>
32-
</QueryClientProvider>
33-
);
18+
renderWithQueryClient(<Talks2024 />);
3419
const subtitleElement = screen.getByText(
3520
/speakers coming from all corners of the world/i
3621
);
3722
expect(subtitleElement).toBeInTheDocument();
3823
});
3924

4025
it("renders a filter by track dropdown", () => {
41-
const queryClient = new QueryClient();
42-
render(
43-
<QueryClientProvider client={queryClient}>
44-
<Talks2024/>
45-
</QueryClientProvider>
46-
);
26+
renderWithQueryClient(<Talks2024 />);
4727
const dropdownElement = screen.getByText("Loading");
4828
expect(dropdownElement).toBeInTheDocument();
4929
});
5030

5131
it("renders a loading message when talks are being fetched", () => {
52-
const queryClient = new QueryClient();
53-
render(
54-
<QueryClientProvider client={queryClient}>
55-
<Talks2024/>
56-
</QueryClientProvider>
57-
);
32+
renderWithQueryClient(<Talks2024 />);
5833
expect(screen.getByText("Loading")).toBeInTheDocument();
5934
});
6035

6136
it("renders a message when no talks are selected", () => {
62-
const queryClient = new QueryClient();
63-
render(
64-
<QueryClientProvider client={queryClient}>
65-
<Talks2024/>
66-
</QueryClientProvider>
67-
);
37+
renderWithQueryClient(<Talks2024 />);
6838
const dropdownElement = screen.getByText("Loading");
6939
expect(dropdownElement).toBeInTheDocument();
7040
});
Lines changed: 44 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,43 @@
1-
import React, {FC} from "react";
2-
import {QueryClient, QueryClientProvider} from "react-query";
3-
import {renderHook, waitFor} from "@testing-library/react";
4-
import {useFetchSpeakers} from "./useFetchSpeakers";
5-
import axios, {AxiosHeaders, AxiosResponse} from "axios";
6-
import {speakerAdapter} from "../services/speakerAdapter";
7-
import {IResponse} from "../types/speakers";
1+
import { renderHook, waitFor } from "@testing-library/react";
2+
import { useFetchSpeakers } from "./useFetchSpeakers";
3+
import axios from "axios";
4+
import { speakerAdapter } from "../services/speakerAdapter";
5+
import { IResponse } from "../types/speakers";
6+
import {
7+
createMockAxiosResponse,
8+
createMockSpeaker,
9+
getQueryClientWrapper,
10+
SPEAKER_URLS,
11+
} from "../utils/testing/testUtils";
812

913
jest.mock("axios");
1014
const mockedAxios = axios as jest.Mocked<typeof axios>;
11-
const axiosHeaders = new AxiosHeaders();
1215

13-
const payload: AxiosResponse<IResponse[]> = {
14-
status: 200,
15-
statusText: "OK",
16-
headers: {},
17-
config: {
18-
headers: axiosHeaders,
19-
},
20-
data: [
16+
// Create mock speakers
17+
const mockSpeaker1 = createMockSpeaker();
18+
const mockSpeaker2 = createMockSpeaker({
19+
id: "2",
20+
fullName: "Jane Doe",
21+
profilePicture: "https://example.com/jane.jpg",
22+
tagLine: "Data scientist",
23+
bio: "I am a data scientist",
24+
sessions: [],
25+
links: [
2126
{
22-
id: "1",
23-
fullName: "John Smith",
24-
profilePicture: "https://example.com/john.jpg",
25-
tagLine: "Software engineer",
26-
bio: "I am a software engineer",
27-
sessions: [
28-
{
29-
id: 4567,
30-
name: "sample session",
31-
},
32-
],
33-
links: [
34-
{
35-
linkType: "Twitter",
36-
url: "https://twitter.com/johnsmith",
37-
title: "",
38-
},
39-
{
40-
linkType: "LinkedIn",
41-
url: "https://linkedin.com/in/johnsmith",
42-
title: "",
43-
},
44-
],
27+
linkType: "Twitter",
28+
url: "https://twitter.com/janedoe",
29+
title: "",
4530
},
4631
{
47-
id: "2",
48-
fullName: "Jane Doe",
49-
profilePicture: "https://example.com/jane.jpg",
50-
tagLine: "Data scientist",
51-
bio: "I am a data scientist",
52-
sessions: [],
53-
links: [
54-
{
55-
linkType: "Twitter",
56-
url: "https://twitter.com/janedoe",
57-
title: "",
58-
},
59-
{
60-
linkType: "LinkedIn",
61-
url: "https://linkedin.com/in/janedoe",
62-
title: "",
63-
},
64-
],
32+
linkType: "LinkedIn",
33+
url: "https://linkedin.com/in/janedoe",
34+
title: "",
6535
},
6636
],
67-
};
37+
});
38+
39+
// Create mock response
40+
const payload = createMockAxiosResponse([mockSpeaker1, mockSpeaker2]);
6841

6942
describe("fetch speaker hook and speaker adapter", () => {
7043
beforeAll(() => {
@@ -75,61 +48,25 @@ describe("fetch speaker hook and speaker adapter", () => {
7548
});
7649

7750
it("should adapt from a server response with default URL", async () => {
78-
const queryClient = new QueryClient();
79-
51+
const { wrapper } = getQueryClientWrapper();
8052
mockedAxios.get.mockImplementation(() => Promise.resolve(payload));
81-
const wrapper: FC<React.PropsWithChildren<React.PropsWithChildren<{}>>> = ({ children }) => {
82-
return (
83-
<QueryClientProvider client={queryClient}>
84-
{children}
85-
</QueryClientProvider>
86-
);
87-
};
8853

8954
const { result } = renderHook(() => useFetchSpeakers(), {
9055
wrapper,
9156
});
9257
await waitFor(() => result.current.isSuccess, {});
9358
await waitFor(() => !result.current.isLoading, {});
94-
expect(mockedAxios.get).toHaveBeenCalledWith("https://sessionize.com/api/v2/xhudniix/view/Speakers");
59+
expect(mockedAxios.get).toHaveBeenCalledWith(SPEAKER_URLS.DEFAULT);
9560
expect(result.current.isLoading).toEqual(false);
9661
expect(result.current.error).toEqual(null);
9762
expect(result.current.data).toEqual(speakerAdapter(payload.data));
9863
});
9964

10065
it("should adapt from server response a query with id", async () => {
10166
//Given
102-
const queryClient = new QueryClient();
67+
const { wrapper } = getQueryClientWrapper();
10368
mockedAxios.get.mockResolvedValueOnce(payload);
104-
const expectedPayload: IResponse[] = [
105-
{
106-
id: "1",
107-
bio: "I am a software engineer",
108-
fullName: "John Smith",
109-
links: [
110-
{
111-
linkType: "LinkedIn",
112-
url: "https://linkedin.com/in/johnsmith",
113-
title: "",
114-
},
115-
{
116-
url: "https://twitter.com/johnsmith",
117-
title: "",
118-
linkType: "Twitter",
119-
},
120-
],
121-
profilePicture: "https://example.com/john.jpg",
122-
tagLine: "Software engineer",
123-
sessions: [{ id: 4567, name: "sample session" }],
124-
},
125-
];
126-
const wrapper: FC<React.PropsWithChildren<React.PropsWithChildren<{}>>> = ({ children }) => {
127-
return (
128-
<QueryClientProvider client={queryClient}>
129-
{children}
130-
</QueryClientProvider>
131-
);
132-
};
69+
const expectedPayload: IResponse[] = [mockSpeaker1];
13370

13471
//When
13572
const { result } = renderHook(() => useFetchSpeakers("1"), {
@@ -138,64 +75,43 @@ describe("fetch speaker hook and speaker adapter", () => {
13875
await waitFor(() => result.current.isSuccess);
13976
await waitFor(() => !result.current.isLoading, {});
14077
//then
141-
expect(mockedAxios.get).toHaveBeenCalledWith("https://sessionize.com/api/v2/xhudniix/view/Speakers");
78+
expect(mockedAxios.get).toHaveBeenCalledWith(SPEAKER_URLS.DEFAULT);
14279
expect(result.current.data).toEqual(speakerAdapter(expectedPayload));
14380
});
14481

14582
it("should use 2023 URL when '2023' is passed", async () => {
146-
const queryClient = new QueryClient();
83+
const { wrapper } = getQueryClientWrapper();
14784
mockedAxios.get.mockImplementation(() => Promise.resolve(payload));
148-
const wrapper: FC<React.PropsWithChildren<React.PropsWithChildren<{}>>> = ({ children }) => {
149-
return (
150-
<QueryClientProvider client={queryClient}>
151-
{children}
152-
</QueryClientProvider>
153-
);
154-
};
15585

15686
const { result } = renderHook(() => useFetchSpeakers("2023"), {
15787
wrapper,
15888
});
15989
await waitFor(() => result.current.isSuccess, {});
16090
await waitFor(() => !result.current.isLoading, {});
161-
expect(mockedAxios.get).toHaveBeenCalledWith("https://sessionize.com/api/v2/ttsitynd/view/Speakers");
91+
expect(mockedAxios.get).toHaveBeenCalledWith(SPEAKER_URLS["2023"]);
16292
expect(result.current.isLoading).toEqual(false);
16393
expect(result.current.error).toEqual(null);
16494
expect(result.current.data).toEqual(speakerAdapter(payload.data));
16595
});
16696

16797
it("should use 2024 URL when '2024' is passed", async () => {
168-
const queryClient = new QueryClient();
98+
const { wrapper } = getQueryClientWrapper();
16999
mockedAxios.get.mockImplementation(() => Promise.resolve(payload));
170-
const wrapper: FC<React.PropsWithChildren<React.PropsWithChildren<{}>>> = ({ children }) => {
171-
return (
172-
<QueryClientProvider client={queryClient}>
173-
{children}
174-
</QueryClientProvider>
175-
);
176-
};
177100

178101
const { result } = renderHook(() => useFetchSpeakers("2024"), {
179102
wrapper,
180103
});
181104
await waitFor(() => result.current.isSuccess, {});
182105
await waitFor(() => !result.current.isLoading, {});
183-
expect(mockedAxios.get).toHaveBeenCalledWith("https://sessionize.com/api/v2/teq4asez/view/Speakers");
106+
expect(mockedAxios.get).toHaveBeenCalledWith(SPEAKER_URLS["2024"]);
184107
expect(result.current.isLoading).toEqual(false);
185108
expect(result.current.error).toEqual(null);
186109
expect(result.current.data).toEqual(speakerAdapter(payload.data));
187110
});
188111

189112
it("should use custom URL when a URL is passed", async () => {
190-
const queryClient = new QueryClient();
113+
const { wrapper } = getQueryClientWrapper();
191114
mockedAxios.get.mockImplementation(() => Promise.resolve(payload));
192-
const wrapper: FC<React.PropsWithChildren<React.PropsWithChildren<{}>>> = ({ children }) => {
193-
return (
194-
<QueryClientProvider client={queryClient}>
195-
{children}
196-
</QueryClientProvider>
197-
);
198-
};
199115

200116
const customUrl = "https://example.com/api/speakers";
201117
const { result } = renderHook(() => useFetchSpeakers(customUrl), {
@@ -211,37 +127,9 @@ describe("fetch speaker hook and speaker adapter", () => {
211127

212128
it("should filter by ID when both a URL and ID are passed", async () => {
213129
//Given
214-
const queryClient = new QueryClient();
130+
const { wrapper } = getQueryClientWrapper();
215131
mockedAxios.get.mockResolvedValueOnce(payload);
216-
const expectedPayload: IResponse[] = [
217-
{
218-
id: "1",
219-
bio: "I am a software engineer",
220-
fullName: "John Smith",
221-
links: [
222-
{
223-
linkType: "LinkedIn",
224-
url: "https://linkedin.com/in/johnsmith",
225-
title: "",
226-
},
227-
{
228-
url: "https://twitter.com/johnsmith",
229-
title: "",
230-
linkType: "Twitter",
231-
},
232-
],
233-
profilePicture: "https://example.com/john.jpg",
234-
tagLine: "Software engineer",
235-
sessions: [{ id: 4567, name: "sample session" }],
236-
},
237-
];
238-
const wrapper: FC<React.PropsWithChildren<React.PropsWithChildren<{}>>> = ({ children }) => {
239-
return (
240-
<QueryClientProvider client={queryClient}>
241-
{children}
242-
</QueryClientProvider>
243-
);
244-
};
132+
const expectedPayload: IResponse[] = [mockSpeaker1];
245133

246134
//When
247135
const customUrl = "https://example.com/api/speakers";
@@ -254,4 +142,4 @@ describe("fetch speaker hook and speaker adapter", () => {
254142
expect(mockedAxios.get).toHaveBeenCalledWith(customUrl);
255143
expect(result.current.data).toEqual(speakerAdapter(expectedPayload));
256144
});
257-
});
145+
});

0 commit comments

Comments
 (0)