@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
@@ -0,0 +1,11 @@
1
+ import type { Dispatch } from 'redux';
2
+ import type { StoreState } from '../../reducers';
3
+ import type { CorrectionFromAPI, Options } from '../../types/common';
4
+ export declare const CORRECTION_FETCH_REQUEST: "@@correction/FETCH_REQUEST";
5
+ export declare const CORRECTION_FETCH_SUCCESS: "@@correction/FETCH_SUCCESS";
6
+ export declare const CORRECTION_FETCH_FAILURE: "@@correction/FETCH_FAILURE";
7
+ export declare type FetchCorrection = {
8
+ type: typeof CORRECTION_FETCH_SUCCESS;
9
+ payload: CorrectionFromAPI | void;
10
+ };
11
+ export declare const fetchCorrection: (dispatch: Dispatch, getState: () => StoreState, { services }: Options) => FetchCorrection;
@@ -0,0 +1,19 @@
1
+ import buildTask from '@coorpacademy/redux-task';
2
+ import get from 'lodash/fp/get';
3
+ export const CORRECTION_FETCH_REQUEST = '@@correction/FETCH_REQUEST';
4
+ export const CORRECTION_FETCH_SUCCESS = '@@correction/FETCH_SUCCESS';
5
+ export const CORRECTION_FETCH_FAILURE = '@@correction/FETCH_FAILURE';
6
+ export const fetchCorrection = (dispatch, getState, { services }) => {
7
+ const action = buildTask({
8
+ types: [CORRECTION_FETCH_REQUEST, CORRECTION_FETCH_SUCCESS, CORRECTION_FETCH_FAILURE],
9
+ task: () => {
10
+ const state = getState();
11
+ const token = get(['data', 'token'], state);
12
+ const progressionId = get(['data', 'progression', '_id'], state);
13
+ const answer = get(['ui', 'answers'], state);
14
+ const slideRef = get(['ui', 'currentSlideRef'], state);
15
+ return services.fetchCorrection(slideRef, token, progressionId, answer);
16
+ }
17
+ });
18
+ return dispatch(action);
19
+ };
@@ -5,7 +5,7 @@ export declare const SKILLS_FETCH_REQUEST: "@@skills/FETCH_REQUEST";
5
5
  export declare const SKILLS_FETCH_SUCCESS: "@@skills/FETCH_SUCCESS";
6
6
  export declare const SKILLS_FETCH_FAILURE: "@@skills/FETCH_FAILURE";
7
7
  export declare type ReceivedSkills = {
8
- type: '@@skills/FETCH_SUCCESS';
8
+ type: typeof SKILLS_FETCH_SUCCESS;
9
9
  payload: Skill[];
10
10
  };
11
- export declare const fetchSkills: (dispatch: Dispatch, getState: () => StoreState, { services }: Options) => Promise<void>;
11
+ export declare const fetchSkills: (dispatch: Dispatch, getState: () => StoreState, { services }: Options) => ReceivedSkills;
@@ -3,14 +3,14 @@ import get from 'lodash/fp/get';
3
3
  export const SKILLS_FETCH_REQUEST = '@@skills/FETCH_REQUEST';
4
4
  export const SKILLS_FETCH_SUCCESS = '@@skills/FETCH_SUCCESS';
5
5
  export const SKILLS_FETCH_FAILURE = '@@skills/FETCH_FAILURE';
6
- export const fetchSkills = async (dispatch, getState, { services }) => {
6
+ export const fetchSkills = (dispatch, getState, { services }) => {
7
7
  const action = buildTask({
8
8
  types: [SKILLS_FETCH_REQUEST, SKILLS_FETCH_SUCCESS, SKILLS_FETCH_FAILURE],
9
9
  task: () => {
10
10
  const state = getState();
11
- const token = get('data.token', state);
11
+ const token = get(['data', 'token'], state);
12
12
  return services.fetchSkills(token);
13
13
  }
14
14
  });
15
- await dispatch(action);
15
+ return dispatch(action);
16
16
  };
@@ -14,7 +14,7 @@ export const fetchSlide = (slideRef) => async (dispatch, getState, { services })
14
14
  },
15
15
  task: () => {
16
16
  const state = getState();
17
- const token = get('data.token', state);
17
+ const token = get(['data', 'token'], state);
18
18
  return services.fetchSlide(slideRef, token);
19
19
  },
20
20
  meta: { slideRef }
@@ -6,16 +6,14 @@ export const POST_ANSWER_SUCCESS = '@@answer/POST_SUCCESS';
6
6
  export const POST_ANSWER_FAILURE = '@@answer/POST_FAILURE';
7
7
  export const postAnswer = async (dispatch, getState, { services }) => {
8
8
  const state = getState();
9
- const token = get('data.token', state);
10
- const answer = get('ui.answers', state);
9
+ const token = get(['data', 'token'], state);
10
+ const answer = get(['ui', 'answers'], state);
11
11
  const progression = state.data.progression;
12
12
  if (!progression)
13
13
  throw new Error('cannot answer question of inexisting progression');
14
14
  const action = buildTask({
15
15
  types: [POST_ANSWER_REQUEST, POST_ANSWER_SUCCESS, POST_ANSWER_FAILURE],
16
- task: () => {
17
- return services.postAnswer(progression, token, answer);
18
- }
16
+ task: () => services.postAnswer(progression, token, answer)
19
17
  });
20
18
  const response = await dispatch(action);
21
19
  if (response.type === POST_ANSWER_SUCCESS) {
@@ -6,12 +6,10 @@ export const POST_PROGRESSION_SUCCESS = '@@progression/POST_SUCCESS';
6
6
  export const POST_PROGRESSION_FAILURE = '@@progression/POST_FAILURE';
7
7
  export const postProgression = (skillRef) => async (dispatch, getState, { services }) => {
8
8
  const state = getState();
9
- const token = get('data.token', state);
9
+ const token = get(['data', 'token'], state);
10
10
  const action = buildTask({
11
11
  types: [POST_PROGRESSION_REQUEST, POST_PROGRESSION_SUCCESS, POST_PROGRESSION_FAILURE],
12
- task: () => {
13
- return services.postProgression(skillRef, token);
14
- }
12
+ task: () => services.postProgression(skillRef, token)
15
13
  });
16
14
  const response = await dispatch(action);
17
15
  if (response.type === POST_PROGRESSION_SUCCESS) {
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,73 @@
1
+ import test from 'ava';
2
+ import { getChoicesCorrection, postAnswerResponses, services as mockedServices } from '../../../test/util/services.mock';
3
+ import { createTestStore } from '../../test/create-test-store';
4
+ import { CORRECTION_FETCH_FAILURE, CORRECTION_FETCH_REQUEST, CORRECTION_FETCH_SUCCESS, fetchCorrection } from '../fetch-correction';
5
+ import { freeTextSlide } from '../../../views/slides/test/fixtures/free-text';
6
+ import { qcmSlide } from '../../../views/slides/test/fixtures/qcm';
7
+ const progression = postAnswerResponses[freeTextSlide.universalRef];
8
+ const skillRef = '_skill-ref';
9
+ const answer = ['Lister vos tâches pour vous libérer l’esprit', 'Vous isoler dans un lieu calme'];
10
+ const initialState = {
11
+ data: {
12
+ progression,
13
+ slides: {
14
+ [freeTextSlide.universalRef]: freeTextSlide,
15
+ [qcmSlide.universalRef]: qcmSlide
16
+ },
17
+ skills: [{ skillRef, custom: false, name: skillRef, slidesToReview: 5 }],
18
+ token: '1234'
19
+ },
20
+ ui: {
21
+ currentSlideRef: freeTextSlide._id,
22
+ navigation: ['skills', 'slides'],
23
+ answers: answer,
24
+ slide: {
25
+ validateButton: false
26
+ }
27
+ }
28
+ };
29
+ test('should dispatch CORRECTION_FETCH_SUCCESS actions when fetchCorrection returns a correction object', async (t) => {
30
+ t.plan(6);
31
+ const services = {
32
+ ...mockedServices,
33
+ fetchCorrection: (slideRef, token, progressionId, _answer) => {
34
+ t.is(slideRef, freeTextSlide.universalRef);
35
+ t.is(token, '1234');
36
+ t.is(progression._id, progressionId);
37
+ t.is(_answer, answer);
38
+ return Promise.resolve(getChoicesCorrection(slideRef));
39
+ }
40
+ };
41
+ const expectedActions = [
42
+ { type: CORRECTION_FETCH_REQUEST },
43
+ {
44
+ type: CORRECTION_FETCH_SUCCESS,
45
+ payload: getChoicesCorrection(freeTextSlide.universalRef)
46
+ }
47
+ ];
48
+ const { dispatch } = createTestStore(t, initialState, services, expectedActions);
49
+ await dispatch(fetchCorrection);
50
+ });
51
+ test('should dispatch CORRECTION_FETCH_FAILURE action when fetchCorrection fails', async (t) => {
52
+ t.plan(6);
53
+ const services = {
54
+ ...mockedServices,
55
+ fetchCorrection: (slideRef, token, progressionId, _answer) => {
56
+ t.is(slideRef, freeTextSlide.universalRef);
57
+ t.is(token, '1234');
58
+ t.is(progression._id, progressionId);
59
+ t.is(_answer, answer);
60
+ return Promise.reject(new Error('unexpected'));
61
+ }
62
+ };
63
+ const expectedActions = [
64
+ { type: CORRECTION_FETCH_REQUEST },
65
+ {
66
+ type: CORRECTION_FETCH_FAILURE,
67
+ payload: new Error('unexpected'),
68
+ error: true
69
+ }
70
+ ];
71
+ const { dispatch } = createTestStore(t, initialState, services, expectedActions);
72
+ await dispatch(fetchCorrection);
73
+ });
@@ -18,7 +18,8 @@ const initialState = {
18
18
  }
19
19
  }
20
20
  };
21
- test('should dispatch SKILLS_FETCH_SUCCESS actions when fetchSkills return a list of skills', async (t) => {
21
+ test('should dispatch SKILLS_FETCH_SUCCESS actions when fetchSkills returns a list of skills', async (t) => {
22
+ t.plan(3);
22
23
  const services = {
23
24
  ...mockedServices,
24
25
  fetchSkills: token => {
@@ -37,6 +38,7 @@ test('should dispatch SKILLS_FETCH_SUCCESS actions when fetchSkills return a lis
37
38
  await dispatch(fetchSkills);
38
39
  });
39
40
  test('should dispatch SKILLS_FETCH_FAILURE action when fetchSkills fails', async (t) => {
41
+ t.plan(3);
40
42
  const services = {
41
43
  ...mockedServices,
42
44
  fetchSkills: token => {
@@ -21,6 +21,7 @@ const initialState = {
21
21
  }
22
22
  };
23
23
  test('should dispatch FETCH_SUCCESS and SET_CURRENT_SLIDE actions when fetchSlide return a slide', async (t) => {
24
+ t.plan(5);
24
25
  const services = {
25
26
  ...mockedServices,
26
27
  fetchSlide: (slideRef, token) => {
@@ -42,6 +43,7 @@ test('should dispatch FETCH_SUCCESS and SET_CURRENT_SLIDE actions when fetchSlid
42
43
  await dispatch(fetchSlide('sli_VJYjJnJhg'));
43
44
  });
44
45
  test('should dispatch SLIDE_FETCH_FAILURE action when fetchSlide fails', async (t) => {
46
+ t.plan(4);
45
47
  const services = {
46
48
  ...mockedServices,
47
49
  fetchSlide: (slideRef, token) => {
@@ -21,7 +21,7 @@ const initialState = {
21
21
  allAnswers: [],
22
22
  isCorrect: true,
23
23
  nextContent: {
24
- ref: freeTextSlide.id,
24
+ ref: freeTextSlide._id,
25
25
  type: 'slide'
26
26
  },
27
27
  pendingSlides: [],
@@ -33,13 +33,13 @@ const initialState = {
33
33
  }
34
34
  },
35
35
  slides: {
36
- [freeTextSlide.id]: freeTextSlide
36
+ [freeTextSlide._id]: freeTextSlide
37
37
  },
38
38
  skills: [{ skillRef, custom: false, name: skillRef, slidesToReview: 5 }],
39
39
  token: '1234'
40
40
  },
41
41
  ui: {
42
- currentSlideRef: freeTextSlide.id,
42
+ currentSlideRef: freeTextSlide._id,
43
43
  navigation: ['skills', 'slides'],
44
44
  answers: answer,
45
45
  slide: {
@@ -48,16 +48,17 @@ const initialState = {
48
48
  }
49
49
  };
50
50
  test('should dispatch POST_ANSWER_REQUEST, then POST_ANSWER_SUCCESS when the updated progression is returned', async (t) => {
51
+ t.plan(4);
51
52
  const expectedActions = [
52
53
  { type: POST_ANSWER_REQUEST },
53
54
  {
54
55
  type: POST_ANSWER_SUCCESS,
55
- payload: postAnswerResponses[freeTextSlide.id]
56
+ payload: postAnswerResponses[freeTextSlide._id]
56
57
  },
57
- { type: SLIDE_FETCH_REQUEST, meta: { slideRef: qcmGraphicSlide.id } },
58
+ { type: SLIDE_FETCH_REQUEST, meta: { slideRef: qcmGraphicSlide._id } },
58
59
  {
59
60
  type: SLIDE_FETCH_SUCCESS,
60
- meta: { slideRef: qcmGraphicSlide.id },
61
+ meta: { slideRef: qcmGraphicSlide._id },
61
62
  payload: qcmGraphicSlide
62
63
  },
63
64
  { type: SET_CURRENT_SLIDE, payload: qcmGraphicSlide }
@@ -66,6 +67,7 @@ test('should dispatch POST_ANSWER_REQUEST, then POST_ANSWER_SUCCESS when the upd
66
67
  await dispatch(postAnswer);
67
68
  });
68
69
  test('should dispatch POST_ANSWER_REQUEST, then POST_ANSWER_FAILURE on error', async (t) => {
70
+ t.plan(3);
69
71
  const expectedActions = [
70
72
  { type: POST_ANSWER_REQUEST },
71
73
  {
@@ -76,7 +78,10 @@ test('should dispatch POST_ANSWER_REQUEST, then POST_ANSWER_FAILURE on error', a
76
78
  ];
77
79
  const { dispatch } = createTestStore(t, initialState, {
78
80
  ...services,
79
- postAnswer: () => Promise.reject(new Error('unexpected'))
81
+ postAnswer: () => {
82
+ t.pass();
83
+ return Promise.reject(new Error('unexpected'));
84
+ }
80
85
  }, expectedActions);
81
86
  await dispatch(postAnswer);
82
87
  });
@@ -21,7 +21,8 @@ const initialState = {
21
21
  }
22
22
  }
23
23
  };
24
- test('should dispatch POST_PROGRESSION_SUCCESS and SLIDE_FETCH_REQUEST actions when postProgression return a progression', async (t) => {
24
+ test('should dispatch POST_PROGRESSION_SUCCESS and SLIDE_FETCH_REQUEST actions when postProgression returns a progression', async (t) => {
25
+ t.plan(9);
25
26
  const progression = {
26
27
  _id: '62b1d1087aa12f00253f40ee',
27
28
  content: {
@@ -84,6 +85,7 @@ test('should dispatch POST_PROGRESSION_SUCCESS and SLIDE_FETCH_REQUEST actions w
84
85
  await dispatch(postProgression('skill_12345'));
85
86
  });
86
87
  test('should dispatch POST_PROGRESSION_FAILURE action when postProgression fails', async (t) => {
88
+ t.plan(4);
87
89
  const services = {
88
90
  ...mockedServices,
89
91
  postProgression: (skillRef, token) => {
@@ -50,7 +50,7 @@ const initialState = {
50
50
  }
51
51
  };
52
52
  const buildInitialState = (state, question) => {
53
- return pipe(set(['data', 'progression', 'state', 'nextContent', 'ref'], question.id), set(['data', 'slides', question.id], question), set(['ui', 'currentSlideRef'], question.id))(state);
53
+ return pipe(set(['data', 'progression', 'state', 'nextContent', 'ref'], question._id), set(['data', 'slides', question._id], question), set(['ui', 'currentSlideRef'], question._id))(state);
54
54
  };
55
55
  test('should dispatch EDIT_BASIC action when editAnswer is called', async (t) => {
56
56
  const state = buildInitialState(initialState, freeTextSlide);
@@ -7,12 +7,12 @@ export declare type DataState = {
7
7
  progression: ProgressionState;
8
8
  skills: SkillsState;
9
9
  slides: SlidesState;
10
- token?: TokenState;
10
+ token: TokenState;
11
11
  };
12
12
  declare const _default: import("redux").Reducer<import("redux").CombinedState<{
13
13
  progression: ProgressionState;
14
14
  skills: SkillsState;
15
15
  slides: SlidesState;
16
- token: TokenState;
16
+ token: string;
17
17
  }>, import("../../actions/api/post-answer").PostAnswerSuccessAction | import("../../actions/api/post-progression").ReceivedProgression | import("../../actions/api/fetch-skills").ReceivedSkills | import("./slides").SlidesAction | import("../../actions/data/token").StoreToken>;
18
18
  export default _default;
@@ -6,11 +6,11 @@ const reducer = (state = initialState, action) => {
6
6
  switch (action.type) {
7
7
  case SLIDE_FETCH_REQUEST: {
8
8
  const { meta } = action;
9
- return set(meta.slideRef, null, state);
9
+ return set([meta.slideRef], null, state);
10
10
  }
11
11
  case SLIDE_FETCH_SUCCESS: {
12
12
  const slide = action.payload;
13
- return set(slide.id, slide, state);
13
+ return set([slide._id], slide, state);
14
14
  }
15
15
  default:
16
16
  return state;
@@ -1,11 +1,11 @@
1
1
  import test from 'ava';
2
2
  import reducer from '../token';
3
3
  import { STORE_TOKEN } from '../../../actions/data/token';
4
- test('should have inital value', t => {
4
+ test('should have initial value', t => {
5
5
  const state = reducer(undefined, {});
6
- t.is(state, null);
6
+ t.is(state, '');
7
7
  });
8
8
  test('should set the value of STORE_TOKEN action', t => {
9
- const state = reducer(null, { type: STORE_TOKEN, payload: 'token' });
9
+ const state = reducer('', { type: STORE_TOKEN, payload: 'token' });
10
10
  t.is(state, 'token');
11
11
  });
@@ -1,4 +1,4 @@
1
1
  import { StoreToken } from '../../actions/data/token';
2
- export declare type TokenState = string | null;
3
- declare const reducer: (state: TokenState | undefined, action: StoreToken) => TokenState;
2
+ export declare type TokenState = string;
3
+ declare const reducer: (state: string | undefined, action: StoreToken) => TokenState;
4
4
  export default reducer;
@@ -1,6 +1,6 @@
1
1
  import { STORE_TOKEN } from '../../actions/data/token';
2
2
  // eslint-disable-next-line default-param-last
3
- const reducer = (state = null, action) => {
3
+ const reducer = (state = '', action) => {
4
4
  switch (action.type) {
5
5
  case STORE_TOKEN:
6
6
  return action.payload;
@@ -9,7 +9,7 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
9
9
  progression: import("./data/progression").ProgressionState;
10
10
  skills: import("./data/skills").SkillsState;
11
11
  slides: import("./data/slides").SlidesState;
12
- token: import("./data/token").TokenState;
12
+ token: string;
13
13
  }>;
14
14
  ui: import("redux").CombinedState<{
15
15
  currentSlideRef: string;
@@ -4,7 +4,7 @@ const reducer = (
4
4
  state = '', action) => {
5
5
  switch (action.type) {
6
6
  case SET_CURRENT_SLIDE: {
7
- return action.payload.id;
7
+ return action.payload._id;
8
8
  }
9
9
  default:
10
10
  return state;
@@ -3,7 +3,7 @@ import decode from 'jwt-decode';
3
3
  import { toJSON } from './tools/fetch-responses';
4
4
  export const fetchSlide = async (slideRef, token) => {
5
5
  const { host } = decode(token);
6
- const response = await crossFetch(`${host}/api/v2/slide/${slideRef}/parentContentTitle`, {
6
+ const response = await crossFetch(`${host}/api/v1/slides/${slideRef}/parentContentTitle`, {
7
7
  headers: { authorization: token }
8
8
  });
9
9
  return toJSON(response);
@@ -3,14 +3,14 @@ import decode from 'jwt-decode';
3
3
  import { toJSON } from './tools/fetch-responses';
4
4
  export const postAnswer = async (progression, token, answer) => {
5
5
  const progressionId = progression._id;
6
- const skillRef = progression.content.ref;
6
+ const slideRef = progression.state.nextContent.ref;
7
7
  const { host } = decode(token);
8
8
  const response = await crossFetch(`${host}/api/v2/progressions/${progressionId}/answers`, {
9
9
  method: 'post',
10
- headers: { authorization: token },
10
+ headers: { authorization: token, 'content-type': 'application/json' },
11
11
  body: JSON.stringify({
12
12
  content: {
13
- ref: skillRef,
13
+ ref: slideRef,
14
14
  type: 'slide'
15
15
  },
16
16
  answer
@@ -5,11 +5,11 @@ export const postProgression = async (skillRef, token) => {
5
5
  const { host } = decode(token);
6
6
  const response = await crossFetch(`${host}/api/v2/progressions`, {
7
7
  method: 'post',
8
- headers: { authorization: token },
8
+ headers: { authorization: token, 'content-type': 'application/json' },
9
9
  body: JSON.stringify({
10
10
  content: {
11
11
  ref: skillRef,
12
- type: 'slide'
12
+ type: 'skill'
13
13
  },
14
14
  engine: {
15
15
  ref: 'review',
@@ -4,7 +4,7 @@ import { qcmDragSlide } from '../../views/slides/test/fixtures/qcm-drag';
4
4
  import { fetchSlide } from '../fetch-slide';
5
5
  test.before(() => {
6
6
  nock('http://localhost:3000')
7
- .get('/api/v2/slide/sli_123546/parentContentTitle')
7
+ .get('/api/v1/slides/sli_123546/parentContentTitle')
8
8
  .reply(200, qcmDragSlide);
9
9
  });
10
10
  test.after(() => {
@@ -63,7 +63,15 @@ const result = {
63
63
  };
64
64
  test.before(() => {
65
65
  const moocApi = nock('http://localhost:3000');
66
- moocApi.post('/api/v2/progressions/123456123456/answers').reply(200, result);
66
+ moocApi
67
+ .post('/api/v2/progressions/123456123456/answers', {
68
+ content: {
69
+ ref: 'sli_NkvrWPFF2',
70
+ type: 'slide'
71
+ },
72
+ answer
73
+ })
74
+ .reply(200, result);
67
75
  });
68
76
  test.after(() => {
69
77
  nock.cleanAll();
@@ -28,7 +28,18 @@ const result = {
28
28
  };
29
29
  test.before(() => {
30
30
  const moocApi = nock('http://localhost:3000');
31
- moocApi.post('/api/v2/progressions').reply(200, result);
31
+ moocApi
32
+ .post('/api/v2/progressions', {
33
+ content: {
34
+ ref: '_skill-ref',
35
+ type: 'skill'
36
+ },
37
+ engine: {
38
+ ref: 'review',
39
+ version: '1'
40
+ }
41
+ })
42
+ .reply(200, result);
32
43
  });
33
44
  test.after(() => {
34
45
  nock.cleanAll();
@@ -1,5 +1,6 @@
1
- import { ProgressionFromAPI, Services } from '../../types/common';
1
+ import { CorrectionFromAPI, ProgressionFromAPI, Services } from '../../types/common';
2
2
  export declare const postProgressionResponse: ProgressionFromAPI;
3
3
  export declare const postAnswerResponses: Record<string, ProgressionFromAPI>;
4
4
  export declare const progressionSlideWithPendingSlide: ProgressionFromAPI;
5
+ export declare const getChoicesCorrection: (ref: string, wrongChoice?: boolean) => CorrectionFromAPI;
5
6
  export declare const services: Services;
@@ -327,7 +327,7 @@ export const progressionSlideWithPendingSlide = {
327
327
  stars: 32
328
328
  }
329
329
  };
330
- const getChoicesCorrection = (ref, wrongChoice = false) => {
330
+ export const getChoicesCorrection = (ref, wrongChoice = false) => {
331
331
  switch (ref) {
332
332
  case qcmSlide.universalRef: {
333
333
  const correctAnswer = [get('question.content.choices.0.label', qcmSlide)];
@@ -393,7 +393,7 @@ const getChoicesCorrection = (ref, wrongChoice = false) => {
393
393
  };
394
394
  export const services = {
395
395
  fetchSkills: () => Promise.resolve(fetchSkillsResponse),
396
- fetchSlide: ref => Promise.resolve({ ...getSlideFixture(ref), universalRef: ref, id: ref }),
396
+ fetchSlide: ref => Promise.resolve({ ...getSlideFixture(ref), universalRef: ref, _id: ref }),
397
397
  postProgression: () => Promise.resolve(postProgressionResponse),
398
398
  postAnswer: progression => {
399
399
  const 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 const 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 const 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 const 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 const 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 const 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 const 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'
@@ -16,7 +16,7 @@ const progression = {
16
16
  allAnswers: [],
17
17
  isCorrect: true,
18
18
  nextContent: {
19
- ref: templateSlide.id,
19
+ ref: templateSlide._id,
20
20
  type: 'slide'
21
21
  },
22
22
  pendingSlides: [],
@@ -31,13 +31,13 @@ const initialState = {
31
31
  data: {
32
32
  progression,
33
33
  slides: {
34
- [templateSlide.id]: templateSlide
34
+ [templateSlide._id]: templateSlide
35
35
  },
36
36
  skills: [],
37
37
  token: '1234'
38
38
  },
39
39
  ui: {
40
- currentSlideRef: templateSlide.id,
40
+ currentSlideRef: templateSlide._id,
41
41
  navigation: ['skills', 'slides'],
42
42
  answers: [],
43
43
  slide: {