diff --git a/src/mocks/index.js b/src/mocks/index.js index 0db16fe..5abecff 100644 --- a/src/mocks/index.js +++ b/src/mocks/index.js @@ -13,6 +13,7 @@ export { default as drivers } from './drivers'; export { default as externalApis } from './externalApis'; export { default as incidents } from './incidents'; export { default as messages } from './messages'; +export { default as messageChannels } from './messageChannels'; export { default as patterns } from './patterns'; export { default as reportingTickets } from './reportingTickets'; export { default as realTime } from './realTime'; diff --git a/src/mocks/messageChannels.js b/src/mocks/messageChannels.js new file mode 100644 index 0000000..d4a5af1 --- /dev/null +++ b/src/mocks/messageChannels.js @@ -0,0 +1,23 @@ +// eslint-disable-next-line import/no-extraneous-dependencies +import fetchMock from 'fetch-mock'; +import Client from '../Client'; + +const messageChannels = { + setUpSuccessfulMock: (client) => { + const listResponse = () => new Response( + Client.toBlob(messageChannels.list), { + headers: { + Link: '', + }, + }); + fetchMock + .get(client.resolve('/1/SYNC/message_channels'), listResponse); + }, + getByName: name => messageChannels.list.find(v => v.name === name), + list: [{ + href: '/1/SYNC/message_channels/Signs', + name: 'Signs', + }], +}; + +export default messageChannels; diff --git a/src/resources/Customer.js b/src/resources/Customer.js index 17fe148..5cc23e7 100644 --- a/src/resources/Customer.js +++ b/src/resources/Customer.js @@ -20,6 +20,7 @@ import EnplugScreenshot from './EnplugScreenshot'; import EnplugConfiguration from './EnplugConfiguration'; import Message from './Message'; import MessagesContext from './MessagesContext'; +import MessageChannels from './MessageChannels'; import Pattern from './Pattern'; import PatternsContext from './PatternsContext'; import ReportingTicket from './ReportingTicket'; @@ -233,6 +234,14 @@ class Customer extends Resource { return this.resource(Incident, Incident.makeHref(this.code, id)); } + /** + * Gets a customers available message channels by its code. + * @returns {MessageChannels} for fetching this customer's message channels + */ + messageChannels() { + return this.resource(MessageChannels, MessageChannels.makeHref(this.code)); + } + /** * Gets a context for querying this customer's messages * @returns {MessagesContext} Context for querying this customer's messages diff --git a/src/resources/MessageChannels.js b/src/resources/MessageChannels.js new file mode 100644 index 0000000..a22a20c --- /dev/null +++ b/src/resources/MessageChannels.js @@ -0,0 +1,54 @@ +import Resource from './Resource'; + +/** + * MessageChannels resource + */ +class MessageChannels extends Resource { + /** + * Creates a new MessageChannels. + * + * Will populate itself with the values given to it after the client parameter + * @example Assigning partial message channels data to a new instance + * const client = new Client(); + * const partialMessageChannelsData = [{ + * href: '/1/SYNC/message_channel/GTFS-RT', + * name: 'GTFS-RT', + * }]; + * const messageChannel = new MessageChannel(client, partialMessageChannelsData); + * messageChannel.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' || k === 'code'); + + Object.assign(this, newProperties, { hydrated }); + } + + /** + * Makes a href for a given customer code + * @param {string} customerCode Customer code + * @returns {{href: string}} URI to instance of messageChannels + */ + static makeHref(customerCode) { + return { + href: `/1/${customerCode}/message_channels`, + }; + } + + /** + * Fetches the data for this message channel via the client + * @returns {Promise} If successful, a hydrated instance of this messageChannels + */ + fetch() { + return this.client.get(this.href) + .then(response => response.json()) + .then(messageChannels => new MessageChannels(this.client, this, messageChannels)); + } +} + +export default MessageChannels; diff --git a/src/resources/MessageChannels.test.js b/src/resources/MessageChannels.test.js new file mode 100644 index 0000000..a1e8cc5 --- /dev/null +++ b/src/resources/MessageChannels.test.js @@ -0,0 +1,34 @@ +import chai from 'chai'; +import fetchMock from 'fetch-mock'; +import chaiAsPromised from 'chai-as-promised'; +import Client from '../Client'; +import MessageChannels from './MessageChannels'; +import { messageChannels as mockMessageChannels } from '../mocks'; + +chai.should(); +chai.use(chaiAsPromised); + +describe('When instantiating a message channel based on customer and name', () => { + const client = new Client(); + const messageChannels = new MessageChannels(client, MessageChannels.makeHref('SYNC')); + + it('should set the href', () => messageChannels.href.should.equal('/1/SYNC/message_channels')); + it('should not be hydrated', () => messageChannels.hydrated.should.equal(false)); +}); + +describe('When fetching message channels based on customer', () => { + const client = new Client(); + + beforeEach(() => mockMessageChannels.setUpSuccessfulMock(client)); + beforeEach(() => fetchMock.catch(503)); + afterEach(fetchMock.restore); + + let promise; + beforeEach(() => { + promise = new MessageChannels(client, MessageChannels.makeHref('SYNC')).fetch(); + }); + + it('should resolve the promise', () => promise.should.be.fulfilled); + it('should set the href', () => promise.then(v => v.href).should.eventually.equal('/1/SYNC/message_channels')); + it('should be hydrated', () => promise.then(v => v.hydrated).should.eventually.equal(true)); +});