diff options
Diffstat (limited to 'spec/javascript')
20 files changed, 3538 insertions, 0 deletions
| diff --git a/spec/javascript/journey_patterns/actions_spec.js b/spec/javascript/journey_patterns/actions_spec.js new file mode 100644 index 000000000..2542fa2f4 --- /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..24780ab5a --- /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..4031ea234 --- /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..a3cd4bf0a --- /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..ab094088a --- /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..507e1e0ed --- /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..b375cdc2c --- /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/time_table/actions_spec.js b/spec/javascript/time_table/actions_spec.js new file mode 100644 index 000000000..003b7f6b5 --- /dev/null +++ b/spec/javascript/time_table/actions_spec.js @@ -0,0 +1,237 @@ +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..374ad1814 --- /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..1794d2acd --- /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..5aa8d27a2 --- /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..63e4033f9 --- /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..f0f9eaa8c --- /dev/null +++ b/spec/javascript/time_table/reducers/timetable_spec.js @@ -0,0 +1,338 @@ +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..74765a7ef --- /dev/null +++ b/spec/javascript/vehicle_journeys/actions_spec.js @@ -0,0 +1,449 @@ +import actions from '../../../app/javascript/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..207eaead4 --- /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..69de9168b --- /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..352997c7c --- /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..8fc0f557e --- /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..c02ab3398 --- /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) +  }) +}) | 
