Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

# [Unreleased](https://github.com/purecloudlabs/genesys-cloud-streaming-client/compare/v19.7.1...HEAD)
# [Unreleased](https://github.com/purecloudlabs/genesys-cloud-streaming-client/compare/v19.8.0...HEAD)

# [v19.8.0](https://github.com/purecloudlabs/genesys-cloud-streaming-client/compare/v19.7.1...v19.8.0)
### Added
* [STREAM-1661](https://inindca.atlassian.net/browse/STREAM-1661) - Expose current alerting leader status rather than exposing a snapshot of the value. The previous property is now deprecated.

# [v19.7.1](https://github.com/purecloudlabs/genesys-cloud-streaming-client/compare/v19.7.0...v19.7.1)
### Changed
Expand Down
4 changes: 2 additions & 2 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": "genesys-cloud-streaming-client",
"version": "19.7.1",
"version": "19.8.0",
"description": "client for the Genesys Cloud Streaming APIs (websocket/xmpp interface)",
"repository": "https:github.com/purecloudlabs/genesys-cloud-streaming-client",
"license": "MIT",
Expand Down
4 changes: 4 additions & 0 deletions src/alerting-leader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ export class AlertingLeaderExtension extends EventEmitter implements StreamingCl
on: this.on.bind(this),
off: this.off.bind(this),
claimAlertingLeader: this.claimAlertingLeader.bind(this),
getLeaderStatus: () => { return this.leaderStatus; },
leaderStatus: this.leaderStatus
};
}
Expand All @@ -164,5 +165,8 @@ export interface AlertingLeaderApi {
on: (event: string, handler: (...args: any) => void) => void;
off: (event: string, handler: (...args: any) => void) => void;
claimAlertingLeader (): Promise<void>;
getLeaderStatus (): ILeaderStatus;

/* @deprecated Use {@link getLeaderStatus} */
leaderStatus: ILeaderStatus;
}
40 changes: 25 additions & 15 deletions test/unit/alerting-leader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,11 @@ describe('AlertingLeader', () => {
const clientOptions = { alertableInteractionTypes: [ AlertableInteractionTypes.voice ] };
const fakeClient = new FakeClient({ apiHost: 'example.com' }) as unknown as Client;
const alertingLeader = new AlertingLeaderExtension(fakeClient, clientOptions as IClientOptions);
const alertingLeaderExposedApi = alertingLeader.expose;
const expectedPayload = { voice: { alerting: true, configured: false } };

expect.assertions(4);
alertingLeader.expose.on('alertingLeaderChanged', (event) => {
alertingLeaderExposedApi.on('alertingLeaderChanged', (event) => {
expect(event).toMatchObject(expectedPayload);
});

Expand All @@ -124,7 +125,7 @@ describe('AlertingLeader', () => {
alertingLeader['getAlertingLeader'] = jest.fn().mockRejectedValue({});
await alertingLeader['setupAlertingLeader']();

expect(alertingLeader.expose.leaderStatus).toMatchObject(expectedPayload);
expect(alertingLeaderExposedApi.getLeaderStatus()).toMatchObject(expectedPayload);
});

it('should not set up alerting leader if not configured', async () => {
Expand Down Expand Up @@ -165,6 +166,7 @@ describe('AlertingLeader', () => {
fakeClient.config.userId = userId;
const alertingLeader = new AlertingLeaderExtension(fakeClient, {} as IClientOptions);
alertingLeader['connectionId'] = connectionId;
const alertingLeaderExposedApi = alertingLeader.expose;
fakeClient._notifications._subscribeInternal = jest.fn().mockResolvedValue({});
const hawkPayload = {
eventBody: {
Expand All @@ -175,14 +177,14 @@ describe('AlertingLeader', () => {
const expectedEventPayload = { voice: { alerting: true, configured: true } };

expect.assertions(2);
alertingLeader.expose.on('alertingLeaderChanged', (event) => {
alertingLeaderExposedApi.on('alertingLeaderChanged', (event) => {
expect(event).toMatchObject(expectedEventPayload);
});

await alertingLeader['subscribeToAlertingLeader']();
fakeClient.emit(`notify:v2.users.${userId}.alertingleader`, hawkPayload);

expect(alertingLeader.expose.leaderStatus).toStrictEqual(expectedEventPayload);
expect(alertingLeaderExposedApi.getLeaderStatus()).toStrictEqual(expectedEventPayload);
});

it('should include the clientType if present', async () => {
Expand All @@ -193,6 +195,7 @@ describe('AlertingLeader', () => {
fakeClient.config.userId = userId;
const alertingLeader = new AlertingLeaderExtension(fakeClient, {} as IClientOptions);
alertingLeader['connectionId'] = connectionId;
const alertingLeaderExposedApi = alertingLeader.expose;
fakeClient._notifications._subscribeInternal = jest.fn().mockResolvedValue({});
const hawkPayload = {
eventBody: {
Expand All @@ -204,14 +207,14 @@ describe('AlertingLeader', () => {
const expectedEventPayload = { voice: { alerting: true, configured: true, clientType } };

expect.assertions(2);
alertingLeader.expose.on('alertingLeaderChanged', (event) => {
alertingLeaderExposedApi.on('alertingLeaderChanged', (event) => {
expect(event).toMatchObject(expectedEventPayload);
});

await alertingLeader['subscribeToAlertingLeader']();
fakeClient.emit(`notify:v2.users.${userId}.alertingleader`, hawkPayload);

expect(alertingLeader.expose.leaderStatus).toStrictEqual(expectedEventPayload);
expect(alertingLeaderExposedApi.getLeaderStatus()).toStrictEqual(expectedEventPayload);
});

it('should not emit its own event if there is no eventBody', async () => {
Expand All @@ -221,12 +224,13 @@ describe('AlertingLeader', () => {
fakeClient.config.userId = userId;
const alertingLeader = new AlertingLeaderExtension(fakeClient, {} as IClientOptions);
alertingLeader['connectionId'] = connectionId;
const alertingLeaderExposedApi = alertingLeader.expose;
fakeClient._notifications._subscribeInternal = jest.fn().mockResolvedValue({});
const hawkPayload = {};

expect.assertions(1);
const eventSpy = jest.fn();
alertingLeader.expose.on('alertingLeaderChanged', eventSpy);
alertingLeaderExposedApi.on('alertingLeaderChanged', eventSpy);

await alertingLeader['subscribeToAlertingLeader']();
fakeClient.emit(`notify:v2.users.${userId}.alertingleader`, hawkPayload);
Expand All @@ -241,6 +245,7 @@ describe('AlertingLeader', () => {
fakeClient.config.userId = userId;
const alertingLeader = new AlertingLeaderExtension(fakeClient, {} as IClientOptions);
alertingLeader['connectionId'] = connectionId;
const alertingLeaderExposedApi = alertingLeader.expose;
fakeClient._notifications._subscribeInternal = jest.fn().mockResolvedValue({});
const hawkPayload = {
eventBody: {
Expand All @@ -254,7 +259,7 @@ describe('AlertingLeader', () => {
const axiosMock = new AxiosMockAdapter(axios);
axiosMock.onGet(alertingLeaderUrl).reply(200, { connectionId });
const eventSpy = jest.fn();
alertingLeader.expose.on('alertingLeaderChanged', eventSpy);
alertingLeaderExposedApi.on('alertingLeaderChanged', eventSpy);

await alertingLeader['subscribeToAlertingLeader']();
const getLeaderPromise = alertingLeader['getAlertingLeader']();
Expand Down Expand Up @@ -355,15 +360,16 @@ describe('AlertingLeader', () => {
const clientOptions = { alertableInteractionTypes: [ AlertableInteractionTypes.voice ] };
const alertingLeader = new AlertingLeaderExtension(fakeClient, clientOptions as IClientOptions);
alertingLeader['connectionId'] = connectionId;
const alertingLeaderExposedApi = alertingLeader.expose;
const expectedPayload = { voice: { alerting: true, configured: true, clientType } };

expect.assertions(2);
alertingLeader.expose.on('alertingLeaderChanged', (event) => {
alertingLeaderExposedApi.on('alertingLeaderChanged', (event) => {
expect(event).toStrictEqual(expectedPayload);
});
await alertingLeader['getAlertingLeader']();

expect(alertingLeader.expose.leaderStatus).toMatchObject(expectedPayload);
expect(alertingLeaderExposedApi.getLeaderStatus()).toMatchObject(expectedPayload);
axiosMock.restore();
});

Expand All @@ -376,15 +382,16 @@ describe('AlertingLeader', () => {
const clientOptions = { alertableInteractionTypes: [ AlertableInteractionTypes.voice ] };
const alertingLeader = new AlertingLeaderExtension(fakeClient, clientOptions as IClientOptions);
alertingLeader['connectionId'] = connectionId;
const alertingLeaderExposedApi = alertingLeader.expose;
const expectedPayload = { voice: { alerting: false, configured: true } };

expect.assertions(2);
alertingLeader.expose.on('alertingLeaderChanged', (event) => {
alertingLeaderExposedApi.on('alertingLeaderChanged', (event) => {
expect(event).toStrictEqual(expectedPayload);
});
await alertingLeader['getAlertingLeader']();

expect(alertingLeader.expose.leaderStatus).toMatchObject(expectedPayload);
expect(alertingLeaderExposedApi.getLeaderStatus()).toMatchObject(expectedPayload);
axiosMock.restore();
});

Expand Down Expand Up @@ -421,8 +428,9 @@ describe('AlertingLeader', () => {
const clientOptions = { alertableInteractionTypes: [ AlertableInteractionTypes.voice ] };
const alertingLeader = new AlertingLeaderExtension(fakeClient, clientOptions as IClientOptions);
alertingLeader['connectionId'] = connectionId;
const alertingLeaderExposedApi = alertingLeader.expose;

alertingLeader.expose.claimAlertingLeader();
alertingLeaderExposedApi.claimAlertingLeader();

expect(httpSpy.mock.calls[0][0]).toBe(alertingLeaderPath);
expect(httpSpy.mock.calls[0][1]).toMatchObject({ data: { connectionId: connectionId } });
Expand All @@ -437,9 +445,10 @@ describe('AlertingLeader', () => {
fakeClient.http.requestApi = httpSpy;
const alertingLeader = new AlertingLeaderExtension(fakeClient, {} as IClientOptions);
alertingLeader['connectionId'] = connectionId;
const alertingLeaderExposedApi = alertingLeader.expose;

try {
await alertingLeader.expose.claimAlertingLeader();
await alertingLeaderExposedApi.claimAlertingLeader();
} catch (err) {
expect(err).toBeInstanceOf(StreamingClientError);
expect((err as any)['type']).toBe(StreamingClientErrorTypes.generic);
Expand All @@ -459,9 +468,10 @@ describe('AlertingLeader', () => {
const clientOptions = { alertableInteractionTypes: [ AlertableInteractionTypes.voice ] };
const alertingLeader = new AlertingLeaderExtension(fakeClient, clientOptions as IClientOptions);
alertingLeader['connectionId'] = connectionId;
const alertingLeaderExposedApi = alertingLeader.expose;

try {
await alertingLeader.expose.claimAlertingLeader();
await alertingLeaderExposedApi.claimAlertingLeader();
} catch (err) {
expect(err).toBeInstanceOf(StreamingClientError);
expect((err as any)['type']).toBe(StreamingClientErrorTypes.generic);
Expand Down
Loading