@coorpacademy/app-review 0.2.4 → 0.2.6

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 (97) hide show
  1. package/es/actions/api/post-answer.js +4 -2
  2. package/es/actions/api/test/fetch-correction.test.js +2 -1
  3. package/es/actions/api/test/fetch-skills.test.js +2 -1
  4. package/es/actions/api/test/fetch-slide.test.js +2 -1
  5. package/es/actions/api/test/post-answer.test.js +32 -10
  6. package/es/actions/api/test/post-progression.test.js +2 -1
  7. package/es/actions/data/test/token.test.js +2 -1
  8. package/es/actions/test/create-test-store.d.ts +1 -1
  9. package/es/actions/ui/answers.js +13 -6
  10. package/es/actions/ui/test/answers.test.js +17 -1
  11. package/es/actions/ui/test/slides.test.js +2 -1
  12. package/es/reducers/data/index.d.ts +4 -2
  13. package/es/reducers/data/index.js +2 -6
  14. package/es/reducers/index.d.ts +2 -1
  15. package/es/reducers/ui/index.d.ts +1 -1
  16. package/es/reducers/ui/slide.d.ts +3 -1
  17. package/es/reducers/ui/slide.js +5 -0
  18. package/es/reducers/ui/test/slide.test.js +12 -0
  19. package/es/types/slides.d.ts +1 -0
  20. package/es/views/skills/test/skills.test.js +4 -2
  21. package/es/views/slides/map-api-slide-to-ui.js +8 -7
  22. package/es/views/slides/test/fixtures/qcm-graphic.js +4 -2
  23. package/es/views/slides/test/fixtures/qcm.js +4 -4
  24. package/es/views/slides/test/index.test.js +20 -10
  25. package/es/views/slides/test/slide.free-text.on-change.test.d.ts +1 -0
  26. package/es/views/slides/test/slide.free-text.on-change.test.js +69 -0
  27. package/es/views/slides/test/slide.qcm-drag.on-click.test.d.ts +1 -0
  28. package/es/views/slides/test/slide.qcm-drag.on-click.test.js +69 -0
  29. package/es/views/slides/test/slide.qcm-graphic.on-click.test.d.ts +1 -0
  30. package/es/views/slides/test/slide.qcm-graphic.on-click.test.js +69 -0
  31. package/es/views/slides/test/slide.qcm.on-click.test.d.ts +1 -0
  32. package/es/views/slides/test/slide.qcm.on-click.test.js +71 -0
  33. package/es/views/slides/test/slide.slider.on-change.test.d.ts +1 -0
  34. package/es/views/slides/test/slide.slider.on-change.test.js +70 -0
  35. package/es/views/slides/test/slide.template.on-change.test.js +2 -1
  36. package/lib/actions/api/post-answer.js +9 -5
  37. package/lib/actions/api/test/fetch-correction.test.js +2 -1
  38. package/lib/actions/api/test/fetch-skills.test.js +2 -1
  39. package/lib/actions/api/test/fetch-slide.test.js +2 -1
  40. package/lib/actions/api/test/post-answer.test.js +45 -14
  41. package/lib/actions/api/test/post-progression.test.js +2 -1
  42. package/lib/actions/data/test/token.test.js +2 -1
  43. package/lib/actions/test/create-test-store.d.ts +1 -1
  44. package/lib/actions/ui/answers.js +13 -6
  45. package/lib/actions/ui/test/answers.test.js +43 -1
  46. package/lib/actions/ui/test/slides.test.js +2 -1
  47. package/lib/reducers/data/index.d.ts +4 -2
  48. package/lib/reducers/data/index.js +2 -6
  49. package/lib/reducers/index.d.ts +2 -1
  50. package/lib/reducers/ui/index.d.ts +1 -1
  51. package/lib/reducers/ui/slide.d.ts +3 -1
  52. package/lib/reducers/ui/slide.js +5 -0
  53. package/lib/reducers/ui/test/slide.test.js +12 -0
  54. package/lib/types/slides.d.ts +1 -0
  55. package/lib/views/skills/test/skills.test.js +4 -2
  56. package/lib/views/slides/map-api-slide-to-ui.js +8 -7
  57. package/lib/views/slides/test/fixtures/qcm-graphic.js +4 -2
  58. package/lib/views/slides/test/fixtures/qcm.js +4 -4
  59. package/lib/views/slides/test/index.test.js +20 -10
  60. package/lib/views/slides/test/slide.free-text.on-change.test.d.ts +1 -0
  61. package/lib/views/slides/test/slide.free-text.on-change.test.js +71 -0
  62. package/lib/views/slides/test/slide.qcm-drag.on-click.test.d.ts +1 -0
  63. package/lib/views/slides/test/slide.qcm-drag.on-click.test.js +71 -0
  64. package/lib/views/slides/test/slide.qcm-graphic.on-click.test.d.ts +1 -0
  65. package/lib/views/slides/test/slide.qcm-graphic.on-click.test.js +71 -0
  66. package/lib/views/slides/test/slide.qcm.on-click.test.d.ts +1 -0
  67. package/lib/views/slides/test/slide.qcm.on-click.test.js +73 -0
  68. package/lib/views/slides/test/slide.slider.on-change.test.d.ts +1 -0
  69. package/lib/views/slides/test/slide.slider.on-change.test.js +72 -0
  70. package/lib/views/slides/test/slide.template.on-change.test.js +2 -1
  71. package/package.json +3 -3
  72. package/src/actions/api/post-answer.ts +4 -2
  73. package/src/actions/api/test/fetch-correction.test.ts +2 -1
  74. package/src/actions/api/test/fetch-skills.test.ts +2 -1
  75. package/src/actions/api/test/fetch-slide.test.ts +2 -1
  76. package/src/actions/api/test/post-answer.test.ts +51 -10
  77. package/src/actions/api/test/post-progression.test.ts +2 -1
  78. package/src/actions/data/test/token.test.ts +2 -1
  79. package/src/actions/test/create-test-store.ts +1 -1
  80. package/src/actions/ui/answers.ts +15 -6
  81. package/src/actions/ui/test/answers.test.ts +33 -2
  82. package/src/actions/ui/test/slides.test.ts +2 -1
  83. package/src/reducers/data/index.ts +3 -7
  84. package/src/reducers/ui/slide.ts +7 -1
  85. package/src/reducers/ui/test/slide.test.ts +13 -0
  86. package/src/types/slides.ts +1 -0
  87. package/src/views/skills/test/skills.test.ts +4 -2
  88. package/src/views/slides/map-api-slide-to-ui.ts +8 -7
  89. package/src/views/slides/test/fixtures/qcm-graphic.ts +4 -2
  90. package/src/views/slides/test/fixtures/qcm.ts +5 -4
  91. package/src/views/slides/test/index.test.ts +20 -10
  92. package/src/views/slides/test/slide.free-text.on-change.test.ts +79 -0
  93. package/src/views/slides/test/slide.qcm-drag.on-click.test.ts +78 -0
  94. package/src/views/slides/test/slide.qcm-graphic.on-click.test.ts +79 -0
  95. package/src/views/slides/test/slide.qcm.on-click.test.ts +80 -0
  96. package/src/views/slides/test/slide.slider.on-change.test.ts +80 -0
  97. package/src/views/slides/test/slide.template.on-change.test.ts +2 -1
@@ -1,5 +1,6 @@
1
1
  import buildTask from '@coorpacademy/redux-task';
2
2
  import get from 'lodash/fp/get';
3
+ import { fetchCorrection } from './fetch-correction';
3
4
  import { fetchSlide } from './fetch-slide';
4
5
  export const POST_ANSWER_REQUEST = '@@answer/POST_REQUEST';
5
6
  export const POST_ANSWER_SUCCESS = '@@answer/POST_SUCCESS';
@@ -8,9 +9,9 @@ export const postAnswer = async (dispatch, getState, { services }) => {
8
9
  const state = getState();
9
10
  const token = get(['data', 'token'], state);
10
11
  const answer = get(['ui', 'answers'], state);
11
- const progression = state.data.progression;
12
+ const progression = get(['data', 'progression'], state);
12
13
  if (!progression)
13
- throw new Error('cannot answer question of inexisting progression');
14
+ throw new Error('Cannot answer a question of an inexistent progression');
14
15
  const action = buildTask({
15
16
  types: [POST_ANSWER_REQUEST, POST_ANSWER_SUCCESS, POST_ANSWER_FAILURE],
16
17
  task: () => services.postAnswer(progression, token, answer)
@@ -20,5 +21,6 @@ export const postAnswer = async (dispatch, getState, { services }) => {
20
21
  const updatedProgression = response.payload;
21
22
  const slideRef = updatedProgression.state.nextContent.ref;
22
23
  await dispatch(fetchSlide(slideRef));
24
+ await dispatch(fetchCorrection);
23
25
  }
24
26
  };
@@ -15,7 +15,8 @@ const initialState = {
15
15
  [qcmSlide.universalRef]: qcmSlide
16
16
  },
17
17
  skills: [{ skillRef, custom: false, name: skillRef, slidesToReview: 5 }],
18
- token: '1234'
18
+ token: '1234',
19
+ corrections: {}
19
20
  },
20
21
  ui: {
21
22
  currentSlideRef: freeTextSlide._id,
@@ -7,7 +7,8 @@ const initialState = {
7
7
  progression: null,
8
8
  slides: {},
9
9
  skills: [],
10
- token: '1234'
10
+ token: '1234',
11
+ corrections: {}
11
12
  },
12
13
  ui: {
13
14
  currentSlideRef: '',
@@ -9,7 +9,8 @@ const initialState = {
9
9
  progression: null,
10
10
  slides: {},
11
11
  skills: [],
12
- token: '1234'
12
+ token: '1234',
13
+ corrections: {}
13
14
  },
14
15
  ui: {
15
16
  currentSlideRef: '',
@@ -1,11 +1,11 @@
1
1
  import test from 'ava';
2
2
  import { createTestStore } from '../../test/create-test-store';
3
- import { postAnswerResponses, services } from '../../../test/util/services.mock';
3
+ import { getChoicesCorrection, postAnswerResponses, services } from '../../../test/util/services.mock';
4
4
  import { postAnswer, POST_ANSWER_FAILURE, POST_ANSWER_REQUEST, POST_ANSWER_SUCCESS } from '../post-answer';
5
+ import { freeTextSlide } from '../../../views/slides/test/fixtures/free-text';
6
+ import { CORRECTION_FETCH_REQUEST, CORRECTION_FETCH_SUCCESS } from '../fetch-correction';
5
7
  import { SLIDE_FETCH_REQUEST, SLIDE_FETCH_SUCCESS } from '../fetch-slide';
6
8
  import { qcmGraphicSlide } from '../../../views/slides/test/fixtures/qcm-graphic';
7
- import { freeTextSlide } from '../../../views/slides/test/fixtures/free-text';
8
- import { SET_CURRENT_SLIDE } from '../../ui/slides';
9
9
  const progressionId = '123456789123';
10
10
  const skillRef = '_skill-ref';
11
11
  const answer = ['Lister vos tâches pour vous libérer l’esprit', 'Vous isoler dans un lieu calme'];
@@ -36,7 +36,8 @@ const initialState = {
36
36
  [freeTextSlide._id]: freeTextSlide
37
37
  },
38
38
  skills: [{ skillRef, custom: false, name: skillRef, slidesToReview: 5 }],
39
- token: '1234'
39
+ token: '1234',
40
+ corrections: {}
40
41
  },
41
42
  ui: {
42
43
  currentSlideRef: freeTextSlide._id,
@@ -47,24 +48,39 @@ const initialState = {
47
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
+ test('should dispatch post-answer, fetch-slide and fetch-correction actions when the answer is submitted', async (t) => {
52
+ t.plan(8);
52
53
  const expectedActions = [
53
54
  { type: POST_ANSWER_REQUEST },
54
55
  {
55
56
  type: POST_ANSWER_SUCCESS,
56
57
  payload: postAnswerResponses[freeTextSlide._id]
57
58
  },
58
- { type: SLIDE_FETCH_REQUEST, meta: { slideRef: qcmGraphicSlide._id } },
59
+ {
60
+ type: SLIDE_FETCH_REQUEST,
61
+ meta: {
62
+ slideRef: qcmGraphicSlide._id
63
+ }
64
+ },
59
65
  {
60
66
  type: SLIDE_FETCH_SUCCESS,
61
- meta: { slideRef: qcmGraphicSlide._id },
67
+ meta: {
68
+ slideRef: qcmGraphicSlide._id
69
+ },
62
70
  payload: qcmGraphicSlide
63
71
  },
64
- { type: SET_CURRENT_SLIDE, payload: qcmGraphicSlide }
72
+ { type: CORRECTION_FETCH_REQUEST, meta: { slideRef: freeTextSlide._id } },
73
+ {
74
+ type: CORRECTION_FETCH_SUCCESS,
75
+ meta: { slideRef: freeTextSlide._id },
76
+ payload: getChoicesCorrection(freeTextSlide._id)
77
+ }
65
78
  ];
66
- const { dispatch } = createTestStore(t, initialState, services, expectedActions);
79
+ const { dispatch, getState } = createTestStore(t, initialState, services, expectedActions);
67
80
  await dispatch(postAnswer);
81
+ const state = getState();
82
+ t.false(state.ui.slide.validateButton);
83
+ t.true(state.ui.slide.animateCorrectionPopin);
68
84
  });
69
85
  test('should dispatch POST_ANSWER_REQUEST, then POST_ANSWER_FAILURE on error', async (t) => {
70
86
  t.plan(3);
@@ -85,3 +101,9 @@ test('should dispatch POST_ANSWER_REQUEST, then POST_ANSWER_FAILURE on error', a
85
101
  }, expectedActions);
86
102
  await dispatch(postAnswer);
87
103
  });
104
+ test('should not dispatch any action && throw an error if progression does not exist', async (t) => {
105
+ t.plan(1);
106
+ const expectedActions = [];
107
+ const { dispatch } = createTestStore(t, { ...initialState, data: { ...initialState.data, progression: null } }, services, expectedActions);
108
+ await t.throwsAsync(() => dispatch(postAnswer), undefined, 'Cannot answer a question of an inexistent progression');
109
+ });
@@ -10,7 +10,8 @@ const initialState = {
10
10
  progression: null,
11
11
  slides: {},
12
12
  skills: [],
13
- token: '1234'
13
+ token: '1234',
14
+ corrections: {}
14
15
  },
15
16
  ui: {
16
17
  currentSlideRef: '',
@@ -7,7 +7,8 @@ const initialState = {
7
7
  progression: null,
8
8
  slides: {},
9
9
  skills: [],
10
- token: '1234'
10
+ token: '1234',
11
+ corrections: {}
11
12
  },
12
13
  ui: {
13
14
  currentSlideRef: '',
@@ -2,4 +2,4 @@ import type { ExecutionContext } from 'ava';
2
2
  import { AnyAction, Store } from 'redux';
3
3
  import { StoreState } from '../../reducers';
4
4
  import { Services } from '../../types/common';
5
- export declare const createTestStore: (t: ExecutionContext, initialState: StoreState, services: Services, actions: AnyAction[]) => Store;
5
+ export declare const createTestStore: (t: ExecutionContext, initialState: StoreState, services: Services, actions: AnyAction[]) => Store<StoreState, AnyAction>;
@@ -1,4 +1,7 @@
1
- import { flatten, get, includes, pull } from 'lodash/fp';
1
+ import flatten from 'lodash/fp/flatten';
2
+ import get from 'lodash/fp/get';
3
+ import includes from 'lodash/fp/includes';
4
+ import pull from 'lodash/fp/pull';
2
5
  export const EDIT_QCM = '@@answer/EDIT_QCM';
3
6
  export const EDIT_QCM_GRAPHIC = '@@answer/EDIT_QCM_GRAPHIC';
4
7
  export const EDIT_QCM_DRAG = '@@answer/EDIT_QCM_DRAG';
@@ -27,17 +30,21 @@ const buildAnswer = (userAnswers, questionType, newValue) => {
27
30
  case 'slider':
28
31
  case 'template':
29
32
  return newValue;
30
- default:
33
+ /* istanbul ignore next */ default:
31
34
  return [];
32
35
  }
33
36
  };
34
37
  export const editAnswer = (answer) => (dispatch, getState) => {
35
38
  const state = getState();
36
- const currentSlideRef = get(['ui', 'currentSlideRef'])(state);
37
- const userAnswers = get(['ui', 'answers'])(state);
38
- const slide = get(['data', 'slides', currentSlideRef])(state);
39
- const questionType = get(['question', 'type'])(slide);
39
+ const currentSlideRef = get(['ui', 'currentSlideRef'], state);
40
+ const userAnswers = get(['ui', 'answers'], state);
41
+ const slide = get(['data', 'slides', currentSlideRef], state);
42
+ if (!slide)
43
+ throw new Error('No slide was found');
44
+ const questionType = get(['question', 'type'], slide);
40
45
  const type = get(questionType, ANSWER_EDIT);
46
+ if (!type)
47
+ throw new Error(`Question type ${questionType} is not supported`);
41
48
  return dispatch({
42
49
  type,
43
50
  payload: buildAnswer(userAnswers, questionType, answer)
@@ -1,6 +1,7 @@
1
1
  import test from 'ava';
2
2
  import pipe from 'lodash/fp/pipe';
3
3
  import set from 'lodash/fp/set';
4
+ import omit from 'lodash/fp/omit';
4
5
  import { createTestStore } from '../../test/create-test-store';
5
6
  import { services } from '../../../test/util/services.mock';
6
7
  import { freeTextSlide } from '../../../views/slides/test/fixtures/free-text';
@@ -38,7 +39,8 @@ const initialState = {
38
39
  },
39
40
  slides: {},
40
41
  skills: [],
41
- token: '1234'
42
+ token: '1234',
43
+ corrections: {}
42
44
  },
43
45
  ui: {
44
46
  currentSlideRef: '',
@@ -52,6 +54,20 @@ const initialState = {
52
54
  const buildInitialState = (state, question) => {
53
55
  return pipe(set(['data', 'progression', 'state', 'nextContent', 'ref'], question._id), set(['data', 'slides', question._id], question), set(['ui', 'currentSlideRef'], question._id))(state);
54
56
  };
57
+ test('editAnswer should throw an Error if the slide is not found', async (t) => {
58
+ const state = buildInitialState(initialState, freeTextSlide);
59
+ const expectedActions = [{ type: undefined, payload: [] }];
60
+ const { dispatch } = createTestStore(t, omit(['data', 'slides'], state), services, expectedActions);
61
+ await t.throws(() => dispatch(editAnswer(['Some kind of answer'])), undefined, 'No slide was found or questionType was not found');
62
+ });
63
+ test('editAnswer should throw an Error for unsupported questions', async (t) => {
64
+ const state = buildInitialState(initialState, {
65
+ ...freeTextSlide,
66
+ question: { ...freeTextSlide.question, type: 'unsupportedType' }
67
+ });
68
+ const { dispatch } = createTestStore(t, state, services, []);
69
+ await t.throws(() => dispatch(editAnswer(['Some kind of answer'])), undefined, 'Question type unsupportedType is not supported');
70
+ });
55
71
  test('should dispatch EDIT_BASIC action when editAnswer is called', async (t) => {
56
72
  const state = buildInitialState(initialState, freeTextSlide);
57
73
  const expectedActions = [{ type: ANSWER_EDIT.basic, payload: ['My Answer'] }];
@@ -8,7 +8,8 @@ const initialState = {
8
8
  progression: null,
9
9
  slides: {},
10
10
  skills: [],
11
- token: '1234'
11
+ token: '1234',
12
+ corrections: {}
12
13
  },
13
14
  ui: {
14
15
  currentSlideRef: '',
@@ -1,18 +1,20 @@
1
+ import { CorrectionsState } from './corrections';
1
2
  import { ProgressionState } from './progression';
2
3
  import { SkillsState } from './skills';
3
4
  import { SlidesState } from './slides';
4
5
  import { TokenState } from './token';
5
6
  export declare type DataState = {
6
- isFetching?: boolean;
7
+ corrections: CorrectionsState;
7
8
  progression: ProgressionState;
8
9
  skills: SkillsState;
9
10
  slides: SlidesState;
10
11
  token: TokenState;
11
12
  };
12
13
  declare const _default: import("redux").Reducer<import("redux").CombinedState<{
14
+ corrections: CorrectionsState;
13
15
  progression: ProgressionState;
14
16
  skills: SkillsState;
15
17
  slides: SlidesState;
16
18
  token: string;
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>;
19
+ }>, import("./corrections").CorrectionsAction | 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
20
  export default _default;
@@ -1,11 +1,7 @@
1
1
  import { combineReducers } from 'redux';
2
+ import corrections from './corrections';
2
3
  import progression from './progression';
3
4
  import skills from './skills';
4
5
  import slides from './slides';
5
6
  import token from './token';
6
- export default combineReducers({
7
- progression,
8
- skills,
9
- slides,
10
- token
11
- });
7
+ export default combineReducers({ corrections, progression, skills, slides, token });
@@ -6,6 +6,7 @@ export declare type StoreState = {
6
6
  };
7
7
  declare const _default: import("redux").Reducer<import("redux").CombinedState<{
8
8
  data: import("redux").CombinedState<{
9
+ corrections: import("./data/corrections").CorrectionsState;
9
10
  progression: import("./data/progression").ProgressionState;
10
11
  skills: import("./data/skills").SkillsState;
11
12
  slides: import("./data/slides").SlidesState;
@@ -17,5 +18,5 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
17
18
  answers: import("./ui/answers").AnswerState;
18
19
  slide: import("./ui/slide").UISlideState;
19
20
  }>;
20
- }>, import("../actions/ui/slides").SetCurrentSlide | import("../actions/api/post-answer").PostAnswerRequestAction | import("../actions/api/post-answer").PostAnswerSuccessAction | import("../actions/api/post-progression").ReceivedProgression | import("../actions/api/fetch-skills").ReceivedSkills | import("./data/slides").SlidesAction | import("../actions/data/token").StoreToken | import("../actions/ui/navigation").NavigateTo | import("../actions/ui/navigation").NavigateBack | import("../actions/ui/answers").EditAnswerAction>;
21
+ }>, import("./data/corrections").CorrectionsAction | import("../actions/ui/slides").SetCurrentSlide | import("../actions/api/post-answer").PostAnswerRequestAction | import("../actions/api/post-answer").PostAnswerSuccessAction | import("../actions/api/post-progression").ReceivedProgression | import("../actions/api/fetch-skills").ReceivedSkills | import("./data/slides").SlidesAction | import("../actions/data/token").StoreToken | import("../actions/ui/navigation").NavigateTo | import("../actions/ui/navigation").NavigateBack | import("../actions/ui/answers").EditAnswerAction>;
21
22
  export default _default;
@@ -13,5 +13,5 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
13
13
  navigation: NavigationState;
14
14
  answers: AnswerState;
15
15
  slide: UISlideState;
16
- }>, import("../../actions/ui/slides").SetCurrentSlide | import("../../actions/api/post-answer").PostAnswerRequestAction | import("../../actions/ui/navigation").NavigateTo | import("../../actions/ui/navigation").NavigateBack | import("../../actions/ui/answers").EditAnswerAction>;
16
+ }>, import("../../actions/api/fetch-correction").ReceivedCorrection | import("../../actions/ui/slides").SetCurrentSlide | import("../../actions/api/post-answer").PostAnswerRequestAction | import("../../actions/ui/navigation").NavigateTo | import("../../actions/ui/navigation").NavigateBack | import("../../actions/ui/answers").EditAnswerAction>;
17
17
  export default _default;
@@ -1,8 +1,10 @@
1
1
  import { EditAnswerAction } from '../../actions/ui/answers';
2
2
  import { PostAnswerRequestAction } from '../../actions/api/post-answer';
3
+ import { ReceivedCorrection } from '../../actions/api/fetch-correction';
3
4
  export declare type UISlideState = {
4
5
  validateButton: boolean;
6
+ animateCorrectionPopin?: boolean;
5
7
  };
6
8
  export declare const initialState: UISlideState;
7
- declare const reducer: (state: UISlideState | undefined, action: PostAnswerRequestAction | EditAnswerAction) => UISlideState;
9
+ declare const reducer: (state: UISlideState | undefined, action: PostAnswerRequestAction | EditAnswerAction | ReceivedCorrection) => UISlideState;
8
10
  export default reducer;
@@ -1,8 +1,10 @@
1
1
  import compact from 'lodash/fp/compact';
2
2
  import isEmpty from 'lodash/fp/isEmpty';
3
3
  import pipe from 'lodash/fp/pipe';
4
+ import set from 'lodash/fp/set';
4
5
  import { EDIT_BASIC, EDIT_QCM, EDIT_QCM_DRAG, EDIT_QCM_GRAPHIC, EDIT_SLIDER, EDIT_TEMPLATE } from '../../actions/ui/answers';
5
6
  import { POST_ANSWER_REQUEST } from '../../actions/api/post-answer';
7
+ import { CORRECTION_FETCH_SUCCESS } from '../../actions/api/fetch-correction';
6
8
  export const initialState = { validateButton: false };
7
9
  const reducer = (
8
10
  // eslint-disable-next-line default-param-last
@@ -19,6 +21,9 @@ state = initialState, action) => {
19
21
  case POST_ANSWER_REQUEST: {
20
22
  return initialState;
21
23
  }
24
+ case CORRECTION_FETCH_SUCCESS: {
25
+ return set(['animateCorrectionPopin'], true, state);
26
+ }
22
27
  default:
23
28
  return state;
24
29
  }
@@ -1,10 +1,22 @@
1
1
  import test from 'ava';
2
2
  import reducer, { initialState } from '../slide';
3
3
  import { EDIT_BASIC } from '../../../actions/ui/answers';
4
+ import { CORRECTION_FETCH_SUCCESS } from '../../../actions/api/fetch-correction';
4
5
  test('should use initial state if no answers are found when an EditAnswerAction is received', t => {
5
6
  const state = reducer(undefined, { type: EDIT_BASIC, payload: [''] });
6
7
  t.truthy(state);
7
8
  t.false(state.validateButton);
9
+ t.falsy(state.animateCorrectionPopin);
10
+ });
11
+ test('should set animateCorrectionPopin to true if CORRECTION_FETCH_SUCCESS is received', t => {
12
+ const state = reducer(undefined, {
13
+ type: CORRECTION_FETCH_SUCCESS,
14
+ payload: undefined,
15
+ meta: { slideRef: '1234' }
16
+ });
17
+ t.truthy(state);
18
+ t.false(state.validateButton);
19
+ t.true(state.animateCorrectionPopin);
8
20
  });
9
21
  test('should return state directly when there is no corresponding action handler + have an initial state', t => {
10
22
  const state = reducer(undefined, { type: 'NOPE' });
@@ -5,6 +5,7 @@ export declare type Choice = {
5
5
  help?: string;
6
6
  onClick: Function;
7
7
  ariaLabel?: string;
8
+ 'aria-label'?: string;
8
9
  };
9
10
  export declare type QcmDrag = {
10
11
  type: 'qcmDrag';
@@ -8,7 +8,8 @@ test('should create initial props when there are no skills on the state', t => {
8
8
  progression: null,
9
9
  skills: [],
10
10
  slides: {},
11
- token: '1234'
11
+ token: '1234',
12
+ corrections: {}
12
13
  },
13
14
  ui: {
14
15
  currentSlideRef: '',
@@ -49,7 +50,8 @@ test('should create initial props when skills on the state', t => {
49
50
  }
50
51
  ],
51
52
  slides: {},
52
- token: '1234'
53
+ token: '1234',
54
+ corrections: {}
53
55
  },
54
56
  ui: {
55
57
  currentSlideRef: '',
@@ -4,14 +4,14 @@ const qcmProps = (dispatch) => (answers, question) => {
4
4
  return {
5
5
  type: 'qcm',
6
6
  answers: map(choice => {
7
- const label = choice.label || '';
7
+ const label = getOr('', 'label', choice);
8
8
  return {
9
9
  title: label,
10
10
  selected: includes(label, answers),
11
11
  onClick: () => {
12
12
  dispatch(editAnswer([label]));
13
13
  },
14
- ariaLabel: choice.label
14
+ 'aria-label': label
15
15
  };
16
16
  }, question.content.choices)
17
17
  };
@@ -20,7 +20,7 @@ const qcmDragProps = (dispatch) => (answers, question) => {
20
20
  return {
21
21
  type: 'qcmDrag',
22
22
  answers: map(choice => {
23
- const label = choice.label || '';
23
+ const label = getOr('', 'label', choice);
24
24
  const indexInAnswer = indexOf(label, answers);
25
25
  return {
26
26
  title: label,
@@ -37,14 +37,15 @@ const qcmGraphicProps = (dispatch) => (answers, question) => {
37
37
  return {
38
38
  type: 'qcmGraphic',
39
39
  answers: map(choice => {
40
- const label = choice.label || '';
40
+ const label = getOr('', 'label', choice);
41
41
  return {
42
42
  title: label,
43
43
  image: get('media.src.0.url', choice),
44
44
  selected: includes(label, answers),
45
45
  onClick: () => {
46
46
  dispatch(editAnswer([label]));
47
- }
47
+ },
48
+ ariaLabel: label
48
49
  };
49
50
  }, question.content.choices)
50
51
  };
@@ -106,8 +107,8 @@ const templateProps = (dispatch) => (answers, question) => {
106
107
  const basicProps = (dispatch) => (answers, question) => {
107
108
  return {
108
109
  type: 'freeText',
109
- placeholder: question.content.placeholder || '',
110
- value: answers[0] || '',
110
+ placeholder: getOr('', 'content.placeholder', question),
111
+ value: getOr('', '0', answers),
111
112
  onChange: (text) => {
112
113
  dispatch(editAnswer([text]));
113
114
  }
@@ -74,13 +74,15 @@ export const qcmGraphicUISlide = {
74
74
  title: 'Vrai',
75
75
  image: '//static.coorpacademy.com/content/CoorpAcademy/content-partnerships/cockpit-partner-au-feminin/default/true-1512554153232.jpg',
76
76
  selected: false,
77
- onClick: noop
77
+ onClick: noop,
78
+ ariaLabel: 'Vrai'
78
79
  },
79
80
  {
80
81
  title: 'Faux',
81
82
  image: '//static.coorpacademy.com/content/CoorpAcademy/content-partnerships/cockpit-partner-au-feminin/default/false-1512554160848.jpg',
82
83
  selected: false,
83
- onClick: noop
84
+ onClick: noop,
85
+ ariaLabel: 'Faux'
84
86
  }
85
87
  ]
86
88
  }
@@ -83,25 +83,25 @@ export const qcmUISlide = {
83
83
  title: 'Le créateur peut fixer un pourcentage pour chaque transaction future',
84
84
  selected: false,
85
85
  onClick: noop,
86
- ariaLabel: 'Le créateur peut fixer un pourcentage pour chaque transaction future'
86
+ 'aria-label': 'Le créateur peut fixer un pourcentage pour chaque transaction future'
87
87
  },
88
88
  {
89
89
  title: "Pour chaque transaction il existe un pourcentage fixe déterminé par le droit d'auteur du pays où se tient la vente",
90
90
  selected: false,
91
91
  onClick: noop,
92
- ariaLabel: "Pour chaque transaction il existe un pourcentage fixe déterminé par le droit d'auteur du pays où se tient la vente"
92
+ 'aria-label': "Pour chaque transaction il existe un pourcentage fixe déterminé par le droit d'auteur du pays où se tient la vente"
93
93
  },
94
94
  {
95
95
  title: "Seule la galerie ou la plateforme peut toucher une commission sur la vente d'un NFT",
96
96
  selected: false,
97
97
  onClick: noop,
98
- ariaLabel: "Seule la galerie ou la plateforme peut toucher une commission sur la vente d'un NFT"
98
+ 'aria-label': "Seule la galerie ou la plateforme peut toucher une commission sur la vente d'un NFT"
99
99
  },
100
100
  {
101
101
  title: "Les NFT payés en ETH ne peuvent pas être soumis au paiement d'une commission",
102
102
  selected: false,
103
103
  onClick: noop,
104
- ariaLabel: "Les NFT payés en ETH ne peuvent pas être soumis au paiement d'une commission"
104
+ 'aria-label': "Les NFT payés en ETH ne peuvent pas être soumis au paiement d'une commission"
105
105
  }
106
106
  ]
107
107
  }
@@ -18,7 +18,8 @@ test('should create initial props when fetched slide is not still received', t =
18
18
  slides: {
19
19
  sli_N1XACJobn: null
20
20
  },
21
- token: '1234'
21
+ token: '1234',
22
+ corrections: {}
22
23
  },
23
24
  ui: {
24
25
  currentSlideRef: '',
@@ -105,7 +106,8 @@ test('should create props when first slide is on the state', t => {
105
106
  slides: {
106
107
  sli_VJYjJnJhg: freeTextSlide
107
108
  },
108
- token: '1234'
109
+ token: '1234',
110
+ corrections: {}
109
111
  },
110
112
  ui: {
111
113
  currentSlideRef: 'sli_VJYjJnJhg',
@@ -203,7 +205,8 @@ test('should create props when slide is on the state and user has selected answe
203
205
  slides: {
204
206
  sli_VJYjJnJhg: freeTextSlide
205
207
  },
206
- token: '1234'
208
+ token: '1234',
209
+ corrections: {}
207
210
  },
208
211
  ui: {
209
212
  currentSlideRef: 'sli_VJYjJnJhg',
@@ -302,7 +305,8 @@ test('should verify props when first slide was answered correctly and next slide
302
305
  sli_VJYjJnJhg: freeTextSlide,
303
306
  sli_VkSQroQnx: null
304
307
  },
305
- token: '1234'
308
+ token: '1234',
309
+ corrections: {}
306
310
  },
307
311
  ui: {
308
312
  currentSlideRef: 'sli_VJYjJnJhg',
@@ -401,7 +405,8 @@ test('should verify props when first slide was answered with error and next slid
401
405
  sli_VJYjJnJhg: freeTextSlide,
402
406
  sli_VkSQroQnx: null
403
407
  },
404
- token: '1234'
408
+ token: '1234',
409
+ corrections: {}
405
410
  },
406
411
  ui: {
407
412
  currentSlideRef: 'sli_VJYjJnJhg',
@@ -458,7 +463,8 @@ test('should verify props when first slide was answered and next slide is fecthe
458
463
  sli_VJYjJnJhg: freeTextSlide,
459
464
  sli_VkSQroQnx: qcmGraphicSlide
460
465
  },
461
- token: '1234'
466
+ token: '1234',
467
+ corrections: {}
462
468
  },
463
469
  ui: {
464
470
  currentSlideRef: 'sli_VJYjJnJhg',
@@ -559,7 +565,8 @@ test('should verify props when currentSlideRef has changed to nextContent of pro
559
565
  sli_VJYjJnJhg: freeTextSlide,
560
566
  sli_VkSQroQnx: qcmGraphicSlide
561
567
  },
562
- token: '1234'
568
+ token: '1234',
569
+ corrections: {}
563
570
  },
564
571
  ui: {
565
572
  currentSlideRef: 'sli_VkSQroQnx',
@@ -620,7 +627,8 @@ test('should verify props when progression is in success', t => {
620
627
  [sliderSlide.universalRef]: sliderSlide,
621
628
  [templateSlide.universalRef]: templateSlide
622
629
  },
623
- token: '1234'
630
+ token: '1234',
631
+ corrections: {}
624
632
  },
625
633
  ui: {
626
634
  currentSlideRef: templateSlide.universalRef,
@@ -681,7 +689,8 @@ test('should verify props when progression has answered a current pendingslide',
681
689
  [sliderSlide.universalRef]: sliderSlide,
682
690
  [templateSlide.universalRef]: templateSlide
683
691
  },
684
- token: '1234'
692
+ token: '1234',
693
+ corrections: {}
685
694
  },
686
695
  ui: {
687
696
  currentSlideRef: freeTextSlide.universalRef,
@@ -740,7 +749,8 @@ test('should verify props when progression has still pendingslide', t => {
740
749
  [sliderSlide.universalRef]: sliderSlide,
741
750
  [templateSlide.universalRef]: templateSlide
742
751
  },
743
- token: '1234'
752
+ token: '1234',
753
+ corrections: {}
744
754
  },
745
755
  ui: {
746
756
  currentSlideRef: qcmSlide.universalRef,