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
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { act, fireEvent,
|
|
1
|
+
import { RouteObject } from 'react-router-dom';
|
|
2
|
+
import { act, fireEvent, screen } from '@testing-library/react';
|
|
3
3
|
import { location } from 'utils/indirection/window';
|
|
4
|
+
import { render } from 'utils/test/render';
|
|
5
|
+
import { RouterWrapper } from 'utils/test/wrappers/RouterWrapper';
|
|
4
6
|
import { RouterButton } from '.';
|
|
5
7
|
|
|
6
8
|
jest.mock('utils/indirection/window', () => ({
|
|
@@ -27,7 +29,7 @@ describe('<RouterButton/>', () => {
|
|
|
27
29
|
},
|
|
28
30
|
];
|
|
29
31
|
|
|
30
|
-
render(<
|
|
32
|
+
render(<RouterWrapper routes={routes} />, { wrapper: null });
|
|
31
33
|
screen.getByText('Root');
|
|
32
34
|
|
|
33
35
|
const button = screen.getByRole('link', { name: 'Go to other' });
|
|
@@ -39,19 +41,15 @@ describe('<RouterButton/>', () => {
|
|
|
39
41
|
screen.getByText('Other');
|
|
40
42
|
});
|
|
41
43
|
it('natively navigates', async () => {
|
|
42
|
-
|
|
44
|
+
render(
|
|
45
|
+
<div>
|
|
46
|
+
Root
|
|
47
|
+
<RouterButton href="https://fun-mooc.fr">Go to other</RouterButton>
|
|
48
|
+
</div>,
|
|
43
49
|
{
|
|
44
|
-
|
|
45
|
-
element: (
|
|
46
|
-
<div>
|
|
47
|
-
Root
|
|
48
|
-
<RouterButton href="https://fun-mooc.fr">Go to other</RouterButton>
|
|
49
|
-
</div>
|
|
50
|
-
),
|
|
50
|
+
wrapper: RouterWrapper,
|
|
51
51
|
},
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
render(<RouterProvider router={createMemoryRouter(routes)} />);
|
|
52
|
+
);
|
|
55
53
|
screen.getByText('Root');
|
|
56
54
|
|
|
57
55
|
const button = screen.getByRole('link', { name: 'Go to other' });
|
|
@@ -1,20 +1,13 @@
|
|
|
1
1
|
import { faker } from '@faker-js/faker';
|
|
2
|
-
import {
|
|
3
|
-
import { QueryClientProvider } from '@tanstack/react-query';
|
|
4
|
-
import { render, screen, waitFor } from '@testing-library/react';
|
|
2
|
+
import { screen, waitFor } from '@testing-library/react';
|
|
5
3
|
import fetchMock from 'fetch-mock';
|
|
6
|
-
import { IntlProvider } from 'react-intl';
|
|
7
|
-
import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
|
8
4
|
import { StringHelper } from 'utils/StringHelper';
|
|
9
5
|
import { expectNoSpinner } from 'utils/test/expectSpinner';
|
|
10
|
-
import {
|
|
11
|
-
RichieContextFactory as mockRichieContextFactory,
|
|
12
|
-
UserFactory,
|
|
13
|
-
} from 'utils/test/factories/richie';
|
|
14
|
-
import JoanieSessionProvider from 'contexts/SessionContext/JoanieSessionProvider';
|
|
15
|
-
import { createTestQueryClient } from 'utils/test/createTestQueryClient';
|
|
6
|
+
import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie';
|
|
16
7
|
import { ContractFactory, OrganizationFactory } from 'utils/test/factories/joanie';
|
|
17
8
|
import { PER_PAGE } from 'settings';
|
|
9
|
+
import { setupJoanieSession } from 'utils/test/wrappers/JoanieAppWrapper';
|
|
10
|
+
import { render } from 'utils/test/render';
|
|
18
11
|
import { TeacherDashboardOrganizationSidebar } from '.';
|
|
19
12
|
|
|
20
13
|
jest.mock('utils/context', () => ({
|
|
@@ -26,31 +19,7 @@ jest.mock('utils/context', () => ({
|
|
|
26
19
|
}));
|
|
27
20
|
|
|
28
21
|
describe('<TeacherDashboardOrganizationSidebar />', () => {
|
|
29
|
-
|
|
30
|
-
fetchMock.get('https://joanie.endpoint/api/v1.0/orders/', []);
|
|
31
|
-
fetchMock.get('https://joanie.endpoint/api/v1.0/addresses/', []);
|
|
32
|
-
fetchMock.get('https://joanie.endpoint/api/v1.0/credit-cards/', []);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
afterEach(() => {
|
|
36
|
-
fetchMock.restore();
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
const Wrapper = ({ organizationId }: { organizationId: string }) => (
|
|
40
|
-
<IntlProvider locale="en">
|
|
41
|
-
<QueryClientProvider client={createTestQueryClient({ user: UserFactory().one() })}>
|
|
42
|
-
<JoanieSessionProvider>
|
|
43
|
-
<CunninghamProvider>
|
|
44
|
-
<MemoryRouter initialEntries={['/' + organizationId]}>
|
|
45
|
-
<Routes>
|
|
46
|
-
<Route path="/:organizationId" element={<TeacherDashboardOrganizationSidebar />} />
|
|
47
|
-
</Routes>
|
|
48
|
-
</MemoryRouter>
|
|
49
|
-
</CunninghamProvider>
|
|
50
|
-
</JoanieSessionProvider>
|
|
51
|
-
</QueryClientProvider>
|
|
52
|
-
</IntlProvider>
|
|
53
|
-
);
|
|
22
|
+
setupJoanieSession();
|
|
54
23
|
|
|
55
24
|
it('should render', async () => {
|
|
56
25
|
const organization = OrganizationFactory({ logo: null }).one();
|
|
@@ -66,7 +35,9 @@ describe('<TeacherDashboardOrganizationSidebar />', () => {
|
|
|
66
35
|
{ results: [], count: 0, previous: null, next: null },
|
|
67
36
|
);
|
|
68
37
|
|
|
69
|
-
render(<
|
|
38
|
+
render(<TeacherDashboardOrganizationSidebar />, {
|
|
39
|
+
routerOptions: { path: '/:organizationId', initialEntries: [`/${organization.id}`] },
|
|
40
|
+
});
|
|
70
41
|
|
|
71
42
|
await expectNoSpinner('Loading organization...');
|
|
72
43
|
|
|
@@ -106,7 +77,9 @@ describe('<TeacherDashboardOrganizationSidebar />', () => {
|
|
|
106
77
|
},
|
|
107
78
|
);
|
|
108
79
|
|
|
109
|
-
render(<
|
|
80
|
+
render(<TeacherDashboardOrganizationSidebar />, {
|
|
81
|
+
routerOptions: { path: '/:organizationId', initialEntries: [`/${organization.id}`] },
|
|
82
|
+
});
|
|
110
83
|
await expectNoSpinner('Loading organization...');
|
|
111
84
|
|
|
112
85
|
// It should display contract link with badge next to it displaying the number of contracts to sign
|
|
@@ -140,7 +113,9 @@ describe('<TeacherDashboardOrganizationSidebar />', () => {
|
|
|
140
113
|
},
|
|
141
114
|
);
|
|
142
115
|
|
|
143
|
-
render(<
|
|
116
|
+
render(<TeacherDashboardOrganizationSidebar />, {
|
|
117
|
+
routerOptions: { path: '/:organizationId', initialEntries: [`/${organization.id}`] },
|
|
118
|
+
});
|
|
144
119
|
await expectNoSpinner('Loading organization...');
|
|
145
120
|
|
|
146
121
|
// It should display contract link with no badge next to it
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { PropsWithChildren } from 'react';
|
|
2
|
-
import { IntlProvider } from 'react-intl';
|
|
3
2
|
import { renderHook } from '@testing-library/react';
|
|
3
|
+
import { IntlWrapper } from 'utils/test/wrappers/IntlWrapper';
|
|
4
4
|
import useDashboardRoutes from '.';
|
|
5
5
|
|
|
6
6
|
describe('useDashboardRouter', () => {
|
|
7
|
-
const Wrapper = ({ children }: PropsWithChildren<{}>) =>
|
|
8
|
-
<IntlProvider locale="en">{children}</IntlProvider>
|
|
9
|
-
);
|
|
7
|
+
const Wrapper = ({ children }: PropsWithChildren<{}>) => <IntlWrapper>{children}</IntlWrapper>;
|
|
10
8
|
|
|
11
9
|
it('should render path according to the active language', () => {
|
|
12
10
|
const { result } = renderHook(useDashboardRoutes, { wrapper: Wrapper });
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { PropsWithChildren } from 'react';
|
|
2
|
-
import { QueryClientProvider } from '@tanstack/react-query';
|
|
3
|
-
import { IntlProvider } from 'react-intl';
|
|
4
1
|
import { act, renderHook, waitFor } from '@testing-library/react';
|
|
5
2
|
import fetchMock from 'fetch-mock';
|
|
6
3
|
import { Priority } from 'types';
|
|
7
4
|
import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie';
|
|
8
5
|
import { CourseRunFactory } from 'utils/test/factories/joanie';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
6
|
+
import { setupJoanieSession } from 'utils/test/wrappers/JoanieAppWrapper';
|
|
7
|
+
import { BaseJoanieAppWrapper } from 'utils/test/wrappers/BaseJoanieAppWrapper';
|
|
11
8
|
import { useEnroll } from './index';
|
|
12
9
|
|
|
13
10
|
jest.mock('utils/indirection/window', () => ({
|
|
@@ -27,32 +24,14 @@ jest.mock('utils/context', () => ({
|
|
|
27
24
|
* conditions in DashboardItemOrder.spec.tsx.
|
|
28
25
|
*/
|
|
29
26
|
describe('useEnroll ( edge case )', () => {
|
|
30
|
-
|
|
31
|
-
return (
|
|
32
|
-
<QueryClientProvider client={createTestQueryClient({ user: true })}>
|
|
33
|
-
<IntlProvider locale="en">
|
|
34
|
-
<SessionProvider>{children}</SessionProvider>
|
|
35
|
-
</IntlProvider>
|
|
36
|
-
</QueryClientProvider>
|
|
37
|
-
);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
beforeEach(() => {
|
|
41
|
-
// SessionProvider inital requests
|
|
42
|
-
fetchMock.get('https://joanie.endpoint/api/v1.0/orders/', []);
|
|
43
|
-
fetchMock.get('https://joanie.endpoint/api/v1.0/addresses/', []);
|
|
44
|
-
fetchMock.get('https://joanie.endpoint/api/v1.0/credit-cards/', []);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
afterEach(() => {
|
|
48
|
-
jest.clearAllMocks();
|
|
49
|
-
fetchMock.restore();
|
|
50
|
-
});
|
|
27
|
+
setupJoanieSession();
|
|
51
28
|
|
|
52
29
|
it('should return early when a course run is not enrollable', async () => {
|
|
53
30
|
fetchMock.get('https://joanie.endpoint/api/v1.0/enrollments/', []);
|
|
54
31
|
fetchMock.post('https://joanie.endpoint/api/v1.0/enrollments/', {});
|
|
55
|
-
const { result } = renderHook(() => useEnroll([], undefined), {
|
|
32
|
+
const { result } = renderHook(() => useEnroll([], undefined), {
|
|
33
|
+
wrapper: BaseJoanieAppWrapper,
|
|
34
|
+
});
|
|
56
35
|
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
57
36
|
|
|
58
37
|
const courseRun = CourseRunFactory().one();
|
|
@@ -68,7 +47,7 @@ describe('useEnroll ( edge case )', () => {
|
|
|
68
47
|
fetchMock.get('https://joanie.endpoint/api/v1.0/enrollments/', []);
|
|
69
48
|
fetchMock.post('https://joanie.endpoint/api/v1.0/enrollments/', {});
|
|
70
49
|
const { result } = renderHook(() => useEnroll([], undefined), {
|
|
71
|
-
wrapper,
|
|
50
|
+
wrapper: BaseJoanieAppWrapper,
|
|
72
51
|
});
|
|
73
52
|
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
74
53
|
|
|
@@ -1,42 +1,35 @@
|
|
|
1
1
|
import { PropsWithChildren, useMemo } from 'react';
|
|
2
|
-
import { createMemoryRouter, RouterProvider } from 'react-router-dom';
|
|
3
2
|
import { renderHook, waitFor } from '@testing-library/react';
|
|
3
|
+
import { RouterWrapper } from 'utils/test/wrappers/RouterWrapper';
|
|
4
4
|
import useRouteInfo from '.';
|
|
5
5
|
|
|
6
6
|
describe('useRouteInfo', () => {
|
|
7
|
-
let routerOptions = {
|
|
8
|
-
initialEntries: ['/posts'],
|
|
9
|
-
};
|
|
10
|
-
const Router = ({ children }: PropsWithChildren) => {
|
|
11
|
-
const router = useMemo(
|
|
12
|
-
() =>
|
|
13
|
-
createMemoryRouter(
|
|
14
|
-
[
|
|
15
|
-
{
|
|
16
|
-
path: '/posts',
|
|
17
|
-
element: <div data-testid="posts">{children}</div>,
|
|
18
|
-
loader: () => ({ posts: [] }),
|
|
19
|
-
children: [
|
|
20
|
-
{
|
|
21
|
-
path: ':postId',
|
|
22
|
-
element: <div data-testid="route-post">{children}</div>,
|
|
23
|
-
handle: { title: 'A post' },
|
|
24
|
-
},
|
|
25
|
-
],
|
|
26
|
-
},
|
|
27
|
-
],
|
|
28
|
-
routerOptions,
|
|
29
|
-
),
|
|
30
|
-
[children, routerOptions],
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
return <RouterProvider router={router} />;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
7
|
it('should return all information about the active route', async () => {
|
|
8
|
+
let currentUrl = '/posts';
|
|
37
9
|
// First render to match the '/posts' route
|
|
38
10
|
const { result, rerender } = renderHook(useRouteInfo, {
|
|
39
|
-
wrapper:
|
|
11
|
+
wrapper: ({ children }: PropsWithChildren) => {
|
|
12
|
+
const initialEntries = useMemo(() => [currentUrl], [currentUrl]);
|
|
13
|
+
return (
|
|
14
|
+
<RouterWrapper
|
|
15
|
+
initialEntries={initialEntries}
|
|
16
|
+
routes={[
|
|
17
|
+
{
|
|
18
|
+
path: '/posts',
|
|
19
|
+
element: <div data-testid="posts">{children}</div>,
|
|
20
|
+
loader: () => ({ posts: [] }),
|
|
21
|
+
children: [
|
|
22
|
+
{
|
|
23
|
+
path: ':postId',
|
|
24
|
+
element: <div data-testid="route-post">{children}</div>,
|
|
25
|
+
handle: { title: 'A post' },
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
]}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
},
|
|
40
33
|
});
|
|
41
34
|
|
|
42
35
|
await waitFor(() =>
|
|
@@ -49,8 +42,7 @@ describe('useRouteInfo', () => {
|
|
|
49
42
|
}),
|
|
50
43
|
);
|
|
51
44
|
|
|
52
|
-
|
|
53
|
-
routerOptions = { initialEntries: ['/posts/a-first-post'] };
|
|
45
|
+
currentUrl = '/posts/a-first-post';
|
|
54
46
|
rerender();
|
|
55
47
|
|
|
56
48
|
await waitFor(() =>
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { fireEvent, getByText,
|
|
2
|
-
import { IntlProvider } from 'react-intl';
|
|
3
|
-
import { QueryClientProvider } from '@tanstack/react-query';
|
|
1
|
+
import { fireEvent, getByText, screen, act } from '@testing-library/react';
|
|
4
2
|
import fetchMock from 'fetch-mock';
|
|
5
3
|
import {
|
|
6
4
|
RichieContextFactory as mockRichieContextFactory,
|
|
@@ -9,12 +7,14 @@ import {
|
|
|
9
7
|
import { AddressFactory } from 'utils/test/factories/joanie';
|
|
10
8
|
import { location } from 'utils/indirection/window';
|
|
11
9
|
import { User } from 'types/User';
|
|
12
|
-
import { Nullable } from 'types/utils';
|
|
13
10
|
import { expectBreadcrumbsToEqualParts } from 'utils/test/expectBreadcrumbsToEqualParts';
|
|
14
11
|
import { Address } from 'types/Joanie';
|
|
15
|
-
import JoanieSessionProvider from 'contexts/SessionContext/JoanieSessionProvider';
|
|
16
12
|
import { expectUrlMatchLocationDisplayed } from 'utils/test/expectUrlMatchLocationDisplayed';
|
|
13
|
+
import { setupJoanieSession } from 'utils/test/wrappers/JoanieAppWrapper';
|
|
14
|
+
import { render } from 'utils/test/render';
|
|
17
15
|
import { createTestQueryClient } from 'utils/test/createTestQueryClient';
|
|
16
|
+
import { BaseJoanieAppWrapper } from 'utils/test/wrappers/BaseJoanieAppWrapper';
|
|
17
|
+
import { expectNoSpinner } from 'utils/test/expectSpinner';
|
|
18
18
|
import { LearnerDashboardPaths } from './utils/learnerRouteMessages';
|
|
19
19
|
import { DashboardTest } from './components/DashboardTest';
|
|
20
20
|
|
|
@@ -40,29 +40,15 @@ jest.mock('hooks/useIntersectionObserver', () => ({
|
|
|
40
40
|
}));
|
|
41
41
|
|
|
42
42
|
describe('<Dashboard />', () => {
|
|
43
|
-
|
|
44
|
-
return (
|
|
45
|
-
<IntlProvider locale="en">
|
|
46
|
-
<QueryClientProvider client={createTestQueryClient({ user })}>
|
|
47
|
-
<JoanieSessionProvider>
|
|
48
|
-
<DashboardTest initialRoute={LearnerDashboardPaths.COURSES} />
|
|
49
|
-
</JoanieSessionProvider>
|
|
50
|
-
</QueryClientProvider>
|
|
51
|
-
</IntlProvider>
|
|
52
|
-
);
|
|
53
|
-
};
|
|
43
|
+
setupJoanieSession();
|
|
54
44
|
|
|
55
45
|
beforeEach(() => {
|
|
56
|
-
jest.resetAllMocks();
|
|
57
|
-
fetchMock.get('https://joanie.endpoint/api/v1.0/orders/', []);
|
|
58
|
-
fetchMock.get('https://joanie.endpoint/api/v1.0/credit-cards/', []);
|
|
59
|
-
fetchMock.get('https://joanie.endpoint/api/v1.0/addresses/', []);
|
|
60
46
|
fetchMock.get(
|
|
61
|
-
'https://joanie.endpoint/api/v1.0/enrollments/?page=1&page_size=50
|
|
47
|
+
'https://joanie.endpoint/api/v1.0/enrollments/?was_created_by_order=false&page=1&page_size=50',
|
|
62
48
|
{ count: 0, results: [] },
|
|
63
49
|
);
|
|
64
50
|
fetchMock.get(
|
|
65
|
-
'https://joanie.endpoint/api/v1.0/orders/?page=1&page_size=50
|
|
51
|
+
'https://joanie.endpoint/api/v1.0/orders/?product_type=credential&state_exclude=canceled&page=1&page_size=50',
|
|
66
52
|
{
|
|
67
53
|
count: 0,
|
|
68
54
|
results: [],
|
|
@@ -70,38 +56,42 @@ describe('<Dashboard />', () => {
|
|
|
70
56
|
);
|
|
71
57
|
});
|
|
72
58
|
|
|
73
|
-
afterEach(() => {
|
|
74
|
-
fetchMock.restore();
|
|
75
|
-
});
|
|
76
|
-
|
|
77
59
|
it('should redirect to the site root if user is not authenticated', async () => {
|
|
78
|
-
|
|
79
|
-
|
|
60
|
+
render(<DashboardTest initialRoute={LearnerDashboardPaths.COURSES} />, {
|
|
61
|
+
wrapper: BaseJoanieAppWrapper,
|
|
62
|
+
queryOptions: {
|
|
63
|
+
client: createTestQueryClient({ user: null }),
|
|
64
|
+
},
|
|
80
65
|
});
|
|
81
66
|
|
|
82
67
|
expect(location.replace).toHaveBeenNthCalledWith(1, '/');
|
|
83
68
|
});
|
|
84
69
|
|
|
85
|
-
it('should redirect from dashboard index route to courses route', () => {
|
|
86
|
-
|
|
70
|
+
it('should redirect from dashboard index route to courses route', async () => {
|
|
71
|
+
render(<DashboardTest initialRoute={LearnerDashboardPaths.COURSES} />, {
|
|
72
|
+
wrapper: BaseJoanieAppWrapper,
|
|
73
|
+
});
|
|
87
74
|
|
|
88
|
-
|
|
75
|
+
await expectNoSpinner('Loading orders and enrollments...');
|
|
89
76
|
|
|
90
77
|
expect(location.replace).not.toBeCalled();
|
|
91
78
|
expectUrlMatchLocationDisplayed(LearnerDashboardPaths.COURSES);
|
|
92
79
|
});
|
|
93
80
|
|
|
94
|
-
it('should render breadcrumbs', () => {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
81
|
+
it('should render breadcrumbs', async () => {
|
|
82
|
+
render(<DashboardTest initialRoute={LearnerDashboardPaths.COURSES} />, {
|
|
83
|
+
wrapper: BaseJoanieAppWrapper,
|
|
84
|
+
});
|
|
85
|
+
await expectNoSpinner('Loading orders and enrollments...');
|
|
98
86
|
expectBreadcrumbsToEqualParts(['chevron_leftBack', 'My courses']);
|
|
99
87
|
});
|
|
100
88
|
|
|
101
89
|
it('changes route when using the sidebar', async () => {
|
|
102
|
-
const user = UserFactory().one();
|
|
103
90
|
fetchMock.get('https://joanie.endpoint/api/v1.0/addresses/', [], { overwriteRoutes: true });
|
|
104
|
-
render(<
|
|
91
|
+
render(<DashboardTest initialRoute={LearnerDashboardPaths.COURSES} />, {
|
|
92
|
+
wrapper: BaseJoanieAppWrapper,
|
|
93
|
+
});
|
|
94
|
+
await expectNoSpinner('Loading orders and enrollments...');
|
|
105
95
|
expectUrlMatchLocationDisplayed(LearnerDashboardPaths.COURSES);
|
|
106
96
|
|
|
107
97
|
// Go to "My Preferences" route.
|
|
@@ -113,12 +103,14 @@ describe('<Dashboard />', () => {
|
|
|
113
103
|
});
|
|
114
104
|
|
|
115
105
|
it('redirect when clicking on the breadcrumbs back button', async () => {
|
|
116
|
-
const user = UserFactory().one();
|
|
117
106
|
const address: Address = AddressFactory().one();
|
|
118
107
|
fetchMock.get('https://joanie.endpoint/api/v1.0/addresses/', [address], {
|
|
119
108
|
overwriteRoutes: true,
|
|
120
109
|
});
|
|
121
|
-
render(<
|
|
110
|
+
render(<DashboardTest initialRoute={LearnerDashboardPaths.COURSES} />, {
|
|
111
|
+
wrapper: BaseJoanieAppWrapper,
|
|
112
|
+
});
|
|
113
|
+
await expectNoSpinner('Loading orders and enrollments...');
|
|
122
114
|
expectUrlMatchLocationDisplayed(LearnerDashboardPaths.COURSES);
|
|
123
115
|
expectBreadcrumbsToEqualParts(['chevron_leftBack', 'My courses']);
|
|
124
116
|
|
|
@@ -160,16 +152,30 @@ describe('<Dashboard />', () => {
|
|
|
160
152
|
expect(location.replace).toHaveBeenCalledWith('https://localhost');
|
|
161
153
|
});
|
|
162
154
|
|
|
163
|
-
it('should render username in sidebar if full_name is not defined', () => {
|
|
155
|
+
it('should render username in sidebar if full_name is not defined', async () => {
|
|
164
156
|
const user: User = UserFactory({ full_name: undefined }).one();
|
|
165
|
-
render(<
|
|
157
|
+
render(<DashboardTest initialRoute={LearnerDashboardPaths.COURSES} />, {
|
|
158
|
+
wrapper: BaseJoanieAppWrapper,
|
|
159
|
+
queryOptions: {
|
|
160
|
+
client: createTestQueryClient({ user }),
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
await expectNoSpinner('Loading orders and enrollments...');
|
|
164
|
+
|
|
166
165
|
const sidebar = screen.getByTestId('dashboard__sidebar');
|
|
167
166
|
getByText(sidebar, user.username, { exact: false });
|
|
168
167
|
});
|
|
169
168
|
|
|
170
|
-
it('should render full_name in sidebar', () => {
|
|
169
|
+
it('should render full_name in sidebar', async () => {
|
|
171
170
|
const user: User = UserFactory().one();
|
|
172
|
-
render(<
|
|
171
|
+
render(<DashboardTest initialRoute={LearnerDashboardPaths.COURSES} />, {
|
|
172
|
+
wrapper: BaseJoanieAppWrapper,
|
|
173
|
+
queryOptions: {
|
|
174
|
+
client: createTestQueryClient({ user }),
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
await expectNoSpinner('Loading orders and enrollments...');
|
|
178
|
+
|
|
173
179
|
const sidebar = screen.getByTestId('dashboard__sidebar');
|
|
174
180
|
getByText(sidebar, user.full_name!, { exact: false });
|
|
175
181
|
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { screen } from '@testing-library/react';
|
|
2
2
|
import userEvent from '@testing-library/user-event';
|
|
3
3
|
import { IntlProvider } from 'react-intl';
|
|
4
4
|
import { HistoryProvider } from 'hooks/useHistory';
|
|
5
|
+
import { render } from 'utils/test/render';
|
|
5
6
|
import LanguageSelector from '.';
|
|
6
7
|
|
|
7
8
|
jest.mock('utils/indirection/window', () => ({
|
|
@@ -31,15 +32,14 @@ describe('<LanguageSelector />', () => {
|
|
|
31
32
|
<IntlProvider locale="en">
|
|
32
33
|
<LanguageSelector currentLanguage="fr" languages={languages} />
|
|
33
34
|
</IntlProvider>,
|
|
35
|
+
{ wrapper: null },
|
|
34
36
|
);
|
|
35
37
|
|
|
36
38
|
const button = screen.getByLabelText('Select a language:', {
|
|
37
39
|
selector: 'button',
|
|
38
40
|
});
|
|
39
41
|
|
|
40
|
-
await
|
|
41
|
-
await userEvent.click(button);
|
|
42
|
-
});
|
|
42
|
+
await userEvent.click(button);
|
|
43
43
|
|
|
44
44
|
screen.getByRole('listbox', { name: 'Select a language:' });
|
|
45
45
|
screen.getByRole('option', { name: 'Anglais' });
|
|
@@ -69,14 +69,14 @@ describe('<LanguageSelector />', () => {
|
|
|
69
69
|
<LanguageSelector currentLanguage="fr" languages={languages} />
|
|
70
70
|
</IntlProvider>
|
|
71
71
|
</HistoryProvider>,
|
|
72
|
+
{ wrapper: null },
|
|
72
73
|
);
|
|
73
74
|
const button = screen.getByLabelText('Select a language:', {
|
|
74
75
|
selector: 'button',
|
|
75
76
|
});
|
|
76
77
|
|
|
77
|
-
await
|
|
78
|
-
|
|
79
|
-
});
|
|
78
|
+
await userEvent.click(button);
|
|
79
|
+
|
|
80
80
|
const link = await screen.findByRole('link', { name: 'Anglais' });
|
|
81
81
|
expect(link).toHaveAttribute('href', '/switch/to/en/?args=0');
|
|
82
82
|
expect(link.title).toEqual('Switch to Anglais');
|