@coorpacademy/app-review 0.1.21 → 0.2.0

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 (106) hide show
  1. package/es/actions/api/fetch-correction.d.ts +11 -0
  2. package/es/actions/api/fetch-correction.js +19 -0
  3. package/es/actions/api/fetch-skills.d.ts +2 -2
  4. package/es/actions/api/fetch-skills.js +3 -3
  5. package/es/actions/api/fetch-slide.js +1 -1
  6. package/es/actions/api/post-answer.js +3 -5
  7. package/es/actions/api/post-progression.js +2 -4
  8. package/es/actions/api/test/fetch-correction.test.d.ts +1 -0
  9. package/es/actions/api/test/fetch-correction.test.js +73 -0
  10. package/es/actions/api/test/fetch-skills.test.js +3 -1
  11. package/es/actions/api/test/fetch-slide.test.js +2 -0
  12. package/es/actions/api/test/post-answer.test.js +12 -7
  13. package/es/actions/api/test/post-progression.test.js +3 -1
  14. package/es/actions/ui/test/answers.test.js +1 -1
  15. package/es/reducers/data/index.d.ts +2 -2
  16. package/es/reducers/data/slides.js +2 -2
  17. package/es/reducers/data/test/token.test.js +3 -3
  18. package/es/reducers/data/token.d.ts +2 -2
  19. package/es/reducers/data/token.js +1 -1
  20. package/es/reducers/index.d.ts +1 -1
  21. package/es/reducers/ui/current-slide-ref.js +1 -1
  22. package/es/services/fetch-slide.js +1 -1
  23. package/es/services/post-answer.js +3 -3
  24. package/es/services/post-progression.js +2 -2
  25. package/es/services/test/fetch-slide.test.js +1 -1
  26. package/es/services/test/post-answer.test.js +9 -1
  27. package/es/services/test/post-progression.test.js +12 -1
  28. package/es/test/util/services.mock.d.ts +2 -1
  29. package/es/test/util/services.mock.js +2 -2
  30. package/es/types/common.d.ts +1 -1
  31. package/es/views/slides/test/fixtures/free-text.js +1 -1
  32. package/es/views/slides/test/fixtures/qcm-drag.js +1 -1
  33. package/es/views/slides/test/fixtures/qcm-graphic.js +1 -1
  34. package/es/views/slides/test/fixtures/qcm.js +1 -1
  35. package/es/views/slides/test/fixtures/slider.js +1 -1
  36. package/es/views/slides/test/fixtures/template.js +1 -1
  37. package/es/views/slides/test/slide.template.on-change.test.js +3 -3
  38. package/lib/actions/api/fetch-correction.d.ts +11 -0
  39. package/lib/actions/api/fetch-correction.js +20 -0
  40. package/lib/actions/api/fetch-skills.d.ts +2 -2
  41. package/lib/actions/api/fetch-skills.js +8 -55
  42. package/lib/actions/api/fetch-slide.js +1 -1
  43. package/lib/actions/api/post-answer.js +3 -5
  44. package/lib/actions/api/post-progression.js +2 -4
  45. package/lib/actions/api/test/fetch-correction.test.d.ts +1 -0
  46. package/lib/actions/api/test/fetch-correction.test.js +133 -0
  47. package/lib/actions/api/test/fetch-skills.test.js +3 -1
  48. package/lib/actions/api/test/fetch-slide.test.js +2 -0
  49. package/lib/actions/api/test/post-answer.test.js +12 -7
  50. package/lib/actions/api/test/post-progression.test.js +3 -1
  51. package/lib/actions/ui/test/answers.test.js +1 -1
  52. package/lib/reducers/data/index.d.ts +2 -2
  53. package/lib/reducers/data/slides.js +2 -2
  54. package/lib/reducers/data/test/token.test.js +3 -3
  55. package/lib/reducers/data/token.d.ts +2 -2
  56. package/lib/reducers/data/token.js +1 -1
  57. package/lib/reducers/index.d.ts +1 -1
  58. package/lib/reducers/ui/current-slide-ref.js +1 -1
  59. package/lib/services/fetch-slide.js +1 -1
  60. package/lib/services/post-answer.js +4 -4
  61. package/lib/services/post-progression.js +2 -2
  62. package/lib/services/test/fetch-slide.test.js +1 -1
  63. package/lib/services/test/post-answer.test.js +9 -1
  64. package/lib/services/test/post-progression.test.js +12 -1
  65. package/lib/test/util/services.mock.d.ts +2 -1
  66. package/lib/test/util/services.mock.js +2 -2
  67. package/lib/types/common.d.ts +1 -1
  68. package/lib/views/slides/test/fixtures/free-text.js +1 -1
  69. package/lib/views/slides/test/fixtures/qcm-drag.js +1 -1
  70. package/lib/views/slides/test/fixtures/qcm-graphic.js +1 -1
  71. package/lib/views/slides/test/fixtures/qcm.js +1 -1
  72. package/lib/views/slides/test/fixtures/slider.js +1 -1
  73. package/lib/views/slides/test/fixtures/template.js +1 -1
  74. package/lib/views/slides/test/slide.template.on-change.test.js +3 -3
  75. package/package.json +2 -2
  76. package/src/actions/api/fetch-correction.ts +33 -0
  77. package/src/actions/api/fetch-skills.ts +5 -5
  78. package/src/actions/api/fetch-slide.ts +1 -1
  79. package/src/actions/api/post-answer.ts +3 -5
  80. package/src/actions/api/post-progression.ts +2 -4
  81. package/src/actions/api/test/fetch-correction.test.ts +94 -0
  82. package/src/actions/api/test/fetch-skills.test.ts +3 -1
  83. package/src/actions/api/test/fetch-slide.test.ts +2 -0
  84. package/src/actions/api/test/post-answer.test.ts +12 -7
  85. package/src/actions/api/test/post-progression.test.ts +3 -1
  86. package/src/actions/ui/test/answers.test.ts +3 -3
  87. package/src/reducers/data/index.ts +1 -1
  88. package/src/reducers/data/slides.ts +2 -2
  89. package/src/reducers/data/test/token.test.ts +3 -3
  90. package/src/reducers/data/token.ts +2 -2
  91. package/src/reducers/ui/current-slide-ref.ts +1 -1
  92. package/src/services/fetch-slide.ts +1 -1
  93. package/src/services/post-answer.ts +3 -3
  94. package/src/services/post-progression.ts +2 -2
  95. package/src/services/test/fetch-slide.test.ts +1 -1
  96. package/src/services/test/post-answer.test.ts +9 -1
  97. package/src/services/test/post-progression.test.ts +12 -1
  98. package/src/test/util/services.mock.ts +2 -2
  99. package/src/types/common.ts +1 -1
  100. package/src/views/slides/test/fixtures/free-text.ts +1 -1
  101. package/src/views/slides/test/fixtures/qcm-drag.ts +1 -1
  102. package/src/views/slides/test/fixtures/qcm-graphic.ts +1 -1
  103. package/src/views/slides/test/fixtures/qcm.ts +1 -1
  104. package/src/views/slides/test/fixtures/slider.ts +1 -1
  105. package/src/views/slides/test/fixtures/template.ts +1 -1
  106. package/src/views/slides/test/slide.template.on-change.test.ts +3 -3
@@ -339,7 +339,7 @@ export var progressionSlideWithPendingSlide = {
339
339
  stars: 32
340
340
  }
341
341
  };
342
- var getChoicesCorrection = function (ref, wrongChoice) {
342
+ export var getChoicesCorrection = function (ref, wrongChoice) {
343
343
  if (wrongChoice === void 0) { wrongChoice = false; }
344
344
  switch (ref) {
345
345
  case qcmSlide.universalRef: {
@@ -406,7 +406,7 @@ var getChoicesCorrection = function (ref, wrongChoice) {
406
406
  };
407
407
  export var services = {
408
408
  fetchSkills: function () { return Promise.resolve(fetchSkillsResponse); },
409
- fetchSlide: function (ref) { return Promise.resolve(__assign(__assign({}, getSlideFixture(ref)), { universalRef: ref, id: ref })); },
409
+ fetchSlide: function (ref) { return Promise.resolve(__assign(__assign({}, getSlideFixture(ref)), { universalRef: ref, _id: ref })); },
410
410
  postProgression: function () { return Promise.resolve(postProgressionResponse); },
411
411
  postAnswer: function (progression) {
412
412
  var currentSlide = progression.state.nextContent.ref;
@@ -62,13 +62,13 @@ export declare type TemplateQuestion = Omit<BaseQuestion, 'content'> & {
62
62
  };
63
63
  export declare type Question = QcmQuestion | QcmGraphicQuestion | QcmDragQuestion | BasicQuestion | SliderQuestion | TemplateQuestion;
64
64
  export declare type SlideFromAPI = {
65
+ _id: string;
65
66
  question: Question;
66
67
  klf: string;
67
68
  universalRef: string;
68
69
  tips?: string;
69
70
  clue?: string;
70
71
  hasClue?: boolean;
71
- id: string;
72
72
  parentContentTitle: {
73
73
  title: string;
74
74
  type: 'chapter' | 'course';
@@ -18,7 +18,7 @@ export var freeTextSlide = {
18
18
  klf: 'To negotiate your salary when being hired, you have to establish a benchmark beforehand. In other words, you should assess the salary to which you aspire by enquiring about the remuneration paid in the same industry, the same region and the same position.',
19
19
  tips: 'According to Insee, Paris salaries are 20-25% higher compared with those of the provinces in 2015.',
20
20
  universalRef: 'sli_VJYjJnJhg',
21
- id: 'sli_VJYjJnJhg',
21
+ _id: 'sli_VJYjJnJhg',
22
22
  parentContentTitle: {
23
23
  title: 'Developing the review app',
24
24
  type: 'course'
@@ -65,7 +65,7 @@ export var qcmDragSlide = {
65
65
  klf: "Le burn out s'installe en quatre étapes : tout d'abord, l'implication (investissement émotionnel et/ou affectif, sacrifice de sa vie privée) ; en second, la stagnation (premières déceptions, signes de fatigue) ; ensuite, la frustration (efforts non reconnus) ; et enfin, la démoralisation (problèmes de concentration, sentiment d'inutilité, désespoir).",
66
66
  tips: "Encadré par la loi, l'entretien professionnel a pour but d'aider le collaborateur à verbaliser ses difficultés et à construire son projet professionnel.",
67
67
  universalRef: 'sli_4yGBq-mCg',
68
- id: 'sli_4yGBq-mCg',
68
+ _id: 'sli_4yGBq-mCg',
69
69
  parentContentTitle: {
70
70
  title: 'Using redux',
71
71
  type: 'chapter'
@@ -57,7 +57,7 @@ export var qcmGraphicSlide = {
57
57
  klf: "Il ne faut pas prendre la négociation comme une affaire personnelle, afin de rester centré sur son sujet. Mais cela ne signifie pas être dépourvu de toute émotion, car celles-ci peuvent être de vrais atouts. À condition de réussir à les exprimer sans accuser l'autre d'en être à l'origine.",
58
58
  tips: "Pour gérer ses émotions, il faut d'abord les identifier, notamment en analysant ses ressentis physiques et en trouvant l'élément déclencheur.",
59
59
  universalRef: 'sli_VkSQroQnx',
60
- id: 'sli_VkSQroQnx',
60
+ _id: 'sli_VkSQroQnx',
61
61
  parentContentTitle: {
62
62
  title: 'Developing the review app',
63
63
  type: 'course'
@@ -66,7 +66,7 @@ export var qcmSlide = {
66
66
  tips: 'En 2021, le média en ligne Numerama a créé un NFT vendu aux enchères sur OpenSea. Sur cette plateforme, il est obligatoire de mettre un prix de réserve, autrement dit un prix minimum au-dessous duquel la vente ne sera pas automatiquement acceptée. Sur OpenSea il ne peut être inférieur à 1 ETH. Si le prix de réserve est atteint, pas de problème, les "gas fees" (les frais de gaz) sont couverts par OpenSea. Mais, si ce n’est pas le cas, c’est au vendeur de s’en acquitter. <br/>Le NFT en question est parti à 0,021 ETH, soit 40€ au cours de l\'époque, un prix inférieur au prix de réserve. Numerama a dû acquitter des frais de gaz, et payer 190 €. <br/>Avec les NFT, on ne gagne pas à tous les coups.',
67
67
  universalRef: 'sli_N1XACJobn',
68
68
  hasClue: true,
69
- id: 'sli_N1XACJobn',
69
+ _id: 'sli_N1XACJobn',
70
70
  parentContentTitle: {
71
71
  title: 'Developing the review app',
72
72
  type: 'course'
@@ -13,7 +13,7 @@ export var sliderSlide = {
13
13
  klf: 'Dans le cadre d’un projet local, la communauté de communes du Thouarsais, dans le Poitou (ouest de la France), a développé un parc diversifié d’énergies renouvelables : éolien, biomasse, solaire… En sept ans seulement, entre 2007 et 2014, la part d’énergies renouvelables est passée de zéro à un tiers !',
14
14
  tips: 'En 2014, le Thouarsais a reçu la médaille de bronze du championnat européen des énergies renouvelables.',
15
15
  universalRef: 'sli_VkAzsCLKb',
16
- id: 'sli_VkAzsCLKb',
16
+ _id: 'sli_VkAzsCLKb',
17
17
  parentContentTitle: {
18
18
  title: 'Developing the review app',
19
19
  type: 'course'
@@ -79,7 +79,7 @@ export var templateSlide = {
79
79
  klf: 'L’apprenant peut aussi évaluer sa performance grâce à un classement disponible sur la vue leaderboard. Elle compare sa position par rapport à celle des autres apprenants de la plateforme.',
80
80
  tips: "La position d'un apprenant peut être aussi consultée depuis le header ou en-tête de la page. Elle se met à jour à chaque fois qu'un apprenant obtient des étoiles.",
81
81
  universalRef: 'sli_N13-hG3kX',
82
- id: 'sli_N13-hG3kX',
82
+ _id: 'sli_N13-hG3kX',
83
83
  parentContentTitle: {
84
84
  title: 'Developing the review app',
85
85
  type: 'course'
@@ -17,7 +17,7 @@ var progression = {
17
17
  allAnswers: [],
18
18
  isCorrect: true,
19
19
  nextContent: {
20
- ref: templateSlide.id,
20
+ ref: templateSlide._id,
21
21
  type: 'slide'
22
22
  },
23
23
  pendingSlides: [],
@@ -32,13 +32,13 @@ var initialState = {
32
32
  data: {
33
33
  progression: progression,
34
34
  slides: (_a = {},
35
- _a[templateSlide.id] = templateSlide,
35
+ _a[templateSlide._id] = templateSlide,
36
36
  _a),
37
37
  skills: [],
38
38
  token: '1234'
39
39
  },
40
40
  ui: {
41
- currentSlideRef: templateSlide.id,
41
+ currentSlideRef: templateSlide._id,
42
42
  navigation: ['skills', 'slides'],
43
43
  answers: [],
44
44
  slide: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coorpacademy/app-review",
3
- "version": "0.1.21",
3
+ "version": "0.2.0",
4
4
  "description": "",
5
5
  "engines": {
6
6
  "node": ">=16.15.0"
@@ -78,5 +78,5 @@
78
78
  "ts-node": "^10.9.1",
79
79
  "typescript": "^4.7.4"
80
80
  },
81
- "gitHead": "c1783083ab70ca3ccbeebb029a521470457212c8"
81
+ "gitHead": "197f4f2387f064686d20b57ec812a456b97124ea"
82
82
  }
@@ -0,0 +1,33 @@
1
+ import type {Dispatch} from 'redux';
2
+ import buildTask from '@coorpacademy/redux-task';
3
+ import get from 'lodash/fp/get';
4
+ import type {StoreState} from '../../reducers';
5
+ import type {CorrectionFromAPI, Options} from '../../types/common';
6
+
7
+ export const CORRECTION_FETCH_REQUEST = '@@correction/FETCH_REQUEST' as const;
8
+ export const CORRECTION_FETCH_SUCCESS = '@@correction/FETCH_SUCCESS' as const;
9
+ export const CORRECTION_FETCH_FAILURE = '@@correction/FETCH_FAILURE' as const;
10
+
11
+ export type FetchCorrection = {
12
+ type: typeof CORRECTION_FETCH_SUCCESS;
13
+ payload: CorrectionFromAPI | void;
14
+ };
15
+
16
+ export const fetchCorrection = (
17
+ dispatch: Dispatch,
18
+ getState: () => StoreState,
19
+ {services}: Options
20
+ ): FetchCorrection => {
21
+ const action = buildTask({
22
+ types: [CORRECTION_FETCH_REQUEST, CORRECTION_FETCH_SUCCESS, CORRECTION_FETCH_FAILURE],
23
+ task: () => {
24
+ const state = getState();
25
+ const token = get(['data', 'token'], state);
26
+ const progressionId = get(['data', 'progression', '_id'], state);
27
+ const answer = get(['ui', 'answers'], state);
28
+ const slideRef = get(['ui', 'currentSlideRef'], state);
29
+ return services.fetchCorrection(slideRef, token, progressionId, answer);
30
+ }
31
+ });
32
+ return dispatch(action);
33
+ };
@@ -9,23 +9,23 @@ export const SKILLS_FETCH_SUCCESS = '@@skills/FETCH_SUCCESS' as const;
9
9
  export const SKILLS_FETCH_FAILURE = '@@skills/FETCH_FAILURE' as const;
10
10
 
11
11
  export type ReceivedSkills = {
12
- type: '@@skills/FETCH_SUCCESS';
12
+ type: typeof SKILLS_FETCH_SUCCESS;
13
13
  payload: Skill[];
14
14
  };
15
15
 
16
- export const fetchSkills = async (
16
+ export const fetchSkills = (
17
17
  dispatch: Dispatch,
18
18
  getState: () => StoreState,
19
19
  {services}: Options
20
- ): Promise<void> => {
20
+ ): ReceivedSkills => {
21
21
  const action = buildTask({
22
22
  types: [SKILLS_FETCH_REQUEST, SKILLS_FETCH_SUCCESS, SKILLS_FETCH_FAILURE],
23
23
  task: () => {
24
24
  const state = getState();
25
- const token = get('data.token', state);
25
+ const token = get(['data', 'token'], state);
26
26
  return services.fetchSkills(token);
27
27
  }
28
28
  });
29
29
 
30
- await dispatch(action);
30
+ return dispatch(action);
31
31
  };
@@ -32,7 +32,7 @@ export const fetchSlide =
32
32
  },
33
33
  task: () => {
34
34
  const state = getState();
35
- const token = get('data.token', state);
35
+ const token = get(['data', 'token'], state);
36
36
  return services.fetchSlide(slideRef, token);
37
37
  },
38
38
  meta: {slideRef}
@@ -24,16 +24,14 @@ export const postAnswer = async (
24
24
  {services}: Options
25
25
  ): Promise<void> => {
26
26
  const state = getState();
27
- const token = get('data.token', state);
28
- const answer = get('ui.answers', state);
27
+ const token = get(['data', 'token'], state);
28
+ const answer = get(['ui', 'answers'], state);
29
29
  const progression = state.data.progression;
30
30
  if (!progression) throw new Error('cannot answer question of inexisting progression');
31
31
 
32
32
  const action = buildTask({
33
33
  types: [POST_ANSWER_REQUEST, POST_ANSWER_SUCCESS, POST_ANSWER_FAILURE],
34
- task: () => {
35
- return services.postAnswer(progression, token, answer);
36
- }
34
+ task: () => services.postAnswer(progression, token, answer)
37
35
  });
38
36
  const response = await dispatch(action);
39
37
  if (response.type === POST_ANSWER_SUCCESS) {
@@ -18,12 +18,10 @@ export const postProgression =
18
18
  (skillRef: string) =>
19
19
  async (dispatch: Dispatch, getState: () => StoreState, {services}: Options): Promise<void> => {
20
20
  const state = getState();
21
- const token = get('data.token', state);
21
+ const token = get(['data', 'token'], state);
22
22
  const action = buildTask({
23
23
  types: [POST_PROGRESSION_REQUEST, POST_PROGRESSION_SUCCESS, POST_PROGRESSION_FAILURE],
24
- task: () => {
25
- return services.postProgression(skillRef, token);
26
- }
24
+ task: () => services.postProgression(skillRef, token)
27
25
  });
28
26
  const response = await dispatch(action);
29
27
 
@@ -0,0 +1,94 @@
1
+ import test from 'ava';
2
+ import type {Services} from '../../../types/common';
3
+ import type {StoreState} from '../../../reducers';
4
+ import {
5
+ getChoicesCorrection,
6
+ postAnswerResponses,
7
+ services as mockedServices
8
+ } from '../../../test/util/services.mock';
9
+ import {createTestStore} from '../../test/create-test-store';
10
+ import {
11
+ CORRECTION_FETCH_FAILURE,
12
+ CORRECTION_FETCH_REQUEST,
13
+ CORRECTION_FETCH_SUCCESS,
14
+ fetchCorrection
15
+ } from '../fetch-correction';
16
+ import {freeTextSlide} from '../../../views/slides/test/fixtures/free-text';
17
+ import {qcmSlide} from '../../../views/slides/test/fixtures/qcm';
18
+
19
+ const progression = postAnswerResponses[freeTextSlide.universalRef];
20
+ const skillRef = '_skill-ref';
21
+ const answer = ['Lister vos tâches pour vous libérer l’esprit', 'Vous isoler dans un lieu calme'];
22
+
23
+ const initialState: StoreState = {
24
+ data: {
25
+ progression,
26
+ slides: {
27
+ [freeTextSlide.universalRef]: freeTextSlide,
28
+ [qcmSlide.universalRef]: qcmSlide
29
+ },
30
+ skills: [{skillRef, custom: false, name: skillRef, slidesToReview: 5}],
31
+ token: '1234'
32
+ },
33
+ ui: {
34
+ currentSlideRef: freeTextSlide._id,
35
+ navigation: ['skills', 'slides'],
36
+ answers: answer,
37
+ slide: {
38
+ validateButton: false
39
+ }
40
+ }
41
+ };
42
+
43
+ test('should dispatch CORRECTION_FETCH_SUCCESS actions when fetchCorrection returns a correction object', async t => {
44
+ t.plan(6);
45
+ const services: Services = {
46
+ ...mockedServices,
47
+ fetchCorrection: (slideRef, token, progressionId, _answer) => {
48
+ t.is(slideRef, freeTextSlide.universalRef);
49
+ t.is(token, '1234');
50
+ t.is(progression._id, progressionId);
51
+ t.is(_answer, answer);
52
+ return Promise.resolve(getChoicesCorrection(slideRef));
53
+ }
54
+ };
55
+
56
+ const expectedActions = [
57
+ {type: CORRECTION_FETCH_REQUEST},
58
+ {
59
+ type: CORRECTION_FETCH_SUCCESS,
60
+ payload: getChoicesCorrection(freeTextSlide.universalRef)
61
+ }
62
+ ];
63
+
64
+ const {dispatch} = createTestStore(t, initialState, services, expectedActions);
65
+
66
+ await dispatch(fetchCorrection);
67
+ });
68
+
69
+ test('should dispatch CORRECTION_FETCH_FAILURE action when fetchCorrection fails', async t => {
70
+ t.plan(6);
71
+ const services: Services = {
72
+ ...mockedServices,
73
+ fetchCorrection: (slideRef, token, progressionId, _answer) => {
74
+ t.is(slideRef, freeTextSlide.universalRef);
75
+ t.is(token, '1234');
76
+ t.is(progression._id, progressionId);
77
+ t.is(_answer, answer);
78
+ return Promise.reject(new Error('unexpected'));
79
+ }
80
+ };
81
+
82
+ const expectedActions = [
83
+ {type: CORRECTION_FETCH_REQUEST},
84
+ {
85
+ type: CORRECTION_FETCH_FAILURE,
86
+ payload: new Error('unexpected'),
87
+ error: true
88
+ }
89
+ ];
90
+
91
+ const {dispatch} = createTestStore(t, initialState, services, expectedActions);
92
+
93
+ await dispatch(fetchCorrection);
94
+ });
@@ -27,7 +27,8 @@ const initialState: StoreState = {
27
27
  }
28
28
  };
29
29
 
30
- test('should dispatch SKILLS_FETCH_SUCCESS actions when fetchSkills return a list of skills', async t => {
30
+ test('should dispatch SKILLS_FETCH_SUCCESS actions when fetchSkills returns a list of skills', async t => {
31
+ t.plan(3);
31
32
  const services: Services = {
32
33
  ...mockedServices,
33
34
  fetchSkills: token => {
@@ -50,6 +51,7 @@ test('should dispatch SKILLS_FETCH_SUCCESS actions when fetchSkills return a lis
50
51
  });
51
52
 
52
53
  test('should dispatch SKILLS_FETCH_FAILURE action when fetchSkills fails', async t => {
54
+ t.plan(3);
53
55
  const services: Services = {
54
56
  ...mockedServices,
55
57
  fetchSkills: token => {
@@ -30,6 +30,7 @@ const initialState: StoreState = {
30
30
  };
31
31
 
32
32
  test('should dispatch FETCH_SUCCESS and SET_CURRENT_SLIDE actions when fetchSlide return a slide', async t => {
33
+ t.plan(5);
33
34
  const services: Services = {
34
35
  ...mockedServices,
35
36
  fetchSlide: (slideRef, token) => {
@@ -55,6 +56,7 @@ test('should dispatch FETCH_SUCCESS and SET_CURRENT_SLIDE actions when fetchSlid
55
56
  });
56
57
 
57
58
  test('should dispatch SLIDE_FETCH_FAILURE action when fetchSlide fails', async t => {
59
+ t.plan(4);
58
60
  const services: Services = {
59
61
  ...mockedServices,
60
62
  fetchSlide: (slideRef, token) => {
@@ -29,7 +29,7 @@ const initialState: StoreState = {
29
29
  allAnswers: [],
30
30
  isCorrect: true,
31
31
  nextContent: {
32
- ref: freeTextSlide.id,
32
+ ref: freeTextSlide._id,
33
33
  type: 'slide'
34
34
  },
35
35
  pendingSlides: [],
@@ -41,13 +41,13 @@ const initialState: StoreState = {
41
41
  }
42
42
  },
43
43
  slides: {
44
- [freeTextSlide.id]: freeTextSlide
44
+ [freeTextSlide._id]: freeTextSlide
45
45
  },
46
46
  skills: [{skillRef, custom: false, name: skillRef, slidesToReview: 5}],
47
47
  token: '1234'
48
48
  },
49
49
  ui: {
50
- currentSlideRef: freeTextSlide.id,
50
+ currentSlideRef: freeTextSlide._id,
51
51
  navigation: ['skills', 'slides'],
52
52
  answers: answer,
53
53
  slide: {
@@ -57,16 +57,17 @@ const initialState: StoreState = {
57
57
  };
58
58
 
59
59
  test('should dispatch POST_ANSWER_REQUEST, then POST_ANSWER_SUCCESS when the updated progression is returned', async t => {
60
+ t.plan(4);
60
61
  const expectedActions = [
61
62
  {type: POST_ANSWER_REQUEST},
62
63
  {
63
64
  type: POST_ANSWER_SUCCESS,
64
- payload: postAnswerResponses[freeTextSlide.id]
65
+ payload: postAnswerResponses[freeTextSlide._id]
65
66
  },
66
- {type: SLIDE_FETCH_REQUEST, meta: {slideRef: qcmGraphicSlide.id}},
67
+ {type: SLIDE_FETCH_REQUEST, meta: {slideRef: qcmGraphicSlide._id}},
67
68
  {
68
69
  type: SLIDE_FETCH_SUCCESS,
69
- meta: {slideRef: qcmGraphicSlide.id},
70
+ meta: {slideRef: qcmGraphicSlide._id},
70
71
  payload: qcmGraphicSlide
71
72
  },
72
73
  {type: SET_CURRENT_SLIDE, payload: qcmGraphicSlide}
@@ -78,6 +79,7 @@ test('should dispatch POST_ANSWER_REQUEST, then POST_ANSWER_SUCCESS when the upd
78
79
  });
79
80
 
80
81
  test('should dispatch POST_ANSWER_REQUEST, then POST_ANSWER_FAILURE on error', async t => {
82
+ t.plan(3);
81
83
  const expectedActions = [
82
84
  {type: POST_ANSWER_REQUEST},
83
85
  {
@@ -92,7 +94,10 @@ test('should dispatch POST_ANSWER_REQUEST, then POST_ANSWER_FAILURE on error', a
92
94
  initialState,
93
95
  {
94
96
  ...services,
95
- postAnswer: () => Promise.reject(new Error('unexpected'))
97
+ postAnswer: () => {
98
+ t.pass();
99
+ return Promise.reject(new Error('unexpected'));
100
+ }
96
101
  },
97
102
  expectedActions
98
103
  );
@@ -30,7 +30,8 @@ const initialState: StoreState = {
30
30
  }
31
31
  };
32
32
 
33
- test('should dispatch POST_PROGRESSION_SUCCESS and SLIDE_FETCH_REQUEST actions when postProgression return a progression', async t => {
33
+ test('should dispatch POST_PROGRESSION_SUCCESS and SLIDE_FETCH_REQUEST actions when postProgression returns a progression', async t => {
34
+ t.plan(9);
34
35
  const progression: ProgressionFromAPI = {
35
36
  _id: '62b1d1087aa12f00253f40ee',
36
37
  content: {
@@ -98,6 +99,7 @@ test('should dispatch POST_PROGRESSION_SUCCESS and SLIDE_FETCH_REQUEST actions w
98
99
  });
99
100
 
100
101
  test('should dispatch POST_PROGRESSION_FAILURE action when postProgression fails', async t => {
102
+ t.plan(4);
101
103
  const services: Services = {
102
104
  ...mockedServices,
103
105
  postProgression: (skillRef, token) => {
@@ -56,9 +56,9 @@ const initialState: StoreState = {
56
56
 
57
57
  const buildInitialState = (state: StoreState, question: SlideFromAPI): StoreState => {
58
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)
59
+ set(['data', 'progression', 'state', 'nextContent', 'ref'], question._id),
60
+ set(['data', 'slides', question._id], question),
61
+ set(['ui', 'currentSlideRef'], question._id)
62
62
  )(state);
63
63
  };
64
64
 
@@ -10,7 +10,7 @@ export type DataState = {
10
10
  progression: ProgressionState;
11
11
  skills: SkillsState;
12
12
  slides: SlidesState;
13
- token?: TokenState;
13
+ token: TokenState;
14
14
  };
15
15
 
16
16
  export default combineReducers({
@@ -17,11 +17,11 @@ const reducer = (state: SlidesState = initialState, action: SlidesAction): Slide
17
17
  switch (action.type) {
18
18
  case SLIDE_FETCH_REQUEST: {
19
19
  const {meta} = action;
20
- return set(meta.slideRef, null, state);
20
+ return set([meta.slideRef], null, state);
21
21
  }
22
22
  case SLIDE_FETCH_SUCCESS: {
23
23
  const slide = action.payload;
24
- return set(slide.id, slide, state);
24
+ return set([slide._id], slide, state);
25
25
  }
26
26
  default:
27
27
  return state;
@@ -2,12 +2,12 @@ import test from 'ava';
2
2
  import reducer from '../token';
3
3
  import {StoreToken, STORE_TOKEN} from '../../../actions/data/token';
4
4
 
5
- test('should have inital value', t => {
5
+ test('should have initial value', t => {
6
6
  const state = reducer(undefined, {} as StoreToken);
7
- t.is(state, null);
7
+ t.is(state, '');
8
8
  });
9
9
 
10
10
  test('should set the value of STORE_TOKEN action', t => {
11
- const state = reducer(null, {type: STORE_TOKEN, payload: 'token'});
11
+ const state = reducer('', {type: STORE_TOKEN, payload: 'token'});
12
12
  t.is(state, 'token');
13
13
  });
@@ -1,9 +1,9 @@
1
1
  import {StoreToken, STORE_TOKEN} from '../../actions/data/token';
2
2
 
3
- export type TokenState = string | null;
3
+ export type TokenState = string;
4
4
 
5
5
  // eslint-disable-next-line default-param-last
6
- const reducer = (state: TokenState = null, action: StoreToken): TokenState => {
6
+ const reducer = (state: TokenState = '', action: StoreToken): TokenState => {
7
7
  switch (action.type) {
8
8
  case STORE_TOKEN:
9
9
  return action.payload;
@@ -9,7 +9,7 @@ const reducer = (
9
9
  ): CurrentSlideRefState => {
10
10
  switch (action.type) {
11
11
  case SET_CURRENT_SLIDE: {
12
- return action.payload.id;
12
+ return action.payload._id;
13
13
  }
14
14
  default:
15
15
  return state;
@@ -6,7 +6,7 @@ import {toJSON} from './tools/fetch-responses';
6
6
 
7
7
  export const fetchSlide = async (slideRef: string, token: string): Promise<SlideFromAPI | void> => {
8
8
  const {host}: JWT = decode(token);
9
- const response = await crossFetch(`${host}/api/v2/slide/${slideRef}/parentContentTitle`, {
9
+ const response = await crossFetch(`${host}/api/v1/slides/${slideRef}/parentContentTitle`, {
10
10
  headers: {authorization: token}
11
11
  });
12
12
 
@@ -10,14 +10,14 @@ export const postAnswer = async (
10
10
  answer: string[]
11
11
  ): Promise<ProgressionFromAPI> => {
12
12
  const progressionId = progression._id;
13
- const skillRef = progression.content.ref;
13
+ const slideRef = progression.state.nextContent.ref;
14
14
  const {host}: JWT = decode(token);
15
15
  const response = await crossFetch(`${host}/api/v2/progressions/${progressionId}/answers`, {
16
16
  method: 'post',
17
- headers: {authorization: token},
17
+ headers: {authorization: token, 'content-type': 'application/json'},
18
18
  body: JSON.stringify({
19
19
  content: {
20
- ref: skillRef,
20
+ ref: slideRef,
21
21
  type: 'slide'
22
22
  },
23
23
  answer
@@ -11,11 +11,11 @@ export const postProgression = async (
11
11
  const {host}: JWT = decode(token);
12
12
  const response = await crossFetch(`${host}/api/v2/progressions`, {
13
13
  method: 'post',
14
- headers: {authorization: token},
14
+ headers: {authorization: token, 'content-type': 'application/json'},
15
15
  body: JSON.stringify({
16
16
  content: {
17
17
  ref: skillRef,
18
- type: 'slide'
18
+ type: 'skill'
19
19
  },
20
20
  engine: {
21
21
  ref: 'review',
@@ -5,7 +5,7 @@ import {fetchSlide} from '../fetch-slide';
5
5
 
6
6
  test.before(() => {
7
7
  nock('http://localhost:3000')
8
- .get('/api/v2/slide/sli_123546/parentContentTitle')
8
+ .get('/api/v1/slides/sli_123546/parentContentTitle')
9
9
  .reply(200, qcmDragSlide);
10
10
  });
11
11
 
@@ -68,7 +68,15 @@ const result: ProgressionFromAPI = {
68
68
 
69
69
  test.before(() => {
70
70
  const moocApi = nock('http://localhost:3000');
71
- moocApi.post('/api/v2/progressions/123456123456/answers').reply(200, result);
71
+ moocApi
72
+ .post('/api/v2/progressions/123456123456/answers', {
73
+ content: {
74
+ ref: 'sli_NkvrWPFF2',
75
+ type: 'slide'
76
+ },
77
+ answer
78
+ })
79
+ .reply(200, result);
72
80
  });
73
81
 
74
82
  test.after(() => {
@@ -31,7 +31,18 @@ const result: ProgressionFromAPI = {
31
31
 
32
32
  test.before(() => {
33
33
  const moocApi = nock('http://localhost:3000');
34
- moocApi.post('/api/v2/progressions').reply(200, result);
34
+ moocApi
35
+ .post('/api/v2/progressions', {
36
+ content: {
37
+ ref: '_skill-ref',
38
+ type: 'skill'
39
+ },
40
+ engine: {
41
+ ref: 'review',
42
+ version: '1'
43
+ }
44
+ })
45
+ .reply(200, result);
35
46
  });
36
47
 
37
48
  test.after(() => {
@@ -343,7 +343,7 @@ export const progressionSlideWithPendingSlide: ProgressionFromAPI = {
343
343
  }
344
344
  };
345
345
 
346
- const getChoicesCorrection = (ref: string, wrongChoice = false): CorrectionFromAPI => {
346
+ export const getChoicesCorrection = (ref: string, wrongChoice = false): CorrectionFromAPI => {
347
347
  switch (ref) {
348
348
  case qcmSlide.universalRef: {
349
349
  const correctAnswer = [get('question.content.choices.0.label', qcmSlide)];
@@ -410,7 +410,7 @@ const getChoicesCorrection = (ref: string, wrongChoice = false): CorrectionFromA
410
410
 
411
411
  export const services: Services = {
412
412
  fetchSkills: () => Promise.resolve(fetchSkillsResponse),
413
- fetchSlide: ref => Promise.resolve({...getSlideFixture(ref), universalRef: ref, id: ref}),
413
+ fetchSlide: ref => Promise.resolve({...getSlideFixture(ref), universalRef: ref, _id: ref}),
414
414
  postProgression: () => Promise.resolve(postProgressionResponse),
415
415
  postAnswer: progression => {
416
416
  const currentSlide = progression.state.nextContent.ref;