diff --git a/package-lock.json b/package-lock.json index 0e47272..9aa52a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "syncromatics-track-api", - "version": "3.34.0", + "version": "3.34.0-development-2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 5505ea9..f16a674 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "syncromatics-track-api", - "version": "3.34.0", + "version": "3.34.0-development-2", "description": "Library to interact with the Syncromatics Track API", "main": "dist/index.js", "scripts": { diff --git a/src/examples/create_pattern_for_sync_route_editor.test.js b/src/examples/create_pattern_for_sync_route_editor.test.js new file mode 100644 index 0000000..01d00a8 --- /dev/null +++ b/src/examples/create_pattern_for_sync_route_editor.test.js @@ -0,0 +1,32 @@ +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 getting a pattern for use in the Sync route editor', () => { + 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 return a pattern compatible with the Sync route editor', () => { + api.logIn({ username: 'charlie@example.com', password: 'securepassword' }); + fetchMock.get('/1/SYNC/patterns/editor/1', { + status: 200, + }); + + const getPatternForSyncRouteEditorPromise = api.customer('SYNC').patterns() + .getPatternForSyncRouteEditor(1) + .then(getPatternResponse => { + getPatternResponse.should.be.an('object'); + // todo: flesh this out after payload shape is confirmed + }); + return getPatternForSyncRouteEditorPromise; + }); +}); \ No newline at end of file diff --git a/src/mocks/patterns.js b/src/mocks/patterns.js index ac3396c..6532dfe 100644 --- a/src/mocks/patterns.js +++ b/src/mocks/patterns.js @@ -13,6 +13,77 @@ const patterns = { Link: '; rel="next", ; rel="last"', }, }); + + + const getPatternForSyncRouteEditorResponse = () => new Response(Client.toBlob( + { + "patternId": 1, + "customerId": 1, + "name": "Playa Short Loop South", + "shortName": "Playa Short Loop South", + "length": 5.0, + "color": "#2BFF4F", + "textColor": "#171717", + "isPublic": true, + "enabledForOperations": true, + "encodedPolyline": "ssfnEbtzqUqCdByAiEIaBc@aCk@yAxAmAp@AdEI`EdAu@~E^tAyBtAq@d@", + "description": "Playa Short Loop South", + "controlPoints": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13 + ], + "stops": [ + { + "stopId": 4102770, + "stopOrder": 0, + "waypointOrder": 0, + "isTimepoint": true, + "distanceAlongLine": 0.0 + }, + { + "stopId": 4102771, + "stopOrder": 1, + "waypointOrder": 3, + "isTimepoint": true, + "distanceAlongLine": 245.5316588466202 + }, + { + "stopId": 4102772, + "stopOrder": 2, + "waypointOrder": 6, + "isTimepoint": true, + "distanceAlongLine": 418.48256470210265 + }, + { + "stopId": 4102774, + "stopOrder": 3, + "waypointOrder": 8, + "isTimepoint": true, + "distanceAlongLine": 556.4922568924719 + }, + { + "stopId": 4102773, + "stopOrder": 4, + "waypointOrder": 10, + "isTimepoint": true, + "distanceAlongLine": 776.9836166999818 + } + ] + } + )); + const createDetourPatternResponse = () => new Response(Client.toBlob({ "href": "/1/{customerCode}/patterns/1"})); @@ -36,6 +107,7 @@ const patterns = { .get(client.resolve('/1/SYNC/patterns/1?expand=stops'), singleResponse) .get(client.resolve('/1/SYNC/patterns/1?expand=route'), singleResponse) .get(client.resolve('/1/SYNC/patterns/1?expand=stops,route'), singleResponse) + .get(client.resolve('/1/SYNC/patterns/editor/1'), getPatternForSyncRouteEditorResponse()) .post(client.resolve('/1/SYNC/patterns/detour'), createDetourPatternResponse); }, getById: id => patterns.list diff --git a/src/resources/Pattern.js b/src/resources/Pattern.js index c9c694e..8cc20ff 100644 --- a/src/resources/Pattern.js +++ b/src/resources/Pattern.js @@ -26,14 +26,21 @@ class Pattern extends Resource { const newProperties = Object.assign({}, ...rest); const hydrated = !Object.keys(newProperties).every(k => k === 'href'); - const references = { - route: newProperties.route && new Route(this.client, newProperties.route), - }; + + const references = {}; + if (newProperties.route) { + references.route = new Route(this.client, newProperties.route); + } Object.assign(this, newProperties, { hydrated, ...references, }); + + // Ensure 'route' is completely removed if it's null or empty + if (!this.route) { + delete this.route; + } } /** diff --git a/src/resources/PatternsContext.js b/src/resources/PatternsContext.js index 04e4e64..511c234 100644 --- a/src/resources/PatternsContext.js +++ b/src/resources/PatternsContext.js @@ -97,6 +97,13 @@ class PatternsContext extends PagedContext { return this; } + getPatternForSyncRouteEditor(patternId) { + const url = `/1/${this.code}/patterns/editor/${patternId}`; + return this.client.get(url) + .then(response => response.json()) + .then(data => new Pattern(this.client, data)); + } + /** * Creates a new detour pattern along with child elements, if applicable (stops, waypoints, etc.) * @param {Object} patternPayload The pattern and stop data to be sent in the request body