@coorpacademy/app-review 0.2.9 → 0.2.10-alpha.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/es/actions/api/post-answer.js +10 -2
  2. package/es/actions/api/test/post-answer.test.js +64 -2
  3. package/es/actions/ui/next-slide.d.ts +14 -0
  4. package/es/actions/ui/next-slide.js +15 -0
  5. package/es/actions/ui/test/next-slide.test.d.ts +1 -0
  6. package/es/actions/ui/test/next-slide.test.js +63 -0
  7. package/es/reducers/data/index.d.ts +1 -1
  8. package/es/reducers/index.d.ts +1 -1
  9. package/es/test/index.test.js +0 -3
  10. package/es/types/common.d.ts +0 -8
  11. package/es/types/slides.d.ts +2 -1
  12. package/es/views/slides/map-api-slide-to-ui.js +5 -0
  13. package/es/views/slides/test/fixtures/slider.js +2 -1
  14. package/es/views/slides/test/slide.slider.on-slider-change.test.d.ts +1 -0
  15. package/es/views/slides/test/slide.slider.on-slider-change.test.js +63 -0
  16. package/lib/actions/api/post-answer.js +15 -3
  17. package/lib/actions/api/test/post-answer.test.js +74 -2
  18. package/lib/actions/ui/next-slide.d.ts +14 -0
  19. package/lib/actions/ui/next-slide.js +16 -0
  20. package/lib/actions/ui/test/next-slide.test.d.ts +1 -0
  21. package/lib/actions/ui/test/next-slide.test.js +64 -0
  22. package/lib/reducers/data/index.d.ts +1 -1
  23. package/lib/reducers/index.d.ts +1 -1
  24. package/lib/test/index.test.js +0 -3
  25. package/lib/types/common.d.ts +0 -8
  26. package/lib/types/slides.d.ts +2 -1
  27. package/lib/views/slides/map-api-slide-to-ui.js +5 -0
  28. package/lib/views/slides/test/fixtures/slider.js +2 -1
  29. package/lib/views/slides/test/slide.slider.on-slider-change.test.d.ts +1 -0
  30. package/lib/views/slides/test/slide.slider.on-slider-change.test.js +65 -0
  31. package/package.json +4 -4
  32. package/src/actions/api/post-answer.ts +9 -2
  33. package/src/actions/api/test/post-answer.test.ts +76 -2
  34. package/src/actions/ui/next-slide.ts +31 -0
  35. package/src/actions/ui/test/next-slide.test.ts +75 -0
  36. package/src/test/index.test.tsx +0 -3
  37. package/src/types/common.ts +0 -10
  38. package/src/types/slides.ts +2 -1
  39. package/src/views/slides/map-api-slide-to-ui.ts +5 -0
  40. package/src/views/slides/test/fixtures/slider.ts +2 -1
  41. package/src/views/slides/test/slide.slider.on-slider-change.test.ts +71 -0
@@ -2,6 +2,7 @@ import buildTask from '@coorpacademy/redux-task';
2
2
  import get from 'lodash/fp/get';
3
3
  import { fetchCorrection } from './fetch-correction';
4
4
  import { fetchSlide } from './fetch-slide';
5
+ import { fetchEndRank, fetchStartRank } from './fetch-rank';
5
6
  export const POST_ANSWER_REQUEST = '@@answer/POST_REQUEST';
6
7
  export const POST_ANSWER_SUCCESS = '@@answer/POST_SUCCESS';
7
8
  export const POST_ANSWER_FAILURE = '@@answer/POST_FAILURE';
@@ -20,7 +21,14 @@ export const postAnswer = async (dispatch, getState, { services }) => {
20
21
  if (response.type === POST_ANSWER_SUCCESS) {
21
22
  const updatedProgression = response.payload;
22
23
  const slideRef = updatedProgression.state.nextContent.ref;
23
- await dispatch(fetchSlide(slideRef));
24
- await dispatch(fetchCorrection);
24
+ if (slideRef !== 'successExitNode') {
25
+ await dispatch(fetchSlide(slideRef));
26
+ await dispatch(fetchCorrection);
27
+ await dispatch(fetchStartRank);
28
+ }
29
+ else {
30
+ await dispatch(fetchCorrection);
31
+ await dispatch(fetchEndRank);
32
+ }
25
33
  }
26
34
  };
@@ -5,7 +5,11 @@ import { postAnswer, POST_ANSWER_FAILURE, POST_ANSWER_REQUEST, POST_ANSWER_SUCCE
5
5
  import { freeTextSlide } from '../../../views/slides/test/fixtures/free-text';
6
6
  import { CORRECTION_FETCH_REQUEST, CORRECTION_FETCH_SUCCESS } from '../fetch-correction';
7
7
  import { SLIDE_FETCH_REQUEST, SLIDE_FETCH_SUCCESS } from '../fetch-slide';
8
+ import { qcmSlide } from '../../../views/slides/test/fixtures/qcm';
8
9
  import { qcmGraphicSlide } from '../../../views/slides/test/fixtures/qcm-graphic';
10
+ import { templateSlide } from '../../../views/slides/test/fixtures/template';
11
+ import { sliderSlide } from '../../../views/slides/test/fixtures/slider';
12
+ import { RANK_FETCH_START_REQUEST, RANK_FETCH_START_SUCCESS, RANK_FETCH_END_REQUEST, RANK_FETCH_END_SUCCESS } from '../fetch-rank';
9
13
  const progressionId = '123456789123';
10
14
  const skillRef = '_skill-ref';
11
15
  const answer = ['Lister vos tâches pour vous libérer l’esprit', 'Vous isoler dans un lieu calme'];
@@ -49,8 +53,8 @@ const initialState = {
49
53
  }
50
54
  }
51
55
  };
52
- test('should dispatch post-answer, fetch-slide and fetch-correction actions when the answer is submitted', async (t) => {
53
- t.plan(8);
56
+ test('should dispatch post-answer, fetch-slide and fetch-correction and fetch-start-rank actions when the answer is submitted and when the slide ref is not "successExitNode"', async (t) => {
57
+ t.plan(10);
54
58
  const expectedActions = [
55
59
  { type: POST_ANSWER_REQUEST },
56
60
  {
@@ -75,6 +79,13 @@ test('should dispatch post-answer, fetch-slide and fetch-correction actions when
75
79
  type: CORRECTION_FETCH_SUCCESS,
76
80
  meta: { slideRef: freeTextSlide._id },
77
81
  payload: getChoicesCorrection(freeTextSlide._id)
82
+ },
83
+ {
84
+ type: RANK_FETCH_START_REQUEST
85
+ },
86
+ {
87
+ type: RANK_FETCH_START_SUCCESS,
88
+ payload: { rank: 93 }
78
89
  }
79
90
  ];
80
91
  const { dispatch, getState } = createTestStore(t, initialState, services, expectedActions);
@@ -83,6 +94,57 @@ test('should dispatch post-answer, fetch-slide and fetch-correction actions when
83
94
  t.false(state.ui.slide.validateButton);
84
95
  t.true(state.ui.slide.animateCorrectionPopin);
85
96
  });
97
+ test('should dispatch post-answer, fetch-correction and fetch-end-rank actions when the answer is submitted and when the slide ref is "successExitNode"', async (t) => {
98
+ t.plan(8);
99
+ const stateBeforeExitNode = {
100
+ data: {
101
+ progression: postAnswerResponses[sliderSlide.universalRef],
102
+ slides: {
103
+ [freeTextSlide._id]: freeTextSlide,
104
+ [qcmGraphicSlide._id]: qcmGraphicSlide,
105
+ [qcmSlide._id]: qcmSlide,
106
+ [sliderSlide._id]: sliderSlide
107
+ },
108
+ skills: [{ skillRef, custom: false, name: skillRef, slidesToReview: 5 }],
109
+ token: '1234',
110
+ corrections: {},
111
+ rank: {}
112
+ },
113
+ ui: {
114
+ currentSlideRef: templateSlide._id,
115
+ navigation: ['skills', 'slides'],
116
+ answers: ['Leaderboard', 'utilisateurs', 'étoiles'],
117
+ slide: {
118
+ validateButton: false
119
+ }
120
+ }
121
+ };
122
+ const expectedActions = [
123
+ { type: POST_ANSWER_REQUEST },
124
+ {
125
+ type: POST_ANSWER_SUCCESS,
126
+ payload: postAnswerResponses[templateSlide._id]
127
+ },
128
+ { type: CORRECTION_FETCH_REQUEST, meta: { slideRef: templateSlide._id } },
129
+ {
130
+ type: CORRECTION_FETCH_SUCCESS,
131
+ meta: { slideRef: templateSlide._id },
132
+ payload: getChoicesCorrection(templateSlide._id)
133
+ },
134
+ {
135
+ type: RANK_FETCH_END_REQUEST
136
+ },
137
+ {
138
+ type: RANK_FETCH_END_SUCCESS,
139
+ payload: { rank: 93 }
140
+ }
141
+ ];
142
+ const { dispatch, getState } = createTestStore(t, stateBeforeExitNode, services, expectedActions);
143
+ await dispatch(postAnswer);
144
+ const state = getState();
145
+ t.false(state.ui.slide.validateButton);
146
+ t.true(state.ui.slide.animateCorrectionPopin);
147
+ });
86
148
  test('should dispatch POST_ANSWER_REQUEST, then POST_ANSWER_FAILURE on error', async (t) => {
87
149
  t.plan(3);
88
150
  const expectedActions = [
@@ -0,0 +1,14 @@
1
+ import type { Dispatch } from 'redux';
2
+ import type { StoreState } from '../../reducers';
3
+ export declare const NEXT_SLIDE: "@@slide/NEXT_SLIDE";
4
+ declare type NextSlidePayload = {
5
+ currentSlideRef: string;
6
+ nextSlideRef: string;
7
+ animationType: string;
8
+ };
9
+ export declare type NextSlide = {
10
+ type: typeof NEXT_SLIDE;
11
+ payload: NextSlidePayload;
12
+ };
13
+ export declare const nextSlide: (dispatch: Dispatch, getState: () => StoreState) => NextSlide;
14
+ export {};
@@ -0,0 +1,15 @@
1
+ import get from 'lodash/fp/get';
2
+ export const NEXT_SLIDE = '@@slide/NEXT_SLIDE';
3
+ export const nextSlide = (dispatch, getState) => {
4
+ const state = getState();
5
+ const payload = {
6
+ currentSlideRef: get(['ui', 'currentSlideRef'], state),
7
+ nextSlideRef: get(['data', 'progression', 'state', 'nextContent', 'ref'], state),
8
+ animationType: state.data.progression?.state.isCorrect ? 'unstack' : 'restack'
9
+ };
10
+ const action = {
11
+ type: NEXT_SLIDE,
12
+ payload
13
+ };
14
+ return dispatch(action);
15
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,63 @@
1
+ import test from 'ava';
2
+ import pipe from 'lodash/fp/pipe';
3
+ import set from 'lodash/fp/set';
4
+ import { nextSlide, NEXT_SLIDE } from '../next-slide';
5
+ import { createTestStore } from '../../test/create-test-store';
6
+ import { getChoicesCorrection, postAnswerResponses, services } from '../../../test/util/services.mock';
7
+ import { freeTextSlide } from '../../../views/slides/test/fixtures/free-text';
8
+ import { qcmGraphicSlide } from '../../../views/slides/test/fixtures/qcm-graphic';
9
+ const progression = postAnswerResponses[freeTextSlide.universalRef];
10
+ const skillRef = '_skill-ref';
11
+ const answer = ['Vous isoler dans un lieu calme'];
12
+ const state = {
13
+ data: {
14
+ progression,
15
+ slides: {
16
+ [freeTextSlide.universalRef]: freeTextSlide,
17
+ [qcmGraphicSlide.universalRef]: qcmGraphicSlide
18
+ },
19
+ skills: [{ skillRef, custom: false, name: skillRef, slidesToReview: 5 }],
20
+ token: '1234',
21
+ corrections: { [freeTextSlide.universalRef]: getChoicesCorrection(freeTextSlide.universalRef) },
22
+ rank: { start: 93 }
23
+ },
24
+ ui: {
25
+ currentSlideRef: freeTextSlide._id,
26
+ navigation: ['loader', 'slides'],
27
+ answers: answer,
28
+ slide: {
29
+ validateButton: false,
30
+ animateCorrectionPopin: true,
31
+ showCorrectionPopin: true
32
+ }
33
+ }
34
+ };
35
+ test('should dispatch NEXT_SLIDE action when nextSlide is called and the progression state is correct', t => {
36
+ const expectedActions = [
37
+ {
38
+ type: NEXT_SLIDE,
39
+ payload: {
40
+ currentSlideRef: freeTextSlide.universalRef,
41
+ nextSlideRef: qcmGraphicSlide.universalRef,
42
+ animationType: 'unstack'
43
+ }
44
+ }
45
+ ];
46
+ const { dispatch } = createTestStore(t, state, services, expectedActions);
47
+ dispatch(nextSlide);
48
+ });
49
+ test('should dispatch NEXT_SLIDE action when nextSlide is called and the progression state is not correct', t => {
50
+ const stateWithWrongAnswer = pipe(set(['data', 'progression', 'state', 'isCorrect'], false), set(['data', 'progression', 'state', 'allAnswers', 0, 'isCorrect'], false))(state);
51
+ const expectedActions = [
52
+ {
53
+ type: NEXT_SLIDE,
54
+ payload: {
55
+ currentSlideRef: freeTextSlide.universalRef,
56
+ nextSlideRef: qcmGraphicSlide.universalRef,
57
+ animationType: 'restack'
58
+ }
59
+ }
60
+ ];
61
+ const { dispatch } = createTestStore(t, stateWithWrongAnswer, services, expectedActions);
62
+ dispatch(nextSlide);
63
+ });
@@ -19,5 +19,5 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
19
19
  slides: SlidesState;
20
20
  token: string;
21
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>;
22
+ }>, import("./corrections").CorrectionsAction | import("../../actions/api/fetch-rank").RankAction | 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>;
23
23
  export default _default;
@@ -19,5 +19,5 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
19
19
  answers: import("./ui/answers").AnswerState;
20
20
  slide: import("./ui/slide").UISlideState;
21
21
  }>;
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
+ }>, import("./data/corrections").CorrectionsAction | import("../actions/ui/slides").SetCurrentSlide | import("../actions/api/fetch-rank").RankAction | 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>;
23
23
  export default _default;
@@ -36,9 +36,6 @@ const clickAllSlides = async (t, container, accumulator = 0) => {
36
36
  };
37
37
  const appOptions = {
38
38
  token: process.env.API_TEST_TOKEN || '',
39
- templateContext: {
40
- theme: { color: { primary: '#123' } }
41
- },
42
39
  skillRef: 'skill_NJC0jFKoH',
43
40
  services
44
41
  };
@@ -1,8 +1,3 @@
1
- declare type TemplateContextValues = {
2
- brandTheme?: unknown;
3
- theme?: unknown;
4
- translations?: unknown;
5
- };
6
1
  export declare type ChoiceFromAPI = {
7
2
  _id: string;
8
3
  id?: string;
@@ -140,9 +135,6 @@ export declare type Options = {
140
135
  };
141
136
  export declare type AppOptions = {
142
137
  token: string;
143
- theme?: unknown;
144
- translations?: unknown;
145
- templateContext?: TemplateContextValues;
146
138
  skillRef?: string;
147
139
  services: Services;
148
140
  };
@@ -44,8 +44,9 @@ export declare type DropDown = {
44
44
  export declare type QuestionRange = {
45
45
  type: 'slider';
46
46
  placeholder?: string;
47
- onChange?: Function;
47
+ onChange?: (value: number) => void;
48
48
  onChangeEnd?: Function;
49
+ onSliderChange?: (value: number) => void;
49
50
  multi?: boolean;
50
51
  value: number | number[];
51
52
  title: string;
@@ -132,8 +132,13 @@ const sliderProps = (dispatch) => (answers, question) => {
132
132
  title: `${currentValue} ${question.content.unitLabel}`,
133
133
  value: sliderPosition,
134
134
  onChange: (position) => {
135
+ // atom/range handler
135
136
  const newValue = pipe(multiply(maxValue), round, get(__, values), _toString)(position);
136
137
  dispatch(editAnswer([newValue]));
138
+ },
139
+ onSliderChange: (newValue) => {
140
+ // mobile/slider handler
141
+ dispatch(editAnswer([`${newValue}`]));
137
142
  }
138
143
  };
139
144
  };
@@ -30,7 +30,8 @@ export const sliderUISlide = {
30
30
  maxLabel: '15 an(s)',
31
31
  title: '1 an(s)',
32
32
  value: 0,
33
- onChange: noop
33
+ onChange: noop,
34
+ onSliderChange: noop
34
35
  }
35
36
  }
36
37
  };
@@ -0,0 +1,63 @@
1
+ import test from 'ava';
2
+ import get from 'lodash/fp/get';
3
+ import { mapStateToSlidesProps } from '..';
4
+ import { services } from '../../../test/util/services.mock';
5
+ import { createTestStore } from '../../../actions/test/create-test-store';
6
+ import { EDIT_SLIDER } from '../../../actions/ui/answers';
7
+ import { sliderSlide } from './fixtures/slider';
8
+ const progression = {
9
+ _id: '123456789123',
10
+ content: { type: 'skill', ref: '_skill-ref' },
11
+ engine: {
12
+ ref: 'review'
13
+ },
14
+ state: {
15
+ allAnswers: [],
16
+ isCorrect: true,
17
+ nextContent: {
18
+ ref: sliderSlide._id,
19
+ type: 'slide'
20
+ },
21
+ pendingSlides: [],
22
+ slides: [],
23
+ step: {
24
+ current: 1
25
+ },
26
+ stars: 0
27
+ }
28
+ };
29
+ const initialState = {
30
+ data: {
31
+ progression,
32
+ slides: {
33
+ [sliderSlide._id]: sliderSlide
34
+ },
35
+ skills: [],
36
+ token: '1234',
37
+ corrections: {},
38
+ rank: {}
39
+ },
40
+ ui: {
41
+ currentSlideRef: sliderSlide._id,
42
+ navigation: ['skills', 'slides'],
43
+ answers: [],
44
+ slide: {
45
+ validateButton: false
46
+ }
47
+ }
48
+ };
49
+ test('should dispatch EDIT_SLIDER action via the property onSliderChange of a Slider slide', t => {
50
+ t.plan(1);
51
+ const expectedActions = [
52
+ {
53
+ type: EDIT_SLIDER,
54
+ payload: ['111']
55
+ }
56
+ ];
57
+ const { dispatch, getState } = createTestStore(t, initialState, services, expectedActions);
58
+ const props = mapStateToSlidesProps(getState(), dispatch);
59
+ const SlideProps = props.stack.slides['0'].answerUI?.model;
60
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
61
+ const onSliderChange = get('onSliderChange', SlideProps);
62
+ onSliderChange(111);
63
+ });
@@ -38,6 +38,7 @@ import buildTask from '@coorpacademy/redux-task';
38
38
  import get from 'lodash/fp/get';
39
39
  import { fetchCorrection } from './fetch-correction';
40
40
  import { fetchSlide } from './fetch-slide';
41
+ import { fetchEndRank, fetchStartRank } from './fetch-rank';
41
42
  export var POST_ANSWER_REQUEST = '@@answer/POST_REQUEST';
42
43
  export var POST_ANSWER_SUCCESS = '@@answer/POST_SUCCESS';
43
44
  export var POST_ANSWER_FAILURE = '@@answer/POST_FAILURE';
@@ -61,17 +62,28 @@ export var postAnswer = function (dispatch, getState, _a) {
61
62
  return [4 /*yield*/, dispatch(action)];
62
63
  case 1:
63
64
  response = _b.sent();
64
- if (!(response.type === POST_ANSWER_SUCCESS)) return [3 /*break*/, 4];
65
+ if (!(response.type === POST_ANSWER_SUCCESS)) return [3 /*break*/, 8];
65
66
  updatedProgression = response.payload;
66
67
  slideRef = updatedProgression.state.nextContent.ref;
68
+ if (!(slideRef !== 'successExitNode')) return [3 /*break*/, 5];
67
69
  return [4 /*yield*/, dispatch(fetchSlide(slideRef))];
68
70
  case 2:
69
71
  _b.sent();
70
72
  return [4 /*yield*/, dispatch(fetchCorrection)];
71
73
  case 3:
72
74
  _b.sent();
73
- _b.label = 4;
74
- case 4: return [2 /*return*/];
75
+ return [4 /*yield*/, dispatch(fetchStartRank)];
76
+ case 4:
77
+ _b.sent();
78
+ return [3 /*break*/, 8];
79
+ case 5: return [4 /*yield*/, dispatch(fetchCorrection)];
80
+ case 6:
81
+ _b.sent();
82
+ return [4 /*yield*/, dispatch(fetchEndRank)];
83
+ case 7:
84
+ _b.sent();
85
+ _b.label = 8;
86
+ case 8: return [2 /*return*/];
75
87
  }
76
88
  });
77
89
  });
@@ -53,7 +53,11 @@ import { postAnswer, POST_ANSWER_FAILURE, POST_ANSWER_REQUEST, POST_ANSWER_SUCCE
53
53
  import { freeTextSlide } from '../../../views/slides/test/fixtures/free-text';
54
54
  import { CORRECTION_FETCH_REQUEST, CORRECTION_FETCH_SUCCESS } from '../fetch-correction';
55
55
  import { SLIDE_FETCH_REQUEST, SLIDE_FETCH_SUCCESS } from '../fetch-slide';
56
+ import { qcmSlide } from '../../../views/slides/test/fixtures/qcm';
56
57
  import { qcmGraphicSlide } from '../../../views/slides/test/fixtures/qcm-graphic';
58
+ import { templateSlide } from '../../../views/slides/test/fixtures/template';
59
+ import { sliderSlide } from '../../../views/slides/test/fixtures/slider';
60
+ import { RANK_FETCH_START_REQUEST, RANK_FETCH_START_SUCCESS, RANK_FETCH_END_REQUEST, RANK_FETCH_END_SUCCESS } from '../fetch-rank';
57
61
  var progressionId = '123456789123';
58
62
  var skillRef = '_skill-ref';
59
63
  var answer = ['Lister vos tâches pour vous libérer l’esprit', 'Vous isoler dans un lieu calme'];
@@ -97,12 +101,12 @@ var initialState = {
97
101
  }
98
102
  }
99
103
  };
100
- test('should dispatch post-answer, fetch-slide and fetch-correction actions when the answer is submitted', function (t) { return __awaiter(void 0, void 0, void 0, function () {
104
+ test('should dispatch post-answer, fetch-slide and fetch-correction and fetch-start-rank actions when the answer is submitted and when the slide ref is not "successExitNode"', function (t) { return __awaiter(void 0, void 0, void 0, function () {
101
105
  var expectedActions, _a, dispatch, getState, state;
102
106
  return __generator(this, function (_b) {
103
107
  switch (_b.label) {
104
108
  case 0:
105
- t.plan(8);
109
+ t.plan(10);
106
110
  expectedActions = [
107
111
  { type: POST_ANSWER_REQUEST },
108
112
  {
@@ -127,6 +131,13 @@ test('should dispatch post-answer, fetch-slide and fetch-correction actions when
127
131
  type: CORRECTION_FETCH_SUCCESS,
128
132
  meta: { slideRef: freeTextSlide._id },
129
133
  payload: getChoicesCorrection(freeTextSlide._id)
134
+ },
135
+ {
136
+ type: RANK_FETCH_START_REQUEST
137
+ },
138
+ {
139
+ type: RANK_FETCH_START_SUCCESS,
140
+ payload: { rank: 93 }
130
141
  }
131
142
  ];
132
143
  _a = createTestStore(t, initialState, services, expectedActions), dispatch = _a.dispatch, getState = _a.getState;
@@ -140,6 +151,67 @@ test('should dispatch post-answer, fetch-slide and fetch-correction actions when
140
151
  }
141
152
  });
142
153
  }); });
154
+ test('should dispatch post-answer, fetch-correction and fetch-end-rank actions when the answer is submitted and when the slide ref is "successExitNode"', function (t) { return __awaiter(void 0, void 0, void 0, function () {
155
+ var stateBeforeExitNode, expectedActions, _a, dispatch, getState, state;
156
+ var _b;
157
+ return __generator(this, function (_c) {
158
+ switch (_c.label) {
159
+ case 0:
160
+ t.plan(8);
161
+ stateBeforeExitNode = {
162
+ data: {
163
+ progression: postAnswerResponses[sliderSlide.universalRef],
164
+ slides: (_b = {},
165
+ _b[freeTextSlide._id] = freeTextSlide,
166
+ _b[qcmGraphicSlide._id] = qcmGraphicSlide,
167
+ _b[qcmSlide._id] = qcmSlide,
168
+ _b[sliderSlide._id] = sliderSlide,
169
+ _b),
170
+ skills: [{ skillRef: skillRef, custom: false, name: skillRef, slidesToReview: 5 }],
171
+ token: '1234',
172
+ corrections: {},
173
+ rank: {}
174
+ },
175
+ ui: {
176
+ currentSlideRef: templateSlide._id,
177
+ navigation: ['skills', 'slides'],
178
+ answers: ['Leaderboard', 'utilisateurs', 'étoiles'],
179
+ slide: {
180
+ validateButton: false
181
+ }
182
+ }
183
+ };
184
+ expectedActions = [
185
+ { type: POST_ANSWER_REQUEST },
186
+ {
187
+ type: POST_ANSWER_SUCCESS,
188
+ payload: postAnswerResponses[templateSlide._id]
189
+ },
190
+ { type: CORRECTION_FETCH_REQUEST, meta: { slideRef: templateSlide._id } },
191
+ {
192
+ type: CORRECTION_FETCH_SUCCESS,
193
+ meta: { slideRef: templateSlide._id },
194
+ payload: getChoicesCorrection(templateSlide._id)
195
+ },
196
+ {
197
+ type: RANK_FETCH_END_REQUEST
198
+ },
199
+ {
200
+ type: RANK_FETCH_END_SUCCESS,
201
+ payload: { rank: 93 }
202
+ }
203
+ ];
204
+ _a = createTestStore(t, stateBeforeExitNode, services, expectedActions), dispatch = _a.dispatch, getState = _a.getState;
205
+ return [4 /*yield*/, dispatch(postAnswer)];
206
+ case 1:
207
+ _c.sent();
208
+ state = getState();
209
+ t.false(state.ui.slide.validateButton);
210
+ t.true(state.ui.slide.animateCorrectionPopin);
211
+ return [2 /*return*/];
212
+ }
213
+ });
214
+ }); });
143
215
  test('should dispatch POST_ANSWER_REQUEST, then POST_ANSWER_FAILURE on error', function (t) { return __awaiter(void 0, void 0, void 0, function () {
144
216
  var expectedActions, dispatch;
145
217
  return __generator(this, function (_a) {
@@ -0,0 +1,14 @@
1
+ import type { Dispatch } from 'redux';
2
+ import type { StoreState } from '../../reducers';
3
+ export declare const NEXT_SLIDE: "@@slide/NEXT_SLIDE";
4
+ declare type NextSlidePayload = {
5
+ currentSlideRef: string;
6
+ nextSlideRef: string;
7
+ animationType: string;
8
+ };
9
+ export declare type NextSlide = {
10
+ type: typeof NEXT_SLIDE;
11
+ payload: NextSlidePayload;
12
+ };
13
+ export declare const nextSlide: (dispatch: Dispatch, getState: () => StoreState) => NextSlide;
14
+ export {};
@@ -0,0 +1,16 @@
1
+ import get from 'lodash/fp/get';
2
+ export var NEXT_SLIDE = '@@slide/NEXT_SLIDE';
3
+ export var nextSlide = function (dispatch, getState) {
4
+ var _a;
5
+ var state = getState();
6
+ var payload = {
7
+ currentSlideRef: get(['ui', 'currentSlideRef'], state),
8
+ nextSlideRef: get(['data', 'progression', 'state', 'nextContent', 'ref'], state),
9
+ animationType: ((_a = state.data.progression) === null || _a === void 0 ? void 0 : _a.state.isCorrect) ? 'unstack' : 'restack'
10
+ };
11
+ var action = {
12
+ type: NEXT_SLIDE,
13
+ payload: payload
14
+ };
15
+ return dispatch(action);
16
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,64 @@
1
+ var _a, _b;
2
+ import test from 'ava';
3
+ import pipe from 'lodash/fp/pipe';
4
+ import set from 'lodash/fp/set';
5
+ import { nextSlide, NEXT_SLIDE } from '../next-slide';
6
+ import { createTestStore } from '../../test/create-test-store';
7
+ import { getChoicesCorrection, postAnswerResponses, services } from '../../../test/util/services.mock';
8
+ import { freeTextSlide } from '../../../views/slides/test/fixtures/free-text';
9
+ import { qcmGraphicSlide } from '../../../views/slides/test/fixtures/qcm-graphic';
10
+ var progression = postAnswerResponses[freeTextSlide.universalRef];
11
+ var skillRef = '_skill-ref';
12
+ var answer = ['Vous isoler dans un lieu calme'];
13
+ var state = {
14
+ data: {
15
+ progression: progression,
16
+ slides: (_a = {},
17
+ _a[freeTextSlide.universalRef] = freeTextSlide,
18
+ _a[qcmGraphicSlide.universalRef] = qcmGraphicSlide,
19
+ _a),
20
+ skills: [{ skillRef: skillRef, custom: false, name: skillRef, slidesToReview: 5 }],
21
+ token: '1234',
22
+ corrections: (_b = {}, _b[freeTextSlide.universalRef] = getChoicesCorrection(freeTextSlide.universalRef), _b),
23
+ rank: { start: 93 }
24
+ },
25
+ ui: {
26
+ currentSlideRef: freeTextSlide._id,
27
+ navigation: ['loader', 'slides'],
28
+ answers: answer,
29
+ slide: {
30
+ validateButton: false,
31
+ animateCorrectionPopin: true,
32
+ showCorrectionPopin: true
33
+ }
34
+ }
35
+ };
36
+ test('should dispatch NEXT_SLIDE action when nextSlide is called and the progression state is correct', function (t) {
37
+ var expectedActions = [
38
+ {
39
+ type: NEXT_SLIDE,
40
+ payload: {
41
+ currentSlideRef: freeTextSlide.universalRef,
42
+ nextSlideRef: qcmGraphicSlide.universalRef,
43
+ animationType: 'unstack'
44
+ }
45
+ }
46
+ ];
47
+ var dispatch = createTestStore(t, state, services, expectedActions).dispatch;
48
+ dispatch(nextSlide);
49
+ });
50
+ test('should dispatch NEXT_SLIDE action when nextSlide is called and the progression state is not correct', function (t) {
51
+ var stateWithWrongAnswer = pipe(set(['data', 'progression', 'state', 'isCorrect'], false), set(['data', 'progression', 'state', 'allAnswers', 0, 'isCorrect'], false))(state);
52
+ var expectedActions = [
53
+ {
54
+ type: NEXT_SLIDE,
55
+ payload: {
56
+ currentSlideRef: freeTextSlide.universalRef,
57
+ nextSlideRef: qcmGraphicSlide.universalRef,
58
+ animationType: 'restack'
59
+ }
60
+ }
61
+ ];
62
+ var dispatch = createTestStore(t, stateWithWrongAnswer, services, expectedActions).dispatch;
63
+ dispatch(nextSlide);
64
+ });
@@ -19,5 +19,5 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
19
19
  slides: SlidesState;
20
20
  token: string;
21
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>;
22
+ }>, import("./corrections").CorrectionsAction | import("../../actions/api/fetch-rank").RankAction | 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>;
23
23
  export default _default;
@@ -19,5 +19,5 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
19
19
  answers: import("./ui/answers").AnswerState;
20
20
  slide: import("./ui/slide").UISlideState;
21
21
  }>;
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
+ }>, import("./data/corrections").CorrectionsAction | import("../actions/ui/slides").SetCurrentSlide | import("../actions/api/fetch-rank").RankAction | 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>;
23
23
  export default _default;
@@ -132,9 +132,6 @@ var clickAllSlides = function (t, container, accumulator) {
132
132
  };
133
133
  var appOptions = {
134
134
  token: process.env.API_TEST_TOKEN || '',
135
- templateContext: {
136
- theme: { color: { primary: '#123' } }
137
- },
138
135
  skillRef: 'skill_NJC0jFKoH',
139
136
  services: services
140
137
  };
@@ -1,8 +1,3 @@
1
- declare type TemplateContextValues = {
2
- brandTheme?: unknown;
3
- theme?: unknown;
4
- translations?: unknown;
5
- };
6
1
  export declare type ChoiceFromAPI = {
7
2
  _id: string;
8
3
  id?: string;
@@ -140,9 +135,6 @@ export declare type Options = {
140
135
  };
141
136
  export declare type AppOptions = {
142
137
  token: string;
143
- theme?: unknown;
144
- translations?: unknown;
145
- templateContext?: TemplateContextValues;
146
138
  skillRef?: string;
147
139
  services: Services;
148
140
  };
@@ -44,8 +44,9 @@ export declare type DropDown = {
44
44
  export declare type QuestionRange = {
45
45
  type: 'slider';
46
46
  placeholder?: string;
47
- onChange?: Function;
47
+ onChange?: (value: number) => void;
48
48
  onChangeEnd?: Function;
49
+ onSliderChange?: (value: number) => void;
49
50
  multi?: boolean;
50
51
  value: number | number[];
51
52
  title: string;
@@ -145,8 +145,13 @@ var sliderProps = function (dispatch) {
145
145
  title: "".concat(currentValue, " ").concat(question.content.unitLabel),
146
146
  value: sliderPosition,
147
147
  onChange: function (position) {
148
+ // atom/range handler
148
149
  var newValue = pipe(multiply(maxValue), round, get(__, values), _toString)(position);
149
150
  dispatch(editAnswer([newValue]));
151
+ },
152
+ onSliderChange: function (newValue) {
153
+ // mobile/slider handler
154
+ dispatch(editAnswer(["".concat(newValue)]));
150
155
  }
151
156
  };
152
157
  };
@@ -30,7 +30,8 @@ export var sliderUISlide = {
30
30
  maxLabel: '15 an(s)',
31
31
  title: '1 an(s)',
32
32
  value: 0,
33
- onChange: noop
33
+ onChange: noop,
34
+ onSliderChange: noop
34
35
  }
35
36
  }
36
37
  };
@@ -0,0 +1,65 @@
1
+ var _a;
2
+ import test from 'ava';
3
+ import get from 'lodash/fp/get';
4
+ import { mapStateToSlidesProps } from '..';
5
+ import { services } from '../../../test/util/services.mock';
6
+ import { createTestStore } from '../../../actions/test/create-test-store';
7
+ import { EDIT_SLIDER } from '../../../actions/ui/answers';
8
+ import { sliderSlide } from './fixtures/slider';
9
+ var progression = {
10
+ _id: '123456789123',
11
+ content: { type: 'skill', ref: '_skill-ref' },
12
+ engine: {
13
+ ref: 'review'
14
+ },
15
+ state: {
16
+ allAnswers: [],
17
+ isCorrect: true,
18
+ nextContent: {
19
+ ref: sliderSlide._id,
20
+ type: 'slide'
21
+ },
22
+ pendingSlides: [],
23
+ slides: [],
24
+ step: {
25
+ current: 1
26
+ },
27
+ stars: 0
28
+ }
29
+ };
30
+ var initialState = {
31
+ data: {
32
+ progression: progression,
33
+ slides: (_a = {},
34
+ _a[sliderSlide._id] = sliderSlide,
35
+ _a),
36
+ skills: [],
37
+ token: '1234',
38
+ corrections: {},
39
+ rank: {}
40
+ },
41
+ ui: {
42
+ currentSlideRef: sliderSlide._id,
43
+ navigation: ['skills', 'slides'],
44
+ answers: [],
45
+ slide: {
46
+ validateButton: false
47
+ }
48
+ }
49
+ };
50
+ test('should dispatch EDIT_SLIDER action via the property onSliderChange of a Slider slide', function (t) {
51
+ var _a;
52
+ t.plan(1);
53
+ var expectedActions = [
54
+ {
55
+ type: EDIT_SLIDER,
56
+ payload: ['111']
57
+ }
58
+ ];
59
+ var _b = createTestStore(t, initialState, services, expectedActions), dispatch = _b.dispatch, getState = _b.getState;
60
+ var props = mapStateToSlidesProps(getState(), dispatch);
61
+ var SlideProps = (_a = props.stack.slides['0'].answerUI) === null || _a === void 0 ? void 0 : _a.model;
62
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
63
+ var onSliderChange = get('onSliderChange', SlideProps);
64
+ onSliderChange(111);
65
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coorpacademy/app-review",
3
- "version": "0.2.9",
3
+ "version": "0.2.10-alpha.16+979312a0a",
4
4
  "description": "",
5
5
  "engines": {
6
6
  "node": ">=16.15.0"
@@ -41,8 +41,8 @@
41
41
  "./package.json": "./package.json"
42
42
  },
43
43
  "dependencies": {
44
- "@coorpacademy/components": "10.22.24",
45
- "@coorpacademy/redux-task": "^1.1.5",
44
+ "@coorpacademy/components": "10.22.25-alpha.16+979312a0a",
45
+ "@coorpacademy/redux-task": "1.1.5",
46
46
  "cross-fetch": "^3.1.5",
47
47
  "jwt-decode": "^3.1.2",
48
48
  "react-redux": "^8.0.1",
@@ -78,5 +78,5 @@
78
78
  "ts-node": "^10.9.1",
79
79
  "typescript": "^4.7.4"
80
80
  },
81
- "gitHead": "3b2b9c0d9d47e93f89c09351c1f79a20c07cefc3"
81
+ "gitHead": "979312a0adf811d29dd0f18ceef61194e2b2c69d"
82
82
  }
@@ -5,6 +5,7 @@ import type {Options, ProgressionFromAPI} from '../../types/common';
5
5
  import type {StoreState} from '../../reducers';
6
6
  import {fetchCorrection} from './fetch-correction';
7
7
  import {fetchSlide} from './fetch-slide';
8
+ import {fetchEndRank, fetchStartRank} from './fetch-rank';
8
9
 
9
10
  export const POST_ANSWER_REQUEST = '@@answer/POST_REQUEST' as const;
10
11
  export const POST_ANSWER_SUCCESS = '@@answer/POST_SUCCESS' as const;
@@ -38,7 +39,13 @@ export const postAnswer = async (
38
39
  if (response.type === POST_ANSWER_SUCCESS) {
39
40
  const updatedProgression = response.payload;
40
41
  const slideRef = updatedProgression.state.nextContent.ref;
41
- await dispatch(fetchSlide(slideRef));
42
- await dispatch(fetchCorrection);
42
+ if (slideRef !== 'successExitNode') {
43
+ await dispatch(fetchSlide(slideRef));
44
+ await dispatch(fetchCorrection);
45
+ await dispatch(fetchStartRank);
46
+ } else {
47
+ await dispatch(fetchCorrection);
48
+ await dispatch(fetchEndRank);
49
+ }
43
50
  }
44
51
  };
@@ -16,7 +16,16 @@ import type {StoreState} from '../../../reducers';
16
16
  import {freeTextSlide} from '../../../views/slides/test/fixtures/free-text';
17
17
  import {CORRECTION_FETCH_REQUEST, CORRECTION_FETCH_SUCCESS} from '../fetch-correction';
18
18
  import {SLIDE_FETCH_REQUEST, SLIDE_FETCH_SUCCESS} from '../fetch-slide';
19
+ import {qcmSlide} from '../../../views/slides/test/fixtures/qcm';
19
20
  import {qcmGraphicSlide} from '../../../views/slides/test/fixtures/qcm-graphic';
21
+ import {templateSlide} from '../../../views/slides/test/fixtures/template';
22
+ import {sliderSlide} from '../../../views/slides/test/fixtures/slider';
23
+ import {
24
+ RANK_FETCH_START_REQUEST,
25
+ RANK_FETCH_START_SUCCESS,
26
+ RANK_FETCH_END_REQUEST,
27
+ RANK_FETCH_END_SUCCESS
28
+ } from '../fetch-rank';
20
29
 
21
30
  const progressionId = '123456789123';
22
31
  const skillRef = '_skill-ref';
@@ -63,8 +72,8 @@ const initialState: StoreState = {
63
72
  }
64
73
  };
65
74
 
66
- test('should dispatch post-answer, fetch-slide and fetch-correction actions when the answer is submitted', async t => {
67
- t.plan(8);
75
+ test('should dispatch post-answer, fetch-slide and fetch-correction and fetch-start-rank actions when the answer is submitted and when the slide ref is not "successExitNode"', async t => {
76
+ t.plan(10);
68
77
  const expectedActions = [
69
78
  {type: POST_ANSWER_REQUEST},
70
79
  {
@@ -89,6 +98,13 @@ test('should dispatch post-answer, fetch-slide and fetch-correction actions when
89
98
  type: CORRECTION_FETCH_SUCCESS,
90
99
  meta: {slideRef: freeTextSlide._id},
91
100
  payload: getChoicesCorrection(freeTextSlide._id)
101
+ },
102
+ {
103
+ type: RANK_FETCH_START_REQUEST
104
+ },
105
+ {
106
+ type: RANK_FETCH_START_SUCCESS,
107
+ payload: {rank: 93}
92
108
  }
93
109
  ];
94
110
 
@@ -102,6 +118,64 @@ test('should dispatch post-answer, fetch-slide and fetch-correction actions when
102
118
  t.true(state.ui.slide.animateCorrectionPopin);
103
119
  });
104
120
 
121
+ test('should dispatch post-answer, fetch-correction and fetch-end-rank actions when the answer is submitted and when the slide ref is "successExitNode"', async t => {
122
+ t.plan(8);
123
+
124
+ const stateBeforeExitNode: StoreState = {
125
+ data: {
126
+ progression: postAnswerResponses[sliderSlide.universalRef],
127
+ slides: {
128
+ [freeTextSlide._id]: freeTextSlide,
129
+ [qcmGraphicSlide._id]: qcmGraphicSlide,
130
+ [qcmSlide._id]: qcmSlide,
131
+ [sliderSlide._id]: sliderSlide
132
+ },
133
+ skills: [{skillRef, custom: false, name: skillRef, slidesToReview: 5}],
134
+ token: '1234',
135
+ corrections: {},
136
+ rank: {}
137
+ },
138
+ ui: {
139
+ currentSlideRef: templateSlide._id,
140
+ navigation: ['skills', 'slides'],
141
+ answers: ['Leaderboard', 'utilisateurs', 'étoiles'],
142
+ slide: {
143
+ validateButton: false
144
+ }
145
+ }
146
+ };
147
+
148
+ const expectedActions = [
149
+ {type: POST_ANSWER_REQUEST},
150
+ {
151
+ type: POST_ANSWER_SUCCESS,
152
+ payload: postAnswerResponses[templateSlide._id]
153
+ },
154
+ {type: CORRECTION_FETCH_REQUEST, meta: {slideRef: templateSlide._id}},
155
+ {
156
+ type: CORRECTION_FETCH_SUCCESS,
157
+ meta: {slideRef: templateSlide._id},
158
+ payload: getChoicesCorrection(templateSlide._id)
159
+ },
160
+ {
161
+ type: RANK_FETCH_END_REQUEST
162
+ },
163
+ {
164
+ type: RANK_FETCH_END_SUCCESS,
165
+ payload: {rank: 93}
166
+ }
167
+ ];
168
+
169
+ const {dispatch, getState} = createTestStore(t, stateBeforeExitNode, services, expectedActions);
170
+
171
+ await dispatch(postAnswer);
172
+
173
+ const state = getState();
174
+
175
+ t.false(state.ui.slide.validateButton);
176
+ t.true(state.ui.slide.animateCorrectionPopin);
177
+ });
178
+
105
179
  test('should dispatch POST_ANSWER_REQUEST, then POST_ANSWER_FAILURE on error', async t => {
106
180
  t.plan(3);
107
181
  const expectedActions = [
@@ -0,0 +1,31 @@
1
+ import type {Dispatch} from 'redux';
2
+ import get from 'lodash/fp/get';
3
+ import type {StoreState} from '../../reducers';
4
+
5
+ export const NEXT_SLIDE = '@@slide/NEXT_SLIDE' as const;
6
+
7
+ type NextSlidePayload = {
8
+ currentSlideRef: string;
9
+ nextSlideRef: string;
10
+ animationType: string;
11
+ };
12
+
13
+ export type NextSlide = {
14
+ type: typeof NEXT_SLIDE;
15
+ payload: NextSlidePayload;
16
+ };
17
+
18
+ export const nextSlide = (dispatch: Dispatch, getState: () => StoreState): NextSlide => {
19
+ const state = getState();
20
+ const payload = {
21
+ currentSlideRef: get(['ui', 'currentSlideRef'], state),
22
+ nextSlideRef: get(['data', 'progression', 'state', 'nextContent', 'ref'], state),
23
+ animationType: state.data.progression?.state.isCorrect ? 'unstack' : 'restack'
24
+ };
25
+ const action = {
26
+ type: NEXT_SLIDE,
27
+ payload
28
+ };
29
+
30
+ return dispatch(action);
31
+ };
@@ -0,0 +1,75 @@
1
+ import test from 'ava';
2
+ import pipe from 'lodash/fp/pipe';
3
+ import set from 'lodash/fp/set';
4
+ import {StoreState} from '../../../reducers';
5
+ import {nextSlide, NEXT_SLIDE} from '../next-slide';
6
+ import {createTestStore} from '../../test/create-test-store';
7
+ import {
8
+ getChoicesCorrection,
9
+ postAnswerResponses,
10
+ services
11
+ } from '../../../test/util/services.mock';
12
+ import {freeTextSlide} from '../../../views/slides/test/fixtures/free-text';
13
+ import {qcmGraphicSlide} from '../../../views/slides/test/fixtures/qcm-graphic';
14
+
15
+ const progression = postAnswerResponses[freeTextSlide.universalRef];
16
+ const skillRef = '_skill-ref';
17
+ const answer = ['Vous isoler dans un lieu calme'];
18
+
19
+ const state: StoreState = {
20
+ data: {
21
+ progression,
22
+ slides: {
23
+ [freeTextSlide.universalRef]: freeTextSlide,
24
+ [qcmGraphicSlide.universalRef]: qcmGraphicSlide
25
+ },
26
+ skills: [{skillRef, custom: false, name: skillRef, slidesToReview: 5}],
27
+ token: '1234',
28
+ corrections: {[freeTextSlide.universalRef]: getChoicesCorrection(freeTextSlide.universalRef)},
29
+ rank: {start: 93}
30
+ },
31
+ ui: {
32
+ currentSlideRef: freeTextSlide._id,
33
+ navigation: ['loader', 'slides'],
34
+ answers: answer,
35
+ slide: {
36
+ validateButton: false,
37
+ animateCorrectionPopin: true,
38
+ showCorrectionPopin: true
39
+ }
40
+ }
41
+ };
42
+ test('should dispatch NEXT_SLIDE action when nextSlide is called and the progression state is correct', t => {
43
+ const expectedActions = [
44
+ {
45
+ type: NEXT_SLIDE,
46
+ payload: {
47
+ currentSlideRef: freeTextSlide.universalRef,
48
+ nextSlideRef: qcmGraphicSlide.universalRef,
49
+ animationType: 'unstack'
50
+ }
51
+ }
52
+ ];
53
+ const {dispatch} = createTestStore(t, state, services, expectedActions);
54
+ dispatch(nextSlide);
55
+ });
56
+
57
+ test('should dispatch NEXT_SLIDE action when nextSlide is called and the progression state is not correct', t => {
58
+ const stateWithWrongAnswer = pipe(
59
+ set(['data', 'progression', 'state', 'isCorrect'], false),
60
+ set(['data', 'progression', 'state', 'allAnswers', 0, 'isCorrect'], false)
61
+ )(state);
62
+
63
+ const expectedActions = [
64
+ {
65
+ type: NEXT_SLIDE,
66
+ payload: {
67
+ currentSlideRef: freeTextSlide.universalRef,
68
+ nextSlideRef: qcmGraphicSlide.universalRef,
69
+ animationType: 'restack'
70
+ }
71
+ }
72
+ ];
73
+ const {dispatch} = createTestStore(t, stateWithWrongAnswer, services, expectedActions);
74
+ dispatch(nextSlide);
75
+ });
@@ -58,9 +58,6 @@ const clickAllSlides = async (
58
58
 
59
59
  const appOptions: AppOptions = {
60
60
  token: process.env.API_TEST_TOKEN || '',
61
- templateContext: {
62
- theme: {color: {primary: '#123'}}
63
- },
64
61
  skillRef: 'skill_NJC0jFKoH',
65
62
  services
66
63
  };
@@ -1,10 +1,3 @@
1
- // TODO use type from components
2
- type TemplateContextValues = {
3
- brandTheme?: unknown;
4
- theme?: unknown; // TODO type Theme
5
- translations?: unknown; // TODO type Translations
6
- };
7
-
8
1
  // TODO: EDIT_CHOICES -> specify typing
9
2
  export type ChoiceFromAPI = {
10
3
  _id: string;
@@ -176,9 +169,6 @@ export type Options = {
176
169
 
177
170
  export type AppOptions = {
178
171
  token: string;
179
- theme?: unknown;
180
- translations?: unknown;
181
- templateContext?: TemplateContextValues;
182
172
  skillRef?: string;
183
173
  services: Services;
184
174
  };
@@ -59,8 +59,9 @@ export type DropDown = {
59
59
  export type QuestionRange = {
60
60
  type: 'slider';
61
61
  placeholder?: string;
62
- onChange?: Function;
62
+ onChange?: (value: number) => void;
63
63
  onChangeEnd?: Function;
64
+ onSliderChange?: (value: number) => void;
64
65
  multi?: boolean;
65
66
  value: number | number[];
66
67
  title: string;
@@ -225,6 +225,7 @@ const sliderProps =
225
225
  title: `${currentValue} ${question.content.unitLabel}`,
226
226
  value: sliderPosition,
227
227
  onChange: (position: number): void => {
228
+ // atom/range handler
228
229
  const newValue: string = pipe(
229
230
  multiply(maxValue),
230
231
  round,
@@ -232,6 +233,10 @@ const sliderProps =
232
233
  _toString
233
234
  )(position);
234
235
  dispatch(editAnswer([newValue]));
236
+ },
237
+ onSliderChange: (newValue: number): void => {
238
+ // mobile/slider handler
239
+ dispatch(editAnswer([`${newValue}`]));
235
240
  }
236
241
  };
237
242
  };
@@ -36,7 +36,8 @@ export const sliderUISlide: Partial<UISlide> = {
36
36
  maxLabel: '15 an(s)',
37
37
  title: '1 an(s)',
38
38
  value: 0,
39
- onChange: noop
39
+ onChange: noop,
40
+ onSliderChange: noop
40
41
  }
41
42
  }
42
43
  };
@@ -0,0 +1,71 @@
1
+ import test from 'ava';
2
+ import get from 'lodash/fp/get';
3
+ import {ProgressionFromAPI} from '../../../types/common';
4
+ import {StoreState} from '../../../reducers';
5
+ import {mapStateToSlidesProps} from '..';
6
+ import {services} from '../../../test/util/services.mock';
7
+ import {createTestStore} from '../../../actions/test/create-test-store';
8
+ import {EDIT_SLIDER} from '../../../actions/ui/answers';
9
+ import {QuestionRange} from '../../../types/slides';
10
+ import {sliderSlide} from './fixtures/slider';
11
+
12
+ const progression: ProgressionFromAPI = {
13
+ _id: '123456789123',
14
+ content: {type: 'skill', ref: '_skill-ref'},
15
+ engine: {
16
+ ref: 'review'
17
+ },
18
+ state: {
19
+ allAnswers: [],
20
+ isCorrect: true,
21
+ nextContent: {
22
+ ref: sliderSlide._id,
23
+ type: 'slide'
24
+ },
25
+ pendingSlides: [],
26
+ slides: [],
27
+ step: {
28
+ current: 1
29
+ },
30
+ stars: 0
31
+ }
32
+ };
33
+
34
+ const initialState: StoreState = {
35
+ data: {
36
+ progression,
37
+ slides: {
38
+ [sliderSlide._id]: sliderSlide
39
+ },
40
+ skills: [],
41
+ token: '1234',
42
+ corrections: {},
43
+ rank: {}
44
+ },
45
+ ui: {
46
+ currentSlideRef: sliderSlide._id,
47
+ navigation: ['skills', 'slides'],
48
+ answers: [],
49
+ slide: {
50
+ validateButton: false
51
+ }
52
+ }
53
+ };
54
+
55
+ test('should dispatch EDIT_SLIDER action via the property onSliderChange of a Slider slide', t => {
56
+ t.plan(1);
57
+
58
+ const expectedActions = [
59
+ {
60
+ type: EDIT_SLIDER,
61
+ payload: ['111']
62
+ }
63
+ ];
64
+ const {dispatch, getState} = createTestStore(t, initialState, services, expectedActions);
65
+ const props = mapStateToSlidesProps(getState(), dispatch);
66
+
67
+ const SlideProps = props.stack.slides['0'].answerUI?.model as QuestionRange;
68
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
69
+ const onSliderChange = get('onSliderChange', SlideProps)!;
70
+ onSliderChange(111);
71
+ });