From 2f72c7944b4d395050adb032e536f7ef0f1c11c9 Mon Sep 17 00:00:00 2001 From: Jeff Koch <4649003+jrkoch@users.noreply.github.com> Date: Tue, 25 Jul 2017 12:08:24 -0700 Subject: [PATCH] feat(stop): Create or update stop (#18) (EN-1811) * feat(stop): Create or update stop * Update MessageTemplate.js Changed comments to use humanized description of MessageTemplate * Update MessageTemplate.js Humanized another MessageTemplate in the comments --- src/examples/get_stops.test.js | 42 ++++++++++++++++++++++++++++++++ src/mocks.js | 14 ++++++++++- src/resources/MessageTemplate.js | 11 +++++---- src/resources/Stop.js | 31 ++++++++++++++++++++++- src/resources/Stop.test.js | 42 ++++++++++++++++++++++++++++++++ src/resources/Tag.js | 3 ++- 6 files changed, 135 insertions(+), 8 deletions(-) diff --git a/src/examples/get_stops.test.js b/src/examples/get_stops.test.js index 62a5992..02dfad9 100644 --- a/src/examples/get_stops.test.js +++ b/src/examples/get_stops.test.js @@ -46,3 +46,45 @@ describe('When retrieving a stop by ID', () => { return stopsPromise; }); }); + +describe('When creating a stop', () => { + const api = new Track({ autoRenew: false }); + + beforeEach(() => charlie.setUpSuccessfulMock(api.client)); + beforeEach(() => mockStops.setUpSuccessfulMock(api.client)); + beforeEach(() => fetchMock.catch(503)); + afterEach(fetchMock.restore); + + it('should create a stop', () => { + api.logIn({ username: 'charlie@example.com', password: 'securepassword' }); + + const stopPromise = api.customer('SYNC').stop({ name: '1st and Main' }) + .create() + .then(stop => stop); // Do things with stop + + return stopPromise; + }); +}); + +describe('When updating a stop', () => { + const api = new Track({ autoRenew: false }); + + beforeEach(() => charlie.setUpSuccessfulMock(api.client)); + beforeEach(() => mockStops.setUpSuccessfulMock(api.client)); + beforeEach(() => fetchMock.catch(503)); + afterEach(fetchMock.restore); + + it('should update a stop', () => { + api.logIn({ username: 'charlie@example.com', password: 'securepassword' }); + + const stopPromise = api.customer('SYNC').stop(1) + .fetch() + .then((stop) => { + // eslint-disable-next-line no-param-reassign + stop.name = 'First and Main'; + return stop.update(); + }); + + return stopPromise; + }); +}); diff --git a/src/mocks.js b/src/mocks.js index 501cf99..b8e3cf2 100644 --- a/src/mocks.js +++ b/src/mocks.js @@ -292,10 +292,22 @@ export const stops = { }, }); const singleResponse = () => new Response(Client.toBlob(stops.getById(1))); + const postResponse = () => new Response(undefined, { + headers: { + Location: '/1/SYNC/stops/1', + }, + }); + const putResponse = () => new Response(undefined, { + headers: { + Location: '/1/SYNC/stops/1', + }, + }); fetchMock .get(client.resolve('/1/SYNC/stops?page=1&perPage=10&q=1st&sort='), listResponse) - .get(client.resolve('/1/SYNC/stops/1'), singleResponse); + .get(client.resolve('/1/SYNC/stops/1'), singleResponse) + .post(client.resolve('/1/SYNC/stops'), postResponse) + .put(client.resolve('/1/SYNC/stops/1'), putResponse); }, getById: id => stops.list.find(v => v.id === id), list: [ diff --git a/src/resources/MessageTemplate.js b/src/resources/MessageTemplate.js index a7fde33..a345147 100644 --- a/src/resources/MessageTemplate.js +++ b/src/resources/MessageTemplate.js @@ -61,8 +61,8 @@ class MessageTemplate extends Resource { } /** - * Creates a new messageTemplate via the client - * @returns {Promise} If successful, the a hydrated instance of messageTemplate with id + * Creates a new message template via the client + * @returns {Promise} If successful, the a hydrated instance of message template with id */ create() { // eslint-disable-next-line no-unused-vars @@ -77,13 +77,14 @@ class MessageTemplate extends Resource { /** - * Updates data for a message templte via the client - * @returns {Promise} if successful returns instance of this tag + * Updates data for a message template via the client + * @returns {Promise} if successful returns instance of this message template */ update() { // eslint-disable-next-line no-unused-vars const { client, hydrated, customerCode, ...body } = this; - return this.client.put(`/1/${this.customerCode}/message_templates/${this.id}`, { body }) + const { href } = MessageTemplate.makeHref(this.customerCode, this.id); + return this.client.put(href, { body }) .then(() => new MessageTemplate(this.client, { ...this })); } } diff --git a/src/resources/Stop.js b/src/resources/Stop.js index c7d058b..3eb9897 100644 --- a/src/resources/Stop.js +++ b/src/resources/Stop.js @@ -24,7 +24,7 @@ class Stop extends Resource { super(client); const newProperties = Object.assign({}, ...rest); - const hydrated = !Object.keys(newProperties).every(k => k === 'href'); + const hydrated = !Object.keys(newProperties).every(k => k === 'href' || k === 'code'); Object.assign(this, newProperties, { hydrated, @@ -40,6 +40,7 @@ class Stop extends Resource { static makeHref(customerCode, id) { return { href: `/1/${customerCode}/stops/${id}`, + code: customerCode, }; } @@ -52,6 +53,34 @@ class Stop extends Resource { .then(response => response.json()) .then(stop => new Stop(this.client, this, stop)); } + + /** + * Saves data for a stop via the client + * @returns {Promise} If successful, returns a stop with the id included + */ + create() { + // eslint-disable-next-line no-unused-vars + const { client, hydrated, code, ...body } = this; + return this.client.post(`/1/${code}/stops`, { body }) + .then(response => response.headers.get('location')) + .then((href) => { + const match = /\/\d+\/\S+\/stops\/(\d+)/.exec(href); + return new Stop(this.client, { ...this, href, id: parseFloat(match[1]) }); + }); + } + + /** + * Updates data for a stop via the client + * @returns {Promise} If successful, returns instance of this stop + */ + update() { + // eslint-disable-next-line no-unused-vars + const { client, hydrated, code, ...body } = this; + const { href } = Stop.makeHref(code, this.id); + return this.client.put(href, { body }) + .then(() => new Stop(this.client, { ...this })); + } + } export default Stop; diff --git a/src/resources/Stop.test.js b/src/resources/Stop.test.js index 7def573..288ed53 100644 --- a/src/resources/Stop.test.js +++ b/src/resources/Stop.test.js @@ -42,3 +42,45 @@ describe('When fetching a stop based on customer and ID', () => { it('should set the href', () => promise.then(v => v.href).should.eventually.equal('/1/SYNC/stops/1')); it('should be hydrated', () => promise.then(v => v.hydrated).should.eventually.equal(true)); }); + +describe('When creating a stop', () => { + const client = new Client(); + + beforeEach(() => mockStops.setUpSuccessfulMock(client)); + beforeEach(() => fetchMock.catch(503)); + afterEach(fetchMock.restore); + + let promise; + beforeEach(() => { + promise = new Stop(client, { code: 'SYNC', name: '1st and Main' }).create(); + }); + + it('should resolve the promise', () => promise.should.be.fulfilled); + it('should set the href', () => promise.then(v => v.href).should.eventually.equal('/1/SYNC/stops/1')); + it('should set the ID', () => promise.then(v => v.id).should.eventually.equal(1)); +}); + +describe('When updating a stop', () => { + const client = new Client(); + const updateValue = 'First and Main'; + + beforeEach(() => mockStops.setUpSuccessfulMock(client)); + beforeEach(() => fetchMock.catch(503)); + afterEach(fetchMock.restore); + + let promise; + beforeEach(() => { + promise = new Stop(client, { code: 'SYNC', name: '1st and Main' }) + .create() + .then((stop) => { + // eslint-disable-next-line no-param-reassign + stop.name = updateValue; + return stop.update(); + }) + .then(stop => stop); + }); + + it('should resolve the promise', () => promise.should.be.fulfilled); + it('should set the href', () => promise.then(v => v.href).should.eventually.equal('/1/SYNC/stops/1')); + it('should set the name', () => promise.then(v => v.name).should.eventually.equal(updateValue)); +}); diff --git a/src/resources/Tag.js b/src/resources/Tag.js index 03cd35b..55108d4 100644 --- a/src/resources/Tag.js +++ b/src/resources/Tag.js @@ -66,7 +66,8 @@ class Tag extends Resource { update() { // eslint-disable-next-line no-unused-vars const { client, hydrated, customerCode, ...body } = this; - return this.client.put(`/1/${this.customerCode}/tags/${this.id}`, { body }) + const { href } = Tag.makeHref(this.customerCode, this.id); + return this.client.put(href, { body }) .then(() => new Tag(this.client, { ...this })); }