richie-education 2.25.0-b2.dev146 → 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.
Files changed (79) hide show
  1. package/js/contexts/JoanieApiContext/index.spec.tsx +1 -1
  2. package/js/contexts/SessionContext/JoanieSessionProvider.spec.tsx +44 -37
  3. package/js/contexts/SessionContext/index.spec.tsx +42 -21
  4. package/js/contexts/SessionContext/no-authentication.spec.tsx +3 -2
  5. package/js/hooks/useCourseSearchParams/index.spec.tsx +0 -1
  6. package/js/hooks/useLearnerCoursesSearch/index.tsx +74 -0
  7. package/js/hooks/useOrders.ts +1 -0
  8. package/js/hooks/useUnionResource/index.spec.tsx +11 -9
  9. package/js/pages/DashboardCourses/_styles.scss +0 -1
  10. package/js/pages/DashboardCourses/index.spec.tsx +5 -3
  11. package/js/pages/DashboardCourses/index.tsx +28 -13
  12. package/js/pages/DashboardCourses/useOrdersEnrollments.tsx +7 -9
  13. package/js/pages/TeacherDashboardCoursesLoader/index.tsx +4 -2
  14. package/js/types/Joanie.ts +1 -0
  15. package/js/utils/test/render.tsx +5 -1
  16. package/js/utils/test/wrappers/BaseAppWrapper.tsx +5 -8
  17. package/js/utils/test/wrappers/BaseJoanieAppWrapper.tsx +4 -7
  18. package/js/utils/test/wrappers/IntlWrapper.tsx +4 -2
  19. package/js/utils/test/wrappers/PresentationalAppWrapper.tsx +1 -1
  20. package/js/utils/test/wrappers/ReactQueryAppWrapper.tsx +16 -0
  21. package/js/widgets/Dashboard/components/DashboardAvatar/index.spec.tsx +8 -5
  22. package/js/widgets/Dashboard/components/DashboardBox/index.spec.tsx +3 -1
  23. package/js/widgets/Dashboard/components/DashboardItem/Certificate/index.spec.tsx +19 -39
  24. package/js/widgets/Dashboard/components/DashboardItem/CertificateStatus/index.spec.tsx +14 -12
  25. package/js/widgets/Dashboard/components/DashboardItem/Contract/index.spec.tsx +5 -43
  26. package/js/widgets/Dashboard/components/DashboardItem/CourseEnrolling/index.spec.tsx +16 -15
  27. package/js/widgets/Dashboard/components/DashboardItem/Enrollment/DashboardItemEnrollment.spec.tsx +8 -18
  28. package/js/widgets/Dashboard/components/DashboardItem/Enrollment/ProductCertificateFooter/index.spec.tsx +19 -51
  29. package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrder.spec.tsx +40 -70
  30. package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderContract.spec.tsx +31 -32
  31. package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateLearnerMessage/index.spec.tsx +19 -31
  32. package/js/widgets/Dashboard/components/DashboardItem/Order/OrderStateTeacherMessage/index.spec.tsx +26 -37
  33. package/js/widgets/Dashboard/components/DashboardItem/index.spec.tsx +28 -23
  34. package/js/widgets/Dashboard/components/DashboardLayoutRoute/index.spec.tsx +53 -51
  35. package/js/widgets/Dashboard/components/DashboardSidebar/components/ContractNavLink/index.spec.tsx +24 -49
  36. package/js/widgets/Dashboard/components/DashboardSidebar/components/MenuNavLink/index.spec.tsx +5 -14
  37. package/js/widgets/Dashboard/components/ProtectedOutlet/AuthenticatedOutlet.spec.tsx +62 -54
  38. package/js/widgets/Dashboard/components/ProtectedOutlet/ProtectedOutlet.spec.tsx +67 -42
  39. package/js/widgets/Dashboard/components/RouterButton/index.spec.tsx +12 -14
  40. package/js/widgets/Dashboard/components/SearchBar/_styles.scss +7 -1
  41. package/js/widgets/Dashboard/components/SearchBar/index.tsx +5 -1
  42. package/js/widgets/Dashboard/components/TeacherDashboardOrganizationSidebar/index.spec.tsx +14 -39
  43. package/js/widgets/Dashboard/hooks/useDashboardRouter/index.spec.tsx +2 -4
  44. package/js/widgets/Dashboard/hooks/useEnroll/index.spec.tsx +7 -28
  45. package/js/widgets/Dashboard/hooks/useRouteInfo/index.spec.tsx +25 -33
  46. package/js/widgets/Dashboard/index.spec.tsx +49 -43
  47. package/js/widgets/LanguageSelector/index.spec.tsx +7 -7
  48. package/js/widgets/LtiConsumer/index.spec.tsx +46 -48
  49. package/js/widgets/RootSearchSuggestField/index.spec.tsx +8 -6
  50. package/js/widgets/Search/components/PaginateCourseSearch/index.spec.tsx +10 -3
  51. package/js/widgets/Search/components/SearchFilterGroup/index.spec.tsx +5 -3
  52. package/js/widgets/Search/components/SearchFilterGroupModal/index.spec.tsx +8 -4
  53. package/js/widgets/Search/components/SearchFilterValueLeaf/index.spec.tsx +7 -3
  54. package/js/widgets/Search/components/SearchFilterValueParent/index.spec.tsx +12 -7
  55. package/js/widgets/Search/components/SearchFiltersPane/index.spec.tsx +5 -1
  56. package/js/widgets/Search/hooks/useCourseSearch/index.spec.tsx +4 -12
  57. package/js/widgets/Search/hooks/useFilterValue/index.spec.tsx +0 -2
  58. package/js/widgets/Search/index.spec.tsx +14 -6
  59. package/js/widgets/SearchSuggestField/index.spec.tsx +14 -1
  60. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseProductCertificateItem/index.spec.tsx +16 -31
  61. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseProductCourseRuns/index.spec.tsx +46 -72
  62. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseRunItem/index.spec.tsx +5 -2
  63. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.spec.tsx +147 -162
  64. package/js/widgets/SyllabusCourseRunsList/components/CourseRunEnrollment/CourseRunUnenrollmentButton/index.spec.tsx +6 -4
  65. package/js/widgets/SyllabusCourseRunsList/components/CourseRunEnrollment/index.joanie.spec.tsx +22 -99
  66. package/js/widgets/SyllabusCourseRunsList/components/CourseRunEnrollment/index.openedx.spec.tsx +27 -83
  67. package/js/widgets/SyllabusCourseRunsList/components/CourseRunItem/index.spec.tsx +4 -1
  68. package/js/widgets/SyllabusCourseRunsList/components/CourseRunItemWithEnrollment/index.spec.tsx +28 -35
  69. package/js/widgets/SyllabusCourseRunsList/components/CourseWishButton/hooks/useCourseWish/index.spec.tsx +9 -28
  70. package/js/widgets/SyllabusCourseRunsList/components/CourseWishButton/index.login.spec.tsx +23 -48
  71. package/js/widgets/SyllabusCourseRunsList/components/CourseWishButton/index.logout.spec.tsx +20 -29
  72. package/js/widgets/SyllabusCourseRunsList/components/SyllabusSimpleCourseRunsList/index.spec.tsx +9 -4
  73. package/js/widgets/SyllabusCourseRunsList/hooks/useCourseEnrollment/index.spec.tsx +8 -10
  74. package/js/widgets/SyllabusCourseRunsList/index.spec.tsx +28 -39
  75. package/js/widgets/UserLogin/components/UserMenu/index.spec.tsx +9 -6
  76. package/js/widgets/UserLogin/index.not.isJoanieEnabled.spec.tsx +21 -32
  77. package/js/widgets/UserLogin/index.spec.tsx +15 -37
  78. package/js/widgets/index.spec.tsx +12 -17
  79. package/package.json +1 -1
@@ -42,8 +42,10 @@ export const TeacherDashboardCoursesLoader = () => {
42
42
  </h1>
43
43
  </div>
44
44
 
45
- <SearchBar onSubmit={submitSearch} />
46
- <SearchResultsCount nbResults={count} />
45
+ <SearchBar.Container>
46
+ <SearchBar onSubmit={submitSearch} />
47
+ <SearchResultsCount nbResults={count} />
48
+ </SearchBar.Container>
47
49
  </div>
48
50
  <div className="teacher-courses-page">
49
51
  <TeacherDashboardCourseList
@@ -460,6 +460,7 @@ export interface PaginatedResourceQuery extends ResourcesQuery {
460
460
  export interface EnrollmentsQuery extends PaginatedResourceQuery {
461
461
  course_run_id?: CourseRun['id'];
462
462
  was_created_by_order?: boolean;
463
+ query?: string;
463
464
  }
464
465
 
465
466
  interface EnrollmentCreationPayload {
@@ -65,7 +65,11 @@ export const render: RenderFunction = (
65
65
  rerenderOptions?: Partial<Omit<AppWrapperProps, 'testingLibraryOptions'>>,
66
66
  ) => {
67
67
  return renderResult.rerender(
68
- Wrapper === null ? element : <Wrapper {...rerenderOptions}>{rerenderElement}</Wrapper>,
68
+ Wrapper === null ? (
69
+ rerenderElement
70
+ ) : (
71
+ <Wrapper {...rerenderOptions}>{rerenderElement}</Wrapper>
72
+ ),
69
73
  );
70
74
  },
71
75
  };
@@ -1,8 +1,7 @@
1
1
  import { PropsWithChildren } from 'react';
2
- import { SessionProvider } from 'contexts/SessionContext';
3
- import { IntlWrapper } from './IntlWrapper';
4
- import { ReactQueryWrapper } from './ReactQueryWrapper';
2
+ import BaseSessionProvider from 'contexts/SessionContext/BaseSessionProvider';
5
3
  import { AppWrapperProps } from './types';
4
+ import { ReactQueryAppWrapper } from './ReactQueryAppWrapper';
6
5
 
7
6
  export const BaseAppWrapper = ({
8
7
  children,
@@ -10,10 +9,8 @@ export const BaseAppWrapper = ({
10
9
  queryOptions,
11
10
  }: PropsWithChildren<AppWrapperProps>) => {
12
11
  return (
13
- <IntlWrapper {...(intlOptions || { locale: 'en' })}>
14
- <ReactQueryWrapper {...(queryOptions || {})}>
15
- <SessionProvider>{children}</SessionProvider>
16
- </ReactQueryWrapper>
17
- </IntlWrapper>
12
+ <ReactQueryAppWrapper queryOptions={queryOptions} intlOptions={intlOptions}>
13
+ <BaseSessionProvider>{children}</BaseSessionProvider>
14
+ </ReactQueryAppWrapper>
18
15
  );
19
16
  };
@@ -1,9 +1,8 @@
1
1
  import { PropsWithChildren } from 'react';
2
2
 
3
3
  import JoanieSessionProvider from 'contexts/SessionContext/JoanieSessionProvider';
4
- import { IntlWrapper } from './IntlWrapper';
5
- import { ReactQueryWrapper } from './ReactQueryWrapper';
6
4
  import { AppWrapperProps } from './types';
5
+ import { ReactQueryAppWrapper } from './ReactQueryAppWrapper';
7
6
 
8
7
  export const BaseJoanieAppWrapper = ({
9
8
  children,
@@ -11,10 +10,8 @@ export const BaseJoanieAppWrapper = ({
11
10
  queryOptions,
12
11
  }: PropsWithChildren<AppWrapperProps>) => {
13
12
  return (
14
- <IntlWrapper {...(intlOptions || { locale: 'en' })}>
15
- <ReactQueryWrapper {...(queryOptions || {})}>
16
- <JoanieSessionProvider>{children}</JoanieSessionProvider>
17
- </ReactQueryWrapper>
18
- </IntlWrapper>
13
+ <ReactQueryAppWrapper queryOptions={queryOptions} intlOptions={intlOptions}>
14
+ <JoanieSessionProvider>{children}</JoanieSessionProvider>
15
+ </ReactQueryAppWrapper>
19
16
  );
20
17
  };
@@ -1,7 +1,9 @@
1
- import { ComponentProps, PropsWithChildren } from 'react';
1
+ import { ComponentProps } from 'react';
2
2
  import { IntlProvider, ReactIntlErrorCode } from 'react-intl';
3
3
 
4
- export interface IntlWrapperProps extends PropsWithChildren, ComponentProps<typeof IntlProvider> {}
4
+ export interface IntlWrapperProps extends Omit<ComponentProps<typeof IntlProvider>, 'locale'> {
5
+ locale?: string;
6
+ }
5
7
 
6
8
  export const IntlWrapper = ({ children, ...options }: IntlWrapperProps) => (
7
9
  <IntlProvider
@@ -9,7 +9,7 @@ export const PresentationalAppWrapper = ({
9
9
  routerOptions,
10
10
  }: PropsWithChildren<{ intlOptions?: IntlWrapperProps; routerOptions?: RouterWrapperProps }>) => {
11
11
  return (
12
- <IntlWrapper {...(intlOptions || { locale: 'en' })}>
12
+ <IntlWrapper {...intlOptions}>
13
13
  <CunninghamProvider>
14
14
  <RouterWrapper {...routerOptions}>{children}</RouterWrapper>
15
15
  </CunninghamProvider>
@@ -0,0 +1,16 @@
1
+ import { PropsWithChildren } from 'react';
2
+ import { IntlWrapper } from './IntlWrapper';
3
+ import { ReactQueryWrapper } from './ReactQueryWrapper';
4
+ import { AppWrapperProps } from './types';
5
+
6
+ export const ReactQueryAppWrapper = ({
7
+ children,
8
+ intlOptions,
9
+ queryOptions,
10
+ }: PropsWithChildren<AppWrapperProps>) => {
11
+ return (
12
+ <IntlWrapper {...intlOptions}>
13
+ <ReactQueryWrapper {...queryOptions}>{children}</ReactQueryWrapper>
14
+ </IntlWrapper>
15
+ );
16
+ };
@@ -1,15 +1,16 @@
1
- import { render, screen } from '@testing-library/react';
1
+ import { screen } from '@testing-library/react';
2
2
  import { JoanieFileFactory } from 'utils/test/factories/joanie';
3
+ import { render } from 'utils/test/render';
3
4
  import { DashboardAvatar, DashboardAvatarVariantEnum } from '.';
4
5
 
5
6
  describe('<DashboardAvatar/>', () => {
6
7
  it('should work with empty title', () => {
7
- render(<DashboardAvatar title="" />);
8
+ render(<DashboardAvatar title="" />, { wrapper: null });
8
9
  expect(screen.getByTestId('dashboard-avatar')).toHaveTextContent('');
9
10
  });
10
11
 
11
12
  it('should display the first letter of the title', () => {
12
- render(<DashboardAvatar title="Bob" />);
13
+ render(<DashboardAvatar title="Bob" />, { wrapper: null });
13
14
  expect(screen.getByTestId('dashboard-avatar')).toHaveTextContent('B');
14
15
  });
15
16
 
@@ -18,14 +19,16 @@ describe('<DashboardAvatar/>', () => {
18
19
  src: 'http://my.awesome.image',
19
20
  srcset: '200w http://my.awesome.image/200',
20
21
  }).one();
21
- render(<DashboardAvatar title="Bob" image={image} />);
22
+ render(<DashboardAvatar title="Bob" image={image} />, { wrapper: null });
22
23
  const img = screen.getByAltText('Bob');
23
24
  expect(img).toHaveAttribute('src', 'http://my.awesome.image');
24
25
  expect(img).toHaveAttribute('srcset', '200w http://my.awesome.image/200');
25
26
  });
26
27
 
27
28
  it('should contain the variant class for SQUARE', () => {
28
- render(<DashboardAvatar title="Bob" variant={DashboardAvatarVariantEnum.SQUARE} />);
29
+ render(<DashboardAvatar title="Bob" variant={DashboardAvatarVariantEnum.SQUARE} />, {
30
+ wrapper: null,
31
+ });
29
32
  expect(screen.getByTestId('dashboard-avatar')).toHaveClass('dashboard__avatar--square');
30
33
  });
31
34
  });
@@ -1,4 +1,5 @@
1
- import { render, screen } from '@testing-library/react';
1
+ import { screen } from '@testing-library/react';
2
+ import { render } from 'utils/test/render';
2
3
  import { DashboardBox } from '.';
3
4
 
4
5
  describe('<DashboardBox/>', () => {
@@ -7,6 +8,7 @@ describe('<DashboardBox/>', () => {
7
8
  <DashboardBox header="Header" footer="Footer">
8
9
  Content
9
10
  </DashboardBox>,
11
+ { wrapper: null },
10
12
  );
11
13
  screen.getByText('Header');
12
14
  screen.getByText('Content');
@@ -1,13 +1,8 @@
1
- import { render, screen, waitFor } from '@testing-library/react';
2
- import { PropsWithChildren } from 'react';
3
- import { QueryClientProvider } from '@tanstack/react-query';
4
- import { IntlProvider } from 'react-intl';
1
+ import { screen, waitFor } from '@testing-library/react';
5
2
  import userEvent from '@testing-library/user-event';
6
3
  import fetchMock from 'fetch-mock';
7
4
  import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie';
8
5
  import { Certificate, ProductType } from 'types/Joanie';
9
- import { createTestQueryClient } from 'utils/test/createTestQueryClient';
10
- import { SessionProvider } from 'contexts/SessionContext';
11
6
  import { DashboardItemCertificate } from 'widgets/Dashboard/components/DashboardItem/Certificate/index';
12
7
  import { DEFAULT_DATE_FORMAT } from 'hooks/useDateFormat';
13
8
  import {
@@ -17,12 +12,15 @@ import {
17
12
  NestedCredentialOrderFactory,
18
13
  } from 'utils/test/factories/joanie';
19
14
  import { HttpStatusCode } from 'utils/errors/HttpError';
15
+ import { setupJoanieSession } from 'utils/test/wrappers/JoanieAppWrapper';
16
+ import { render } from 'utils/test/render';
17
+ import { BaseJoanieAppWrapper } from 'utils/test/wrappers/BaseJoanieAppWrapper';
20
18
 
21
19
  jest.mock('utils/context', () => ({
22
20
  __esModule: true,
23
21
  default: mockRichieContextFactory({
24
22
  authentication: { backend: 'fonzie', endpoint: 'https://auth.test' },
25
- joanie_backend: { endpoint: 'https://joanie.test' },
23
+ joanie_backend: { endpoint: 'https://joanie.endpoint' },
26
24
  }).one(),
27
25
  }));
28
26
 
@@ -49,15 +47,7 @@ describe.each([
49
47
  }),
50
48
  },
51
49
  ])('<DashboardCertificate/> $label', ({ overrideFactory }) => {
52
- const Wrapper = ({ children }: PropsWithChildren) => {
53
- return (
54
- <QueryClientProvider client={createTestQueryClient({ user: true })}>
55
- <IntlProvider locale="en">
56
- <SessionProvider>{children}</SessionProvider>
57
- </IntlProvider>
58
- </QueryClientProvider>
59
- );
60
- };
50
+ setupJoanieSession();
61
51
 
62
52
  beforeAll(() => {
63
53
  // eslint-disable-next-line compat/compat
@@ -67,23 +57,11 @@ describe.each([
67
57
  HTMLAnchorElement.prototype.click = jest.fn();
68
58
  });
69
59
 
70
- beforeEach(() => {
71
- // SessionProvider queries
72
- fetchMock.get('https://joanie.test/api/v1.0/orders/', []);
73
- fetchMock.get('https://joanie.test/api/v1.0/addresses/', []);
74
- fetchMock.get('https://joanie.test/api/v1.0/credit-cards/', []);
75
- });
76
-
77
- afterEach(() => {
78
- jest.clearAllMocks();
79
- fetchMock.restore();
80
- });
81
-
82
60
  it('displays a certificate', async () => {
83
61
  const certificate: Certificate = CertificateFactory(overrideFactory()).one();
84
62
  render(
85
63
  <DashboardItemCertificate certificate={certificate} productType={ProductType.CREDENTIAL} />,
86
- { wrapper: Wrapper },
64
+ { wrapper: BaseJoanieAppWrapper },
87
65
  );
88
66
 
89
67
  await waitFor(() => screen.getByText(certificate.certificate_definition.title));
@@ -107,18 +85,20 @@ describe.each([
107
85
  it('downloads the certificate', async () => {
108
86
  const certificate: Certificate = CertificateFactory(overrideFactory()).one();
109
87
 
110
- fetchMock.get(`https://joanie.test/api/v1.0/certificates/${certificate.id}/download/`, () => ({
111
- status: HttpStatusCode.OK,
112
- body: new Blob(['test']),
113
- headers: {
114
- 'Content-Disposition': 'attachment; filename="test.pdf";',
115
- 'Content-Type': 'application/pdf',
116
- },
117
- }));
118
-
88
+ fetchMock.get(
89
+ `https://joanie.endpoint/api/v1.0/certificates/${certificate.id}/download/`,
90
+ () => ({
91
+ status: HttpStatusCode.OK,
92
+ body: new Blob(['test']),
93
+ headers: {
94
+ 'Content-Disposition': 'attachment; filename="test.pdf";',
95
+ 'Content-Type': 'application/pdf',
96
+ },
97
+ }),
98
+ );
119
99
  render(
120
100
  <DashboardItemCertificate certificate={certificate} productType={ProductType.CREDENTIAL} />,
121
- { wrapper: Wrapper },
101
+ { wrapper: BaseJoanieAppWrapper },
122
102
  );
123
103
 
124
104
  await waitFor(() => screen.getByText(certificate.certificate_definition.title));
@@ -1,21 +1,19 @@
1
- import { IntlProvider } from 'react-intl';
2
- import { render, screen } from '@testing-library/react';
1
+ import { screen } from '@testing-library/react';
2
+ import { PropsWithChildren } from 'react';
3
3
  import { ProductType } from 'types/Joanie';
4
4
  import { CertificateFactory } from 'utils/test/factories/joanie';
5
- import CertificateStatus, { CertificateStatusProps } from '.';
5
+ import { render } from 'utils/test/render';
6
+ import { IntlWrapper } from 'utils/test/wrappers/IntlWrapper';
7
+ import CertificateStatus from '.';
6
8
 
7
9
  describe('<CertificateStatus/>', () => {
8
- const Wrapper = ({ certificate, productType }: CertificateStatusProps) => (
9
- <IntlProvider locale="en">
10
- <CertificateStatus certificate={certificate} productType={productType} />
11
- </IntlProvider>
12
- );
13
-
14
10
  it('should display message for issued certificate.', () => {
15
11
  const certificate = CertificateFactory({
16
12
  issued_on: new Date('01/01/2021').toISOString(),
17
13
  }).one();
18
- render(<Wrapper certificate={certificate} productType={ProductType.CERTIFICATE} />);
14
+ render(<CertificateStatus certificate={certificate} productType={ProductType.CERTIFICATE} />, {
15
+ wrapper: ({ children }: PropsWithChildren) => <IntlWrapper>{children}</IntlWrapper>,
16
+ });
19
17
  expect(screen.getByText('Issued on Jan 01, 2021')).toBeInTheDocument();
20
18
 
21
19
  expect(
@@ -31,7 +29,9 @@ describe('<CertificateStatus/>', () => {
31
29
  });
32
30
 
33
31
  it('should display message for no certificate of product type certificate.', () => {
34
- render(<Wrapper productType={ProductType.CERTIFICATE} />);
32
+ render(<CertificateStatus productType={ProductType.CERTIFICATE} />, {
33
+ wrapper: ({ children }: PropsWithChildren) => <IntlWrapper>{children}</IntlWrapper>,
34
+ });
35
35
 
36
36
  expect(
37
37
  screen.getByText(
@@ -48,7 +48,9 @@ describe('<CertificateStatus/>', () => {
48
48
  });
49
49
 
50
50
  it('should display message for no certificate of product type credential.', () => {
51
- render(<Wrapper productType={ProductType.CREDENTIAL} />);
51
+ render(<CertificateStatus productType={ProductType.CREDENTIAL} />, {
52
+ wrapper: ({ children }: PropsWithChildren) => <IntlWrapper>{children}</IntlWrapper>,
53
+ });
52
54
  expect(
53
55
  screen.getByText(
54
56
  'When all your courses have been passed, you will be able to download your certificate here.',
@@ -1,14 +1,7 @@
1
- import { render, screen } from '@testing-library/react';
2
- import { PropsWithChildren } from 'react';
3
- import { QueryClientProvider } from '@tanstack/react-query';
4
- import { IntlProvider } from 'react-intl';
5
- import fetchMock from 'fetch-mock';
1
+ import { screen } from '@testing-library/react';
6
2
  import { faker } from '@faker-js/faker';
7
- import { MemoryRouter } from 'react-router-dom';
8
3
  import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie';
9
4
  import { Contract, NestedCredentialOrder } from 'types/Joanie';
10
- import { createTestQueryClient } from 'utils/test/createTestQueryClient';
11
- import { SessionProvider } from 'contexts/SessionContext';
12
5
  import { DashboardItemContract } from 'widgets/Dashboard/components/DashboardItem/Contract/index';
13
6
  import { DEFAULT_DATE_FORMAT } from 'hooks/useDateFormat';
14
7
  import {
@@ -16,12 +9,14 @@ import {
16
9
  CredentialOrderFactory,
17
10
  NestedCredentialOrderFactory,
18
11
  } from 'utils/test/factories/joanie';
12
+ import { setupJoanieSession } from 'utils/test/wrappers/JoanieAppWrapper';
13
+ import { render } from 'utils/test/render';
19
14
 
20
15
  jest.mock('utils/context', () => ({
21
16
  __esModule: true,
22
17
  default: mockRichieContextFactory({
23
18
  authentication: { backend: 'fonzie', endpoint: 'https://auth.test' },
24
- joanie_backend: { endpoint: 'https://joanie.test' },
19
+ joanie_backend: { endpoint: 'https://joanie.endpoint' },
25
20
  }).one(),
26
21
  }));
27
22
 
@@ -35,34 +30,13 @@ describe.each([
35
30
  OrderSerializer: CredentialOrderFactory,
36
31
  },
37
32
  ])('<DashboardContract/> $label', ({ OrderSerializer }) => {
38
- const Wrapper = ({ children }: PropsWithChildren) => {
39
- return (
40
- <QueryClientProvider client={createTestQueryClient({ user: true })}>
41
- <IntlProvider locale="en">
42
- <SessionProvider>
43
- <MemoryRouter>{children}</MemoryRouter>
44
- </SessionProvider>
45
- </IntlProvider>
46
- </QueryClientProvider>
47
- );
48
- };
33
+ setupJoanieSession();
49
34
 
50
35
  beforeAll(() => {
51
36
  // eslint-disable-next-line compat/compat
52
37
  URL.createObjectURL = jest.fn();
53
38
  });
54
39
 
55
- beforeEach(() => {
56
- fetchMock.get('https://joanie.test/api/v1.0/orders/', []);
57
- fetchMock.get('https://joanie.test/api/v1.0/addresses/', []);
58
- fetchMock.get('https://joanie.test/api/v1.0/credit-cards/', []);
59
- });
60
-
61
- afterEach(() => {
62
- jest.clearAllMocks();
63
- fetchMock.restore();
64
- });
65
-
66
40
  it.each([
67
41
  { label: 'writable', writable: true },
68
42
  { label: 'none-writable', writable: false },
@@ -81,9 +55,6 @@ describe.each([
81
55
  contract={contract}
82
56
  writable={writable}
83
57
  />,
84
- {
85
- wrapper: Wrapper,
86
- },
87
58
  );
88
59
 
89
60
  expect(await screen.findByText(contract.definition.title)).toBeInTheDocument();
@@ -118,9 +89,6 @@ describe.each([
118
89
  contract={contract}
119
90
  writable={writable}
120
91
  />,
121
- {
122
- wrapper: Wrapper,
123
- },
124
92
  );
125
93
 
126
94
  expect(await screen.findByText(contract.definition.title)).toBeInTheDocument();
@@ -149,9 +117,6 @@ describe.each([
149
117
  contract={contract}
150
118
  writable={true}
151
119
  />,
152
- {
153
- wrapper: Wrapper,
154
- },
155
120
  );
156
121
 
157
122
  expect(await screen.findByText(contract.definition.title)).toBeInTheDocument();
@@ -179,9 +144,6 @@ describe.each([
179
144
  contract={contract}
180
145
  writable={false}
181
146
  />,
182
- {
183
- wrapper: Wrapper,
184
- },
185
147
  );
186
148
 
187
149
  expect(await screen.findByText(contract.definition.title)).toBeInTheDocument();
@@ -1,5 +1,5 @@
1
- import { render, screen } from '@testing-library/react';
2
- import { IntlProvider, createIntl } from 'react-intl';
1
+ import { screen } from '@testing-library/react';
2
+ import { createIntl } from 'react-intl';
3
3
  import { PropsWithChildren } from 'react';
4
4
  import { CredentialOrderFactory, EnrollmentFactory } from 'utils/test/factories/joanie';
5
5
  import { Priority } from 'types';
@@ -9,6 +9,8 @@ import { CourseRunFactoryFromPriority } from 'utils/test/factories/richie';
9
9
  import { noop } from 'utils';
10
10
  import { computeState } from 'utils/CourseRuns';
11
11
  import { formatRelativeDate } from 'utils/relativeDate';
12
+ import { IntlWrapper } from 'utils/test/wrappers/IntlWrapper';
13
+ import { render } from 'utils/test/render';
12
14
  import { DashboardItemCourseEnrollingRun, Enrolled } from '.';
13
15
 
14
16
  /**
@@ -16,10 +18,6 @@ import { DashboardItemCourseEnrollingRun, Enrolled } from '.';
16
18
  * DashboardItemOrder.spec.tsx. But here are some tests that are more straightforward.
17
19
  */
18
20
  describe('<Enrolled/>', () => {
19
- const wrapper = ({ children }: PropsWithChildren) => {
20
- return <IntlProvider locale="en">{children}</IntlProvider>;
21
- };
22
-
23
21
  it.each([
24
22
  {
25
23
  buttonTestLabel: 'and access course button',
@@ -87,7 +85,9 @@ describe('<Enrolled/>', () => {
87
85
  async ({ priority, expectButton, expectLabelTemplate }) => {
88
86
  const enrollment: Enrollment = EnrollmentFactory().one();
89
87
  enrollment.course_run.state.priority = priority;
90
- render(<Enrolled enrollment={enrollment} />, { wrapper });
88
+ render(<Enrolled enrollment={enrollment} />, {
89
+ wrapper: ({ children }: PropsWithChildren) => <IntlWrapper>{children}</IntlWrapper>,
90
+ });
91
91
  const intl = createIntl({ locale: 'en' });
92
92
 
93
93
  const fromDate = new Intl.DateTimeFormat('en', DEFAULT_DATE_FORMAT).format(
@@ -138,14 +138,15 @@ describe('<DashboardItemCourseEnrollingRun/>', () => {
138
138
  joanieCourseRun.course = order.course;
139
139
 
140
140
  render(
141
- <IntlProvider locale="en">
142
- <DashboardItemCourseEnrollingRun
143
- order={order}
144
- courseRun={joanieCourseRun}
145
- selected={false}
146
- enroll={noop}
147
- />
148
- </IntlProvider>,
141
+ <DashboardItemCourseEnrollingRun
142
+ order={order}
143
+ courseRun={joanieCourseRun}
144
+ selected={false}
145
+ enroll={noop}
146
+ />,
147
+ {
148
+ wrapper: ({ children }: PropsWithChildren) => <IntlWrapper>{children}</IntlWrapper>,
149
+ },
149
150
  );
150
151
 
151
152
  if (expectEnrollmentNotYetOpened) {
@@ -1,7 +1,5 @@
1
- import { IntlProvider } from 'react-intl';
2
- import { render, screen } from '@testing-library/react';
1
+ import { screen } from '@testing-library/react';
3
2
  import { faker } from '@faker-js/faker';
4
- import { QueryClientProvider } from '@tanstack/react-query';
5
3
  import { Enrollment } from 'types/Joanie';
6
4
  import {
7
5
  CourseStateFactory,
@@ -10,28 +8,20 @@ import {
10
8
  import { CourseRunWithCourseFactory, EnrollmentFactory } from 'utils/test/factories/joanie';
11
9
  import { DEFAULT_DATE_FORMAT } from 'hooks/useDateFormat';
12
10
  import { Priority } from 'types';
13
- import { createTestQueryClient } from 'utils/test/createTestQueryClient';
14
- import JoanieSessionProvider from 'contexts/SessionContext/JoanieSessionProvider';
11
+ import { setupJoanieSession } from 'utils/test/wrappers/JoanieAppWrapper';
12
+ import { render } from 'utils/test/render';
15
13
  import { DashboardItemEnrollment } from './DashboardItemEnrollment';
16
14
 
17
15
  jest.mock('utils/context', () => ({
18
16
  __esModule: true,
19
17
  default: mockRichieContextFactory({
20
18
  authentication: { backend: 'fonzie', endpoint: 'https://auth.endpoint.test' },
21
- joanie_backend: { endpoint: 'https://joanie.endpoint.test' },
19
+ joanie_backend: { endpoint: 'https://joanie.endpoint' },
22
20
  }).one(),
23
21
  }));
24
22
 
25
23
  describe('<DashboardItemEnrollment/>', () => {
26
- const Wrapper = ({ enrollment }: { enrollment: Enrollment }) => (
27
- <IntlProvider locale="en">
28
- <QueryClientProvider client={createTestQueryClient()}>
29
- <JoanieSessionProvider>
30
- <DashboardItemEnrollment enrollment={enrollment} />
31
- </JoanieSessionProvider>
32
- </QueryClientProvider>
33
- </IntlProvider>
34
- );
24
+ setupJoanieSession();
35
25
 
36
26
  it('renders a opened enrollment', () => {
37
27
  const enrollment: Enrollment = EnrollmentFactory({
@@ -44,7 +34,7 @@ describe('<DashboardItemEnrollment/>', () => {
44
34
  }).one();
45
35
  enrollment.course_run.state.priority = Priority.ONGOING_OPEN;
46
36
 
47
- render(<Wrapper enrollment={enrollment} />);
37
+ render(<DashboardItemEnrollment enrollment={enrollment} />);
48
38
  screen.getByText(enrollment.course_run.course!.title);
49
39
  screen.getByText('Ref. ' + enrollment.course_run.course!.code);
50
40
  const link = screen.getByRole('link', { name: 'Access to course' });
@@ -71,7 +61,7 @@ describe('<DashboardItemEnrollment/>', () => {
71
61
  }).one(),
72
62
  }).one();
73
63
 
74
- render(<Wrapper enrollment={enrollment} />);
64
+ render(<DashboardItemEnrollment enrollment={enrollment} />);
75
65
  screen.getByText(enrollment.course_run.course!.title);
76
66
  screen.getByText('Ref. ' + enrollment.course_run.course!.code);
77
67
  const link = screen.getByRole('link', { name: 'Access to course' });
@@ -86,7 +76,7 @@ describe('<DashboardItemEnrollment/>', () => {
86
76
  course_run: CourseRunWithCourseFactory().one(),
87
77
  }).one();
88
78
 
89
- render(<Wrapper enrollment={enrollment} />);
79
+ render(<DashboardItemEnrollment enrollment={enrollment} />);
90
80
  screen.getByText(enrollment.course_run.course!.title);
91
81
  screen.getByText('Ref. ' + enrollment.course_run.course!.code);
92
82
  screen.getByText('Not enrolled');