Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions src/lib/api/UrlHandlerApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ const replaceHistory = query => {

/** Default URL parser implementation */
class UrlParser {
constructor() {
this.parse = this.parse.bind(this);
}

_sanitizeParamValue = value => {
let parsedValue = parseInt(value);
if (_isNaN(parsedValue)) {
Expand All @@ -51,7 +55,7 @@ class UrlParser {
* Parse the URL query string and return an object with all the params.
* @param {string} queryString the query string to parse
*/
parse = (queryString = '') => {
parse(queryString = '') {
const parsedParams = Qs.parse(queryString, { ignoreQueryPrefix: true });
const params = {};
Object.entries(parsedParams).forEach(entry => {
Expand All @@ -60,7 +64,7 @@ class UrlParser {
params[key] = this._sanitizeParamValue(value);
});
return params;
};
}
}

/** Default implementation for a param validator class */
Expand Down Expand Up @@ -113,6 +117,10 @@ export class UrlHandlerApi {
Object.keys(this.urlParamsMapping).forEach(stateKey => {
this.fromUrlParamsMapping[this.urlParamsMapping[stateKey]] = stateKey;
});

this.get = this.get.bind(this);
this.set = this.set.bind(this);
this.replace = this.replace.bind(this);
}

/**
Expand Down Expand Up @@ -226,34 +234,34 @@ export class UrlHandlerApi {
* Return a new version of the given `query` state with updated values parsed from the URL query string.
* @param {object} queryState the `query` state
*/
get = queryState => {
get(queryState) {
const urlParamsObj = this.urlParser.parse(window.location.search);
const urlStateObj = this._mapUrlParamsToQueryState(urlParamsObj);
const newQueryState = this._mergeParamsIntoState(urlStateObj, queryState);
const newUrlParams = this._mapQueryStateToUrlParams(newQueryState);
replaceHistory(newUrlParams);
return newQueryState;
};
}

/**
* Update the URL query string parameters from the given `query` state
* @param {object} stateQuery the `query` state
*/
set = stateQuery => {
set(stateQuery) {
if (this.keepHistory) {
const newUrlParams = this._mapQueryStateToUrlParams(stateQuery);
pushHistory(newUrlParams);
} else {
this.replace(stateQuery);
}
};
}

/**
* Replace the URL query string parameters from the given `query` state
* @param {object} stateQuery the `query` state
*/
replace = stateQuery => {
replace(stateQuery) {
const newUrlParams = this._mapQueryStateToUrlParams(stateQuery);
replaceHistory(newUrlParams);
};
}
}
8 changes: 6 additions & 2 deletions src/lib/api/contrib/elasticsearch/ESRequestSerializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@
import _isEmpty from 'lodash/isEmpty';

export class ESRequestSerializer {
constructor() {
this.serialize = this.serialize.bind(this);
}

/**
* Return a serialized version of the app state `query` for the API backend.
* @param {object} stateQuery the `query` state to serialize
*/
serialize = stateQuery => {
serialize(stateQuery) {
const { queryString, sortBy, sortOrder, page, size } = stateQuery;

const bodyParams = {};
Expand Down Expand Up @@ -41,5 +45,5 @@ export class ESRequestSerializer {
}

return bodyParams;
};
}
}
8 changes: 6 additions & 2 deletions src/lib/api/contrib/elasticsearch/ESResponseSerializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,19 @@
*/

export class ESResponseSerializer {
constructor() {
this.serialize = this.serialize.bind(this);
}

/**
* Return a serialized version of the API backend response for the app state `results`.
* @param {object} payload the backend response payload
*/
serialize = payload => {
serialize(payload) {
return {
aggregations: payload.aggregations || {},
hits: payload.hits.hits.map(hit => hit._source),
total: payload.hits.total.value,
};
};
}
}
5 changes: 3 additions & 2 deletions src/lib/api/contrib/elasticsearch/ESSearchApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export class ESSearchApi {
this.initSerializers(config);
this.initInterceptors(config);
this.initAxios();
this.search = this.search.bind(this);
}

validateAxiosConfig() {
Expand Down Expand Up @@ -72,12 +73,12 @@ export class ESSearchApi {
* Perform the backend request to search and return the serialized list of results for the app state `results`.
* @param {string} stateQuery the `query` state with the user input
*/
search = async stateQuery => {
async search(stateQuery) {
const payload = this.requestSerializer.serialize(stateQuery);
const response = await this.http.request({
method: 'POST',
data: payload,
});
return this.responseSerializer.serialize(response.data);
};
}
}
8 changes: 6 additions & 2 deletions src/lib/api/contrib/invenio/InvenioRequestSerializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import _extend from 'lodash/extend';

/** Default backend request serializer */
export class InvenioRequestSerializer {
constructor() {
this.serialize = this.serialize.bind(this);
}

_addFilter = (filter, filterUrlParams) => {
if (!Array.isArray(filter)) {
throw new Error(
Expand Down Expand Up @@ -58,7 +62,7 @@ export class InvenioRequestSerializer {
* Return a serialized version of the app state `query` for the API backend.
* @param {object} stateQuery the `query` state to serialize
*/
serialize = stateQuery => {
serialize(stateQuery) {
const { queryString, sortBy, sortOrder, page, size, filters } = stateQuery;

const getParams = {};
Expand All @@ -82,5 +86,5 @@ export class InvenioRequestSerializer {
_extend(getParams, filterParams);

return Qs.stringify(getParams, { arrayFormat: 'repeat' });
};
}
}
8 changes: 6 additions & 2 deletions src/lib/api/contrib/invenio/InvenioResponseSerializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,19 @@

/** Default backend response serializer */
export class InvenioResponseSerializer {
constructor() {
this.serialize = this.serialize.bind(this);
}

/**
* Return a serialized version of the API backend response for the app state `results`.
* @param {object} payload the backend response payload
*/
serialize = payload => {
serialize(payload) {
return {
aggregations: payload.aggregations || {},
hits: payload.hits.hits,
total: payload.hits.total,
};
};
}
}
5 changes: 3 additions & 2 deletions src/lib/api/contrib/invenio/InvenioSearchApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export class InvenioSearchApi {
this.initSerializers(config);
this.initInterceptors(config);
this.initAxios();
this.search = this.search.bind(this);
}

validateAxiosConfig() {
Expand Down Expand Up @@ -76,10 +77,10 @@ export class InvenioSearchApi {
* Perform the backend request to search and return the serialized list of results for the app state `results`.
* @param {string} stateQuery the `query` state with the user input
*/
search = async stateQuery => {
async search(stateQuery) {
const response = await this.http.request({
params: stateQuery,
});
return this.responseSerializer.serialize(response.data);
};
}
}
10 changes: 6 additions & 4 deletions src/lib/api/contrib/invenio/InvenioSuggestionApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ import { InvenioSearchApi } from './InvenioSearchApi';
class InvenioSuggestionRequestSerializer {
constructor(queryField) {
this.queryField = queryField;
this.serialize = this.serialize.bind(this);
}

/**
* Return a serialized version of the app state `query` for the API backend.
* @param {object} stateQuery the `query` state to serialize
*/
serialize = stateQuery => {
serialize(stateQuery) {
const { suggestionString } = stateQuery;

const getParams = {};
Expand All @@ -29,12 +30,13 @@ class InvenioSuggestionRequestSerializer {
}

return Qs.stringify(getParams, { arrayFormat: 'repeat', encode: false });
};
}
}

class InvenioSuggestionResponseSerializer {
constructor(responseField) {
this.responseFieldPath = responseField.split('.');
this.serialize = this.serialize.bind(this);
}

_serializeSuggestions = responseHits => {
Expand All @@ -49,11 +51,11 @@ class InvenioSuggestionResponseSerializer {
* Return a serialized version of the API backend response for the app state `suggestions`.
* @param {object} payload the backend response payload
*/
serialize = payload => {
serialize(payload) {
return {
suggestions: this._serializeSuggestions(payload.hits.hits || []),
};
};
}
}

export class InvenioSuggestionApi extends InvenioSearchApi {
Expand Down
6 changes: 2 additions & 4 deletions src/lib/components/ReactSearchKit/ReactSearchKit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,10 @@ describe('test ReactSearchKit component', () => {
it('should use default configuration', () => {
const rsk = shallow(<ReactSearchKit searchApi={searchApi} />);

const mockUrlHandlerApi = new UrlHandlerApi();
expect(configureStore).toBeCalledWith(
expect.objectContaining({
searchApi: searchApi,
urlHandlerApi: mockUrlHandlerApi,
urlHandlerApi: UrlHandlerApi.mock.instances[0],
})
);
expect(UrlHandlerApi.mock.calls[0]).toMatchObject({});
Expand Down Expand Up @@ -94,11 +93,10 @@ describe('test ReactSearchKit component', () => {
/>
);

const mockUrlHandlerApi = new UrlHandlerApi();
expect(configureStore).toBeCalledWith(
expect.objectContaining({
searchApi: searchApi,
urlHandlerApi: mockUrlHandlerApi,
urlHandlerApi: UrlHandlerApi.mock.instances[0],
})
);
expect(UrlHandlerApi.mock.calls[0][0]).toMatchObject({
Expand Down