richie-education 2.25.0-b2.dev148 → 2.25.0-b2.dev152
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/js/contexts/JoanieApiContext/index.spec.tsx +1 -1
- package/js/contexts/SessionContext/JoanieSessionProvider.spec.tsx +44 -37
- package/js/contexts/SessionContext/index.spec.tsx +42 -21
- package/js/contexts/SessionContext/no-authentication.spec.tsx +3 -2
- package/js/hooks/useCourseSearchParams/index.spec.tsx +0 -1
- package/js/hooks/useUnionResource/index.spec.tsx +11 -9
- package/js/utils/test/render.tsx +5 -1
- package/js/utils/test/wrappers/BaseAppWrapper.tsx +5 -8
- package/js/utils/test/wrappers/BaseJoanieAppWrapper.tsx +4 -7
- package/js/utils/test/wrappers/IntlWrapper.tsx +4 -2
- package/js/utils/test/wrappers/PresentationalAppWrapper.tsx +1 -1
- package/js/utils/test/wrappers/ReactQueryAppWrapper.tsx +16 -0
- package/js/widgets/Dashboard/components/DashboardAvatar/index.spec.tsx +8 -5
- package/js/widgets/Dashboard/components/DashboardBox/index.spec.tsx +3 -1
- package/js/widgets/Dashboard/components/DashboardItem/Certificate/index.spec.tsx +19 -39
- package/js/widgets/Dashboard/components/DashboardItem/CertificateStatus/index.spec.tsx +14 -12
- package/js/widgets/Dashboard/components/DashboardItem/Contract/index.spec.tsx +5 -43
- package/js/widgets/Dashboard/components/DashboardItem/CourseEnrolling/index.spec.tsx +16 -15
- package/js/widgets/Dashboard/components/DashboardItem/Enrollment/DashboardItemEnrollment.spec.tsx +8 -18
- package/js/widgets/Dashboard/components/DashboardItem/Enrollment/ProductCertificateFooter/index.spec.tsx +19 -51
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrder.spec.tsx +40 -70
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderContract.spec.tsx +31 -32
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateLearnerMessage/index.spec.tsx +19 -31
- package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateTeacherMessage/index.spec.tsx +26 -37
- package/js/widgets/Dashboard/components/DashboardItem/index.spec.tsx +28 -23
- package/js/widgets/Dashboard/components/DashboardLayoutRoute/index.spec.tsx +53 -51
- package/js/widgets/Dashboard/components/DashboardSidebar/components/ContractNavLink/index.spec.tsx +24 -49
- package/js/widgets/Dashboard/components/DashboardSidebar/components/MenuNavLink/index.spec.tsx +5 -14
- package/js/widgets/Dashboard/components/ProtectedOutlet/AuthenticatedOutlet.spec.tsx +62 -54
- package/js/widgets/Dashboard/components/ProtectedOutlet/ProtectedOutlet.spec.tsx +67 -42
- package/js/widgets/Dashboard/components/RouterButton/index.spec.tsx +12 -14
- package/js/widgets/Dashboard/components/TeacherDashboardOrganizationSidebar/index.spec.tsx +14 -39
- package/js/widgets/Dashboard/hooks/useDashboardRouter/index.spec.tsx +2 -4
- package/js/widgets/Dashboard/hooks/useEnroll/index.spec.tsx +7 -28
- package/js/widgets/Dashboard/hooks/useRouteInfo/index.spec.tsx +25 -33
- package/js/widgets/Dashboard/index.spec.tsx +49 -43
- package/js/widgets/LanguageSelector/index.spec.tsx +7 -7
- package/js/widgets/LtiConsumer/index.spec.tsx +46 -48
- package/js/widgets/RootSearchSuggestField/index.spec.tsx +8 -6
- package/js/widgets/Search/components/PaginateCourseSearch/index.spec.tsx +10 -3
- package/js/widgets/Search/components/SearchFilterGroup/index.spec.tsx +5 -3
- package/js/widgets/Search/components/SearchFilterGroupModal/index.spec.tsx +8 -4
- package/js/widgets/Search/components/SearchFilterValueLeaf/index.spec.tsx +7 -3
- package/js/widgets/Search/components/SearchFilterValueParent/index.spec.tsx +12 -7
- package/js/widgets/Search/components/SearchFiltersPane/index.spec.tsx +5 -1
- package/js/widgets/Search/hooks/useCourseSearch/index.spec.tsx +4 -12
- package/js/widgets/Search/hooks/useFilterValue/index.spec.tsx +0 -2
- package/js/widgets/Search/index.spec.tsx +14 -6
- package/js/widgets/SearchSuggestField/index.spec.tsx +14 -1
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseProductCertificateItem/index.spec.tsx +16 -31
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseProductCourseRuns/index.spec.tsx +46 -72
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseRunItem/index.spec.tsx +5 -2
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.spec.tsx +147 -162
- package/js/widgets/SyllabusCourseRunsList/components/CourseRunEnrollment/CourseRunUnenrollmentButton/index.spec.tsx +6 -4
- package/js/widgets/SyllabusCourseRunsList/components/CourseRunEnrollment/index.joanie.spec.tsx +22 -99
- package/js/widgets/SyllabusCourseRunsList/components/CourseRunEnrollment/index.openedx.spec.tsx +27 -83
- package/js/widgets/SyllabusCourseRunsList/components/CourseRunItem/index.spec.tsx +4 -1
- package/js/widgets/SyllabusCourseRunsList/components/CourseRunItemWithEnrollment/index.spec.tsx +28 -35
- package/js/widgets/SyllabusCourseRunsList/components/CourseWishButton/hooks/useCourseWish/index.spec.tsx +9 -28
- package/js/widgets/SyllabusCourseRunsList/components/CourseWishButton/index.login.spec.tsx +23 -48
- package/js/widgets/SyllabusCourseRunsList/components/CourseWishButton/index.logout.spec.tsx +20 -29
- package/js/widgets/SyllabusCourseRunsList/components/SyllabusSimpleCourseRunsList/index.spec.tsx +9 -4
- package/js/widgets/SyllabusCourseRunsList/hooks/useCourseEnrollment/index.spec.tsx +8 -10
- package/js/widgets/SyllabusCourseRunsList/index.spec.tsx +28 -39
- package/js/widgets/UserLogin/components/UserMenu/index.spec.tsx +9 -6
- package/js/widgets/UserLogin/index.not.isJoanieEnabled.spec.tsx +21 -32
- package/js/widgets/UserLogin/index.spec.tsx +15 -37
- package/js/widgets/index.spec.tsx +12 -17
- package/package.json +1 -1
|
@@ -2,18 +2,15 @@
|
|
|
2
2
|
* Test suite for CourseAddToWishlist component
|
|
3
3
|
* for logged visitors
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { screen } from '@testing-library/react';
|
|
6
6
|
import fetchMock from 'fetch-mock';
|
|
7
|
-
import { IntlProvider } from 'react-intl';
|
|
8
|
-
import { QueryClientProvider } from '@tanstack/react-query';
|
|
9
7
|
import userEvent from '@testing-library/user-event';
|
|
10
8
|
import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie';
|
|
11
|
-
import { createTestQueryClient } from 'utils/test/createTestQueryClient';
|
|
12
|
-
import JoanieApiProvider from 'contexts/JoanieApiContext';
|
|
13
|
-
import { SessionProvider } from 'contexts/SessionContext';
|
|
14
9
|
import { HttpStatusCode } from 'utils/errors/HttpError';
|
|
15
|
-
import { CourseLight } from 'types/Joanie';
|
|
16
10
|
import { CourseLightFactory } from 'utils/test/factories/joanie';
|
|
11
|
+
import { setupJoanieSession } from 'utils/test/wrappers/JoanieAppWrapper';
|
|
12
|
+
import { render } from 'utils/test/render';
|
|
13
|
+
import { expectNoSpinner } from 'utils/test/expectSpinner';
|
|
17
14
|
import CourseWishButton from '.';
|
|
18
15
|
|
|
19
16
|
jest.mock('utils/context', () => ({
|
|
@@ -24,63 +21,44 @@ jest.mock('utils/context', () => ({
|
|
|
24
21
|
endpoint: 'https://authentication.test',
|
|
25
22
|
},
|
|
26
23
|
joanie_backend: {
|
|
27
|
-
endpoint: 'https://joanie.
|
|
24
|
+
endpoint: 'https://joanie.endpoint',
|
|
28
25
|
},
|
|
29
26
|
}).one(),
|
|
30
27
|
}));
|
|
31
28
|
|
|
32
|
-
const renderButton = (course: CourseLight) =>
|
|
33
|
-
render(
|
|
34
|
-
<IntlProvider locale="en">
|
|
35
|
-
<QueryClientProvider client={createTestQueryClient({ user: true })}>
|
|
36
|
-
<JoanieApiProvider>
|
|
37
|
-
<SessionProvider>
|
|
38
|
-
<CourseWishButton course={course} />
|
|
39
|
-
</SessionProvider>
|
|
40
|
-
</JoanieApiProvider>
|
|
41
|
-
</QueryClientProvider>
|
|
42
|
-
</IntlProvider>,
|
|
43
|
-
);
|
|
44
|
-
|
|
45
29
|
describe('CourseWishButton', () => {
|
|
30
|
+
const joanieSessionData = setupJoanieSession();
|
|
31
|
+
let nbApiCalls: number;
|
|
46
32
|
const course = CourseLightFactory().one();
|
|
47
33
|
|
|
48
34
|
beforeEach(() => {
|
|
49
|
-
|
|
50
|
-
fetchMock.get('https://joanie.test/api/v1.0/orders/', []);
|
|
51
|
-
fetchMock.get('https://joanie.test/api/v1.0/addresses/', []);
|
|
52
|
-
fetchMock.get('https://joanie.test/api/v1.0/credit-cards/', []);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
afterEach(() => {
|
|
56
|
-
jest.clearAllMocks();
|
|
57
|
-
fetchMock.restore();
|
|
35
|
+
nbApiCalls = joanieSessionData.nbSessionApiRequest;
|
|
58
36
|
});
|
|
59
37
|
|
|
60
38
|
it('renders a notify me button', async () => {
|
|
61
|
-
fetchMock.get(`https://joanie.
|
|
39
|
+
fetchMock.get(`https://joanie.endpoint/api/v1.0/courses/${course.code}/wish/`, {
|
|
62
40
|
status: HttpStatusCode.OK,
|
|
63
41
|
body: {
|
|
64
42
|
status: false,
|
|
65
43
|
},
|
|
66
44
|
});
|
|
67
|
-
|
|
45
|
+
render(<CourseWishButton course={course} />);
|
|
68
46
|
|
|
69
|
-
// wait for JoanieSession initialization
|
|
70
|
-
await waitFor(() => expect(screen.queryByText('loading...')).not.toBeInTheDocument());
|
|
71
47
|
// wait for CourseAddToWishlist initialization
|
|
72
|
-
await
|
|
48
|
+
await expectNoSpinner();
|
|
73
49
|
|
|
74
50
|
const $notifyButton = screen.getByRole('button', { name: 'Notify me' });
|
|
75
51
|
expect($notifyButton).toBeInTheDocument();
|
|
76
52
|
|
|
77
|
-
let nbApiCalls = 3; // JoanieSessionProvider initial requests
|
|
78
53
|
nbApiCalls += 1; // useUserWishlistCourses inital fetch
|
|
79
54
|
expect(fetchMock.calls().length).toBe(nbApiCalls);
|
|
80
55
|
|
|
81
|
-
fetchMock.post(
|
|
56
|
+
fetchMock.post(
|
|
57
|
+
`https://joanie.endpoint/api/v1.0/courses/${course.code}/wish/`,
|
|
58
|
+
HttpStatusCode.OK,
|
|
59
|
+
);
|
|
82
60
|
fetchMock.get(
|
|
83
|
-
`https://joanie.
|
|
61
|
+
`https://joanie.endpoint/api/v1.0/courses/${course.code}/wish/`,
|
|
84
62
|
{
|
|
85
63
|
status: HttpStatusCode.OK,
|
|
86
64
|
body: {
|
|
@@ -90,7 +68,7 @@ describe('CourseWishButton', () => {
|
|
|
90
68
|
{ overwriteRoutes: true },
|
|
91
69
|
);
|
|
92
70
|
|
|
93
|
-
await
|
|
71
|
+
await userEvent.click($notifyButton);
|
|
94
72
|
|
|
95
73
|
await screen.findByRole('button', { name: 'Do not notify me anymore' });
|
|
96
74
|
expect(screen.queryByRole('button', { name: 'Notify me' })).not.toBeInTheDocument();
|
|
@@ -101,25 +79,22 @@ describe('CourseWishButton', () => {
|
|
|
101
79
|
});
|
|
102
80
|
|
|
103
81
|
it('renders a "do not notify me" button', async () => {
|
|
104
|
-
fetchMock.get(`https://joanie.
|
|
82
|
+
fetchMock.get(`https://joanie.endpoint/api/v1.0/courses/${course.code}/wish/`, {
|
|
105
83
|
status: HttpStatusCode.OK,
|
|
106
84
|
body: {
|
|
107
85
|
status: true,
|
|
108
86
|
},
|
|
109
87
|
});
|
|
110
|
-
|
|
88
|
+
render(<CourseWishButton course={course} />);
|
|
111
89
|
|
|
112
|
-
// wait for JoanieSession initialization
|
|
113
|
-
await waitFor(() => expect(screen.queryByText('loading...')).not.toBeInTheDocument());
|
|
114
90
|
// wait for CourseAddToWishlist initialization
|
|
115
|
-
await
|
|
91
|
+
await expectNoSpinner();
|
|
116
92
|
|
|
117
93
|
const $stopNotifyButton = await screen.findByRole('button', {
|
|
118
94
|
name: 'Do not notify me anymore',
|
|
119
95
|
});
|
|
120
96
|
expect($stopNotifyButton).toBeInTheDocument();
|
|
121
97
|
|
|
122
|
-
let nbApiCalls = 3; // JoanieSessionProvider initial requests
|
|
123
98
|
nbApiCalls += 1; // useUserWishlistCourses inital fetch
|
|
124
99
|
expect(fetchMock.calls().length).toBe(nbApiCalls);
|
|
125
100
|
|
|
@@ -127,11 +102,11 @@ describe('CourseWishButton', () => {
|
|
|
127
102
|
// react-query will refetch data using the GET url.
|
|
128
103
|
|
|
129
104
|
fetchMock.delete(
|
|
130
|
-
`https://joanie.
|
|
105
|
+
`https://joanie.endpoint/api/v1.0/courses/${course.code}/wish/`,
|
|
131
106
|
HttpStatusCode.OK,
|
|
132
107
|
);
|
|
133
108
|
fetchMock.get(
|
|
134
|
-
`https://joanie.
|
|
109
|
+
`https://joanie.endpoint/api/v1.0/courses/${course.code}/wish/`,
|
|
135
110
|
{
|
|
136
111
|
status: HttpStatusCode.OK,
|
|
137
112
|
body: {
|
|
@@ -141,7 +116,7 @@ describe('CourseWishButton', () => {
|
|
|
141
116
|
{ overwriteRoutes: true },
|
|
142
117
|
);
|
|
143
118
|
|
|
144
|
-
await
|
|
119
|
+
await userEvent.click($stopNotifyButton);
|
|
145
120
|
|
|
146
121
|
expect(await screen.findByRole('button', { name: 'Notify me' })).toBeInTheDocument();
|
|
147
122
|
expect(
|
|
@@ -2,18 +2,17 @@
|
|
|
2
2
|
* Test suite for CourseAddToWishlist component
|
|
3
3
|
* for anonymous visitors
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import fetchMock from 'fetch-mock';
|
|
7
|
-
import { IntlProvider } from 'react-intl';
|
|
8
|
-
import { QueryClientProvider } from '@tanstack/react-query';
|
|
5
|
+
import { screen } from '@testing-library/react';
|
|
9
6
|
import userEvent from '@testing-library/user-event';
|
|
7
|
+
import fetchMock from 'fetch-mock';
|
|
10
8
|
import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie';
|
|
11
|
-
import { createTestQueryClient } from 'utils/test/createTestQueryClient';
|
|
12
|
-
import JoanieApiProvider from 'contexts/JoanieApiContext';
|
|
13
|
-
import { SessionProvider } from 'contexts/SessionContext';
|
|
14
9
|
import { location } from 'utils/indirection/window';
|
|
15
10
|
import { CourseLightFactory } from 'utils/test/factories/joanie';
|
|
16
|
-
import {
|
|
11
|
+
import { setupJoanieSession } from 'utils/test/wrappers/JoanieAppWrapper';
|
|
12
|
+
import { render } from 'utils/test/render';
|
|
13
|
+
import { HttpStatusCode } from 'utils/errors/HttpError';
|
|
14
|
+
import { expectNoSpinner } from 'utils/test/expectSpinner';
|
|
15
|
+
import { createTestQueryClient } from 'utils/test/createTestQueryClient';
|
|
17
16
|
import CourseWishButton from '.';
|
|
18
17
|
|
|
19
18
|
jest.mock('utils/indirection/window', () => ({
|
|
@@ -31,36 +30,28 @@ jest.mock('utils/context', () => ({
|
|
|
31
30
|
endpoint: 'https://authentication.test',
|
|
32
31
|
},
|
|
33
32
|
joanie_backend: {
|
|
34
|
-
endpoint: 'https://joanie.
|
|
33
|
+
endpoint: 'https://joanie.endpoint',
|
|
35
34
|
},
|
|
36
35
|
}).one(),
|
|
37
36
|
}));
|
|
38
37
|
|
|
39
|
-
const renderButton = (course: CourseLight) =>
|
|
40
|
-
render(
|
|
41
|
-
<IntlProvider locale="en">
|
|
42
|
-
<QueryClientProvider client={createTestQueryClient({ user: null })}>
|
|
43
|
-
<JoanieApiProvider>
|
|
44
|
-
<SessionProvider>
|
|
45
|
-
<CourseWishButton course={course} />
|
|
46
|
-
</SessionProvider>
|
|
47
|
-
</JoanieApiProvider>
|
|
48
|
-
</QueryClientProvider>
|
|
49
|
-
</IntlProvider>,
|
|
50
|
-
);
|
|
51
|
-
|
|
52
38
|
describe('CourseWishButton', () => {
|
|
39
|
+
setupJoanieSession();
|
|
53
40
|
const course = CourseLightFactory().one();
|
|
54
41
|
|
|
55
|
-
afterEach(() => {
|
|
56
|
-
jest.clearAllMocks();
|
|
57
|
-
fetchMock.restore();
|
|
58
|
-
});
|
|
59
|
-
|
|
60
42
|
it('renders a log me link', async () => {
|
|
61
|
-
|
|
43
|
+
fetchMock.get(`https://joanie.endpoint/api/v1.0/courses/${course.code}/wish/`, {
|
|
44
|
+
status: HttpStatusCode.OK,
|
|
45
|
+
body: {
|
|
46
|
+
status: false,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
render(<CourseWishButton course={course} />, {
|
|
51
|
+
queryOptions: { client: createTestQueryClient({ user: null }) },
|
|
52
|
+
});
|
|
62
53
|
// wait for JoanieSession initialization
|
|
63
|
-
await
|
|
54
|
+
await expectNoSpinner();
|
|
64
55
|
|
|
65
56
|
const $logMeButton = await screen.findByRole('button', { name: 'Log in to be notified' });
|
|
66
57
|
expect($logMeButton).toBeInTheDocument();
|
package/js/widgets/SyllabusCourseRunsList/components/SyllabusSimpleCourseRunsList/index.spec.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { screen } from '@testing-library/react';
|
|
2
2
|
import { CourseRunFactory } from 'utils/test/factories/richie';
|
|
3
|
+
import { render } from 'utils/test/render';
|
|
3
4
|
import { SyllabusSimpleCourseRunsList } from '.';
|
|
4
5
|
|
|
5
6
|
jest.mock('widgets/SyllabusCourseRunsList/components/CourseRunItem', () => ({
|
|
@@ -16,7 +17,9 @@ describe('SyllabusSimpleCourseRunsList', () => {
|
|
|
16
17
|
it('should render CourseRunItemWithEnrollment when checkEnrollment is true', () => {
|
|
17
18
|
const courseRun = CourseRunFactory().one();
|
|
18
19
|
|
|
19
|
-
render(<SyllabusSimpleCourseRunsList courseRuns={[courseRun]} checkEnrollment
|
|
20
|
+
render(<SyllabusSimpleCourseRunsList courseRuns={[courseRun]} checkEnrollment />, {
|
|
21
|
+
wrapper: null,
|
|
22
|
+
});
|
|
20
23
|
|
|
21
24
|
screen.getByText('CourseRunItemWithEnrollment');
|
|
22
25
|
});
|
|
@@ -24,7 +27,7 @@ describe('SyllabusSimpleCourseRunsList', () => {
|
|
|
24
27
|
it('should not render CourseRunItemWithEnrollment when checkEnrollment is false', () => {
|
|
25
28
|
const courseRun = CourseRunFactory().one();
|
|
26
29
|
|
|
27
|
-
render(<SyllabusSimpleCourseRunsList courseRuns={[courseRun]}
|
|
30
|
+
render(<SyllabusSimpleCourseRunsList courseRuns={[courseRun]} />, { wrapper: null });
|
|
28
31
|
|
|
29
32
|
screen.getByText('CourseRunItem');
|
|
30
33
|
});
|
|
@@ -34,7 +37,9 @@ describe('SyllabusSimpleCourseRunsList', () => {
|
|
|
34
37
|
snapshot: 'https://example.com/snaphosts/1/',
|
|
35
38
|
}).one();
|
|
36
39
|
|
|
37
|
-
render(<SyllabusSimpleCourseRunsList courseRuns={[courseRun]} checkEnrollment
|
|
40
|
+
render(<SyllabusSimpleCourseRunsList courseRuns={[courseRun]} checkEnrollment />, {
|
|
41
|
+
wrapper: null,
|
|
42
|
+
});
|
|
38
43
|
|
|
39
44
|
screen.getByText('CourseRunItem');
|
|
40
45
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { act, renderHook, waitFor } from '@testing-library/react';
|
|
2
|
-
import { QueryClient
|
|
2
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
3
3
|
import { faker } from '@faker-js/faker';
|
|
4
4
|
import fetchMock from 'fetch-mock';
|
|
5
5
|
import { PropsWithChildren } from 'react';
|
|
@@ -10,11 +10,11 @@ import {
|
|
|
10
10
|
UserFactory,
|
|
11
11
|
CourseRunFactory,
|
|
12
12
|
} from 'utils/test/factories/richie';
|
|
13
|
-
import BaseSessionProvider from 'contexts/SessionContext/BaseSessionProvider';
|
|
14
13
|
import { createTestQueryClient } from 'utils/test/createTestQueryClient';
|
|
15
14
|
import { User } from 'types/User';
|
|
16
15
|
import useCourseEnrollment from 'widgets/SyllabusCourseRunsList/hooks/useCourseEnrollment/index';
|
|
17
16
|
import { HttpStatusCode } from 'utils/errors/HttpError';
|
|
17
|
+
import { BaseAppWrapper } from 'utils/test/wrappers/BaseAppWrapper';
|
|
18
18
|
|
|
19
19
|
jest.mock('utils/context', () => ({
|
|
20
20
|
__esModule: true,
|
|
@@ -38,15 +38,9 @@ describe('useCourseEnrollment', () => {
|
|
|
38
38
|
const wrapper =
|
|
39
39
|
(client: QueryClient) =>
|
|
40
40
|
({ children }: PropsWithChildren) => (
|
|
41
|
-
<
|
|
42
|
-
<BaseSessionProvider>{children}</BaseSessionProvider>
|
|
43
|
-
</QueryClientProvider>
|
|
41
|
+
<BaseAppWrapper queryOptions={{ client }}>{children}</BaseAppWrapper>
|
|
44
42
|
);
|
|
45
43
|
|
|
46
|
-
beforeEach(() => {
|
|
47
|
-
fetchMock.restore();
|
|
48
|
-
});
|
|
49
|
-
|
|
50
44
|
it('does not make request when user is not authenticated', async () => {
|
|
51
45
|
const user: User = UserFactory().one();
|
|
52
46
|
const courseRun: CourseRun = CourseRunFactory().one();
|
|
@@ -60,9 +54,13 @@ describe('useCourseEnrollment', () => {
|
|
|
60
54
|
wrapper: wrapper(createTestQueryClient({ user: null })),
|
|
61
55
|
});
|
|
62
56
|
|
|
57
|
+
await waitFor(() => {
|
|
58
|
+
expect(result.current).not.toBeNull();
|
|
59
|
+
});
|
|
60
|
+
|
|
63
61
|
expect(fetchMock.called()).toBeFalsy();
|
|
64
62
|
expect(result.current.enrollment).toBeUndefined();
|
|
65
|
-
expect(result.current.enrollmentIsActive).
|
|
63
|
+
expect(result.current.enrollmentIsActive).toBe(false);
|
|
66
64
|
});
|
|
67
65
|
|
|
68
66
|
it('retrieves enrollment when user is authenticated', async () => {
|
|
@@ -4,14 +4,11 @@ import {
|
|
|
4
4
|
getByRole,
|
|
5
5
|
getByText,
|
|
6
6
|
queryByRole,
|
|
7
|
-
render,
|
|
8
7
|
screen,
|
|
9
8
|
within,
|
|
10
9
|
} from '@testing-library/react';
|
|
11
10
|
import ReactDOM from 'react-dom';
|
|
12
|
-
import { createIntl
|
|
13
|
-
import { QueryClientProvider } from '@tanstack/react-query';
|
|
14
|
-
import { PropsWithChildren } from 'react';
|
|
11
|
+
import { createIntl } from 'react-intl';
|
|
15
12
|
import fetchMock from 'fetch-mock';
|
|
16
13
|
import userEvent from '@testing-library/user-event';
|
|
17
14
|
import { faker } from '@faker-js/faker';
|
|
@@ -23,16 +20,14 @@ import {
|
|
|
23
20
|
import SyllabusCourseRunsList from 'widgets/SyllabusCourseRunsList/index';
|
|
24
21
|
import { createTestQueryClient } from 'utils/test/createTestQueryClient';
|
|
25
22
|
import { CourseRun, Priority } from 'types';
|
|
26
|
-
import JoanieApiProvider from 'contexts/JoanieApiContext';
|
|
27
23
|
import { CourseProductRelation } from 'types/Joanie';
|
|
28
24
|
import { CourseLightFactory, CourseProductRelationFactory } from 'utils/test/factories/joanie';
|
|
29
25
|
import { DEFAULT_DATE_FORMAT } from 'hooks/useDateFormat';
|
|
30
26
|
import { StringHelper } from 'utils/StringHelper';
|
|
31
27
|
import { computeStates } from 'utils/CourseRuns';
|
|
32
|
-
import { User } from 'types/User';
|
|
33
|
-
import { Nullable } from 'types/utils';
|
|
34
|
-
import BaseSessionProvider from 'contexts/SessionContext/BaseSessionProvider';
|
|
35
28
|
import { IntlHelper } from 'utils/IntlHelper';
|
|
29
|
+
import { render } from 'utils/test/render';
|
|
30
|
+
import { setupJoanieSession } from 'utils/test/wrappers/JoanieAppWrapper';
|
|
36
31
|
|
|
37
32
|
jest.mock('utils/context', () => {
|
|
38
33
|
const mock = mockRichieContextFactory().one();
|
|
@@ -40,7 +35,7 @@ jest.mock('utils/context', () => {
|
|
|
40
35
|
{
|
|
41
36
|
backend: 'joanie',
|
|
42
37
|
course_regexp: '^.*/api/v1.0((?:/(?:courses|course-runs|products)/[^/]+)+)/?$',
|
|
43
|
-
endpoint: 'https://joanie.
|
|
38
|
+
endpoint: 'https://joanie.endpoint',
|
|
44
39
|
},
|
|
45
40
|
{
|
|
46
41
|
backend: 'openedx-hawthorn',
|
|
@@ -49,7 +44,7 @@ jest.mock('utils/context', () => {
|
|
|
49
44
|
},
|
|
50
45
|
];
|
|
51
46
|
mock.authentication = { backend: 'fonzie', endpoint: 'https://auth.test' };
|
|
52
|
-
mock.joanie_backend = { endpoint: 'https://joanie.
|
|
47
|
+
mock.joanie_backend = { endpoint: 'https://joanie.endpoint' };
|
|
53
48
|
return {
|
|
54
49
|
__esModule: true,
|
|
55
50
|
default: mock,
|
|
@@ -59,6 +54,9 @@ jest.mock('utils/context', () => {
|
|
|
59
54
|
const MAX_ARCHIVED_COURSE_RUNS = 5;
|
|
60
55
|
|
|
61
56
|
describe('<SyllabusCourseRunsList/>', () => {
|
|
57
|
+
let nbApiCalls: number;
|
|
58
|
+
const joanieSessionData = setupJoanieSession();
|
|
59
|
+
|
|
62
60
|
beforeAll(() => {
|
|
63
61
|
// @ts-ignore
|
|
64
62
|
ReactDOM.createPortal = jest.fn((element) => {
|
|
@@ -66,24 +64,15 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
66
64
|
});
|
|
67
65
|
});
|
|
68
66
|
|
|
67
|
+
beforeEach(() => {
|
|
68
|
+
nbApiCalls = joanieSessionData.nbSessionApiRequest;
|
|
69
|
+
});
|
|
70
|
+
|
|
69
71
|
afterEach(() => {
|
|
70
72
|
// @ts-ignore
|
|
71
73
|
ReactDOM.createPortal.mockClear();
|
|
72
|
-
fetchMock.restore();
|
|
73
74
|
});
|
|
74
75
|
|
|
75
|
-
const Wrapper = ({ children, user = null }: PropsWithChildren<{ user?: Nullable<User> }>) => {
|
|
76
|
-
return (
|
|
77
|
-
<QueryClientProvider client={createTestQueryClient({ user })}>
|
|
78
|
-
<IntlProvider locale="en">
|
|
79
|
-
<JoanieApiProvider>
|
|
80
|
-
<BaseSessionProvider>{children}</BaseSessionProvider>
|
|
81
|
-
</JoanieApiProvider>
|
|
82
|
-
</IntlProvider>
|
|
83
|
-
</QueryClientProvider>
|
|
84
|
-
);
|
|
85
|
-
};
|
|
86
|
-
|
|
87
76
|
const getHeaderContainer = (): HTMLElement => {
|
|
88
77
|
return document.querySelector('.course-detail__row')!;
|
|
89
78
|
};
|
|
@@ -176,7 +165,7 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
176
165
|
maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
|
|
177
166
|
/>,
|
|
178
167
|
{
|
|
179
|
-
|
|
168
|
+
queryOptions: { client: createTestQueryClient({ user: null }) },
|
|
180
169
|
},
|
|
181
170
|
);
|
|
182
171
|
|
|
@@ -213,7 +202,7 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
213
202
|
maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
|
|
214
203
|
/>,
|
|
215
204
|
{
|
|
216
|
-
|
|
205
|
+
queryOptions: { client: createTestQueryClient({ user: null }) },
|
|
217
206
|
},
|
|
218
207
|
);
|
|
219
208
|
|
|
@@ -250,7 +239,7 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
250
239
|
maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
|
|
251
240
|
/>,
|
|
252
241
|
{
|
|
253
|
-
|
|
242
|
+
queryOptions: { client: createTestQueryClient({ user: null }) },
|
|
254
243
|
},
|
|
255
244
|
);
|
|
256
245
|
|
|
@@ -295,7 +284,7 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
295
284
|
maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
|
|
296
285
|
/>,
|
|
297
286
|
{
|
|
298
|
-
|
|
287
|
+
queryOptions: { client: createTestQueryClient({ user: null }) },
|
|
299
288
|
},
|
|
300
289
|
);
|
|
301
290
|
|
|
@@ -315,7 +304,7 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
315
304
|
it('has one opened product', async () => {
|
|
316
305
|
const course = CourseLightFactory().one();
|
|
317
306
|
const relation = CourseProductRelationFactory().one();
|
|
318
|
-
const resourceLink = `https://joanie.
|
|
307
|
+
const resourceLink = `https://joanie.endpoint/api/v1.0/courses/${course.code}/products/${relation.product.id}/`;
|
|
319
308
|
fetchMock.get(resourceLink, relation);
|
|
320
309
|
|
|
321
310
|
const courseRun = CourseRunFactoryFromPriority(Priority.ONGOING_OPEN)({
|
|
@@ -329,7 +318,7 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
329
318
|
maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
|
|
330
319
|
/>,
|
|
331
320
|
{
|
|
332
|
-
|
|
321
|
+
queryOptions: { client: createTestQueryClient({ user: null }) },
|
|
333
322
|
},
|
|
334
323
|
);
|
|
335
324
|
|
|
@@ -353,7 +342,7 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
353
342
|
maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
|
|
354
343
|
/>,
|
|
355
344
|
{
|
|
356
|
-
|
|
345
|
+
queryOptions: { client: createTestQueryClient({ user: null }) },
|
|
357
346
|
},
|
|
358
347
|
);
|
|
359
348
|
getByRole(getPortalContainer(), 'heading', {
|
|
@@ -378,7 +367,7 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
378
367
|
maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
|
|
379
368
|
/>,
|
|
380
369
|
{
|
|
381
|
-
|
|
370
|
+
queryOptions: { client: createTestQueryClient({ user: null }) },
|
|
382
371
|
},
|
|
383
372
|
);
|
|
384
373
|
getByRole(getPortalContainer(), 'heading', {
|
|
@@ -415,7 +404,7 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
415
404
|
maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
|
|
416
405
|
/>,
|
|
417
406
|
{
|
|
418
|
-
|
|
407
|
+
queryOptions: { client: createTestQueryClient({ user: null }) },
|
|
419
408
|
},
|
|
420
409
|
);
|
|
421
410
|
|
|
@@ -467,7 +456,7 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
467
456
|
maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
|
|
468
457
|
/>,
|
|
469
458
|
{
|
|
470
|
-
|
|
459
|
+
queryOptions: { client: createTestQueryClient({ user: null }) },
|
|
471
460
|
},
|
|
472
461
|
);
|
|
473
462
|
|
|
@@ -494,7 +483,7 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
494
483
|
maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
|
|
495
484
|
/>,
|
|
496
485
|
{
|
|
497
|
-
|
|
486
|
+
queryOptions: { client: createTestQueryClient({ user: null }) },
|
|
498
487
|
},
|
|
499
488
|
);
|
|
500
489
|
|
|
@@ -540,7 +529,7 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
540
529
|
maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
|
|
541
530
|
/>,
|
|
542
531
|
{
|
|
543
|
-
|
|
532
|
+
queryOptions: { client: createTestQueryClient({ user: null }) },
|
|
544
533
|
},
|
|
545
534
|
);
|
|
546
535
|
|
|
@@ -600,7 +589,7 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
600
589
|
maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
|
|
601
590
|
/>,
|
|
602
591
|
{
|
|
603
|
-
|
|
592
|
+
queryOptions: { client: createTestQueryClient({ user: null }) },
|
|
604
593
|
},
|
|
605
594
|
);
|
|
606
595
|
|
|
@@ -651,7 +640,7 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
651
640
|
maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
|
|
652
641
|
/>,
|
|
653
642
|
{
|
|
654
|
-
|
|
643
|
+
queryOptions: { client: createTestQueryClient({ user: null }) },
|
|
655
644
|
},
|
|
656
645
|
);
|
|
657
646
|
|
|
@@ -711,7 +700,7 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
711
700
|
maxArchivedCourseRuns={MAX_ARCHIVED_COURSE_RUNS}
|
|
712
701
|
/>,
|
|
713
702
|
{
|
|
714
|
-
|
|
703
|
+
queryOptions: { client: createTestQueryClient({ user }) },
|
|
715
704
|
},
|
|
716
705
|
);
|
|
717
706
|
|
|
@@ -730,7 +719,7 @@ describe('<SyllabusCourseRunsList/>', () => {
|
|
|
730
719
|
const links = screen.getAllByRole('link');
|
|
731
720
|
expect(links.length).toBe(1);
|
|
732
721
|
const calledUrls = fetchMock.calls().map((call) => call[0]);
|
|
733
|
-
expect(calledUrls).toHaveLength(1);
|
|
722
|
+
expect(calledUrls).toHaveLength(nbApiCalls + 1);
|
|
734
723
|
|
|
735
724
|
// Assert user's enrollment state has been checked for the ongoing course run.
|
|
736
725
|
const link = within(portalContainer).getByRole('link');
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { screen } from '@testing-library/react';
|
|
2
2
|
import userEvent from '@testing-library/user-event';
|
|
3
|
-
import {
|
|
3
|
+
import { IntlWrapper } from 'utils/test/wrappers/IntlWrapper';
|
|
4
|
+
import { render } from 'utils/test/render';
|
|
4
5
|
import { UserMenu } from '.';
|
|
5
6
|
|
|
6
7
|
/* Enforce to use DesktopUserMenu by default */
|
|
@@ -44,9 +45,10 @@ describe('<UserMenu />', () => {
|
|
|
44
45
|
|
|
45
46
|
it('renders a dropdown with links matching the data passed to the "link" prop', async () => {
|
|
46
47
|
render(
|
|
47
|
-
<
|
|
48
|
+
<IntlWrapper>
|
|
48
49
|
<UserMenu {...props} />
|
|
49
|
-
</
|
|
50
|
+
</IntlWrapper>,
|
|
51
|
+
{ wrapper: null },
|
|
50
52
|
);
|
|
51
53
|
|
|
52
54
|
const button = screen.getByLabelText('Access to your profile settings', {
|
|
@@ -69,9 +71,10 @@ describe('<UserMenu />', () => {
|
|
|
69
71
|
mockMatches = false;
|
|
70
72
|
|
|
71
73
|
render(
|
|
72
|
-
<
|
|
74
|
+
<IntlWrapper>
|
|
73
75
|
<UserMenu {...props} />
|
|
74
|
-
</
|
|
76
|
+
</IntlWrapper>,
|
|
77
|
+
{ wrapper: null },
|
|
75
78
|
);
|
|
76
79
|
|
|
77
80
|
screen.getByRole('heading', { name: 'John Doe' });
|