@coorpacademy/app-review 0.1.16 → 0.1.18

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 (196) hide show
  1. package/es/actions/api/fetch-skills.d.ts +3 -3
  2. package/es/actions/api/fetch-skills.js +7 -2
  3. package/es/actions/api/fetch-slide.d.ts +1 -1
  4. package/es/actions/api/fetch-slide.js +3 -1
  5. package/es/actions/api/post-answer.d.ts +14 -0
  6. package/es/actions/api/post-answer.js +25 -0
  7. package/es/actions/api/post-progression.d.ts +3 -3
  8. package/es/actions/api/post-progression.js +5 -2
  9. package/es/actions/api/test/fetch-skills.test.js +7 -4
  10. package/es/actions/api/test/fetch-slide.test.js +7 -4
  11. package/es/actions/api/test/post-answer.test.d.ts +1 -0
  12. package/es/actions/api/test/post-answer.test.js +82 -0
  13. package/es/actions/api/test/post-progression.test.js +7 -4
  14. package/es/actions/data/test/token.test.d.ts +1 -0
  15. package/es/actions/data/test/token.test.js +25 -0
  16. package/es/actions/index.d.ts +1 -8
  17. package/es/actions/{api/test → test}/create-test-store.d.ts +2 -2
  18. package/es/actions/{api/test → test}/create-test-store.js +1 -1
  19. package/es/actions/ui/answers.d.ts +17 -3
  20. package/es/actions/ui/answers.js +41 -3
  21. package/es/actions/ui/slides.d.ts +0 -5
  22. package/es/actions/ui/slides.js +0 -4
  23. package/es/actions/ui/test/answers.test.d.ts +1 -0
  24. package/es/actions/ui/test/answers.test.js +100 -0
  25. package/es/actions/ui/test/slides.test.d.ts +1 -0
  26. package/es/actions/ui/test/slides.test.js +26 -0
  27. package/es/common/index.d.ts +0 -3
  28. package/es/common/index.js +0 -4
  29. package/es/index.js +1 -3
  30. package/es/reducers/data/index.d.ts +1 -1
  31. package/es/reducers/data/progression.d.ts +3 -3
  32. package/es/reducers/data/progression.js +2 -5
  33. package/es/reducers/data/slides.d.ts +2 -3
  34. package/es/reducers/data/test/progression.test.js +12 -27
  35. package/es/reducers/index.d.ts +2 -1
  36. package/es/reducers/ui/answers.d.ts +2 -2
  37. package/es/reducers/ui/answers.js +4 -8
  38. package/es/reducers/ui/index.d.ts +4 -1
  39. package/es/reducers/ui/index.js +3 -1
  40. package/es/reducers/ui/slide.d.ts +8 -0
  41. package/es/reducers/ui/slide.js +26 -0
  42. package/es/reducers/ui/test/answers.test.js +23 -3
  43. package/es/reducers/ui/test/current-slide-ref.test.js +1 -1
  44. package/es/reducers/ui/test/navigation.test.js +5 -5
  45. package/es/reducers/ui/test/slide.test.d.ts +1 -0
  46. package/es/reducers/ui/test/slide.test.js +12 -0
  47. package/es/test/util/services.mock.d.ts +3 -1
  48. package/es/test/util/services.mock.js +89 -72
  49. package/es/types/common.d.ts +0 -25
  50. package/es/views/skills/index.d.ts +1 -1
  51. package/es/views/skills/index.js +0 -3
  52. package/es/views/skills/test/skills.test.d.ts +1 -0
  53. package/es/views/skills/test/skills.test.js +94 -0
  54. package/es/views/slides/index.d.ts +13 -2
  55. package/es/views/slides/index.js +19 -15
  56. package/es/views/slides/map-api-slide-to-ui.js +65 -68
  57. package/es/views/slides/test/fixtures/free-text.d.ts +2 -1
  58. package/es/views/slides/test/fixtures/qcm-drag.d.ts +2 -1
  59. package/es/views/slides/test/fixtures/qcm-graphic.d.ts +2 -1
  60. package/es/views/slides/test/fixtures/qcm.d.ts +2 -1
  61. package/es/views/slides/test/fixtures/slider.d.ts +2 -1
  62. package/es/views/slides/test/fixtures/template.d.ts +4 -0
  63. package/{lib/views/slides/test/fixtures/select-template.js → es/views/slides/test/fixtures/template.js} +82 -4
  64. package/es/views/slides/test/index.test.d.ts +1 -0
  65. package/es/views/slides/test/index.test.js +473 -0
  66. package/es/views/slides/test/map-api-slide-to-ui.test.js +4 -10
  67. package/es/views/slides/test/slide.template.on-change.test.d.ts +1 -0
  68. package/es/views/slides/test/slide.template.on-change.test.js +79 -0
  69. package/lib/actions/api/fetch-skills.d.ts +3 -3
  70. package/lib/actions/api/fetch-skills.js +22 -19
  71. package/lib/actions/api/fetch-slide.d.ts +1 -1
  72. package/lib/actions/api/fetch-slide.js +3 -1
  73. package/lib/actions/api/post-answer.d.ts +14 -0
  74. package/lib/actions/api/post-answer.js +75 -0
  75. package/lib/actions/api/post-progression.d.ts +3 -3
  76. package/lib/actions/api/post-progression.js +6 -3
  77. package/lib/actions/api/test/fetch-skills.test.js +7 -4
  78. package/lib/actions/api/test/fetch-slide.test.js +7 -4
  79. package/lib/actions/api/test/post-answer.test.d.ts +1 -0
  80. package/lib/actions/api/test/post-answer.test.js +145 -0
  81. package/lib/actions/api/test/post-progression.test.js +7 -4
  82. package/lib/actions/data/test/token.test.d.ts +1 -0
  83. package/lib/actions/data/test/token.test.js +70 -0
  84. package/lib/actions/index.d.ts +1 -8
  85. package/lib/actions/{api/test → test}/create-test-store.d.ts +2 -2
  86. package/lib/actions/{api/test → test}/create-test-store.js +1 -1
  87. package/lib/actions/ui/answers.d.ts +17 -3
  88. package/lib/actions/ui/answers.js +50 -3
  89. package/lib/actions/ui/slides.d.ts +0 -5
  90. package/lib/actions/ui/slides.js +0 -4
  91. package/lib/actions/ui/test/answers.test.d.ts +1 -0
  92. package/lib/actions/ui/test/answers.test.js +190 -0
  93. package/lib/actions/ui/test/slides.test.d.ts +1 -0
  94. package/lib/actions/ui/test/slides.test.js +71 -0
  95. package/lib/common/index.d.ts +0 -3
  96. package/lib/common/index.js +0 -4
  97. package/lib/index.js +1 -3
  98. package/lib/reducers/data/index.d.ts +1 -1
  99. package/lib/reducers/data/progression.d.ts +3 -3
  100. package/lib/reducers/data/progression.js +2 -5
  101. package/lib/reducers/data/slides.d.ts +2 -3
  102. package/lib/reducers/data/test/progression.test.js +12 -27
  103. package/lib/reducers/index.d.ts +2 -1
  104. package/lib/reducers/ui/answers.d.ts +2 -2
  105. package/lib/reducers/ui/answers.js +4 -8
  106. package/lib/reducers/ui/index.d.ts +4 -1
  107. package/lib/reducers/ui/index.js +3 -1
  108. package/lib/reducers/ui/slide.d.ts +8 -0
  109. package/lib/reducers/ui/slide.js +27 -0
  110. package/lib/reducers/ui/test/answers.test.js +23 -3
  111. package/lib/reducers/ui/test/current-slide-ref.test.js +1 -1
  112. package/lib/reducers/ui/test/navigation.test.js +5 -5
  113. package/lib/reducers/ui/test/slide.test.d.ts +1 -0
  114. package/lib/reducers/ui/test/slide.test.js +12 -0
  115. package/lib/test/util/services.mock.d.ts +3 -1
  116. package/lib/test/util/services.mock.js +89 -72
  117. package/lib/types/common.d.ts +0 -25
  118. package/lib/views/skills/index.d.ts +1 -1
  119. package/lib/views/skills/index.js +0 -3
  120. package/lib/views/skills/test/skills.test.d.ts +1 -0
  121. package/lib/views/skills/test/skills.test.js +94 -0
  122. package/lib/views/slides/index.d.ts +13 -2
  123. package/lib/views/slides/index.js +19 -15
  124. package/lib/views/slides/map-api-slide-to-ui.js +106 -99
  125. package/lib/views/slides/test/fixtures/free-text.d.ts +2 -1
  126. package/lib/views/slides/test/fixtures/qcm-drag.d.ts +2 -1
  127. package/lib/views/slides/test/fixtures/qcm-graphic.d.ts +2 -1
  128. package/lib/views/slides/test/fixtures/qcm.d.ts +2 -1
  129. package/lib/views/slides/test/fixtures/slider.d.ts +2 -1
  130. package/lib/views/slides/test/fixtures/template.d.ts +4 -0
  131. package/{es/views/slides/test/fixtures/select-template.js → lib/views/slides/test/fixtures/template.js} +82 -4
  132. package/lib/views/slides/test/index.test.d.ts +1 -0
  133. package/lib/views/slides/test/index.test.js +473 -0
  134. package/lib/views/slides/test/map-api-slide-to-ui.test.js +4 -10
  135. package/lib/views/slides/test/slide.template.on-change.test.d.ts +1 -0
  136. package/lib/views/slides/test/slide.template.on-change.test.js +82 -0
  137. package/package.json +6 -5
  138. package/src/actions/api/fetch-skills.ts +18 -11
  139. package/src/actions/api/fetch-slide.ts +3 -1
  140. package/src/actions/api/post-answer.ts +44 -0
  141. package/src/actions/api/post-progression.ts +7 -4
  142. package/src/actions/api/test/fetch-skills.test.ts +9 -6
  143. package/src/actions/api/test/fetch-slide.test.ts +9 -6
  144. package/src/actions/api/test/post-answer.test.ts +101 -0
  145. package/src/actions/api/test/post-progression.test.ts +9 -6
  146. package/src/actions/data/test/token.test.ts +29 -0
  147. package/src/actions/index.ts +1 -17
  148. package/src/actions/{api/test → test}/create-test-store.ts +2 -2
  149. package/src/actions/ui/answers.ts +55 -6
  150. package/src/actions/ui/slides.ts +1 -8
  151. package/src/actions/ui/test/answers.test.ts +115 -0
  152. package/src/actions/ui/test/slides.test.ts +30 -0
  153. package/src/common/index.ts +0 -7
  154. package/src/index.tsx +1 -3
  155. package/src/reducers/data/progression.ts +4 -7
  156. package/src/reducers/data/slides.ts +2 -3
  157. package/src/reducers/data/test/progression.test.ts +15 -31
  158. package/src/reducers/ui/answers.ts +5 -9
  159. package/src/reducers/ui/index.ts +4 -1
  160. package/src/reducers/ui/slide.ts +43 -0
  161. package/src/reducers/ui/test/answers.test.ts +29 -4
  162. package/src/reducers/ui/test/current-slide-ref.test.ts +1 -1
  163. package/src/reducers/ui/test/navigation.test.ts +5 -5
  164. package/src/reducers/ui/test/slide.test.ts +15 -0
  165. package/src/test/util/services.mock.ts +94 -73
  166. package/src/types/common.ts +0 -30
  167. package/src/views/skills/index.ts +1 -5
  168. package/src/views/skills/test/skills.test.ts +101 -0
  169. package/src/views/slides/index.ts +38 -23
  170. package/src/views/slides/map-api-slide-to-ui.ts +146 -113
  171. package/src/views/slides/test/fixtures/free-text.ts +2 -1
  172. package/src/views/slides/test/fixtures/qcm-drag.ts +2 -1
  173. package/src/views/slides/test/fixtures/qcm-graphic.ts +2 -1
  174. package/src/views/slides/test/fixtures/qcm.ts +2 -1
  175. package/src/views/slides/test/fixtures/slider.ts +2 -1
  176. package/src/views/slides/test/fixtures/{select-template.ts → template.ts} +84 -5
  177. package/src/views/slides/test/index.test.ts +493 -0
  178. package/src/views/slides/test/map-api-slide-to-ui.test.ts +6 -11
  179. package/src/views/slides/test/slide.template.on-change.test.ts +92 -0
  180. package/es/fixtures/qcm-slide.d.ts +0 -2
  181. package/es/fixtures/qcm-slide.js +0 -33
  182. package/es/fixtures/temp-fixture.d.ts +0 -3
  183. package/es/fixtures/temp-fixture.js +0 -84
  184. package/es/views/slides/test/fixtures/select-template.d.ts +0 -3
  185. package/es/views/slides/test/fixtures/text-template.d.ts +0 -3
  186. package/es/views/slides/test/fixtures/text-template.js +0 -58
  187. package/lib/fixtures/qcm-slide.d.ts +0 -2
  188. package/lib/fixtures/qcm-slide.js +0 -33
  189. package/lib/fixtures/temp-fixture.d.ts +0 -3
  190. package/lib/fixtures/temp-fixture.js +0 -84
  191. package/lib/views/slides/test/fixtures/select-template.d.ts +0 -3
  192. package/lib/views/slides/test/fixtures/text-template.d.ts +0 -3
  193. package/lib/views/slides/test/fixtures/text-template.js +0 -58
  194. package/src/fixtures/qcm-slide.ts +0 -35
  195. package/src/fixtures/temp-fixture.ts +0 -94
  196. package/src/views/slides/test/fixtures/text-template.ts +0 -61
@@ -0,0 +1,44 @@
1
+ import type {Dispatch} from 'redux';
2
+ import buildTask from '@coorpacademy/redux-task';
3
+ import get from 'lodash/fp/get';
4
+ import type {Options, ProgressionFromAPI} from '../../types/common';
5
+ import type {StoreState} from '../../reducers';
6
+ import {fetchSlide} from './fetch-slide';
7
+
8
+ export const POST_ANSWER_REQUEST = '@@answer/POST_REQUEST' as const;
9
+ export const POST_ANSWER_SUCCESS = '@@answer/POST_SUCCESS' as const;
10
+ export const POST_ANSWER_FAILURE = '@@answer/POST_FAILURE' as const;
11
+
12
+ export type PostAnswerRequestAction = {
13
+ type: typeof POST_ANSWER_REQUEST;
14
+ };
15
+
16
+ export type PostAnswerSuccessAction = {
17
+ type: typeof POST_ANSWER_SUCCESS;
18
+ payload: ProgressionFromAPI;
19
+ };
20
+
21
+ export const postAnswer = async (
22
+ dispatch: Dispatch,
23
+ getState: () => StoreState,
24
+ {services}: Options
25
+ ): Promise<void> => {
26
+ const action = buildTask({
27
+ types: [POST_ANSWER_REQUEST, POST_ANSWER_SUCCESS, POST_ANSWER_FAILURE],
28
+ task: () => {
29
+ const state = getState();
30
+ const token = get('data.token', state);
31
+ const answer = get('ui.answers', state);
32
+ const progressionId = get('data.progression._id', state);
33
+ const skillRef = get('data.progression.content.ref', state);
34
+ return services.postAnswer(skillRef, token, progressionId, answer);
35
+ }
36
+ });
37
+ const response = await dispatch(action);
38
+
39
+ if (response.type === POST_ANSWER_SUCCESS) {
40
+ const progression = response.payload;
41
+ const slideRef = progression.state.nextContent.ref;
42
+ await dispatch(fetchSlide(slideRef));
43
+ }
44
+ };
@@ -1,6 +1,7 @@
1
1
  import type {Dispatch} from 'redux';
2
2
  import buildTask from '@coorpacademy/redux-task';
3
- import {Options, ProgressionFromAPI} from '../../types/common';
3
+ import get from 'lodash/fp/get';
4
+ import type {Options, ProgressionFromAPI} from '../../types/common';
4
5
  import type {StoreState} from '../../reducers';
5
6
  import {fetchSlide} from './fetch-slide';
6
7
 
@@ -8,14 +9,16 @@ export const POST_PROGRESSION_REQUEST = '@@progression/POST_REQUEST' as const;
8
9
  export const POST_PROGRESSION_SUCCESS = '@@progression/POST_SUCCESS' as const;
9
10
  export const POST_PROGRESSION_FAILURE = '@@progression/POST_FAILURE' as const;
10
11
 
11
- export type ReceiveProgression = {
12
+ export type ReceivedProgression = {
12
13
  type: typeof POST_PROGRESSION_SUCCESS;
13
14
  payload: ProgressionFromAPI;
14
15
  };
15
16
 
16
17
  export const postProgression =
17
- (skillRef: string, token: string) =>
18
+ (skillRef: string) =>
18
19
  async (dispatch: Dispatch, getState: () => StoreState, {services}: Options): Promise<void> => {
20
+ const state = getState();
21
+ const token = get('data.token', state);
19
22
  const action = buildTask({
20
23
  types: [POST_PROGRESSION_REQUEST, POST_PROGRESSION_SUCCESS, POST_PROGRESSION_FAILURE],
21
24
  task: () => {
@@ -27,6 +30,6 @@ export const postProgression =
27
30
  if (response.type === POST_PROGRESSION_SUCCESS) {
28
31
  const progression = response.payload;
29
32
  const slideRef = progression.state.nextContent.ref;
30
- await dispatch(fetchSlide(slideRef, token));
33
+ await dispatch(fetchSlide(slideRef));
31
34
  }
32
35
  };
@@ -1,5 +1,6 @@
1
1
  import test from 'ava';
2
- import {Services} from '../../../types/common';
2
+ import type {Services} from '../../../types/common';
3
+ import type {StoreState} from '../../../reducers';
3
4
  import {
4
5
  fetchSkills,
5
6
  SKILLS_FETCH_FAILURE,
@@ -7,8 +8,7 @@ import {
7
8
  SKILLS_FETCH_SUCCESS
8
9
  } from '../fetch-skills';
9
10
  import {services as mockedServices} from '../../../test/util/services.mock';
10
- import {StoreState} from '../../../reducers';
11
- import {createTestStore} from './create-test-store';
11
+ import {createTestStore} from '../../test/create-test-store';
12
12
 
13
13
  const initialState: StoreState = {
14
14
  data: {
@@ -20,7 +20,10 @@ const initialState: StoreState = {
20
20
  ui: {
21
21
  currentSlideRef: '',
22
22
  navigation: [],
23
- answers: []
23
+ answers: [],
24
+ slide: {
25
+ validateButton: false
26
+ }
24
27
  }
25
28
  };
26
29
 
@@ -43,7 +46,7 @@ test('should dispatch SKILLS_FETCH_SUCCESS actions when fetchSkills return a lis
43
46
 
44
47
  const {dispatch} = createTestStore(t, initialState, services, expectedActions);
45
48
 
46
- await dispatch(fetchSkills('1234'));
49
+ await dispatch(fetchSkills);
47
50
  });
48
51
 
49
52
  test('should dispatch SKILLS_FETCH_FAILURE action when fetchSkills fails', async t => {
@@ -66,5 +69,5 @@ test('should dispatch SKILLS_FETCH_FAILURE action when fetchSkills fails', async
66
69
 
67
70
  const {dispatch} = createTestStore(t, initialState, services, expectedActions);
68
71
 
69
- await dispatch(fetchSkills('1234'));
72
+ await dispatch(fetchSkills);
70
73
  });
@@ -1,5 +1,5 @@
1
1
  import test from 'ava';
2
- import {Services} from '../../../types/common';
2
+ import type {Services} from '../../../types/common';
3
3
  import {
4
4
  fetchSlide,
5
5
  SLIDE_FETCH_FAILURE,
@@ -8,9 +8,9 @@ import {
8
8
  } from '../fetch-slide';
9
9
  import {freeTextSlide} from '../../../views/slides/test/fixtures/free-text';
10
10
  import {services as mockedServices} from '../../../test/util/services.mock';
11
- import {StoreState} from '../../../reducers';
11
+ import type {StoreState} from '../../../reducers';
12
12
  import {SET_CURRENT_SLIDE} from '../../ui/slides';
13
- import {createTestStore} from './create-test-store';
13
+ import {createTestStore} from '../../test/create-test-store';
14
14
 
15
15
  const initialState: StoreState = {
16
16
  data: {
@@ -22,7 +22,10 @@ const initialState: StoreState = {
22
22
  ui: {
23
23
  currentSlideRef: '',
24
24
  navigation: [],
25
- answers: []
25
+ answers: [],
26
+ slide: {
27
+ validateButton: false
28
+ }
26
29
  }
27
30
  };
28
31
 
@@ -48,7 +51,7 @@ test('should dispatch FETCH_SUCCESS and SET_CURRENT_SLIDE actions when fetchSlid
48
51
 
49
52
  const {dispatch} = createTestStore(t, initialState, services, expectedActions);
50
53
 
51
- await dispatch(fetchSlide('sli_VJYjJnJhg', '1234'));
54
+ await dispatch(fetchSlide('sli_VJYjJnJhg'));
52
55
  });
53
56
 
54
57
  test('should dispatch SLIDE_FETCH_FAILURE action when fetchSlide fails', async t => {
@@ -73,5 +76,5 @@ test('should dispatch SLIDE_FETCH_FAILURE action when fetchSlide fails', async t
73
76
 
74
77
  const {dispatch} = createTestStore(t, initialState, services, expectedActions);
75
78
 
76
- await dispatch(fetchSlide('slide_ref', '1234'));
79
+ await dispatch(fetchSlide('slide_ref'));
77
80
  });
@@ -0,0 +1,101 @@
1
+ import test from 'ava';
2
+ import {createTestStore} from '../../test/create-test-store';
3
+ import {postAnswerResponse, services} from '../../../test/util/services.mock';
4
+ import {
5
+ postAnswer,
6
+ POST_ANSWER_FAILURE,
7
+ POST_ANSWER_REQUEST,
8
+ POST_ANSWER_SUCCESS
9
+ } from '../post-answer';
10
+ import type {StoreState} from '../../../reducers';
11
+ import {SLIDE_FETCH_REQUEST, SLIDE_FETCH_SUCCESS} from '../fetch-slide';
12
+ import {qcmGraphicSlide} from '../../../views/slides/test/fixtures/qcm-graphic';
13
+ import {freeTextSlide} from '../../../views/slides/test/fixtures/free-text';
14
+ import {SET_CURRENT_SLIDE} from '../../ui/slides';
15
+
16
+ const progressionId = '123456789123';
17
+ const skillRef = '_skill-ref';
18
+ const answer = ['Lister vos tâches pour vous libérer l’esprit', 'Vous isoler dans un lieu calme'];
19
+
20
+ const initialState: StoreState = {
21
+ data: {
22
+ progression: {
23
+ _id: progressionId,
24
+ content: {type: 'skill', ref: skillRef},
25
+ engine: {
26
+ ref: 'review'
27
+ },
28
+ state: {
29
+ allAnswers: [],
30
+ isCorrect: true,
31
+ nextContent: {
32
+ ref: 'sli_VJYjJnJhg',
33
+ type: 'slide'
34
+ },
35
+ pendingSlides: [],
36
+ slides: [],
37
+ step: {
38
+ current: 1
39
+ },
40
+ stars: 0
41
+ }
42
+ },
43
+ slides: {
44
+ [freeTextSlide.id]: freeTextSlide
45
+ },
46
+ skills: [{skillRef, custom: false, name: skillRef, slidesToReview: 5}],
47
+ token: '1234'
48
+ },
49
+ ui: {
50
+ currentSlideRef: 'sli_VJYjJnJhg',
51
+ navigation: ['skills', 'slides'],
52
+ answers: answer,
53
+ slide: {
54
+ validateButton: false
55
+ }
56
+ }
57
+ };
58
+
59
+ test('should dispatch POST_ANSWER_REQUEST, then POST_ANSWER_SUCCESS when the updated progression is returned', async t => {
60
+ const expectedActions = [
61
+ {type: POST_ANSWER_REQUEST},
62
+ {
63
+ type: POST_ANSWER_SUCCESS,
64
+ payload: postAnswerResponse
65
+ },
66
+ {type: SLIDE_FETCH_REQUEST, meta: {slideRef: 'sli_VkSQroQnx'}},
67
+ {
68
+ type: SLIDE_FETCH_SUCCESS,
69
+ meta: {slideRef: 'sli_VkSQroQnx'},
70
+ payload: qcmGraphicSlide
71
+ },
72
+ {type: SET_CURRENT_SLIDE, payload: qcmGraphicSlide}
73
+ ];
74
+
75
+ const {dispatch} = createTestStore(t, initialState, services, expectedActions);
76
+
77
+ await dispatch(postAnswer);
78
+ });
79
+
80
+ test('should dispatch POST_ANSWER_REQUEST, then POST_ANSWER_FAILURE on error', async t => {
81
+ const expectedActions = [
82
+ {type: POST_ANSWER_REQUEST},
83
+ {
84
+ type: POST_ANSWER_FAILURE,
85
+ payload: new Error('unexpected'),
86
+ error: true
87
+ }
88
+ ];
89
+
90
+ const {dispatch} = createTestStore(
91
+ t,
92
+ initialState,
93
+ {
94
+ ...services,
95
+ postAnswer: () => Promise.reject(new Error('unexpected'))
96
+ },
97
+ expectedActions
98
+ );
99
+
100
+ await dispatch(postAnswer);
101
+ });
@@ -1,5 +1,5 @@
1
1
  import test from 'ava';
2
- import {ProgressionFromAPI, Services} from '../../../types/common';
2
+ import type {ProgressionFromAPI, Services} from '../../../types/common';
3
3
  import {
4
4
  postProgression,
5
5
  POST_PROGRESSION_REQUEST,
@@ -8,10 +8,10 @@ import {
8
8
  } from '../post-progression';
9
9
  import {freeTextSlide} from '../../../views/slides/test/fixtures/free-text';
10
10
  import {services as mockedServices} from '../../../test/util/services.mock';
11
- import {StoreState} from '../../../reducers';
11
+ import type {StoreState} from '../../../reducers';
12
12
  import {SLIDE_FETCH_REQUEST, SLIDE_FETCH_SUCCESS} from '../fetch-slide';
13
13
  import {SET_CURRENT_SLIDE} from '../../ui/slides';
14
- import {createTestStore} from './create-test-store';
14
+ import {createTestStore} from '../../test/create-test-store';
15
15
 
16
16
  const initialState: StoreState = {
17
17
  data: {
@@ -23,7 +23,10 @@ const initialState: StoreState = {
23
23
  ui: {
24
24
  currentSlideRef: '',
25
25
  navigation: [],
26
- answers: []
26
+ answers: [],
27
+ slide: {
28
+ validateButton: false
29
+ }
27
30
  }
28
31
  };
29
32
 
@@ -91,7 +94,7 @@ test('should dispatch POST_PROGRESSION_SUCCESS and SLIDE_FETCH_REQUEST actions w
91
94
 
92
95
  const {dispatch} = createTestStore(t, initialState, services, expectedActions);
93
96
 
94
- await dispatch(postProgression('skill_12345', '1234'));
97
+ await dispatch(postProgression('skill_12345'));
95
98
  });
96
99
 
97
100
  test('should dispatch POST_PROGRESSION_FAILURE action when postProgression fails', async t => {
@@ -115,5 +118,5 @@ test('should dispatch POST_PROGRESSION_FAILURE action when postProgression fails
115
118
 
116
119
  const {dispatch} = createTestStore(t, initialState, services, expectedActions);
117
120
 
118
- await dispatch(postProgression('skill_12345', '1234'));
121
+ await dispatch(postProgression('skill_12345'));
119
122
  });
@@ -0,0 +1,29 @@
1
+ import test from 'ava';
2
+ import {createTestStore} from '../../test/create-test-store';
3
+ import {services} from '../../../test/util/services.mock';
4
+ import {StoreState} from '../../../reducers';
5
+ import {storeToken, STORE_TOKEN} from '../token';
6
+
7
+ const initialState: StoreState = {
8
+ data: {
9
+ progression: null,
10
+ slides: {},
11
+ skills: [],
12
+ token: '1234'
13
+ },
14
+ ui: {
15
+ currentSlideRef: '',
16
+ navigation: [],
17
+ answers: [],
18
+ slide: {
19
+ validateButton: false
20
+ }
21
+ }
22
+ };
23
+
24
+ test('should dispatch STORE_TOKEN action when storeToken is called', async t => {
25
+ const expectedActions = [{type: STORE_TOKEN, payload: 'JWT.token'}];
26
+
27
+ const {dispatch} = createTestStore(t, initialState, services, expectedActions);
28
+ await dispatch(storeToken('JWT.token'));
29
+ });
@@ -1,22 +1,6 @@
1
- import {StoreToken} from './data/token';
2
-
3
- import {navigateBack, navigateTo, NavigateBack, NavigateTo, StartApp} from './ui/navigation';
4
- import {ReceivedSlide} from './api/fetch-slide';
5
- import {ReceiveProgression} from './api/post-progression';
6
- import {ReceivedSkills} from './api/fetch-skills';
7
- import {validateSlide} from './ui/slides';
8
-
9
- export type Action =
10
- | NavigateBack
11
- | NavigateTo
12
- | ReceivedSkills
13
- | StartApp
14
- | ReceivedSlide
15
- | StoreToken
16
- | ReceiveProgression;
1
+ import {navigateBack, navigateTo} from './ui/navigation';
17
2
 
18
3
  export type Dispatchers = {
19
4
  navigateTo: typeof navigateTo;
20
5
  navigateBack: typeof navigateBack;
21
- validateSlide: typeof validateSlide;
22
6
  };
@@ -2,8 +2,8 @@ import type {ExecutionContext} from 'ava';
2
2
  import constant from 'lodash/fp/constant';
3
3
  import {AnyAction, applyMiddleware, compose, createStore, Dispatch, Middleware, Store} from 'redux';
4
4
  import thunk from 'redux-thunk';
5
- import rootReducer, {StoreState} from '../../../reducers';
6
- import {Services} from '../../../types/common';
5
+ import rootReducer, {StoreState} from '../../reducers';
6
+ import {Services} from '../../types/common';
7
7
 
8
8
  const assertActionsMiddleware = (t: ExecutionContext, ACTIONS: AnyAction[]): Middleware =>
9
9
  constant((next: Dispatch) => (action: AnyAction): unknown => {
@@ -1,16 +1,65 @@
1
1
  import {Dispatch} from 'redux';
2
+ import {flatten, get, includes, pull} from 'lodash/fp';
3
+ import type {StoreState} from '../../reducers';
2
4
 
5
+ export const EDIT_QCM = '@@answer/EDIT_QCM' as const;
6
+ export const EDIT_QCM_GRAPHIC = '@@answer/EDIT_QCM_GRAPHIC' as const;
7
+ export const EDIT_QCM_DRAG = '@@answer/EDIT_QCM_DRAG' as const;
8
+ export const EDIT_TEMPLATE = '@@answer/EDIT_TEMPLATE' as const;
3
9
  export const EDIT_BASIC = '@@answer/EDIT_BASIC' as const;
4
- export type EditBasicAction = {
5
- type: typeof EDIT_BASIC;
10
+ export const EDIT_SLIDER = '@@answer/EDIT_SLIDER' as const;
11
+
12
+ export const ANSWER_EDIT = {
13
+ qcm: EDIT_QCM,
14
+ qcmGraphic: EDIT_QCM_GRAPHIC,
15
+ qcmDrag: EDIT_QCM_DRAG,
16
+ template: EDIT_TEMPLATE,
17
+ basic: EDIT_BASIC,
18
+ slider: EDIT_SLIDER
19
+ } as const;
20
+
21
+ export type EditAnswerAction = {
22
+ type:
23
+ | typeof EDIT_QCM
24
+ | typeof EDIT_QCM_GRAPHIC
25
+ | typeof EDIT_QCM_DRAG
26
+ | typeof EDIT_TEMPLATE
27
+ | typeof EDIT_BASIC
28
+ | typeof EDIT_SLIDER;
6
29
  payload: string[];
7
30
  };
8
31
 
32
+ const buildAnswer = (userAnswers: string[], questionType: string, newValue: string[]): string[] => {
33
+ switch (questionType) {
34
+ case 'qcm':
35
+ case 'qcmGraphic':
36
+ case 'qcmDrag': {
37
+ const firstValue = newValue[0];
38
+ return includes(firstValue, userAnswers)
39
+ ? pull(firstValue, userAnswers)
40
+ : flatten([...userAnswers, firstValue]);
41
+ }
42
+ case 'basic':
43
+ case 'slider':
44
+ case 'template':
45
+ return newValue;
46
+ default:
47
+ return [];
48
+ }
49
+ };
50
+
9
51
  export const editAnswer =
10
- (answer: string) =>
11
- (dispatch: Dispatch): EditBasicAction => {
52
+ (answer: string[]) =>
53
+ (dispatch: Dispatch, getState: () => StoreState): EditAnswerAction => {
54
+ const state = getState();
55
+ const currentSlideRef = get(['ui', 'currentSlideRef'])(state);
56
+ const userAnswers = get(['ui', 'answers'])(state);
57
+ const slide = get(['data', 'slides', currentSlideRef])(state);
58
+ const questionType = get(['question', 'type'])(slide);
59
+ const type = get(questionType, ANSWER_EDIT);
60
+
12
61
  return dispatch({
13
- type: EDIT_BASIC,
14
- payload: [answer]
62
+ type,
63
+ payload: buildAnswer(userAnswers, questionType, answer)
15
64
  });
16
65
  };
@@ -15,6 +15,7 @@ export type Slide = {
15
15
  };
16
16
 
17
17
  export const SET_CURRENT_SLIDE = '@@slide/SET_CURRENT_SLIDE' as const;
18
+
18
19
  export type SetCurrentSlide = {
19
20
  type: typeof SET_CURRENT_SLIDE;
20
21
  payload: SlideFromAPI;
@@ -24,12 +25,4 @@ export const setCurrentSlide = (payload: SlideFromAPI): SetCurrentSlide => ({
24
25
  payload
25
26
  });
26
27
 
27
- export const VALIDATE_SLIDE = '@@slide/VALIDATE';
28
- export type ValidateSlide = {
29
- type: typeof VALIDATE_SLIDE;
30
- };
31
- export const validateSlide = (): ValidateSlide => ({
32
- type: VALIDATE_SLIDE
33
- });
34
-
35
28
  export type UISlidesAction = SetCurrentSlide;
@@ -0,0 +1,115 @@
1
+ import test from 'ava';
2
+ import pipe from 'lodash/fp/pipe';
3
+ import set from 'lodash/fp/set';
4
+ import {SlideFromAPI} from '../../../types/common';
5
+ import {createTestStore} from '../../test/create-test-store';
6
+ import {services} from '../../../test/util/services.mock';
7
+ import {freeTextSlide} from '../../../views/slides/test/fixtures/free-text';
8
+ import {qcmDragSlide} from '../../../views/slides/test/fixtures/qcm-drag';
9
+ import {qcmSlide} from '../../../views/slides/test/fixtures/qcm';
10
+ import {qcmGraphicSlide} from '../../../views/slides/test/fixtures/qcm-graphic';
11
+ import {sliderSlide} from '../../../views/slides/test/fixtures/slider';
12
+ import {templateSlide} from '../../../views/slides/test/fixtures/template';
13
+
14
+ import {StoreState} from '../../../reducers';
15
+ import {editAnswer, ANSWER_EDIT} from '../answers';
16
+
17
+ const initialState: StoreState = {
18
+ data: {
19
+ progression: {
20
+ _id: '62b1d1087aa12f00253f40ee',
21
+ content: {
22
+ ref: '_skill-ref',
23
+ type: 'skill'
24
+ },
25
+ engine: {
26
+ ref: 'review'
27
+ },
28
+ state: {
29
+ allAnswers: [],
30
+ isCorrect: true,
31
+ nextContent: {
32
+ ref: '',
33
+ type: 'slide'
34
+ },
35
+ pendingSlides: [],
36
+ slides: [],
37
+ step: {
38
+ current: 1
39
+ },
40
+ stars: 0
41
+ }
42
+ },
43
+ slides: {},
44
+ skills: [],
45
+ token: '1234'
46
+ },
47
+ ui: {
48
+ currentSlideRef: '',
49
+ navigation: [],
50
+ answers: [],
51
+ slide: {
52
+ validateButton: false
53
+ }
54
+ }
55
+ };
56
+
57
+ const buildInitialState = (state: StoreState, question: SlideFromAPI): StoreState => {
58
+ return pipe(
59
+ set(['data', 'progression', 'state', 'nextContent', 'ref'], question.id),
60
+ set(['data', 'slides', question.id], question),
61
+ set(['ui', 'currentSlideRef'], question.id)
62
+ )(state);
63
+ };
64
+
65
+ test('should dispatch EDIT_BASIC action when editAnswer is called', async t => {
66
+ const state = buildInitialState(initialState, freeTextSlide);
67
+ const expectedActions = [{type: ANSWER_EDIT.basic, payload: ['My Answer']}];
68
+ const {dispatch} = createTestStore(t, state, services, expectedActions);
69
+ await dispatch(editAnswer(['My Answer']));
70
+ });
71
+
72
+ test('should dispatch EDIT_QCM action when editAnswer is called', async t => {
73
+ let state = buildInitialState(initialState, qcmSlide);
74
+ state = set(['ui', 'answers'], ['My First Answer', 'My Second Answer'], state);
75
+ const expectedActions = [{type: ANSWER_EDIT.qcm, payload: ['My First Answer']}];
76
+ const {dispatch} = createTestStore(t, state, services, expectedActions);
77
+ await dispatch(editAnswer(['My Second Answer']));
78
+ });
79
+
80
+ test('should dispatch EDIT_QCM_GRAPHIC action when editAnswer is called', async t => {
81
+ let state = buildInitialState(initialState, qcmGraphicSlide);
82
+ state = set(['ui', 'answers'], ['My First Answer', 'My Second Answer', 'My Third Answer'], state);
83
+ const expectedActions = [
84
+ {type: ANSWER_EDIT.qcmGraphic, payload: ['My First Answer', 'My Third Answer']}
85
+ ];
86
+ const {dispatch} = createTestStore(t, state, services, expectedActions);
87
+ await dispatch(editAnswer(['My Second Answer']));
88
+ });
89
+
90
+ test('should dispatch EDIT_QCM_DRAG action when editAnswer is called', async t => {
91
+ let state = buildInitialState(initialState, qcmDragSlide);
92
+ state = set(['ui', 'answers'], ['My First Answer', 'My Second Answer'], state);
93
+ const expectedActions = [
94
+ {type: ANSWER_EDIT.qcmDrag, payload: ['My First Answer', 'My Second Answer', 'My Third Answer']}
95
+ ];
96
+ const {dispatch} = createTestStore(t, state, services, expectedActions);
97
+ await dispatch(editAnswer(['My Third Answer']));
98
+ });
99
+
100
+ test('should dispatch EDIT_SLIDER action when editAnswer is called', async t => {
101
+ const state = buildInitialState(initialState, sliderSlide);
102
+ const expectedActions = [{type: ANSWER_EDIT.slider, payload: ['5']}];
103
+ const {dispatch} = createTestStore(t, state, services, expectedActions);
104
+ await dispatch(editAnswer(['5']));
105
+ });
106
+
107
+ test('should dispatch EDIT_TEMPLATE action when editAnswer is called', async t => {
108
+ let state = buildInitialState(initialState, templateSlide);
109
+ state = set(['ui', 'answers'], ['Catalogue', '', 'étoiles'], state);
110
+ const expectedActions = [
111
+ {type: ANSWER_EDIT.template, payload: ['Catalogue', 'My Answer', 'étoiles']}
112
+ ];
113
+ const {dispatch} = createTestStore(t, state, services, expectedActions);
114
+ await dispatch(editAnswer(['Catalogue', 'My Answer', 'étoiles']));
115
+ });
@@ -0,0 +1,30 @@
1
+ import test from 'ava';
2
+ import {createTestStore} from '../../test/create-test-store';
3
+ import {services} from '../../../test/util/services.mock';
4
+ import {freeTextSlide} from '../../../views/slides/test/fixtures/free-text';
5
+ import {StoreState} from '../../../reducers';
6
+ import {setCurrentSlide, SET_CURRENT_SLIDE} from '../slides';
7
+
8
+ const initialState: StoreState = {
9
+ data: {
10
+ progression: null,
11
+ slides: {},
12
+ skills: [],
13
+ token: '1234'
14
+ },
15
+ ui: {
16
+ currentSlideRef: '',
17
+ navigation: [],
18
+ answers: [],
19
+ slide: {
20
+ validateButton: false
21
+ }
22
+ }
23
+ };
24
+
25
+ test('should dispatch SET_CURRENT_SLIDE action when setCurrentSlide is called', async t => {
26
+ const expectedActions = [{type: SET_CURRENT_SLIDE, payload: freeTextSlide}];
27
+
28
+ const {dispatch} = createTestStore(t, initialState, services, expectedActions);
29
+ await dispatch(setCurrentSlide(freeTextSlide));
30
+ });
@@ -1,8 +1,3 @@
1
- import _toString from 'lodash/fp/toString';
2
-
3
- export const TOTAL_SLIDES_STACK = 5;
4
- export const HIGHEST_INDEX = TOTAL_SLIDES_STACK - 1;
5
-
6
1
  export const VIEWS: {
7
2
  readonly skills: 'skills';
8
3
  readonly onboarding: 'onboarding';
@@ -16,5 +11,3 @@ export const VIEWS: {
16
11
  export const slideIndexes = ['0', '1', '2', '3', '4'] as const;
17
12
 
18
13
  export type SlideIndexes = typeof slideIndexes[number];
19
-
20
- export const indexToString = (index: number): SlideIndexes => _toString(index) as SlideIndexes;
package/src/index.tsx CHANGED
@@ -68,9 +68,7 @@ const AppReview = ({options}: {options: AppOptions}): JSX.Element | null => {
68
68
 
69
69
  /* ThunkAction is not assignable to parameter of type 'AnyAction'
70
70
  ts problem is described here = https://github.com/reduxjs/redux-thunk/issues/333 */
71
- skillRef
72
- ? store.dispatch(postProgression(skillRef, token))
73
- : store.dispatch(fetchSkills(token));
71
+ skillRef ? store.dispatch(postProgression(skillRef)) : store.dispatch(fetchSkills);
74
72
  }, [options, store]);
75
73
 
76
74
  useEffect(() => {
@@ -1,5 +1,5 @@
1
- import {ValidateSlide, VALIDATE_SLIDE} from '../../actions/ui/slides';
2
- import {POST_PROGRESSION_SUCCESS, ReceiveProgression} from '../../actions/api/post-progression';
1
+ import {PostAnswerSuccessAction, POST_ANSWER_SUCCESS} from '../../actions/api/post-answer';
2
+ import {POST_PROGRESSION_SUCCESS, ReceivedProgression} from '../../actions/api/post-progression';
3
3
  import {ProgressionFromAPI} from '../../types/common';
4
4
 
5
5
  export type ProgressionState = ProgressionFromAPI | null;
@@ -7,13 +7,10 @@ export type ProgressionState = ProgressionFromAPI | null;
7
7
  const reducer = (
8
8
  // eslint-disable-next-line default-param-last
9
9
  state: ProgressionState = null,
10
- action: ValidateSlide | ReceiveProgression
10
+ action: ReceivedProgression | PostAnswerSuccessAction
11
11
  ): ProgressionState => {
12
12
  switch (action.type) {
13
- case VALIDATE_SLIDE: {
14
- // TODO: fix on VALIDATE ticket -> launch a POST PROGRESSION
15
- return state;
16
- }
13
+ case POST_ANSWER_SUCCESS:
17
14
  case POST_PROGRESSION_SUCCESS: {
18
15
  const progression = action.payload;
19
16
  return progression;