Skip to content

Commit

Permalink
Feature/EN-9611 clean up cancel trips client (#127)
Browse files Browse the repository at this point in the history
* WIP updates to API to add tripCancelations to customer

* Update TripCancelation.js

* Update TripCancelation.js

* skip tests to see if github action builds work

* cleanup

* debug

* fix context test

* text fixing

* debug branch publish

* Update TripCancelationsContext.js

* 0.0.1-development

* remove build debug

* additions for creation of cancelations

* discard

* Revert "discard"

This reverts commit 570afb3.

* 0.0.2-development

* add trip cancelation subscription stuff

* 0.0.3-development

* remove area

* 0.0.4-development

* add batch create

* 0.0.5-development

* add batch create to customer

* 0.0.6-development

* start working out batch save

* 0.0.7-development

* still working it out

* 0.0.8-development

* fix test

* 0.0.9-development

* exactly like dispatch

* 0.0.10-development

* found it

* 0.0.11-development

* cleanup

* 0.0.12-development

* fix naming

* 0.0.13-development

* need post response from create

* 0.0.14-development

* Revert "need post response from create"

This reverts commit 35be53f.

* post like get

* 0.0.15-development

* remove parent level cancelations

* Revert "remove parent level cancelations"

This reverts commit c7cf93a.

* update controller paths

* 0.0.20-development

* cleaned up and tests pass

* 0.0.21-development

* final cleanup

* 0.0.22-development

---------

Co-authored-by: Jeffery Olson <[email protected]>
Co-authored-by: glen <[email protected]>
  • Loading branch information
3 people authored Dec 20, 2023
1 parent 55796a2 commit 097930d
Show file tree
Hide file tree
Showing 16 changed files with 428 additions and 5 deletions.
5 changes: 2 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "syncromatics-track-api",
"version": "0.0.0-development",
"version": "0.0.22-development",
"description": "Library to interact with the Syncromatics Track API",
"main": "dist/index.js",
"scripts": {
Expand Down
56 changes: 56 additions & 0 deletions src/examples/get_trip_cancelations_batch.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import fetchMock from 'fetch-mock';
import Track from '../index';
import { charlie, tripCancelationBatches as mocks } from '../mocks';

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

describe('When retrieving trip cancelations by customer', () => {
const api = new Track({ autoRenew: false });

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

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

const tripCancelationBatchPromise = api.customer('SYNC').tripCancelationBatch()
.fetch()
.then(msg => msg); // Do things with message

return tripCancelationBatchPromise;
});
});

describe('When creating trip cancelations', () => {
const api = new Track({ autoRenew: false });

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

it('should save trip cancelations batch', () => {
api.logIn({ username: '[email protected]', password: 'securepassword' });

const tripCancelationBatchPromise = api.customer('SYNC').tripCancelationBatch({
cancelations: [
{
customerId: 1,
},
{
customerId: 1,
},
],
})
.create()
.then(msg => msg); // Do things with msg

return tripCancelationBatchPromise;
});
});

1 change: 1 addition & 0 deletions src/mocks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export { default as voipCallRecords } from './voipCallRecords';
export { default as callParticipants } from './callParticipants';
export { default as dispatchMessages } from './dispatchMessages';
export { default as dispatchMessageBatches } from './dispatchMessageBatches';
export { default as tripCancelationBatches } from './tripCancelationBatches';
export { default as dispatchMessageStatus } from './dispatchMessageStatus';
export { default as drivers } from './drivers';
export { default as externalApis } from './externalApis';
Expand Down
4 changes: 4 additions & 0 deletions src/mocks/realTime.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import stopArrivals from './stopArrivals';
import stops from './stops';
import vehicleArrivals from './vehicleArrivals';
import vehicles from './vehicles';
import tripCancelationBatches from "./tripCancelationBatches";

const realTimeUri = 'ws://localhost:8083/1/realtime';
const realTime = {
Expand Down Expand Up @@ -138,6 +139,9 @@ const realTime = {
case 'BIKE_RACK_SLOTS':
data = bikeRackSlots.list;
break;
case 'TRIP_CANCELATIONS':
data = tripCancelationBatches.response.cancelations;
break;
case 'CALL_STATES':
data = callStates.list;
break;
Expand Down
42 changes: 42 additions & 0 deletions src/mocks/tripCancelationBatches.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import fetchMock from 'fetch-mock';
import Client from '../Client';

const tripCancelationBatches = {
setUpSuccessfulMock: (client) => {
const fetchResponse = () => new Response(Client.toBlob(tripCancelationBatches.response));
const createResponse = () => new Response(Client.toBlob(tripCancelationBatches.response));
const fetchByIdResponse = () => new Response(Client.toBlob(tripCancelationBatches.response.cancelations[0]));

fetchMock
.get(client.resolve('/1/SYNC/serviceadjustments/tripcancelations'), fetchResponse)
.post(client.resolve('/1/SYNC/serviceadjustments/tripcancelations'), createResponse)
.get(client.resolve('/1/SYNC/serviceadjustments/tripcancelation/1'), fetchByIdResponse)
},
getById: id => tripCancelationBatches.response.cancelations.find(v => v.id === id),
response: {
cancelations:
[{
href: "/1/SYNC/serviceadjustments/tripcancelation/1",
id: 1,
tripId: 4498693,
customerId: 1,
serviceDateTime: "2023-12-12T00:00:00",
createDateTime: "2023-12-12T15:28:47.2885755-08:00",
uncancel: false,
userId: 3313
},
{
href: "/1/SYNC/serviceadjustments/tripcancelation/2",
id: 2,
tripId: 4498691,
customerId: 1,
serviceDateTime: "2023-12-12T00:00:00",
createDateTime: "2023-12-12T15:28:47.2931379-08:00",
uncancel: false,
userId: 3313
}],
}
};

export default tripCancelationBatches;
11 changes: 10 additions & 1 deletion src/resources/Customer.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import VehiclesContext from './VehiclesContext';
import VoipTicket from './VoipTicket';
import VoipCallRecordsContext from "./VoipCallRecordsContext";
import VoipCallRecord from "./VoipCallRecord";
import TripCancelationBatch from "./TripCancelationBatch";

/**
* Customer resource
Expand Down Expand Up @@ -253,7 +254,7 @@ class Customer extends Resource {
dispatchMessageBatch(id) {
return this.resource(DispatchMessageBatch, DispatchMessageBatch.makeHref(this.code, id));
}

/**
* Gets a dispatch message status resource
* @returns {DispatchMessageStatus} Dispatch Message Status resource
Expand Down Expand Up @@ -512,6 +513,14 @@ class Customer extends Resource {
trip(id) {
return this.resource(Trip, Trip.makeHref(this.code, id));
}

/**
* Gets a trip cancelation batch resource
* @return {TripCancelationBatch} Trip Cancelation Batch resource
*/
tripCancelationBatch() {
return this.resource(TripCancelationBatch, TripCancelationBatch.makeHref(this.code));
}

/**
* Gets a TwitterOAuth resource
Expand Down
2 changes: 2 additions & 0 deletions src/resources/Customer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import Vehicle from './Vehicle';
import VehiclesContext from './VehiclesContext';
import VoipTicket from './VoipTicket';
import Assignment from './Assignment';
import TripCancelationBatch from "./TripCancelationBatch";

chai.should();
chai.use(chaiAsPromised);
Expand Down Expand Up @@ -99,6 +100,7 @@ describe('When getting resources related to a customer', () => {
it('should allow tags to be searched', () => customer.tags().should.be.instanceof(TagsContext));
it('should allow a tag to be retrieved', () => customer.tag().should.be.instanceof(Tag));
it('should allow a trip to be retrieved', () => customer.trip().should.be.instanceof(Trip));
it("should allow trip cancelations to be retrieved", () => customer.tripCancelationBatch().should.be.instanceof(TripCancelationBatch));
it('should allow a twitter oauth token to be created', () => customer.twitterOAuth().should.be.instanceof(TwitterOAuth));
it('should allow a twitter oauth request token to be created', () => customer.twitterOAuthRequest().should.be.instanceof(TwitterOAuthRequest));
it('should allow a twitter username to be retrieved', () => customer.twitterUsername().should.be.instanceof(TwitterUsername));
Expand Down
9 changes: 9 additions & 0 deletions src/resources/RealTimeContextFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import EnplugHealthsRealTimeContext from './EnplugHealthsRealTimeContext';
import IncidentsRealTimeContext from './IncidentsRealTimeContext';
import VehiclesRealTimeContext from './VehiclesRealTimeContext';
import VoipHeartbeatHandler from './VoipHeartbeatHandler';
import TripCancelationsRealTimeContext from "./TripCancelationsRealtimeContext";

/**
* A factory for creating entity-specific Real Time Contexts for a given Real Time Client.
Expand Down Expand Up @@ -89,6 +90,14 @@ class RealTimeContextFactory {
return new BikeRackSlotsRealTimeContext(this.realTimeClient, this.customerCode);
}

/**
* Creates a RealTimeContext for querying Trip Cancelation updates.
* @returns {TripCancelationsRealTimeContext} The newly created context.
*/
tripCancelations() {
return new TripCancelationsRealTimeContext(this.realTimeClient, this.customerCode);
}

/**
* Creates a RealTimeContext for querying Call State updates.
* @returns {CallStatesRealTimeContext} The newly created context.
Expand Down
5 changes: 5 additions & 0 deletions src/resources/RealTimeContextFactory.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ describe('When creating a RealTimeContext', () => {
result.realTimeClient.should.equal(realTimeClient);
});

it('should reuse its RealTimeClient when creating an TripCancelationsRealtimeContext', () => {
const result = factory.tripCancelations();
result.realTimeClient.should.equal(realTimeClient);
});

it('should reuse its RealTimeClient when creating an CallStatesRealTimeContext', () => {
const result = factory.callStates();
result.realTimeClient.should.equal(realTimeClient);
Expand Down
45 changes: 45 additions & 0 deletions src/resources/TripCancelation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import Resource from './Resource';

/**
* TripCancelation resource
*/
class TripCancelation extends Resource {
/**
* @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' || k === 'code');

Object.assign(this, newProperties, {
hydrated,
});
}

/**
* Makes a href for a given customer code and cancelation id
* @param {string} customerCode Customer code
* @param {number} id Cancelation ID
* @returns {{href: string}} URI to instance of trip cancelation
*/
static makeHref(customerCode, id) {
return {
href: `/1/${customerCode}/serviceadjustments/tripcancelation/${id}`,
};
}

/**
* Fetches the data for this trip cancelation via the client
* @returns {Promise} If successful, a hydrated instance of this trip cancelation
*/
fetch() {
return this.client.get(this.href)
.then(response => response.json())
.then(tripCancelation => new TripCancelation(this.client, this, tripCancelation));
}
}

export default TripCancelation;
44 changes: 44 additions & 0 deletions src/resources/TripCancelation.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import fetchMock from 'fetch-mock';
import Client from '../Client';
import TripCancelation from "./TripCancelation";
import tripCancelationBatches from "../mocks/tripCancelationBatches";

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

describe('When instantiating a TripCancelation based on customer and ID', () => {
const client = new Client();
const tripCancelation = new TripCancelation(client, TripCancelation.makeHref('SYNC', 1));

it('should set the href', () => tripCancelation.href.should.equal('/1/SYNC/serviceadjustments/tripcancelation/1'));
it('should not be hydrated', () => tripCancelation.hydrated.should.equal(false));
});

describe('When instantiating a TripCancelation based on an object', () => {
const client = new Client();
const tripCancelation = new TripCancelation(client, tripCancelationBatches.getById(1));

it('should set the ID', () => tripCancelation.id.should.equal(1));
it('should set the href', () => tripCancelation.href.should.equal('/1/SYNC/serviceadjustments/tripcancelation/1'));
it('should be hydrated', () => tripCancelation.hydrated.should.equal(true));
});

describe('When fetching a TripCancelation based on customer and ID', () => {
const client = new Client();

beforeEach(() => tripCancelationBatches.setUpSuccessfulMock(client));
beforeEach(() => fetchMock.catch(503));
afterEach(fetchMock.restore);

let promise;
beforeEach(() => {
promise = new TripCancelation(client, TripCancelation.makeHref('SYNC', 1)).fetch();
});

it('should resolve the promise', () => promise.should.be.fulfilled);
it('should set the ID', () => promise.then(v => v.id).should.eventually.equal(1));
it('should set the href', () => promise.then(v => v.href).should.eventually.equal('/1/SYNC/serviceadjustments/tripcancelation/1'));
it('should be hydrated', () => promise.then(v => v.hydrated).should.eventually.equal(true));
});
59 changes: 59 additions & 0 deletions src/resources/TripCancelationBatch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import Resource from './Resource';
import TripCancelation from "./TripCancelation";

class TripCancelationBatch extends Resource {
/**
* Creates a new TripCancelationBatch object for fetching/saving trip cancelations
* @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 {code, ...newProperties} = rest;
this.customerCode = code;
const hydrated = !Object.keys(newProperties).every(k => k === 'href' || k === 'customerCode');
const references = {
cancelations: newProperties.cancelations
&& newProperties.cancelations.map(m => new TripCancelation(this.client, m)),
};
Object.assign(this, newProperties, {
hydrated,
...references,
});
}

/**
* Makes a href for a given customer code
* @param {string} customerCode Alphanumeric code of the customer
* @returns {object} href object containing URL for the instance
*/
static makeHref(customerCode) {
return {
href: `/1/${customerCode}/serviceadjustments/tripcancelations`,
code: customerCode,
};
}

/**
* Fetches current trip cancelation data for customer
* @returns {Promise} If successful, a hydrated instance of this trip cancelation batch
*/
fetch() {
return this.client.get(this.href)
.then(response => response.json())
.then(cancelations => new TripCancelationBatch(this.client, {...this, ...cancelations}));
}

/**
* Create new cancelations for customer
* @returns {Promise} If successful, a hydrated instance of this trip cancelation batch
*/
create() {
const {client, hydrated, customerCode, ...body} = this;
return this.client.post(`/1/${this.customerCode}/serviceadjustments/tripcancelations`, {body})
.then(response => response.json())
.then(cancelations => new TripCancelationBatch(this.client, {...this, ...cancelations}));
}
}

export default TripCancelationBatch;
Loading

0 comments on commit 097930d

Please sign in to comment.