@coorpacademy/app-review 0.1.19 → 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.
- package/es/actions/api/post-answer.js +9 -8
- package/es/actions/api/test/post-answer.test.js +6 -6
- package/es/reducers/data/test/progression.test.js +4 -3
- package/es/services/post-answer.d.ts +1 -1
- package/es/services/post-answer.js +3 -1
- package/es/services/test/post-answer.test.js +27 -4
- package/es/test/util/services.mock.d.ts +2 -1
- package/es/test/util/services.mock.js +264 -23
- package/es/types/common.d.ts +11 -9
- package/es/views/slides/index.d.ts +1 -0
- package/es/views/slides/index.js +24 -8
- package/es/views/slides/test/index.test.js +518 -203
- package/lib/actions/api/post-answer.js +10 -9
- package/lib/actions/api/test/post-answer.test.js +6 -6
- package/lib/reducers/data/test/progression.test.js +4 -3
- package/lib/services/post-answer.d.ts +1 -1
- package/lib/services/post-answer.js +4 -2
- package/lib/services/test/post-answer.test.js +27 -4
- package/lib/test/util/services.mock.d.ts +2 -1
- package/lib/test/util/services.mock.js +265 -23
- package/lib/types/common.d.ts +11 -9
- package/lib/views/slides/index.d.ts +1 -0
- package/lib/views/slides/index.js +23 -7
- package/lib/views/slides/test/index.test.js +521 -203
- package/package.json +3 -4
- package/src/actions/api/post-answer.ts +9 -9
- package/src/actions/api/test/post-answer.test.ts +6 -6
- package/src/reducers/data/test/progression.test.ts +4 -3
- package/src/services/post-answer.ts +3 -2
- package/src/services/test/post-answer.test.ts +28 -4
- package/src/test/util/services.mock.ts +274 -24
- package/src/types/common.ts +13 -10
- package/src/views/slides/index.ts +35 -10
- 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
|
-
|
|
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
|
|
22
|
-
const slideRef =
|
|
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 {
|
|
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:
|
|
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:
|
|
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:
|
|
55
|
+
payload: postAnswerResponses[freeTextSlide.id]
|
|
56
56
|
},
|
|
57
|
-
{ type: SLIDE_FETCH_REQUEST, meta: { slideRef:
|
|
57
|
+
{ type: SLIDE_FETCH_REQUEST, meta: { slideRef: qcmGraphicSlide.id } },
|
|
58
58
|
{
|
|
59
59
|
type: SLIDE_FETCH_SUCCESS,
|
|
60
|
-
meta: { slideRef:
|
|
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 {
|
|
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:
|
|
21
|
+
payload: postAnswerResponses[freeTextSlide.universalRef]
|
|
21
22
|
});
|
|
22
|
-
t.deepEqual(state,
|
|
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: (
|
|
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 (
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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
|
-
|
|
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:
|
|
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
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
|
|
65
|
-
|
|
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:
|
|
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:
|
|
308
|
+
ref: qcmSlide.universalRef,
|
|
78
309
|
type: 'slide'
|
|
79
310
|
},
|
|
80
311
|
content: {
|
|
81
|
-
ref:
|
|
312
|
+
ref: freeTextSlide.universalRef,
|
|
82
313
|
type: 'slide'
|
|
83
314
|
},
|
|
84
|
-
pendingSlides: [],
|
|
85
|
-
slides: [
|
|
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:
|
|
325
|
+
current: 7
|
|
88
326
|
},
|
|
89
|
-
stars:
|
|
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:
|
|
334
|
+
postAnswer: progression => {
|
|
335
|
+
const currentSlide = progression.state.nextContent.ref;
|
|
336
|
+
return Promise.resolve(get(currentSlide, postAnswerResponses));
|
|
337
|
+
}
|
|
97
338
|
};
|
package/es/types/common.d.ts
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
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 {};
|
package/es/views/slides/index.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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
|
|
114
|
-
if (!
|
|
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:
|
|
123
|
-
current:
|
|
138
|
+
icon: getIconForCurrentStep(slideRef, lastGivenAnswerForSlide, currentSlideRef, lastGivenAnswer),
|
|
139
|
+
current: lastGivenAnswerForSlide.slideRef === currentSlideRef
|
|
124
140
|
};
|
|
125
141
|
});
|
|
126
142
|
return steps;
|