From 91e85a1b974eb0bfb42df8c896570e0a690d11f1 Mon Sep 17 00:00:00 2001 From: cedricnjanga Date: Tue, 10 Oct 2017 11:05:53 +0200 Subject: Need to test webpack config and to configure teaspoon to run React Apps specs --- spec/javascript/journey_patterns/actions_spec.js | 154 +++++++ .../reducers/journey_patterns_spec.js | 125 ++++++ .../journey_patterns/reducers/modal_spec.js | 98 +++++ .../journey_patterns/reducers/pagination_spec.js | 93 ++++ .../journey_patterns/reducers/status_spec.js | 51 +++ spec/javascript/routes/actions_spec.js | 101 +++++ .../javascript/routes/reducers/stop_points_spec.js | 486 +++++++++++++++++++++ spec/javascript/spec_helper.coffee | 32 ++ spec/javascript/spec_helper.js | 35 ++ spec/javascript/time_table/actions_spec.js | 238 ++++++++++ spec/javascript/time_table/reducers/metas_spec.js | 77 ++++ spec/javascript/time_table/reducers/modal_spec.js | 328 ++++++++++++++ .../time_table/reducers/pagination_spec.js | 139 ++++++ spec/javascript/time_table/reducers/status_spec.js | 50 +++ .../time_table/reducers/timetable_spec.js | 336 ++++++++++++++ spec/javascript/vehicle_journeys/actions_spec.js | 449 +++++++++++++++++++ .../vehicle_journeys/reducers/filters_spec.js | 165 +++++++ .../vehicle_journeys/reducers/modal_spec.js | 179 ++++++++ .../vehicle_journeys/reducers/pagination_spec.js | 123 ++++++ .../vehicle_journeys/reducers/status_spec.js | 45 ++ .../reducers/vehicle_journeys_spec.js | 268 ++++++++++++ 21 files changed, 3572 insertions(+) create mode 100644 spec/javascript/journey_patterns/actions_spec.js create mode 100644 spec/javascript/journey_patterns/reducers/journey_patterns_spec.js create mode 100644 spec/javascript/journey_patterns/reducers/modal_spec.js create mode 100644 spec/javascript/journey_patterns/reducers/pagination_spec.js create mode 100644 spec/javascript/journey_patterns/reducers/status_spec.js create mode 100644 spec/javascript/routes/actions_spec.js create mode 100644 spec/javascript/routes/reducers/stop_points_spec.js create mode 100644 spec/javascript/spec_helper.coffee create mode 100644 spec/javascript/spec_helper.js create mode 100644 spec/javascript/time_table/actions_spec.js create mode 100644 spec/javascript/time_table/reducers/metas_spec.js create mode 100644 spec/javascript/time_table/reducers/modal_spec.js create mode 100644 spec/javascript/time_table/reducers/pagination_spec.js create mode 100644 spec/javascript/time_table/reducers/status_spec.js create mode 100644 spec/javascript/time_table/reducers/timetable_spec.js create mode 100644 spec/javascript/vehicle_journeys/actions_spec.js create mode 100644 spec/javascript/vehicle_journeys/reducers/filters_spec.js create mode 100644 spec/javascript/vehicle_journeys/reducers/modal_spec.js create mode 100644 spec/javascript/vehicle_journeys/reducers/pagination_spec.js create mode 100644 spec/javascript/vehicle_journeys/reducers/status_spec.js create mode 100644 spec/javascript/vehicle_journeys/reducers/vehicle_journeys_spec.js (limited to 'spec/javascript') diff --git a/spec/javascript/journey_patterns/actions_spec.js b/spec/javascript/journey_patterns/actions_spec.js new file mode 100644 index 000000000..75f2682b1 --- /dev/null +++ b/spec/javascript/journey_patterns/actions_spec.js @@ -0,0 +1,154 @@ +import actions from '../../app/javascript/journey_patterns/actions' + +const dispatch = function(){} +const currentPage = 1 + +describe('when receiveJourneyPatterns is triggered', () => { + it('should create an action to pass json to reducer', () => { + const json = undefined + const expectedAction = { + type: 'RECEIVE_JOURNEY_PATTERNS', + json + } + expect(actions.receiveJourneyPatterns()).toEqual(expectedAction) + }) +}) + +describe('when previous navigation button is clicked', () => { + it('should create an action to go to previous page', () => { + const nextPage = false + const pagination = { + totalCount: 25, + perPage: 12, + page:1 + } + const expectedAction = { + type: 'GO_TO_PREVIOUS_PAGE', + dispatch, + pagination, + nextPage + } + expect(actions.goToPreviousPage(dispatch, pagination)).toEqual(expectedAction) + }) +}) +describe('when next navigation button is clicked', () => { + it('should create an action to go to next page', () => { + const nextPage = true + const pagination = { + totalCount: 25, + perPage: 12, + page:1 + } + const expectedAction = { + type: 'GO_TO_NEXT_PAGE', + dispatch, + pagination, + nextPage + } + expect(actions.goToNextPage(dispatch, pagination)).toEqual(expectedAction) + }) +}) +describe('when clicking on a journey pattern checkbox', () => { + it('should create an action to update journey pattern stop points', () => { + const event = { + currentTarget: { + id: '1' + } + } + const index = 1 + const expectedAction = { + type: 'UPDATE_CHECKBOX_VALUE', + id: event.currentTarget.id, + index, + } + expect(actions.updateCheckboxValue(event, index)).toEqual(expectedAction) + }) +}) +describe('when clicking on next button', () => { + it('should create an action to open a confirm modal', () => { + const callback = function(){} + const expectedAction = { + type: 'OPEN_CONFIRM_MODAL', + callback + } + expect(actions.openConfirmModal(callback)).toEqual(expectedAction) + }) +}) +describe('when clicking on edit button', () => { + it('should create an action to open a edit modal', () => { + const index = 1 + const journeyPattern = {} + const expectedAction = { + type: 'EDIT_JOURNEYPATTERN_MODAL', + index, + journeyPattern, + } + expect(actions.openEditModal(index, journeyPattern)).toEqual(expectedAction) + }) +}) +describe('when clicking on add button', () => { + it('should create an action to open a create modal', () => { + const expectedAction = { + type: 'CREATE_JOURNEYPATTERN_MODAL', + } + expect(actions.openCreateModal()).toEqual(expectedAction) + }) +}) +describe('when clicking on close button inside edit or add modal', () => { + it('should create an action to close modal', () => { + const expectedAction = { + type: 'CLOSE_MODAL', + } + expect(actions.closeModal()).toEqual(expectedAction) + }) +}) +describe('when clicking on a journey pattern delete button', () => { + it('should create an action to delete journey pattern', () => { + const index = 1 + const expectedAction = { + type: 'DELETE_JOURNEYPATTERN', + index + } + expect(actions.deleteJourneyPattern(index)).toEqual(expectedAction) + }) +}) +describe('when clicking on validate button inside edit modal', () => { + it('should create an action to save journey pattern modifications', () => { + const index = 1 + const data = {} + const expectedAction = { + type: 'SAVE_MODAL', + index, + data + } + expect(actions.saveModal(index, data)).toEqual(expectedAction) + }) +}) +describe('when clicking on validate button inside create modal', () => { + it('should create an action to create a new journey pattern', () => { + const data = {} + const expectedAction = { + type: 'ADD_JOURNEYPATTERN', + data + } + expect(actions.addJourneyPattern(data)).toEqual(expectedAction) + }) +}) +describe('when submitting new journeyPatterns', () => { + it('should create an action to update pagination totalCount', () => { + const diff = 1 + const expectedAction = { + type: 'UPDATE_TOTAL_COUNT', + diff + } + expect(actions.updateTotalCount(diff)).toEqual(expectedAction) + }) +}) +describe('when fetching api', () => { + it('should create an action to fetch api', () => { + const expectedAction = { + type: 'FETCH_API', + } + expect(actions.fetchingApi()).toEqual(expectedAction) + }) +}) diff --git a/spec/javascript/journey_patterns/reducers/journey_patterns_spec.js b/spec/javascript/journey_patterns/reducers/journey_patterns_spec.js new file mode 100644 index 000000000..13a88e477 --- /dev/null +++ b/spec/javascript/journey_patterns/reducers/journey_patterns_spec.js @@ -0,0 +1,125 @@ +import jpReducer from '../../../app/javascript/journey_patterns/reducers/journeyPatterns' + +let state = [] +let fakeStopPoints = [{ + area_type : "lda", + checked : false, + id : 45289, + name : "Clichy Levallois", + object_id : "FR:92044:LDA:72073:STIF", + position : 0, +},{ + area_type : "lda", + checked : false, + id : 40534, + name : "Thomas Lemaître", + object_id : "FR:92050:LDA:70915:STIF", + position : 1, +}] +let stopPoints = [{ + area_type : 'zdep', + city_name : 'Plaisir', + for_alighting : 'normal', + for_boarding : 'normal', + id : 14892, + name : 'test1', + object_id : 'test:StopPoint:1', + position : 0, + zip_code : '78490' +},{ + area_type : 'zdep', + city_name : 'Plaisir', + for_alighting : 'normal', + for_boarding : 'normal', + id : 14893, + name : 'test2', + object_id : 'test:StopPoint:2', + position : 1, + zip_code : '78490' +}] + +describe('journeyPatterns reducer', () => { + beforeEach(()=>{ + state = [ + { + deletable: false, + name: 'm1', + object_id : 'o1', + published_name: 'M1', + registration_number: '', + stop_points: fakeStopPoints + }, + { + deletable: false, + name: 'm2', + object_id : 'o2', + published_name: 'M2', + registration_number: '', + stop_points: fakeStopPoints + } + ] + }) + + it('should return the initial state', () => { + expect( + jpReducer(undefined, {}) + ).toEqual([]) + }) + + it('should handle ADD_JOURNEYPATTERN', () => { + let fakeData = { + name: {value : 'm3'}, + published_name: {value: 'M3'}, + registration_number: {value: ''} + } + let stopPoints = stopPoints + expect( + jpReducer(state, { + type: 'ADD_JOURNEYPATTERN', + data: fakeData + }) + ).toEqual([{ + name : 'm3', + published_name: 'M3', + registration_number: '', + deletable: false, + stop_points: stopPoints + }, ...state]) + }) + + it('should handle UPDATE_CHECKBOX_VALUE', () => { + let newFirstStopPoint = Object.assign({}, fakeStopPoints[0], {checked: !fakeStopPoints[0].checked} ) + let newStopPoints = [newFirstStopPoint, fakeStopPoints[1]] + let newState = Object.assign({}, state[0], {stop_points: newStopPoints}) + expect( + jpReducer(state, { + type: 'UPDATE_CHECKBOX_VALUE', + id: 45289, + index: 0 + }) + ).toEqual([newState, state[1]]) + }) + + it('should handle DELETE_JOURNEYPATTERN', () => { + expect( + jpReducer(state, { + type: 'DELETE_JOURNEYPATTERN', + index: 1 + }) + ).toEqual([state[0], Object.assign({}, state[1], {deletable: true})]) + }) + it('should handle SAVE_MODAL', () => { + let newState = Object.assign({}, state[0], {name: 'p1', published_name: 'P1', registration_number: 'PP11'}) + expect( + jpReducer(state, { + type: 'SAVE_MODAL', + data: { + name: {value: 'p1'}, + published_name: {value: 'P1'}, + registration_number: {value: 'PP11'} + }, + index: 0 + }) + ).toEqual([newState, state[1]]) + }) +}) diff --git a/spec/javascript/journey_patterns/reducers/modal_spec.js b/spec/javascript/journey_patterns/reducers/modal_spec.js new file mode 100644 index 000000000..a5d215a9c --- /dev/null +++ b/spec/javascript/journey_patterns/reducers/modal_spec.js @@ -0,0 +1,98 @@ +import modalReducer from '../../../app/javascript/journey_patterns/reducers/modal' + +let state = {} + +let fakeJourneyPattern = { + name: 'jp_test 1', + object_id: 'jp_test:JourneyPattern:1', + published_name: 'jp_test publishedname 1', + registration_number: 'jp_test registrationnumber 1', + stop_points: [], + deletable: false +} + +const cb = function(){} + +describe('modal reducer', () => { + beforeEach(() => { + state = { + type: '', + modalProps: {}, + confirmModal: {} + } + }) + + it('should return the initial state', () => { + expect( + modalReducer(undefined, {}) + ).toEqual({}) + }) + + it('should handle OPEN_CONFIRM_MODAL', () => { + let newState = Object.assign({}, state, { + type: 'confirm', + confirmModal: { + callback: cb + } + }) + expect( + modalReducer(state, { + type: 'OPEN_CONFIRM_MODAL', + callback: cb + }) + ).toEqual(newState) + }) + + it('should handle EDIT_JOURNEYPATTERN_MODAL', () => { + let newState = Object.assign({}, state, { + type: 'edit', + modalProps: { + index: 0, + journeyPattern: fakeJourneyPattern + }, + confirmModal: {} + }) + expect( + modalReducer(state, { + type: 'EDIT_JOURNEYPATTERN_MODAL', + index: 0, + journeyPattern : fakeJourneyPattern + }) + ).toEqual(newState) + }) + + it('should handle CREATE_JOURNEYPATTERN_MODAL', () => { + expect( + modalReducer(state, { + type: 'CREATE_JOURNEYPATTERN_MODAL' + }) + ).toEqual(Object.assign({}, state, { type: 'create' })) + }) + + it('should handle DELETE_JOURNEYPATTERN', () => { + expect( + modalReducer(state, { + type: 'DELETE_JOURNEYPATTERN', + index: 0 + }) + ).toEqual(state) + }) + + it('should handle SAVE_MODAL', () => { + expect( + modalReducer(state, { + type: 'SAVE_MODAL', + index: 0, + data: {} + }) + ).toEqual(state) + }) + + it('should handle CLOSE_MODAL', () => { + expect( + modalReducer(state, { + type: 'CLOSE_MODAL' + }) + ).toEqual(state) + }) +}) diff --git a/spec/javascript/journey_patterns/reducers/pagination_spec.js b/spec/javascript/journey_patterns/reducers/pagination_spec.js new file mode 100644 index 000000000..78a09eace --- /dev/null +++ b/spec/javascript/journey_patterns/reducers/pagination_spec.js @@ -0,0 +1,93 @@ +import reducer from '../../../app/javascript/journey_patterns/reducers/pagination' + +const diff = 1 +let state = { + page : 2, + totalCount : 50, + stateChanged: false, + perPage: 20 +} +let pagination = Object.assign({}, state) +const dispatch = function(){} + +describe('pagination reducer, given parameters allowing page change', () => { + + it('should return the initial state', () => { + expect( + reducer(undefined, {}) + ).toEqual({}) + }) + + it('should handle GO_TO_NEXT_PAGE and change state', () => { + expect( + reducer(state, { + type: 'GO_TO_NEXT_PAGE', + dispatch, + pagination, + nextPage : true + }) + ).toEqual(Object.assign({}, state, {page : state.page + 1, stateChanged: false})) + }) + + it('should return GO_TO_PREVIOUS_PAGE and change state', () => { + expect( + reducer(state, { + type: 'GO_TO_PREVIOUS_PAGE', + dispatch, + pagination, + nextPage : false + }) + ).toEqual(Object.assign({}, state, {page : state.page - 1, stateChanged: false})) + }) +}) + + +describe('pagination reducer, given parameters not allowing to go to previous page', () => { + + beforeEach(()=>{ + state.page = 1 + pagination.page = 1 + }) + + it('should return GO_TO_PREVIOUS_PAGE and not change state', () => { + expect( + reducer(state, { + type: 'GO_TO_PREVIOUS_PAGE', + dispatch, + pagination, + nextPage : false + }) + ).toEqual(state) + }) +}) + +describe('pagination reducer, given parameters not allowing to go to next page', () => { + + beforeEach(()=>{ + state.page = 3 + pagination.page = 3 + }) + + it('should return GO_TO_NEXT_PAGE and not change state', () => { + expect( + reducer(state, { + type: 'GO_TO_NEXT_PAGE', + dispatch, + pagination, + nextPage : true + }) + ).toEqual(state) + }) +}) + +describe('pagination reducer, given parameters changing totalCount', () => { + + it('should return UPDATE_TOTAL_COUNT and update totalCount', () => { + expect( + reducer(state, { + type: 'UPDATE_TOTAL_COUNT', + diff + }) + ).toEqual(Object.assign({}, state, {totalCount: state.totalCount - diff})) + }) +}) diff --git a/spec/javascript/journey_patterns/reducers/status_spec.js b/spec/javascript/journey_patterns/reducers/status_spec.js new file mode 100644 index 000000000..bf27a3d05 --- /dev/null +++ b/spec/javascript/journey_patterns/reducers/status_spec.js @@ -0,0 +1,51 @@ +import statusReducer from '../../../app/javascript/journey_patterns/reducers/status' + +let state = {} + +let pagination = { + page : 2, + totalCount : 25, + stateChanged: false, + perPage: 12 +} +const dispatch = function(){} + +describe('status reducer', () => { + beforeEach(() => { + state = { + fetchSuccess: true, + isFetching: false + } + }) + + it('should return the initial state', () => { + expect( + statusReducer(undefined, {}) + ).toEqual({}) + }) + + it('should handle UNAVAILABLE_SERVER', () => { + expect( + statusReducer(state, { + type: 'UNAVAILABLE_SERVER' + }) + ).toEqual(Object.assign({}, state, {fetchSuccess: false})) + }) + + it('should handle RECEIVE_JOURNEY_PATTERNS', () => { + expect( + statusReducer(state, { + type: 'RECEIVE_JOURNEY_PATTERNS' + }) + ).toEqual(Object.assign({}, state, {fetchSuccess: true, isFetching: false})) + }) + + it('should handle FETCH_API', () => { + expect( + statusReducer(state, { + type: 'FETCH_API' + }) + ).toEqual(Object.assign({}, state, {isFetching: true})) + }) + +}) diff --git a/spec/javascript/routes/actions_spec.js b/spec/javascript/routes/actions_spec.js new file mode 100644 index 000000000..490b1b615 --- /dev/null +++ b/spec/javascript/routes/actions_spec.js @@ -0,0 +1,101 @@ +import actions from '../../app/javascript/routes/actions' + +describe('actions', () => { + it('should create an action to add a stop', () => { + const expectedAction = { + type: 'ADD_STOP', + } + expect(actions.addStop()).toEqual(expectedAction) + }) +}) +describe('actions', () => { + it('should create an action to move up a stop', () => { + const index = 1 + const expectedAction = { + type: 'MOVE_STOP_UP', + index + } + expect(actions.moveStopUp(index)).toEqual(expectedAction) + }) +}) +describe('actions', () => { + it('should create an action to move down a stop', () => { + const index = 1 + const expectedAction = { + type: 'MOVE_STOP_DOWN', + index + } + expect(actions.moveStopDown(index)).toEqual(expectedAction) + }) +}) +describe('actions', () => { + it('should create an action to delete a stop', () => { + const index = 1 + const expectedAction = { + type: 'DELETE_STOP', + index + } + expect(actions.deleteStop(index)).toEqual(expectedAction) + }) +}) +describe('actions', () => { + it('should create an action to update the value of a stop', () => { + const text = 'updated text' + const index = 1 + const expectedAction = { + type: 'UPDATE_INPUT_VALUE', + index, + text + } + expect(actions.updateInputValue(index, text)).toEqual(expectedAction) + }) +}) + +describe('actions', () => { + it('should create an action to update the up select of a stop', () => { + const event = { + currentTarget: { + value: 'forbidden', + id: 'up' + } + } + const index = 1 + const expectedAction = { + type :'UPDATE_SELECT_VALUE', + select_id: 'up', + select_value: 'forbidden', + index + } + expect(actions.updateSelectValue(event, index)).toEqual(expectedAction) + }) +}) + +describe('actions', () => { + it('should create an action to toggle the map', () => { + const index = 1 + const expectedAction = { + type: 'TOGGLE_MAP', + index + } + expect(actions.toggleMap(index)).toEqual(expectedAction) + }) +}) + +describe('actions', () => { + it('should create an action to select a marker on the map', () => { + const index = 1 + const data = { + geometry: undefined, + registration_number: 'rn_test', + stoparea_id: 'sid_test', + text: 't_test', + user_objectid: 'uoid_test' + } + const expectedAction = { + type: 'SELECT_MARKER', + index, + data + } + expect(actions.selectMarker(index, data)).toEqual(expectedAction) + }) +}) diff --git a/spec/javascript/routes/reducers/stop_points_spec.js b/spec/javascript/routes/reducers/stop_points_spec.js new file mode 100644 index 000000000..c9d76a29e --- /dev/null +++ b/spec/javascript/routes/reducers/stop_points_spec.js @@ -0,0 +1,486 @@ +import stopPointsReducer from '../../../app/javascript/routes/reducers/stopPoints' + +let state = [] + +let fakeData = { + geometry: undefined, + registration_number: 'rn_test', + stoparea_id: 'sid_test', + text: 't_test', + user_objectid: 'uoid_test' +} + +describe('stops reducer', () => { + beforeEach(()=>{ + state = [ + { + text: 'first', + index: 0, + stoppoint_id: 72, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + }, + { + text: 'second', + index: 1, + stoppoint_id: 73, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + } + ] + }) + + it('should return the initial state', () => { + expect( + stopPointsReducer(undefined, {}) + ).toEqual([]) + }) + + it('should handle ADD_STOP', () => { + expect( + stopPointsReducer(state, { + type: 'ADD_STOP' + }) + ).toEqual( + [ + { + text: 'first', + index: 0, + stoppoint_id: 72, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + }, + { + text: 'second', + index: 1, + stoppoint_id: 73, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + }, + { + text: '', + index: 2, + edit: true, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + } + ] + ) + }) + + it('should handle MOVE_UP_STOP', () => { + expect( + stopPointsReducer(state, { + type: 'MOVE_STOP_UP', + index: 1 + }) + ).toEqual( + [ + { + text: 'second', + index: 1, + stoppoint_id: 72, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + }, + { + text: 'first', + index: 0, + stoppoint_id: 73, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + } + ] + ) + }) + + it('should handle MOVE_DOWN_STOP', () => { + expect( + stopPointsReducer(state, { + type: 'MOVE_STOP_DOWN', + index: 0 + }) + ).toEqual( + [ + { + text: 'second', + index: 1, + stoppoint_id: 72, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + }, + { + text: 'first', + index: 0, + stoppoint_id: 73, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + } + ] + ) + }) + + // it('should handle DELETE_STOP', () => { + // expect( + // stopPointsReducer(state, { + // type: 'DELETE_STOP', + // index: 1 + // }) + // ).toEqual( + // [ + // { + // text: 'first', + // index: 0, + // stoppoint_id: 72, + // edit: false, + // for_boarding: 'normal', + // for_alighting: 'normal', + // olMap: { + // isOpened: false, + // json: {} + // } + // } + // ] + // ) + // }) + + it('should handle UPDATE_INPUT_VALUE', () => { + expect( + stopPointsReducer(state, { + type: 'UPDATE_INPUT_VALUE', + index: 0, + edit: false, + text: { + text: "new value", + name: 'new', + stoparea_id: 1, + user_objectid: "1234", + longitude: 123, + latitude: 123, + registration_number: '0', + city_name: 'city', + area_type: 'area', + short_name: 'new', + comment: 'newcomment' + } + }) + ).toEqual( + [ + { + text: 'new value', + name: 'new', + index: 0, + stoppoint_id: 72, + edit: false, + stoparea_id: 1, + for_boarding: 'normal', + for_alighting: 'normal', + user_objectid: "1234", + longitude: 123, + latitude: 123, + registration_number: '0', + city_name: 'city', + area_type: 'area', + short_name: 'new', + comment: 'newcomment', + olMap: { + isOpened: false, + json: {} + } + }, + { + text: 'second', + index: 1, + stoppoint_id: 73, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + } + ] + ) + }) + + it('should handle UPDATE_SELECT_VALUE', () => { + expect( + stopPointsReducer(state, { + type :'UPDATE_SELECT_VALUE', + select_id: 'for_boarding', + select_value: 'prohibited', + index: 0 + }) + ).toEqual( + [ + { + text: 'first', + index: 0, + stoppoint_id: 72, + edit: false, + for_boarding: 'prohibited', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + }, + { + text: 'second', + index: 1, + stoppoint_id: 73, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + } + ] + ) + }) + + it('should handle TOGGLE_MAP', () => { + expect( + stopPointsReducer(state, { + type: 'TOGGLE_MAP', + index: 0 + }) + ).toEqual( + [ + { + text: 'first', + index: 0, + stoppoint_id: 72, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: true, + json: { + text: 'first', + index: 0, + stoppoint_id: 72, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: undefined + } + } + }, + { + text: 'second', + index: 1, + stoppoint_id: 73, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + } + ] + ) + }) + + it('should handle TOGGLE_EDIT', () => { + expect( + stopPointsReducer(state, { + type: 'TOGGLE_EDIT', + index: 0 + }) + ).toEqual( + [ + { + text: 'first', + index: 0, + stoppoint_id: 72, + edit: true, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + }, + { + text: 'second', + index: 1, + stoppoint_id: 73, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + } + ] + ) + }) + + it('should handle SELECT_MARKER', () => { + let openedMapState = [ + { + text: 'first', + index: 0, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: true, + json: {} + } + }, + { + text: 'second', + index: 1, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + } + ] + expect( + stopPointsReducer(openedMapState, { + type: 'SELECT_MARKER', + index: 0, + data: fakeData + }) + ).toEqual( + [ + { + text: 'first', + index: 0, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: true, + json: fakeData + } + }, + { + text: 'second', + index: 1, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + } + ] + ) + }) + + it('should handle UNSELECT_MARKER', () => { + let openedMapState = [ + { + text: 'first', + index: 0, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: true, + json: {} + } + }, + { + text: 'second', + index: 1, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + } + ] + + expect( + stopPointsReducer(openedMapState, { + type: 'UNSELECT_MARKER', + index: 0 + }) + ).toEqual( + [ + { + text: 'first', + index: 0, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: true, + json: {} + } + }, + { + text: 'second', + index: 1, + edit: false, + for_boarding: 'normal', + for_alighting: 'normal', + olMap: { + isOpened: false, + json: {} + } + } + ] + ) + }) +}) diff --git a/spec/javascript/spec_helper.coffee b/spec/javascript/spec_helper.coffee new file mode 100644 index 000000000..9ff516885 --- /dev/null +++ b/spec/javascript/spec_helper.coffee @@ -0,0 +1,32 @@ +# Teaspoon includes some support files, but you can use anything from your own support path too. +# require support/jasmine-jquery-1.7.0 +# require support/jasmine-jquery-2.0.0 +# require support/jasmine-jquery-2.1.0 +# require support/sinon +# require support/your-support-file +# +# PhantomJS (Teaspoons default driver) doesn't have support for Function.prototype.bind, which has caused confusion. +# Use this polyfill to avoid the confusion. +#= require support/phantomjs-shims +# +# You can require your own javascript files here. By default this will include everything in application, however you +# may get better load performance if you require the specific files that are being used in the spec that tests them. +#= require application +# +# Deferring execution +# If you're using CommonJS, RequireJS or some other asynchronous library you can defer execution. Call +# Teaspoon.execute() after everything has been loaded. Simple example of a timeout: +# +# Teaspoon.defer = true +# setTimeout(Teaspoon.execute, 1000) +# +# Matching files +# By default Teaspoon will look for files that match _spec.{js,js.coffee,.coffee}. Add a filename_spec.js file in your +# spec path and it'll be included in the default suite automatically. If you want to customize suites, check out the +# configuration in teaspoon_env.rb +# +# Manifest +# If you'd rather require your spec files manually (to control order for instance) you can disable the suite matcher in +# the configuration and use this file as a manifest. +# +# For more information: http://github.com/modeset/teaspoon diff --git a/spec/javascript/spec_helper.js b/spec/javascript/spec_helper.js new file mode 100644 index 000000000..b6fcb7d8d --- /dev/null +++ b/spec/javascript/spec_helper.js @@ -0,0 +1,35 @@ +// Teaspoon includes some support files, but you can use anything from your own support path too. +// require support/jasmine-jquery-1.7.0 +// require support/jasmine-jquery-2.0.0 +// require support/jasmine-jquery-2.1.0 +// require support/sinon +// require support/your-support-file +//= require jquery +//= require bootstrap-sass-official +import { polyfill } from 'es6-object-assign' +// +// PhantomJS (Teaspoons default driver) doesn't have support for Function.prototype.bind, which has caused confusion. +// Use this polyfill to avoid the confusion. +//= require support/phantomjs-shims +// +// You can require your own javascript files here. By default this will include everything in application, however you +// may get better load performance if you require the specific files that are being used in the spec that tests them. +//= require application +// +// Deferring execution +// If you're using CommonJS, RequireJS or some other asynchronous library you can defer execution. Call +// Teaspoon.execute() after everything has been loaded. Simple example of a timeout: +// +// Teaspoon.defer = true +// setTimeout(Teaspoon.execute, 1000) +// +// Matching files +// By default Teaspoon will look for files that match _spec.{js,js.coffee,.coffee}. Add a filename_spec.js file in your +// spec path and it'll be included in the default suite automatically. If you want to customize suites, check out the +// configuration in teaspoon_env.rb +// +// Manifest +// If you'd rather require your spec files manually (to control order for instance) you can disable the suite matcher in +// the configuration and use this file as a manifest. +// +// For more information: http://github.com/modeset/teaspoon diff --git a/spec/javascript/time_table/actions_spec.js b/spec/javascript/time_table/actions_spec.js new file mode 100644 index 000000000..4c1d4e200 --- /dev/null +++ b/spec/javascript/time_table/actions_spec.js @@ -0,0 +1,238 @@ +import actions from '../../app/javascript/time_tables/actions' +const dispatch = function(){} +const dayTypes = [true, true, true, true, true, true, true] +const day = { + date : "2017-05-01", + day : "lundi", + excluded_date : false, + in_periods : true, + include_date : false, + mday : 1, + wday : 1, + wnumber : "18" +} +describe('actions', () => { + it('should create an action to update dayTypes', () => { + let obj = {} + const expectedAction = { + type: 'UPDATE_DAY_TYPES', + dayTypes: obj + } + expect(actions.updateDayTypes(obj)).toEqual(expectedAction) + }) + + it('should create an action to update comment', () => { + const expectedAction = { + type: 'UPDATE_COMMENT', + comment: 'test' + } + expect(actions.updateComment('test')).toEqual(expectedAction) + }) + + it('should create an action to update color', () => { + const expectedAction = { + type: 'UPDATE_COLOR', + color: '#ffffff' + } + expect(actions.updateColor('#ffffff')).toEqual(expectedAction) + }) + + it('should create an action to update selected tags', () => { + let selectedItem = { + id: 1, + name: 'test' + } + const expectedAction = { + type: 'UPDATE_SELECT_TAG', + selectedItem: selectedItem + } + expect(actions.select2Tags(selectedItem)).toEqual(expectedAction) + }) + + it('should create an action to update unselected tags', () => { + let selectedItem = { + id: 1, + name: 'test' + } + const expectedAction = { + type: 'UPDATE_UNSELECT_TAG', + selectedItem: selectedItem + } + expect(actions.unselect2Tags(selectedItem)).toEqual(expectedAction) + }) + + + it('should create an action to go to previous page', () => { + let pagination = { + currentPage: '2017-01-01', + periode_range: [], + stateChanged: false + } + const expectedAction = { + type: 'GO_TO_PREVIOUS_PAGE', + dispatch, + pagination, + nextPage: false + } + expect(actions.goToPreviousPage(dispatch, pagination)).toEqual(expectedAction) + }) + + it('should create an action to go to next page', () => { + let pagination = { + currentPage: '2017-01-01', + periode_range: [], + stateChanged: false + } + const expectedAction = { + type: 'GO_TO_NEXT_PAGE', + dispatch, + pagination, + nextPage: true + } + expect(actions.goToNextPage(dispatch, pagination)).toEqual(expectedAction) + }) + + it('should create an action to change page', () => { + let page = '2017-05-04' + const expectedAction = { + type: 'CHANGE_PAGE', + dispatch, + page: page + } + expect(actions.changePage(dispatch, page)).toEqual(expectedAction) + }) + + it('should create an action to delete period', () => { + let index = 1 + const expectedAction = { + type: 'DELETE_PERIOD', + index, + dayTypes + } + expect(actions.deletePeriod(index, dayTypes)).toEqual(expectedAction) + }) + + it('should create an action to open add period form', () => { + const expectedAction = { + type: 'OPEN_ADD_PERIOD_FORM', + } + expect(actions.openAddPeriodForm()).toEqual(expectedAction) + }) + + it('should create an action to open edit period form', () => { + let period = { + id : 1, + period_end : "2017-03-05", + period_start : "2017-02-23" + } + let index = 1 + const expectedAction = { + type: 'OPEN_EDIT_PERIOD_FORM', + period, + index + } + expect(actions.openEditPeriodForm(period, index)).toEqual(expectedAction) + }) + + it('should create an action to close period form', () => { + const expectedAction = { + type: 'CLOSE_PERIOD_FORM', + } + expect(actions.closePeriodForm()).toEqual(expectedAction) + }) + + it('should create an action to update period form', () => { + let val = "11" + let group = "start" + let selectType = "day" + const expectedAction = { + type: 'UPDATE_PERIOD_FORM', + val, + group, + selectType + } + expect(actions.updatePeriodForm(val, group, selectType)).toEqual(expectedAction) + }) + + it('should create an action to validate period form', () => { + let modalProps = {} + let timeTablePeriods = [] + let metas = {} + let timetableInDates = [] + let error = '' + const expectedAction = { + type: 'VALIDATE_PERIOD_FORM', + modalProps, + timeTablePeriods, + metas, + timetableInDates, + error + } + expect(actions.validatePeriodForm(modalProps, timeTablePeriods, metas, timetableInDates, error)).toEqual(expectedAction) + }) + + it('should create an action to add an included date', () => { + let index = 1 + let date = actions.formatDate(new Date) + const expectedAction = { + type: 'ADD_INCLUDED_DATE', + index, + dayTypes, + date + } + expect(actions.addIncludedDate(index, dayTypes, date)).toEqual(expectedAction) + }) + + it('should create an action to remove an included dat', () => { + let index = 1 + let date = actions.formatDate(new Date) + const expectedAction = { + type: 'REMOVE_INCLUDED_DATE', + index, + dayTypes, + date + } + expect(actions.removeIncludedDate(index, dayTypes, date)).toEqual(expectedAction) + }) + + it('should create an action to add an excluded date in period', () => { + let index = 1 + let date = actions.formatDate(new Date) + const expectedAction = { + type: 'ADD_EXCLUDED_DATE', + index, + dayTypes, + date + } + expect(actions.addExcludedDate(index, dayTypes, date)).toEqual(expectedAction) + }) + + it('should create an action to remove an excluded date from period', () => { + let index = 1 + let date = actions.formatDate(new Date) + const expectedAction = { + type: 'REMOVE_EXCLUDED_DATE', + index, + dayTypes, + date + } + expect(actions.removeExcludedDate(index, dayTypes, date)).toEqual(expectedAction) + }) + + it('should create an action to open confirm modal', () => { + let callback = function(){} + const expectedAction = { + type: 'OPEN_CONFIRM_MODAL', + callback + } + expect(actions.openConfirmModal(callback)).toEqual(expectedAction) + }) + + it('should create an action to close modal', () => { + const expectedAction = { + type: 'CLOSE_MODAL', + } + expect(actions.closeModal()).toEqual(expectedAction) + }) + +}) diff --git a/spec/javascript/time_table/reducers/metas_spec.js b/spec/javascript/time_table/reducers/metas_spec.js new file mode 100644 index 000000000..8806cc1cf --- /dev/null +++ b/spec/javascript/time_table/reducers/metas_spec.js @@ -0,0 +1,77 @@ +import metasReducer from '../../../app/javascript/time_tables/reducers/metas' + +let state = {} + +describe('metas reducer', () => { + beforeEach(() => { + let tag = { + id: 0, + name: 'test' + } + state = { + comment: 'test', + day_types: [true, true, true, true, true, true, true], + color: 'blue', + initial_tags: [tag], + tags: [tag] + } + }) + + it('should return the initial state', () => { + expect( + metasReducer(undefined, {}) + ).toEqual({}) + }) + + it('should handle UPDATE_DAY_TYPES', () => { + const arr = [false, false, true, true, true, true, true] + expect( + metasReducer(state, { + type: 'UPDATE_DAY_TYPES', + dayTypes: arr + }) + ).toEqual(Object.assign({}, state, {day_types: arr, calendar: null})) + }) + + it('should handle UPDATE_COMMENT', () => { + expect( + metasReducer(state, { + type: 'UPDATE_COMMENT', + comment: 'title' + }) + ).toEqual(Object.assign({}, state, {comment: 'title'})) + }) + + it('should handle UPDATE_COLOR', () => { + expect( + metasReducer(state, { + type: 'UPDATE_COLOR', + color: '#ffffff' + }) + ).toEqual(Object.assign({}, state, {color: '#ffffff'})) + }) + + it('should handle UPDATE_SELECT_TAG', () => { + expect( + metasReducer(state, { + type: 'UPDATE_SELECT_TAG', + selectedItem:{ + id: 1, + name: 'great' + } + }) + ).toEqual(Object.assign({}, state, {tags: [...state.tags, {id: 1, name:'great'}]})) + }) + + it('should handle UPDATE_UNSELECT_TAG', () => { + expect( + metasReducer(state, { + type: 'UPDATE_UNSELECT_TAG', + selectedItem:{ + id: 0, + name: 'test' + } + }) + ).toEqual(Object.assign({}, state, {tags: []})) + }) +}) diff --git a/spec/javascript/time_table/reducers/modal_spec.js b/spec/javascript/time_table/reducers/modal_spec.js new file mode 100644 index 000000000..f627ca53b --- /dev/null +++ b/spec/javascript/time_table/reducers/modal_spec.js @@ -0,0 +1,328 @@ +import modalReducer from '../../../app/javascript/time_tables/reducers/modal' + +let state = {} + +describe('modal reducer', () => { + beforeEach(() => { + state = { + confirmModal: {}, + modalProps: { + active: false, + begin: { + day: '01', + month: '01', + year: String(new Date().getFullYear()) + }, + end: { + day: '01', + month: '01', + year: String(new Date().getFullYear()) + }, + index: false, + error: '' + }, + type: "" + } + }) + + it('should return the initial state', () => { + expect( + modalReducer(undefined, {}) + ).toEqual({}) + }) + + it('should handle OPEN_CONFIRM_MODAL', () => { + let callback = function(){} + expect( + modalReducer(state, { + type: 'OPEN_CONFIRM_MODAL', + callback + }) + ).toEqual(Object.assign({}, state, {type: "confirm", confirmModal: { callback: callback }})) + }) + + it('should handle CLOSE_PERIOD_FORM', () => { + let newModalProps = Object.assign({}, state.modalProps, {active: false}) + expect( + modalReducer(state, { + type: 'CLOSE_PERIOD_FORM' + }) + ).toEqual(Object.assign({}, state, {modalProps: newModalProps})) + }) + + it('should handle OPEN_EDIT_PERIOD_FORM', () => { + let period = { + id : 1, + period_end : "2017-03-05", + period_start : "2017-02-23" + } + let period_start = period.period_start.split('-') + let period_end = period.period_end.split('-') + + let index = 1 + + let newModalProps = { + active: true, + begin: { + day: period_start[2], + month: period_start[1], + year: period_start[0] + }, + end: { + day: period_end[2], + month: period_end[1], + year: period_end[0] + }, + index: index, + error: '' + } + expect( + modalReducer(state, { + type: 'OPEN_EDIT_PERIOD_FORM', + period, + index + }) + ).toEqual(Object.assign({}, state, {modalProps: newModalProps})) + }) + + it('should handle OPEN_ADD_PERIOD_FORM', () => { + let emptyDate = { + day: '01', + month: '01', + year: String(new Date().getFullYear()) + } + let newModalProps = Object.assign({}, state.modalProps, { + active: true, + begin: emptyDate, + end: emptyDate, + index: false, + error: "" + }) + + expect( + modalReducer(state, { + type: 'OPEN_ADD_PERIOD_FORM' + }) + ).toEqual(Object.assign({}, state, {modalProps: newModalProps})) + }) + + it('should handle UPDATE_PERIOD_FORM', () => { + let val = "11" + let group = "begin" + let selectType = "day" + + let newModalProps = { + active: false, + begin: { + day: val, + month: '01', + year: String(new Date().getFullYear()) + }, + end: { + day: '01', + month: '01', + year: String(new Date().getFullYear()) + }, + index: false, + error: '' + } + + expect( + modalReducer(state, { + type: 'UPDATE_PERIOD_FORM', + val, + group, + selectType + }) + ).toEqual(Object.assign({}, state, {modalProps: newModalProps})) + }) + + it('should handle VALIDATE_PERIOD_FORM and throw error if period starts after the end', () => { + let modProps = { + active: false, + begin: { + day: '13', + month: '01', + year: String(new Date().getFullYear()) + }, + end: { + day: '01', + month: '01', + year: String(new Date().getFullYear()) + }, + index: false, + error: '' + } + let newModalProps = { + active: true, + begin: { + day: '01', + month: '01', + year: String(new Date().getFullYear()) + }, + end: { + day: '01', + month: '01', + year: String(new Date().getFullYear()) + }, + index: false, + error: 'La date de départ doit être antérieure à la date de fin' + } + + let ttperiods = [] + let ttdates = [] + let metas = [] + + expect( + modalReducer(state, { + type: 'VALIDATE_PERIOD_FORM', + modalProps : modProps, + timeTablePeriods: ttperiods, + metas: metas, + timetableInDates: ttdates, + error: 'La date de départ doit être antérieure à la date de fin' + }) + ).toEqual(Object.assign({}, state, {modalProps: newModalProps})) + }) + + it('should handle VALIDATE_PERIOD_FORM and throw error if periods overlap', () => { + let state2 = { + confirmModal: {}, + modalProps: { + active: false, + begin: { + day: '03', + month: '05', + year: '2017' + }, + end: { + day: '09', + month: '05', + year: '2017' + }, + index: false, + error: '' + }, + type: '' + } + let modProps2 = { + active: false, + begin: { + day: '03', + month: '05', + year: '2017' + }, + end: { + day: '09', + month: '05', + year: '2017' + }, + index: false, + error: '' + } + let ttperiods2 = [ + {id: 261, period_start: '2017-02-23', period_end: '2017-03-05'}, + {id: 262, period_start: '2017-03-15', period_end: '2017-03-25'}, + {id: 264, period_start: '2017-04-24', period_end: '2017-05-04'}, + {id: 265, period_start: '2017-05-14', period_end: '2017-05-24'} + ] + + let ttdates2 = [] + + let newModalProps2 = { + active: true, + begin: { + day: '03', + month: '05', + year: '2017' + }, + end: { + day: '09', + month: '05', + year: '2017' + }, + index: false, + error: "Les périodes ne peuvent pas se chevaucher" + } + + expect( + modalReducer(state2, { + type: 'VALIDATE_PERIOD_FORM', + modalProps : modProps2, + timeTablePeriods: ttperiods2, + timetableInDates: ttdates2, + error: "Les périodes ne peuvent pas se chevaucher" + }) + ).toEqual(Object.assign({}, state2, {modalProps: newModalProps2})) + }) + + it('should handle VALIDATE_PERIOD_FORM and throw error if period overlaps date', () => { + let state3 = { + confirmModal: {}, + modalProps: { + active: false, + begin: { + day: '01', + month: '08', + year: '2017' + }, + end: { + day: '09', + month: '08', + year: '2017' + }, + index: false, + error: '' + }, + type: '' + } + let modProps3 = { + active: true, + begin: { + day: '01', + month: '08', + year: '2017' + }, + end: { + day: '09', + month: '08', + year: '2017' + }, + index: false, + error: '' + } + + let ttperiods3 = [] + let ttdates3 = [{date: "2017-08-04", include_date: true}] + let metas = { + day_types: [true,true,true,true,true,true,true] + } + + let newModalProps3 = { + active: true, + begin: { + day: '01', + month: '08', + year: '2017' + }, + end: { + day: '09', + month: '08', + year: '2017' + }, + index: false, + error: "Une période ne peut chevaucher une date dans un calendrier" + } + + expect( + modalReducer(state3, { + type: 'VALIDATE_PERIOD_FORM', + modalProps : modProps3, + timeTablePeriods: ttperiods3, + timetableInDates: ttdates3, + metas: metas, + error: "Une période ne peut chevaucher une date dans un calendrier" + }) + ).toEqual(Object.assign({}, state3, {modalProps: newModalProps3})) + }) +}) diff --git a/spec/javascript/time_table/reducers/pagination_spec.js b/spec/javascript/time_table/reducers/pagination_spec.js new file mode 100644 index 000000000..23135d98b --- /dev/null +++ b/spec/javascript/time_table/reducers/pagination_spec.js @@ -0,0 +1,139 @@ +import paginationReducer from '../../../app/javascript/time_tables/reducers/pagination' + +const dispatch = function(){} + +let pagination = { + currentPage: "1982-02-15", + periode_range: ["1982-02-01", "1982-02-02", "1982-02-03"], + stateChanged: false +} + +let state = {} + +describe('pagination reducer', () => { + beforeEach(() => { + state = { + currentPage: "", + periode_range: [], + stateChanged: false + } + }) + + it('should return the initial state', () => { + expect( + paginationReducer(undefined, {}) + ).toEqual({}) + }) + + it('should handle RECEIVE_TIME_TABLES', () => { + let json = [{ + current_periode_range: "1982-02-15", + periode_range: ["1982-02-01", "1982-02-02", "1982-02-03"] + }] + expect( + paginationReducer(state, { + type: 'RECEIVE_TIME_TABLES', + json + }) + ).toEqual(Object.assign({}, state, {currentPage: json.current_periode_range, periode_range: json.periode_range})) + }) + + it('should handle GO_TO_PREVIOUS_PAGE', () => { + let nextPage = nextPage ? 1 : -1 + let newPage = pagination.periode_range[pagination.periode_range.indexOf(pagination.currentPage) + nextPage] + + expect( + paginationReducer(state, { + type: 'GO_TO_PREVIOUS_PAGE', + dispatch, + pagination, + nextPage: false + }) + ).toEqual(Object.assign({}, state, {currentPage : newPage, stateChanged: false})) + }) + it('should handle GO_TO_NEXT_PAGE', () => { + let nextPage = nextPage ? 1 : -1 + let newPage = pagination.periode_range[pagination.periode_range.indexOf(pagination.currentPage) + nextPage] + + expect( + paginationReducer(state, { + type: 'GO_TO_NEXT_PAGE', + dispatch, + pagination, + nextPage: false + }) + ).toEqual(Object.assign({}, state, {currentPage : newPage, stateChanged: false})) + }) + + it('should handle CHANGE_PAGE', () => { + let page = "1982-02-15" + expect( + paginationReducer(state, { + type: 'CHANGE_PAGE', + dispatch, + page + }) + ).toEqual(Object.assign({}, state, {currentPage : page, stateChanged: false})) + }) + + it('should handle ADD_INCLUDED_DATE', () => { + expect( + paginationReducer(state, { + type: 'ADD_INCLUDED_DATE' + }) + ).toEqual(Object.assign({}, state, {stateChanged: true})) + }) + + it('should handle REMOVE_INCLUDED_DATE', () => { + expect( + paginationReducer(state, { + type: 'REMOVE_INCLUDED_DATE' + }) + ).toEqual(Object.assign({}, state, {stateChanged: true})) + }) + + it('should handle ADD_EXCLUDED_DATE', () => { + expect( + paginationReducer(state, { + type: 'ADD_EXCLUDED_DATE' + }) + ).toEqual(Object.assign({}, state, {stateChanged: true})) + }) + + it('should handle REMOVE_EXCLUDED_DATE', () => { + expect( + paginationReducer(state, { + type: 'REMOVE_EXCLUDED_DATE' + }) + ).toEqual(Object.assign({}, state, {stateChanged: true})) + }) + + it('should handle DELETE_PERIOD', () => { + expect( + paginationReducer(state, { + type: 'DELETE_PERIOD' + }) + ).toEqual(Object.assign({}, state, {stateChanged: true})) + }) + it('should handle VALIDATE_PERIOD_FORM', () => { + expect( + paginationReducer(state, { + type: 'VALIDATE_PERIOD_FORM' + }) + ).toEqual(Object.assign({}, state, {stateChanged: true})) + }) + it('should handle UPDATE_COMMENT', () => { + expect( + paginationReducer(state, { + type: 'UPDATE_COMMENT' + }) + ).toEqual(Object.assign({}, state, {stateChanged: true})) + }) + it('should handle UPDATE_COLOR', () => { + expect( + paginationReducer(state, { + type: 'UPDATE_COLOR' + }) + ).toEqual(Object.assign({}, state, {stateChanged: true})) + }) +}) diff --git a/spec/javascript/time_table/reducers/status_spec.js b/spec/javascript/time_table/reducers/status_spec.js new file mode 100644 index 000000000..15b733703 --- /dev/null +++ b/spec/javascript/time_table/reducers/status_spec.js @@ -0,0 +1,50 @@ +import statusReducer from '../../../app/javascript/time_tables/reducers/status' + +let state = {} + +describe('status reducer', () => { + beforeEach(() => { + state = { + actionType: "edit", + fetchSuccess: true, + isFetching: false + } + }) + + it('should return the initial state', () => { + expect( + statusReducer(undefined, {}) + ).toEqual({}) + }) + + it('should handle UNAVAILABLE_SERVER', () => { + expect( + statusReducer(state, { + type: 'UNAVAILABLE_SERVER' + }) + ).toEqual(Object.assign({}, state, {fetchSuccess: false})) + }) + + it('should handle FETCH_API', () => { + expect( + statusReducer(state, { + type: 'FETCH_API' + }) + ).toEqual(Object.assign({}, state, {isFetching: true})) + }) + + it('should handle RECEIVE_TIME_TABLES', () => { + expect( + statusReducer(state, { + type: 'RECEIVE_TIME_TABLES' + }) + ).toEqual(Object.assign({}, state, {fetchSuccess: true, isFetching: false})) + }) + it('should handle RECEIVE_MONTH', () => { + expect( + statusReducer(state, { + type: 'RECEIVE_MONTH' + }) + ).toEqual(Object.assign({}, state, {fetchSuccess: true, isFetching: false})) + }) +}) diff --git a/spec/javascript/time_table/reducers/timetable_spec.js b/spec/javascript/time_table/reducers/timetable_spec.js new file mode 100644 index 000000000..f5e5c0a36 --- /dev/null +++ b/spec/javascript/time_table/reducers/timetable_spec.js @@ -0,0 +1,336 @@ +require('whatwg-fetch') +import timetableReducer from '../../../app/javascript/time_tables/reducers/timetable' + +let state = {} +const dispatch = function(){} +let arrDayTypes = [true, true, true, true, true, true, true] +let strDayTypes = 'LuMaMeJeVeSaDi' +let time_table_periods = [{"id":261,"period_start":"2017-02-23","period_end":"2017-03-05"},{"id":262,"period_start":"2017-03-15","period_end":"2017-03-25"},{"id":263,"period_start":"2017-04-04","period_end":"2017-04-14"},{"id":264,"period_start":"2017-04-24","period_end":"2017-05-04"},{"id":265,"period_start":"2017-05-14","period_end":"2017-05-24"}] +let time_table_dates = [] +let current_periode_range = "2017-05-01" +let periode_range = ["2014-05-01","2014-06-01","2014-07-01","2014-08-01","2014-09-01","2014-10-01","2014-11-01","2014-12-01","2015-01-01","2015-02-01","2015-03-01","2015-04-01","2015-05-01","2015-06-01","2015-07-01","2015-08-01","2015-09-01","2015-10-01","2015-11-01","2015-12-01","2016-01-01","2016-02-01","2016-03-01","2016-04-01","2016-05-01","2016-06-01","2016-07-01","2016-08-01","2016-09-01","2016-10-01","2016-11-01","2016-12-01","2017-01-01","2017-02-01","2017-03-01","2017-04-01","2017-05-01","2017-06-01","2017-07-01","2017-08-01","2017-09-01","2017-10-01","2017-11-01","2017-12-01","2018-01-01","2018-02-01","2018-03-01","2018-04-01","2018-05-01","2018-06-01","2018-07-01","2018-08-01","2018-09-01","2018-10-01","2018-11-01","2018-12-01","2019-01-01","2019-02-01","2019-03-01","2019-04-01","2019-05-01","2019-06-01","2019-07-01","2019-08-01","2019-09-01","2019-10-01","2019-11-01","2019-12-01","2020-01-01","2020-02-01","2020-03-01","2020-04-01","2020-05-01"] +let current_month = [{"day":"lundi","date":"2017-05-01","wday":1,"wnumber":"18","mday":1,"include_date":false,"excluded_date":false},{"day":"mardi","date":"2017-05-02","wday":2,"wnumber":"18","mday":2,"include_date":false,"excluded_date":false},{"day":"mercredi","date":"2017-05-03","wday":3,"wnumber":"18","mday":3,"include_date":false,"excluded_date":false},{"day":"jeudi","date":"2017-05-04","wday":4,"wnumber":"18","mday":4,"include_date":false,"excluded_date":false},{"day":"vendredi","date":"2017-05-05","wday":5,"wnumber":"18","mday":5,"include_date":false,"excluded_date":false},{"day":"samedi","date":"2017-05-06","wday":6,"wnumber":"18","mday":6,"include_date":false,"excluded_date":false},{"day":"dimanche","date":"2017-05-07","wday":0,"wnumber":"18","mday":7,"include_date":false,"excluded_date":false},{"day":"lundi","date":"2017-05-08","wday":1,"wnumber":"19","mday":8,"include_date":false,"excluded_date":false},{"day":"mardi","date":"2017-05-09","wday":2,"wnumber":"19","mday":9,"include_date":false,"excluded_date":false},{"day":"mercredi","date":"2017-05-10","wday":3,"wnumber":"19","mday":10,"include_date":false,"excluded_date":false},{"day":"jeudi","date":"2017-05-11","wday":4,"wnumber":"19","mday":11,"include_date":false,"excluded_date":false},{"day":"vendredi","date":"2017-05-12","wday":5,"wnumber":"19","mday":12,"include_date":false,"excluded_date":false},{"day":"samedi","date":"2017-05-13","wday":6,"wnumber":"19","mday":13,"include_date":false,"excluded_date":false},{"day":"dimanche","date":"2017-05-14","wday":0,"wnumber":"19","mday":14,"include_date":false,"excluded_date":false},{"day":"lundi","date":"2017-05-15","wday":1,"wnumber":"20","mday":15,"include_date":false,"excluded_date":false},{"day":"mardi","date":"2017-05-16","wday":2,"wnumber":"20","mday":16,"include_date":false,"excluded_date":false},{"day":"mercredi","date":"2017-05-17","wday":3,"wnumber":"20","mday":17,"include_date":false,"excluded_date":false},{"day":"jeudi","date":"2017-05-18","wday":4,"wnumber":"20","mday":18,"include_date":false,"excluded_date":false},{"day":"vendredi","date":"2017-05-19","wday":5,"wnumber":"20","mday":19,"include_date":false,"excluded_date":false},{"day":"samedi","date":"2017-05-20","wday":6,"wnumber":"20","mday":20,"include_date":false,"excluded_date":false},{"day":"dimanche","date":"2017-05-21","wday":0,"wnumber":"20","mday":21,"include_date":false,"excluded_date":false},{"day":"lundi","date":"2017-05-22","wday":1,"wnumber":"21","mday":22,"include_date":false,"excluded_date":false},{"day":"mardi","date":"2017-05-23","wday":2,"wnumber":"21","mday":23,"include_date":false,"excluded_date":false},{"day":"mercredi","date":"2017-05-24","wday":3,"wnumber":"21","mday":24,"include_date":false,"excluded_date":false},{"day":"jeudi","date":"2017-05-25","wday":4,"wnumber":"21","mday":25,"include_date":false,"excluded_date":false},{"day":"vendredi","date":"2017-05-26","wday":5,"wnumber":"21","mday":26,"include_date":false,"excluded_date":false},{"day":"samedi","date":"2017-05-27","wday":6,"wnumber":"21","mday":27,"include_date":false,"excluded_date":false},{"day":"dimanche","date":"2017-05-28","wday":0,"wnumber":"21","mday":28,"include_date":false,"excluded_date":false},{"day":"lundi","date":"2017-05-29","wday":1,"wnumber":"22","mday":29,"include_date":false,"excluded_date":false},{"day":"mardi","date":"2017-05-30","wday":2,"wnumber":"22","mday":30,"include_date":false,"excluded_date":false},{"day":"mercredi","date":"2017-05-31","wday":3,"wnumber":"22","mday":31,"include_date":false,"excluded_date":false}] + +let newCurrentMonth = [{"day":"lundi","date":"2017-05-01","wday":1,"wnumber":"18","mday":1,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"mardi","date":"2017-05-02","wday":2,"wnumber":"18","mday":2,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"mercredi","date":"2017-05-03","wday":3,"wnumber":"18","mday":3,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"jeudi","date":"2017-05-04","wday":4,"wnumber":"18","mday":4,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"vendredi","date":"2017-05-05","wday":5,"wnumber":"18","mday":5,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"samedi","date":"2017-05-06","wday":6,"wnumber":"18","mday":6,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"dimanche","date":"2017-05-07","wday":0,"wnumber":"18","mday":7,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"lundi","date":"2017-05-08","wday":1,"wnumber":"19","mday":8,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"mardi","date":"2017-05-09","wday":2,"wnumber":"19","mday":9,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"mercredi","date":"2017-05-10","wday":3,"wnumber":"19","mday":10,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"jeudi","date":"2017-05-11","wday":4,"wnumber":"19","mday":11,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"vendredi","date":"2017-05-12","wday":5,"wnumber":"19","mday":12,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"samedi","date":"2017-05-13","wday":6,"wnumber":"19","mday":13,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"dimanche","date":"2017-05-14","wday":0,"wnumber":"19","mday":14,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"lundi","date":"2017-05-15","wday":1,"wnumber":"20","mday":15,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"mardi","date":"2017-05-16","wday":2,"wnumber":"20","mday":16,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"mercredi","date":"2017-05-17","wday":3,"wnumber":"20","mday":17,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"jeudi","date":"2017-05-18","wday":4,"wnumber":"20","mday":18,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"vendredi","date":"2017-05-19","wday":5,"wnumber":"20","mday":19,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"samedi","date":"2017-05-20","wday":6,"wnumber":"20","mday":20,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"dimanche","date":"2017-05-21","wday":0,"wnumber":"20","mday":21,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"lundi","date":"2017-05-22","wday":1,"wnumber":"21","mday":22,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"mardi","date":"2017-05-23","wday":2,"wnumber":"21","mday":23,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"mercredi","date":"2017-05-24","wday":3,"wnumber":"21","mday":24,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"jeudi","date":"2017-05-25","wday":4,"wnumber":"21","mday":25,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"vendredi","date":"2017-05-26","wday":5,"wnumber":"21","mday":26,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"samedi","date":"2017-05-27","wday":6,"wnumber":"21","mday":27,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"dimanche","date":"2017-05-28","wday":0,"wnumber":"21","mday":28,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"lundi","date":"2017-05-29","wday":1,"wnumber":"22","mday":29,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"mardi","date":"2017-05-30","wday":2,"wnumber":"22","mday":30,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"mercredi","date":"2017-05-31","wday":3,"wnumber":"22","mday":31,"include_date":false,"excluded_date":false,"in_periods":false}] + +let json = { + current_month: current_month, + current_periode_range: current_periode_range, + periode_range: periode_range, + time_table_periods: time_table_periods, + day_types: strDayTypes, + time_table_dates: time_table_dates +} + +describe('timetable reducer with empty state', () => { + beforeEach(() => { + state = { + current_month: [], + current_periode_range: "", + periode_range: [], + time_table_periods: [], + time_table_dates: [] + } + }) + + it('should return the initial state', () => { + expect( + timetableReducer(undefined, {}) + ).toEqual({}) + }) + + it('should handle RECEIVE_TIME_TABLES', () => { + let newState = { + current_month: newCurrentMonth, + current_periode_range: current_periode_range, + periode_range: periode_range, + time_table_periods: time_table_periods, + time_table_dates: [] + } + expect( + timetableReducer(state, { + type: 'RECEIVE_TIME_TABLES', + json + }) + ).toEqual(newState) + }) +}) + +describe('timetable reducer with filled state', () => { + beforeEach(() => { + state = { + current_month: newCurrentMonth, + current_periode_range: current_periode_range, + periode_range: periode_range, + time_table_periods: time_table_periods, + time_table_dates: time_table_dates + } + }) + + it('should handle RECEIVE_MONTH', () => { + expect( + timetableReducer(state, { + type: 'RECEIVE_MONTH', + json: { + days: current_month, + day_types: strDayTypes + } + }) + ).toEqual(state) + }) + + + it('should handle GO_TO_PREVIOUS_PAGE', () => { + let pagination = { + periode_range: periode_range, + currentPage: current_periode_range + } + expect( + timetableReducer(state, { + type: 'GO_TO_PREVIOUS_PAGE', + dispatch, + pagination, + nextPage: false + }) + ).toEqual(Object.assign({}, state, {current_periode_range: '2017-04-01'})) + }) + + it('should handle GO_TO_NEXT_PAGE', () => { + let pagination = { + periode_range: periode_range, + currentPage: current_periode_range + } + expect( + timetableReducer(state, { + type: 'GO_TO_NEXT_PAGE', + dispatch, + pagination, + nextPage: true + }) + ).toEqual(Object.assign({}, state, {current_periode_range: '2017-06-01'})) + }) + + it('should handle CHANGE_PAGE', () => { + const actions = { + fetchTimeTables: function(){} + } + let newPage = '2017-05-01' + expect( + timetableReducer(state, { + type: 'CHANGE_PAGE', + dispatch, + page: newPage + }) + ).toEqual(Object.assign({}, state, {current_periode_range: newPage})) + }) + + it('should handle DELETE_PERIOD and remove excluded days that were in period', () => { + state.time_table_dates.push({date: "2017-05-01", in_out: false}) + state.current_month[0].excluded_date = true + state.time_table_periods[3].deleted = true + + let begin = new Date(state.time_table_periods[3].period_start) + let end = new Date(state.time_table_periods[3].period_end) + + let newState = Object.assign({}, state, { + time_table_dates: [], + current_month: state.current_month.map((d, i) => { + if (new Date(d.date) >= begin && new Date(d.date) <= end) { + d.excluded_date = false + d.in_periods = false + } + return d + }) + }) + expect( + timetableReducer(state, { + type: 'DELETE_PERIOD', + index: 3, + dayTypes: arrDayTypes + }) + ).toEqual(newState) + }) + + it('should handle ADD_INCLUDED_DATE', () => { + let newDates = state.time_table_dates.concat({date: "2017-05-05", in_out: true}) + + let newCM = newCurrentMonth.map((d,i) => { + if (i == 4) d.include_date = true + return d + }) + + let newState = Object.assign({}, state, {time_table_dates: newDates, current_month: newCM}) + + expect( + timetableReducer(state, { + type: 'ADD_INCLUDED_DATE', + index: 4, + dayTypes: arrDayTypes, + date: "2017-05-05" + }) + ).toEqual(newState) + }) + + it('should handle REMOVE_INCLUDED_DATE', () => { + state.current_month[4].include_date = true + state.time_table_dates.push({date: "2017-05-05", in_out: true}) + + let newCM = newCurrentMonth.map((d,i) => { + if (i == 4) d.include_date = false + return d + }) + + let newDates = state.time_table_dates.filter(d => d.date != "2017-05-05" && d.in_out != true ) + let newState = Object.assign({}, state, {time_table_dates: newDates, current_month: newCM}) + expect( + timetableReducer(state, { + type: 'REMOVE_INCLUDED_DATE', + index: 4, + dayTypes: arrDayTypes, + date: "2017-05-05" + }) + ).toEqual(newState) + }) + + it('should handle ADD_EXCLUDED_DATE', () => { + let newDates = state.time_table_dates.concat({date: "2017-05-01", in_out: false}) + + let newCM = newCurrentMonth.map((d,i) => { + if (i == 0){ + d.include_date = false + d.excluded_date = true + } + return d + }) + + let newState = Object.assign({}, state, {time_table_dates: newDates, current_month: newCM}) + + expect( + timetableReducer(state, { + type: 'ADD_EXCLUDED_DATE', + index: 0, + dayTypes: arrDayTypes, + date: "2017-05-01" + }) + ).toEqual(newState) + }) + + it('should handle REMOVE_EXCLUDED_DATE', () => { + state.time_table_dates = [{date: "2017-05-01", in_out: false}] + state.current_month[0].excluded_date = false + let newState = Object.assign({}, state, {time_table_dates: []}) + expect( + timetableReducer(state, { + type: 'REMOVE_EXCLUDED_DATE', + index: 0, + dayTypes: arrDayTypes, + date: "2017-05-01" + }) + ).toEqual(newState) + }) + + it('should handle UPDATE_DAY_TYPES and remove out_day that are out of day types', () => { + state.time_table_dates = [{date: "2017-05-01", in_out: false}] + let newArrDayTypes = Array.from(arrDayTypes, (dt, i) => { + if (i == 1) dt = false + return dt + }) + expect( + timetableReducer(state, { + type: 'UPDATE_DAY_TYPES', + dayTypes: newArrDayTypes + }).time_table_dates + ).toEqual([]) + }) + + it('should handle UPDATE_DAY_TYPES and remove in_day that are in day types and in period', () => { + state.time_table_dates = [{ date: "2017-05-16", in_out: true }] + expect( + timetableReducer(state, { + type: 'UPDATE_DAY_TYPES', + dayTypes: arrDayTypes + }).time_table_dates + ).toEqual([]) + }) + + it('should handle VALIDATE_PERIOD_FORM and add period if modalProps index = false', () => { + let newPeriods = state.time_table_periods.concat({"period_start": "2018-05-15", "period_end": "2018-05-24"}) + let newState = Object.assign({}, state, {time_table_periods: newPeriods, time_table_dates: []}) + let modalProps = { + active: false, + begin: { + day: '15', + month: '05', + year: '2018' + }, + end: { + day: '24', + month: '05', + year: '2018' + }, + error: '', + index: false + } + expect( + timetableReducer(state, { + type: 'VALIDATE_PERIOD_FORM', + modalProps: modalProps, + timeTablePeriods: state.time_table_periods, + metas: { + day_types: arrDayTypes + }, + timetableInDates: state.time_table_dates.filter(d => d.in_out == true), + error: modalProps.error + }) + ).toEqual(newState) + }) + + it('should handle VALIDATE_PERIOD_FORM and update period if modalProps index != false', () => { + + let begin = new Date(state.time_table_periods[0].period_start) + let end = new Date(state.time_table_periods[0].period_end) + let newCM = newCurrentMonth.map((d) => { + if (new Date (d.date) >= begin && new Date(d.date) <= end) { + d.in_periods = false + d.excluded_date = false + } + return d + }) + + let newPeriods = state.time_table_periods.map( (p,i) => { + if (i == 0) { + p.period_start = "2018-05-15" + p.period_end = "2018-05-24" + } + return p + }) + let newState = Object.assign({}, state, {time_table_periods: newPeriods}) + + let modalProps = { + active: false, + begin: { + day: '15', + month: '05', + year: '2018' + }, + end: { + day: '24', + month: '05', + year: '2018' + }, + error: '', + index: 0 + } + expect( + timetableReducer(state, { + type: 'VALIDATE_PERIOD_FORM', + modalProps: modalProps, + timeTablePeriods: state.time_table_periods, + metas: { + day_types: arrDayTypes + }, + timetableInDates: state.time_table_dates.filter(d => d.in_out == true) + }) + ).toEqual(newState) + }) +}) diff --git a/spec/javascript/vehicle_journeys/actions_spec.js b/spec/javascript/vehicle_journeys/actions_spec.js new file mode 100644 index 000000000..b847893d2 --- /dev/null +++ b/spec/javascript/vehicle_journeys/actions_spec.js @@ -0,0 +1,449 @@ +import actions from 'vehicle_journeys/actions/index' + +const dispatch = function(){} +const currentPage = 1 + +describe('when cannot fetch api', () => { + it('should create an action to toggle error', () => { + const expectedAction = { + type: 'UNAVAILABLE_SERVER', + } + expect(actions.unavailableServer()).toEqual(expectedAction) + }) +}) +describe('when fetching api', () => { + it('should create an action to fetch api', () => { + const expectedAction = { + type: 'FETCH_API', + } + expect(actions.fetchingApi()).toEqual(expectedAction) + }) +}) +describe('when receiveJourneyPatterns is triggered', () => { + it('should create an action to pass json to reducer', () => { + const json = undefined + const expectedAction = { + type: 'RECEIVE_VEHICLE_JOURNEYS', + json + } + expect(actions.receiveVehicleJourneys()).toEqual(expectedAction) + }) +}) +describe('when clicking on add button', () => { + it('should create an action to open a create modal', () => { + const expectedAction = { + type: 'CREATE_VEHICLEJOURNEY_MODAL', + } + expect(actions.openCreateModal()).toEqual(expectedAction) + }) +}) +describe('when using select2 to pick a journey pattern', () => { + it('should create an action to select a journey pattern inside modal', () => { + let selectedJP = { + id: 1, + object_id: 2, + name: 'test', + published_name: 'test', + stop_area_short_descriptions: ['test'] + } + const expectedAction = { + type: 'SELECT_JP_CREATE_MODAL', + selectedItem:{ + id: selectedJP.id, + objectid: selectedJP.object_id, + name: selectedJP.name, + published_name: selectedJP.published_name, + stop_areas: selectedJP.stop_area_short_descriptions + } + } + expect(actions.selectJPCreateModal(selectedJP)).toEqual(expectedAction) + }) +}) +describe('when clicking on validate button inside create modal', () => { + it('should create an action to create a new vehicle journey', () => { + const data = {} + const selectedJourneyPattern = {} + const selectedCompany = {} + const stopPointsList = [] + const expectedAction = { + type: 'ADD_VEHICLEJOURNEY', + data, + selectedJourneyPattern, + stopPointsList, + selectedCompany + } + expect(actions.addVehicleJourney(data, selectedJourneyPattern, stopPointsList, selectedCompany)).toEqual(expectedAction) + }) +}) +describe('when previous navigation button is clicked', () => { + it('should create an action to go to previous page', () => { + const nextPage = false + const queryString = '' + const pagination = { + totalCount: 25, + perPage: 12, + page:1 + } + const expectedAction = { + type: 'GO_TO_PREVIOUS_PAGE', + dispatch, + pagination, + nextPage, + queryString + } + expect(actions.goToPreviousPage(dispatch, pagination, queryString)).toEqual(expectedAction) + }) +}) +describe('when next navigation button is clicked', () => { + it('should create an action to go to next page', () => { + const queryString = '' + const nextPage = true + const pagination = { + totalCount: 25, + perPage: 12, + page:1 + } + const expectedAction = { + type: 'GO_TO_NEXT_PAGE', + dispatch, + pagination, + nextPage, + queryString + } + expect(actions.goToNextPage(dispatch, pagination, queryString)).toEqual(expectedAction) + }) +}) +describe('when checking a vehicleJourney', () => { + it('should create an action to select vj', () => { + const index = 1 + const expectedAction = { + type: 'SELECT_VEHICLEJOURNEY', + index + } + expect(actions.selectVehicleJourney(index)).toEqual(expectedAction) + }) +}) +describe('when clicking on cancel selection button', () => { + it('should create an action to cancel whole selection', () => { + const index = 1 + const expectedAction = { + type: 'CANCEL_SELECTION' + } + expect(actions.cancelSelection()).toEqual(expectedAction) + }) +}) +describe('when clicking on delete button', () => { + it('should create an action to delete vj', () => { + const expectedAction = { + type: 'DELETE_VEHICLEJOURNEYS', + } + expect(actions.deleteVehicleJourneys()).toEqual(expectedAction) + }) +}) +describe('when toggling arrivals', () => { + it('should create an action to toggleArrivals', () => { + const expectedAction = { + type: 'TOGGLE_ARRIVALS', + } + expect(actions.toggleArrivals()).toEqual(expectedAction) + }) +}) +describe('when updating vjas time', () => { + it('should create an action to update time', () => { + const val = 33, subIndex = 0, index = 0, timeUnit = 'minute', isDeparture = true, isArrivalsToggled = true + const expectedAction = { + type: 'UPDATE_TIME', + val, + subIndex, + index, + timeUnit, + isDeparture, + isArrivalsToggled + } + expect(actions.updateTime(val, subIndex, index, timeUnit, isDeparture, isArrivalsToggled)).toEqual(expectedAction) + }) +}) +describe('when clicking on validate button inside shifting modal', () => { + it('should create an action to shift a vehiclejourney schedule', () => { + const addtionalTime = 0 + const expectedAction = { + type: 'SHIFT_VEHICLEJOURNEY', + addtionalTime + } + expect(actions.shiftVehicleJourney(addtionalTime)).toEqual(expectedAction) + }) +}) +describe('when clicking on validate button inside editing modal', () => { + it('should create an action to update a vehiclejourney', () => { + const data = {} + const selectedCompany = {} + const expectedAction = { + type: 'EDIT_VEHICLEJOURNEY', + data, + selectedCompany + } + expect(actions.editVehicleJourney(data, selectedCompany)).toEqual(expectedAction) + }) +}) +describe('when clicking on validate button inside duplicating modal', () => { + it('should create an action to duplicate a vehiclejourney schedule', () => { + const addtionalTime = 0 + const departureDelta = 0 + const duplicateNumber = 1 + const expectedAction = { + type: 'DUPLICATE_VEHICLEJOURNEY', + addtionalTime, + duplicateNumber, + departureDelta + } + expect(actions.duplicateVehicleJourney(addtionalTime, duplicateNumber, departureDelta)).toEqual(expectedAction) + }) +}) +describe('when clicking on edit notes modal', () => { + it('should create an action to open footnotes modal', () => { + const vehicleJourney = {} + const expectedAction = { + type: 'EDIT_NOTES_VEHICLEJOURNEY_MODAL', + vehicleJourney + } + expect(actions.openNotesEditModal(vehicleJourney)).toEqual(expectedAction) + }) +}) +describe('when clicking on a footnote button inside footnote modal', () => { + it('should create an action to toggle this footnote', () => { + const footnote = {}, isShown = true + const expectedAction = { + type: 'TOGGLE_FOOTNOTE_MODAL', + footnote, + isShown + } + expect(actions.toggleFootnoteModal(footnote, isShown)).toEqual(expectedAction) + }) +}) +describe('when clicking on validate button inside footnote modal', () => { + it('should create an action to update vj footnotes', () => { + const footnotes = [] + const expectedAction = { + type: 'EDIT_VEHICLEJOURNEY_NOTES', + footnotes + } + expect(actions.editVehicleJourneyNotes(footnotes)).toEqual(expectedAction) + }) +}) +describe('when clicking on calendar button in toolbox', () => { + it('should create an action to open calendar modal', () => { + const vehicleJourneys = [] + const expectedAction = { + type: 'EDIT_CALENDARS_VEHICLEJOURNEY_MODAL', + vehicleJourneys + } + expect(actions.openCalendarsEditModal(vehicleJourneys)).toEqual(expectedAction) + }) +}) +describe('when clicking on delete button next to a timetable inside modal', () => { + it('should create an action to delete timetable from selected vehicle journeys', () => { + const timetable = {} + const expectedAction = { + type: 'DELETE_CALENDAR_MODAL', + timetable + } + expect(actions.deleteCalendarModal(timetable)).toEqual(expectedAction) + }) +}) +describe('when clicking on validate button inside calendars modal', () => { + it('should create an action to update vj calendars', () => { + const vehicleJourneys = [] + const timetables = [] + const expectedAction = { + type: 'EDIT_VEHICLEJOURNEYS_TIMETABLES', + vehicleJourneys, + timetables + } + expect(actions.editVehicleJourneyTimetables(vehicleJourneys, timetables)).toEqual(expectedAction) + }) +}) +describe('when clicking on add button inside calendars modal', () => { + it('should create an action to add the selected timetable to preselected vjs', () => { + const expectedAction = { + type: 'ADD_SELECTED_TIMETABLE', + } + expect(actions.addSelectedTimetable()).toEqual(expectedAction) + }) +}) +describe('when using select2 to pick a timetable', () => { + it('should create an action to select a timetable inside modal', () => { + let selectedTT = { + id: 1, + objectid: 2, + comment: 'test', + } + const expectedAction = { + type: 'SELECT_TT_CALENDAR_MODAL', + selectedItem:{ + id: selectedTT.id, + objectid: selectedTT.objectid, + comment: selectedTT.comment, + } + } + expect(actions.selectTTCalendarsModal(selectedTT)).toEqual(expectedAction) + }) +}) +describe('when clicking on reset button inside query filters', () => { + it('should create an action to reset the query filters', () => { + const expectedAction = { + type: 'BATCH', + payload: [ + {type: 'RESET_FILTERS'}, + {type: 'RESET_PAGINATION'}, + {type: 'QUERY_FILTER_VEHICLEJOURNEYS', dispatch: undefined}, + ] + } + expect(actions.resetFilters()).toEqual(expectedAction) + }) +}) +describe('when clicking on filter button inside query filters', () => { + it('should create an action to filter', () => { + const expectedAction = { + type: 'BATCH', + payload: [ + {type: 'CREATE_QUERY_STRING'}, + {type: 'RESET_PAGINATION'}, + {type: 'QUERY_FILTER_VEHICLEJOURNEYS', dispatch: undefined}, + ] + } + expect(actions.filterQuery()).toEqual(expectedAction) + }) +}) +describe('when clicking on checkbox to show vj without schedule', () => { + it('should create an action to toggle this filter', () => { + const expectedAction = { + type: 'TOGGLE_WITHOUT_SCHEDULE', + } + expect(actions.toggleWithoutSchedule()).toEqual(expectedAction) + }) +}) +describe('when setting new interval', () => { + const val = 1 + const unit = 'hour' + it('should create actions to update intervals in state', () => { + let expectedAction = { + type: 'UPDATE_START_TIME_FILTER', + val, + unit + } + expect(actions.updateStartTimeFilter(val, unit)).toEqual(expectedAction) + }) + it('should create actions to update intervals in state', () => { + let expectedAction = { + type: 'UPDATE_END_TIME_FILTER', + val, + unit + } + expect(actions.updateEndTimeFilter(val, unit)).toEqual(expectedAction) + }) +}) +describe('when using select2 to pick a timetable in the filters', () => { + it('should create an action to select a timetable as a filter', () => { + let selectedTT = { + id: 1, + objectid: 2, + comment: 'test', + } + const expectedAction = { + type: 'SELECT_TT_FILTER', + selectedItem:{ + id: selectedTT.id, + objectid: selectedTT.objectid, + comment: selectedTT.comment, + } + } + expect(actions.filterSelect2Timetable(selectedTT)).toEqual(expectedAction) + }) +}) +describe('when using select2 to pick a journeypattern in the filters', () => { + it('should create an action to select a journey pattern as a filter', () => { + let selectedJP = { + id: 1, + object_id: 2, + name: 'test', + published_name: 'test' + } + const expectedAction = { + type: 'SELECT_JP_FILTER', + selectedItem:{ + id: selectedJP.id, + objectid: selectedJP.object_id, + name: selectedJP.name, + published_name: selectedJP.published_name + } + } + expect(actions.filterSelect2JourneyPattern(selectedJP)).toEqual(expectedAction) + }) +}) +describe('when user clicked either on filter or reset button in filters', () => { + it('should create an action to reset pagination', () => { + const expectedAction = { + type: 'RESET_PAGINATION', + } + expect(actions.resetPagination()).toEqual(expectedAction) + }) +}) +describe('when user clicked either on filter or reset button in filters', () => { + it('should create an action to create a queryString with params filters', () => { + const expectedAction = { + type: 'CREATE_QUERY_STRING', + } + expect(actions.createQueryString()).toEqual(expectedAction) + }) +}) +describe('when submitting new vj', () => { + it('should create an action to update pagination totalCount', () => { + const diff = 1 + const expectedAction = { + type: 'UPDATE_TOTAL_COUNT', + diff + } + expect(actions.updateTotalCount(diff)).toEqual(expectedAction) + }) +}) +describe('when receiving vj', () => { + it('should create an action to show pagination totalCount', () => { + const total = 1 + const expectedAction = { + type: 'RECEIVE_TOTAL_COUNT', + total + } + expect(actions.receiveTotalCount(total)).toEqual(expectedAction) + }) +}) +describe('when using select2 to pick a company', () => { + it('should create an action to select a company inside modal', () => { + let selectedCompany = { + id: 1, + objectid: 2, + name: 'test', + } + const expectedAction = { + type: 'SELECT_CP_EDIT_MODAL', + selectedItem:{ + id: selectedCompany.id, + objectid: selectedCompany.objectid, + name: selectedCompany.name, + } + } + expect(actions.select2Company(selectedCompany)).toEqual(expectedAction) + }) +}) +describe('when using select2 to unselect a company', () => { + it('should create an action to unselect a company inside modal', () => { + let selectedCompany = { + id: 1, + objectid: 2, + name: 'test', + } + const expectedAction = { + type: 'UNSELECT_CP_EDIT_MODAL' + } + expect(actions.unselect2Company()).toEqual(expectedAction) + }) +}) diff --git a/spec/javascript/vehicle_journeys/reducers/filters_spec.js b/spec/javascript/vehicle_journeys/reducers/filters_spec.js new file mode 100644 index 000000000..43f03ab30 --- /dev/null +++ b/spec/javascript/vehicle_journeys/reducers/filters_spec.js @@ -0,0 +1,165 @@ +import statusReducer from '../../../app/javascript/vehicle_journeys/reducers/filters' + +let state = {} + +describe('filters reducer', () => { + const cleanInterval = { + start:{ + hour: '00', + minute: '00' + }, + end:{ + hour: '23', + minute: '59' + } + } + beforeEach(() => { + state = { + toggleArrivals: false, + query: { + interval: { + start:{ + hour: '11', + minute: '11' + }, + end:{ + hour: '22', + minute: '22' + } + }, + journeyPattern: {}, + vehicleJourney: {}, + timetable: {}, + withoutSchedule: true, + withoutTimeTable: true + }, + queryString: '' + } + }) + + it('should return the initial state', () => { + expect( + statusReducer(undefined, {}) + ).toEqual({}) + }) + + it('should handle TOGGLE_ARRIVALS', () => { + expect( + statusReducer(state, { + type: 'TOGGLE_ARRIVALS' + }) + ).toEqual(Object.assign({}, state, {toggleArrivals: true})) + }) + + it('should handle RESET_FILTERS', () => { + let cleanQuery = JSON.parse(JSON.stringify(state.query)) + cleanQuery.interval = cleanInterval + expect( + statusReducer(state, { + type: 'RESET_FILTERS' + }) + ).toEqual(Object.assign({}, state, {query: cleanQuery})) + }) + + it('should handle TOGGLE_WITHOUT_SCHEDULE', () => { + let rslt = JSON.parse(JSON.stringify(state.query)) + rslt.withoutSchedule = false + expect( + statusReducer(state, { + type: 'TOGGLE_WITHOUT_SCHEDULE' + }) + ).toEqual(Object.assign({}, state, {query: rslt})) + }) + + it('should handle UPDATE_START_TIME_FILTER', () => { + let val = 12 + let unit = 'minute' + let rslt = JSON.parse(JSON.stringify(state.query)) + rslt.interval.start.minute = String(val) + expect( + statusReducer(state, { + type: 'UPDATE_START_TIME_FILTER', + val, + unit + }) + ).toEqual(Object.assign({}, state, {query: rslt})) + }) + + it('should handle UPDATE_START_TIME_FILTER and not make any update', () => { + let val = 23 + let unit = 'hour' + expect( + statusReducer(state, { + type: 'UPDATE_START_TIME_FILTER', + val, + unit + }) + ).toEqual(state) + }) + + it('should handle UPDATE_END_TIME_FILTER', () => { + let val = 12 + let unit = 'minute' + let rslt = JSON.parse(JSON.stringify(state.query)) + rslt.interval.end.minute = String(val) + expect( + statusReducer(state, { + type: 'UPDATE_END_TIME_FILTER', + val, + unit + }) + ).toEqual(Object.assign({}, state, {query: rslt})) + }) + + it('should handle UPDATE_END_TIME_FILTER and not make any update', () => { + let val = 1 + let unit = 'hour' + expect( + statusReducer(state, { + type: 'UPDATE_END_TIME_FILTER', + val, + unit + }) + ).toEqual(state) + }) + + it('should handle SELECT_TT_FILTER', () => { + let newTimetable = {timetable : {id: 1}} + let newQuery = Object.assign({}, state.query, newTimetable) + expect( + statusReducer(state, { + type: 'SELECT_TT_FILTER', + selectedItem: {id: 1} + }) + ).toEqual(Object.assign({}, state, {query: newQuery})) + }) + + it('should handle SELECT_JP_FILTER', () => { + let newJourneyPattern = {journeyPattern : {id: 1}} + let newQuery = Object.assign({}, state.query, newJourneyPattern) + expect( + statusReducer(state, { + type: 'SELECT_JP_FILTER', + selectedItem: {id: 1} + }) + ).toEqual(Object.assign({}, state, {query: newQuery})) + }) + + it('should handle CREATE_QUERY_STRING', () => { + let strResult = [ + "q%5Bjourney_pattern_id_eq%5D=undefined", + "&q%5Bobjectid_cont%5D=undefined", + "&q%5Btime_tables_id_eq%5D=undefined", + "&q%5Bvehicle_journey_at_stops_departure_time_gteq%5D=11%3A11", + "&q%5Bvehicle_journey_at_stops_departure_time_lteq%5D=22%3A22", + "&q%5Bvehicle_journey_without_departure_time%5D=true", + "&q%5Bvehicle_journey_without_time_table%5D=true" + ].join('') + + expect( + statusReducer(state, { + type: 'CREATE_QUERY_STRING', + }) + ).toEqual(Object.assign({}, state, {queryString: strResult})) + }) +}) diff --git a/spec/javascript/vehicle_journeys/reducers/modal_spec.js b/spec/javascript/vehicle_journeys/reducers/modal_spec.js new file mode 100644 index 000000000..210ac9e78 --- /dev/null +++ b/spec/javascript/vehicle_journeys/reducers/modal_spec.js @@ -0,0 +1,179 @@ +import modalReducer from '../../app/javascript/vehicle_journeys/reducers/modal' + +let state = {} + +const cb = function(){} + +describe('modal reducer', () => { + beforeEach(() => { + state = { + type: '', + modalProps: {}, + confirmModal: {} + } + }) + + it('should return the initial state', () => { + expect( + modalReducer(undefined, {}) + ).toEqual({}) + }) + + it('should handle OPEN_CONFIRM_MODAL', () => { + let newState = Object.assign({}, state, { + type: 'confirm', + confirmModal: { + callback: cb + } + }) + expect( + modalReducer(state, { + type: 'OPEN_CONFIRM_MODAL', + callback: cb + }) + ).toEqual(newState) + }) + + it('should handle CREATE_VEHICLEJOURNEY_MODAL', () => { + expect( + modalReducer(state, { + type: 'CREATE_VEHICLEJOURNEY_MODAL' + }) + ).toEqual(Object.assign({}, state, { type: 'create' })) + }) + + it('should handle SELECT_JP_CREATE_MODAL', () => { + let newModalProps = {selectedJPModal : {id: 1}} + expect( + modalReducer(state, { + type: 'SELECT_JP_CREATE_MODAL', + selectedItem: {id: 1} + }) + ).toEqual(Object.assign({}, state, {modalProps: newModalProps})) + }) + + it('should handle CLOSE_MODAL', () => { + expect( + modalReducer(state, { + type: 'CLOSE_MODAL' + }) + ).toEqual(state) + }) + + it('should handle EDIT_NOTES_VEHICLEJOURNEY_MODAL', () => { + let vehicleJourney = {} + let modalPropsResult = { + vehicleJourney: {} + } + expect( + modalReducer(state, { + type: 'EDIT_NOTES_VEHICLEJOURNEY_MODAL', + vehicleJourney + }) + ).toEqual(Object.assign({}, state, {type: 'notes_edit', modalProps: modalPropsResult})) + }) + + it('should handle TOGGLE_FOOTNOTE_MODAL', () => { + state.modalProps = {vehicleJourney : {footnotes: [{}, {}]}} + let footnote = {} + let newState = { + // for the sake of the test, no need to specify the type + type: '', + modalProps:{vehicleJourney: {footnotes: [{},{},{}]}}, + confirmModal: {} + } + expect( + modalReducer(state, { + type: 'TOGGLE_FOOTNOTE_MODAL', + footnote, + isShown: true + }) + ).toEqual(newState) + }) + + it('should handle EDIT_CALENDARS_VEHICLEJOURNEY_MODAL', () => { + let vehicleJourneys = [] + let modalPropsResult = { + vehicleJourneys: [], + timetables: [] + } + expect( + modalReducer(state, { + type: 'EDIT_CALENDARS_VEHICLEJOURNEY_MODAL', + vehicleJourneys + }) + ).toEqual(Object.assign({}, state, {type: 'calendars_edit', modalProps: modalPropsResult})) + }) + + it('should handle SELECT_TT_CALENDAR_MODAL', () => { + let newModalProps = {selectedTimetable : {id: 1}} + expect( + modalReducer(state, { + type: 'SELECT_TT_CALENDAR_MODAL', + selectedItem: {id: 1} + }) + ).toEqual(Object.assign({}, state, {modalProps: newModalProps})) + }) + + it('should handle ADD_SELECTED_TIMETABLE', () => { + let fakeTimetables = [{'test': 'test'}, {'test 2': 'test 2'}, {'add': 'add'}] + let newTimeTables = [{'test': 'test'}, {'test 2': 'test 2'}, {'add': 'add'}] + let fakeVehicleJourneys= [{time_tables: fakeTimetables}, {time_tables: newTimeTables}] + state.modalProps.vehicleJourneys = fakeVehicleJourneys + state.modalProps.timetables = fakeTimetables + state.modalProps.selectedTimetable = {'add': 'add'} + let newState = { + type: '', + modalProps:{ + vehicleJourneys: [{time_tables: newTimeTables},{time_tables: newTimeTables}], + timetables: [{'test': 'test'},{'test 2': 'test 2'},{'add': 'add'}], + selectedTimetable: {'add': 'add'} + }, + confirmModal: {} + } + expect( + modalReducer(state, { + type: 'ADD_SELECTED_TIMETABLE', + }) + ).toEqual(newState) + }) + + it('should handle DELETE_CALENDAR_MODAL', () => { + let deletableTimetable = {'delete': 'delete'} + let fakeTimetables = [{'test': 'test'}, {'test 2': 'test 2'}, deletableTimetable] + let newTimeTables = [{'test': 'test'}, {'test 2': 'test 2'}] + let fakeVehicleJourneys= [{time_tables: fakeTimetables}, {time_tables: fakeTimetables}] + state.modalProps = Object.assign({}, state.modalProps,{vehicleJourneys : fakeVehicleJourneys, timetables: fakeTimetables }) + let newState = { + // for the sake of the test, no need to specify the type + type: '', + modalProps:{vehicleJourneys: [{time_tables: newTimeTables},{time_tables: newTimeTables}], timetables: [{'test': 'test'},{'test 2': 'test 2'}]}, + confirmModal: {} + } + expect( + modalReducer(state, { + type: 'DELETE_CALENDAR_MODAL', + timetable: deletableTimetable + }) + ).toEqual(newState) + }) + + it('should handle SELECT_CP_EDIT_MODAL', () => { + let newModalProps = {selectedCompany : {name: 'ALBATRANS'}} + expect( + modalReducer(state, { + type: 'SELECT_CP_EDIT_MODAL', + selectedItem: {name: 'ALBATRANS'} + }) + ).toEqual(Object.assign({}, state, {modalProps: newModalProps})) + }) + + it('should handle UNSELECT_CP_EDIT_MODAL', () => { + let newModalProps = {selectedCompany : undefined} + expect( + modalReducer(state, { + type: 'UNSELECT_CP_EDIT_MODAL' + }) + ).toEqual(Object.assign({}, state, {modalProps: newModalProps})) + }) +}) diff --git a/spec/javascript/vehicle_journeys/reducers/pagination_spec.js b/spec/javascript/vehicle_journeys/reducers/pagination_spec.js new file mode 100644 index 000000000..0ec2dbea2 --- /dev/null +++ b/spec/javascript/vehicle_journeys/reducers/pagination_spec.js @@ -0,0 +1,123 @@ +import reducer from '../../../app/javascript/vehicle_journeys/reducers/pagination' + +const diff = 1 +let state = { + page : 2, + totalCount : 25, + stateChanged: false, + perPage: 12 +} +let pagination = Object.assign({}, state) +const dispatch = function(){} + +describe('pagination reducer, given parameters allowing page change', () => { + + it('should return the initial state', () => { + expect( + reducer(undefined, {}) + ).toEqual({}) + }) + + it('should handle RECEIVE_TOTAL_COUNT', () => { + expect( + reducer(state, { + type: 'RECEIVE_TOTAL_COUNT', + total: 1 + }) + ).toEqual(Object.assign({}, state, {totalCount: 1})) + }) + + it('should handle RESET_PAGINATION', () => { + expect( + reducer(state, { + type: 'RESET_PAGINATION', + }) + ).toEqual(Object.assign({}, state, {page: 1})) + }) + + it('should handle UPDATE_TOTAL_COUNT', () => { + expect( + reducer(state, { + type: 'UPDATE_TOTAL_COUNT', + diff: 1 + }) + ).toEqual(Object.assign({}, state, {totalCount: 24})) + }) + + it('should handle GO_TO_NEXT_PAGE and change state', () => { + expect( + reducer(state, { + type: 'GO_TO_NEXT_PAGE', + dispatch, + pagination, + nextPage : true + }) + ).toEqual(Object.assign({}, state, {page : state.page + 1, stateChanged: false})) + }) + + it('should return GO_TO_PREVIOUS_PAGE and change state', () => { + expect( + reducer(state, { + type: 'GO_TO_PREVIOUS_PAGE', + dispatch, + pagination, + nextPage : false + }) + ).toEqual(Object.assign({}, state, {page : state.page - 1, stateChanged: false})) + }) + + it('should handle UPDATE_TIME', () => { + const val = '33', subIndex = 0, index = 0, timeUnit = 'minute', isDeparture = true, isArrivalsToggled = true + expect( + reducer(state, { + type: 'UPDATE_TIME', + val, + subIndex, + index, + timeUnit, + isDeparture, + isArrivalsToggled + }) + ).toEqual(Object.assign({}, state, {stateChanged: true})) + }) + +}) + + +describe('pagination reducer, given parameters not allowing to go to previous page', () => { + + beforeEach(()=>{ + state.page = 1 + pagination.page = 1 + }) + + it('should return GO_TO_PREVIOUS_PAGE and not change state', () => { + expect( + reducer(state, { + type: 'GO_TO_PREVIOUS_PAGE', + dispatch, + pagination, + nextPage : false + }) + ).toEqual(state) + }) +}) + +describe('pagination reducer, given parameters not allowing to go to next page', () => { + + beforeEach(()=>{ + state.page = 3 + pagination.page = 3 + }) + + it('should return GO_TO_NEXT_PAGE and not change state', () => { + expect( + reducer(state, { + type: 'GO_TO_NEXT_PAGE', + dispatch, + pagination, + nextPage : true + }) + ).toEqual(state) + }) +}) diff --git a/spec/javascript/vehicle_journeys/reducers/status_spec.js b/spec/javascript/vehicle_journeys/reducers/status_spec.js new file mode 100644 index 000000000..7dee88c97 --- /dev/null +++ b/spec/javascript/vehicle_journeys/reducers/status_spec.js @@ -0,0 +1,45 @@ +import statusReducer from '../../../app/javascript/vehicle_journeys/reducers/status' + +let state = {} + +const dispatch = function(){} + +describe('status reducer', () => { + beforeEach(() => { + state = { + fetchSuccess: true, + isFetching: false + } + }) + + it('should return the initial state', () => { + expect( + statusReducer(undefined, {}) + ).toEqual({}) + }) + + it('should handle UNAVAILABLE_SERVER', () => { + expect( + statusReducer(state, { + type: 'UNAVAILABLE_SERVER' + }) + ).toEqual(Object.assign({}, state, {fetchSuccess: false})) + }) + + it('should handle RECEIVE_VEHICLE_JOURNEYS', () => { + expect( + statusReducer(state, { + type: 'RECEIVE_VEHICLE_JOURNEYS' + }) + ).toEqual(Object.assign({}, state, {fetchSuccess: true, isFetching: false})) + }) + + it('should handle FETCH_API', () => { + expect( + statusReducer(state, { + type: 'FETCH_API' + }) + ).toEqual(Object.assign({}, state, {isFetching: true})) + }) + +}) diff --git a/spec/javascript/vehicle_journeys/reducers/vehicle_journeys_spec.js b/spec/javascript/vehicle_journeys/reducers/vehicle_journeys_spec.js new file mode 100644 index 000000000..92f75206c --- /dev/null +++ b/spec/javascript/vehicle_journeys/reducers/vehicle_journeys_spec.js @@ -0,0 +1,268 @@ +import vjReducer from '../../../app/javascript/vehicle_journeys/reducers/vehicleJourneys' + +let state = [] +let stateModal = { + type: '', + modalProps: {}, + confirmModal: {} +} +let fakeFootnotes = [{ + id: 1, + code: 1, + label: "1" +},{ + id: 2, + code: 2, + label: "2" +}] + +let fakeTimeTables = [{ + published_journey_name: 'test 1', + objectid: '1' +},{ + published_journey_name: 'test 2', + objectid: '2' +},{ + published_journey_name: 'test 3', + objectid: '3' +}] +let fakeVJAS = [{ + delta : 627, + arrival_time : { + hour: '11', + minute: '55' + }, + departure_time : { + hour: '22', + minute: '22' + }, + stop_area_object_id : "FR:92024:ZDE:420553:STIF" +}] + +describe('vehicleJourneys reducer', () => { + beforeEach(()=>{ + state = [ + { + journey_pattern_id: 1, + published_journey_name: "vj1", + objectid: '11', + deletable: false, + selected: true, + footnotes: fakeFootnotes, + time_tables: fakeTimeTables, + vehicle_journey_at_stops: fakeVJAS + }, + { + journey_pattern_id: 2, + published_journey_name: "vj2", + objectid: '22', + selected: false, + deletable: false, + footnotes: fakeFootnotes, + time_tables: fakeTimeTables, + vehicle_journey_at_stops: fakeVJAS + } + ] + }) + + it('should return the initial state', () => { + expect( + vjReducer(undefined, {}) + ).toEqual([]) + }) + + + it('should handle ADD_VEHICLEJOURNEY', () => { + let pristineVjasList = [{ + delta : 0, + arrival_time : { + hour: '00', + minute: '00' + }, + departure_time : { + hour: '00', + minute: '00' + }, + stop_point_objectid: 'test', + stop_area_cityname: 'city', + dummy: true + }] + let fakeData = { + published_journey_name: {value: 'test'}, + published_journey_identifier: {value : ''} + } + let fakeSelectedJourneyPattern = {id: "1"} + let fakeSelectedCompany = {name: "ALBATRANS"} + expect( + vjReducer(state, { + type: 'ADD_VEHICLEJOURNEY', + data: fakeData, + selectedJourneyPattern: fakeSelectedJourneyPattern, + stopPointsList: [{object_id: 'test', city_name: 'city'}], + selectedCompany: fakeSelectedCompany + }) + ).toEqual([{ + journey_pattern: fakeSelectedJourneyPattern, + company: fakeSelectedCompany, + published_journey_name: 'test', + published_journey_identifier: '', + objectid: '', + footnotes: [], + time_tables: [], + vehicle_journey_at_stops: pristineVjasList, + selected: false, + deletable: false, + transport_mode: 'undefined', + transport_submode: 'undefined' + }, ...state]) + }) + + it('should handle RECEIVE_VEHICLE_JOURNEYS', () => { + expect( + vjReducer(state, { + type: 'RECEIVE_VEHICLE_JOURNEYS', + json: state + }) + ).toEqual(state) + }) + + it('should handle UPDATE_TIME', () => { + const val = '33', subIndex = 0, index = 0, timeUnit = 'minute', isDeparture = true, isArrivalsToggled = true + let newVJAS = [{ + delta: 638, + arrival_time : { + hour: '11', + minute: '55' + }, + departure_time : { + hour: '22', + minute: '33' + }, + stop_area_object_id : "FR:92024:ZDE:420553:STIF" + }] + let newVJ = Object.assign({}, state[0], {vehicle_journey_at_stops: newVJAS}) + expect( + vjReducer(state, { + type: 'UPDATE_TIME', + val, + subIndex, + index, + timeUnit, + isDeparture, + isArrivalsToggled + }) + ).toEqual([newVJ, state[1]]) + }) + + it('should handle SELECT_VEHICLEJOURNEY', () => { + const index = 1 + const newVJ = Object.assign({}, state[1], {selected: true}) + expect( + vjReducer(state, { + type: 'SELECT_VEHICLEJOURNEY', + index + }) + ).toEqual([state[0], newVJ]) + }) + + it('should handle CANCEL_SELECTION', () => { + const index = 1 + const newVJ = Object.assign({}, state[0], {selected: false}) + expect( + vjReducer(state, { + type: 'CANCEL_SELECTION', + index + }) + ).toEqual([newVJ, state[1]]) + }) + + it('should handle DELETE_VEHICLEJOURNEYS', () => { + const newVJ = Object.assign({}, state[0], {deletable: true, selected: false}) + expect( + vjReducer(state, { + type: 'DELETE_VEHICLEJOURNEYS' + }) + ).toEqual([newVJ, state[1]]) + }) + + it('should handle SHIFT_VEHICLEJOURNEY', () => { + let newVJAS = [{ + delta: 627, + arrival_time : { + hour: '12', + minute: '00' + }, + departure_time : { + hour: '22', + minute: '27' + }, + stop_area_object_id : "FR:92024:ZDE:420553:STIF" + }] + let addtionalTime = 5 + let newVJ = Object.assign({}, state[0], {vehicle_journey_at_stops: newVJAS}) + expect( + vjReducer(state, { + type: 'SHIFT_VEHICLEJOURNEY', + addtionalTime + }) + ).toEqual([newVJ, state[1]]) + }) + + it('should handle DUPLICATE_VEHICLEJOURNEY', () => { + let newVJAS = [{ + delta: 627, + arrival_time : { + hour: '12', + minute: '01' + }, + departure_time : { + hour: '22', + minute: '28' + }, + stop_area_object_id : "FR:92024:ZDE:420553:STIF" + }] + let departureDelta = 1 + let addtionalTime = 5 + let duplicateNumber = 1 + + let newVJ = Object.assign({}, state[0], {vehicle_journey_at_stops: newVJAS, selected: false}) + newVJ.published_journey_name = state[0].published_journey_name + '-0' + delete newVJ['objectid'] + expect( + vjReducer(state, { + type: 'DUPLICATE_VEHICLEJOURNEY', + addtionalTime, + duplicateNumber, + departureDelta + }) + ).toEqual([state[0], newVJ, state[1]]) + }) + + it('should handle EDIT_VEHICLEJOURNEY', () => { + let fakeData = { + published_journey_name: {value : 'test'}, + published_journey_identifier: {value: 'test'} + } + let fakeSelectedCompany : {name : 'ALBATRANS'} + let newVJ = Object.assign({}, state[0], {company: fakeSelectedCompany, published_journey_name: fakeData.published_journey_name.value, published_journey_identifier: fakeData.published_journey_identifier.value}) + expect( + vjReducer(state, { + type: 'EDIT_VEHICLEJOURNEY', + data: fakeData + }) + ).toEqual([newVJ, state[1]]) + }) + + + it('should handle EDIT_VEHICLEJOURNEYS_TIMETABLES', () => { + let newState = JSON.parse(JSON.stringify(state)) + newState[0].time_tables = [fakeTimeTables[0]] + expect( + vjReducer(state, { + type: 'EDIT_VEHICLEJOURNEYS_TIMETABLES', + vehicleJourneys: state, + timetables: [fakeTimeTables[0]] + }) + ).toEqual(newState) + }) +}) -- cgit v1.2.3 From 1c8f131301e7efa828f60945273bfb6b16a0e430 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Mon, 16 Oct 2017 17:57:25 +0200 Subject: add jest for js test, fix js test errors, remove unused config in config/environement --- spec/javascript/journey_patterns/actions_spec.js | 2 +- .../reducers/journey_patterns_spec.js | 2 +- .../journey_patterns/reducers/modal_spec.js | 2 +- .../journey_patterns/reducers/pagination_spec.js | 2 +- .../journey_patterns/reducers/status_spec.js | 2 +- spec/javascript/routes/actions_spec.js | 2 +- .../javascript/routes/reducers/stop_points_spec.js | 2 +- spec/javascript/spec_helper.js | 35 ---------------------- spec/javascript/time_table/actions_spec.js | 2 +- spec/javascript/time_table/reducers/metas_spec.js | 2 +- spec/javascript/time_table/reducers/modal_spec.js | 2 +- .../time_table/reducers/pagination_spec.js | 2 +- spec/javascript/time_table/reducers/status_spec.js | 2 +- .../time_table/reducers/timetable_spec.js | 4 ++- spec/javascript/vehicle_journeys/actions_spec.js | 2 +- .../vehicle_journeys/reducers/filters_spec.js | 2 +- .../vehicle_journeys/reducers/modal_spec.js | 2 +- .../vehicle_journeys/reducers/pagination_spec.js | 2 +- .../vehicle_journeys/reducers/status_spec.js | 2 +- .../reducers/vehicle_journeys_spec.js | 2 +- 20 files changed, 21 insertions(+), 54 deletions(-) delete mode 100644 spec/javascript/spec_helper.js (limited to 'spec/javascript') diff --git a/spec/javascript/journey_patterns/actions_spec.js b/spec/javascript/journey_patterns/actions_spec.js index 75f2682b1..2542fa2f4 100644 --- a/spec/javascript/journey_patterns/actions_spec.js +++ b/spec/javascript/journey_patterns/actions_spec.js @@ -1,4 +1,4 @@ -import actions from '../../app/javascript/journey_patterns/actions' +import actions from '../../../app/javascript/journey_patterns/actions' const dispatch = function(){} const currentPage = 1 diff --git a/spec/javascript/journey_patterns/reducers/journey_patterns_spec.js b/spec/javascript/journey_patterns/reducers/journey_patterns_spec.js index 13a88e477..24780ab5a 100644 --- a/spec/javascript/journey_patterns/reducers/journey_patterns_spec.js +++ b/spec/javascript/journey_patterns/reducers/journey_patterns_spec.js @@ -1,4 +1,4 @@ -import jpReducer from '../../../app/javascript/journey_patterns/reducers/journeyPatterns' +import jpReducer from '../../../../app/javascript/journey_patterns/reducers/journeyPatterns' let state = [] let fakeStopPoints = [{ diff --git a/spec/javascript/journey_patterns/reducers/modal_spec.js b/spec/javascript/journey_patterns/reducers/modal_spec.js index a5d215a9c..4031ea234 100644 --- a/spec/javascript/journey_patterns/reducers/modal_spec.js +++ b/spec/javascript/journey_patterns/reducers/modal_spec.js @@ -1,4 +1,4 @@ -import modalReducer from '../../../app/javascript/journey_patterns/reducers/modal' +import modalReducer from '../../../../app/javascript/journey_patterns/reducers/modal' let state = {} diff --git a/spec/javascript/journey_patterns/reducers/pagination_spec.js b/spec/javascript/journey_patterns/reducers/pagination_spec.js index 78a09eace..a3cd4bf0a 100644 --- a/spec/javascript/journey_patterns/reducers/pagination_spec.js +++ b/spec/javascript/journey_patterns/reducers/pagination_spec.js @@ -1,4 +1,4 @@ -import reducer from '../../../app/javascript/journey_patterns/reducers/pagination' +import reducer from '../../../../app/javascript/journey_patterns/reducers/pagination' const diff = 1 let state = { diff --git a/spec/javascript/journey_patterns/reducers/status_spec.js b/spec/javascript/journey_patterns/reducers/status_spec.js index bf27a3d05..ab094088a 100644 --- a/spec/javascript/journey_patterns/reducers/status_spec.js +++ b/spec/javascript/journey_patterns/reducers/status_spec.js @@ -1,4 +1,4 @@ -import statusReducer from '../../../app/javascript/journey_patterns/reducers/status' +import statusReducer from '../../../../app/javascript/journey_patterns/reducers/status' let state = {} diff --git a/spec/javascript/routes/actions_spec.js b/spec/javascript/routes/actions_spec.js index 490b1b615..507e1e0ed 100644 --- a/spec/javascript/routes/actions_spec.js +++ b/spec/javascript/routes/actions_spec.js @@ -1,4 +1,4 @@ -import actions from '../../app/javascript/routes/actions' +import actions from '../../../app/javascript/routes/actions' describe('actions', () => { it('should create an action to add a stop', () => { diff --git a/spec/javascript/routes/reducers/stop_points_spec.js b/spec/javascript/routes/reducers/stop_points_spec.js index c9d76a29e..b375cdc2c 100644 --- a/spec/javascript/routes/reducers/stop_points_spec.js +++ b/spec/javascript/routes/reducers/stop_points_spec.js @@ -1,4 +1,4 @@ -import stopPointsReducer from '../../../app/javascript/routes/reducers/stopPoints' +import stopPointsReducer from '../../../../app/javascript/routes/reducers/stopPoints' let state = [] diff --git a/spec/javascript/spec_helper.js b/spec/javascript/spec_helper.js deleted file mode 100644 index b6fcb7d8d..000000000 --- a/spec/javascript/spec_helper.js +++ /dev/null @@ -1,35 +0,0 @@ -// Teaspoon includes some support files, but you can use anything from your own support path too. -// require support/jasmine-jquery-1.7.0 -// require support/jasmine-jquery-2.0.0 -// require support/jasmine-jquery-2.1.0 -// require support/sinon -// require support/your-support-file -//= require jquery -//= require bootstrap-sass-official -import { polyfill } from 'es6-object-assign' -// -// PhantomJS (Teaspoons default driver) doesn't have support for Function.prototype.bind, which has caused confusion. -// Use this polyfill to avoid the confusion. -//= require support/phantomjs-shims -// -// You can require your own javascript files here. By default this will include everything in application, however you -// may get better load performance if you require the specific files that are being used in the spec that tests them. -//= require application -// -// Deferring execution -// If you're using CommonJS, RequireJS or some other asynchronous library you can defer execution. Call -// Teaspoon.execute() after everything has been loaded. Simple example of a timeout: -// -// Teaspoon.defer = true -// setTimeout(Teaspoon.execute, 1000) -// -// Matching files -// By default Teaspoon will look for files that match _spec.{js,js.coffee,.coffee}. Add a filename_spec.js file in your -// spec path and it'll be included in the default suite automatically. If you want to customize suites, check out the -// configuration in teaspoon_env.rb -// -// Manifest -// If you'd rather require your spec files manually (to control order for instance) you can disable the suite matcher in -// the configuration and use this file as a manifest. -// -// For more information: http://github.com/modeset/teaspoon diff --git a/spec/javascript/time_table/actions_spec.js b/spec/javascript/time_table/actions_spec.js index 4c1d4e200..9c1a6b6f1 100644 --- a/spec/javascript/time_table/actions_spec.js +++ b/spec/javascript/time_table/actions_spec.js @@ -1,4 +1,4 @@ -import actions from '../../app/javascript/time_tables/actions' +import actions from '../../../app/javascript/time_tables/actions' const dispatch = function(){} const dayTypes = [true, true, true, true, true, true, true] const day = { diff --git a/spec/javascript/time_table/reducers/metas_spec.js b/spec/javascript/time_table/reducers/metas_spec.js index 8806cc1cf..374ad1814 100644 --- a/spec/javascript/time_table/reducers/metas_spec.js +++ b/spec/javascript/time_table/reducers/metas_spec.js @@ -1,4 +1,4 @@ -import metasReducer from '../../../app/javascript/time_tables/reducers/metas' +import metasReducer from '../../../../app/javascript/time_tables/reducers/metas' let state = {} diff --git a/spec/javascript/time_table/reducers/modal_spec.js b/spec/javascript/time_table/reducers/modal_spec.js index f627ca53b..1794d2acd 100644 --- a/spec/javascript/time_table/reducers/modal_spec.js +++ b/spec/javascript/time_table/reducers/modal_spec.js @@ -1,4 +1,4 @@ -import modalReducer from '../../../app/javascript/time_tables/reducers/modal' +import modalReducer from '../../../../app/javascript/time_tables/reducers/modal' let state = {} diff --git a/spec/javascript/time_table/reducers/pagination_spec.js b/spec/javascript/time_table/reducers/pagination_spec.js index 23135d98b..5aa8d27a2 100644 --- a/spec/javascript/time_table/reducers/pagination_spec.js +++ b/spec/javascript/time_table/reducers/pagination_spec.js @@ -1,4 +1,4 @@ -import paginationReducer from '../../../app/javascript/time_tables/reducers/pagination' +import paginationReducer from '../../../../app/javascript/time_tables/reducers/pagination' const dispatch = function(){} diff --git a/spec/javascript/time_table/reducers/status_spec.js b/spec/javascript/time_table/reducers/status_spec.js index 15b733703..63e4033f9 100644 --- a/spec/javascript/time_table/reducers/status_spec.js +++ b/spec/javascript/time_table/reducers/status_spec.js @@ -1,4 +1,4 @@ -import statusReducer from '../../../app/javascript/time_tables/reducers/status' +import statusReducer from '../../../../app/javascript/time_tables/reducers/status' let state = {} diff --git a/spec/javascript/time_table/reducers/timetable_spec.js b/spec/javascript/time_table/reducers/timetable_spec.js index f5e5c0a36..f0f9eaa8c 100644 --- a/spec/javascript/time_table/reducers/timetable_spec.js +++ b/spec/javascript/time_table/reducers/timetable_spec.js @@ -1,5 +1,5 @@ require('whatwg-fetch') -import timetableReducer from '../../../app/javascript/time_tables/reducers/timetable' +import timetableReducer from '../../../../app/javascript/time_tables/reducers/timetable' let state = {} const dispatch = function(){} @@ -22,6 +22,8 @@ let json = { time_table_dates: time_table_dates } + + describe('timetable reducer with empty state', () => { beforeEach(() => { state = { diff --git a/spec/javascript/vehicle_journeys/actions_spec.js b/spec/javascript/vehicle_journeys/actions_spec.js index b847893d2..74765a7ef 100644 --- a/spec/javascript/vehicle_journeys/actions_spec.js +++ b/spec/javascript/vehicle_journeys/actions_spec.js @@ -1,4 +1,4 @@ -import actions from 'vehicle_journeys/actions/index' +import actions from '../../../app/javascript/vehicle_journeys/actions/index' const dispatch = function(){} const currentPage = 1 diff --git a/spec/javascript/vehicle_journeys/reducers/filters_spec.js b/spec/javascript/vehicle_journeys/reducers/filters_spec.js index 43f03ab30..207eaead4 100644 --- a/spec/javascript/vehicle_journeys/reducers/filters_spec.js +++ b/spec/javascript/vehicle_journeys/reducers/filters_spec.js @@ -1,4 +1,4 @@ -import statusReducer from '../../../app/javascript/vehicle_journeys/reducers/filters' +import statusReducer from '../../../../app/javascript/vehicle_journeys/reducers/filters' let state = {} diff --git a/spec/javascript/vehicle_journeys/reducers/modal_spec.js b/spec/javascript/vehicle_journeys/reducers/modal_spec.js index 210ac9e78..69de9168b 100644 --- a/spec/javascript/vehicle_journeys/reducers/modal_spec.js +++ b/spec/javascript/vehicle_journeys/reducers/modal_spec.js @@ -1,4 +1,4 @@ -import modalReducer from '../../app/javascript/vehicle_journeys/reducers/modal' +import modalReducer from '../../../../app/javascript/vehicle_journeys/reducers/modal' let state = {} diff --git a/spec/javascript/vehicle_journeys/reducers/pagination_spec.js b/spec/javascript/vehicle_journeys/reducers/pagination_spec.js index 0ec2dbea2..352997c7c 100644 --- a/spec/javascript/vehicle_journeys/reducers/pagination_spec.js +++ b/spec/javascript/vehicle_journeys/reducers/pagination_spec.js @@ -1,4 +1,4 @@ -import reducer from '../../../app/javascript/vehicle_journeys/reducers/pagination' +import reducer from '../../../../app/javascript/vehicle_journeys/reducers/pagination' const diff = 1 let state = { diff --git a/spec/javascript/vehicle_journeys/reducers/status_spec.js b/spec/javascript/vehicle_journeys/reducers/status_spec.js index 7dee88c97..8fc0f557e 100644 --- a/spec/javascript/vehicle_journeys/reducers/status_spec.js +++ b/spec/javascript/vehicle_journeys/reducers/status_spec.js @@ -1,4 +1,4 @@ -import statusReducer from '../../../app/javascript/vehicle_journeys/reducers/status' +import statusReducer from '../../../../app/javascript/vehicle_journeys/reducers/status' let state = {} diff --git a/spec/javascript/vehicle_journeys/reducers/vehicle_journeys_spec.js b/spec/javascript/vehicle_journeys/reducers/vehicle_journeys_spec.js index 92f75206c..c02ab3398 100644 --- a/spec/javascript/vehicle_journeys/reducers/vehicle_journeys_spec.js +++ b/spec/javascript/vehicle_journeys/reducers/vehicle_journeys_spec.js @@ -1,4 +1,4 @@ -import vjReducer from '../../../app/javascript/vehicle_journeys/reducers/vehicleJourneys' +import vjReducer from '../../../../app/javascript/vehicle_journeys/reducers/vehicleJourneys' let state = [] let stateModal = { -- cgit v1.2.3