@coorpacademy/app-review 0.1.15 → 0.1.16

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 (212) hide show
  1. package/es/actions/api/fetch-skills.d.ts +4 -6
  2. package/es/actions/api/fetch-skills.js +7 -4
  3. package/es/actions/api/fetch-slide.d.ts +14 -7
  4. package/es/actions/api/fetch-slide.js +22 -19
  5. package/es/actions/api/post-progression.d.ts +4 -6
  6. package/es/actions/api/post-progression.js +13 -8
  7. package/es/actions/api/test/create-test-store.d.ts +5 -0
  8. package/es/actions/api/test/create-test-store.js +16 -0
  9. package/es/actions/api/test/fetch-skills.test.js +54 -0
  10. package/es/actions/api/test/fetch-slide.test.js +61 -0
  11. package/es/actions/api/test/post-progression.test.d.ts +1 -0
  12. package/es/actions/api/test/post-progression.test.js +102 -0
  13. package/es/actions/ui/answers.d.ts +7 -0
  14. package/es/actions/ui/answers.js +7 -0
  15. package/es/fixtures/temp-fixture.d.ts +1 -1
  16. package/es/index.js +10 -16
  17. package/es/reducers/data/index.d.ts +1 -1
  18. package/es/reducers/data/slides.d.ts +2 -2
  19. package/es/reducers/data/slides.js +5 -1
  20. package/es/reducers/data/test/progression.test.d.ts +1 -0
  21. package/es/reducers/data/test/progression.test.js +38 -0
  22. package/es/reducers/data/test/skills.test.d.ts +1 -0
  23. package/es/reducers/data/test/skills.test.js +12 -0
  24. package/es/reducers/data/test/slides.test.d.ts +1 -0
  25. package/es/reducers/data/test/slides.test.js +20 -0
  26. package/es/reducers/data/test/token.test.d.ts +1 -0
  27. package/es/reducers/data/test/token.test.js +11 -0
  28. package/es/reducers/index.d.ts +2 -2
  29. package/es/reducers/ui/answers.d.ts +4 -0
  30. package/es/reducers/ui/answers.js +13 -0
  31. package/es/reducers/ui/index.d.ts +4 -4
  32. package/es/reducers/ui/index.js +2 -2
  33. package/es/reducers/ui/test/answers.test.d.ts +1 -0
  34. package/es/reducers/ui/test/answers.test.js +11 -0
  35. package/es/reducers/ui/test/current-slide-ref.test.d.ts +1 -0
  36. package/es/reducers/ui/test/current-slide-ref.test.js +12 -0
  37. package/es/reducers/ui/test/navigation.test.d.ts +1 -0
  38. package/es/reducers/ui/test/navigation.test.js +15 -0
  39. package/es/services/fetch-slide.js +1 -1
  40. package/es/services/index.js +3 -1
  41. package/es/services/post-answer.d.ts +2 -0
  42. package/es/services/post-answer.js +18 -0
  43. package/es/services/test/fetch-slide.test.d.ts +1 -0
  44. package/es/services/test/fetch-slide.test.js +22 -0
  45. package/es/services/test/post-answer.test.d.ts +1 -0
  46. package/es/services/test/post-answer.test.js +57 -0
  47. package/es/services/test/post-progression.test.js +9 -1
  48. package/es/test/util/services.mock.js +37 -7
  49. package/es/types/common.d.ts +22 -8
  50. package/es/views/slides/index.d.ts +78 -2
  51. package/es/views/slides/index.js +70 -4
  52. package/es/views/slides/map-api-slide-to-ui.d.ts +8 -0
  53. package/es/views/slides/map-api-slide-to-ui.js +172 -0
  54. package/{lib/helpers → es/views/slides}/test/fixtures/free-text.d.ts +1 -1
  55. package/es/views/slides/test/fixtures/free-text.js +38 -0
  56. package/es/{helpers → views/slides}/test/fixtures/qcm-drag.d.ts +1 -1
  57. package/es/views/slides/test/fixtures/qcm-drag.js +108 -0
  58. package/es/{helpers → views/slides}/test/fixtures/qcm-graphic.d.ts +1 -1
  59. package/es/views/slides/test/fixtures/qcm-graphic.js +88 -0
  60. package/es/{helpers → views/slides}/test/fixtures/qcm.d.ts +1 -1
  61. package/es/{helpers → views/slides}/test/fixtures/qcm.js +5 -1
  62. package/es/{helpers → views/slides}/test/fixtures/select-template.d.ts +1 -1
  63. package/es/views/slides/test/fixtures/select-template.js +92 -0
  64. package/es/{helpers → views/slides}/test/fixtures/slider.d.ts +1 -1
  65. package/es/views/slides/test/fixtures/slider.js +36 -0
  66. package/es/{helpers → views/slides}/test/fixtures/text-template.d.ts +1 -1
  67. package/es/{helpers → views/slides}/test/fixtures/text-template.js +5 -1
  68. package/es/views/slides/test/map-api-slide-to-ui.test.d.ts +1 -0
  69. package/es/{helpers → views/slides}/test/map-api-slide-to-ui.test.js +19 -9
  70. package/lib/actions/api/fetch-skills.d.ts +4 -6
  71. package/lib/actions/api/fetch-skills.js +55 -7
  72. package/lib/actions/api/fetch-slide.d.ts +14 -7
  73. package/lib/actions/api/fetch-slide.js +70 -20
  74. package/lib/actions/api/post-progression.d.ts +4 -6
  75. package/lib/actions/api/post-progression.js +63 -9
  76. package/lib/actions/api/test/create-test-store.d.ts +5 -0
  77. package/lib/actions/api/test/create-test-store.js +18 -0
  78. package/lib/actions/api/test/fetch-skills.test.d.ts +1 -0
  79. package/lib/actions/api/test/fetch-skills.test.js +113 -0
  80. package/lib/actions/api/test/fetch-slide.test.d.ts +1 -0
  81. package/lib/actions/api/test/fetch-slide.test.js +120 -0
  82. package/lib/actions/api/test/post-progression.test.d.ts +1 -0
  83. package/lib/actions/api/test/post-progression.test.js +160 -0
  84. package/lib/actions/ui/answers.d.ts +7 -0
  85. package/lib/actions/ui/answers.js +9 -0
  86. package/lib/fixtures/temp-fixture.d.ts +1 -1
  87. package/lib/index.js +21 -18
  88. package/lib/reducers/data/index.d.ts +1 -1
  89. package/lib/reducers/data/slides.d.ts +2 -2
  90. package/lib/reducers/data/slides.js +5 -1
  91. package/lib/reducers/data/test/progression.test.d.ts +1 -0
  92. package/lib/reducers/data/test/progression.test.js +38 -0
  93. package/lib/reducers/data/test/skills.test.d.ts +1 -0
  94. package/lib/reducers/data/test/skills.test.js +12 -0
  95. package/lib/reducers/data/test/slides.test.d.ts +1 -0
  96. package/lib/reducers/data/test/slides.test.js +20 -0
  97. package/lib/reducers/data/test/token.test.d.ts +1 -0
  98. package/lib/reducers/data/test/token.test.js +11 -0
  99. package/lib/reducers/index.d.ts +2 -2
  100. package/lib/reducers/ui/answers.d.ts +4 -0
  101. package/lib/reducers/ui/answers.js +14 -0
  102. package/lib/reducers/ui/index.d.ts +4 -4
  103. package/lib/reducers/ui/index.js +2 -2
  104. package/lib/reducers/ui/test/answers.test.d.ts +1 -0
  105. package/lib/reducers/ui/test/answers.test.js +11 -0
  106. package/lib/reducers/ui/test/current-slide-ref.test.d.ts +1 -0
  107. package/lib/reducers/ui/test/current-slide-ref.test.js +12 -0
  108. package/lib/reducers/ui/test/navigation.test.d.ts +1 -0
  109. package/lib/reducers/ui/test/navigation.test.js +15 -0
  110. package/lib/services/fetch-slide.js +1 -1
  111. package/lib/services/index.js +3 -1
  112. package/lib/services/post-answer.d.ts +2 -0
  113. package/lib/services/post-answer.js +62 -0
  114. package/lib/services/test/fetch-slide.test.d.ts +1 -0
  115. package/lib/services/test/fetch-slide.test.js +76 -0
  116. package/lib/services/test/post-answer.test.d.ts +1 -0
  117. package/lib/services/test/post-answer.test.js +111 -0
  118. package/lib/services/test/post-progression.test.js +9 -1
  119. package/lib/test/util/services.mock.js +37 -7
  120. package/lib/types/common.d.ts +22 -8
  121. package/lib/views/slides/index.d.ts +78 -2
  122. package/lib/views/slides/index.js +70 -4
  123. package/lib/views/slides/map-api-slide-to-ui.d.ts +8 -0
  124. package/lib/views/slides/map-api-slide-to-ui.js +178 -0
  125. package/{es/helpers → lib/views/slides}/test/fixtures/free-text.d.ts +1 -1
  126. package/lib/views/slides/test/fixtures/free-text.js +38 -0
  127. package/lib/{helpers → views/slides}/test/fixtures/qcm-drag.d.ts +1 -1
  128. package/lib/views/slides/test/fixtures/qcm-drag.js +108 -0
  129. package/lib/{helpers → views/slides}/test/fixtures/qcm-graphic.d.ts +1 -1
  130. package/lib/views/slides/test/fixtures/qcm-graphic.js +88 -0
  131. package/lib/{helpers → views/slides}/test/fixtures/qcm.d.ts +1 -1
  132. package/lib/{helpers → views/slides}/test/fixtures/qcm.js +5 -1
  133. package/lib/{helpers → views/slides}/test/fixtures/select-template.d.ts +1 -1
  134. package/lib/views/slides/test/fixtures/select-template.js +92 -0
  135. package/lib/{helpers → views/slides}/test/fixtures/slider.d.ts +1 -1
  136. package/lib/views/slides/test/fixtures/slider.js +36 -0
  137. package/lib/{helpers → views/slides}/test/fixtures/text-template.d.ts +1 -1
  138. package/lib/{helpers → views/slides}/test/fixtures/text-template.js +5 -1
  139. package/lib/views/slides/test/map-api-slide-to-ui.test.d.ts +1 -0
  140. package/lib/{helpers → views/slides}/test/map-api-slide-to-ui.test.js +19 -9
  141. package/package.json +3 -3
  142. package/src/actions/api/fetch-skills.ts +12 -12
  143. package/src/actions/api/fetch-slide.ts +33 -29
  144. package/src/actions/api/post-progression.ts +18 -21
  145. package/src/actions/api/test/create-test-store.ts +25 -0
  146. package/src/actions/api/test/fetch-skills.test.ts +70 -0
  147. package/src/actions/api/test/fetch-slide.test.ts +77 -0
  148. package/src/actions/api/test/post-progression.test.ts +119 -0
  149. package/src/actions/ui/answers.ts +16 -0
  150. package/src/fixtures/temp-fixture.ts +1 -1
  151. package/src/index.tsx +14 -29
  152. package/src/reducers/data/index.ts +1 -1
  153. package/src/reducers/data/slides.ts +11 -2
  154. package/src/reducers/data/test/progression.test.ts +42 -0
  155. package/src/reducers/data/test/skills.test.ts +14 -0
  156. package/src/reducers/data/test/slides.test.ts +26 -0
  157. package/src/reducers/data/test/token.test.ts +13 -0
  158. package/src/reducers/ui/answers.ts +19 -0
  159. package/src/reducers/ui/index.ts +3 -3
  160. package/src/reducers/ui/test/answers.test.ts +13 -0
  161. package/src/reducers/ui/test/current-slide-ref.test.ts +14 -0
  162. package/src/reducers/ui/test/navigation.test.ts +19 -0
  163. package/src/services/fetch-slide.ts +1 -1
  164. package/src/services/index.ts +3 -1
  165. package/src/services/post-answer.ts +27 -0
  166. package/src/services/test/fetch-slide.test.ts +30 -0
  167. package/src/services/test/post-answer.test.ts +68 -0
  168. package/src/services/test/post-progression.test.ts +9 -1
  169. package/src/test/util/services.mock.ts +37 -7
  170. package/src/types/common.ts +34 -14
  171. package/src/views/slides/index.ts +164 -5
  172. package/src/views/slides/map-api-slide-to-ui.ts +251 -0
  173. package/src/views/slides/test/fixtures/free-text.ts +43 -0
  174. package/src/views/slides/test/fixtures/qcm-drag.ts +111 -0
  175. package/src/views/slides/test/fixtures/qcm-graphic.ts +94 -0
  176. package/src/{helpers → views/slides}/test/fixtures/qcm.ts +6 -2
  177. package/src/views/slides/test/fixtures/select-template.ts +98 -0
  178. package/src/views/slides/test/fixtures/slider.ts +41 -0
  179. package/src/{helpers → views/slides}/test/fixtures/text-template.ts +6 -2
  180. package/src/{helpers → views/slides}/test/map-api-slide-to-ui.test.ts +21 -10
  181. package/es/helpers/map-api-slide-to-ui.d.ts +0 -11
  182. package/es/helpers/map-api-slide-to-ui.js +0 -193
  183. package/es/helpers/test/fixtures/free-text.js +0 -30
  184. package/es/helpers/test/fixtures/qcm-drag.js +0 -112
  185. package/es/helpers/test/fixtures/qcm-graphic.js +0 -76
  186. package/es/helpers/test/fixtures/select-template.js +0 -94
  187. package/es/helpers/test/fixtures/slider.js +0 -33
  188. package/es/reducers/ui/slides.d.ts +0 -9
  189. package/es/reducers/ui/slides.js +0 -42
  190. package/es/types/views/slides.d.ts +0 -74
  191. package/es/types/views/slides.js +0 -6
  192. package/lib/helpers/map-api-slide-to-ui.d.ts +0 -11
  193. package/lib/helpers/map-api-slide-to-ui.js +0 -201
  194. package/lib/helpers/test/fixtures/free-text.js +0 -30
  195. package/lib/helpers/test/fixtures/qcm-drag.js +0 -112
  196. package/lib/helpers/test/fixtures/qcm-graphic.js +0 -76
  197. package/lib/helpers/test/fixtures/select-template.js +0 -94
  198. package/lib/helpers/test/fixtures/slider.js +0 -33
  199. package/lib/reducers/ui/slides.d.ts +0 -9
  200. package/lib/reducers/ui/slides.js +0 -43
  201. package/lib/types/views/slides.d.ts +0 -74
  202. package/lib/types/views/slides.js +0 -6
  203. package/src/helpers/map-api-slide-to-ui.ts +0 -279
  204. package/src/helpers/test/fixtures/free-text.ts +0 -33
  205. package/src/helpers/test/fixtures/qcm-drag.ts +0 -115
  206. package/src/helpers/test/fixtures/qcm-graphic.ts +0 -79
  207. package/src/helpers/test/fixtures/select-template.ts +0 -97
  208. package/src/helpers/test/fixtures/slider.ts +0 -36
  209. package/src/reducers/ui/slides.ts +0 -58
  210. package/src/types/views/slides.ts +0 -90
  211. /package/es/{helpers/test/map-api-slide-to-ui.test.d.ts → actions/api/test/fetch-skills.test.d.ts} +0 -0
  212. /package/{lib/helpers/test/map-api-slide-to-ui.test.d.ts → es/actions/api/test/fetch-slide.test.d.ts} +0 -0
@@ -10,6 +10,7 @@ var __assign = (this && this.__assign) || function () {
10
10
  return __assign.apply(this, arguments);
11
11
  };
12
12
  import test from 'ava';
13
+ import identity from 'lodash/fp/identity';
13
14
  import { mapApiSlideToUi } from '../map-api-slide-to-ui';
14
15
  import { qcmUISlide, qcmSlide } from './fixtures/qcm';
15
16
  import { qcmDragUISlide, qcmDragSlide } from './fixtures/qcm-drag';
@@ -18,26 +19,35 @@ import { qcmGraphicUISlide, qcmGraphicSlide } from './fixtures/qcm-graphic';
18
19
  import { textTemplateSlide, textTemplateUISlide } from './fixtures/text-template';
19
20
  import { selectTemplateSlide, selectTemplateUISlide } from './fixtures/select-template';
20
21
  import { sliderSlide, sliderUISlide } from './fixtures/slider';
21
- var _mapApiSlideToUi = mapApiSlideToUi({ translate: function (text) { return text; } });
22
+ var _mapApiSlideToUi = mapApiSlideToUi(identity);
22
23
  var macro = test.macro({
23
24
  title: function (providedTitle) {
24
25
  return "should handle ".concat(providedTitle, " conversion").trim();
25
26
  },
26
27
  exec: function (t, arg) {
27
- t.deepEqual(JSON.parse(JSON.stringify(_mapApiSlideToUi(arg.slide))), JSON.parse(JSON.stringify(arg.expectedUiSlide)));
28
+ t.deepEqual(JSON.parse(JSON.stringify(_mapApiSlideToUi(arg.slide, arg.answers))), JSON.parse(JSON.stringify(arg.expectedUiSlide)));
28
29
  }
29
30
  });
30
- test('qcm', macro, { slide: qcmSlide, expectedUiSlide: qcmUISlide });
31
- test('qcm drag', macro, { slide: qcmDragSlide, expectedUiSlide: qcmDragUISlide });
32
- test('qcm graphic', macro, { slide: qcmGraphicSlide, expectedUiSlide: qcmGraphicUISlide });
33
- test('text template', macro, { slide: textTemplateSlide, expectedUiSlide: textTemplateUISlide });
31
+ test('qcm', macro, { slide: qcmSlide, answers: [], expectedUiSlide: qcmUISlide });
32
+ test('qcm drag', macro, { slide: qcmDragSlide, answers: [], expectedUiSlide: qcmDragUISlide });
33
+ test('qcm graphic', macro, {
34
+ slide: qcmGraphicSlide,
35
+ answers: [],
36
+ expectedUiSlide: qcmGraphicUISlide
37
+ });
38
+ test('text template', macro, {
39
+ slide: textTemplateSlide,
40
+ answers: [],
41
+ expectedUiSlide: textTemplateUISlide
42
+ });
34
43
  test('select template', macro, {
35
44
  slide: selectTemplateSlide,
45
+ answers: [],
36
46
  expectedUiSlide: selectTemplateUISlide
37
47
  });
38
- test('free text', macro, { slide: freeTextSlide, expectedUiSlide: freeTextUISlide });
39
- test('slider', macro, { slide: sliderSlide, expectedUiSlide: sliderUISlide });
48
+ test('free text', macro, { slide: freeTextSlide, answers: [], expectedUiSlide: freeTextUISlide });
49
+ test('slider', macro, { slide: sliderSlide, answers: [], expectedUiSlide: sliderUISlide });
40
50
  test('should throw an error if the question type can not be handled', function (t) {
41
51
  var faultySlide = __assign(__assign({}, qcmSlide), { question: { type: 'lol' } });
42
- t.throws(function () { return _mapApiSlideToUi(faultySlide); });
52
+ t.throws(function () { return _mapApiSlideToUi(faultySlide, []); });
43
53
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coorpacademy/app-review",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "",
5
5
  "engines": {
6
6
  "node": ">=16.15.0"
@@ -40,7 +40,7 @@
40
40
  "./package.json": "./package.json"
41
41
  },
42
42
  "dependencies": {
43
- "@coorpacademy/components": "10.22.9",
43
+ "@coorpacademy/components": "10.22.10",
44
44
  "@coorpacademy/redux-task": "^1.1.5",
45
45
  "cross-fetch": "^3.1.5",
46
46
  "jwt-decode": "^3.1.2",
@@ -77,5 +77,5 @@
77
77
  "ts-node": "^10.8.1",
78
78
  "typescript": "^4.7.4"
79
79
  },
80
- "gitHead": "0f66b53a129b22c69cb3db1f3ae3993903cd8df3"
80
+ "gitHead": "508e3fdb30d727840bd9b13e9402c2970eb17731"
81
81
  }
@@ -1,6 +1,5 @@
1
1
  import buildTask from '@coorpacademy/redux-task';
2
- import type {ThunkAction, ThunkDispatch} from 'redux-thunk';
3
- import {AnyAction} from 'redux';
2
+ import {Dispatch} from 'redux';
4
3
  import type {StoreState} from '../../reducers';
5
4
  import {Options, Skill} from '../../types/common';
6
5
 
@@ -8,17 +7,18 @@ export const SKILLS_FETCH_REQUEST = '@@skills/FETCH_REQUEST' as const;
8
7
  export const SKILLS_FETCH_SUCCESS = '@@skills/FETCH_SUCCESS' as const;
9
8
  export const SKILLS_FETCH_FAILURE = '@@skills/FETCH_FAILURE' as const;
10
9
 
11
- export interface ReceivedSkills extends AnyAction {
10
+ export type ReceivedSkills = {
12
11
  type: '@@skills/FETCH_SUCCESS';
13
12
  payload: Skill[];
14
- }
13
+ };
15
14
 
16
- export type FetchSkillsAction = ThunkAction<Promise<void>, StoreState, Options, AnyAction>;
17
- type Dispatch = ThunkDispatch<StoreState, Options, AnyAction>;
15
+ export const fetchSkills =
16
+ (token: string) =>
17
+ async (dispatch: Dispatch, getState: () => StoreState, {services}: Options): Promise<void> => {
18
+ const action = buildTask({
19
+ types: [SKILLS_FETCH_REQUEST, SKILLS_FETCH_SUCCESS, SKILLS_FETCH_FAILURE],
20
+ task: () => services.fetchSkills(token)
21
+ });
18
22
 
19
- export const fetchSkills = (token: string): FetchSkillsAction =>
20
- buildTask({
21
- types: [SKILLS_FETCH_REQUEST, SKILLS_FETCH_SUCCESS, SKILLS_FETCH_FAILURE],
22
- task: (dispatch: Dispatch, getState: () => StoreState, {services}: Options) =>
23
- services.fetchSkills(token)
24
- });
23
+ await dispatch(action);
24
+ };
@@ -1,45 +1,49 @@
1
- import type {AnyAction} from 'redux';
2
- import type {ThunkAction, ThunkDispatch} from 'redux-thunk';
1
+ import type {Dispatch} from 'redux';
3
2
  import buildTask from '@coorpacademy/redux-task';
4
3
  import get from 'lodash/fp/get';
5
4
  import has from 'lodash/fp/has';
6
5
  import isEmpty from 'lodash/fp/isEmpty';
7
6
  import type {StoreState} from '../../reducers';
8
- import type {Options, ProgressionFromAPI, SlideFromAPI} from '../../types/common';
7
+ import type {Options, SlideFromAPI} from '../../types/common';
9
8
  import {setCurrentSlide} from '../ui/slides';
10
9
 
11
10
  export const SLIDE_FETCH_REQUEST = '@@slides/FETCH_REQUEST' as const;
12
11
  export const SLIDE_FETCH_SUCCESS = '@@slides/FETCH_SUCCESS' as const;
13
12
  export const SLIDE_FETCH_FAILURE = '@@slides/FETCH_FAILURE' as const;
14
13
 
15
- export interface ReceivedSlide extends AnyAction {
14
+ export type FetchSlide = {
15
+ type: typeof SLIDE_FETCH_REQUEST;
16
+ meta: {slideRef: string};
17
+ };
18
+
19
+ export type ReceivedSlide = {
16
20
  type: typeof SLIDE_FETCH_SUCCESS;
17
21
  payload: SlideFromAPI;
18
- }
22
+ meta: {slideRef: string};
23
+ };
19
24
 
20
- export type FetchSlideAction = ThunkAction<Promise<SlideFromAPI>, StoreState, Options, AnyAction>;
21
- type Dispatch = ThunkDispatch<StoreState, Options, AnyAction>;
25
+ export const fetchSlide =
26
+ (slideRef: string, token: string) =>
27
+ async (dispatch: Dispatch, getState: () => StoreState, {services}: Options): Promise<void> => {
28
+ const action = buildTask({
29
+ types: [SLIDE_FETCH_REQUEST, SLIDE_FETCH_SUCCESS, SLIDE_FETCH_FAILURE],
30
+ bailout: (state: StoreState): boolean => {
31
+ return has(`data.slide.${slideRef}`, state);
32
+ },
33
+ task: () => {
34
+ return services.fetchSlide(slideRef, token);
35
+ },
36
+ meta: {slideRef}
37
+ });
38
+ const response = await dispatch(action);
22
39
 
23
- export const fetchSlide = (
24
- progressionFromAPI: ProgressionFromAPI,
25
- token: string
26
- ): FetchSlideAction =>
27
- buildTask({
28
- types: [SLIDE_FETCH_REQUEST, SLIDE_FETCH_SUCCESS, SLIDE_FETCH_FAILURE],
29
- bailout: (state: StoreState): boolean => {
30
- const {ref: slideRef} = get('state.nextContent', progressionFromAPI);
31
- return has(`data.slide.${slideRef}`, state);
32
- },
33
- task: (dispatch: Dispatch, getState: () => StoreState, {services}: Options) => {
34
- const {ref: slideRef} = get('state.nextContent', progressionFromAPI);
35
- return services.fetchSlide(slideRef, token).then((slideFromAPI: SlideFromAPI | void) => {
36
- if (!slideFromAPI) throw new Error('Slide not found');
37
- const state = getState();
38
- const slides = get('data.progression.state.slides', state);
39
- if (isEmpty(slides)) {
40
- dispatch(setCurrentSlide(slideFromAPI));
41
- }
42
- return slideFromAPI;
43
- });
40
+ if (response.type === SLIDE_FETCH_SUCCESS) {
41
+ const slideFromAPI = response.payload;
42
+ if (!slideFromAPI) throw new Error('Slide not found');
43
+ const state = getState();
44
+ const slides = get('data.progression.state.slides', state);
45
+ if (isEmpty(slides)) {
46
+ dispatch(setCurrentSlide(slideFromAPI));
47
+ }
44
48
  }
45
- });
49
+ };
@@ -1,5 +1,4 @@
1
- import type {AnyAction} from 'redux';
2
- import type {ThunkAction, ThunkDispatch} from 'redux-thunk';
1
+ import type {Dispatch} from 'redux';
3
2
  import buildTask from '@coorpacademy/redux-task';
4
3
  import {Options, ProgressionFromAPI} from '../../types/common';
5
4
  import type {StoreState} from '../../reducers';
@@ -9,27 +8,25 @@ export const POST_PROGRESSION_REQUEST = '@@progression/POST_REQUEST' as const;
9
8
  export const POST_PROGRESSION_SUCCESS = '@@progression/POST_SUCCESS' as const;
10
9
  export const POST_PROGRESSION_FAILURE = '@@progression/POST_FAILURE' as const;
11
10
 
12
- export interface ReceiveProgression extends AnyAction {
11
+ export type ReceiveProgression = {
13
12
  type: typeof POST_PROGRESSION_SUCCESS;
14
13
  payload: ProgressionFromAPI;
15
- }
14
+ };
16
15
 
17
- export type PostProgressionAction = ThunkAction<
18
- Promise<ProgressionFromAPI>,
19
- StoreState,
20
- Options,
21
- AnyAction
22
- >;
16
+ export const postProgression =
17
+ (skillRef: string, token: string) =>
18
+ async (dispatch: Dispatch, getState: () => StoreState, {services}: Options): Promise<void> => {
19
+ const action = buildTask({
20
+ types: [POST_PROGRESSION_REQUEST, POST_PROGRESSION_SUCCESS, POST_PROGRESSION_FAILURE],
21
+ task: () => {
22
+ return services.postProgression(skillRef, token);
23
+ }
24
+ });
25
+ const response = await dispatch(action);
23
26
 
24
- type Dispatch = ThunkDispatch<StoreState, Options, AnyAction>;
25
-
26
- export const postProgression = (skillRef: string, token: string): PostProgressionAction =>
27
- buildTask({
28
- types: [POST_PROGRESSION_REQUEST, POST_PROGRESSION_SUCCESS, POST_PROGRESSION_FAILURE],
29
- task: (dispatch: Dispatch, getState: () => StoreState, {services}: Options) => {
30
- return services.postProgression(skillRef, token).then((progression: ProgressionFromAPI) => {
31
- dispatch(fetchSlide(progression, token));
32
- return progression;
33
- });
27
+ if (response.type === POST_PROGRESSION_SUCCESS) {
28
+ const progression = response.payload;
29
+ const slideRef = progression.state.nextContent.ref;
30
+ await dispatch(fetchSlide(slideRef, token));
34
31
  }
35
- });
32
+ };
@@ -0,0 +1,25 @@
1
+ import type {ExecutionContext} from 'ava';
2
+ import constant from 'lodash/fp/constant';
3
+ import {AnyAction, applyMiddleware, compose, createStore, Dispatch, Middleware, Store} from 'redux';
4
+ import thunk from 'redux-thunk';
5
+ import rootReducer, {StoreState} from '../../../reducers';
6
+ import {Services} from '../../../types/common';
7
+
8
+ const assertActionsMiddleware = (t: ExecutionContext, ACTIONS: AnyAction[]): Middleware =>
9
+ constant((next: Dispatch) => (action: AnyAction): unknown => {
10
+ const expectedAction = ACTIONS.shift();
11
+ if (!expectedAction) throw new Error(`Missing {type: "${action.type}"} action`);
12
+ t.deepEqual(action, expectedAction);
13
+ return next(action);
14
+ });
15
+
16
+ export const createTestStore = (
17
+ t: ExecutionContext,
18
+ initialState: StoreState,
19
+ services: Services,
20
+ actions: AnyAction[]
21
+ ): Store => {
22
+ const thunkMiddleware = thunk.withExtraArgument({services});
23
+ const enhancer = compose(applyMiddleware(thunkMiddleware, assertActionsMiddleware(t, actions)));
24
+ return createStore(rootReducer, initialState, enhancer);
25
+ };
@@ -0,0 +1,70 @@
1
+ import test from 'ava';
2
+ import {Services} from '../../../types/common';
3
+ import {
4
+ fetchSkills,
5
+ SKILLS_FETCH_FAILURE,
6
+ SKILLS_FETCH_REQUEST,
7
+ SKILLS_FETCH_SUCCESS
8
+ } from '../fetch-skills';
9
+ import {services as mockedServices} from '../../../test/util/services.mock';
10
+ import {StoreState} from '../../../reducers';
11
+ import {createTestStore} from './create-test-store';
12
+
13
+ const initialState: StoreState = {
14
+ data: {
15
+ progression: null,
16
+ slides: {},
17
+ skills: [],
18
+ token: '1234'
19
+ },
20
+ ui: {
21
+ currentSlideRef: '',
22
+ navigation: [],
23
+ answers: []
24
+ }
25
+ };
26
+
27
+ test('should dispatch SKILLS_FETCH_SUCCESS actions when fetchSkills return a list of skills', async t => {
28
+ const services: Services = {
29
+ ...mockedServices,
30
+ fetchSkills: token => {
31
+ t.is(token, '1234');
32
+ return Promise.resolve([]);
33
+ }
34
+ };
35
+
36
+ const expectedActions = [
37
+ {type: SKILLS_FETCH_REQUEST},
38
+ {
39
+ type: SKILLS_FETCH_SUCCESS,
40
+ payload: []
41
+ }
42
+ ];
43
+
44
+ const {dispatch} = createTestStore(t, initialState, services, expectedActions);
45
+
46
+ await dispatch(fetchSkills('1234'));
47
+ });
48
+
49
+ test('should dispatch SKILLS_FETCH_FAILURE action when fetchSkills fails', async t => {
50
+ const services: Services = {
51
+ ...mockedServices,
52
+ fetchSkills: token => {
53
+ t.is(token, '1234');
54
+ return Promise.reject(new Error('unexpected'));
55
+ }
56
+ };
57
+
58
+ const expectedActions = [
59
+ {type: SKILLS_FETCH_REQUEST},
60
+ {
61
+ type: SKILLS_FETCH_FAILURE,
62
+ payload: new Error('unexpected'),
63
+ error: true
64
+ }
65
+ ];
66
+
67
+ const {dispatch} = createTestStore(t, initialState, services, expectedActions);
68
+
69
+ await dispatch(fetchSkills('1234'));
70
+ });
@@ -0,0 +1,77 @@
1
+ import test from 'ava';
2
+ import {Services} from '../../../types/common';
3
+ import {
4
+ fetchSlide,
5
+ SLIDE_FETCH_FAILURE,
6
+ SLIDE_FETCH_REQUEST,
7
+ SLIDE_FETCH_SUCCESS
8
+ } from '../fetch-slide';
9
+ import {freeTextSlide} from '../../../views/slides/test/fixtures/free-text';
10
+ import {services as mockedServices} from '../../../test/util/services.mock';
11
+ import {StoreState} from '../../../reducers';
12
+ import {SET_CURRENT_SLIDE} from '../../ui/slides';
13
+ import {createTestStore} from './create-test-store';
14
+
15
+ const initialState: StoreState = {
16
+ data: {
17
+ progression: null,
18
+ slides: {},
19
+ skills: [],
20
+ token: '1234'
21
+ },
22
+ ui: {
23
+ currentSlideRef: '',
24
+ navigation: [],
25
+ answers: []
26
+ }
27
+ };
28
+
29
+ test('should dispatch FETCH_SUCCESS and SET_CURRENT_SLIDE actions when fetchSlide return a slide', async t => {
30
+ const services: Services = {
31
+ ...mockedServices,
32
+ fetchSlide: (slideRef, token) => {
33
+ t.is(token, '1234');
34
+ t.is(slideRef, 'sli_VJYjJnJhg');
35
+ return Promise.resolve(freeTextSlide);
36
+ }
37
+ };
38
+
39
+ const expectedActions = [
40
+ {type: SLIDE_FETCH_REQUEST, meta: {slideRef: 'sli_VJYjJnJhg'}},
41
+ {
42
+ type: SLIDE_FETCH_SUCCESS,
43
+ meta: {slideRef: 'sli_VJYjJnJhg'},
44
+ payload: freeTextSlide
45
+ },
46
+ {type: SET_CURRENT_SLIDE, payload: freeTextSlide}
47
+ ];
48
+
49
+ const {dispatch} = createTestStore(t, initialState, services, expectedActions);
50
+
51
+ await dispatch(fetchSlide('sli_VJYjJnJhg', '1234'));
52
+ });
53
+
54
+ test('should dispatch SLIDE_FETCH_FAILURE action when fetchSlide fails', async t => {
55
+ const services: Services = {
56
+ ...mockedServices,
57
+ fetchSlide: (slideRef, token) => {
58
+ t.is(token, '1234');
59
+ t.is(slideRef, 'slide_ref');
60
+ return Promise.reject(new Error('error'));
61
+ }
62
+ };
63
+
64
+ const expectedActions = [
65
+ {type: SLIDE_FETCH_REQUEST, meta: {slideRef: 'slide_ref'}},
66
+ {
67
+ type: SLIDE_FETCH_FAILURE,
68
+ meta: {slideRef: 'slide_ref'},
69
+ payload: new Error('error'),
70
+ error: true
71
+ }
72
+ ];
73
+
74
+ const {dispatch} = createTestStore(t, initialState, services, expectedActions);
75
+
76
+ await dispatch(fetchSlide('slide_ref', '1234'));
77
+ });
@@ -0,0 +1,119 @@
1
+ import test from 'ava';
2
+ import {ProgressionFromAPI, Services} from '../../../types/common';
3
+ import {
4
+ postProgression,
5
+ POST_PROGRESSION_REQUEST,
6
+ POST_PROGRESSION_SUCCESS,
7
+ POST_PROGRESSION_FAILURE
8
+ } from '../post-progression';
9
+ import {freeTextSlide} from '../../../views/slides/test/fixtures/free-text';
10
+ import {services as mockedServices} from '../../../test/util/services.mock';
11
+ import {StoreState} from '../../../reducers';
12
+ import {SLIDE_FETCH_REQUEST, SLIDE_FETCH_SUCCESS} from '../fetch-slide';
13
+ import {SET_CURRENT_SLIDE} from '../../ui/slides';
14
+ import {createTestStore} from './create-test-store';
15
+
16
+ const initialState: StoreState = {
17
+ data: {
18
+ progression: null,
19
+ slides: {},
20
+ skills: [],
21
+ token: '1234'
22
+ },
23
+ ui: {
24
+ currentSlideRef: '',
25
+ navigation: [],
26
+ answers: []
27
+ }
28
+ };
29
+
30
+ test('should dispatch POST_PROGRESSION_SUCCESS and SLIDE_FETCH_REQUEST actions when postProgression return a progression', async t => {
31
+ const progression: ProgressionFromAPI = {
32
+ _id: '62b1d1087aa12f00253f40ee',
33
+ content: {
34
+ ref: '_skill-ref',
35
+ type: 'skill'
36
+ },
37
+ engine: {
38
+ ref: 'review'
39
+ },
40
+ state: {
41
+ allAnswers: [],
42
+ isCorrect: true,
43
+ nextContent: {
44
+ ref: 'sli_VJYjJnJhg',
45
+ type: 'slide'
46
+ },
47
+ pendingSlides: [],
48
+ slides: [],
49
+ step: {
50
+ current: 1
51
+ },
52
+ stars: 0
53
+ }
54
+ };
55
+
56
+ const services: Services = {
57
+ ...mockedServices,
58
+ postProgression: (skillRef, token) => {
59
+ t.is(token, '1234');
60
+ t.is(skillRef, 'skill_12345');
61
+ return Promise.resolve(progression);
62
+ },
63
+ fetchSlide: (slideRef, token) => {
64
+ t.is(token, '1234');
65
+ t.is(slideRef, 'sli_VJYjJnJhg');
66
+ return Promise.resolve(freeTextSlide);
67
+ }
68
+ };
69
+
70
+ const expectedActions = [
71
+ {type: POST_PROGRESSION_REQUEST},
72
+ {
73
+ type: POST_PROGRESSION_SUCCESS,
74
+ payload: progression
75
+ },
76
+ {
77
+ type: SLIDE_FETCH_REQUEST,
78
+ meta: {
79
+ slideRef: 'sli_VJYjJnJhg'
80
+ }
81
+ },
82
+ {
83
+ type: SLIDE_FETCH_SUCCESS,
84
+ meta: {
85
+ slideRef: 'sli_VJYjJnJhg'
86
+ },
87
+ payload: freeTextSlide
88
+ },
89
+ {type: SET_CURRENT_SLIDE, payload: freeTextSlide}
90
+ ];
91
+
92
+ const {dispatch} = createTestStore(t, initialState, services, expectedActions);
93
+
94
+ await dispatch(postProgression('skill_12345', '1234'));
95
+ });
96
+
97
+ test('should dispatch POST_PROGRESSION_FAILURE action when postProgression fails', async t => {
98
+ const services: Services = {
99
+ ...mockedServices,
100
+ postProgression: (skillRef, token) => {
101
+ t.is(token, '1234');
102
+ t.is(skillRef, 'skill_12345');
103
+ return Promise.reject(new Error('error'));
104
+ }
105
+ };
106
+
107
+ const expectedActions = [
108
+ {type: POST_PROGRESSION_REQUEST},
109
+ {
110
+ type: POST_PROGRESSION_FAILURE,
111
+ payload: new Error('error'),
112
+ error: true
113
+ }
114
+ ];
115
+
116
+ const {dispatch} = createTestStore(t, initialState, services, expectedActions);
117
+
118
+ await dispatch(postProgression('skill_12345', '1234'));
119
+ });
@@ -0,0 +1,16 @@
1
+ import {Dispatch} from 'redux';
2
+
3
+ export const EDIT_BASIC = '@@answer/EDIT_BASIC' as const;
4
+ export type EditBasicAction = {
5
+ type: typeof EDIT_BASIC;
6
+ payload: string[];
7
+ };
8
+
9
+ export const editAnswer =
10
+ (answer: string) =>
11
+ (dispatch: Dispatch): EditBasicAction => {
12
+ return dispatch({
13
+ type: EDIT_BASIC,
14
+ payload: [answer]
15
+ });
16
+ };
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable no-console */
2
- import {SlidesViewProps, CorrectionPopinProps} from '../types/views/slides';
2
+ import {SlidesViewProps, CorrectionPopinProps} from '../views/slides';
3
3
 
4
4
  export const correctionPopinProps: CorrectionPopinProps = {
5
5
  klf: {
package/src/index.tsx CHANGED
@@ -1,7 +1,7 @@
1
1
  import React, {useEffect, useState} from 'react';
2
2
  import type {} from 'redux-thunk/extend-redux'; // https://github.com/reduxjs/redux-thunk/issues/333
3
3
  import {AnyAction, Store} from 'redux';
4
- import {connect, Provider} from 'react-redux';
4
+ import {useSelector, useDispatch, Provider} from 'react-redux';
5
5
  import AppReviewTemplate from '@coorpacademy/components/es/template/app-review';
6
6
  import {TemplateContext} from '@coorpacademy/components/es/template/app-review/template-context';
7
7
 
@@ -11,43 +11,28 @@ import configureStore from './configure-store';
11
11
 
12
12
  import type {AppOptions} from './types/common';
13
13
  import type {StoreState} from './reducers';
14
- import type {SlidesViewStaticProps} from './types/views/slides';
15
14
 
16
- import {Dispatchers} from './actions';
17
- import {validateSlide} from './actions/ui/slides';
18
-
19
- import {navigateTo, navigateBack, ViewPath} from './actions/ui/navigation';
15
+ import {navigateTo, ViewPath} from './actions/ui/navigation';
20
16
  import {storeToken} from './actions/data/token';
21
17
  import {fetchSkills} from './actions/api/fetch-skills';
22
18
  import {postProgression} from './actions/api/post-progression';
23
19
  import {VIEWS} from './common';
24
20
  import {mapStateToSlidesProps} from './views/slides';
25
- import {mapStateToSkillsProps, SkillsProps} from './views/skills';
26
-
27
- type StaticProps = {
28
- viewName: 'skills' | 'onboarding' | 'slides' | 'loader';
29
- slides: SlidesViewStaticProps | null;
30
- skills: SkillsProps | null;
31
- };
21
+ import {mapStateToSkillsProps} from './views/skills';
32
22
 
33
- const mapDispatchToProps: Dispatchers = {
34
- navigateTo,
35
- navigateBack,
36
- validateSlide
37
- };
23
+ const ConnectedApp = (): JSX.Element => {
24
+ const dispatch = useDispatch();
38
25
 
39
- const getCurrentViewName = (storeState: StoreState): ViewPath =>
40
- storeState.ui.navigation[storeState.ui.navigation.length - 1];
41
-
42
- const mapStateToProps = (state: StoreState): StaticProps => {
43
- return {
44
- viewName: getCurrentViewName(state),
45
- slides: mapStateToSlidesProps(state),
46
- skills: mapStateToSkillsProps(state)
26
+ const props = {
27
+ viewName: useSelector(
28
+ (state: StoreState) => state.ui.navigation[state.ui.navigation.length - 1]
29
+ ),
30
+ slides: useSelector((state: StoreState) => mapStateToSlidesProps(state, dispatch)),
31
+ skills: useSelector((state: StoreState) => mapStateToSkillsProps(state))
47
32
  };
48
- };
49
33
 
50
- const App = connect(mapStateToProps, mapDispatchToProps)(AppReviewTemplate);
34
+ return <AppReviewTemplate {...props} />;
35
+ };
51
36
 
52
37
  const AppReview = ({options}: {options: AppOptions}): JSX.Element | null => {
53
38
  const [store, setStore] = useState<Store<StoreState, AnyAction> | null>(null);
@@ -109,7 +94,7 @@ const AppReview = ({options}: {options: AppOptions}): JSX.Element | null => {
109
94
  return (
110
95
  <Provider store={store}>
111
96
  <TemplateContext values={values}>
112
- <App />
97
+ <ConnectedApp />
113
98
  </TemplateContext>
114
99
  </Provider>
115
100
  );
@@ -7,7 +7,7 @@ import token, {TokenState} from './token';
7
7
 
8
8
  export type DataState = {
9
9
  isFetching?: boolean;
10
- progression?: ProgressionState;
10
+ progression: ProgressionState;
11
11
  skills: SkillsState;
12
12
  slides: SlidesState;
13
13
  token?: TokenState;