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