@coorpacademy/app-review 0.2.8 → 0.2.9

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 (98) hide show
  1. package/es/actions/api/fetch-rank.d.ts +32 -0
  2. package/es/actions/api/fetch-rank.js +30 -0
  3. package/es/actions/api/test/fetch-correction.test.js +2 -1
  4. package/es/actions/api/test/fetch-rank.test.d.ts +1 -0
  5. package/es/actions/api/test/fetch-rank.test.js +100 -0
  6. package/es/actions/api/test/fetch-skills.test.js +2 -1
  7. package/es/actions/api/test/fetch-slide.test.js +2 -1
  8. package/es/actions/api/test/post-answer.test.js +2 -1
  9. package/es/actions/api/test/post-progression.test.js +2 -1
  10. package/es/actions/data/test/token.test.js +2 -1
  11. package/es/actions/ui/test/answers.test.js +2 -1
  12. package/es/actions/ui/test/slides.test.js +2 -1
  13. package/es/reducers/data/corrections.d.ts +1 -1
  14. package/es/reducers/data/index.d.ts +4 -1
  15. package/es/reducers/data/index.js +2 -1
  16. package/es/reducers/data/rank.d.ts +7 -0
  17. package/es/reducers/data/rank.js +36 -0
  18. package/es/reducers/data/test/rank.test.d.ts +1 -0
  19. package/es/reducers/data/test/rank.test.js +59 -0
  20. package/es/reducers/index.d.ts +4 -3
  21. package/es/reducers/ui/slide.d.ts +1 -0
  22. package/es/reducers/ui/slide.js +1 -1
  23. package/es/test/util/services.mock.d.ts +1 -0
  24. package/es/test/util/services.mock.js +16 -0
  25. package/es/views/skills/test/skills.test.js +4 -2
  26. package/es/views/slides/index.d.ts +21 -19
  27. package/es/views/slides/index.js +29 -3
  28. package/es/views/slides/test/fixtures/qcm-graphic.js +190 -28
  29. package/es/views/slides/test/index.test.js +200 -19
  30. package/es/views/slides/test/slide.free-text.on-change.test.js +4 -1
  31. package/es/views/slides/test/slide.qcm-drag.on-click.test.js +4 -1
  32. package/es/views/slides/test/slide.qcm-graphic.on-click.test.js +6 -3
  33. package/es/views/slides/test/slide.qcm.on-click.test.js +4 -1
  34. package/es/views/slides/test/slide.slider.on-change.test.js +4 -1
  35. package/es/views/slides/test/slide.template.on-change.test.js +6 -1
  36. package/lib/actions/api/fetch-rank.d.ts +32 -0
  37. package/lib/actions/api/fetch-rank.js +32 -0
  38. package/lib/actions/api/test/fetch-correction.test.js +2 -1
  39. package/lib/actions/api/test/fetch-rank.test.d.ts +1 -0
  40. package/lib/actions/api/test/fetch-rank.test.js +171 -0
  41. package/lib/actions/api/test/fetch-skills.test.js +2 -1
  42. package/lib/actions/api/test/fetch-slide.test.js +2 -1
  43. package/lib/actions/api/test/post-answer.test.js +2 -1
  44. package/lib/actions/api/test/post-progression.test.js +2 -1
  45. package/lib/actions/data/test/token.test.js +2 -1
  46. package/lib/actions/ui/test/answers.test.js +2 -1
  47. package/lib/actions/ui/test/slides.test.js +2 -1
  48. package/lib/reducers/data/corrections.d.ts +1 -1
  49. package/lib/reducers/data/index.d.ts +4 -1
  50. package/lib/reducers/data/index.js +2 -1
  51. package/lib/reducers/data/rank.d.ts +7 -0
  52. package/lib/reducers/data/rank.js +37 -0
  53. package/lib/reducers/data/test/rank.test.d.ts +1 -0
  54. package/lib/reducers/data/test/rank.test.js +59 -0
  55. package/lib/reducers/index.d.ts +4 -3
  56. package/lib/reducers/ui/slide.d.ts +1 -0
  57. package/lib/reducers/ui/slide.js +1 -1
  58. package/lib/test/util/services.mock.d.ts +1 -0
  59. package/lib/test/util/services.mock.js +7 -0
  60. package/lib/views/skills/test/skills.test.js +4 -2
  61. package/lib/views/slides/index.d.ts +21 -19
  62. package/lib/views/slides/index.js +29 -3
  63. package/lib/views/slides/test/fixtures/qcm-graphic.js +190 -28
  64. package/lib/views/slides/test/index.test.js +211 -22
  65. package/lib/views/slides/test/slide.free-text.on-change.test.js +4 -1
  66. package/lib/views/slides/test/slide.qcm-drag.on-click.test.js +4 -1
  67. package/lib/views/slides/test/slide.qcm-graphic.on-click.test.js +6 -3
  68. package/lib/views/slides/test/slide.qcm.on-click.test.js +4 -1
  69. package/lib/views/slides/test/slide.slider.on-change.test.js +4 -1
  70. package/lib/views/slides/test/slide.template.on-change.test.js +6 -1
  71. package/package.json +3 -3
  72. package/src/actions/api/fetch-rank.ts +84 -0
  73. package/src/actions/api/test/fetch-correction.test.ts +2 -1
  74. package/src/actions/api/test/fetch-rank.test.ts +130 -0
  75. package/src/actions/api/test/fetch-skills.test.ts +2 -1
  76. package/src/actions/api/test/fetch-slide.test.ts +2 -1
  77. package/src/actions/api/test/post-answer.test.ts +2 -1
  78. package/src/actions/api/test/post-progression.test.ts +2 -1
  79. package/src/actions/data/test/token.test.ts +2 -1
  80. package/src/actions/ui/test/answers.test.ts +2 -1
  81. package/src/actions/ui/test/slides.test.ts +2 -1
  82. package/src/reducers/data/corrections.ts +1 -1
  83. package/src/reducers/data/index.ts +3 -1
  84. package/src/reducers/data/rank.ts +60 -0
  85. package/src/reducers/data/test/rank.test.ts +78 -0
  86. package/src/reducers/index.ts +2 -2
  87. package/src/reducers/ui/slide.ts +2 -1
  88. package/src/test/util/services.mock.ts +17 -0
  89. package/src/views/skills/test/skills.test.ts +4 -2
  90. package/src/views/slides/index.ts +65 -22
  91. package/src/views/slides/test/fixtures/qcm-graphic.ts +196 -29
  92. package/src/views/slides/test/index.test.ts +210 -21
  93. package/src/views/slides/test/slide.free-text.on-change.test.ts +4 -1
  94. package/src/views/slides/test/slide.qcm-drag.on-click.test.ts +4 -1
  95. package/src/views/slides/test/slide.qcm-graphic.on-click.test.ts +6 -4
  96. package/src/views/slides/test/slide.qcm.on-click.test.ts +4 -1
  97. package/src/views/slides/test/slide.slider.on-change.test.ts +4 -1
  98. package/src/views/slides/test/slide.template.on-change.test.ts +6 -1
@@ -0,0 +1,130 @@
1
+ import test from 'ava';
2
+ import type {Services} from '../../../types/common';
3
+ import type {StoreState} from '../../../reducers';
4
+ import {
5
+ fetchStartRank,
6
+ fetchEndRank,
7
+ RANK_FETCH_START_REQUEST,
8
+ RANK_FETCH_START_SUCCESS,
9
+ RANK_FETCH_START_FAILURE,
10
+ RANK_FETCH_END_REQUEST,
11
+ RANK_FETCH_END_SUCCESS,
12
+ RANK_FETCH_END_FAILURE
13
+ } from '../fetch-rank';
14
+ import {services as mockedServices} from '../../../test/util/services.mock';
15
+ import {createTestStore} from '../../test/create-test-store';
16
+
17
+ const initialState: StoreState = {
18
+ data: {
19
+ progression: null,
20
+ slides: {},
21
+ skills: [],
22
+ token: '1234',
23
+ corrections: {},
24
+ rank: {}
25
+ },
26
+ ui: {
27
+ currentSlideRef: '',
28
+ navigation: [],
29
+ answers: [],
30
+ slide: {
31
+ validateButton: false
32
+ }
33
+ }
34
+ };
35
+
36
+ test('should dispatch FETCH_START_SUCCESS action when fetchStartRank returns the start rank', async t => {
37
+ t.plan(3);
38
+
39
+ const services: Services = {
40
+ ...mockedServices,
41
+ fetchRank: token => {
42
+ t.is(token, '1234');
43
+ return Promise.resolve({rank: 93});
44
+ }
45
+ };
46
+ const expectedActions = [
47
+ {type: RANK_FETCH_START_REQUEST},
48
+ {
49
+ type: RANK_FETCH_START_SUCCESS,
50
+ payload: {rank: 93}
51
+ }
52
+ ];
53
+
54
+ const {dispatch} = createTestStore(t, initialState, services, expectedActions);
55
+ await dispatch(fetchStartRank);
56
+ });
57
+
58
+ test('should dispatch FETCH_START_FAILURE action when fetchStartRank fails', async t => {
59
+ t.plan(3);
60
+
61
+ const services: Services = {
62
+ ...mockedServices,
63
+ fetchRank: token => {
64
+ t.is(token, '1234');
65
+ return Promise.reject(new Error('unexpected'));
66
+ }
67
+ };
68
+
69
+ const expectedActions = [
70
+ {type: RANK_FETCH_START_REQUEST},
71
+ {
72
+ type: RANK_FETCH_START_FAILURE,
73
+ payload: new Error('unexpected'),
74
+ error: true
75
+ }
76
+ ];
77
+
78
+ const {dispatch} = createTestStore(t, initialState, services, expectedActions);
79
+
80
+ await dispatch(fetchStartRank);
81
+ });
82
+
83
+ test('should dispatch FETCH_END_SUCCESS action when fetchEndRank returns the end rank', async t => {
84
+ t.plan(3);
85
+
86
+ const services: Services = {
87
+ ...mockedServices,
88
+ fetchRank: token => {
89
+ t.is(token, '1234');
90
+ return Promise.resolve({rank: 93});
91
+ }
92
+ };
93
+
94
+ const expectedActions = [
95
+ {type: RANK_FETCH_END_REQUEST},
96
+ {
97
+ type: RANK_FETCH_END_SUCCESS,
98
+ payload: {rank: 93}
99
+ }
100
+ ];
101
+
102
+ const {dispatch} = createTestStore(t, initialState, services, expectedActions);
103
+
104
+ await dispatch(fetchEndRank);
105
+ });
106
+
107
+ test('should dispatch FETCH_END_FAILURE action when fetchEndRank fails', async t => {
108
+ t.plan(3);
109
+
110
+ const services: Services = {
111
+ ...mockedServices,
112
+ fetchRank: token => {
113
+ t.is(token, '1234');
114
+ return Promise.reject(new Error('unexpected'));
115
+ }
116
+ };
117
+
118
+ const expectedActions = [
119
+ {type: RANK_FETCH_END_REQUEST},
120
+ {
121
+ type: RANK_FETCH_END_FAILURE,
122
+ payload: new Error('unexpected'),
123
+ error: true
124
+ }
125
+ ];
126
+
127
+ const {dispatch} = createTestStore(t, initialState, services, expectedActions);
128
+
129
+ await dispatch(fetchEndRank);
130
+ });
@@ -16,7 +16,8 @@ const initialState: StoreState = {
16
16
  slides: {},
17
17
  skills: [],
18
18
  token: '1234',
19
- corrections: {}
19
+ corrections: {},
20
+ rank: {}
20
21
  },
21
22
  ui: {
22
23
  currentSlideRef: '',
@@ -18,7 +18,8 @@ const initialState: StoreState = {
18
18
  slides: {},
19
19
  skills: [],
20
20
  token: '1234',
21
- corrections: {}
21
+ corrections: {},
22
+ rank: {}
22
23
  },
23
24
  ui: {
24
25
  currentSlideRef: '',
@@ -50,7 +50,8 @@ const initialState: StoreState = {
50
50
  },
51
51
  skills: [{skillRef, custom: false, name: skillRef, slidesToReview: 5}],
52
52
  token: '1234',
53
- corrections: {}
53
+ corrections: {},
54
+ rank: {}
54
55
  },
55
56
  ui: {
56
57
  currentSlideRef: freeTextSlide._id,
@@ -19,7 +19,8 @@ const initialState: StoreState = {
19
19
  slides: {},
20
20
  skills: [],
21
21
  token: '1234',
22
- corrections: {}
22
+ corrections: {},
23
+ rank: {}
23
24
  },
24
25
  ui: {
25
26
  currentSlideRef: '',
@@ -10,7 +10,8 @@ const initialState: StoreState = {
10
10
  slides: {},
11
11
  skills: [],
12
12
  token: '1234',
13
- corrections: {}
13
+ corrections: {},
14
+ rank: {}
14
15
  },
15
16
  ui: {
16
17
  currentSlideRef: '',
@@ -44,7 +44,8 @@ const initialState: StoreState = {
44
44
  slides: {},
45
45
  skills: [],
46
46
  token: '1234',
47
- corrections: {}
47
+ corrections: {},
48
+ rank: {}
48
49
  },
49
50
  ui: {
50
51
  currentSlideRef: '',
@@ -11,7 +11,8 @@ const initialState: StoreState = {
11
11
  slides: {},
12
12
  skills: [],
13
13
  token: '1234',
14
- corrections: {}
14
+ corrections: {},
15
+ rank: {}
15
16
  },
16
17
  ui: {
17
18
  currentSlideRef: '',
@@ -1,5 +1,5 @@
1
1
  import set from 'lodash/fp/set';
2
- import {CorrectionFromAPI} from '../../types/common';
2
+ import type {CorrectionFromAPI} from '../../types/common';
3
3
  import {
4
4
  ReceivedCorrection,
5
5
  CORRECTION_FETCH_SUCCESS,
@@ -5,6 +5,7 @@ import progression, {ProgressionState} from './progression';
5
5
  import skills, {SkillsState} from './skills';
6
6
  import slides, {SlidesState} from './slides';
7
7
  import token, {TokenState} from './token';
8
+ import rank, {RankState} from './rank';
8
9
 
9
10
  export type DataState = {
10
11
  corrections: CorrectionsState;
@@ -12,6 +13,7 @@ export type DataState = {
12
13
  skills: SkillsState;
13
14
  slides: SlidesState;
14
15
  token: TokenState;
16
+ rank: RankState;
15
17
  };
16
18
 
17
- export default combineReducers({corrections, progression, skills, slides, token});
19
+ export default combineReducers({corrections, progression, skills, slides, token, rank});
@@ -0,0 +1,60 @@
1
+ import {get, isNull, isUndefined, pipe, set, unset, update} from 'lodash/fp';
2
+ import {
3
+ RankAction,
4
+ RANK_FETCH_START_REQUEST,
5
+ RANK_FETCH_START_SUCCESS,
6
+ RANK_FETCH_START_FAILURE,
7
+ RANK_FETCH_END_REQUEST,
8
+ RANK_FETCH_END_SUCCESS,
9
+ RANK_FETCH_END_FAILURE
10
+ } from '../../actions/api/fetch-rank';
11
+
12
+ export type RankState = {
13
+ start?: number | null;
14
+ end?: number | null;
15
+ };
16
+
17
+ const initialState: RankState = {};
18
+
19
+ const reducer = (
20
+ // eslint-disable-next-line default-param-last
21
+ state: RankState = initialState,
22
+ action: RankAction
23
+ ): RankState => {
24
+ switch (action.type) {
25
+ case RANK_FETCH_START_REQUEST: {
26
+ return update(
27
+ 'start',
28
+ (startRank: RankState['start']) => (isUndefined(startRank) ? null : startRank),
29
+ state
30
+ );
31
+ }
32
+ case RANK_FETCH_START_SUCCESS: {
33
+ const {payload} = action;
34
+ return set('start', payload.rank, state);
35
+ }
36
+ case RANK_FETCH_START_FAILURE: {
37
+ if (pipe(get('start'), isNull)(state)) return unset('start', state);
38
+ return state;
39
+ }
40
+ case RANK_FETCH_END_REQUEST: {
41
+ return update(
42
+ 'end',
43
+ (endRank: RankState['end']) => (isUndefined(endRank) ? null : endRank),
44
+ state
45
+ );
46
+ }
47
+ case RANK_FETCH_END_SUCCESS: {
48
+ const {payload} = action;
49
+ return set('end', payload.rank, state);
50
+ }
51
+ case RANK_FETCH_END_FAILURE: {
52
+ if (pipe(get('end'), isNull)(state)) return unset('end', state);
53
+ return state;
54
+ }
55
+ default:
56
+ return state;
57
+ }
58
+ };
59
+
60
+ export default reducer;
@@ -0,0 +1,78 @@
1
+ import test from 'ava';
2
+ import reducer from '../rank';
3
+ import {
4
+ RankAction,
5
+ RANK_FETCH_START_REQUEST,
6
+ RANK_FETCH_START_SUCCESS,
7
+ RANK_FETCH_START_FAILURE,
8
+ RANK_FETCH_END_REQUEST,
9
+ RANK_FETCH_END_SUCCESS,
10
+ RANK_FETCH_END_FAILURE
11
+ } from '../../../actions/api/fetch-rank';
12
+
13
+ test('should have initial value', t => {
14
+ const state = reducer(undefined, {} as RankAction);
15
+ t.deepEqual(state, {});
16
+ });
17
+
18
+ test("should set the start value to null if the value doesn't exist of FETCH_START_REQUEST action", t => {
19
+ const state = reducer({}, {type: RANK_FETCH_START_REQUEST});
20
+ t.deepEqual(state, {
21
+ start: null
22
+ });
23
+ });
24
+
25
+ test('should do nothing if a start value already exists of FETCH_START_REQUEST action', t => {
26
+ const state = reducer({start: 93}, {type: RANK_FETCH_START_REQUEST});
27
+ t.deepEqual(state, {
28
+ start: 93
29
+ });
30
+ });
31
+
32
+ test('should set the start value of FETCH_START_SUCCESS action', t => {
33
+ const state = reducer({}, {type: RANK_FETCH_START_SUCCESS, payload: {rank: 93}});
34
+ t.deepEqual(state, {
35
+ start: 93
36
+ });
37
+ });
38
+
39
+ test('should unset the start value if the value is null of FETCH_START_FAILURE action', t => {
40
+ const state = reducer({start: null}, {type: RANK_FETCH_START_FAILURE});
41
+ t.deepEqual(state, {});
42
+ });
43
+
44
+ test('should do nothing if the start value already exists of FETCH_START_FAILURE action', t => {
45
+ const state = reducer({start: 93}, {type: RANK_FETCH_START_FAILURE});
46
+ t.deepEqual(state, {start: 93});
47
+ });
48
+
49
+ test("should set the end value to null if the value doesn't exist of FETCH_END_REQUEST action", t => {
50
+ const state = reducer({}, {type: RANK_FETCH_END_REQUEST});
51
+ t.deepEqual(state, {
52
+ end: null
53
+ });
54
+ });
55
+
56
+ test('should do nothing if an end value already exists of FETCH_END_REQUEST action', t => {
57
+ const state = reducer({end: 94}, {type: RANK_FETCH_END_REQUEST});
58
+ t.deepEqual(state, {
59
+ end: 94
60
+ });
61
+ });
62
+
63
+ test('should set the end value of FETCH_END_SUCCESS action', t => {
64
+ const state = reducer({}, {type: RANK_FETCH_END_SUCCESS, payload: {rank: 94}});
65
+ t.deepEqual(state, {
66
+ end: 94
67
+ });
68
+ });
69
+
70
+ test('should unset the end value if the value is null of FETCH_END_FAILURE action', t => {
71
+ const state = reducer({end: null}, {type: RANK_FETCH_END_FAILURE});
72
+ t.deepEqual(state, {});
73
+ });
74
+
75
+ test('should do nothing if the end value already exists of FETCH_END_FAILURE action', t => {
76
+ const state = reducer({end: 94}, {type: RANK_FETCH_END_FAILURE});
77
+ t.deepEqual(state, {end: 94});
78
+ });
@@ -1,7 +1,7 @@
1
1
  import {combineReducers} from 'redux';
2
2
 
3
- import data, {DataState} from './data';
4
- import ui, {UIState} from './ui';
3
+ import data, {type DataState} from './data';
4
+ import ui, {type UIState} from './ui';
5
5
 
6
6
  export type StoreState = {
7
7
  ui: UIState;
@@ -17,6 +17,7 @@ import {CORRECTION_FETCH_SUCCESS, ReceivedCorrection} from '../../actions/api/fe
17
17
  export type UISlideState = {
18
18
  validateButton: boolean;
19
19
  animateCorrectionPopin?: boolean;
20
+ showCorrectionPopin?: boolean;
20
21
  };
21
22
 
22
23
  export const initialState: UISlideState = {validateButton: false};
@@ -39,7 +40,7 @@ const reducer = (
39
40
  return initialState;
40
41
  }
41
42
  case CORRECTION_FETCH_SUCCESS: {
42
- return set(['animateCorrectionPopin'], true, state);
43
+ return pipe(set(['animateCorrectionPopin'], true), set(['showCorrectionPopin'], true))(state);
43
44
  }
44
45
  default:
45
46
  return state;
@@ -288,6 +288,23 @@ export const postAnswerResponses: Record<string, ProgressionFromAPI> = {
288
288
  }
289
289
  };
290
290
 
291
+ export const incorrectFreeTextPostAnswerResponse: ProgressionFromAPI = {
292
+ ...postAnswerResponses[freeTextSlide.universalRef],
293
+ state: {
294
+ ...postAnswerResponses[freeTextSlide.universalRef].state,
295
+ isCorrect: false,
296
+ allAnswers: [
297
+ {
298
+ slideRef: freeTextSlide.universalRef,
299
+ isCorrect: false,
300
+ answer: ['NOPE']
301
+ }
302
+ ],
303
+ pendingSlides: [freeTextSlide.universalRef],
304
+ stars: 0
305
+ }
306
+ };
307
+
291
308
  export const progressionSlideWithPendingSlide: ProgressionFromAPI = {
292
309
  _id: '62b1d1087aa12f00253f40ee',
293
310
  content,
@@ -11,7 +11,8 @@ test('should create initial props when there are no skills on the state', t => {
11
11
  skills: [],
12
12
  slides: {},
13
13
  token: '1234',
14
- corrections: {}
14
+ corrections: {},
15
+ rank: {}
15
16
  },
16
17
  ui: {
17
18
  currentSlideRef: '',
@@ -56,7 +57,8 @@ test('should create initial props when skills on the state', t => {
56
57
  ],
57
58
  slides: {},
58
59
  token: '1234',
59
- corrections: {}
60
+ corrections: {},
61
+ rank: {}
60
62
  },
61
63
  ui: {
62
64
  currentSlideRef: '',
@@ -8,11 +8,12 @@ import reduce from 'lodash/fp/reduce';
8
8
  import set from 'lodash/fp/set';
9
9
  import slice from 'lodash/fp/slice';
10
10
  import toInteger from 'lodash/fp/toInteger';
11
- import {Dispatch} from 'redux';
12
- import {ProgressionAnswerItem, ProgressionFromAPI} from '../../types/common';
13
- import {SlideIndexes} from '../../common';
14
- import {StoreState} from '../../reducers';
15
- import {AnswerUI} from '../../types/slides';
11
+ import type {Dispatch} from 'redux';
12
+ import join from 'lodash/fp/join';
13
+ import type {ProgressionAnswerItem, ProgressionFromAPI} from '../../types/common';
14
+ import type {SlideIndexes} from '../../common';
15
+ import type {StoreState} from '../../reducers';
16
+ import type {AnswerUI} from '../../types/slides';
16
17
  import {postAnswer} from '../../actions/api/post-answer';
17
18
  import {mapApiSlideToUi} from './map-api-slide-to-ui';
18
19
 
@@ -47,22 +48,27 @@ type SlidesStack = {
47
48
  [key in SlideIndexes]: UISlide;
48
49
  };
49
50
 
51
+ type CorrectionPopinInformation = {
52
+ label: string;
53
+ message: string;
54
+ };
55
+
56
+ type CorrectionPopinKlf = {
57
+ label: string;
58
+ tooltip: string;
59
+ };
60
+
61
+ type CorrectionPopinNext = {
62
+ label: string;
63
+ ariaLabel: string;
64
+ };
65
+
50
66
  export type CorrectionPopinProps = {
51
- klf: {
52
- label: string;
53
- onClick: Function;
54
- tooltip: string;
55
- };
56
- information: {
57
- label: string;
58
- message: string;
59
- };
60
- next: {
61
- label: string;
62
- ariaLabel: string;
63
- };
64
- successLabel: string;
65
- failureLabel: string;
67
+ klf?: CorrectionPopinKlf;
68
+ information: CorrectionPopinInformation;
69
+ next: CorrectionPopinNext;
70
+ resultLabel: string;
71
+ type: 'right' | 'wrong';
66
72
  };
67
73
 
68
74
  export type SlidesViewProps = {
@@ -164,7 +170,15 @@ const buildStackSlides = (state: StoreState, dispatch: Dispatch): SlidesStack =>
164
170
  const parentContentTitle = getOr('', 'parentContentTitle.title', slideFromAPI);
165
171
  const parentContentType = getOr('', 'parentContentTitle.type', slideFromAPI);
166
172
 
173
+ const isCurrentSlideRef = currentSlideRef === slideRef;
174
+ const animateCorrectionPopin =
175
+ isCurrentSlideRef && getOr(false, ['ui', 'slide', 'animateCorrectionPopin'], state);
176
+ const showCorrectionPopin =
177
+ isCurrentSlideRef && getOr(false, ['ui', 'slide', 'showCorrectionPopin'], state);
178
+
167
179
  const updatedUiSlide = pipe(
180
+ set('showCorrectionPopin', showCorrectionPopin),
181
+ set('animateCorrectionPopin', animateCorrectionPopin),
168
182
  set('loading', false),
169
183
  set('questionText', questionText),
170
184
  set('answerUI', answerUI),
@@ -261,7 +275,35 @@ export const buildStepItems = (state: StoreState): StepItem[] => {
261
275
  return steps;
262
276
  };
263
277
 
278
+ const getCorrectionPopinProps = (
279
+ isCorrect: boolean,
280
+ correctAnswer: string[],
281
+ klf: string
282
+ ): CorrectionPopinProps => ({
283
+ klf: isCorrect
284
+ ? undefined
285
+ : {
286
+ label: '_klf',
287
+ tooltip: klf
288
+ },
289
+ resultLabel: isCorrect ? '_right' : '_wrong',
290
+ information: {
291
+ label: isCorrect ? '_klf' : '_correctAnswer',
292
+ message: isCorrect ? klf : join(',', correctAnswer)
293
+ },
294
+ next: {
295
+ ariaLabel: '_correctionNextAriaLabel',
296
+ label: '_correctionNextLabel'
297
+ },
298
+ type: isCorrect ? 'right' : 'wrong'
299
+ });
300
+
264
301
  export const mapStateToSlidesProps = (state: StoreState, dispatch: Dispatch): SlidesViewProps => {
302
+ const currentSlideRef = get(['ui', 'currentSlideRef'], state);
303
+ const correction = get(['data', 'corrections', currentSlideRef], state);
304
+ const isCorrect = get(['data', 'progression', 'state', 'isCorrect'], state);
305
+ const klf = getOr('', ['data', 'slides', currentSlideRef, 'klf'], state);
306
+
265
307
  return {
266
308
  header: {
267
309
  mode: '__revision_mode',
@@ -279,11 +321,12 @@ export const mapStateToSlidesProps = (state: StoreState, dispatch: Dispatch): Sl
279
321
  validateButton: {
280
322
  label: '__validate',
281
323
  disabled: !get('ui.slide.validateButton', state),
282
- onClick: (): void => {
324
+ onClick: /* istanbul ignore next */ (): void => {
283
325
  dispatch(postAnswer);
284
326
  }
285
327
  },
286
- correctionPopinProps: undefined,
328
+ correctionPopinProps:
329
+ correction && getCorrectionPopinProps(isCorrect, correction.correctAnswer, klf),
287
330
  endReview: false
288
331
  },
289
332
  congratsProps: undefined