@coorpacademy/app-review 0.1.18 → 0.1.20

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 (34) hide show
  1. package/es/actions/api/post-answer.js +9 -8
  2. package/es/actions/api/test/post-answer.test.js +6 -6
  3. package/es/reducers/data/test/progression.test.js +4 -3
  4. package/es/services/post-answer.d.ts +1 -1
  5. package/es/services/post-answer.js +3 -1
  6. package/es/services/test/post-answer.test.js +27 -4
  7. package/es/test/util/services.mock.d.ts +2 -1
  8. package/es/test/util/services.mock.js +264 -23
  9. package/es/types/common.d.ts +11 -9
  10. package/es/views/slides/index.d.ts +1 -0
  11. package/es/views/slides/index.js +24 -8
  12. package/es/views/slides/test/index.test.js +518 -203
  13. package/lib/actions/api/post-answer.js +10 -9
  14. package/lib/actions/api/test/post-answer.test.js +6 -6
  15. package/lib/reducers/data/test/progression.test.js +4 -3
  16. package/lib/services/post-answer.d.ts +1 -1
  17. package/lib/services/post-answer.js +4 -2
  18. package/lib/services/test/post-answer.test.js +27 -4
  19. package/lib/test/util/services.mock.d.ts +2 -1
  20. package/lib/test/util/services.mock.js +265 -23
  21. package/lib/types/common.d.ts +11 -9
  22. package/lib/views/slides/index.d.ts +1 -0
  23. package/lib/views/slides/index.js +23 -7
  24. package/lib/views/slides/test/index.test.js +521 -203
  25. package/package.json +3 -4
  26. package/src/actions/api/post-answer.ts +9 -9
  27. package/src/actions/api/test/post-answer.test.ts +6 -6
  28. package/src/reducers/data/test/progression.test.ts +4 -3
  29. package/src/services/post-answer.ts +3 -2
  30. package/src/services/test/post-answer.test.ts +28 -4
  31. package/src/test/util/services.mock.ts +274 -24
  32. package/src/types/common.ts +13 -10
  33. package/src/views/slides/index.ts +35 -10
  34. package/src/views/slides/test/index.test.ts +559 -228
@@ -5,21 +5,22 @@ export const POST_ANSWER_REQUEST = '@@answer/POST_REQUEST';
5
5
  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
+ const state = getState();
9
+ const token = get('data.token', state);
10
+ const answer = get('ui.answers', state);
11
+ const progression = state.data.progression;
12
+ if (!progression)
13
+ throw new Error('cannot answer question of inexisting progression');
8
14
  const action = buildTask({
9
15
  types: [POST_ANSWER_REQUEST, POST_ANSWER_SUCCESS, POST_ANSWER_FAILURE],
10
16
  task: () => {
11
- const state = getState();
12
- const token = get('data.token', state);
13
- const answer = get('ui.answers', state);
14
- const progressionId = get('data.progression._id', state);
15
- const skillRef = get('data.progression.content.ref', state);
16
- return services.postAnswer(skillRef, token, progressionId, answer);
17
+ return services.postAnswer(progression, token, answer);
17
18
  }
18
19
  });
19
20
  const response = await dispatch(action);
20
21
  if (response.type === POST_ANSWER_SUCCESS) {
21
- const progression = response.payload;
22
- const slideRef = progression.state.nextContent.ref;
22
+ const updatedProgression = response.payload;
23
+ const slideRef = updatedProgression.state.nextContent.ref;
23
24
  await dispatch(fetchSlide(slideRef));
24
25
  }
25
26
  };
@@ -1,6 +1,6 @@
1
1
  import test from 'ava';
2
2
  import { createTestStore } from '../../test/create-test-store';
3
- import { postAnswerResponse, services } from '../../../test/util/services.mock';
3
+ import { postAnswerResponses, services } from '../../../test/util/services.mock';
4
4
  import { postAnswer, POST_ANSWER_FAILURE, POST_ANSWER_REQUEST, POST_ANSWER_SUCCESS } from '../post-answer';
5
5
  import { SLIDE_FETCH_REQUEST, SLIDE_FETCH_SUCCESS } from '../fetch-slide';
6
6
  import { qcmGraphicSlide } from '../../../views/slides/test/fixtures/qcm-graphic';
@@ -21,7 +21,7 @@ const initialState = {
21
21
  allAnswers: [],
22
22
  isCorrect: true,
23
23
  nextContent: {
24
- ref: 'sli_VJYjJnJhg',
24
+ ref: freeTextSlide.id,
25
25
  type: 'slide'
26
26
  },
27
27
  pendingSlides: [],
@@ -39,7 +39,7 @@ const initialState = {
39
39
  token: '1234'
40
40
  },
41
41
  ui: {
42
- currentSlideRef: 'sli_VJYjJnJhg',
42
+ currentSlideRef: freeTextSlide.id,
43
43
  navigation: ['skills', 'slides'],
44
44
  answers: answer,
45
45
  slide: {
@@ -52,12 +52,12 @@ test('should dispatch POST_ANSWER_REQUEST, then POST_ANSWER_SUCCESS when the upd
52
52
  { type: POST_ANSWER_REQUEST },
53
53
  {
54
54
  type: POST_ANSWER_SUCCESS,
55
- payload: postAnswerResponse
55
+ payload: postAnswerResponses[freeTextSlide.id]
56
56
  },
57
- { type: SLIDE_FETCH_REQUEST, meta: { slideRef: 'sli_VkSQroQnx' } },
57
+ { type: SLIDE_FETCH_REQUEST, meta: { slideRef: qcmGraphicSlide.id } },
58
58
  {
59
59
  type: SLIDE_FETCH_SUCCESS,
60
- meta: { slideRef: 'sli_VkSQroQnx' },
60
+ meta: { slideRef: qcmGraphicSlide.id },
61
61
  payload: qcmGraphicSlide
62
62
  },
63
63
  { type: SET_CURRENT_SLIDE, payload: qcmGraphicSlide }
@@ -2,7 +2,8 @@ import test from 'ava';
2
2
  import reducer from '../progression';
3
3
  import { POST_PROGRESSION_SUCCESS } from '../../../actions/api/post-progression';
4
4
  import { POST_ANSWER_SUCCESS } from '../../../actions/api/post-answer';
5
- import { postAnswerResponse, postProgressionResponse } from '../../../test/util/services.mock';
5
+ import { postAnswerResponses, postProgressionResponse } from '../../../test/util/services.mock';
6
+ import { freeTextSlide } from '../../../views/slides/test/fixtures/free-text';
6
7
  test('should have initial value', t => {
7
8
  const state = reducer(undefined, {});
8
9
  t.is(state, null);
@@ -17,7 +18,7 @@ test('should set the value of POST_PROGRESSION_SUCCESS action', t => {
17
18
  test('should set the value of POST_ANSWER_SUCCESS action', t => {
18
19
  const state = reducer(null, {
19
20
  type: POST_ANSWER_SUCCESS,
20
- payload: postAnswerResponse
21
+ payload: postAnswerResponses[freeTextSlide.universalRef]
21
22
  });
22
- t.deepEqual(state, postAnswerResponse);
23
+ t.deepEqual(state, postAnswerResponses[freeTextSlide.universalRef]);
23
24
  });
@@ -1,2 +1,2 @@
1
1
  import { ProgressionFromAPI } from '../types/common';
2
- export declare const postAnswer: (skillRef: string, token: string, progressionId: string, answer: string[]) => Promise<ProgressionFromAPI>;
2
+ export declare const postAnswer: (progression: ProgressionFromAPI, token: string, answer: string[]) => Promise<ProgressionFromAPI>;
@@ -1,7 +1,9 @@
1
1
  import crossFetch from 'cross-fetch';
2
2
  import decode from 'jwt-decode';
3
3
  import { toJSON } from './tools/fetch-responses';
4
- export const postAnswer = async (skillRef, token, progressionId, answer) => {
4
+ export const postAnswer = async (progression, token, answer) => {
5
+ const progressionId = progression._id;
6
+ const skillRef = progression.content.ref;
5
7
  const { host } = decode(token);
6
8
  const response = await crossFetch(`${host}/api/v2/progressions/${progressionId}/answers`, {
7
9
  method: 'post',
@@ -1,9 +1,32 @@
1
1
  import test from 'ava';
2
2
  import nock from 'nock';
3
3
  import { postAnswer } from '../post-answer';
4
- const progressionId = '123456789123';
5
4
  const skillRef = '_skill-ref';
6
5
  const answer = ['Lister vos tâches pour vous libérer l’esprit', 'Vous isoler dans un lieu calme'];
6
+ const initProgression = {
7
+ content: {
8
+ type: 'skill',
9
+ ref: skillRef
10
+ },
11
+ engine: {
12
+ ref: 'review'
13
+ },
14
+ _id: '123456123456',
15
+ state: {
16
+ allAnswers: [],
17
+ isCorrect: true,
18
+ nextContent: {
19
+ type: 'slide',
20
+ ref: 'sli_NkvrWPFF2'
21
+ },
22
+ pendingSlides: [],
23
+ slides: [],
24
+ step: {
25
+ current: 1
26
+ },
27
+ stars: 0
28
+ }
29
+ };
7
30
  const result = {
8
31
  content: {
9
32
  type: 'skill',
@@ -40,18 +63,18 @@ const result = {
40
63
  };
41
64
  test.before(() => {
42
65
  const moocApi = nock('http://localhost:3000');
43
- moocApi.post(`/api/v2/progressions/${progressionId}/answers`).reply(200, result);
66
+ moocApi.post('/api/v2/progressions/123456123456/answers').reply(200, result);
44
67
  });
45
68
  test.after(() => {
46
69
  nock.cleanAll();
47
70
  });
48
71
  test('should post the answers successfully', async (t) => {
49
72
  const token = process.env.API_TEST_TOKEN || '';
50
- const progression = await postAnswer(skillRef, token, progressionId, answer);
73
+ const progression = await postAnswer(initProgression, token, answer);
51
74
  t.deepEqual(result, progression);
52
75
  });
53
76
  test('should reject bad token', async (t) => {
54
77
  const badToken = 'token is not a jwt';
55
- const error = await t.throwsAsync(() => postAnswer(skillRef, badToken, progressionId, answer));
78
+ const error = await t.throwsAsync(() => postAnswer(initProgression, badToken, answer));
56
79
  t.is(error?.message, "Invalid token specified: Cannot read properties of undefined (reading 'replace')");
57
80
  });
@@ -1,4 +1,5 @@
1
1
  import { ProgressionFromAPI, Services } from '../../types/common';
2
2
  export declare const postProgressionResponse: ProgressionFromAPI;
3
- export declare const postAnswerResponse: ProgressionFromAPI;
3
+ export declare const postAnswerResponses: Record<string, ProgressionFromAPI>;
4
+ export declare const progressionSlideWithPendingSlide: ProgressionFromAPI;
4
5
  export declare const services: Services;
@@ -1,8 +1,16 @@
1
+ import get from 'lodash/fp/get';
1
2
  import { qcmSlide } from '../../views/slides/test/fixtures/qcm';
2
3
  import { qcmGraphicSlide } from '../../views/slides/test/fixtures/qcm-graphic';
3
4
  import { freeTextSlide } from '../../views/slides/test/fixtures/free-text';
4
5
  import { sliderSlide } from '../../views/slides/test/fixtures/slider';
5
6
  import { templateSlide } from '../../views/slides/test/fixtures/template';
7
+ const content = {
8
+ ref: '_skill-ref',
9
+ type: 'skill'
10
+ };
11
+ const engine = {
12
+ ref: 'review'
13
+ };
6
14
  const getSlideFixture = (ref) => {
7
15
  switch (ref) {
8
16
  case qcmSlide.universalRef:
@@ -33,18 +41,13 @@ const fetchSkillsResponse = [
33
41
  ];
34
42
  export const postProgressionResponse = {
35
43
  _id: '62b1d1087aa12f00253f40ee',
36
- content: {
37
- ref: '_skill-ref',
38
- type: 'skill'
39
- },
40
- engine: {
41
- ref: 'review'
42
- },
44
+ content,
45
+ engine,
43
46
  state: {
44
47
  allAnswers: [],
45
48
  isCorrect: true,
46
49
  nextContent: {
47
- ref: 'sli_VJYjJnJhg',
50
+ ref: freeTextSlide.universalRef,
48
51
  type: 'slide'
49
52
  },
50
53
  pendingSlides: [],
@@ -55,43 +58,281 @@ export const postProgressionResponse = {
55
58
  stars: 0
56
59
  }
57
60
  };
58
- export const postAnswerResponse = {
59
- _id: '62b1d1087aa12f00253f40ee',
60
- content: {
61
- ref: '_skill-ref',
62
- type: 'skill'
61
+ export const postAnswerResponses = {
62
+ [freeTextSlide.universalRef]: {
63
+ _id: '62b1d1087aa12f00253f40ee',
64
+ content,
65
+ engine,
66
+ state: {
67
+ allAnswers: [
68
+ {
69
+ slideRef: freeTextSlide.universalRef,
70
+ isCorrect: true,
71
+ answer: ['Benchmark']
72
+ }
73
+ ],
74
+ isCorrect: true,
75
+ nextContent: {
76
+ ref: qcmGraphicSlide.universalRef,
77
+ type: 'slide'
78
+ },
79
+ content: {
80
+ ref: freeTextSlide.universalRef,
81
+ type: 'slide'
82
+ },
83
+ pendingSlides: [],
84
+ slides: [freeTextSlide.universalRef],
85
+ step: {
86
+ current: 2
87
+ },
88
+ stars: 8
89
+ }
90
+ },
91
+ [qcmGraphicSlide.universalRef]: {
92
+ _id: '62b1d1087aa12f00253f40ee',
93
+ content,
94
+ engine,
95
+ state: {
96
+ allAnswers: [
97
+ {
98
+ slideRef: freeTextSlide.universalRef,
99
+ isCorrect: true,
100
+ answer: ['Benchmark']
101
+ },
102
+ {
103
+ slideRef: qcmGraphicSlide.universalRef,
104
+ isCorrect: true,
105
+ answer: ['Faux']
106
+ }
107
+ ],
108
+ isCorrect: true,
109
+ nextContent: {
110
+ ref: qcmSlide.universalRef,
111
+ type: 'slide'
112
+ },
113
+ content: {
114
+ ref: qcmGraphicSlide.universalRef,
115
+ type: 'slide'
116
+ },
117
+ pendingSlides: [],
118
+ slides: [freeTextSlide.universalRef, qcmGraphicSlide.universalRef],
119
+ step: {
120
+ current: 3
121
+ },
122
+ stars: 16
123
+ }
63
124
  },
64
- engine: {
65
- ref: 'review'
125
+ [qcmSlide.universalRef]: {
126
+ _id: '62b1d1087aa12f00253f40ee',
127
+ content,
128
+ engine,
129
+ state: {
130
+ allAnswers: [
131
+ {
132
+ slideRef: freeTextSlide.universalRef,
133
+ isCorrect: true,
134
+ answer: ['Benchmark']
135
+ },
136
+ {
137
+ slideRef: qcmGraphicSlide.universalRef,
138
+ isCorrect: true,
139
+ answer: ['Faux']
140
+ },
141
+ {
142
+ slideRef: qcmSlide.universalRef,
143
+ isCorrect: true,
144
+ answer: ['Le créateur peut fixer un pourcentage pour chaque transaction future']
145
+ }
146
+ ],
147
+ isCorrect: true,
148
+ nextContent: {
149
+ ref: sliderSlide.universalRef,
150
+ type: 'slide'
151
+ },
152
+ content: {
153
+ ref: qcmSlide.universalRef,
154
+ type: 'slide'
155
+ },
156
+ pendingSlides: [],
157
+ slides: [freeTextSlide.universalRef, qcmGraphicSlide.universalRef, qcmSlide.universalRef],
158
+ step: {
159
+ current: 4
160
+ },
161
+ stars: 24
162
+ }
66
163
  },
164
+ [sliderSlide.universalRef]: {
165
+ _id: '62b1d1087aa12f00253f40ee',
166
+ content,
167
+ engine,
168
+ state: {
169
+ allAnswers: [
170
+ {
171
+ slideRef: freeTextSlide.universalRef,
172
+ isCorrect: true,
173
+ answer: ['Benchmark']
174
+ },
175
+ {
176
+ slideRef: qcmGraphicSlide.universalRef,
177
+ isCorrect: true,
178
+ answer: ['Faux']
179
+ },
180
+ {
181
+ slideRef: qcmSlide.universalRef,
182
+ isCorrect: true,
183
+ answer: ['Le créateur peut fixer un pourcentage pour chaque transaction future']
184
+ },
185
+ {
186
+ slideRef: sliderSlide.universalRef,
187
+ isCorrect: true,
188
+ answer: ['7']
189
+ }
190
+ ],
191
+ isCorrect: true,
192
+ nextContent: {
193
+ ref: templateSlide.universalRef,
194
+ type: 'slide'
195
+ },
196
+ content: {
197
+ ref: sliderSlide.universalRef,
198
+ type: 'slide'
199
+ },
200
+ pendingSlides: [],
201
+ slides: [
202
+ freeTextSlide.universalRef,
203
+ qcmGraphicSlide.universalRef,
204
+ qcmSlide.universalRef,
205
+ sliderSlide.universalRef
206
+ ],
207
+ step: {
208
+ current: 5
209
+ },
210
+ stars: 32
211
+ }
212
+ },
213
+ [templateSlide.universalRef]: {
214
+ _id: '62b1d1087aa12f00253f40ee',
215
+ content,
216
+ engine,
217
+ state: {
218
+ allAnswers: [
219
+ {
220
+ slideRef: freeTextSlide.universalRef,
221
+ isCorrect: true,
222
+ answer: ['Benchmark']
223
+ },
224
+ {
225
+ slideRef: qcmGraphicSlide.universalRef,
226
+ isCorrect: true,
227
+ answer: ['Faux']
228
+ },
229
+ {
230
+ slideRef: qcmSlide.universalRef,
231
+ isCorrect: true,
232
+ answer: ['Le créateur peut fixer un pourcentage pour chaque transaction future']
233
+ },
234
+ {
235
+ slideRef: sliderSlide.universalRef,
236
+ isCorrect: true,
237
+ answer: ['7']
238
+ },
239
+ {
240
+ slideRef: templateSlide.universalRef,
241
+ isCorrect: true,
242
+ answer: ['Leaderboard', 'utilisateurs', 'étoiles']
243
+ }
244
+ ],
245
+ isCorrect: true,
246
+ nextContent: {
247
+ ref: 'successExitNode',
248
+ type: 'success'
249
+ },
250
+ content: {
251
+ ref: templateSlide.universalRef,
252
+ type: 'slide'
253
+ },
254
+ pendingSlides: [],
255
+ slides: [
256
+ freeTextSlide.universalRef,
257
+ qcmGraphicSlide.universalRef,
258
+ qcmSlide.universalRef,
259
+ sliderSlide.universalRef,
260
+ templateSlide.universalRef
261
+ ],
262
+ step: {
263
+ current: 6
264
+ },
265
+ stars: 40
266
+ }
267
+ }
268
+ };
269
+ export const progressionSlideWithPendingSlide = {
270
+ _id: '62b1d1087aa12f00253f40ee',
271
+ content,
272
+ engine,
67
273
  state: {
68
274
  allAnswers: [
69
275
  {
70
- slideRef: 'sli_VJYjJnJhg',
276
+ slideRef: freeTextSlide.universalRef,
277
+ isCorrect: false,
278
+ answer: ['Wrong']
279
+ },
280
+ {
281
+ slideRef: qcmGraphicSlide.universalRef,
282
+ isCorrect: true,
283
+ answer: ['Faux']
284
+ },
285
+ {
286
+ slideRef: qcmSlide.universalRef,
287
+ isCorrect: false,
288
+ answer: ['Wrong']
289
+ },
290
+ {
291
+ slideRef: sliderSlide.universalRef,
292
+ isCorrect: true,
293
+ answer: ['7']
294
+ },
295
+ {
296
+ slideRef: templateSlide.universalRef,
297
+ isCorrect: true,
298
+ answer: ['Leaderboard', 'utilisateurs', 'étoiles']
299
+ },
300
+ {
301
+ slideRef: freeTextSlide.universalRef,
71
302
  isCorrect: true,
72
303
  answer: ['Benchmark']
73
304
  }
74
305
  ],
75
306
  isCorrect: true,
76
307
  nextContent: {
77
- ref: 'sli_VkSQroQnx',
308
+ ref: qcmSlide.universalRef,
78
309
  type: 'slide'
79
310
  },
80
311
  content: {
81
- ref: 'sli_VJYjJnJhg',
312
+ ref: freeTextSlide.universalRef,
82
313
  type: 'slide'
83
314
  },
84
- pendingSlides: [],
85
- slides: ['sli_VJYjJnJhg'],
315
+ pendingSlides: [qcmSlide.universalRef],
316
+ slides: [
317
+ freeTextSlide.universalRef,
318
+ qcmGraphicSlide.universalRef,
319
+ qcmSlide.universalRef,
320
+ sliderSlide.universalRef,
321
+ templateSlide.universalRef,
322
+ freeTextSlide.universalRef
323
+ ],
86
324
  step: {
87
- current: 2
325
+ current: 7
88
326
  },
89
- stars: 4
327
+ stars: 32
90
328
  }
91
329
  };
92
330
  export const services = {
93
331
  fetchSkills: () => Promise.resolve(fetchSkillsResponse),
94
332
  fetchSlide: ref => Promise.resolve({ ...getSlideFixture(ref), universalRef: ref, id: ref }),
95
333
  postProgression: () => Promise.resolve(postProgressionResponse),
96
- postAnswer: () => Promise.resolve(postAnswerResponse)
334
+ postAnswer: progression => {
335
+ const currentSlide = progression.state.nextContent.ref;
336
+ return Promise.resolve(get(currentSlide, postAnswerResponses));
337
+ }
97
338
  };
@@ -74,7 +74,7 @@ export declare type SlideFromAPI = {
74
74
  type: 'chapter' | 'course';
75
75
  };
76
76
  };
77
- declare type ProgressionAnswerItem = {
77
+ export declare type ProgressionAnswerItem = {
78
78
  isCorrect: boolean;
79
79
  slideRef: string;
80
80
  answer: string[];
@@ -97,15 +97,17 @@ export declare type ProgressionState = {
97
97
  };
98
98
  stars: number;
99
99
  };
100
+ export declare type ReviewContent = {
101
+ type: 'skill';
102
+ ref: string;
103
+ };
104
+ export declare type ReviewEngine = {
105
+ ref: 'review';
106
+ };
100
107
  export declare type ProgressionFromAPI = {
101
108
  _id: string;
102
- content: {
103
- type: 'skill';
104
- ref: string;
105
- };
106
- engine: {
107
- ref: 'review';
108
- };
109
+ content: ReviewContent;
110
+ engine: ReviewEngine;
109
111
  state: ProgressionState;
110
112
  };
111
113
  export declare type Skill = {
@@ -118,7 +120,7 @@ export declare type Services = {
118
120
  fetchSkills(token: string): Promise<Skill[]>;
119
121
  fetchSlide(slideRef: string, token: string): Promise<SlideFromAPI | void>;
120
122
  postProgression(skillRef: string, token: string): Promise<ProgressionFromAPI>;
121
- postAnswer(skillRef: string, token: string, progressionId: string, answer: string[]): Promise<ProgressionFromAPI>;
123
+ postAnswer(progression: ProgressionFromAPI, token: string, answer: string[]): Promise<ProgressionFromAPI>;
122
124
  };
123
125
  export declare type Options = {
124
126
  services: Services;
@@ -86,5 +86,6 @@ export declare type SlidesViewProps = {
86
86
  };
87
87
  };
88
88
  export declare const initialState: SlidesStack;
89
+ export declare const buildStepItems: (state: StoreState) => StepItem[];
89
90
  export declare const mapStateToSlidesProps: (state: StoreState, dispatch: Dispatch) => SlidesViewProps;
90
91
  export {};
@@ -1,7 +1,8 @@
1
1
  import concat from 'lodash/fp/concat';
2
+ import findLast from 'lodash/fp/findLast';
2
3
  import get from 'lodash/fp/get';
3
4
  import getOr from 'lodash/fp/getOr';
4
- import isEmpty from 'lodash/fp/isEmpty';
5
+ import last from 'lodash/fp/last';
5
6
  import pipe from 'lodash/fp/pipe';
6
7
  import reduce from 'lodash/fp/reduce';
7
8
  import set from 'lodash/fp/set';
@@ -73,7 +74,14 @@ const buildStackSlides = (state, dispatch) => {
73
74
  }, initialState, initialState);
74
75
  return stack;
75
76
  };
76
- const buildStepItems = (state) => {
77
+ const getIconForCurrentStep = (slideRef, lastGivenAnswerForSlide, currentSlideRef, lastGivenAsnswer) => {
78
+ if (slideRef !== currentSlideRef)
79
+ return lastGivenAnswerForSlide.isCorrect ? 'right' : 'wrong';
80
+ if (lastGivenAsnswer.slideRef !== slideRef)
81
+ return 'no-answer';
82
+ return lastGivenAnswerForSlide.isCorrect ? 'right' : 'wrong';
83
+ };
84
+ export const buildStepItems = (state) => {
77
85
  const { progression } = state.data;
78
86
  const { currentSlideRef } = state.ui;
79
87
  if (!progression)
@@ -105,22 +113,30 @@ const buildStepItems = (state) => {
105
113
  value: '5'
106
114
  }
107
115
  ];
116
+ const slideRefs = getProgressionSlidesRefs(progression);
108
117
  const allAnswers = progression.state.allAnswers;
109
118
  const step = progression.state.step;
110
- if (isEmpty(allAnswers))
119
+ const nextContentRef = progression.state.nextContent.ref;
120
+ const lastGivenAnswer = last(allAnswers);
121
+ if (!lastGivenAnswer)
111
122
  return defaultProps;
112
123
  const steps = defaultProps.map((stepItem, index) => {
113
- const givenAnswer = allAnswers[index];
114
- if (!givenAnswer) {
124
+ const slideRef = slideRefs[index];
125
+ if (!slideRef)
126
+ return stepItem; // non fecthed slide pour given index
127
+ const lastGivenAnswerForSlide = findLast(answer => answer.slideRef === slideRef, allAnswers);
128
+ // never answered slide
129
+ if (!lastGivenAnswerForSlide) {
115
130
  return {
116
131
  ...stepItem,
117
- current: step.current === index + 1
132
+ current: nextContentRef === currentSlideRef && step.current === index + 1
118
133
  };
119
134
  }
135
+ // already answered slide, we computed based on the lastGivenAnswer
120
136
  return {
121
137
  ...stepItem,
122
- icon: givenAnswer.isCorrect ? 'right' : 'wrong',
123
- current: givenAnswer.slideRef === currentSlideRef
138
+ icon: getIconForCurrentStep(slideRef, lastGivenAnswerForSlide, currentSlideRef, lastGivenAnswer),
139
+ current: lastGivenAnswerForSlide.slideRef === currentSlideRef
124
140
  };
125
141
  });
126
142
  return steps;