Skip to content

Commit

Permalink
feat(patterns): Added support for ability to expand models to get add…
Browse files Browse the repository at this point in the history
…itional data from the API (EN-2184) (#20)

* feat(patterns): Added support for ability to expand models to get additional data from the API (EN-2184)

* fix(paging): Fixed paging implementation
  • Loading branch information
thzinc authored Aug 15, 2017
1 parent 3285231 commit fe89fed
Show file tree
Hide file tree
Showing 15 changed files with 239 additions and 57 deletions.
69 changes: 69 additions & 0 deletions src/examples/get_patterns.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import fetchMock from 'fetch-mock';
import Track from '../index';
import { charlie, patterns as mockPatterns } from '../mocks';

chai.should();
chai.use(chaiAsPromised);

describe('When searching for patterns by name', () => {
const api = new Track({ autoRenew: false });

beforeEach(() => charlie.setUpSuccessfulMock(api.client));
beforeEach(() => mockPatterns.setUpSuccessfulMock(api.client));
beforeEach(() => fetchMock.catch(503));
afterEach(fetchMock.restore);

it('should get a list of patterns', () => {
api.logIn({ username: '[email protected]', password: 'securepassword' });

const patternsPromise = api.customer('SYNC').patterns()
.withQuery('blue') // patterns containing "blue" in their name
.getPage()
.then(page => page.list)
.then(patterns => patterns); // Do things with list of patterns

return patternsPromise;
});
});

describe('When getting a collection of patterns with their associated stop information', () => {
const api = new Track({ autoRenew: false });

beforeEach(() => charlie.setUpSuccessfulMock(api.client));
beforeEach(() => mockPatterns.setUpSuccessfulMock(api.client));
beforeEach(() => fetchMock.catch(503));
afterEach(fetchMock.restore);

it('should get a list of patterns', () => {
api.logIn({ username: '[email protected]', password: 'securepassword' });

const patternsPromise = api.customer('SYNC').patterns()
.withExpandedProperty('stops')
.getPage()
.then(page => page.list)
.then(patterns => patterns); // Do things with list of patterns

return patternsPromise;
});
});

describe('When retrieving a pattern by ID', () => {
const api = new Track({ autoRenew: false });

beforeEach(() => charlie.setUpSuccessfulMock(api.client));
beforeEach(() => mockPatterns.setUpSuccessfulMock(api.client));
beforeEach(() => fetchMock.catch(503));
afterEach(fetchMock.restore);

it('should get a pattern', () => {
api.logIn({ username: '[email protected]', password: 'securepassword' });

const patternsPromise = api.customer('SYNC').pattern(1)
.fetch()
.then(pattern => pattern); // Do things with pattern

return patternsPromise;
});
});
170 changes: 130 additions & 40 deletions src/mocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ export const externalApis = {
Client.toBlob(externalApis.list),
{
headers: {
Link: '</1/external_apis?page=1&perPage=10&q=arr&sort=>; rel="next", </1/external_apis?page=1&perPage=10&q=arr&sort=>; rel="last"',
Link: '</1/external_apis?page=1&per_page=10&q=arr&sort=>; rel="next", </1/external_apis?page=1&per_page=10&q=arr&sort=>; rel="last"',
},
});
const singleResponse = () => new Response(Client.toBlob(externalApis.getById(1)));

fetchMock
.get(client.resolve('/1/external_apis?page=1&perPage=10&q=arr&sort='), listResponse)
.get(client.resolve('/1/external_apis?page=1&per_page=10&q=arr&sort='), listResponse)
.get(client.resolve('/1/external_apis/1'), singleResponse);
},
getById: id => externalApis.list.find(e => e.id === id),
Expand All @@ -104,7 +104,7 @@ export const messageTemplates = {
Client.toBlob(messageTemplates.list),
{
headers: {
Link: '</1/SYNC/message_templates?page=1&perPage=10&q=5k&sort=>; rel="next", </1/SYNC/message_templates?page=1&perPage=10&q=5k&sort=>; rel="last"',
Link: '</1/SYNC/message_templates?page=1&per_page=10&q=5k&sort=>; rel="next", </1/SYNC/message_templates?page=1&per_page=10&q=5k&sort=>; rel="last"',
},
});
const singleResponse = () => new Response(Client.toBlob(messageTemplates.getById(1)));
Expand All @@ -115,7 +115,7 @@ export const messageTemplates = {
});

fetchMock
.get(client.resolve('/1/SYNC/message_templates?page=1&perPage=10&q=5k&sort='), listResponse)
.get(client.resolve('/1/SYNC/message_templates?page=1&per_page=10&q=5k&sort='), listResponse)
.get(client.resolve('/1/SYNC/message_templates/1'), singleResponse)
.post(client.resolve('/1/SYNC/message_templates'), createResponse)
.put(client.resolve('/1/SYNC/message_templates/1'), createResponse);
Expand Down Expand Up @@ -173,13 +173,13 @@ export const routes = {
Client.toBlob(routes.list),
{
headers: {
Link: '</1/SYNC/routes?page=1&perPage=10&q=blue&sort=>; rel="next", </1/SYNC/routes?page=1&perPage=10&q=blue&sort=>; rel="last"',
Link: '</1/SYNC/routes?page=1&per_page=10&q=blue&sort=>; rel="next", </1/SYNC/routes?page=1&per_page=10&q=blue&sort=>; rel="last"',
},
});
const singleResponse = () => new Response(Client.toBlob(routes.getById(1)));

fetchMock
.get(client.resolve('/1/SYNC/routes?page=1&perPage=10&q=blue&sort='), listResponse)
.get(client.resolve('/1/SYNC/routes?page=1&per_page=10&q=blue&sort='), listResponse)
.get(client.resolve('/1/SYNC/routes/1'), singleResponse);
},
getById: id => routes.list.find(v => v.id === id),
Expand All @@ -205,19 +205,35 @@ export const routes = {
export const patterns = {
setUpSuccessfulMock: (client) => {
const listResponse = () => new Response(
Client.toBlob(patterns.list),
Client.toBlob(patterns.list.map(pattern => ({
...pattern,
stops: patterns.patternStopReferences,
}))),
{
headers: {
Link: '</1/SYNC/patterns?page=1&perPage=10&q=blue&sort=>; rel="next", </1/SYNC/patterns?page=1&perPage=10&q=blue&sort=>; rel="last"',
Link: '</1/SYNC/patterns?page=1&per_page=10&q=blue&sort=>; rel="next", </1/SYNC/patterns?page=1&per_page=10&q=blue&sort=>; rel="last"',
},
});
const listResponseWithStops = () => new Response(
Client.toBlob(patterns.list.map(pattern => ({
...pattern,
stops: patterns.patternStops,
}))),
{
headers: {
Link: '</1/SYNC/patterns?page=1&per_page=10&q=blue&sort=>; rel="next", </1/SYNC/patterns?page=1&per_page=10&q=blue&sort=>; rel="last"',
},
});
const singleResponse = () => new Response(Client.toBlob(patterns.getById(1)));

fetchMock
.get(client.resolve('/1/SYNC/patterns?[age=1&perPage=10&q=blue&sort='), listResponse)
.get(client.resolve('/1/SYNC/patterns?page=1&per_page=10&q=blue&sort='), listResponse)
.get(client.resolve('/1/SYNC/patterns?page=1&per_page=10&expand=stops&sort='), listResponseWithStops)
.get(client.resolve('/1/SYNC/patterns/1'), singleResponse);
},
getById: id => patterns.list.find(p => p.id === id),
getById: id => patterns.list
.map(p => ({ ...p, stops: patterns.patternStopReferences }))
.find(p => p.id === id),
list: [
{
id: 1,
Expand All @@ -232,29 +248,103 @@ export const patterns = {
length: 28356.700271064834,
direction_type: 'Loop',
encoded_polyline: 'miaoElhmqUeDlA??gDlA??aBl@v@mE??v@mE??x@mE??v@mE??v@mE??x@mE??v@mE??r@wDyA}D??wA{D??yA{D??wA}D??wA{D??{@}BPwE??NwE??PwE??NwE??NwE??PwE??NwE??PwE??NwE??PwE??NwE??NwE??PwE??NwE??PwE??NwE??PwE??NwE??NwE??PwE??NwE??PwE??NwE??PwE??NwE??PwE??NwE??NwE??JgCAwE??AyE??AwE??CyE??AwE??AyE??AwE??AyE??jAcE??|BrBd@`Ao@qE??o@oE??q@qE??i@{DLwE??NwE??BaAnDj@??nDj@??nDj@??nDj@??nDl@??nDj@??nDj@??nDj@??nDj@??vCd@AyE??sDI??sD@??EwE??pDE??rD???CyEsDO??qD???EyE??pDKrDA??DyE???G??qD@??sD???t@iE~@iE??~@kE??~@iE??~@iE??~@iE??`AkE??~@iE??~@iE??~@kE??~@iE??~@iE??`AiE??~@kE??~@iE??~@iE??~@iE??~@kE??~@iE??`AiE??~@kE??~@iE??~@iE??~@iE??~@kE??~@iE??`AiE??~@iE??~@kE??~@iE??~@iE??~@iE??r@cDxA{D??xA{D??xA{D??xA{D??xA{D??xA{D??xA{D??xA{D??vA{D??xA{D??xA{D??xA{D??xA{D??xA{D??xAyD??xA{D??xA{D??vA{D??xA{D??xA{D??xA{D??xA{D??xA{D??bAmCbCrC??`CrC??bCrC??bCrC??`CrC??bCrC??bCrC??`CrC??bCrC??bCrC??`CrC??bCrC??`CpCuB`D??wB`D??wB`D??uB`D??wB`D??uAtByAxD??yAzD??{AzD??yAzD??yAxD??yAzD??yAzD??{AxD??yAzD??yAzD??yAzD??yAxD??q@pE??e@rEIt@c@rE??e@tE??c@rE??c@rE??c@rE??c@rE??e@tE??c@rE??c@rE??c@rE??c@rE??e@tE??c@rE??c@rE??c@rE??c@rE??e@rE??c@tE??c@rE??c@rE??c@rE??e@rE??c@tE??c@rE??c@rE??c@rE??e@rE??c@tE??c@rE??c@rE??]lD??wB~C??wB~C??yB`D??wB~C??wB`D??yB~C??wB`D??wB~C??sBzCbBpD??dBrD??bBrD??bBrD??dBpD??bBrD??dBrD??bBpD??dBrD??bBrD??fA~B??@vE???xE??@vE???xE??@vE??@xE???vE??@vE???xE??@vE??@xE???vE??DxE??BvE?DDxE??BvE??DxE??@dC??c@rE??c@rE??e@rE??c@tE??c@rE??e@rE??c@rE??c@rE??e@rE??c@tE??c@rE??e@rE??c@rE??c@rE??c@rE??e@tE??c@rE??c@rE??e@rE??MtAqDX??qDZ??sDX??qDZ??qDX??qDZ??cAHsDD??qDF??sDF??sDD??sDF??sDF??kDDsDC??sDE??sDE??sDE??qDC??sDE??m@A',
stops: [
{
href: '/1/SYNC/patterns_stops/11652',
},
{
href: '/1/SYNC/patterns_stops/11659',
},
{
href: '/1/SYNC/patterns_stops/11662',
},
{
href: '/1/SYNC/patterns_stops/11648',
},
{
href: '/1/SYNC/patterns_stops/11649',
},
{
href: '/1/SYNC/patterns_stops/11668',
},
],
href: '/1/SYNC/patterns/1',
},
],
patternStopReferences: [
{
href: '/1/SYNC/patterns_stops/11652',
},
{
href: '/1/SYNC/patterns_stops/11659',
},
{
href: '/1/SYNC/patterns_stops/11662',
},
{
href: '/1/SYNC/patterns_stops/11648',
},
{
href: '/1/SYNC/patterns_stops/11649',
},
{
href: '/1/SYNC/patterns_stops/11668',
},
],
patternStops: [
{
href: '/1/SYNC/patterns_stops/11652',
stop: {
href: '/1/SYNC/stops/1',
},
pattern: {
href: '/1/SYNC/routes/1',
},
distance_along_line: 1.23456789,
stop_order: 1,
rtpi_number: 1001,
},
{
href: '/1/SYNC/patterns_stops/11659',
stop: {
href: '/1/SYNC/stops/1',
},
pattern: {
href: '/1/SYNC/routes/1',
},
distance_along_line: 1.23456789,
stop_order: 2,
rtpi_number: 1002,
},
{
href: '/1/SYNC/patterns_stops/11662',
stop: {
href: '/1/SYNC/stops/1',
},
pattern: {
href: '/1/SYNC/routes/1',
},
distance_along_line: 1.23456789,
stop_order: 3,
rtpi_number: 1003,
},
{
href: '/1/SYNC/patterns_stops/11648',
stop: {
href: '/1/SYNC/stops/1',
},
pattern: {
href: '/1/SYNC/routes/1',
},
distance_along_line: 1.23456789,
stop_order: 4,
rtpi_number: 1004,
},
{
href: '/1/SYNC/patterns_stops/11649',
stop: {
href: '/1/SYNC/stops/1',
},
pattern: {
href: '/1/SYNC/routes/1',
},
distance_along_line: 1.23456789,
stop_order: 5,
rtpi_number: 1005,
},
{
href: '/1/SYNC/patterns_stops/11668',
stop: {
href: '/1/SYNC/stops/1',
},
pattern: {
href: '/1/SYNC/routes/1',
},
distance_along_line: 1.23456789,
stop_order: 6,
rtpi_number: 1006,
},
],
};

export const signs = {
Expand All @@ -263,13 +353,13 @@ export const signs = {
Client.toBlob(signs.list),
{
headers: {
Link: '</1/SYNC/signs?page=1&perPage=10&q=first&sort=>; rel="next", </1/SYNC/signs?page=1&perPage=10&q=first&sort=>; rel="last"',
Link: '</1/SYNC/signs?page=1&per_page=10&q=first&sort=>; rel="next", </1/SYNC/signs?page=1&per_page=10&q=first&sort=>; rel="last"',
},
});
const singleResponse = () => new Response(Client.toBlob(signs.getById(1)));

fetchMock
.get(client.resolve('/1/SYNC/signs?page=1&perPage=10&q=first&sort='), listResponse)
.get(client.resolve('/1/SYNC/signs?page=1&per_page=10&q=first&sort='), listResponse)
.get(client.resolve('/1/SYNC/signs/1'), singleResponse);
},
getById: id => signs.list.find(v => v.id === id),
Expand All @@ -289,7 +379,7 @@ export const stops = {
Client.toBlob(stops.list),
{
headers: {
Link: '</1/SYNC/stops?page=1&perPage=10&q=1st&sort=>; rel="next", </1/SYNC/stops?page=1&perPage=10&q=1st&sort=>; rel="last"',
Link: '</1/SYNC/stops?page=1&per_page=10&q=1st&sort=>; rel="next", </1/SYNC/stops?page=1&per_page=10&q=1st&sort=>; rel="last"',
},
});
const singleResponse = () => new Response(Client.toBlob(stops.getById(1)));
Expand All @@ -305,7 +395,7 @@ export const stops = {
});

fetchMock
.get(client.resolve('/1/SYNC/stops?page=1&perPage=10&q=1st&sort='), listResponse)
.get(client.resolve('/1/SYNC/stops?page=1&per_page=10&q=1st&sort='), listResponse)
.get(client.resolve('/1/SYNC/stops/1'), singleResponse)
.post(client.resolve('/1/SYNC/stops'), postResponse)
.put(client.resolve('/1/SYNC/stops/1'), putResponse);
Expand All @@ -328,7 +418,7 @@ export const tags = {
Client.toBlob(tags.list),
{
headers: {
Link: '</1/SYNC/tags?page=1&perPage=10&q=LA&sort=>; rel="next", </1/SYNC/tags?page=1&perPage=10&q=LA&sort=>; rel="last"',
Link: '</1/SYNC/tags?page=1&per_page=10&q=LA&sort=>; rel="next", </1/SYNC/tags?page=1&per_page=10&q=LA&sort=>; rel="last"',
},
});
const singleResponse = () => new Response(Client.toBlob(tags.getById(3)));
Expand All @@ -344,7 +434,7 @@ export const tags = {
});

fetchMock
.get(client.resolve('/1/SYNC/tags?page=1&perPage=10&q=LA&sort='), listResponse)
.get(client.resolve('/1/SYNC/tags?page=1&per_page=10&q=LA&sort='), listResponse)
.get(client.resolve('/1/SYNC/tags/3'), singleResponse)
.post(client.resolve('/1/SYNC/tags'), postResponse)
.put(client.resolve('/1/SYNC/tags/3'), putResponse);
Expand All @@ -366,13 +456,13 @@ export const users = {
Client.toBlob(users.list),
{
headers: {
Link: '</1/users?page=1&perPage=10&q=1st&sort=>; rel="next", </1/users?page=1&perPage=10&q=1st&sort=>; rel="last"',
Link: '</1/users?page=1&per_page=10&q=1st&sort=>; rel="next", </1/users?page=1&per_page=10&q=1st&sort=>; rel="last"',
},
});
const singleResponse = () => new Response(Client.toBlob(users.getById(1)));

fetchMock
.get(client.resolve('/1/users?page=1&perPage=10&q=1st&sort='), listResponse)
.get(client.resolve('/1/users?page=1&per_page=10&q=1st&sort='), listResponse)
.get(client.resolve('/1/users/1'), singleResponse)
.get(client.resolve('/1/users/me'), singleResponse);
},
Expand All @@ -396,13 +486,13 @@ export const vehicles = {
Client.toBlob(vehicles.list),
{
headers: {
Link: '</1/SYNC/vehicles?page=1&perPage=10&q=12&sort=>; rel="next", </1/SYNC/vehicles?page=1&perPage=10&q=12&sort=>; rel="last"',
Link: '</1/SYNC/vehicles?page=1&per_page=10&q=12&sort=>; rel="next", </1/SYNC/vehicles?page=1&per_page=10&q=12&sort=>; rel="last"',
},
});
const singleResponse = () => new Response(Client.toBlob(vehicles.getById(1)));

fetchMock
.get(client.resolve('/1/SYNC/vehicles?page=1&perPage=10&q=12&sort='), listResponse)
.get(client.resolve('/1/SYNC/vehicles?page=1&per_page=10&q=12&sort='), listResponse)
.get(client.resolve('/1/SYNC/vehicles/1'), singleResponse);
},
getById: id => vehicles.list.find(v => v.id === id),
Expand Down
3 changes: 2 additions & 1 deletion src/resources/Customer.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ class Customer extends Resource {
/**
* Gets a pattern resource by id
* @param {Number} id Identity of the pattern
* @returns {Pattern} Pattern resource */
* @returns {Pattern} Pattern resource
*/
pattern(id) {
return this.resource(Pattern, Pattern.makeHref(this.code, id));
}
Expand Down
2 changes: 1 addition & 1 deletion src/resources/ExternalApisContext.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('When building a query for external APIs', () => {
client.setAuthenticated();

beforeEach(() => fetchMock
.get(client.resolve('/1/external_apis?page=9&perPage=27&q=valid&sort=first_valid asc,second_valid desc'), mockExternalApis.list)
.get(client.resolve('/1/external_apis?page=9&per_page=27&q=valid&sort=first_valid asc,second_valid desc'), mockExternalApis.list)
.catch(503));
afterEach(fetchMock.restore);

Expand Down
2 changes: 1 addition & 1 deletion src/resources/MessageTemplatesContext.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('When building a query for message templates', () => {
client.setAuthenticated();

beforeEach(() => fetchMock
.get(client.resolve('/1/SYNC/message_templates?page=9&perPage=27&q=valid&sort='), mockMessageTemplates.list)
.get(client.resolve('/1/SYNC/message_templates?page=9&per_page=27&q=valid&sort='), mockMessageTemplates.list)
.catch(503));
afterEach(fetchMock.restore);

Expand Down
Loading

0 comments on commit fe89fed

Please sign in to comment.