Skip to content

Commit

Permalink
refacto app-player header (#1012)
Browse files Browse the repository at this point in the history
* refacto header

* fixes headers ui

* plugged header props

* plugging level.name

* moved location to /actions/ui + added location.back

* added tests

* displaying chapter info within learner header

* lives are optional within header

* added disciplineRef for Location.back

* fixed tests

* coverage

* review

* removed specific params
  • Loading branch information
chrisdugne authored and godu committed Oct 17, 2017
1 parent e0143af commit 02e5b74
Show file tree
Hide file tree
Showing 46 changed files with 654 additions and 275 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import constant from 'lodash/fp/constant';
import buildTask from '../../utils/redux-task';
import {getProgressionContent} from '../../utils/state-extract';
import {getProgressionContent, getCurrentContent} from '../../utils/state-extract';

export const LOCATION_RETRY_REQUEST = '@@location/RETRY_REQUEST';
export const LOCATION_RETRY_SUCCESS = '@@location/RETRY_SUCCESS';
Expand All @@ -14,7 +13,6 @@ export const retry = (dispatch, getState, {services}) => {
const action = buildTask({
types: [LOCATION_RETRY_REQUEST, LOCATION_RETRY_SUCCESS, LOCATION_RETRY_FAILURE],
task: () => Location.retry(contentRef),
bailout: constant(false),
meta: {contentRef}
});

Expand All @@ -30,8 +28,23 @@ export const exit = (dispatch, getState, {services}) => {

const action = buildTask({
types: [LOCATION_EXIT_REQUEST, LOCATION_EXIT_SUCCESS, LOCATION_EXIT_FAILURE],
task: () => Location.exit(),
bailout: constant(false)
task: () => Location.exit()
});

return dispatch(action);
};

export const LOCATION_BACK_REQUEST = '@@location/BACK_REQUEST';
export const LOCATION_BACK_SUCCESS = '@@location/BACK_SUCCESS';
export const LOCATION_BACK_FAILURE = '@@location/BACK_FAILURE';

export const back = (dispatch, getState, {services}) => {
const {Location} = services; // eslint-disable-line no-shadow
const content = getCurrentContent(getState());

const action = buildTask({
types: [LOCATION_BACK_REQUEST, LOCATION_BACK_SUCCESS, LOCATION_BACK_FAILURE],
task: () => Location.back(content)
});

return dispatch(action);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {fetchContent, fetchContentInfo} from '../api/contents';
import {fetchRecommendations} from '../api/recommendations';
import {fetchAnswer} from '../api/answers';
import {
getCurrentChapterId,
getEngine,
getProgressionContent,
getCurrentProgressionId,
Expand Down Expand Up @@ -43,8 +44,11 @@ export const selectProgression = id => async (dispatch, getState) => {
switch (type) {
case 'slide': {
const slideResult = await dispatch(fetchContent('slide', ref));
const chapterId = getCurrentChapterId(getState());
const chapterResult = await dispatch(fetchContent('chapter', chapterId));

if (isNil(get('payload.context.title', slideResult))) {
return slideResult;
return chapterResult;
}
return dispatch(selectRoute('context'));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ import {
exit,
LOCATION_EXIT_REQUEST,
LOCATION_EXIT_SUCCESS,
LOCATION_EXIT_FAILURE
LOCATION_EXIT_FAILURE,
back,
LOCATION_BACK_REQUEST,
LOCATION_BACK_SUCCESS,
LOCATION_BACK_FAILURE
} from '../location';

test(
Expand Down Expand Up @@ -118,3 +122,57 @@ test(
}
]
);
test(
'should call back location service and dispatch SUCCESS action',
macro,
pipe(
set('ui.current.progressionId', '0'),
set('data.contents.level.entities.foo', {}),
set('data.progressions.entities.0.content', {type: 'level', ref: 'foo'})
)({}),
t => ({
Location: {
back: () => {
return 'foo';
}
}
}),
back,
[
{
type: LOCATION_BACK_REQUEST
},
{
type: LOCATION_BACK_SUCCESS,
payload: 'foo'
}
]
);

test(
'should call back location service and dispatch FAILURE action on error',
macro,
pipe(
set('ui.current.progressionId', '0'),
set('data.contents.level.entities.foo', {}),
set('data.progressions.entities.0.content', {type: 'level', ref: 'foo'})
)({}),
t => ({
Location: {
back: () => {
throw new Error();
}
}
}),
back,
[
{
type: LOCATION_BACK_REQUEST
},
{
type: LOCATION_BACK_FAILURE,
error: true,
payload: new Error()
}
]
);
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ import {
import {RECO_FETCH_REQUEST, RECO_FETCH_SUCCESS} from '../../api/recommendations';
import {UI_SELECT_ROUTE} from '../route';

const slide = {ref: 'bar'};
const slide = {ref: 'bar', chapter_id: 'baz'};
const slideWithContext = {
ref: 'bar',
chapter_id: 'baz',
context: {title: 'some-title', description: 'some-description'}
};

Expand Down Expand Up @@ -214,10 +215,17 @@ test(
},
set('data.contents.slide.entities.bar', null, {})
],
[
{
type: CONTENT_FETCH_SUCCESS,
meta: {type: 'slide', ref: 'bar'},
payload: slide
},
set('data.contents.slide.entities.bar', slide, {})
],
{
type: CONTENT_FETCH_SUCCESS,
meta: {type: 'slide', ref: 'bar'},
payload: slide
type: CONTENT_FETCH_REQUEST,
meta: {type: 'chapter', ref: 'baz'}
}
]
);
Expand Down Expand Up @@ -342,10 +350,17 @@ test(
},
set('data.contents.slide.entities.bar', null, {})
],
[
{
type: CONTENT_FETCH_SUCCESS,
meta: {type: 'slide', ref: 'bar'},
payload: slideWithContext
},
set('data.contents.slide.entities.bar', slideWithContext, {})
],
{
type: CONTENT_FETCH_SUCCESS,
meta: {type: 'slide', ref: 'bar'},
payload: slideWithContext
type: CONTENT_FETCH_REQUEST,
meta: {type: 'chapter', ref: 'baz'}
},
{
type: UI_SELECT_ROUTE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
"_id": "1.A",
"name": "Level1",
"level": "base",
"meta": {
"updatedAt": "2017-01-26T09:19:06.874Z",
"createdAt": "2017-01-26T09:19:05.667Z"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ export const exit = () => {
export const retry = () => {
window.location.reload();
};

export const back = content => {
window.location.reload();
};
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,13 @@ test('should reload page on exit', t => {
};
Location.exit();
});

test('should reload page on back', t => {
t.plan(1);
global.window = {
location: {
reload: () => t.pass()
}
};
Location.back();
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import toString from 'lodash/fp/toString'; // eslint-disable-line no-shadow

const getId = get('_id');

export const getChapterId = get('chapter_id');
export const getChoices = get('question.content.choices');
export const getCurrentProgressionId = get('ui.current.progressionId');
export const getQuestionType = get('question.type');
Expand Down Expand Up @@ -54,6 +55,7 @@ export const getContentInfo = pipe(getCurrentContent, get('info'));
export const getNbSlides = pipe(getContentInfo, get('nbSlides'));
export const getStepContent = pipe(getCurrentProgression, get('state.nextContent'));
export const getPrevStepContent = pipe(getCurrentProgression, get('state.content'));
export const getCurrentChapterId = pipe(getCurrentSlide, getChapterId);

export const getEngine = state => {
return get('engine')(getCurrentProgression(state));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,64 @@
import get from 'lodash/fp/get';
import getOr from 'lodash/fp/getOr';
import {getLives, getCurrentContent} from '../../utils/state-extract';
import indexOf from 'lodash/fp/indexOf';
import {
getContent,
getCurrentChapterId,
getEngine,
getLives,
getCurrentContent
} from '../../utils/state-extract';
import {back} from '../../actions/ui/location';

const headerProps = (options, store) => state => {
const headerContent = (engineRef, state) => {
const content = getCurrentContent(state);

switch (engineRef) {
case 'learner':
return {
title: getOr('', 'name')(content),
details: get('level')(content)
};
case 'microlearning':
default:
return {
title: getOr('', 'name')(content)
};
}
};

const headerSubcontent = (engineRef, state) => {
switch (engineRef) {
case 'learner': {
const chapterId = getCurrentChapterId(state);
const chapter = getContent('chapter', chapterId)(state);
const level = getCurrentContent(state);
const chapterIds = get('chapterIds', level);
const details = chapterId && chapterIds
? `${1 + indexOf(chapterId, chapterIds)}/${chapterIds.length}`
: null;

return {
title: getOr('', 'name', chapter),
details
};
}
case 'microlearning':
default:
return null;
}
};

const headerProps = (options, {dispatch}) => state => {
const engine = getEngine(state);
const {ref: engineRef} = engine;
return {
backHref: '/',
primary: {
title: getOr('', 'name', content)
type: engineRef,
content: {
onClick: () => dispatch(back),
...headerContent(engineRef, state)
},
subcontent: headerSubcontent(engineRef, state),
lives: {
count: getLives(state)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import get from 'lodash/fp/get';
import getOr from 'lodash/fp/getOr';
import isEqual from 'lodash/fp/isEqual';
import pipe from 'lodash/fp/pipe';
import {retry, exit} from '../../actions/api/location';
import {retry, exit} from '../../actions/ui/location';
import {
getCurrentContent,
getCurrentExitNode,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import test from 'ava';
import set from 'lodash/fp/set';
import identity from 'lodash/fp/identity';
import omit from 'lodash/fp/omit';
import {mockTranslate} from '@coorpacademy/translate';
import createHeader from '../header';
import basicSlide from './fixtures/slides/basic';
Expand Down Expand Up @@ -53,15 +54,8 @@ test('should create header with the number of lives in the state', t => {
const ui = {current: {progressionId: 'basic'}};
const state = {data, ui};
const props = headerProps(state);

t.deepEqual(props, {
backHref: '/',
primary: {
title: ''
},
lives: {
count: 100
}
t.deepEqual(props.lives, {
count: 100
});
});

Expand All @@ -70,14 +64,8 @@ test('should read title from the content when available', t => {
const state = {data: set('progressions.entities.basic.content.ref', '1.B2', data), ui};
const props = headerProps(state);

t.deepEqual(props, {
backHref: '/',
primary: {
title: 'some-title'
},
lives: {
count: 100
}
t.deepEqual(omit('onClick', props.content), {
title: 'some-title'
});
});

Expand All @@ -86,13 +74,7 @@ test('should set lives to null if lives are disabled in the progression', t => {
const state = {data: set('progressions.entities.basic.state.livesDisabled', true, data), ui};
const props = headerProps(state);

t.deepEqual(props, {
backHref: '/',
primary: {
title: ''
},
lives: {
count: null
}
t.deepEqual(props.lives, {
count: null
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ test('should create a "Next" CTA when entering a success popin', async t => {
ENGINE_CONFIG_FETCH_SUCCESS,
CONTENT_INFO_FETCH_REQUEST,
CONTENT_FETCH_REQUEST,
CONTENT_FETCH_SUCCESS,
CONTENT_FETCH_REQUEST,
CONTENT_FETCH_SUCCESS
]);

Expand Down
Loading

0 comments on commit 02e5b74

Please sign in to comment.