@coorpacademy/app-review 0.1.5 → 0.1.8
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-skills.d.ts +10 -0
- package/es/actions/api/fetch-skills.js +8 -0
- package/es/actions/api/fetch-slide.d.ts +10 -0
- package/es/actions/api/fetch-slide.js +8 -0
- package/es/actions/api/post-progression.d.ts +10 -0
- package/es/actions/api/post-progression.js +15 -0
- package/es/actions/data/slides.d.ts +7 -24
- package/es/actions/data/slides.js +0 -6
- package/es/actions/data/token.d.ts +2 -2
- package/es/actions/data/token.js +1 -1
- package/es/actions/index.d.ts +5 -3
- package/es/actions/ui/navigation.d.ts +0 -1
- package/es/actions/ui/navigation.js +0 -4
- package/es/actions/ui/step-items.d.ts +2 -8
- package/es/actions/ui/step-items.js +0 -6
- package/es/configure-store.d.ts +3 -34
- package/es/configure-store.js +4 -4
- package/es/fixtures/qcm-slide.d.ts +2 -2
- package/es/index.d.ts +1 -1
- package/es/index.js +78 -42
- package/es/reducers/data/index.d.ts +16 -5
- package/es/reducers/data/progression.d.ts +14 -9
- package/es/reducers/data/progression.js +18 -58
- package/es/reducers/data/skills.d.ts +4 -5
- package/es/reducers/data/skills.js +3 -6
- package/es/reducers/data/slides.d.ts +2 -1
- package/es/reducers/data/slides.js +14 -9
- package/es/reducers/data/token.d.ts +0 -1
- package/es/reducers/data/token.js +1 -5
- package/es/reducers/index.d.ts +9 -3
- package/es/reducers/ui/finished-slides.d.ts +0 -1
- package/es/reducers/ui/finished-slides.js +1 -3
- package/es/reducers/ui/index.d.ts +14 -4
- package/es/reducers/ui/navigation.d.ts +0 -1
- package/es/reducers/ui/navigation.js +1 -3
- package/es/reducers/ui/review-status.d.ts +0 -1
- package/es/reducers/ui/review-status.js +1 -4
- package/es/reducers/ui/step-items.d.ts +5 -5
- package/es/reducers/ui/step-items.js +0 -1
- package/es/services/fetch-skills.d.ts +2 -8
- package/es/services/fetch-skills.js +3 -16
- package/es/services/fetch-slide.d.ts +2 -0
- package/es/services/fetch-slide.js +11 -0
- package/es/services/index.d.ts +2 -0
- package/es/services/index.js +8 -0
- package/es/services/post-progression.d.ts +2 -0
- package/es/services/post-progression.js +21 -0
- package/es/services/test/fetch-skills.test.js +29 -0
- package/es/services/test/post-progression.test.js +35 -0
- package/es/services/tools/fetch-responses.d.ts +1 -1
- package/es/services/tools/sleep.d.ts +1 -0
- package/es/services/tools/sleep.js +3 -0
- package/es/{index.test.js → test/index.test.js} +18 -7
- package/es/test/util/services.mock.d.ts +2 -0
- package/es/test/util/services.mock.js +68 -0
- package/es/types/common.d.ts +66 -2
- package/es/types/common.js +5 -0
- package/es/types/slides.d.ts +1 -1
- package/es/types/ui-progression.d.ts +10 -0
- package/es/types/views/slides.d.ts +1 -1
- package/lib/actions/api/fetch-skills.d.ts +10 -0
- package/lib/actions/api/fetch-skills.js +13 -0
- package/lib/actions/api/fetch-slide.d.ts +10 -0
- package/lib/actions/api/fetch-slide.js +13 -0
- package/lib/actions/api/post-progression.d.ts +10 -0
- package/lib/actions/api/post-progression.js +18 -0
- package/lib/actions/data/slides.d.ts +7 -24
- package/lib/actions/data/slides.js +0 -6
- package/lib/actions/data/token.d.ts +2 -2
- package/lib/actions/data/token.js +1 -1
- package/lib/actions/index.d.ts +5 -3
- package/lib/actions/ui/navigation.d.ts +0 -1
- package/lib/actions/ui/navigation.js +0 -4
- package/lib/actions/ui/step-items.d.ts +2 -8
- package/lib/actions/ui/step-items.js +0 -6
- package/lib/configure-store.d.ts +3 -34
- package/lib/configure-store.js +4 -4
- package/lib/fixtures/qcm-slide.d.ts +2 -2
- package/lib/index.d.ts +1 -1
- package/lib/index.js +78 -86
- package/lib/reducers/data/index.d.ts +16 -5
- package/lib/reducers/data/progression.d.ts +14 -9
- package/lib/reducers/data/progression.js +18 -58
- package/lib/reducers/data/skills.d.ts +4 -5
- package/lib/reducers/data/skills.js +3 -6
- package/lib/reducers/data/slides.d.ts +2 -1
- package/lib/reducers/data/slides.js +14 -9
- package/lib/reducers/data/token.d.ts +0 -1
- package/lib/reducers/data/token.js +1 -5
- package/lib/reducers/index.d.ts +9 -3
- package/lib/reducers/ui/finished-slides.d.ts +0 -1
- package/lib/reducers/ui/finished-slides.js +1 -3
- package/lib/reducers/ui/index.d.ts +14 -4
- package/lib/reducers/ui/navigation.d.ts +0 -1
- package/lib/reducers/ui/navigation.js +1 -3
- package/lib/reducers/ui/review-status.d.ts +0 -1
- package/lib/reducers/ui/review-status.js +1 -4
- package/lib/reducers/ui/step-items.d.ts +5 -5
- package/lib/reducers/ui/step-items.js +0 -1
- package/lib/services/fetch-skills.d.ts +2 -8
- package/lib/services/fetch-skills.js +5 -20
- package/lib/services/fetch-slide.d.ts +2 -0
- package/lib/services/fetch-slide.js +57 -0
- package/lib/services/index.d.ts +2 -0
- package/lib/services/index.js +8 -0
- package/lib/services/post-progression.d.ts +2 -0
- package/lib/services/post-progression.js +65 -0
- package/lib/services/{fetch-skills.test.js → test/fetch-skills.test.js} +23 -16
- package/lib/services/test/post-progression.test.js +89 -0
- package/lib/services/tools/fetch-responses.d.ts +1 -1
- package/lib/services/tools/sleep.d.ts +1 -0
- package/lib/services/tools/sleep.js +5 -0
- package/lib/test/index.test.d.ts +1 -0
- package/lib/{index.test.js → test/index.test.js} +23 -15
- package/lib/test/util/services.mock.d.ts +2 -0
- package/lib/test/util/services.mock.js +68 -0
- package/lib/types/common.d.ts +66 -2
- package/lib/types/common.js +5 -0
- package/lib/types/slides.d.ts +1 -1
- package/lib/types/ui-progression.d.ts +10 -0
- package/lib/types/ui-progression.js +1 -0
- package/lib/types/views/slides.d.ts +1 -1
- package/package.json +6 -5
- package/readme.md +4 -5
- package/src/actions/api/fetch-skills.ts +20 -0
- package/src/actions/api/fetch-slide.ts +20 -0
- package/src/actions/api/post-progression.ts +26 -0
- package/src/actions/data/slides.ts +8 -32
- package/src/actions/data/token.ts +2 -2
- package/src/actions/index.ts +7 -10
- package/src/actions/ui/navigation.ts +0 -5
- package/src/actions/ui/step-items.ts +2 -14
- package/src/configure-store.ts +6 -45
- package/src/fixtures/qcm-slide.ts +2 -2
- package/src/index.tsx +94 -45
- package/src/reducers/data/index.ts +12 -4
- package/src/reducers/data/progression.ts +34 -79
- package/src/reducers/data/skills.ts +5 -10
- package/src/reducers/data/slides.ts +16 -15
- package/src/reducers/data/token.ts +1 -11
- package/src/reducers/index.ts +7 -2
- package/src/reducers/ui/finished-slides.ts +1 -7
- package/src/reducers/ui/index.ts +11 -4
- package/src/reducers/ui/navigation.ts +1 -6
- package/src/reducers/ui/review-status.ts +1 -8
- package/src/reducers/ui/step-items.ts +5 -14
- package/src/services/fetch-skills.ts +4 -30
- package/src/services/fetch-slide.ts +15 -0
- package/src/services/index.ts +10 -0
- package/src/services/post-progression.ts +28 -0
- package/src/services/test/fetch-skills.test.ts +39 -0
- package/src/services/test/post-progression.test.ts +45 -0
- package/src/services/tools/fetch-responses.ts +1 -1
- package/src/services/tools/sleep.ts +4 -0
- package/src/{index.test.tsx → test/index.test.tsx} +16 -10
- package/src/test/util/services.mock.ts +70 -0
- package/src/types/common.ts +78 -2
- package/src/types/globals.d.ts +2 -0
- package/src/types/slides.ts +1 -1
- package/src/types/ui-progression.ts +25 -0
- package/src/types/views/slides.ts +1 -1
- package/es/actions/data/skills.d.ts +0 -13
- package/es/actions/data/skills.js +0 -10
- package/es/middlewares/on-start-app.d.ts +0 -5
- package/es/middlewares/on-start-app.js +0 -29
- package/es/services/fetch-skills.mock.d.ts +0 -3
- package/es/services/fetch-skills.mock.js +0 -17
- package/es/services/fetch-skills.test.js +0 -22
- package/es/services/tools/fetch.mocks.d.ts +0 -8
- package/es/services/tools/fetch.mocks.js +0 -13
- package/es/types/skills.d.ts +0 -7
- package/lib/actions/data/skills.d.ts +0 -13
- package/lib/actions/data/skills.js +0 -10
- package/lib/middlewares/on-start-app.d.ts +0 -5
- package/lib/middlewares/on-start-app.js +0 -34
- package/lib/services/fetch-skills.mock.d.ts +0 -3
- package/lib/services/fetch-skills.mock.js +0 -17
- package/lib/services/tools/fetch.mocks.d.ts +0 -8
- package/lib/services/tools/fetch.mocks.js +0 -35
- package/lib/types/skills.d.ts +0 -7
- package/src/actions/data/skills.ts +0 -24
- package/src/middlewares/on-start-app.ts +0 -42
- package/src/services/fetch-skills.mock.ts +0 -21
- package/src/services/fetch-skills.test.ts +0 -32
- package/src/services/tools/fetch.mocks.ts +0 -41
- package/src/types/skills.ts +0 -8
- /package/es/services/{fetch-skills.test.d.ts → test/fetch-skills.test.d.ts} +0 -0
- /package/es/{index.test.d.ts → services/test/post-progression.test.d.ts} +0 -0
- /package/{lib → es/test}/index.test.d.ts +0 -0
- /package/es/types/{skills.js → ui-progression.js} +0 -0
- /package/lib/services/{fetch-skills.test.d.ts → test/fetch-skills.test.d.ts} +0 -0
- /package/lib/{types/skills.js → services/test/post-progression.test.d.ts} +0 -0
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export const initialState = [];
|
|
3
|
-
// -----------------------------------------------------------------------------
|
|
1
|
+
import { SKILLS_FETCH_SUCCESS } from '../../actions/api/fetch-skills';
|
|
4
2
|
// eslint-disable-next-line default-param-last
|
|
5
|
-
const reducer = (state =
|
|
3
|
+
const reducer = (state = [], action) => {
|
|
6
4
|
switch (action.type) {
|
|
7
|
-
case
|
|
5
|
+
case SKILLS_FETCH_SUCCESS:
|
|
8
6
|
return action.payload;
|
|
9
7
|
default:
|
|
10
8
|
return state;
|
|
11
9
|
}
|
|
12
10
|
};
|
|
13
|
-
// -----------------------------------------------------------------------------
|
|
14
11
|
export default reducer;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import map from 'lodash/fp/map';
|
|
2
|
-
import {
|
|
2
|
+
import { UPDATE_SLIDES_ON_NEXT, UPDATE_SLIDES_ON_VALIDATION } from '../../actions/data/slides';
|
|
3
3
|
import { HIGHEST_INDEX, slideNumbers, TOTAL_SLIDES_STACK } from '../../common';
|
|
4
|
-
|
|
4
|
+
import { slide as qcmSlide } from '../../fixtures/qcm-slide';
|
|
5
|
+
import { SLIDE_FETCH_SUCCESS } from '../../actions/api/fetch-slide';
|
|
5
6
|
const getInitialState = () => {
|
|
6
7
|
const state = {
|
|
7
8
|
slideNumbers
|
|
@@ -30,7 +31,7 @@ const setFirstSlide = (state, slide) => {
|
|
|
30
31
|
// ||-------> Handles the updates of a given slide on validation,
|
|
31
32
|
// & then updates de remaining slides if this given change should impact their content
|
|
32
33
|
const stateUpdateOnValidation = (state, payload) => {
|
|
33
|
-
const { slideNumber, newSlideContent, numberOfFinishedSlides,
|
|
34
|
+
const { slideNumber, newSlideContent, numberOfFinishedSlides, nextContent } = payload;
|
|
34
35
|
const _state = {
|
|
35
36
|
slideNumbers
|
|
36
37
|
};
|
|
@@ -43,7 +44,7 @@ const stateUpdateOnValidation = (state, payload) => {
|
|
|
43
44
|
if (numberOfFinishedSlides === HIGHEST_INDEX) {
|
|
44
45
|
_state[index] = {
|
|
45
46
|
...previousValue,
|
|
46
|
-
|
|
47
|
+
nextContent,
|
|
47
48
|
position: newSlideContent.position,
|
|
48
49
|
isCorrect: newSlideContent.isCorrect
|
|
49
50
|
};
|
|
@@ -54,7 +55,7 @@ const stateUpdateOnValidation = (state, payload) => {
|
|
|
54
55
|
else {
|
|
55
56
|
// updates the rest of the slides here
|
|
56
57
|
const { hidden, position } = previousValue;
|
|
57
|
-
_state[index] = { ...
|
|
58
|
+
_state[index] = { ...nextContent, endReview: newSlideContent.endReview, hidden, position };
|
|
58
59
|
}
|
|
59
60
|
}, state.slideNumbers);
|
|
60
61
|
return _state;
|
|
@@ -72,8 +73,8 @@ const stateUpdateOnNext = (state, payload) => {
|
|
|
72
73
|
// the current slide
|
|
73
74
|
if (index === slideNumber) {
|
|
74
75
|
// when there is only one slide remaining, updates the slide value
|
|
75
|
-
if (numberOfFinishedSlides === HIGHEST_INDEX && previousValue.
|
|
76
|
-
_state[index] = { ...previousValue.
|
|
76
|
+
if (numberOfFinishedSlides === HIGHEST_INDEX && previousValue.nextContent) {
|
|
77
|
+
_state[index] = { ...previousValue.nextContent, position: previousValue.position };
|
|
77
78
|
}
|
|
78
79
|
else
|
|
79
80
|
_state[slideNumber] = newSlideContent;
|
|
@@ -96,8 +97,12 @@ const stateUpdateOnNext = (state, payload) => {
|
|
|
96
97
|
// eslint-disable-next-line default-param-last
|
|
97
98
|
const reducer = (state = initialState, action) => {
|
|
98
99
|
switch (action.type) {
|
|
99
|
-
case
|
|
100
|
-
|
|
100
|
+
case SLIDE_FETCH_SUCCESS: {
|
|
101
|
+
// TODO: An intermediate slide transform is needed here (or in fetchSlide)
|
|
102
|
+
// const apiSlide = action.payload;
|
|
103
|
+
// apiSlide adapt to uiSlide
|
|
104
|
+
const uiSlide = qcmSlide;
|
|
105
|
+
return setFirstSlide(state, uiSlide);
|
|
101
106
|
}
|
|
102
107
|
case UPDATE_SLIDES_ON_VALIDATION: {
|
|
103
108
|
return stateUpdateOnValidation(state, action.payload);
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { STORE_TOKEN } from '../../actions/data/token';
|
|
2
|
-
// -----------------------------------------------------------------------------
|
|
3
|
-
export const initialState = null;
|
|
4
|
-
// -----------------------------------------------------------------------------
|
|
5
2
|
// eslint-disable-next-line default-param-last
|
|
6
|
-
const reducer = (state =
|
|
3
|
+
const reducer = (state = null, action) => {
|
|
7
4
|
switch (action.type) {
|
|
8
5
|
case STORE_TOKEN:
|
|
9
6
|
return action.payload;
|
|
@@ -11,5 +8,4 @@ const reducer = (state = initialState, action) => {
|
|
|
11
8
|
return state;
|
|
12
9
|
}
|
|
13
10
|
};
|
|
14
|
-
// -----------------------------------------------------------------------------
|
|
15
11
|
export default reducer;
|
package/es/reducers/index.d.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import { DataState } from './data';
|
|
2
|
+
import { UIState } from './ui';
|
|
3
|
+
export declare type StoreState = {
|
|
4
|
+
ui: UIState;
|
|
5
|
+
data: DataState;
|
|
6
|
+
};
|
|
1
7
|
declare const _default: import("redux").Reducer<import("redux").CombinedState<{
|
|
2
8
|
data: import("redux").CombinedState<{
|
|
3
9
|
progression: import("./data/progression").ProgressionState;
|
|
4
|
-
skills: import("
|
|
10
|
+
skills: import("./data/skills").SkillsState;
|
|
5
11
|
slides: import("./data/slides").SlidesState;
|
|
6
12
|
token: import("./data/token").TokenState;
|
|
7
13
|
}>;
|
|
@@ -9,7 +15,7 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
|
|
|
9
15
|
finishedSlides: import("./ui/finished-slides").FinishedSlidesState;
|
|
10
16
|
navigation: import("./ui/navigation").NavigationState;
|
|
11
17
|
reviewStatus: import("./ui/review-status").ReviewStatusState;
|
|
12
|
-
stepItems: import("./ui/step-items").
|
|
18
|
+
stepItems: import("./ui/step-items").StepItemsState;
|
|
13
19
|
}>;
|
|
14
|
-
}>, import("../actions/data/slides").ValidateSlide | import("../actions/data/slides").SlidesAction | import("../actions/
|
|
20
|
+
}>, import("../actions/data/slides").ValidateSlide | import("../actions/data/slides").SlidesAction | import("../actions/api/post-progression").ReceiveProgression | import("../actions/api/fetch-skills").ReceivedSkills | import("../actions/data/token").StoreToken | import("../actions/ui/finished-slides").UpdateFinishedSlides | import("../actions/ui/navigation").NavigateTo | import("../actions/ui/navigation").NavigateBack | import("../actions/ui/review-status").UpdateReviewStatus | import("../actions/ui/step-items").StepItemsAction>;
|
|
15
21
|
export default _default;
|
|
@@ -3,6 +3,5 @@ export declare type FinishedSlidesState = {
|
|
|
3
3
|
slideNumbers: number[];
|
|
4
4
|
[key: number]: true;
|
|
5
5
|
};
|
|
6
|
-
export declare const initialState: FinishedSlidesState;
|
|
7
6
|
declare const reducer: (state: FinishedSlidesState | undefined, action: UpdateFinishedSlides) => FinishedSlidesState;
|
|
8
7
|
export default reducer;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import forEach from 'lodash/fp/forEach';
|
|
2
2
|
import { UPDATE_FINISHED_SLIDES } from '../../actions/ui/finished-slides';
|
|
3
3
|
import { slideNumbers } from '../../common';
|
|
4
|
-
|
|
5
|
-
export const initialState = {
|
|
4
|
+
const initialState = {
|
|
6
5
|
slideNumbers
|
|
7
6
|
};
|
|
8
|
-
// -----------------------------------------------------------------------------
|
|
9
7
|
const _forEach = forEach.convert({
|
|
10
8
|
cap: false
|
|
11
9
|
});
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
+
import { FinishedSlidesState } from './finished-slides';
|
|
2
|
+
import { NavigationState } from './navigation';
|
|
3
|
+
import { ReviewStatusState } from './review-status';
|
|
4
|
+
import { StepItemsState } from './step-items';
|
|
5
|
+
export declare type UIState = {
|
|
6
|
+
navigation: NavigationState;
|
|
7
|
+
stepItems: StepItemsState;
|
|
8
|
+
finishedSlides: FinishedSlidesState;
|
|
9
|
+
reviewStatus: ReviewStatusState;
|
|
10
|
+
};
|
|
1
11
|
declare const _default: import("redux").Reducer<import("redux").CombinedState<{
|
|
2
|
-
finishedSlides:
|
|
3
|
-
navigation:
|
|
4
|
-
reviewStatus:
|
|
5
|
-
stepItems:
|
|
12
|
+
finishedSlides: FinishedSlidesState;
|
|
13
|
+
navigation: NavigationState;
|
|
14
|
+
reviewStatus: ReviewStatusState;
|
|
15
|
+
stepItems: StepItemsState;
|
|
6
16
|
}>, import("../../actions/ui/finished-slides").UpdateFinishedSlides | import("../../actions/ui/navigation").NavigateTo | import("../../actions/ui/navigation").NavigateBack | import("../../actions/ui/review-status").UpdateReviewStatus | import("../../actions/ui/step-items").StepItemsAction>;
|
|
7
17
|
export default _default;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type NavigateTo, type NavigateBack } from '../../actions/ui/navigation';
|
|
2
2
|
export declare type NavigationState = Array<'skills' | 'onboarding' | 'slides'>;
|
|
3
|
-
export declare const initialState: NavigationState;
|
|
4
3
|
declare const reducer: (state: NavigationState | undefined, action: NavigateTo | NavigateBack) => NavigationState;
|
|
5
4
|
export default reducer;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { NAVIGATE_BACK, NAVIGATE_TO } from '../../actions/ui/navigation';
|
|
2
|
-
export const initialState = [];
|
|
3
|
-
// -----------------------------------------------------------------------------
|
|
4
2
|
const reducer = (
|
|
5
3
|
// eslint-disable-next-line default-param-last
|
|
6
|
-
state =
|
|
4
|
+
state = [], action) => {
|
|
7
5
|
switch (action.type) {
|
|
8
6
|
case NAVIGATE_TO: {
|
|
9
7
|
return [...state, action.payload];
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { UpdateReviewStatus } from '../../actions/ui/review-status';
|
|
2
2
|
export declare type ReviewStatusState = 'finished' | 'ongoing';
|
|
3
|
-
export declare const initialState: ReviewStatusState;
|
|
4
3
|
declare const reducer: (state: ReviewStatusState | undefined, action: UpdateReviewStatus) => ReviewStatusState;
|
|
5
4
|
export default reducer;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { UPDATE_REVIEW_STATUS } from '../../actions/ui/review-status';
|
|
2
|
-
export const initialState = 'ongoing';
|
|
3
|
-
// -----------------------------------------------------------------------------
|
|
4
2
|
const reducer = (
|
|
5
3
|
// eslint-disable-next-line default-param-last
|
|
6
|
-
state =
|
|
4
|
+
state = 'ongoing', action) => {
|
|
7
5
|
switch (action.type) {
|
|
8
6
|
case UPDATE_REVIEW_STATUS: {
|
|
9
7
|
return action.payload;
|
|
@@ -12,5 +10,4 @@ state = initialState, action) => {
|
|
|
12
10
|
return state;
|
|
13
11
|
}
|
|
14
12
|
};
|
|
15
|
-
// -----------------------------------------------------------------------------
|
|
16
13
|
export default reducer;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { IconValue
|
|
2
|
-
|
|
1
|
+
import { IconValue } from '../../types/common';
|
|
2
|
+
import { StepItemsAction } from '../../actions/ui/step-items';
|
|
3
|
+
export declare type StepItem = {
|
|
3
4
|
current: boolean;
|
|
4
5
|
icon: IconValue;
|
|
5
6
|
value: string;
|
|
6
7
|
};
|
|
7
|
-
export declare type
|
|
8
|
+
export declare type StepItemsState = {
|
|
8
9
|
slideNumbers: number[];
|
|
9
10
|
[key: number]: StepItem;
|
|
10
11
|
};
|
|
11
|
-
export declare type StepItemsState = StepItems;
|
|
12
12
|
export declare const initialState: StepItemsState;
|
|
13
|
-
declare const reducer: (state:
|
|
13
|
+
declare const reducer: (state: StepItemsState | undefined, action: StepItemsAction) => StepItemsState;
|
|
14
14
|
export default reducer;
|
|
@@ -3,7 +3,6 @@ import has from 'lodash/fp/has';
|
|
|
3
3
|
import map from 'lodash/fp/map';
|
|
4
4
|
import { UPDATE_STEP_ITEMS_ON_NEXT, UPDATE_STEP_ITEMS_ON_VALIDATION } from '../../actions/ui/step-items';
|
|
5
5
|
import { HIGHEST_INDEX, slideNumbers, TOTAL_SLIDES_STACK } from '../../common';
|
|
6
|
-
// -----------------------------------------------------------------------------
|
|
7
6
|
const getInitialState = () => {
|
|
8
7
|
const state = {
|
|
9
8
|
slideNumbers
|
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
declare type FetchSkills = (token: string) => Promise<Skills>;
|
|
4
|
-
declare type CreateFetchSkills = (fetch: typeof crossFetch) => FetchSkills;
|
|
5
|
-
declare const fetchSkills: CreateFetchSkills;
|
|
6
|
-
export { fetchSkills };
|
|
7
|
-
declare const _default: FetchSkills;
|
|
8
|
-
export default _default;
|
|
1
|
+
import { Skill } from '../types/common';
|
|
2
|
+
export declare const fetchSkills: (token: string) => Promise<Skill[]>;
|
|
@@ -1,23 +1,10 @@
|
|
|
1
1
|
import crossFetch from 'cross-fetch';
|
|
2
2
|
import decode from 'jwt-decode';
|
|
3
3
|
import { toJSON } from './tools/fetch-responses';
|
|
4
|
-
|
|
5
|
-
// -----------------------------------------------------------------------------
|
|
6
|
-
const fetchSkills = fetch => async (token) => {
|
|
4
|
+
export const fetchSkills = async (token) => {
|
|
7
5
|
const { user: userId, host } = decode(token);
|
|
8
|
-
const response = await
|
|
6
|
+
const response = await crossFetch(`${host}/api/v2/skills/review/user/${userId}`, {
|
|
9
7
|
headers: { authorization: token }
|
|
10
8
|
});
|
|
11
|
-
|
|
12
|
-
return skills;
|
|
9
|
+
return toJSON(response);
|
|
13
10
|
};
|
|
14
|
-
// -----------------------------------------------------------------------------
|
|
15
|
-
const createFetchSkills = () => {
|
|
16
|
-
if (process.env.SERVICES !== 'mocks') {
|
|
17
|
-
return fetchSkills(crossFetch);
|
|
18
|
-
}
|
|
19
|
-
return fetchSkills(mockFetchSkills);
|
|
20
|
-
};
|
|
21
|
-
// -----------------------------------------------------------------------------
|
|
22
|
-
export { fetchSkills };
|
|
23
|
-
export default createFetchSkills();
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import crossFetch from 'cross-fetch';
|
|
2
|
+
import decode from 'jwt-decode';
|
|
3
|
+
import { toJSON } from './tools/fetch-responses';
|
|
4
|
+
export const fetchSlide = async (slideRef, token) => {
|
|
5
|
+
const { host } = decode(token);
|
|
6
|
+
const response = await crossFetch(`${host}/api/v2/slide/${slideRef}`, {
|
|
7
|
+
headers: { authorization: token }
|
|
8
|
+
});
|
|
9
|
+
const slide = (await toJSON(response));
|
|
10
|
+
return slide;
|
|
11
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import crossFetch from 'cross-fetch';
|
|
2
|
+
import decode from 'jwt-decode';
|
|
3
|
+
import { toJSON } from './tools/fetch-responses';
|
|
4
|
+
export const postProgression = async (skillRef, token) => {
|
|
5
|
+
const { host } = decode(token);
|
|
6
|
+
const response = await crossFetch(`${host}/api/v2/progressions`, {
|
|
7
|
+
method: 'post',
|
|
8
|
+
headers: { authorization: token },
|
|
9
|
+
body: JSON.stringify({
|
|
10
|
+
content: {
|
|
11
|
+
ref: skillRef,
|
|
12
|
+
type: 'slide'
|
|
13
|
+
},
|
|
14
|
+
engine: {
|
|
15
|
+
ref: 'review',
|
|
16
|
+
version: '1'
|
|
17
|
+
}
|
|
18
|
+
})
|
|
19
|
+
});
|
|
20
|
+
return toJSON(response);
|
|
21
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import nock from 'nock';
|
|
3
|
+
import { fetchSkills } from '../fetch-skills';
|
|
4
|
+
const result = [
|
|
5
|
+
{
|
|
6
|
+
slidesToReview: 1,
|
|
7
|
+
name: 'skill-test',
|
|
8
|
+
custom: false,
|
|
9
|
+
skillRef: '_skill-ref'
|
|
10
|
+
}
|
|
11
|
+
];
|
|
12
|
+
test.before(() => {
|
|
13
|
+
nock('http://localhost:3000')
|
|
14
|
+
.get('/api/v2/skills/review/user/592d830b240b923f00bffba6')
|
|
15
|
+
.reply(200, result);
|
|
16
|
+
});
|
|
17
|
+
test.after(() => {
|
|
18
|
+
nock.cleanAll();
|
|
19
|
+
});
|
|
20
|
+
test('should fetch skills with success', async (t) => {
|
|
21
|
+
const token = process.env.API_TEST_TOKEN || '';
|
|
22
|
+
const skills = await fetchSkills(token);
|
|
23
|
+
t.deepEqual(result, skills);
|
|
24
|
+
});
|
|
25
|
+
test('should reject bad token', async (t) => {
|
|
26
|
+
const badToken = 'token is not a jwt';
|
|
27
|
+
const error = await t.throwsAsync(() => fetchSkills(badToken));
|
|
28
|
+
t.is(error?.message, "Invalid token specified: Cannot read properties of undefined (reading 'replace')");
|
|
29
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import nock from 'nock';
|
|
3
|
+
import { postProgression } from '../post-progression';
|
|
4
|
+
const skillRef = '_skill-ref';
|
|
5
|
+
const result = {
|
|
6
|
+
_id: '123456123456',
|
|
7
|
+
state: {
|
|
8
|
+
isCorrect: true,
|
|
9
|
+
step: {
|
|
10
|
+
current: 1
|
|
11
|
+
},
|
|
12
|
+
nextContent: {
|
|
13
|
+
type: 'slide',
|
|
14
|
+
ref: 'sli_NJ3m5KtWh'
|
|
15
|
+
},
|
|
16
|
+
pendingSlides: []
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
test.before(() => {
|
|
20
|
+
const moocApi = nock('http://localhost:3000');
|
|
21
|
+
moocApi.post('/api/v2/progressions').reply(200, result);
|
|
22
|
+
});
|
|
23
|
+
test.after(() => {
|
|
24
|
+
nock.cleanAll();
|
|
25
|
+
});
|
|
26
|
+
test('should create progression with success', async (t) => {
|
|
27
|
+
const token = process.env.API_TEST_TOKEN || '';
|
|
28
|
+
const progression = await postProgression(skillRef, token);
|
|
29
|
+
t.deepEqual(result, progression);
|
|
30
|
+
});
|
|
31
|
+
test('should reject bad token', async (t) => {
|
|
32
|
+
const badToken = 'token is not a jwt';
|
|
33
|
+
const error = await t.throwsAsync(() => postProgression(skillRef, badToken));
|
|
34
|
+
t.is(error?.message, "Invalid token specified: Cannot read properties of undefined (reading 'replace')");
|
|
35
|
+
});
|
|
@@ -2,6 +2,6 @@ export declare class ResponseError extends Error {
|
|
|
2
2
|
statusCode: number;
|
|
3
3
|
constructor(statusCode: number, statusText: string, body?: string);
|
|
4
4
|
}
|
|
5
|
-
export declare const toJSON: (response: Response) => Promise<
|
|
5
|
+
export declare const toJSON: <T = unknown>(response: Response) => Promise<T>;
|
|
6
6
|
export declare const toText: (response: Response) => Promise<string>;
|
|
7
7
|
export declare const toVoid: (response: Response) => Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const sleep: (msToSleep: number) => Promise<void>;
|
|
@@ -2,13 +2,11 @@ import browserEnv from 'browser-env';
|
|
|
2
2
|
import test from 'ava';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { render, fireEvent, act } from '@testing-library/react';
|
|
5
|
-
import {
|
|
6
|
-
import AppReview from '
|
|
5
|
+
import { sleep } from '../services/tools/sleep';
|
|
6
|
+
import AppReview from '..';
|
|
7
|
+
import { services } from './util/services.mock';
|
|
7
8
|
browserEnv({ pretendToBeVisual: true });
|
|
8
9
|
const elementExists = (foundElements) => foundElements && foundElements[0];
|
|
9
|
-
const sleep = (msToSleep) => new Promise(resolve => {
|
|
10
|
-
setTimeout(resolve, msToSleep);
|
|
11
|
-
});
|
|
12
10
|
const waitForChanges = async (msToWait = 3000) => {
|
|
13
11
|
await act(async () => {
|
|
14
12
|
await sleep(msToWait); // wait *just* a little longer than the timeout in the component
|
|
@@ -33,20 +31,33 @@ const clickAllSlides = async (t, container, accumulator = 0) => {
|
|
|
33
31
|
await act(async () => {
|
|
34
32
|
await fireEvent.click(nextButton[0]);
|
|
35
33
|
});
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
36
35
|
await clickAllSlides(t, container, accumulator + 1);
|
|
37
36
|
};
|
|
38
37
|
const appOptions = {
|
|
39
38
|
token: process.env.API_TEST_TOKEN || '',
|
|
40
|
-
|
|
39
|
+
templateContext: {
|
|
40
|
+
theme: { color: { primary: '#123' } }
|
|
41
|
+
},
|
|
42
|
+
skillRef: 'skill_NJC0jFKoH',
|
|
43
|
+
services
|
|
41
44
|
};
|
|
42
45
|
test('should validate all the slides (all correct scenario)', async (t) => {
|
|
43
|
-
t.plan(13);
|
|
46
|
+
// t.plan(13);
|
|
47
|
+
t.plan(2);
|
|
44
48
|
const { container } = render(React.createElement(AppReview, { options: appOptions, key: 0 }));
|
|
45
49
|
await waitForChanges(1000);
|
|
50
|
+
const wrapper = container.querySelector('[data-name="loader"]');
|
|
51
|
+
t.truthy(wrapper);
|
|
52
|
+
/*
|
|
46
53
|
const wrapper = container.querySelector('[data-name="slides-revision-container"]');
|
|
47
54
|
t.truthy(wrapper);
|
|
55
|
+
|
|
48
56
|
const stackedSlidesContainer = wrapper?.querySelector('[data-name="stacked-slides-container"]');
|
|
57
|
+
|
|
49
58
|
t.truthy(stackedSlidesContainer);
|
|
59
|
+
|
|
50
60
|
await clickAllSlides(t, container);
|
|
61
|
+
*/
|
|
51
62
|
t.pass();
|
|
52
63
|
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export const services = {
|
|
2
|
+
fetchSkills: () => {
|
|
3
|
+
return Promise.resolve([
|
|
4
|
+
{
|
|
5
|
+
skillRef: '_skill-ref',
|
|
6
|
+
slidesToReview: 2,
|
|
7
|
+
name: 'skill-test',
|
|
8
|
+
custom: false
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
skillRef: '_skill-ref-2',
|
|
12
|
+
slidesToReview: 2,
|
|
13
|
+
name: 'skill-test-2',
|
|
14
|
+
custom: true
|
|
15
|
+
}
|
|
16
|
+
]);
|
|
17
|
+
},
|
|
18
|
+
fetchSlide: ref => {
|
|
19
|
+
// return Promise.resolve(qcm); // why qcm does not look like a slide returned from mooc ?
|
|
20
|
+
return Promise.resolve({
|
|
21
|
+
question: {
|
|
22
|
+
content: {
|
|
23
|
+
choices: [
|
|
24
|
+
{
|
|
25
|
+
selected: false,
|
|
26
|
+
title: 'choix1',
|
|
27
|
+
help: '(help choix1)',
|
|
28
|
+
ariaLabel: '__ariaLabel1',
|
|
29
|
+
onClick: () => undefined
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
selected: false,
|
|
33
|
+
title: 'choix2',
|
|
34
|
+
help: '(help choix2)',
|
|
35
|
+
ariaLabel: '__ariaLabel2',
|
|
36
|
+
onClick: () => undefined
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
selected: false,
|
|
40
|
+
title: 'choix3',
|
|
41
|
+
help: '(help choix3)',
|
|
42
|
+
ariaLabel: '__ariaLabel3',
|
|
43
|
+
onClick: () => undefined
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
klf: '___klf',
|
|
49
|
+
universalRef: ref
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
postProgression: () => {
|
|
53
|
+
return Promise.resolve({
|
|
54
|
+
_id: '62b1d1087aa12f00253f40ee',
|
|
55
|
+
state: {
|
|
56
|
+
pendingSlides: [],
|
|
57
|
+
step: {
|
|
58
|
+
current: 1
|
|
59
|
+
},
|
|
60
|
+
isCorrect: true,
|
|
61
|
+
nextContent: {
|
|
62
|
+
ref: 'sli_N1XACJobn',
|
|
63
|
+
type: 'slide'
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
};
|
package/es/types/common.d.ts
CHANGED
|
@@ -1,9 +1,53 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { UISlide } from './slides';
|
|
2
|
+
declare type TemplateContextValues = {
|
|
3
|
+
brandTheme?: unknown;
|
|
4
|
+
theme?: unknown;
|
|
5
|
+
translations?: unknown;
|
|
6
|
+
};
|
|
7
|
+
export declare type SlideFromAPI = {
|
|
8
|
+
question: {
|
|
9
|
+
content: {
|
|
10
|
+
choices: Record<string, unknown>[];
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
klf: string;
|
|
14
|
+
universalRef: string;
|
|
15
|
+
};
|
|
16
|
+
export declare type ProgressionFromAPI = {
|
|
17
|
+
_id: string;
|
|
18
|
+
state: {
|
|
19
|
+
isCorrect: boolean;
|
|
20
|
+
step: {
|
|
21
|
+
current: number;
|
|
22
|
+
};
|
|
23
|
+
nextContent: {
|
|
24
|
+
type: 'success' | 'slide';
|
|
25
|
+
ref: 'successExitNode' | string;
|
|
26
|
+
};
|
|
27
|
+
pendingSlides: [];
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export declare type Skill = {
|
|
31
|
+
skillRef: string;
|
|
32
|
+
slidesToReview: number;
|
|
33
|
+
custom: boolean;
|
|
34
|
+
name: string;
|
|
35
|
+
};
|
|
36
|
+
export declare type Services = {
|
|
37
|
+
fetchSkills(token: string): Promise<Skill[]>;
|
|
38
|
+
fetchSlide(slideRef: string, token: string): Promise<SlideFromAPI | void>;
|
|
39
|
+
postProgression(skillRef: string, token: string): Promise<ProgressionFromAPI>;
|
|
40
|
+
};
|
|
41
|
+
export declare type Options = {
|
|
42
|
+
services: Services;
|
|
43
|
+
};
|
|
2
44
|
export declare type AppOptions = {
|
|
3
45
|
token: string;
|
|
4
46
|
theme?: unknown;
|
|
5
47
|
translations?: unknown;
|
|
6
|
-
|
|
48
|
+
templateContext?: TemplateContextValues;
|
|
49
|
+
skillRef?: string;
|
|
50
|
+
services: Services;
|
|
7
51
|
};
|
|
8
52
|
export declare type JWT = {
|
|
9
53
|
exp: number;
|
|
@@ -14,6 +58,26 @@ export declare type JWT = {
|
|
|
14
58
|
usage: string;
|
|
15
59
|
host: string;
|
|
16
60
|
};
|
|
61
|
+
declare type SlideUIAnimations = 'unstack' | 'restack';
|
|
62
|
+
export declare type Slide = UISlide & {
|
|
63
|
+
hidden?: boolean;
|
|
64
|
+
position: number;
|
|
65
|
+
animationType?: SlideUIAnimations;
|
|
66
|
+
isCorrect?: boolean;
|
|
67
|
+
endReview?: boolean;
|
|
68
|
+
nextContent?: Omit<Slide, 'endReview' | 'hidden' | 'position' | 'nextContent'>;
|
|
69
|
+
};
|
|
70
|
+
declare const ICON_VALUES: {
|
|
71
|
+
readonly right: "right";
|
|
72
|
+
readonly wrong: "wrong";
|
|
73
|
+
readonly 'no-answer': "no-answer";
|
|
74
|
+
};
|
|
75
|
+
export declare type IconValue = keyof typeof ICON_VALUES;
|
|
76
|
+
export declare type FinishedSlides = {
|
|
77
|
+
slideNumbers: number[];
|
|
78
|
+
[key: number]: true;
|
|
79
|
+
};
|
|
17
80
|
export declare type WithRequired<T, K extends keyof T> = T & {
|
|
18
81
|
[P in K]-?: T[P];
|
|
19
82
|
};
|
|
83
|
+
export {};
|