-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(routes): Added support for getting routes for a customer (EN-153…
…1) (#5) feat(routes): Added support for getting routes for a customer (EN-1531) fix(routes): Fixed comment fix(routes): Added missing unit tests for Customer integration fix(documentation): Updated comments to properly refer to *Context types
- Loading branch information
Showing
9 changed files
with
301 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import chai from 'chai'; | ||
import chaiAsPromised from 'chai-as-promised'; | ||
import fetchMock from 'fetch-mock'; | ||
import Track from '../index'; | ||
import { charlie, routes as mockRoutes } from '../mocks'; | ||
|
||
chai.should(); | ||
chai.use(chaiAsPromised); | ||
|
||
describe('When searching for routes by name', () => { | ||
const api = new Track({ autoRenew: false }); | ||
|
||
beforeEach(() => charlie.setUpSuccessfulMock(api.client)); | ||
beforeEach(() => mockRoutes.setUpSuccessfulMock(api.client)); | ||
beforeEach(() => fetchMock.catch(503)); | ||
afterEach(fetchMock.restore); | ||
|
||
it('should get a list of routes', () => { | ||
api.logIn({ username: '[email protected]', password: 'securepassword' }); | ||
|
||
const routesPromise = api.customer('SYNC').routes() | ||
.withQuery('blue') // Routes containing "blue" in their name | ||
.getPage() | ||
.then(page => page.list) | ||
.then(routes => routes); // Do things with list of routes | ||
|
||
return routesPromise; | ||
}); | ||
}); | ||
|
||
describe('When retrieving a route by ID', () => { | ||
const api = new Track({ autoRenew: false }); | ||
|
||
beforeEach(() => charlie.setUpSuccessfulMock(api.client)); | ||
beforeEach(() => mockRoutes.setUpSuccessfulMock(api.client)); | ||
beforeEach(() => fetchMock.catch(503)); | ||
afterEach(fetchMock.restore); | ||
|
||
it('should get a route', () => { | ||
api.logIn({ username: '[email protected]', password: 'securepassword' }); | ||
|
||
const routesPromise = api.customer('SYNC').route(1) | ||
.fetch() | ||
.then(route => route); // Do things with route | ||
|
||
return routesPromise; | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import Resource from './Resource'; | ||
import Assignment from './Assignment'; | ||
|
||
/** | ||
* Route resource | ||
*/ | ||
class Route extends Resource { | ||
/** | ||
* Creates a new route | ||
* | ||
* Will populate itself with the values given to it after the client parameter | ||
* @example <caption>Assigning partial route data to a new instance</caption> | ||
* const client = new Client(); | ||
* const partialRouteData = { | ||
* href: '/1/SYNC/routes/2', | ||
* name: '9876', | ||
* }; | ||
* const route = new Route(client, partialRouteData); | ||
* | ||
* route.hydrated == true; | ||
* @param {Client} client Instance of pre-configured client | ||
* @param {Array} rest Remaining arguments to use in assigning values to this instance | ||
*/ | ||
constructor(client, ...rest) { | ||
super(client); | ||
|
||
const newProperties = Object.assign({}, ...rest); | ||
const hydrated = !Object.keys(newProperties).every(k => k === 'href'); | ||
const references = { | ||
assignment: newProperties.assignment && new Assignment(this.client, newProperties.assignment), | ||
}; | ||
|
||
Object.assign(this, newProperties, { | ||
hydrated, | ||
...references, | ||
}); | ||
} | ||
|
||
/** | ||
* Makes a href for a given customer code and ID | ||
* @param {string} customerCode Customer code | ||
* @param {Number} id Route ID | ||
* @returns {string} URI to instance of route | ||
*/ | ||
static makeHref(customerCode, id) { | ||
return { | ||
href: `/1/${customerCode}/routes/${id}`, | ||
}; | ||
} | ||
|
||
/** | ||
* Fetches the data for this route via the client | ||
* @returns {Promise} If successful, a hydrated instance of this route | ||
*/ | ||
fetch() { | ||
return this.client.get(this.href) | ||
.then(response => response.json()) | ||
.then(route => new Route(this.client, this, route)); | ||
} | ||
} | ||
|
||
export default Route; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import chai from 'chai'; | ||
import chaiAsPromised from 'chai-as-promised'; | ||
import fetchMock from 'fetch-mock'; | ||
import Client from '../Client'; | ||
import Route from './Route'; | ||
import { routes as mockRoutes } from '../mocks'; | ||
|
||
chai.should(); | ||
chai.use(chaiAsPromised); | ||
|
||
describe('When instantiating a route based on customer and ID', () => { | ||
const client = new Client(); | ||
const route = new Route(client, Route.makeHref('SYNC', 1)); | ||
|
||
it('should set the href', () => route.href.should.equal('/1/SYNC/routes/1')); | ||
it('should not be hydrated', () => route.hydrated.should.equal(false)); | ||
}); | ||
|
||
describe('When instantiating a route based on an object', () => { | ||
const client = new Client(); | ||
const route = new Route(client, mockRoutes.getById(1)); | ||
|
||
it('should set the ID', () => route.id.should.equal(1)); | ||
it('should set the href', () => route.href.should.equal('/1/SYNC/routes/1')); | ||
it('should be hydrated', () => route.hydrated.should.equal(true)); | ||
it('should have one pattern', () => route.patterns.length.should.equal(1)); | ||
it('should have the expected pattern', () => route.patterns[0].href.should.equal('/1/SYNC/patterns/1')); | ||
}); | ||
|
||
describe('When fetching a route based on customer and ID', () => { | ||
const client = new Client(); | ||
|
||
beforeEach(() => mockRoutes.setUpSuccessfulMock(client)); | ||
beforeEach(() => fetchMock.catch(503)); | ||
afterEach(fetchMock.restore); | ||
|
||
let promise; | ||
beforeEach(() => { | ||
promise = new Route(client, Route.makeHref('SYNC', 1)).fetch(); | ||
}); | ||
|
||
it('should resolve the promise', () => promise.should.be.fulfilled); | ||
it('should set the ID', () => promise.then(r => r.id).should.eventually.equal(1)); | ||
it('should set the href', () => promise.then(r => r.href).should.eventually.equal('/1/SYNC/routes/1')); | ||
it('should be hydrated', () => promise.then(r => r.hydrated).should.eventually.equal(true)); | ||
it('should have one pattern', () => promise.then(r => r.patterns.length).should.eventually.equal(1)); | ||
it('should have the expected pattern', () => promise.then(r => r.patterns[0].href).should.eventually.equal('/1/SYNC/patterns/1')); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import 'isomorphic-fetch'; | ||
import PagedContext from './PagedContext'; | ||
import Route from './Route'; | ||
|
||
/** | ||
* Route querying context | ||
* | ||
* This is used to query the list of routes for a customer | ||
*/ | ||
class RoutesContext extends PagedContext { | ||
/** | ||
* Creates a new route context | ||
* @param {Client} client Instance of pre-configured client | ||
* @param {string} customerCode Customer code | ||
* @param {Object} params Object of querystring parameters to append to the URL | ||
*/ | ||
constructor(client, customerCode, params) { | ||
super(client, { ...params }); | ||
this.code = customerCode; | ||
} | ||
|
||
/** | ||
* Sets the query term for the context | ||
* @example | ||
* const routes = new RoutesContext(...); | ||
* routes | ||
* .withQuery('blue') | ||
* .getPage() | ||
* .then(page => ...); | ||
* @param {string} term Query term to search for | ||
* @returns {RoutesContext} Returns itself | ||
*/ | ||
withQuery(term) { | ||
this.params.q = term; | ||
return this; | ||
} | ||
|
||
/** | ||
* Gets the first page of results for this context | ||
* @returns {Promise} If successful, a page of Route objects | ||
* @see Route | ||
*/ | ||
getPage() { | ||
return this.page(Route, `/1/${this.code}/routes`); | ||
} | ||
} | ||
|
||
export default RoutesContext; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import chai from 'chai'; | ||
import chaiAsPromised from 'chai-as-promised'; | ||
import fetchMock from 'fetch-mock'; | ||
import Client from '../Client'; | ||
import RoutesContext from './RoutesContext'; | ||
import { routes as mockRoutes } from '../mocks'; | ||
|
||
chai.should(); | ||
chai.use(chaiAsPromised); | ||
|
||
describe('When building a query for routes', () => { | ||
const client = new Client(); | ||
client.setAuthenticated(); | ||
|
||
beforeEach(() => fetchMock | ||
.get(client.resolve('/1/SYNC/routes?page=9&perPage=27&q=valid&sort=first_valid asc,second_valid desc'), mockRoutes.list) | ||
.catch(503)); | ||
afterEach(fetchMock.restore); | ||
|
||
let promise; | ||
beforeEach(() => { | ||
const routes = new RoutesContext(client, 'SYNC'); | ||
promise = routes | ||
.withPage(9) | ||
.withPerPage(27) | ||
.withQuery('valid') | ||
.sortedBy('ignored', 'desc') | ||
.sortedBy('first_valid') | ||
.thenBy('second_valid', 'desc') | ||
.getPage(); | ||
}); | ||
|
||
it('should make the expected request', () => promise.should.be.fulfilled); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters