Skip to content

Commit 3173bb8

Browse files
authored
Merge branch 'master' into 2269-alert-get-dismissed-in-the-adminalerts-page
2 parents a47d62a + 819db22 commit 3173bb8

File tree

13 files changed

+610
-8413
lines changed

13 files changed

+610
-8413
lines changed

__tests__/pages/admin/lessons/__snapshots__/lessons.test.js.snap

Lines changed: 0 additions & 8073 deletions
This file was deleted.
Lines changed: 118 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,147 @@
1-
import '../../../../__mocks__/useIsMac.mock'
2-
import '../../../../__mocks__/useBreakpoint.mock'
31
import React from 'react'
4-
import Lessons from '../../../../pages/admin/lessons/index'
2+
import Lessons from '../../../../pages/admin/lessons'
3+
import { MockedProvider } from '@apollo/client/testing'
4+
import { act, render, waitFor } from '@testing-library/react'
55
import dummyLessonData from '../../../../__dummy__/lessonData'
66
import dummySessionData from '../../../../__dummy__/sessionData'
77
import dummyAlertData from '../../../../__dummy__/alertData'
8-
import { MockedProvider } from '@apollo/client/testing'
9-
import {
10-
render,
11-
waitForElementToBeRemoved,
12-
fireEvent,
13-
waitFor,
14-
act
15-
} from '@testing-library/react'
168
import '@testing-library/jest-dom'
179
import GET_APP from '../../../../graphql/queries/getApp'
18-
import GET_SESSION from '../../../../graphql/queries/getSession'
10+
import GET_FLAGGED_EXERCISES from '../../../../graphql/queries/getFlaggedExercises'
1911

20-
const mocks = [
12+
const mockExercises = [
2113
{
22-
request: { query: GET_APP },
23-
result: {
24-
data: {
25-
session: dummySessionData,
26-
lessons: dummyLessonData,
27-
alerts: dummyAlertData
14+
flaggedAt: '1651723200000',
15+
module: {
16+
lesson: {
17+
title: 'Arrays'
2818
}
2919
}
3020
},
3121
{
32-
request: { query: GET_APP },
33-
result: {
34-
data: {
35-
session: dummySessionData,
36-
lessons: dummyLessonData,
37-
alerts: dummyAlertData
22+
flaggedAt: '1641099600000',
23+
module: {
24+
lesson: {
25+
title: 'Arrays'
3826
}
3927
}
4028
},
4129
{
42-
request: { query: GET_SESSION },
43-
result: {
44-
data: {
45-
session: {
46-
...dummySessionData
47-
}
30+
flaggedAt: '1609563600000',
31+
module: {
32+
lesson: {
33+
title: 'Foundations of JavaScript'
34+
}
35+
}
36+
},
37+
{
38+
flaggedAt: null,
39+
module: {
40+
lesson: {
41+
title: 'Arrays'
42+
}
43+
}
44+
},
45+
{
46+
flaggedAt: '1357189200000',
47+
module: {
48+
lesson: {
49+
title: 'Foundations of JavaScript'
50+
}
51+
}
52+
},
53+
{
54+
flaggedAt: '1462420800000',
55+
module: {
56+
lesson: {
57+
title: 'Foundations of JavaScript'
58+
}
59+
}
60+
},
61+
{
62+
flaggedAt: null,
63+
module: {
64+
lesson: {
65+
title: 'Foundations of JavaScript'
4866
}
4967
}
5068
}
5169
]
5270

53-
describe('Users test', () => {
54-
test('should switch to selected lesson in AdminLessonsSidebar', async () => {
55-
const { container, getByText, queryByText } = render(
56-
<MockedProvider mocks={mocks} addTypename={false}>
71+
const mocks = {
72+
lessonsLoaded: [
73+
{
74+
request: { query: GET_APP },
75+
result: {
76+
data: {
77+
session: dummySessionData,
78+
lessons: dummyLessonData,
79+
alerts: dummyAlertData
80+
}
81+
}
82+
},
83+
{
84+
request: { query: GET_FLAGGED_EXERCISES },
85+
result: {
86+
data: {
87+
exercises: mockExercises
88+
}
89+
}
90+
}
91+
],
92+
lessonsNotLoaded: [
93+
{
94+
request: { query: GET_APP },
95+
result: {
96+
data: {
97+
session: dummySessionData,
98+
lessons: undefined,
99+
alerts: dummyAlertData
100+
}
101+
}
102+
},
103+
{
104+
request: { query: GET_FLAGGED_EXERCISES },
105+
result: {
106+
data: {
107+
exercises: mockExercises
108+
}
109+
}
110+
}
111+
]
112+
}
113+
114+
describe('new admin lessons page tests', () => {
115+
test('should render adminLessonCard components and show number of pending questions', async () => {
116+
expect.assertions(4)
117+
118+
const { container, getByText, getAllByText } = render(
119+
<MockedProvider mocks={mocks.lessonsLoaded} addTypename={false}>
57120
<Lessons />
58121
</MockedProvider>
59122
)
60-
await waitForElementToBeRemoved(() => queryByText('Loading...'))
61123

62124
// Used to wait for the query response to arrive
63-
await act(async () => await new Promise(res => setTimeout(() => res(), 0)))
125+
await act(async () => await new Promise(res => setTimeout(res, 0)))
126+
127+
await waitFor(() => expect(getByText('3 Pending Questions')).toBeTruthy())
128+
expect(() => getByText('2 Pending Questions')).toBeTruthy()
129+
expect(() => getAllByText('0 Pending Questions')).toBeTruthy()
130+
expect(() => getByText('Arrays')).toBeTruthy()
131+
})
132+
133+
test('should not render any components if lessons data does not load', async () => {
134+
expect.assertions(2)
135+
136+
const { container, getByText, getAllByText } = render(
137+
<MockedProvider mocks={mocks.lessonsNotLoaded}>
138+
<Lessons />
139+
</MockedProvider>
140+
)
141+
142+
await act(async () => await new Promise(res => setTimeout(res, 0)))
64143

65-
await waitFor(() => expect(container).toMatchSnapshot())
66-
const searchByName = getByText('Objects')
67-
fireEvent.click(searchByName)
68-
await waitFor(() => expect(container).toMatchSnapshot())
144+
expect(() => getAllByText('0 Pending Questions')).toThrow()
145+
expect(() => getByText('Arrays')).toThrow()
69146
})
70147
})
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
import React from 'react'
2+
import AddNewLessonPage from '../../../../../pages/admin/lessons/new'
3+
import GET_APP from '../../../../../graphql/queries/getApp'
4+
import CREATE_LESSON from '../../../../../graphql/queries/createLesson'
5+
import dummySessionData from '../../../../../__dummy__/sessionData'
6+
import dummyLessonsData from '../../../../../__dummy__/lessonData'
7+
import dummyAlertData from '../../../../../__dummy__/alertData'
8+
import { act, render, screen } from '@testing-library/react'
9+
import { MockedProvider } from '@apollo/client/testing'
10+
import userEvent from '@testing-library/user-event'
11+
import { useRouter } from 'next/router'
12+
import * as Sentry from '@sentry/browser'
13+
14+
// Imported to be able to use expect(...).toBeInTheDocument()
15+
import '@testing-library/jest-dom'
16+
17+
const createdLesson = {
18+
id: null,
19+
title: 'New Lesson',
20+
description: 'New description',
21+
docUrl: '',
22+
githubUrl: '',
23+
videoUrl: '',
24+
order: 10,
25+
slug: 'js10',
26+
chatUrl: ''
27+
}
28+
29+
const createLessonMock = {
30+
request: {
31+
query: CREATE_LESSON,
32+
variables: {
33+
title: 'New Lesson',
34+
description: 'New description',
35+
docUrl: '',
36+
githubUrl: '',
37+
videoUrl: '',
38+
order: 10,
39+
slug: 'js10',
40+
chatUrl: ''
41+
}
42+
},
43+
result: {
44+
data: {
45+
createLesson: dummyLessonsData
46+
}
47+
},
48+
newData: jest.fn(() => ({
49+
data: {
50+
createLesson: dummyLessonsData
51+
}
52+
}))
53+
}
54+
const createLessonMockWithError = {
55+
request: {
56+
query: CREATE_LESSON,
57+
variables: {
58+
title: 'New Lesson',
59+
description: 'New description',
60+
docUrl: '',
61+
githubUrl: '',
62+
videoUrl: '',
63+
order: 10,
64+
slug: 'js10',
65+
chatUrl: ''
66+
}
67+
},
68+
error: new Error('error')
69+
}
70+
71+
const getAppQueryMock = {
72+
request: { query: GET_APP },
73+
result: {
74+
data: {
75+
session: dummySessionData,
76+
lessons: dummyLessonsData,
77+
alerts: dummyAlertData
78+
}
79+
}
80+
}
81+
82+
const mocks = [getAppQueryMock, createLessonMock]
83+
const mocksWithError = [getAppQueryMock, createLessonMockWithError]
84+
85+
describe('AddNewLesson Page', () => {
86+
const { push } = useRouter()
87+
88+
it('Should add a new lesson', async () => {
89+
expect.assertions(1)
90+
91+
render(
92+
<MockedProvider mocks={mocks}>
93+
<AddNewLessonPage />
94+
</MockedProvider>
95+
)
96+
97+
await act(() => new Promise(res => setTimeout(res, 0)))
98+
99+
const title = screen.getByTestId('input0')
100+
await userEvent.type(title, createdLesson.title)
101+
102+
const description = screen.getByTestId('textbox')
103+
await userEvent.type(description, createdLesson.description)
104+
105+
const submitBtn = screen.getByText('Create Lesson')
106+
await userEvent.click(submitBtn)
107+
108+
expect(createLessonMock.newData).toBeCalled()
109+
})
110+
111+
it('Should not add a new lesson if inputs are invalid', async () => {
112+
expect.assertions(1)
113+
114+
render(
115+
<MockedProvider mocks={mocks}>
116+
<AddNewLessonPage />
117+
</MockedProvider>
118+
)
119+
120+
await act(() => new Promise(res => setTimeout(res, 0)))
121+
122+
const submitBtn = screen.getByText('Create Lesson')
123+
await userEvent.click(submitBtn)
124+
125+
expect(createLessonMock.newData).not.toBeCalled()
126+
})
127+
128+
it('Should catch error if it could not add a new lesson', async () => {
129+
expect.assertions(1)
130+
131+
jest.spyOn(Sentry, 'captureException')
132+
133+
render(
134+
<MockedProvider mocks={mocksWithError}>
135+
<AddNewLessonPage />
136+
</MockedProvider>
137+
)
138+
139+
await act(() => new Promise(res => setTimeout(res, 0)))
140+
141+
const title = screen.getByTestId('input0')
142+
await userEvent.type(title, createdLesson.title)
143+
144+
const description = screen.getByTestId('textbox')
145+
await userEvent.type(description, createdLesson.description)
146+
147+
const submitBtn = screen.getByText('Create Lesson')
148+
await userEvent.click(submitBtn)
149+
150+
// Waiting for the mutation to throw an error
151+
await act(() => new Promise(res => setTimeout(res, 0)))
152+
153+
expect(Sentry.captureException).toBeCalled()
154+
})
155+
156+
it('Should close success alert', async () => {
157+
expect.assertions(1)
158+
159+
render(
160+
<MockedProvider mocks={mocks}>
161+
<AddNewLessonPage />
162+
</MockedProvider>
163+
)
164+
165+
await act(() => new Promise(res => setTimeout(res, 0)))
166+
167+
const title = screen.getByTestId('input0')
168+
await userEvent.type(title, createdLesson.title)
169+
170+
const description = screen.getByTestId('textbox')
171+
await userEvent.type(description, createdLesson.description)
172+
173+
const submitBtn = screen.getByText('Create Lesson')
174+
await userEvent.click(submitBtn)
175+
176+
await userEvent.click(await screen.findByLabelText('Close alert'))
177+
178+
expect(screen.queryByRole('alert')).not.toBeInTheDocument()
179+
})
180+
181+
it('Should close error alert', async () => {
182+
expect.assertions(1)
183+
184+
render(
185+
<MockedProvider mocks={mocksWithError}>
186+
<AddNewLessonPage />
187+
</MockedProvider>
188+
)
189+
190+
await act(() => new Promise(res => setTimeout(res, 0)))
191+
192+
const title = screen.getByTestId('input0')
193+
await userEvent.type(title, createdLesson.title)
194+
195+
const description = screen.getByTestId('textbox')
196+
await userEvent.type(description, createdLesson.description)
197+
198+
const submitBtn = screen.getByText('Create Lesson')
199+
await userEvent.click(submitBtn)
200+
201+
await userEvent.click(await screen.findByLabelText('Close alert'))
202+
203+
expect(screen.queryByRole('alert')).not.toBeInTheDocument()
204+
})
205+
})

0 commit comments

Comments
 (0)