diff options
Diffstat (limited to 'src/client')
| -rw-r--r-- | src/client/react/components/container/HelpBox.js | 2 | ||||
| -rw-r--r-- | src/client/react/components/container/Results.js | 4 | ||||
| -rw-r--r-- | src/client/react/components/container/Search.js | 13 | ||||
| -rw-r--r-- | src/client/react/components/container/View.js | 2 | ||||
| -rw-r--r-- | src/client/react/lib/getSearchResults.js | 22 | ||||
| -rw-r--r-- | src/client/react/reducers.js | 126 | ||||
| -rw-r--r-- | src/client/react/reducers.test.js | 253 | ||||
| -rw-r--r-- | src/client/react/reducers/search.js | 109 | ||||
| -rw-r--r-- | src/client/react/reducers/search.test.js | 198 | ||||
| -rw-r--r-- | src/client/react/reducers/view.js | 73 | 
10 files changed, 403 insertions, 399 deletions
| diff --git a/src/client/react/components/container/HelpBox.js b/src/client/react/components/container/HelpBox.js index 37b5c7e..31624db 100644 --- a/src/client/react/components/container/HelpBox.js +++ b/src/client/react/components/container/HelpBox.js @@ -47,7 +47,7 @@ class HelpBox extends React.Component {  const mapStateToProps = state => ({    results: state.search.results, -  searchText: state.search.searchText, +  searchText: state.search.text,  });  export default connect(mapStateToProps)(HelpBox); diff --git a/src/client/react/components/container/Results.js b/src/client/react/components/container/Results.js index 0f08d7a..5434eb4 100644 --- a/src/client/react/components/container/Results.js +++ b/src/client/react/components/container/Results.js @@ -86,8 +86,8 @@ class Results extends React.Component {  const mapStateToProps = state => ({    results: state.search.results, -  searchText: state.search.searchText, -  selectedResult: state.search.selectedResult, +  searchText: state.search.text, +  selectedResult: state.search.result,  });  export default withRouter(connect(mapStateToProps)(Results)); diff --git a/src/client/react/components/container/Search.js b/src/client/react/components/container/Search.js index 1c4ca4f..30ccad8 100644 --- a/src/client/react/components/container/Search.js +++ b/src/client/react/components/container/Search.js @@ -64,13 +64,13 @@ class Search extends React.Component {    componentDidMount() {      const urlUser = userFromMatch(this.props.match); -    this.props.dispatch({ type: 'SEARCH/SET_USERS', urlUser }); +    this.props.dispatch({ type: 'SEARCH/SET_USER', user: urlUser });    }    componentWillReceiveProps(nextProps) {      if (nextProps.match !== this.props.match) {        const urlUser = userFromMatch(nextProps.match); -      this.props.dispatch({ type: 'SEARCH/SET_USERS', urlUser }); +      this.props.dispatch({ type: 'SEARCH/SET_USER', user: urlUser });      }    } @@ -103,7 +103,7 @@ class Search extends React.Component {        case 'Escape':          event.preventDefault(); -        this.props.dispatch({ type: 'SEARCH/SET_USERS', urlUser }); +        this.props.dispatch({ type: 'SEARCH/SET_USER', user: urlUser });          break;        case 'Enter': @@ -112,7 +112,7 @@ class Search extends React.Component {            // EDGE CASE: The user is set if the user changes, but it doesn't            // change if the result is already the one we are viewing.            // Therefor, we need to dispatch the SET_USER command manually. -          this.props.dispatch({ type: 'SEARCH/SET_USERS', urlUser }); +          this.props.dispatch({ type: 'SEARCH/SET_USER', user: urlUser });          } else if (result) {            this.props.history.push(`/${result}`);          } @@ -170,9 +170,8 @@ class Search extends React.Component {  const mapStateToProps = state => ({    results: state.search.results, -  searchText: state.search.searchText, -  selectedResult: state.search.selectedResult, -  isExactMatch: state.search.isExactMatch, +  searchText: state.search.text, +  selectedResult: state.search.selected,  });  export default withRouter(connect(mapStateToProps)(Search)); diff --git a/src/client/react/components/container/View.js b/src/client/react/components/container/View.js index 28aaad3..b374300 100644 --- a/src/client/react/components/container/View.js +++ b/src/client/react/components/container/View.js @@ -114,7 +114,7 @@ class View extends React.Component {  }  const mapStateToProps = state => ({ -  schedules: state.view.schedules, +  schedules: state.schedules,  });  export default withRouter(connect(mapStateToProps)(View)); diff --git a/src/client/react/lib/getSearchResults.js b/src/client/react/lib/getSearchResults.js new file mode 100644 index 0000000..fa012ac --- /dev/null +++ b/src/client/react/lib/getSearchResults.js @@ -0,0 +1,22 @@ +import FuzzySearch from 'fuzzy-search'; +import uniqBy from 'lodash/uniqBy'; +import users from '../users'; + +function getSearchResults(query) { +  const searcher = new FuzzySearch(users.allUsers, ['value', 'alt']); + +  if (query.trim() === '') { +    return []; +  } + +  const allResults = searcher.search(query); +  const uniqResults = uniqBy(allResults, result => result.id); +  const firstResults = uniqResults.splice(0, 4); + +  const userIds = firstResults.map(result => result.id); + +  return userIds; +} + +export default getSearchResults; + diff --git a/src/client/react/reducers.js b/src/client/react/reducers.js index 13795f7..accf464 100644 --- a/src/client/react/reducers.js +++ b/src/client/react/reducers.js @@ -18,13 +18,123 @@   *   */ -import { combineReducers } from 'redux'; -import search from './reducers/search'; -import view from './reducers/view'; +import getSearchResults from './lib/getSearchResults'; +import users from './users'; -const rootReducer = combineReducers({ -  search, -  view, -}); +const DEFAULT_STATE = { +  // results: [ +  //   's/18562', +  // ], +  search: { +    results: [], +    text: '', +    selected: null, +  }, +  schedules: {}, +}; -export default rootReducer; +const schedule = (state = {}, action) => { +  switch (action.type) { +    case 'VIEW/FETCH_SCHEDULE_REQUEST': +      return { +        ...state, +        state: 'FETCHING', +      }; +    case 'VIEW/FETCH_SCHEDULE_SUCCESS': +      return { +        ...state, +        state: 'FINISHED', +        htmlStr: action.htmlStr, +      }; +    default: +      return state; +  } +}; + +function reducer(state = DEFAULT_STATE, action) { +  switch (action.type) { +    case 'SEARCH/SET_USER': { +      const { user } = action; + +      if (user == null) { +        return { +          ...state, +          search: DEFAULT_STATE.search, +        }; +      } + +      return { +        ...state, +        search: { +          results: [], +          text: users.byId[user].value, +          selected: user, +        }, +      }; +    } + +    case 'SEARCH/INPUT_CHANGE': +      return { +        ...state, +        search: { +          results: getSearchResults(action.searchText), +          text: action.searchText, +          selected: null, +        }, +      }; + +    case 'SEARCH/CHANGE_SELECTED_RESULT': { +      const prevSelectedResult = state.search.selected; +      const prevSelectedResultIndex = state.search.results.indexOf(prevSelectedResult); +      let nextSelectedResultIndex = +        prevSelectedResultIndex + action.relativeChange; + +      if (nextSelectedResultIndex < -1) { +        nextSelectedResultIndex = state.search.results.length - 1; +      } else if (nextSelectedResultIndex > state.search.results.length - 1) { +        nextSelectedResultIndex = -1; +      } + +      const nextSelectedResult = +        nextSelectedResultIndex === -1 +          ? null +          : state.search.results[nextSelectedResultIndex]; + +      return { +        ...state, +        search: { +          ...state.search, +          selected: nextSelectedResult, +        }, +      }; +    } + +    case 'VIEW/FETCH_SCHEDULE_REQUEST': +    case 'VIEW/FETCH_SCHEDULE_SUCCESS': +      return { +        ...state, +        schedules: { +          ...state.schedules, +          [action.user]: +            state.schedules[action.user] +              ? { +                // This user already exists in our state, extend it. +                ...state.schedules[action.user], +                [action.week]: schedule(state.schedules[action.user][action.week], action), +              } +              : { +                // This user does not already exist in our state. +                [action.week]: schedule(undefined, action), +              }, +        }, +      }; + +    default: +      return state; +  } +} + +export default reducer; +export const _test = { +  DEFAULT_STATE, +}; diff --git a/src/client/react/reducers.test.js b/src/client/react/reducers.test.js new file mode 100644 index 0000000..cd195b0 --- /dev/null +++ b/src/client/react/reducers.test.js @@ -0,0 +1,253 @@ +/** + * Copyright (C) 2018 Noah Loomans + * + * This file is part of rooster.hetmml.nl. + * + * rooster.hetmml.nl is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * rooster.hetmml.nl is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with rooster.hetmml.nl.  If not, see <http://www.gnu.org/licenses/>. + * + */ + +window.USERS = [ +  { type: 's', value: '18561' }, +  { type: 's', value: '18562' }, +  { type: 's', value: '18563' }, +  { type: 's', value: '18564' }, +  { type: 's', value: '18565' }, +  { type: 's', value: '18566' }, +  { type: 's', value: '18567' }, +  { type: 's', value: '18568' }, +  { type: 's', value: '18569' }, +]; + +const deepFreeze = require('deep-freeze'); +const reducer = require('./reducers').default; +const { DEFAULT_STATE } = require('./reducers')._test; + +describe('reducers', () => { +  describe('search', () => { +    describe('SEARCH/SET_USER', () => { +      it('Resets the search state if the user is null', () => { +        const prevState = { search: { foo: 'bar' } }; +        const action = { type: 'SEARCH/SET_USER', user: null }; + +        deepFreeze([prevState, action]); + +        expect(reducer(prevState, action)).toEqual({ +          search: DEFAULT_STATE.search, +        }); +      }); + +      it('Sets all the values of that user properly', () => { +        expect(reducer(undefined, { type: 'SEARCH/SET_USER', user: 's/18561' })).toEqual({ +          ...DEFAULT_STATE, +          search: { +            results: [], +            text: '18561', +            selected: 's/18561', +          }, +        }); +      }); +    }); + +    describe('SEARCH/INPUT_CHANGE', () => { +      it('Returns no results when nothing is typed in', () => { +        expect(reducer(undefined, { type: 'SEARCH/INPUT_CHANGE', searchText: '' })).toEqual({ +          ...DEFAULT_STATE, +          search: { +            results: [], +            text: '', +            selected: null, +          }, +        }); +      }); + +      it('Returns no results when a space is typed in', () => { +        expect(reducer(undefined, { type: 'SEARCH/INPUT_CHANGE', searchText: ' ' })).toEqual({ +          ...DEFAULT_STATE, +          search: { +            results: [], +            text: ' ', +            selected: null, +          }, +        }); +      }); + +      it('Preforms a basic search, only returning four results', () => { +        expect(reducer(undefined, { type: 'SEARCH/INPUT_CHANGE', searchText: '18' })).toEqual({ +          ...DEFAULT_STATE, +          search: { +            results: [ +              's/18561', +              's/18562', +              's/18563', +              's/18564', +            ], +            text: '18', +            selected: null, +          }, +        }); +      }); +    }); + +    describe('SEARCH/CHANGE_SELECTED_RESULT', () => { +      it('Does nothing when there are no results', () => { +        const actionPlus = { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: +1 }; +        const actionMin = { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: -1 }; + +        deepFreeze([DEFAULT_STATE, actionPlus, actionMin]); + +        const nextStatePlus = reducer(DEFAULT_STATE, actionPlus); +        const nextStateMin = reducer(DEFAULT_STATE, actionMin); +        expect(nextStatePlus).toEqual(DEFAULT_STATE); +        expect(nextStateMin).toEqual(DEFAULT_STATE); +      }); + +      it('Switches to the correct selectedResult when no selected result is selected', () => { +        const prevState = { +          ...DEFAULT_STATE, +          search: { +            results: ['s/18561', 's/18562', 's/18563'], +            text: '1856', +            selected: null, +          }, +        }; + +        const actionPlus = { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: +1 }; +        const actionMin = { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: -1 }; + +        deepFreeze([prevState, actionPlus, actionMin]); + +        const nextStatePlus = reducer(prevState, actionPlus); +        const nextStateMin = reducer(prevState, actionMin); + +        expect(nextStatePlus).toEqual({ +          ...prevState, +          search: { +            ...prevState.search, +            selected: 's/18561', +          }, +        }); +        expect(nextStateMin).toEqual({ +          ...prevState, +          search: { +            ...prevState.search, +            selected: 's/18563', +          }, +        }); +      }); + +      it('Switches to the correct selectedResult when there is a selected result selected', () => { +        const prevState = { +          ...DEFAULT_STATE, +          search: { +            results: ['s/18561', 's/18562', 's/18563'], +            text: '1856', +            selected: 's/18562', +          }, +        }; + +        const actionPlus = { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: +1 }; +        const actionMin = { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: -1 }; + +        deepFreeze([prevState, actionPlus, actionMin]); + +        const nextStatePlus = reducer(prevState, actionPlus); +        const nextStateMin = reducer(prevState, actionMin); + +        expect(nextStatePlus).toEqual({ +          ...prevState, +          search: { +            ...prevState.search, +            selected: 's/18563', +          }, +        }); +        expect(nextStateMin).toEqual({ +          ...prevState, +          search: { +            ...prevState.search, +            selected: 's/18561', +          }, +        }); +      }); + +      it('Properly wraps around when incrementing', () => { +        expect(reducer({ +          ...DEFAULT_STATE, +          search: { +            results: ['s/18561', 's/18562', 's/18563'], +            text: '1856', +            selected: 's/18563', +          }, +        }, { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: +1 })).toEqual({ +          ...DEFAULT_STATE, +          search: { +            results: ['s/18561', 's/18562', 's/18563'], +            text: '1856', +            selected: null, +          }, +        }); + +        expect(reducer({ +          ...DEFAULT_STATE, +          search: { +            results: ['s/18561', 's/18562', 's/18563'], +            text: '1856', +            selected: null, +          }, +        }, { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: +1 })).toEqual({ +          ...DEFAULT_STATE, +          search: { +            results: ['s/18561', 's/18562', 's/18563'], +            text: '1856', +            selected: 's/18561', +          }, +        }); +      }); + +      it('Properly wraps around when decrementing', () => { +        expect(reducer({ +          ...DEFAULT_STATE, +          search: { +            results: ['s/18561', 's/18562', 's/18563'], +            text: '1856', +            selected: 's/18561', +          }, +        }, { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: -1 })).toEqual({ +          ...DEFAULT_STATE, +          search: { +            results: ['s/18561', 's/18562', 's/18563'], +            text: '1856', +            selected: null, +          }, +        }); + +        expect(reducer({ +          ...DEFAULT_STATE, +          search: { +            results: ['s/18561', 's/18562', 's/18563'], +            text: '1856', +            selected: null, +          }, +        }, { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: -1 })).toEqual({ +          ...DEFAULT_STATE, +          search: { +            results: ['s/18561', 's/18562', 's/18563'], +            text: '1856', +            selected: 's/18563', +          }, +        }); +      }); +    }); +  }); +}); diff --git a/src/client/react/reducers/search.js b/src/client/react/reducers/search.js deleted file mode 100644 index dcc7ec6..0000000 --- a/src/client/react/reducers/search.js +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Copyright (C) 2018 Noah Loomans - * - * This file is part of rooster.hetmml.nl. - * - * rooster.hetmml.nl is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * rooster.hetmml.nl is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with rooster.hetmml.nl.  If not, see <http://www.gnu.org/licenses/>. - * - */ - -import FuzzySearch from 'fuzzy-search'; -import uniqBy from 'lodash/uniqBy'; -import users from '../users'; - -const DEFAULT_STATE = { -  // results: [ -  //   's/18562', -  // ], -  results: [], -  searchText: '', -  selectedResult: null, -}; - -function getSearchResults(allUsers, query) { -  const searcher = new FuzzySearch(allUsers, ['value', 'alt']); - -  if (query.trim() === '') { -    return []; -  } - -  const allResults = searcher.search(query); -  const uniqResults = uniqBy(allResults, result => result.id); -  const firstResults = uniqResults.splice(0, 4); - -  const userIds = firstResults.map(result => result.id); - -  return userIds; -} - -const search = (state = DEFAULT_STATE, action) => { -  switch (action.type) { -    case 'SEARCH/SET_USER': { -      const { user } = action; - -      if (user == null) { -        return DEFAULT_STATE; -      } - -      return { -        ...state, -        results: [], -        searchText: users.byId[user].value, -        selectedResult: user, -      }; -    } - -    case 'SEARCH/INPUT_CHANGE': -      return { -        ...state, -        results: getSearchResults(users.allUsers, action.searchText), -        searchText: action.searchText, -        selectedResult: null, -      }; - -    case 'SEARCH/CHANGE_SELECTED_RESULT': { -      const { results } = state; - -      const prevSelectedResult = state.selectedResult; -      const prevSelectedResultIndex = results.indexOf(prevSelectedResult); -      let nextSelectedResultIndex = -        prevSelectedResultIndex + action.relativeChange; - -      if (nextSelectedResultIndex < -1) { -        nextSelectedResultIndex = results.length - 1; -      } else if (nextSelectedResultIndex > results.length - 1) { -        nextSelectedResultIndex = -1; -      } - -      const nextSelectedResult = -        nextSelectedResultIndex === -1 -          ? null -          : results[nextSelectedResultIndex]; - -      return { -        ...state, -        selectedResult: nextSelectedResult, -      }; -    } - -    default: -      return state; -  } -}; - -export default search; - -export const _test = { -  DEFAULT_STATE, -}; diff --git a/src/client/react/reducers/search.test.js b/src/client/react/reducers/search.test.js deleted file mode 100644 index 48ca05a..0000000 --- a/src/client/react/reducers/search.test.js +++ /dev/null @@ -1,198 +0,0 @@ -/** - * Copyright (C) 2018 Noah Loomans - * - * This file is part of rooster.hetmml.nl. - * - * rooster.hetmml.nl is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * rooster.hetmml.nl is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with rooster.hetmml.nl.  If not, see <http://www.gnu.org/licenses/>. - * - */ - -window.USERS = [ -  { type: 's', value: '18561' }, -  { type: 's', value: '18562' }, -  { type: 's', value: '18563' }, -  { type: 's', value: '18564' }, -  { type: 's', value: '18565' }, -  { type: 's', value: '18566' }, -  { type: 's', value: '18567' }, -  { type: 's', value: '18568' }, -  { type: 's', value: '18569' }, -]; - -const deepFreeze = require('deep-freeze'); -const search = require('./search').default; -const { _test } = require('./search'); - -describe('reducers', () => { -  describe('search', () => { -    describe('SEARCH/SET_USER', () => { -      it('Resets to the default state if the user is null', () => { -        expect(search({ foo: 'bar' }, { type: 'SEARCH/SET_USER', user: null })).toEqual(_test.DEFAULT_STATE); -      }); - -      it('Sets all the values of that user properly', () => { -        expect(search(undefined, { type: 'SEARCH/SET_USER', user: 's/18561' })).toEqual({ -          results: [], -          searchText: '18561', -          selectedResult: 's/18561', -        }); -      }); -    }); - -    describe('SEARCH/INPUT_CHANGE', () => { -      it('Returns no results when nothing is typed in', () => { -        expect(search(undefined, { type: 'SEARCH/INPUT_CHANGE', searchText: '' })).toEqual({ -          results: [], -          searchText: '', -          selectedResult: null, -        }); -      }); - -      it('Returns no results when a space is typed in', () => { -        expect(search(undefined, { type: 'SEARCH/INPUT_CHANGE', searchText: ' ' })).toEqual({ -          results: [], -          searchText: ' ', -          selectedResult: null, -        }); -      }); - -      it('Preforms a basic search, only returning four results', () => { -        expect(search(undefined, { type: 'SEARCH/INPUT_CHANGE', searchText: '18' })).toEqual({ -          results: [ -            's/18561', -            's/18562', -            's/18563', -            's/18564', -          ], -          searchText: '18', -          selectedResult: null, -        }); -      }); -    }); - -    describe('SEARCH/CHANGE_SELECTED_RESULT', () => { -      it('Does nothing when there are no results', () => { -        const prevState = { -          results: [], -          searchText: '', -          selectedResult: null, -        }; - -        const actionPlus = { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: +1 }; -        const actionMin = { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: -1 }; - -        deepFreeze([prevState, actionPlus, actionMin]); - -        const nextStatePlus = search(prevState, actionPlus); -        const nextStateMin = search(prevState, actionMin); -        expect(nextStatePlus).toEqual(prevState); -        expect(nextStateMin).toEqual(prevState); -      }); - -      it('Switches to the correct selectedResult when no selected result is selected', () => { -        const prevState = { -          results: ['s/18561', 's/18562', 's/18563'], -          searchText: '1856', -          selectedResult: null, -        }; - -        const actionPlus = { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: +1 }; -        const actionMin = { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: -1 }; - -        deepFreeze([prevState, actionPlus, actionMin]); - -        const nextStatePlus = search(prevState, actionPlus); -        const nextStateMin = search(prevState, actionMin); - -        expect(nextStatePlus).toEqual({ -          ...prevState, -          selectedResult: 's/18561', -        }); -        expect(nextStateMin).toEqual({ -          ...prevState, -          selectedResult: 's/18563', -        }); -      }); - -      it('Switches to the correct selectedResult when there is a selected result selected', () => { -        const prevState = { -          results: ['s/18561', 's/18562', 's/18563'], -          searchText: '1856', -          selectedResult: 's/18562', -        }; - -        const actionPlus = { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: +1 }; -        const actionMin = { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: -1 }; - -        deepFreeze([prevState, actionPlus, actionMin]); - -        const nextStatePlus = search(prevState, actionPlus); -        const nextStateMin = search(prevState, actionMin); - -        expect(nextStatePlus).toEqual({ -          ...prevState, -          selectedResult: 's/18563', -        }); -        expect(nextStateMin).toEqual({ -          ...prevState, -          selectedResult: 's/18561', -        }); -      }); - -      it('Properly wraps around when incrementing', () => { -        expect(search({ -          results: ['s/18561', 's/18562', 's/18563'], -          searchText: '1856', -          selectedResult: 's/18563', -        }, { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: +1 })).toEqual({ -          results: ['s/18561', 's/18562', 's/18563'], -          searchText: '1856', -          selectedResult: null, -        }); - -        expect(search({ -          results: ['s/18561', 's/18562', 's/18563'], -          searchText: '1856', -          selectedResult: null, -        }, { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: +1 })).toEqual({ -          results: ['s/18561', 's/18562', 's/18563'], -          searchText: '1856', -          selectedResult: 's/18561', -        }); -      }); - -      it('Properly wraps around when decrementing', () => { -        expect(search({ -          results: ['s/18561', 's/18562', 's/18563'], -          searchText: '1856', -          selectedResult: 's/18561', -        }, { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: -1 })).toEqual({ -          results: ['s/18561', 's/18562', 's/18563'], -          searchText: '1856', -          selectedResult: null, -        }); - -        expect(search({ -          results: ['s/18561', 's/18562', 's/18563'], -          searchText: '1856', -          selectedResult: null, -        }, { type: 'SEARCH/CHANGE_SELECTED_RESULT', relativeChange: -1 })).toEqual({ -          results: ['s/18561', 's/18562', 's/18563'], -          searchText: '1856', -          selectedResult: 's/18563', -        }); -      }); -    }); -  }); -}); diff --git a/src/client/react/reducers/view.js b/src/client/react/reducers/view.js deleted file mode 100644 index 8fa56b8..0000000 --- a/src/client/react/reducers/view.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright (C) 2018 Noah Loomans - * - * This file is part of rooster.hetmml.nl. - * - * rooster.hetmml.nl is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * rooster.hetmml.nl is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with rooster.hetmml.nl.  If not, see <http://www.gnu.org/licenses/>. - * - */ - -const schedule = (state = {}, action) => { -  switch (action.type) { -    case 'VIEW/FETCH_SCHEDULE_REQUEST': -      return { -        ...state, -        state: 'FETCHING', -      }; -    case 'VIEW/FETCH_SCHEDULE_SUCCESS': -      return { -        ...state, -        state: 'FINISHED', -        htmlStr: action.htmlStr, -      }; -    default: -      return state; -  } -}; - -const DEFAULT_STATE = { -  schedules: {}, -}; - -const view = (state = DEFAULT_STATE, action) => { -  switch (action.type) { -    case 'VIEW/FETCH_SCHEDULE_REQUEST': -    case 'VIEW/FETCH_SCHEDULE_SUCCESS': -      return { -        ...state, -        schedules: { -          ...state.schedules, -          [action.user]: -            state.schedules[action.user] -              ? { -                // This user already exists in our state, extend it. -                ...state.schedules[action.user], -                [action.week]: schedule(state.schedules[action.user][action.week], action), -              } -              : { -                // This user does not already exist in our state. -                [action.week]: schedule(undefined, action), -              }, -        }, -      }; -    default: -      return state; -  } -}; - -export default view; - -export const _test = { -  DEFAULT_STATE, -}; | 
