@openedx/frontend-app-learner-dashboard 1.0.0-alpha.4 → 1.0.0-alpha.5

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 (159) hide show
  1. package/package.json +4 -5
  2. package/src/app.scss +2 -5
  3. package/src/components/Banner.test.jsx +21 -21
  4. package/src/containers/CourseCard/CourseCard.scss +4 -6
  5. package/src/containers/CourseCard/components/CourseCardActions/ActionButton/hooks.test.js +27 -0
  6. package/src/containers/CourseCard/components/CourseCardActions/ActionButton/index.test.jsx +17 -14
  7. package/src/containers/CourseCard/components/CourseCardActions/BeginCourseButton.test.jsx +37 -34
  8. package/src/containers/CourseCard/components/CourseCardActions/ResumeButton.test.jsx +28 -28
  9. package/src/containers/CourseCard/components/CourseCardActions/SelectSessionButton.test.jsx +26 -17
  10. package/src/containers/CourseCard/components/CourseCardActions/ViewCourseButton.test.jsx +29 -19
  11. package/src/containers/CourseCard/components/CourseCardActions/index.test.jsx +32 -34
  12. package/src/containers/CourseCard/components/CourseCardBanners/CertificateBanner.test.jsx +205 -190
  13. package/src/containers/CourseCard/components/CourseCardBanners/CourseBanner.test.jsx +35 -62
  14. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/hooks.test.js +3 -3
  15. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/index.test.jsx +49 -79
  16. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/ApprovedContent.jsx +1 -2
  17. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/ApprovedContent.test.jsx +51 -34
  18. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/EligibleContent.test.jsx +36 -44
  19. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/MustRequestContent.jsx +1 -2
  20. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/MustRequestContent.test.jsx +74 -44
  21. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/PendingContent.jsx +1 -2
  22. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/PendingContent.test.jsx +40 -34
  23. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/RejectedContent.test.jsx +16 -26
  24. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/CreditContent.test.jsx +38 -28
  25. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/CreditRequestForm/hooks.test.js +6 -0
  26. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/CreditRequestForm/index.test.jsx +25 -24
  27. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/CreditRequestForm/ref.test.jsx +0 -3
  28. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/ProviderLink.test.jsx +15 -13
  29. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/hooks.test.js +3 -3
  30. package/src/containers/CourseCard/components/CourseCardBanners/EntitlementBanner.test.jsx +33 -24
  31. package/src/containers/CourseCard/components/CourseCardBanners/RelatedProgramsBanner/ProgramsList.test.jsx +13 -5
  32. package/src/containers/CourseCard/components/CourseCardBanners/RelatedProgramsBanner/index.test.jsx +34 -27
  33. package/src/containers/CourseCard/components/CourseCardBanners/index.test.jsx +44 -15
  34. package/src/containers/CourseCard/components/CourseCardDetails/hooks.test.js +19 -9
  35. package/src/containers/CourseCard/components/CourseCardDetails/index.scss +1 -5
  36. package/src/containers/CourseCard/components/CourseCardDetails/index.test.jsx +20 -8
  37. package/src/containers/CourseCard/components/CourseCardImage.test.jsx +48 -41
  38. package/src/containers/CourseCard/components/CourseCardMenu/SocialShareMenu.jsx +3 -4
  39. package/src/containers/CourseCard/components/CourseCardMenu/SocialShareMenu.test.jsx +62 -92
  40. package/src/containers/CourseCard/components/CourseCardMenu/hooks.js +8 -7
  41. package/src/containers/CourseCard/components/CourseCardMenu/hooks.test.js +8 -15
  42. package/src/containers/CourseCard/components/CourseCardMenu/index.jsx +2 -3
  43. package/src/containers/CourseCard/components/CourseCardMenu/index.test.jsx +78 -112
  44. package/src/containers/CourseCard/components/CourseCardTitle.test.jsx +51 -45
  45. package/src/containers/CourseCard/components/RelatedProgramsBadge/hooks.jsx +2 -2
  46. package/src/containers/CourseCard/components/RelatedProgramsBadge/hooks.test.js +18 -4
  47. package/src/containers/CourseCard/components/RelatedProgramsBadge/index.jsx +1 -1
  48. package/src/containers/CourseCard/components/RelatedProgramsBadge/index.test.jsx +17 -13
  49. package/src/containers/CourseCard/components/hooks.test.js +19 -8
  50. package/src/containers/CourseCard/hooks.test.js +12 -2
  51. package/src/containers/CourseCard/index.test.jsx +33 -12
  52. package/src/containers/CourseFilterControls/ActiveCourseFilters.test.jsx +19 -8
  53. package/src/containers/CourseFilterControls/CourseFilterControls.test.jsx +51 -36
  54. package/src/containers/CourseFilterControls/components/Checkbox.test.jsx +8 -5
  55. package/src/containers/CourseFilterControls/components/FilterForm.test.jsx +45 -20
  56. package/src/containers/CourseFilterControls/components/SortForm.test.jsx +19 -9
  57. package/src/containers/CourseFilterControls/hooks.test.js +25 -13
  58. package/src/containers/CoursesPanel/CourseList/index.test.jsx +39 -22
  59. package/src/containers/CoursesPanel/NoCoursesView/index.scss +5 -7
  60. package/src/containers/CoursesPanel/NoCoursesView/index.test.jsx +26 -6
  61. package/src/containers/CoursesPanel/hooks.test.js +4 -4
  62. package/src/containers/CoursesPanel/index.scss +5 -7
  63. package/src/containers/CoursesPanel/index.test.jsx +55 -21
  64. package/src/containers/Dashboard/DashboardLayout.test.jsx +43 -52
  65. package/src/containers/Dashboard/LoadingView.test.jsx +5 -10
  66. package/src/containers/Dashboard/hooks.test.js +21 -19
  67. package/src/containers/Dashboard/index.scss +8 -10
  68. package/src/containers/Dashboard/index.test.jsx +51 -92
  69. package/src/containers/EmailSettingsModal/hooks.test.js +3 -3
  70. package/src/containers/EmailSettingsModal/index.test.jsx +27 -10
  71. package/src/containers/RelatedProgramsModal/components/ProgramCard.test.jsx +31 -11
  72. package/src/containers/RelatedProgramsModal/index.test.jsx +27 -15
  73. package/src/containers/SelectSessionModal/constants.js +0 -1
  74. package/src/containers/SelectSessionModal/hooks.test.js +15 -5
  75. package/src/containers/SelectSessionModal/index.test.jsx +24 -11
  76. package/src/containers/UnenrollConfirmModal/components/ConfirmPane.test.jsx +24 -8
  77. package/src/containers/UnenrollConfirmModal/components/FinishedPane.test.jsx +39 -14
  78. package/src/containers/UnenrollConfirmModal/components/ReasonPane.test.jsx +23 -6
  79. package/src/containers/UnenrollConfirmModal/hooks/index.test.js +74 -26
  80. package/src/containers/UnenrollConfirmModal/hooks/reasons.test.js +4 -4
  81. package/src/containers/UnenrollConfirmModal/index.test.jsx +34 -17
  82. package/src/data/constants/app.js +0 -3
  83. package/src/data/constants/app.test.js +0 -12
  84. package/src/data/redux/app/selectors/courseCard.test.js +4 -4
  85. package/src/data/redux/app/selectors/currentList.test.js +5 -3
  86. package/src/data/redux/app/selectors/simpleSelectors.test.js +1 -1
  87. package/src/data/redux/requests/reducer.test.js +1 -1
  88. package/src/data/redux/requests/selectors.js +1 -2
  89. package/src/data/redux/requests/selectors.test.js +1 -29
  90. package/src/data/services/lms/api.test.js +6 -6
  91. package/src/data/services/lms/urls.test.js +1 -1
  92. package/src/data/services/segment/utils.test.js +1 -1
  93. package/src/data/store.test.js +2 -2
  94. package/src/hooks/api.test.js +59 -64
  95. package/src/hooks/utils.test.js +4 -0
  96. package/src/segment.js +1 -2
  97. package/src/setupTest.jsx +0 -206
  98. package/src/slots/WidgetSidebarSlot/index.test.jsx +21 -11
  99. package/src/test/app.test.jsx +65 -75
  100. package/src/test/inspector.js +0 -6
  101. package/src/test/messages.js +1 -1
  102. package/src/testUtils.js +1 -1
  103. package/src/tracking/trackers/course.test.js +4 -4
  104. package/src/tracking/trackers/credit.test.js +5 -5
  105. package/src/tracking/trackers/engagement.test.js +3 -3
  106. package/src/tracking/trackers/entitlements.test.js +3 -3
  107. package/src/tracking/trackers/filter.test.js +3 -3
  108. package/src/tracking/trackers/findCourses.test.js +3 -3
  109. package/src/tracking/trackers/socialShare.test.js +2 -2
  110. package/src/utils/StrictDict.test.js +4 -12
  111. package/src/widgets/LearnerDashboardHeader/ConfirmEmailBanner/messages.js +1 -1
  112. package/src/widgets/LearnerDashboardHeader/MasqueradeBar/index.scss +10 -12
  113. package/src/widgets/LearnerDashboardHeader/hooks.js +1 -1
  114. package/src/widgets/LookingForChallengeWidget/index.test.jsx +22 -8
  115. package/src/__snapshots__/App.test.jsx.snap +0 -83
  116. package/src/__snapshots__/index.test.jsx.snap +0 -43
  117. package/src/components/__snapshots__/Banner.test.jsx.snap +0 -31
  118. package/src/containers/CourseCard/__snapshots__/index.test.jsx.snap +0 -111
  119. package/src/containers/CourseCard/components/CourseCardActions/ActionButton/__snapshots__/index.test.jsx.snap +0 -14
  120. package/src/containers/CourseCard/components/CourseCardActions/__snapshots__/BeginCourseButton.test.jsx.snap +0 -39
  121. package/src/containers/CourseCard/components/CourseCardActions/__snapshots__/ResumeButton.test.jsx.snap +0 -39
  122. package/src/containers/CourseCard/components/CourseCardActions/__snapshots__/SelectSessionButton.test.jsx.snap +0 -19
  123. package/src/containers/CourseCard/components/CourseCardActions/__snapshots__/ViewCourseButton.test.jsx.snap +0 -39
  124. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/__snapshots__/index.test.jsx.snap +0 -58
  125. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/CreditRequestForm/__snapshots__/index.test.jsx.snap +0 -32
  126. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/__snapshots__/CreditContent.test.jsx.snap +0 -60
  127. package/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/components/__snapshots__/ProviderLink.test.jsx.snap +0 -11
  128. package/src/containers/CourseCard/components/CourseCardBanners/RelatedProgramsBanner/__snapshots__/ProgramsList.test.jsx.snap +0 -28
  129. package/src/containers/CourseCard/components/CourseCardBanners/RelatedProgramsBanner/__snapshots__/index.test.jsx.snap +0 -29
  130. package/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/CertificateBanner.test.jsx.snap +0 -205
  131. package/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/CourseBanner.test.jsx.snap +0 -38
  132. package/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/EntitlementBanner.test.jsx.snap +0 -53
  133. package/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/index.test.jsx.snap +0 -41
  134. package/src/containers/CourseCard/components/CourseCardDetails/__snapshots__/index.test.jsx.snap +0 -56
  135. package/src/containers/CourseCard/components/CourseCardMenu/__snapshots__/index.test.jsx.snap +0 -81
  136. package/src/containers/CourseCard/components/RelatedProgramsBadge/__snapshots__/index.test.jsx.snap +0 -25
  137. package/src/containers/CourseCard/components/__snapshots__/CourseCardImage.test.jsx.snap +0 -72
  138. package/src/containers/CourseCard/components/__snapshots__/CourseCardTitle.test.jsx.snap +0 -33
  139. package/src/containers/CourseFilterControls/__snapshots__/ActiveCourseFilters.test.jsx.snap +0 -39
  140. package/src/containers/CourseFilterControls/__snapshots__/CourseFilterControls.test.jsx.snap +0 -169
  141. package/src/containers/CourseFilterControls/components/__snapshots__/Checkbox.test.jsx.snap +0 -46
  142. package/src/containers/CourseFilterControls/components/__snapshots__/FilterForm.test.jsx.snap +0 -41
  143. package/src/containers/CourseFilterControls/components/__snapshots__/SortForm.test.jsx.snap +0 -29
  144. package/src/containers/CoursesPanel/CourseList/__snapshots__/index.test.jsx.snap +0 -70
  145. package/src/containers/CoursesPanel/NoCoursesView/__snapshots__/index.test.jsx.snap +0 -29
  146. package/src/containers/CoursesPanel/__snapshots__/index.test.jsx.snap +0 -55
  147. package/src/containers/Dashboard/__snapshots__/DashboardLayout.test.jsx.snap +0 -197
  148. package/src/containers/Dashboard/__snapshots__/LoadingView.test.jsx.snap +0 -13
  149. package/src/containers/Dashboard/__snapshots__/index.test.jsx.snap +0 -69
  150. package/src/containers/EmailSettingsModal/__snapshots__/index.test.jsx.snap +0 -133
  151. package/src/containers/RelatedProgramsModal/__snapshots__/index.test.jsx.snap +0 -169
  152. package/src/containers/RelatedProgramsModal/components/__snapshots__/ProgramCard.test.jsx.snap +0 -60
  153. package/src/containers/SelectSessionModal/__snapshots__/index.test.jsx.snap +0 -176
  154. package/src/containers/UnenrollConfirmModal/__snapshots__/index.test.jsx.snap +0 -101
  155. package/src/containers/UnenrollConfirmModal/components/__snapshots__/ConfirmPane.test.jsx.snap +0 -22
  156. package/src/containers/UnenrollConfirmModal/components/__snapshots__/FinishedPane.test.jsx.snap +0 -38
  157. package/src/containers/UnenrollConfirmModal/components/__snapshots__/ReasonPane.test.jsx.snap +0 -183
  158. package/src/slots/WidgetSidebarSlot/__snapshots__/index.test.jsx.snap +0 -14
  159. package/src/widgets/LookingForChallengeWidget/__snapshots__/index.test.jsx.snap +0 -45
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openedx/frontend-app-learner-dashboard",
3
- "version": "1.0.0-alpha.4",
3
+ "version": "1.0.0-alpha.5",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
@@ -22,7 +22,6 @@
22
22
  "i18n_extract": "openedx formatjs extract",
23
23
  "lint": "openedx lint .",
24
24
  "lint:fix": "openedx lint --fix .",
25
- "snapshot": "openedx test --updateSnapshot",
26
25
  "test": "openedx test --coverage --passWithNoTests"
27
26
  },
28
27
  "author": "Open edX",
@@ -37,7 +36,6 @@
37
36
  "dependencies": {
38
37
  "@edx/brand": "npm:@openedx/brand-openedx@^1.2.3",
39
38
  "@edx/openedx-atlas": "^0.7.0",
40
- "@edx/react-unit-test-utils": "^4.0.0",
41
39
  "@fortawesome/fontawesome-svg-core": "^1.2.36",
42
40
  "@fortawesome/free-brands-svg-icons": "^5.15.4",
43
41
  "@fortawesome/free-solid-svg-icons": "^5.15.4",
@@ -59,6 +57,7 @@
59
57
  "@edx/browserslist-config": "^1.5.0",
60
58
  "@testing-library/jest-dom": "^6.6.3",
61
59
  "@testing-library/react": "^16.3.0",
60
+ "@testing-library/user-event": "^14.6.1",
62
61
  "identity-obj-proxy": "^3.0.0",
63
62
  "jest": "^29.7.0",
64
63
  "jest-environment-jsdom": "^29.7.0",
@@ -69,8 +68,8 @@
69
68
  "redux-mock-store": "^1.5.4"
70
69
  },
71
70
  "peerDependencies": {
72
- "@openedx/frontend-base": "^1.0.0-alpha.6",
73
- "@openedx/paragon": "^22",
71
+ "@openedx/frontend-base": "^1.0.0-alpha.11",
72
+ "@openedx/paragon": "^23",
74
73
  "@tanstack/react-query": "^5",
75
74
  "@types/react": "^18",
76
75
  "@types/react-dom": "^18",
package/src/app.scss CHANGED
@@ -1,12 +1,9 @@
1
- @import "~@edx/brand/paragon/fonts";
2
- @import "~@edx/brand/paragon/variables";
3
- @import "~@openedx/paragon/scss/core/core";
4
- @import "~@edx/brand/paragon/overrides";
1
+ @use "@openedx/frontend-base/shell/app.scss";
5
2
 
6
3
  $fa-font-path: "~font-awesome/fonts";
7
4
  @import "~font-awesome/scss/font-awesome";
8
5
 
9
- $input-focus-box-shadow: $input-box-shadow; // hack to get upgrade to paragon 4.0.0 to work
6
+ $input-focus-box-shadow: var(--pgn-elevation-form-input-base); // hack to get upgrade to paragon 4.0.0 to work
10
7
 
11
8
  #learnerDashboardRoot {
12
9
  main {
@@ -1,27 +1,27 @@
1
- import { shallow } from '@edx/react-unit-test-utils';
1
+ import { render, screen } from '@testing-library/react';
2
+ import Banner from './Banner';
2
3
 
3
- import { Alert } from '@openedx/paragon';
4
+ describe('Banner component', () => {
5
+ it('renders children content', () => {
6
+ render(<Banner>Test content</Banner>);
7
+ expect(screen.getByText('Test content')).toBeInTheDocument();
8
+ });
4
9
 
5
- import Banner from './Banner';
10
+ it('uses default props correctly', () => {
11
+ render(<Banner>Test content</Banner>);
12
+ const banner = screen.getByRole('alert');
13
+ expect(banner).toHaveClass('mb-0');
14
+ });
6
15
 
7
- describe('Banner', () => {
8
- const props = {
9
- children: 'Hello, world!',
10
- };
11
- describe('snapshot', () => {
12
- test('renders default banner', () => {
13
- const wrapper = shallow(<Banner {...props} />);
14
- expect(wrapper.snapshot).toMatchSnapshot();
15
- });
16
- test('renders with variants', () => {
17
- const wrapper = shallow(<Banner {...props} variant="success" />);
18
- expect(wrapper.snapshot).toMatchSnapshot();
16
+ it('accepts custom variant prop', () => {
17
+ render(<Banner variant="success">Test content</Banner>);
18
+ const banner = screen.getByRole('alert');
19
+ expect(banner).toHaveClass('alert-success');
20
+ });
19
21
 
20
- expect(wrapper.instance.findByType(Alert)[0].props.variant).toEqual('success');
21
- });
22
- test('renders with custom class', () => {
23
- const wrapper = shallow(<Banner {...props} className="custom-class" />);
24
- expect(wrapper.snapshot).toMatchSnapshot();
25
- });
22
+ it('accepts custom className prop', () => {
23
+ render(<Banner className="custom-class">Test content</Banner>);
24
+ const banner = screen.getByRole('alert');
25
+ expect(banner).toHaveClass('custom-class');
26
26
  });
27
27
  });
@@ -1,10 +1,8 @@
1
- @import "@openedx/paragon/scss/core/core";
2
-
3
1
  .course-card {
4
2
  .card {
5
3
  .pgn__card-wrapper-image-cap.vertical {
6
4
  display: flex;
7
- min-height: $card-image-vertical-max-height;
5
+ min-height: var(--pgn-size-card-image-vertical-max-height);
8
6
  }
9
7
  .pgn__card-image-cap {
10
8
  border-bottom-left-radius: 0 !important;
@@ -53,11 +51,11 @@
53
51
  > .alert {
54
52
  border-radius: 0;
55
53
  box-shadow: none;
56
- padding: map-get($spacers, 3) map-get($spacers, 4);
54
+ padding: var(--pgn-spacing-spacer-3) var(--pgn-spacing-spacer-4);
57
55
 
58
56
  &:last-of-type {
59
- border-bottom-left-radius: $alert-border-radius;
60
- border-bottom-right-radius: $alert-border-radius;
57
+ border-bottom-left-radius: var(--pgn-size-alert-border-radius);
58
+ border-bottom-right-radius: var(--pgn-size-alert-border-radius);
61
59
  }
62
60
  }
63
61
 
@@ -1,6 +1,33 @@
1
1
  import { useWindowSize, breakpoints } from '@openedx/paragon';
2
2
  import useIsCollapsed from './hooks';
3
3
 
4
+ jest.mock('@openedx/paragon', () => ({
5
+ ...jest.requireActual('@openedx/paragon'),
6
+ useWindowSize: jest.fn(),
7
+ breakpoints: {
8
+ extraSmall: {
9
+ minWidth: 0,
10
+ maxWidth: 575,
11
+ },
12
+ small: {
13
+ minWidth: 576,
14
+ maxWidth: 767,
15
+ },
16
+ medium: {
17
+ minWidth: 768,
18
+ maxWidth: 991,
19
+ },
20
+ large: {
21
+ minWidth: 992,
22
+ maxWidth: 1199,
23
+ },
24
+ extraLarge: {
25
+ minWidth: 1200,
26
+ maxWidth: 100000,
27
+ },
28
+ },
29
+ }));
30
+
4
31
  describe('useIsCollapsed', () => {
5
32
  it('returns true only when it is between medium and small', () => {
6
33
  // make sure all three breakpoints gap is large enough for test
@@ -1,5 +1,4 @@
1
- import { shallow } from '@edx/react-unit-test-utils';
2
-
1
+ import { render, screen } from '@testing-library/react';
3
2
  import ActionButton from '.';
4
3
 
5
4
  import useIsCollapsed from './hooks';
@@ -8,18 +7,22 @@ jest.mock('./hooks', () => jest.fn());
8
7
 
9
8
  describe('ActionButton', () => {
10
9
  const props = {
11
- arbitary: 'props',
10
+ className: 'custom-class',
11
+ children: 'Test',
12
12
  };
13
- describe('snapshot', () => {
14
- test('is collapsed', () => {
15
- useIsCollapsed.mockReturnValueOnce(true);
16
- const wrapper = shallow(<ActionButton {...props} />);
17
- expect(wrapper.snapshot).toMatchSnapshot();
18
- });
19
- test('is not collapsed', () => {
20
- useIsCollapsed.mockReturnValueOnce(false);
21
- const wrapper = shallow(<ActionButton {...props} />);
22
- expect(wrapper.snapshot).toMatchSnapshot();
23
- });
13
+
14
+ it('is collapsed', async () => {
15
+ useIsCollapsed.mockReturnValue(true);
16
+ render(<ActionButton {...props} />);
17
+ const button = screen.getByRole('button', { name: 'Test' });
18
+ expect(button).toHaveClass('btn-sm', 'custom-class');
19
+ });
20
+
21
+ it('is not collapsed', () => {
22
+ useIsCollapsed.mockReturnValue(false);
23
+ render(<ActionButton {...props} />);
24
+ const button = screen.getByRole('button', { name: 'Test' });
25
+ expect(button).toBeInTheDocument();
26
+ expect(button).not.toHaveClass('size', 'sm');
24
27
  });
25
28
  });
@@ -1,27 +1,29 @@
1
- import { shallow } from '@edx/react-unit-test-utils';
2
-
3
- import { reduxHooks } from 'hooks';
4
- import track from 'tracking';
1
+ import { render, screen } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { IntlProvider } from '@openedx/frontend-base';
4
+ import { reduxHooks } from '@src/hooks';
5
+ import track from '@src/tracking';
5
6
  import useActionDisabledState from '../hooks';
6
7
  import BeginCourseButton from './BeginCourseButton';
7
8
 
8
- jest.mock('tracking', () => ({
9
+ jest.mock('@src/tracking', () => ({
9
10
  course: {
10
11
  enterCourseClicked: jest.fn().mockName('segment.enterCourseClicked'),
11
12
  },
12
13
  }));
13
14
 
14
- jest.mock('hooks', () => ({
15
+ jest.mock('@src/hooks', () => ({
15
16
  reduxHooks: {
16
17
  useCardCourseRunData: jest.fn(),
17
18
  useCardExecEdTrackingParam: jest.fn(),
18
19
  useTrackCourseEvent: jest.fn(),
19
20
  },
20
21
  }));
22
+
21
23
  jest.mock('../hooks', () => jest.fn(() => ({ disableBeginCourse: false })));
22
- jest.mock('./ActionButton', () => 'ActionButton');
23
24
 
24
- let wrapper;
25
+ jest.mock('./ActionButton/hooks', () => jest.fn(() => false));
26
+
25
27
  const homeUrl = 'home-url';
26
28
  reduxHooks.useCardCourseRunData.mockReturnValue({ homeUrl });
27
29
  const execEdPath = (cardId) => `exec-ed-tracking-path=${cardId}`;
@@ -30,56 +32,57 @@ reduxHooks.useTrackCourseEvent.mockImplementation(
30
32
  (eventName, cardId, url) => ({ trackCourseEvent: { eventName, cardId, url } }),
31
33
  );
32
34
 
35
+ const props = {
36
+ cardId: 'cardId',
37
+ };
38
+
39
+ const renderComponent = () => render(<IntlProvider locale="en"><BeginCourseButton {...props} /></IntlProvider>);
40
+
33
41
  describe('BeginCourseButton', () => {
34
- const props = {
35
- cardId: 'cardId',
36
- };
37
42
  beforeEach(() => {
38
43
  jest.clearAllMocks();
39
44
  });
40
- describe('behavior', () => {
45
+ describe('initiliaze hooks', () => {
41
46
  it('initializes course run data with cardId', () => {
42
- wrapper = shallow(<BeginCourseButton {...props} />);
47
+ renderComponent();
43
48
  expect(reduxHooks.useCardCourseRunData).toHaveBeenCalledWith(props.cardId);
44
49
  });
45
50
  it('loads exec education path param', () => {
46
- wrapper = shallow(<BeginCourseButton {...props} />);
51
+ renderComponent();
47
52
  expect(reduxHooks.useCardExecEdTrackingParam).toHaveBeenCalledWith(props.cardId);
48
53
  });
49
54
  it('loads disabled states for begin action from action hooks', () => {
50
- wrapper = shallow(<BeginCourseButton {...props} />);
55
+ renderComponent();
51
56
  expect(useActionDisabledState).toHaveBeenCalledWith(props.cardId);
52
57
  });
53
58
  });
54
- describe('snapshot', () => {
59
+ describe('behavior', () => {
55
60
  describe('disabled', () => {
56
- beforeEach(() => {
57
- useActionDisabledState.mockReturnValueOnce({ disableBeginCourse: true });
58
- wrapper = shallow(<BeginCourseButton {...props} />);
59
- });
60
- test('snapshot', () => {
61
- expect(wrapper.snapshot).toMatchSnapshot();
62
- });
63
61
  it('should be disabled', () => {
64
- expect(wrapper.instance.props.disabled).toEqual(true);
62
+ useActionDisabledState.mockReturnValueOnce({ disableBeginCourse: true });
63
+ renderComponent();
64
+ const button = screen.getByRole('button', { name: 'Begin Course' });
65
+ expect(button).toHaveClass('disabled');
66
+ expect(button).toHaveAttribute('aria-disabled', 'true');
65
67
  });
66
68
  });
67
69
  describe('enabled', () => {
68
- beforeEach(() => {
69
- wrapper = shallow(<BeginCourseButton {...props} />);
70
- });
71
- test('snapshot', () => {
72
- expect(wrapper.snapshot).toMatchSnapshot();
73
- });
74
70
  it('should be enabled', () => {
75
- expect(wrapper.instance.props.disabled).toEqual(false);
71
+ renderComponent();
72
+ const button = screen.getByRole('button', { name: 'Begin Course' });
73
+ expect(button).not.toHaveClass('disabled');
74
+ expect(button).not.toHaveAttribute('aria-disabled', 'true');
76
75
  });
77
- it('should track enter course clicked event on click, with exec ed param', () => {
78
- expect(wrapper.instance.props.onClick).toEqual(reduxHooks.useTrackCourseEvent(
76
+ it('should track enter course clicked event on click, with exec ed param', async () => {
77
+ renderComponent();
78
+ const user = userEvent.setup();
79
+ const button = screen.getByRole('button', { name: 'Begin Course' });
80
+ user.click(button);
81
+ expect(reduxHooks.useTrackCourseEvent).toHaveBeenCalledWith(
79
82
  track.course.enterCourseClicked,
80
83
  props.cardId,
81
84
  homeUrl + execEdPath(props.cardId),
82
- ));
85
+ );
83
86
  });
84
87
  });
85
88
  });
@@ -1,17 +1,19 @@
1
- import { shallow } from '@edx/react-unit-test-utils';
1
+ import { render, screen } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { IntlProvider } from '@openedx/frontend-base';
2
4
 
3
- import { reduxHooks } from 'hooks';
4
- import track from 'tracking';
5
+ import { reduxHooks } from '@src/hooks';
6
+ import track from '@src/tracking';
5
7
  import useActionDisabledState from '../hooks';
6
8
  import ResumeButton from './ResumeButton';
7
9
 
8
- jest.mock('tracking', () => ({
10
+ jest.mock('@src/tracking', () => ({
9
11
  course: {
10
12
  enterCourseClicked: jest.fn().mockName('segment.enterCourseClicked'),
11
13
  },
12
14
  }));
13
15
 
14
- jest.mock('hooks', () => ({
16
+ jest.mock('@src/hooks', () => ({
15
17
  reduxHooks: {
16
18
  useCardCourseRunData: jest.fn(),
17
19
  useCardExecEdTrackingParam: jest.fn(),
@@ -19,7 +21,8 @@ jest.mock('hooks', () => ({
19
21
  },
20
22
  }));
21
23
  jest.mock('../hooks', () => jest.fn(() => ({ disableResumeCourse: false })));
22
- jest.mock('./ActionButton', () => 'ActionButton');
24
+
25
+ jest.mock('./ActionButton/hooks', () => jest.fn(() => false));
23
26
 
24
27
  const resumeUrl = 'resume-url';
25
28
  reduxHooks.useCardCourseRunData.mockReturnValue({ resumeUrl });
@@ -29,55 +32,52 @@ reduxHooks.useTrackCourseEvent.mockImplementation(
29
32
  (eventName, cardId, url) => ({ trackCourseEvent: { eventName, cardId, url } }),
30
33
  );
31
34
 
32
- let wrapper;
33
-
34
35
  describe('ResumeButton', () => {
35
36
  const props = {
36
37
  cardId: 'cardId',
37
38
  };
38
- describe('behavior', () => {
39
+ describe('initialize hooks', () => {
40
+ beforeEach(() => render(<IntlProvider locale="en"><ResumeButton {...props} /></IntlProvider>));
39
41
  it('initializes course run data with cardId', () => {
40
- wrapper = shallow(<ResumeButton {...props} />);
41
42
  expect(reduxHooks.useCardCourseRunData).toHaveBeenCalledWith(props.cardId);
42
43
  });
43
44
  it('loads exec education path param', () => {
44
- wrapper = shallow(<ResumeButton {...props} />);
45
45
  expect(reduxHooks.useCardExecEdTrackingParam).toHaveBeenCalledWith(props.cardId);
46
46
  });
47
47
  it('loads disabled states for resume action from action hooks', () => {
48
- wrapper = shallow(<ResumeButton {...props} />);
49
48
  expect(useActionDisabledState).toHaveBeenCalledWith(props.cardId);
50
49
  });
51
50
  });
52
- describe('snapshot', () => {
51
+ describe('behavior', () => {
53
52
  describe('disabled', () => {
54
53
  beforeEach(() => {
55
54
  useActionDisabledState.mockReturnValueOnce({ disableResumeCourse: true });
56
- wrapper = shallow(<ResumeButton {...props} />);
57
- });
58
- test('snapshot', () => {
59
- expect(wrapper.snapshot).toMatchSnapshot();
60
55
  });
61
56
  it('should be disabled', () => {
62
- expect(wrapper.instance.props.disabled).toEqual(true);
57
+ render(<IntlProvider locale="en"><ResumeButton {...props} /></IntlProvider>);
58
+ const button = screen.getByRole('button', { name: 'Resume' });
59
+ expect(button).toHaveClass('disabled');
60
+ expect(button).toHaveAttribute('aria-disabled', 'true');
63
61
  });
64
62
  });
65
63
  describe('enabled', () => {
66
- beforeEach(() => {
67
- wrapper = shallow(<ResumeButton {...props} />);
68
- });
69
- test('snapshot', () => {
70
- expect(wrapper.snapshot).toMatchSnapshot();
71
- });
72
64
  it('should be enabled', () => {
73
- expect(wrapper.instance.props.disabled).toEqual(false);
65
+ render(<IntlProvider locale="en"><ResumeButton {...props} /></IntlProvider>);
66
+ const button = screen.getByRole('button', { name: 'Resume' });
67
+ expect(button).toBeInTheDocument();
68
+ expect(button).not.toHaveClass('disabled');
69
+ expect(button).not.toHaveAttribute('aria-disabled', 'true');
74
70
  });
75
- it('should track enter course clicked event on click, with exec ed param', () => {
76
- expect(wrapper.instance.props.onClick).toEqual(reduxHooks.useTrackCourseEvent(
71
+ it('should track enter course clicked event on click, with exec ed param', async () => {
72
+ render(<IntlProvider locale="en"><ResumeButton {...props} /></IntlProvider>);
73
+ const user = userEvent.setup();
74
+ const button = screen.getByRole('button', { name: 'Resume' });
75
+ user.click(button);
76
+ expect(reduxHooks.useTrackCourseEvent).toHaveBeenCalledWith(
77
77
  track.course.enterCourseClicked,
78
78
  props.cardId,
79
79
  resumeUrl + execEdPath(props.cardId),
80
- ));
80
+ );
81
81
  });
82
82
  });
83
83
  });
@@ -1,34 +1,43 @@
1
- import { shallow } from '@edx/react-unit-test-utils';
1
+ import { render, screen } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { IntlProvider } from '@openedx/frontend-base';
2
4
 
3
- import { reduxHooks } from 'hooks';
5
+ import { reduxHooks } from '@src/hooks';
4
6
  import useActionDisabledState from '../hooks';
5
7
 
6
8
  import SelectSessionButton from './SelectSessionButton';
7
9
 
8
- jest.mock('hooks', () => ({
10
+ jest.mock('@src/hooks', () => ({
9
11
  reduxHooks: {
10
- useUpdateSelectSessionModalCallback: () => jest.fn().mockName('mockOpenSessionModal'),
12
+ useUpdateSelectSessionModalCallback: jest.fn(),
11
13
  },
12
14
  }));
13
15
  jest.mock('../hooks', () => jest.fn(() => ({ disableSelectSession: false })));
14
- jest.mock('./ActionButton', () => 'ActionButton');
15
16
 
16
- let wrapper;
17
+ jest.mock('./ActionButton/hooks', () => jest.fn(() => false));
17
18
 
18
19
  describe('SelectSessionButton', () => {
19
20
  const props = { cardId: 'cardId' };
20
21
  it('default render', () => {
21
- wrapper = shallow(<SelectSessionButton {...props} />);
22
- expect(wrapper.snapshot).toMatchSnapshot();
23
- expect(wrapper.instance.props.disabled).toEqual(false);
24
- expect(wrapper.instance.props.onClick.getMockName()).toEqual(
25
- reduxHooks.useUpdateSelectSessionModalCallback().getMockName(),
26
- );
22
+ render(<IntlProvider locale="en"><SelectSessionButton {...props} /></IntlProvider>);
23
+ const button = screen.getByRole('button', { name: 'Select Session' });
24
+ expect(button).toBeInTheDocument();
27
25
  });
28
- test('disabled states', () => {
29
- useActionDisabledState.mockReturnValueOnce({ disableSelectSession: true });
30
- wrapper = shallow(<SelectSessionButton {...props} />);
31
- expect(wrapper.snapshot).toMatchSnapshot();
32
- expect(wrapper.instance.props.disabled).toEqual(true);
26
+ describe('if useActionDisabledState is false', () => {
27
+ it('should disabled Select Session', () => {
28
+ useActionDisabledState.mockReturnValueOnce({ disableSelectSession: true });
29
+ render(<IntlProvider locale="en"><SelectSessionButton {...props} /></IntlProvider>);
30
+ const button = screen.getByRole('button', { name: 'Select Session' });
31
+ expect(button).toBeDisabled();
32
+ });
33
+ });
34
+ describe('on click', () => {
35
+ it('should call openSessionModal', async () => {
36
+ render(<IntlProvider locale="en"><SelectSessionButton {...props} /></IntlProvider>);
37
+ const user = userEvent.setup();
38
+ const button = screen.getByRole('button', { name: 'Select Session' });
39
+ await user.click(button);
40
+ expect(reduxHooks.useUpdateSelectSessionModalCallback).toHaveBeenCalledWith(props.cardId);
41
+ });
33
42
  });
34
43
  });
@@ -1,45 +1,55 @@
1
- import { shallow } from '@edx/react-unit-test-utils';
1
+ import { render, screen } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { IntlProvider } from '@openedx/frontend-base';
2
4
 
3
- import track from 'tracking';
4
- import { reduxHooks } from 'hooks';
5
+ import track from '@src/tracking';
6
+ import { reduxHooks } from '@src/hooks';
5
7
  import useActionDisabledState from '../hooks';
6
8
  import ViewCourseButton from './ViewCourseButton';
7
9
 
8
- jest.mock('tracking', () => ({
10
+ jest.mock('@src/tracking', () => ({
9
11
  course: {
10
12
  enterCourseClicked: jest.fn().mockName('segment.enterCourseClicked'),
11
13
  },
12
14
  }));
13
15
 
14
- jest.mock('hooks', () => ({
16
+ jest.mock('@src/hooks', () => ({
15
17
  reduxHooks: {
16
18
  useCardCourseRunData: jest.fn(() => ({ homeUrl: 'homeUrl' })),
17
- useTrackCourseEvent: jest.fn(
18
- (eventName, cardId, url) => ({ trackCourseEvent: { eventName, cardId, url } }),
19
- ),
19
+ useTrackCourseEvent: jest.fn(),
20
20
  },
21
21
  }));
22
22
  jest.mock('../hooks', () => jest.fn(() => ({ disableViewCourse: false })));
23
- jest.mock('./ActionButton', () => 'ActionButton');
23
+
24
+ jest.mock('./ActionButton/hooks', () => jest.fn(() => false));
24
25
 
25
26
  const defaultProps = { cardId: 'cardId' };
26
27
  const homeUrl = 'homeUrl';
27
28
 
28
29
  describe('ViewCourseButton', () => {
29
- test('learner can view course', () => {
30
- const wrapper = shallow(<ViewCourseButton {...defaultProps} />);
31
- expect(wrapper.snapshot).toMatchSnapshot();
32
- expect(wrapper.instance.props.onClick).toEqual(reduxHooks.useTrackCourseEvent(
30
+ it('learner can view course', async () => {
31
+ render(<IntlProvider locale="en"><ViewCourseButton {...defaultProps} /></IntlProvider>);
32
+ const button = screen.getByRole('button', { name: 'View Course' });
33
+ expect(button).toBeInTheDocument();
34
+ expect(button).not.toHaveClass('disabled');
35
+ expect(button).not.toHaveAttribute('aria-disabled', 'true');
36
+ });
37
+ it('calls trackCourseEvent on click', async () => {
38
+ render(<IntlProvider locale="en"><ViewCourseButton {...defaultProps} /></IntlProvider>);
39
+ const user = userEvent.setup();
40
+ const button = screen.getByRole('button', { name: 'View Course' });
41
+ await user.click(button);
42
+ expect(reduxHooks.useTrackCourseEvent).toHaveBeenCalledWith(
33
43
  track.course.enterCourseClicked,
34
44
  defaultProps.cardId,
35
45
  homeUrl,
36
- ));
37
- expect(wrapper.instance.props.disabled).toEqual(false);
46
+ );
38
47
  });
39
- test('learner cannot view course', () => {
48
+ it('learner cannot view course', () => {
40
49
  useActionDisabledState.mockReturnValueOnce({ disableViewCourse: true });
41
- const wrapper = shallow(<ViewCourseButton {...defaultProps} />);
42
- expect(wrapper.snapshot).toMatchSnapshot();
43
- expect(wrapper.instance.props.disabled).toEqual(true);
50
+ render(<IntlProvider locale="en"><ViewCourseButton {...defaultProps} /></IntlProvider>);
51
+ const button = screen.getByRole('button', { name: 'View Course' });
52
+ expect(button).toHaveClass('disabled');
53
+ expect(button).toHaveAttribute('aria-disabled', 'true');
44
54
  });
45
55
  });