Skip to content

Commit

Permalink
feat: _fields filter for PublicAPI entry and entry list CMS-2816
Browse files Browse the repository at this point in the history
  • Loading branch information
simon-scherzinger committed Jun 14, 2017
1 parent 0be491f commit 3093fd7
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 13 deletions.
24 changes: 17 additions & 7 deletions src/PublicAPI.js
Expand Up @@ -429,10 +429,11 @@ export default class PublicAPI extends Core {
*
* @param {string} model name of the model for which the list should be loaded
* @param {string} id the entry id
* @param {number} levels number of levels to request
* @param {number|object?} options options for this entry
* request
* @returns {Promise<EntryResource>} Promise resolving to EntryResource
*/
entry(model, id, levels) {
entry(model, id, options = {}) {
return Promise.resolve()
.then(() => {
if (!model) {
Expand All @@ -443,14 +444,23 @@ export default class PublicAPI extends Core {
throw new Error('id must be defined');
}

if (Number.isInteger(options)) {
options = { _levels: options };
}

if ('_levels' in options && !Number.isInteger(options._levels)) {
throw new Error('_levels must be integer');
}

if ('_fields' in options && !Array.isArray(options._fields)) {
throw new Error('_fields must be Array<string>');
}

return this.follow(`${this[shortIDSymbol]}:${model}`);
})
.then((request) => {
const parameters = { _id: id };
if (levels && levels > 1) {
parameters._levels = levels; // eslint-disable-line no-underscore-dangle
}
request.withTemplateParameters(parameters);
options._id = id;
request.withTemplateParameters(options);
return get(this[environmentSymbol], request);
})
.then(([res, traversal]) => createEntry(res, this[environmentSymbol], traversal));
Expand Down
10 changes: 9 additions & 1 deletion src/helper.js
Expand Up @@ -391,9 +391,17 @@ export function optionsToQuery(options, templateURL) {
throw new Error('sort must be either Array or String.');
}
} else if (key === '_levels') {
if (!Number.isInteger(options[key])) {
throw new Error('_levels must be integer');
}
if (options[key] > 1 && options[key] <= 5) {
out[key] = options[key]; // eslint-disable-line no-underscore-dangle
out[key] = options[key];
}
} else if (key === '_fields') {
if (!Array.isArray(options[key])) {
throw new Error('_fields must be integer');
}
out[key] = options[key];
} else if (typeof options[key] === 'string') {
out[key] = options[key];
} else if (typeof options[key] === 'object') {
Expand Down
7 changes: 4 additions & 3 deletions src/resources/ListResource.js
Expand Up @@ -206,13 +206,14 @@ export default class ListResource extends Resource {
* });
* // for filter see below
*
* @typedef {{size: number, page: number, sort: array<string>, property: filter}} filterOptions
* @typedef {{size: number, page: number, sort: array<string>, _levels: number, _fields:
* Array<string>, property: filter}} filterOptions
*/

/**
*
* {@link filterOptions} can contain key value pairs with filter options. These object will be
* applied when loading a {@link ListResource}.
* {@link filterOptions} can contain key value pairs with filter options for entry fields. These
* object will be applied when loading a {@link ListResource}.
*
* @example
* accounts.accountList({
Expand Down
21 changes: 20 additions & 1 deletion test/Core.test.js
Expand Up @@ -22,7 +22,7 @@ const resolver = require('./mocks/resolver');
const TraversonMock = require('./mocks/TraversonMock');

nock.disableNetConnect();
const should = chai.should();
chai.should();
chai.use(chaiAsPromised);
chai.use(sinonChai);
traverson.registerMediaType(traversonHal.mediaType, traversonHal);
Expand Down Expand Up @@ -657,6 +657,12 @@ describe('optionsToQuery', () => {
};
helper.optionsToQuery(obj).should.not.have.property('_levels');
});
it('should throw on invalid levels, NaN', () => {
const throws = () => {
helper.optionsToQuery({ _levels: 'string' });
};
throws.should.throw(Error);
});
it('should sort one item', () => {
const obj = {
sort: 'name',
Expand All @@ -675,6 +681,19 @@ describe('optionsToQuery', () => {
};
throws.should.throw(Error);
});
it('should have _fields filter', () => {
const obj = {
_fields: ['aField'],
};
helper.optionsToQuery(obj)._fields.should.deep.equal(['aField']); // eslint-disable-line
// no-underscore-dangle
});
it('should throw on invalid _fields', () => {
const throws = () => {
helper.optionsToQuery({ _fields: 'notAnArray' });
};
throws.should.throw(Error);
});
it('should have exact filter on string property', () => {
const obj = { property: 'exact' };
helper.optionsToQuery(obj).should.have.property('property', 'exact');
Expand Down
8 changes: 8 additions & 0 deletions test/publicAPI/PublicAPI.test.js
Expand Up @@ -455,6 +455,14 @@ describe('PublicAPI', () => {
return api.entry('allFields')
.should.be.rejectedWith('id must be defined');
});
it('should throw on invalid _levels', () => {
return api.entry('allFields', '1234567', { _levels: 'string' })
.should.be.rejectedWith('_levels must be integer');
});
it('should throw on invalid _fields', () => {
return api.entry('allFields', '1234567', { _fields: 'string' })
.should.be.rejectedWith('_fields must be Array<string>');
});

it('should create entry', () => {
const getStub = sinon.stub(helper, 'get');
Expand Down
2 changes: 1 addition & 1 deletion typings/PublicAPI.d.ts
Expand Up @@ -32,7 +32,7 @@ export declare class PublicAPI extends Core {

entryList(model: string, options?: filterOptions): Promise<EntryList>;

entry(model: string, id: string, levels: number): Promise<EntryResource>;
entry(model: string, id: string, options: number | { _levels?: number, _fields?: number }): Promise<EntryResource>;

createEntry(model:string, entry: any): Promise<EntryResource>;

Expand Down
1 change: 1 addition & 0 deletions typings/interfaces.d.ts
Expand Up @@ -3,6 +3,7 @@ export interface filterOptions {
page?: number,
sort?: Array<string>,
_levels?: string,
_fields?: Array<string>,
[key: string]: filterType
}

Expand Down

0 comments on commit 3093fd7

Please sign in to comment.