@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.
- package/es/actions/api/fetch-rank.d.ts +32 -0
- package/es/actions/api/fetch-rank.js +30 -0
- package/es/actions/api/test/fetch-correction.test.js +2 -1
- package/es/actions/api/test/fetch-rank.test.d.ts +1 -0
- package/es/actions/api/test/fetch-rank.test.js +100 -0
- package/es/actions/api/test/fetch-skills.test.js +2 -1
- package/es/actions/api/test/fetch-slide.test.js +2 -1
- package/es/actions/api/test/post-answer.test.js +2 -1
- package/es/actions/api/test/post-progression.test.js +2 -1
- package/es/actions/data/test/token.test.js +2 -1
- package/es/actions/ui/test/answers.test.js +2 -1
- package/es/actions/ui/test/slides.test.js +2 -1
- package/es/reducers/data/corrections.d.ts +1 -1
- package/es/reducers/data/index.d.ts +4 -1
- package/es/reducers/data/index.js +2 -1
- package/es/reducers/data/rank.d.ts +7 -0
- package/es/reducers/data/rank.js +36 -0
- package/es/reducers/data/test/rank.test.d.ts +1 -0
- package/es/reducers/data/test/rank.test.js +59 -0
- package/es/reducers/index.d.ts +4 -3
- package/es/reducers/ui/slide.d.ts +1 -0
- package/es/reducers/ui/slide.js +1 -1
- package/es/test/util/services.mock.d.ts +1 -0
- package/es/test/util/services.mock.js +16 -0
- package/es/views/skills/test/skills.test.js +4 -2
- package/es/views/slides/index.d.ts +21 -19
- package/es/views/slides/index.js +29 -3
- package/es/views/slides/test/fixtures/qcm-graphic.js +190 -28
- package/es/views/slides/test/index.test.js +200 -19
- package/es/views/slides/test/slide.free-text.on-change.test.js +4 -1
- package/es/views/slides/test/slide.qcm-drag.on-click.test.js +4 -1
- package/es/views/slides/test/slide.qcm-graphic.on-click.test.js +6 -3
- package/es/views/slides/test/slide.qcm.on-click.test.js +4 -1
- package/es/views/slides/test/slide.slider.on-change.test.js +4 -1
- package/es/views/slides/test/slide.template.on-change.test.js +6 -1
- package/lib/actions/api/fetch-rank.d.ts +32 -0
- package/lib/actions/api/fetch-rank.js +32 -0
- package/lib/actions/api/test/fetch-correction.test.js +2 -1
- package/lib/actions/api/test/fetch-rank.test.d.ts +1 -0
- package/lib/actions/api/test/fetch-rank.test.js +171 -0
- package/lib/actions/api/test/fetch-skills.test.js +2 -1
- package/lib/actions/api/test/fetch-slide.test.js +2 -1
- package/lib/actions/api/test/post-answer.test.js +2 -1
- package/lib/actions/api/test/post-progression.test.js +2 -1
- package/lib/actions/data/test/token.test.js +2 -1
- package/lib/actions/ui/test/answers.test.js +2 -1
- package/lib/actions/ui/test/slides.test.js +2 -1
- package/lib/reducers/data/corrections.d.ts +1 -1
- package/lib/reducers/data/index.d.ts +4 -1
- package/lib/reducers/data/index.js +2 -1
- package/lib/reducers/data/rank.d.ts +7 -0
- package/lib/reducers/data/rank.js +37 -0
- package/lib/reducers/data/test/rank.test.d.ts +1 -0
- package/lib/reducers/data/test/rank.test.js +59 -0
- package/lib/reducers/index.d.ts +4 -3
- package/lib/reducers/ui/slide.d.ts +1 -0
- package/lib/reducers/ui/slide.js +1 -1
- package/lib/test/util/services.mock.d.ts +1 -0
- package/lib/test/util/services.mock.js +7 -0
- package/lib/views/skills/test/skills.test.js +4 -2
- package/lib/views/slides/index.d.ts +21 -19
- package/lib/views/slides/index.js +29 -3
- package/lib/views/slides/test/fixtures/qcm-graphic.js +190 -28
- package/lib/views/slides/test/index.test.js +211 -22
- package/lib/views/slides/test/slide.free-text.on-change.test.js +4 -1
- package/lib/views/slides/test/slide.qcm-drag.on-click.test.js +4 -1
- package/lib/views/slides/test/slide.qcm-graphic.on-click.test.js +6 -3
- package/lib/views/slides/test/slide.qcm.on-click.test.js +4 -1
- package/lib/views/slides/test/slide.slider.on-change.test.js +4 -1
- package/lib/views/slides/test/slide.template.on-change.test.js +6 -1
- package/package.json +3 -3
- package/src/actions/api/fetch-rank.ts +84 -0
- package/src/actions/api/test/fetch-correction.test.ts +2 -1
- package/src/actions/api/test/fetch-rank.test.ts +130 -0
- package/src/actions/api/test/fetch-skills.test.ts +2 -1
- package/src/actions/api/test/fetch-slide.test.ts +2 -1
- package/src/actions/api/test/post-answer.test.ts +2 -1
- package/src/actions/api/test/post-progression.test.ts +2 -1
- package/src/actions/data/test/token.test.ts +2 -1
- package/src/actions/ui/test/answers.test.ts +2 -1
- package/src/actions/ui/test/slides.test.ts +2 -1
- package/src/reducers/data/corrections.ts +1 -1
- package/src/reducers/data/index.ts +3 -1
- package/src/reducers/data/rank.ts +60 -0
- package/src/reducers/data/test/rank.test.ts +78 -0
- package/src/reducers/index.ts +2 -2
- package/src/reducers/ui/slide.ts +2 -1
- package/src/test/util/services.mock.ts +17 -0
- package/src/views/skills/test/skills.test.ts +4 -2
- package/src/views/slides/index.ts +65 -22
- package/src/views/slides/test/fixtures/qcm-graphic.ts +196 -29
- package/src/views/slides/test/index.test.ts +210 -21
- package/src/views/slides/test/slide.free-text.on-change.test.ts +4 -1
- package/src/views/slides/test/slide.qcm-drag.on-click.test.ts +4 -1
- package/src/views/slides/test/slide.qcm-graphic.on-click.test.ts +6 -4
- package/src/views/slides/test/slide.qcm.on-click.test.ts +4 -1
- package/src/views/slides/test/slide.slider.on-change.test.ts +4 -1
- package/src/views/slides/test/slide.template.on-change.test.ts +6 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Dispatch } from 'redux';
|
|
2
|
+
import type { StoreState } from '../../reducers';
|
|
3
|
+
import type { Rank, Services, Options } from '../../types/common';
|
|
4
|
+
export declare const RANK_FETCH_START_REQUEST: "@@rank/FETCH_START_REQUEST";
|
|
5
|
+
export declare const RANK_FETCH_START_SUCCESS: "@@rank/FETCH_START_SUCCESS";
|
|
6
|
+
export declare const RANK_FETCH_START_FAILURE: "@@rank/FETCH_START_FAILURE";
|
|
7
|
+
export declare const RANK_FETCH_END_REQUEST: "@@rank/FETCH_END_REQUEST";
|
|
8
|
+
export declare const RANK_FETCH_END_SUCCESS: "@@rank/FETCH_END_SUCCESS";
|
|
9
|
+
export declare const RANK_FETCH_END_FAILURE: "@@rank/FETCH_END_FAILURE";
|
|
10
|
+
declare type RankFetchStartRequestType = typeof RANK_FETCH_START_REQUEST;
|
|
11
|
+
declare type RankFetchStartSuccessType = typeof RANK_FETCH_START_SUCCESS;
|
|
12
|
+
declare type RankFetchStartFailureType = typeof RANK_FETCH_START_FAILURE;
|
|
13
|
+
declare type RankFetchEndRequestType = typeof RANK_FETCH_END_REQUEST;
|
|
14
|
+
declare type RankFetchEndSuccessType = typeof RANK_FETCH_END_SUCCESS;
|
|
15
|
+
declare type RankFetchEndFailureType = typeof RANK_FETCH_END_FAILURE;
|
|
16
|
+
export declare type RankRequestAction = {
|
|
17
|
+
type: RankFetchStartRequestType | RankFetchEndRequestType;
|
|
18
|
+
};
|
|
19
|
+
export declare type RankSuccessAction = {
|
|
20
|
+
type: RankFetchStartSuccessType | RankFetchEndSuccessType;
|
|
21
|
+
payload: Rank;
|
|
22
|
+
};
|
|
23
|
+
export declare type RankFailureAction = {
|
|
24
|
+
type: RankFetchStartFailureType | RankFetchEndFailureType;
|
|
25
|
+
};
|
|
26
|
+
export declare type RankAction = RankRequestAction | RankSuccessAction | RankFailureAction;
|
|
27
|
+
declare type RankStart = [RankFetchStartRequestType, RankFetchStartSuccessType, RankFetchStartFailureType];
|
|
28
|
+
declare type RankEnd = [RankFetchEndRequestType, RankFetchEndSuccessType, RankFetchEndFailureType];
|
|
29
|
+
export declare const fetchRank: (dispatch: Dispatch, getState: () => StoreState, services: Services, types: RankStart | RankEnd, path?: string) => RankAction;
|
|
30
|
+
export declare const fetchStartRank: (dispatch: Dispatch, getState: () => StoreState, { services }: Options) => RankAction;
|
|
31
|
+
export declare const fetchEndRank: (dispatch: Dispatch, getState: () => StoreState, { services }: Options) => RankAction;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import buildTask from '@coorpacademy/redux-task';
|
|
2
|
+
import get from 'lodash/fp/get';
|
|
3
|
+
export const RANK_FETCH_START_REQUEST = '@@rank/FETCH_START_REQUEST';
|
|
4
|
+
export const RANK_FETCH_START_SUCCESS = '@@rank/FETCH_START_SUCCESS';
|
|
5
|
+
export const RANK_FETCH_START_FAILURE = '@@rank/FETCH_START_FAILURE';
|
|
6
|
+
export const RANK_FETCH_END_REQUEST = '@@rank/FETCH_END_REQUEST';
|
|
7
|
+
export const RANK_FETCH_END_SUCCESS = '@@rank/FETCH_END_SUCCESS';
|
|
8
|
+
export const RANK_FETCH_END_FAILURE = '@@rank/FETCH_END_FAILURE';
|
|
9
|
+
export const fetchRank = (dispatch, getState, services, types, path) => {
|
|
10
|
+
const action = buildTask({
|
|
11
|
+
types,
|
|
12
|
+
task: () => {
|
|
13
|
+
const state = getState();
|
|
14
|
+
const token = get(['data', 'token'], state);
|
|
15
|
+
return services.fetchRank(token);
|
|
16
|
+
},
|
|
17
|
+
bailout: path ? (state) => !!get(path, state) : undefined
|
|
18
|
+
});
|
|
19
|
+
return dispatch(action);
|
|
20
|
+
};
|
|
21
|
+
export const fetchStartRank = (dispatch, getState, { services }) => {
|
|
22
|
+
return fetchRank(dispatch, getState, services, [RANK_FETCH_START_REQUEST, RANK_FETCH_START_SUCCESS, RANK_FETCH_START_FAILURE], 'data.rank.start');
|
|
23
|
+
};
|
|
24
|
+
export const fetchEndRank = (dispatch, getState, { services }) => {
|
|
25
|
+
return fetchRank(dispatch, getState, services, [
|
|
26
|
+
RANK_FETCH_END_REQUEST,
|
|
27
|
+
RANK_FETCH_END_SUCCESS,
|
|
28
|
+
RANK_FETCH_END_FAILURE
|
|
29
|
+
]);
|
|
30
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import { fetchStartRank, fetchEndRank, RANK_FETCH_START_REQUEST, RANK_FETCH_START_SUCCESS, RANK_FETCH_START_FAILURE, RANK_FETCH_END_REQUEST, RANK_FETCH_END_SUCCESS, RANK_FETCH_END_FAILURE } from '../fetch-rank';
|
|
3
|
+
import { services as mockedServices } from '../../../test/util/services.mock';
|
|
4
|
+
import { createTestStore } from '../../test/create-test-store';
|
|
5
|
+
const initialState = {
|
|
6
|
+
data: {
|
|
7
|
+
progression: null,
|
|
8
|
+
slides: {},
|
|
9
|
+
skills: [],
|
|
10
|
+
token: '1234',
|
|
11
|
+
corrections: {},
|
|
12
|
+
rank: {}
|
|
13
|
+
},
|
|
14
|
+
ui: {
|
|
15
|
+
currentSlideRef: '',
|
|
16
|
+
navigation: [],
|
|
17
|
+
answers: [],
|
|
18
|
+
slide: {
|
|
19
|
+
validateButton: false
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
test('should dispatch FETCH_START_SUCCESS action when fetchStartRank returns the start rank', async (t) => {
|
|
24
|
+
t.plan(3);
|
|
25
|
+
const services = {
|
|
26
|
+
...mockedServices,
|
|
27
|
+
fetchRank: token => {
|
|
28
|
+
t.is(token, '1234');
|
|
29
|
+
return Promise.resolve({ rank: 93 });
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const expectedActions = [
|
|
33
|
+
{ type: RANK_FETCH_START_REQUEST },
|
|
34
|
+
{
|
|
35
|
+
type: RANK_FETCH_START_SUCCESS,
|
|
36
|
+
payload: { rank: 93 }
|
|
37
|
+
}
|
|
38
|
+
];
|
|
39
|
+
const { dispatch } = createTestStore(t, initialState, services, expectedActions);
|
|
40
|
+
await dispatch(fetchStartRank);
|
|
41
|
+
});
|
|
42
|
+
test('should dispatch FETCH_START_FAILURE action when fetchStartRank fails', async (t) => {
|
|
43
|
+
t.plan(3);
|
|
44
|
+
const services = {
|
|
45
|
+
...mockedServices,
|
|
46
|
+
fetchRank: token => {
|
|
47
|
+
t.is(token, '1234');
|
|
48
|
+
return Promise.reject(new Error('unexpected'));
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const expectedActions = [
|
|
52
|
+
{ type: RANK_FETCH_START_REQUEST },
|
|
53
|
+
{
|
|
54
|
+
type: RANK_FETCH_START_FAILURE,
|
|
55
|
+
payload: new Error('unexpected'),
|
|
56
|
+
error: true
|
|
57
|
+
}
|
|
58
|
+
];
|
|
59
|
+
const { dispatch } = createTestStore(t, initialState, services, expectedActions);
|
|
60
|
+
await dispatch(fetchStartRank);
|
|
61
|
+
});
|
|
62
|
+
test('should dispatch FETCH_END_SUCCESS action when fetchEndRank returns the end rank', async (t) => {
|
|
63
|
+
t.plan(3);
|
|
64
|
+
const services = {
|
|
65
|
+
...mockedServices,
|
|
66
|
+
fetchRank: token => {
|
|
67
|
+
t.is(token, '1234');
|
|
68
|
+
return Promise.resolve({ rank: 93 });
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
const expectedActions = [
|
|
72
|
+
{ type: RANK_FETCH_END_REQUEST },
|
|
73
|
+
{
|
|
74
|
+
type: RANK_FETCH_END_SUCCESS,
|
|
75
|
+
payload: { rank: 93 }
|
|
76
|
+
}
|
|
77
|
+
];
|
|
78
|
+
const { dispatch } = createTestStore(t, initialState, services, expectedActions);
|
|
79
|
+
await dispatch(fetchEndRank);
|
|
80
|
+
});
|
|
81
|
+
test('should dispatch FETCH_END_FAILURE action when fetchEndRank fails', async (t) => {
|
|
82
|
+
t.plan(3);
|
|
83
|
+
const services = {
|
|
84
|
+
...mockedServices,
|
|
85
|
+
fetchRank: token => {
|
|
86
|
+
t.is(token, '1234');
|
|
87
|
+
return Promise.reject(new Error('unexpected'));
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
const expectedActions = [
|
|
91
|
+
{ type: RANK_FETCH_END_REQUEST },
|
|
92
|
+
{
|
|
93
|
+
type: RANK_FETCH_END_FAILURE,
|
|
94
|
+
payload: new Error('unexpected'),
|
|
95
|
+
error: true
|
|
96
|
+
}
|
|
97
|
+
];
|
|
98
|
+
const { dispatch } = createTestStore(t, initialState, services, expectedActions);
|
|
99
|
+
await dispatch(fetchEndRank);
|
|
100
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CorrectionFromAPI } from '../../types/common';
|
|
1
|
+
import type { CorrectionFromAPI } from '../../types/common';
|
|
2
2
|
import { ReceivedCorrection, FetchCorrection } from '../../actions/api/fetch-correction';
|
|
3
3
|
export declare type CorrectionsState = Record<string, CorrectionFromAPI>;
|
|
4
4
|
export declare type CorrectionsAction = ReceivedCorrection | FetchCorrection;
|
|
@@ -3,12 +3,14 @@ import { ProgressionState } from './progression';
|
|
|
3
3
|
import { SkillsState } from './skills';
|
|
4
4
|
import { SlidesState } from './slides';
|
|
5
5
|
import { TokenState } from './token';
|
|
6
|
+
import { RankState } from './rank';
|
|
6
7
|
export declare type DataState = {
|
|
7
8
|
corrections: CorrectionsState;
|
|
8
9
|
progression: ProgressionState;
|
|
9
10
|
skills: SkillsState;
|
|
10
11
|
slides: SlidesState;
|
|
11
12
|
token: TokenState;
|
|
13
|
+
rank: RankState;
|
|
12
14
|
};
|
|
13
15
|
declare const _default: import("redux").Reducer<import("redux").CombinedState<{
|
|
14
16
|
corrections: CorrectionsState;
|
|
@@ -16,5 +18,6 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
|
|
|
16
18
|
skills: SkillsState;
|
|
17
19
|
slides: SlidesState;
|
|
18
20
|
token: string;
|
|
19
|
-
|
|
21
|
+
rank: RankState;
|
|
22
|
+
}>, import("./corrections").CorrectionsAction | import("../../actions/api/post-answer").PostAnswerSuccessAction | import("../../actions/api/post-progression").ReceivedProgression | import("../../actions/api/fetch-skills").ReceivedSkills | import("./slides").SlidesAction | import("../../actions/data/token").StoreToken | import("../../actions/api/fetch-rank").RankAction>;
|
|
20
23
|
export default _default;
|
|
@@ -4,4 +4,5 @@ import progression from './progression';
|
|
|
4
4
|
import skills from './skills';
|
|
5
5
|
import slides from './slides';
|
|
6
6
|
import token from './token';
|
|
7
|
-
|
|
7
|
+
import rank from './rank';
|
|
8
|
+
export default combineReducers({ corrections, progression, skills, slides, token, rank });
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { get, isNull, isUndefined, pipe, set, unset, update } from 'lodash/fp';
|
|
2
|
+
import { RANK_FETCH_START_REQUEST, RANK_FETCH_START_SUCCESS, RANK_FETCH_START_FAILURE, RANK_FETCH_END_REQUEST, RANK_FETCH_END_SUCCESS, RANK_FETCH_END_FAILURE } from '../../actions/api/fetch-rank';
|
|
3
|
+
const initialState = {};
|
|
4
|
+
const reducer = (
|
|
5
|
+
// eslint-disable-next-line default-param-last
|
|
6
|
+
state = initialState, action) => {
|
|
7
|
+
switch (action.type) {
|
|
8
|
+
case RANK_FETCH_START_REQUEST: {
|
|
9
|
+
return update('start', (startRank) => (isUndefined(startRank) ? null : startRank), state);
|
|
10
|
+
}
|
|
11
|
+
case RANK_FETCH_START_SUCCESS: {
|
|
12
|
+
const { payload } = action;
|
|
13
|
+
return set('start', payload.rank, state);
|
|
14
|
+
}
|
|
15
|
+
case RANK_FETCH_START_FAILURE: {
|
|
16
|
+
if (pipe(get('start'), isNull)(state))
|
|
17
|
+
return unset('start', state);
|
|
18
|
+
return state;
|
|
19
|
+
}
|
|
20
|
+
case RANK_FETCH_END_REQUEST: {
|
|
21
|
+
return update('end', (endRank) => (isUndefined(endRank) ? null : endRank), state);
|
|
22
|
+
}
|
|
23
|
+
case RANK_FETCH_END_SUCCESS: {
|
|
24
|
+
const { payload } = action;
|
|
25
|
+
return set('end', payload.rank, state);
|
|
26
|
+
}
|
|
27
|
+
case RANK_FETCH_END_FAILURE: {
|
|
28
|
+
if (pipe(get('end'), isNull)(state))
|
|
29
|
+
return unset('end', state);
|
|
30
|
+
return state;
|
|
31
|
+
}
|
|
32
|
+
default:
|
|
33
|
+
return state;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
export default reducer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import reducer from '../rank';
|
|
3
|
+
import { RANK_FETCH_START_REQUEST, RANK_FETCH_START_SUCCESS, RANK_FETCH_START_FAILURE, RANK_FETCH_END_REQUEST, RANK_FETCH_END_SUCCESS, RANK_FETCH_END_FAILURE } from '../../../actions/api/fetch-rank';
|
|
4
|
+
test('should have initial value', t => {
|
|
5
|
+
const state = reducer(undefined, {});
|
|
6
|
+
t.deepEqual(state, {});
|
|
7
|
+
});
|
|
8
|
+
test("should set the start value to null if the value doesn't exist of FETCH_START_REQUEST action", t => {
|
|
9
|
+
const state = reducer({}, { type: RANK_FETCH_START_REQUEST });
|
|
10
|
+
t.deepEqual(state, {
|
|
11
|
+
start: null
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
test('should do nothing if a start value already exists of FETCH_START_REQUEST action', t => {
|
|
15
|
+
const state = reducer({ start: 93 }, { type: RANK_FETCH_START_REQUEST });
|
|
16
|
+
t.deepEqual(state, {
|
|
17
|
+
start: 93
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
test('should set the start value of FETCH_START_SUCCESS action', t => {
|
|
21
|
+
const state = reducer({}, { type: RANK_FETCH_START_SUCCESS, payload: { rank: 93 } });
|
|
22
|
+
t.deepEqual(state, {
|
|
23
|
+
start: 93
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
test('should unset the start value if the value is null of FETCH_START_FAILURE action', t => {
|
|
27
|
+
const state = reducer({ start: null }, { type: RANK_FETCH_START_FAILURE });
|
|
28
|
+
t.deepEqual(state, {});
|
|
29
|
+
});
|
|
30
|
+
test('should do nothing if the start value already exists of FETCH_START_FAILURE action', t => {
|
|
31
|
+
const state = reducer({ start: 93 }, { type: RANK_FETCH_START_FAILURE });
|
|
32
|
+
t.deepEqual(state, { start: 93 });
|
|
33
|
+
});
|
|
34
|
+
test("should set the end value to null if the value doesn't exist of FETCH_END_REQUEST action", t => {
|
|
35
|
+
const state = reducer({}, { type: RANK_FETCH_END_REQUEST });
|
|
36
|
+
t.deepEqual(state, {
|
|
37
|
+
end: null
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
test('should do nothing if an end value already exists of FETCH_END_REQUEST action', t => {
|
|
41
|
+
const state = reducer({ end: 94 }, { type: RANK_FETCH_END_REQUEST });
|
|
42
|
+
t.deepEqual(state, {
|
|
43
|
+
end: 94
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
test('should set the end value of FETCH_END_SUCCESS action', t => {
|
|
47
|
+
const state = reducer({}, { type: RANK_FETCH_END_SUCCESS, payload: { rank: 94 } });
|
|
48
|
+
t.deepEqual(state, {
|
|
49
|
+
end: 94
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
test('should unset the end value if the value is null of FETCH_END_FAILURE action', t => {
|
|
53
|
+
const state = reducer({ end: null }, { type: RANK_FETCH_END_FAILURE });
|
|
54
|
+
t.deepEqual(state, {});
|
|
55
|
+
});
|
|
56
|
+
test('should do nothing if the end value already exists of FETCH_END_FAILURE action', t => {
|
|
57
|
+
const state = reducer({ end: 94 }, { type: RANK_FETCH_END_FAILURE });
|
|
58
|
+
t.deepEqual(state, { end: 94 });
|
|
59
|
+
});
|
package/es/reducers/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DataState } from './data';
|
|
2
|
-
import { UIState } from './ui';
|
|
1
|
+
import { type DataState } from './data';
|
|
2
|
+
import { type UIState } from './ui';
|
|
3
3
|
export declare type StoreState = {
|
|
4
4
|
ui: UIState;
|
|
5
5
|
data: DataState;
|
|
@@ -11,6 +11,7 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
|
|
|
11
11
|
skills: import("./data/skills").SkillsState;
|
|
12
12
|
slides: import("./data/slides").SlidesState;
|
|
13
13
|
token: string;
|
|
14
|
+
rank: import("./data/rank").RankState;
|
|
14
15
|
}>;
|
|
15
16
|
ui: import("redux").CombinedState<{
|
|
16
17
|
currentSlideRef: string;
|
|
@@ -18,5 +19,5 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
|
|
|
18
19
|
answers: import("./ui/answers").AnswerState;
|
|
19
20
|
slide: import("./ui/slide").UISlideState;
|
|
20
21
|
}>;
|
|
21
|
-
}>, import("./data/corrections").CorrectionsAction | import("../actions/ui/slides").SetCurrentSlide | import("../actions/api/post-answer").PostAnswerRequestAction | import("../actions/api/post-answer").PostAnswerSuccessAction | import("../actions/api/post-progression").ReceivedProgression | import("../actions/api/fetch-skills").ReceivedSkills | import("./data/slides").SlidesAction | import("../actions/data/token").StoreToken | import("../actions/ui/navigation").NavigateTo | import("../actions/ui/navigation").NavigateBack | import("../actions/ui/answers").EditAnswerAction>;
|
|
22
|
+
}>, import("./data/corrections").CorrectionsAction | import("../actions/ui/slides").SetCurrentSlide | import("../actions/api/post-answer").PostAnswerRequestAction | import("../actions/api/post-answer").PostAnswerSuccessAction | import("../actions/api/post-progression").ReceivedProgression | import("../actions/api/fetch-skills").ReceivedSkills | import("./data/slides").SlidesAction | import("../actions/data/token").StoreToken | import("../actions/api/fetch-rank").RankAction | import("../actions/ui/navigation").NavigateTo | import("../actions/ui/navigation").NavigateBack | import("../actions/ui/answers").EditAnswerAction>;
|
|
22
23
|
export default _default;
|
|
@@ -4,6 +4,7 @@ import { ReceivedCorrection } from '../../actions/api/fetch-correction';
|
|
|
4
4
|
export declare type UISlideState = {
|
|
5
5
|
validateButton: boolean;
|
|
6
6
|
animateCorrectionPopin?: boolean;
|
|
7
|
+
showCorrectionPopin?: boolean;
|
|
7
8
|
};
|
|
8
9
|
export declare const initialState: UISlideState;
|
|
9
10
|
declare const reducer: (state: UISlideState | undefined, action: PostAnswerRequestAction | EditAnswerAction | ReceivedCorrection) => UISlideState;
|
package/es/reducers/ui/slide.js
CHANGED
|
@@ -22,7 +22,7 @@ state = initialState, action) => {
|
|
|
22
22
|
return initialState;
|
|
23
23
|
}
|
|
24
24
|
case CORRECTION_FETCH_SUCCESS: {
|
|
25
|
-
return set(['animateCorrectionPopin'], true, state);
|
|
25
|
+
return pipe(set(['animateCorrectionPopin'], true), set(['showCorrectionPopin'], true))(state);
|
|
26
26
|
}
|
|
27
27
|
default:
|
|
28
28
|
return state;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CorrectionFromAPI, ProgressionFromAPI, Services } from '../../types/common';
|
|
2
2
|
export declare const postProgressionResponse: ProgressionFromAPI;
|
|
3
3
|
export declare const postAnswerResponses: Record<string, ProgressionFromAPI>;
|
|
4
|
+
export declare const incorrectFreeTextPostAnswerResponse: ProgressionFromAPI;
|
|
4
5
|
export declare const progressionSlideWithPendingSlide: ProgressionFromAPI;
|
|
5
6
|
export declare const getChoicesCorrection: (ref: string, wrongChoice?: boolean) => CorrectionFromAPI;
|
|
6
7
|
export declare const services: Services;
|
|
@@ -272,6 +272,22 @@ export const postAnswerResponses = {
|
|
|
272
272
|
}
|
|
273
273
|
}
|
|
274
274
|
};
|
|
275
|
+
export const incorrectFreeTextPostAnswerResponse = {
|
|
276
|
+
...postAnswerResponses[freeTextSlide.universalRef],
|
|
277
|
+
state: {
|
|
278
|
+
...postAnswerResponses[freeTextSlide.universalRef].state,
|
|
279
|
+
isCorrect: false,
|
|
280
|
+
allAnswers: [
|
|
281
|
+
{
|
|
282
|
+
slideRef: freeTextSlide.universalRef,
|
|
283
|
+
isCorrect: false,
|
|
284
|
+
answer: ['NOPE']
|
|
285
|
+
}
|
|
286
|
+
],
|
|
287
|
+
pendingSlides: [freeTextSlide.universalRef],
|
|
288
|
+
stars: 0
|
|
289
|
+
}
|
|
290
|
+
};
|
|
275
291
|
export const progressionSlideWithPendingSlide = {
|
|
276
292
|
_id: '62b1d1087aa12f00253f40ee',
|
|
277
293
|
content,
|
|
@@ -9,7 +9,8 @@ test('should create initial props when there are no skills on the state', t => {
|
|
|
9
9
|
skills: [],
|
|
10
10
|
slides: {},
|
|
11
11
|
token: '1234',
|
|
12
|
-
corrections: {}
|
|
12
|
+
corrections: {},
|
|
13
|
+
rank: {}
|
|
13
14
|
},
|
|
14
15
|
ui: {
|
|
15
16
|
currentSlideRef: '',
|
|
@@ -51,7 +52,8 @@ test('should create initial props when skills on the state', t => {
|
|
|
51
52
|
],
|
|
52
53
|
slides: {},
|
|
53
54
|
token: '1234',
|
|
54
|
-
corrections: {}
|
|
55
|
+
corrections: {},
|
|
56
|
+
rank: {}
|
|
55
57
|
},
|
|
56
58
|
ui: {
|
|
57
59
|
currentSlideRef: '',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Dispatch } from 'redux';
|
|
2
|
-
import { SlideIndexes } from '../../common';
|
|
3
|
-
import { StoreState } from '../../reducers';
|
|
4
|
-
import { AnswerUI } from '../../types/slides';
|
|
1
|
+
import type { Dispatch } from 'redux';
|
|
2
|
+
import type { SlideIndexes } from '../../common';
|
|
3
|
+
import type { StoreState } from '../../reducers';
|
|
4
|
+
import type { AnswerUI } from '../../types/slides';
|
|
5
5
|
declare const ICON_VALUES: {
|
|
6
6
|
readonly right: "right";
|
|
7
7
|
readonly wrong: "wrong";
|
|
@@ -27,22 +27,24 @@ export declare type UISlide = {
|
|
|
27
27
|
declare type SlidesStack = {
|
|
28
28
|
[key in SlideIndexes]: UISlide;
|
|
29
29
|
};
|
|
30
|
+
declare type CorrectionPopinInformation = {
|
|
31
|
+
label: string;
|
|
32
|
+
message: string;
|
|
33
|
+
};
|
|
34
|
+
declare type CorrectionPopinKlf = {
|
|
35
|
+
label: string;
|
|
36
|
+
tooltip: string;
|
|
37
|
+
};
|
|
38
|
+
declare type CorrectionPopinNext = {
|
|
39
|
+
label: string;
|
|
40
|
+
ariaLabel: string;
|
|
41
|
+
};
|
|
30
42
|
export declare type CorrectionPopinProps = {
|
|
31
|
-
klf
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
information: {
|
|
37
|
-
label: string;
|
|
38
|
-
message: string;
|
|
39
|
-
};
|
|
40
|
-
next: {
|
|
41
|
-
label: string;
|
|
42
|
-
ariaLabel: string;
|
|
43
|
-
};
|
|
44
|
-
successLabel: string;
|
|
45
|
-
failureLabel: string;
|
|
43
|
+
klf?: CorrectionPopinKlf;
|
|
44
|
+
information: CorrectionPopinInformation;
|
|
45
|
+
next: CorrectionPopinNext;
|
|
46
|
+
resultLabel: string;
|
|
47
|
+
type: 'right' | 'wrong';
|
|
46
48
|
};
|
|
47
49
|
export declare type SlidesViewProps = {
|
|
48
50
|
header: {
|
package/es/views/slides/index.js
CHANGED
|
@@ -8,6 +8,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
|
+
import join from 'lodash/fp/join';
|
|
11
12
|
import { postAnswer } from '../../actions/api/post-answer';
|
|
12
13
|
import { mapApiSlideToUi } from './map-api-slide-to-ui';
|
|
13
14
|
const ICON_VALUES = {
|
|
@@ -67,7 +68,10 @@ const buildStackSlides = (state, dispatch) => {
|
|
|
67
68
|
const { questionText, answerUI } = mapApiSlideToUi(dispatch)(slideFromAPI, answers);
|
|
68
69
|
const parentContentTitle = getOr('', 'parentContentTitle.title', slideFromAPI);
|
|
69
70
|
const parentContentType = getOr('', 'parentContentTitle.type', slideFromAPI);
|
|
70
|
-
const
|
|
71
|
+
const isCurrentSlideRef = currentSlideRef === slideRef;
|
|
72
|
+
const animateCorrectionPopin = isCurrentSlideRef && getOr(false, ['ui', 'slide', 'animateCorrectionPopin'], state);
|
|
73
|
+
const showCorrectionPopin = isCurrentSlideRef && getOr(false, ['ui', 'slide', 'showCorrectionPopin'], state);
|
|
74
|
+
const updatedUiSlide = pipe(set('showCorrectionPopin', showCorrectionPopin), set('animateCorrectionPopin', animateCorrectionPopin), set('loading', false), set('questionText', questionText), set('answerUI', answerUI), set('parentContentTitle', `From "${parentContentTitle}" ${parentContentType}`) // TODO translate: -From- .... -Course/chapter-
|
|
71
75
|
// TODO: Set position according to currentSlideRef et slideRefs (or maybe a value on the state ui.slidePositions !!)
|
|
72
76
|
)(uiSlide);
|
|
73
77
|
return set(index, updatedUiSlide, acc);
|
|
@@ -141,7 +145,29 @@ export const buildStepItems = (state) => {
|
|
|
141
145
|
});
|
|
142
146
|
return steps;
|
|
143
147
|
};
|
|
148
|
+
const getCorrectionPopinProps = (isCorrect, correctAnswer, klf) => ({
|
|
149
|
+
klf: isCorrect
|
|
150
|
+
? undefined
|
|
151
|
+
: {
|
|
152
|
+
label: '_klf',
|
|
153
|
+
tooltip: klf
|
|
154
|
+
},
|
|
155
|
+
resultLabel: isCorrect ? '_right' : '_wrong',
|
|
156
|
+
information: {
|
|
157
|
+
label: isCorrect ? '_klf' : '_correctAnswer',
|
|
158
|
+
message: isCorrect ? klf : join(',', correctAnswer)
|
|
159
|
+
},
|
|
160
|
+
next: {
|
|
161
|
+
ariaLabel: '_correctionNextAriaLabel',
|
|
162
|
+
label: '_correctionNextLabel'
|
|
163
|
+
},
|
|
164
|
+
type: isCorrect ? 'right' : 'wrong'
|
|
165
|
+
});
|
|
144
166
|
export const mapStateToSlidesProps = (state, dispatch) => {
|
|
167
|
+
const currentSlideRef = get(['ui', 'currentSlideRef'], state);
|
|
168
|
+
const correction = get(['data', 'corrections', currentSlideRef], state);
|
|
169
|
+
const isCorrect = get(['data', 'progression', 'state', 'isCorrect'], state);
|
|
170
|
+
const klf = getOr('', ['data', 'slides', currentSlideRef, 'klf'], state);
|
|
145
171
|
return {
|
|
146
172
|
header: {
|
|
147
173
|
mode: '__revision_mode',
|
|
@@ -159,11 +185,11 @@ export const mapStateToSlidesProps = (state, dispatch) => {
|
|
|
159
185
|
validateButton: {
|
|
160
186
|
label: '__validate',
|
|
161
187
|
disabled: !get('ui.slide.validateButton', state),
|
|
162
|
-
onClick: () => {
|
|
188
|
+
onClick: /* istanbul ignore next */ () => {
|
|
163
189
|
dispatch(postAnswer);
|
|
164
190
|
}
|
|
165
191
|
},
|
|
166
|
-
correctionPopinProps:
|
|
192
|
+
correctionPopinProps: correction && getCorrectionPopinProps(isCorrect, correction.correctAnswer, klf),
|
|
167
193
|
endReview: false
|
|
168
194
|
},
|
|
169
195
|
congratsProps: undefined
|