Commit 72772c5d authored by mfluharty's avatar mfluharty

Separate searchProjects into conventional actions

fetchSearchResults to be called from the component
requestSearchResults to prepare the state
receiveSearchResultsSuccess to handle successful searches
receiveSearchResultsError to handle search errors
parent 2ffdcc02
......@@ -62,7 +62,7 @@ export default {
},
methods: {
...mapActions([
'searchProjects',
'fetchSearchResults',
'addProjectsToDashboard',
'fetchProjects',
'setProjectEndpoints',
......@@ -84,7 +84,7 @@ export default {
},
searched(query) {
this.setSearchQuery(query);
this.searchProjects();
this.fetchSearchResults();
},
projectClicked(project) {
this.toggleSelectedProject(project);
......
......@@ -147,7 +147,7 @@ export const setSearchQuery = ({ commit }, query) => {
commit(types.SET_SEARCH_QUERY, query);
};
export const searchProjects = ({ commit, state }) => {
export const fetchSearchResults = ({ commit, state, dispatch }) => {
if (!state.searchQuery) {
commit(types.SEARCHED_WITH_NO_QUERY);
} else if (state.searchQuery.length < API_MINIMUM_QUERY_LENGTH) {
......@@ -155,26 +155,33 @@ export const searchProjects = ({ commit, state }) => {
} else {
commit(types.INCREMENT_PROJECT_SEARCH_COUNT, 1);
dispatch('requestSearchResults');
Api.projects(state.searchQuery, {})
.then(results => dispatch('receiveSearchResultsSuccess', results))
.catch(() => dispatch('receiveSearchResultsError'));
}
};
export const requestSearchResults = ({ commit }) => {
// Flipping this property separately to allows the UI
// to hide the "minimum query" message
// before the seach results arrive from the API
commit(types.SET_MESSAGE_MINIMUM_QUERY, false);
};
Api.projects(state.searchQuery, {})
.then(results => {
export const receiveSearchResultsSuccess = ({ commit }, results) => {
if (results.length === 0) {
commit(types.SEARCHED_SUCCESSFULLY_NO_RESULTS);
} else {
commit(types.SEARCHED_SUCCESSFULLY_WITH_RESULTS, results);
}
return commit(types.DECREMENT_PROJECT_SEARCH_COUNT, 1);
};
commit(types.DECREMENT_PROJECT_SEARCH_COUNT, 1);
})
.catch(() => {
export const receiveSearchResultsError = ({ commit }) => {
commit(types.SEARCHED_WITH_API_ERROR);
commit(types.DECREMENT_PROJECT_SEARCH_COUNT, 1);
});
}
};
export const setProjectEndpoints = ({ commit }, endpoints) => {
......
......@@ -329,16 +329,13 @@ describe('actions', () => {
});
});
describe('searchProjects', () => {
const mockQuery = 'mock-query';
describe('fetchSearchResults', () => {
it('commits the SEARCHED_WITH_NO_QUERY if the search query was empty', done => {
mockAxios.onAny().replyOnce(200, mockProjects);
store.state.searchQuery = '';
testAction(
actions.searchProjects,
mockQuery,
actions.fetchSearchResults,
null,
store.state,
[
{
......@@ -350,48 +347,83 @@ describe('actions', () => {
);
});
it('sets project search results', done => {
it(`commits the SEARCHED_WITH_TOO_SHORT_QUERY type if the search query wasn't long enough`, done => {
store.state.searchQuery = 'a';
testAction(
actions.fetchSearchResults,
null,
store.state,
[
{
type: types.SEARCHED_WITH_TOO_SHORT_QUERY,
},
],
[],
done,
);
});
it(`dispatches the correct actions when the query is valid`, done => {
mockAxios.onAny().replyOnce(200, mockProjects);
store.state.searchQuery = mockQuery;
store.state.searchQuery = 'mock-query';
testAction(
actions.searchProjects,
mockQuery,
actions.fetchSearchResults,
null,
store.state,
[
{
type: types.INCREMENT_PROJECT_SEARCH_COUNT,
payload: 1,
},
],
[
{
type: types.SET_MESSAGE_MINIMUM_QUERY,
payload: false,
type: 'requestSearchResults',
},
{
type: types.SEARCHED_SUCCESSFULLY_WITH_RESULTS,
type: 'receiveSearchResultsSuccess',
payload: mockProjects,
},
],
done,
);
});
});
describe('requestSearchResults', () => {
it(`unsets the 'query is too short' warning status`, done => {
testAction(
actions.requestSearchResults,
null,
store.state,
[
{
type: types.DECREMENT_PROJECT_SEARCH_COUNT,
payload: 1,
type: types.SET_MESSAGE_MINIMUM_QUERY,
payload: false,
},
],
[],
done,
);
});
});
it(`commits the SEARCHED_WITH_TOO_SHORT_QUERY type if the search query wasn't long enough`, done => {
mockAxios.onAny().replyOnce(200, []);
store.state.searchQuery = 'a';
describe('receiveSearchResultsSuccess', () => {
it('sets project search results', done => {
testAction(
actions.searchProjects,
mockQuery,
actions.receiveSearchResultsSuccess,
mockProjects,
store.state,
[
{
type: types.SEARCHED_WITH_TOO_SHORT_QUERY,
type: types.SEARCHED_SUCCESSFULLY_WITH_RESULTS,
payload: mockProjects,
},
{
type: types.DECREMENT_PROJECT_SEARCH_COUNT,
payload: 1,
},
],
[],
......@@ -400,22 +432,13 @@ describe('actions', () => {
});
it('commits the SEARCHED_SUCCESSFULLY_NO_RESULTS type (among others) if the search returns with no results', done => {
mockAxios.onAny().replyOnce(200, []);
store.state.searchQuery = mockQuery;
store.state.searchQuery = 'mock-query';
testAction(
actions.searchProjects,
mockQuery,
actions.receiveSearchResultsSuccess,
[],
store.state,
[
{
type: types.INCREMENT_PROJECT_SEARCH_COUNT,
payload: 1,
},
{
type: types.SET_MESSAGE_MINIMUM_QUERY,
payload: false,
},
{
type: types.SEARCHED_SUCCESSFULLY_NO_RESULTS,
},
......@@ -428,24 +451,15 @@ describe('actions', () => {
done,
);
});
});
describe('receiveSearchResultsError', () => {
it('commits the SEARCHED_WITH_API_ERROR type (among others) if the search API returns an error code', done => {
store.state.searchQuery = mockQuery;
mockAxios.onAny().replyOnce(500);
testAction(
actions.searchProjects,
mockQuery,
actions.receiveSearchResultsError,
['error'],
store.state,
[
{
type: types.INCREMENT_PROJECT_SEARCH_COUNT,
payload: 1,
},
{
type: types.SET_MESSAGE_MINIMUM_QUERY,
payload: false,
},
{
type: types.SEARCHED_WITH_API_ERROR,
},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment