liveperson-functions-client
Version:
JavaScript client for LivePerson Functions.
281 lines • 11.4 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jwt = __importStar(require("jsonwebtoken"));
const baseClient_1 = require("../../src/client/baseClient");
const client_1 = require("../../src/client/client");
const csdsClient_1 = require("../../src/helper/csdsClient");
const nock_1 = __importDefault(require("nock"));
const secret = 'mySecret';
const TEST_HOST = 'test123.com';
const ACCOUNT_ID = '123456';
jest.mock('../../src/helper/csdsClient', () => {
return {
CsdsClient: jest.fn().mockImplementation(() => {
return {
get: jest.fn(() => TEST_HOST),
};
}),
};
});
jest.mock('simple-oauth2', () => ({
ClientCredentials: jest.fn(() => ({
getToken: async () => ({
token: {
access_token: jwt.sign({
aud: 'le4711',
azp: 'bf16f923-b256-40c8-afa5-1b8e8372da09',
scope: 'faas.lambda.invoke',
iss: 'Sentinel',
exp: Date.now() / 1000 + 60 * 60,
iat: Date.now(),
}, secret),
},
}),
})),
}));
const testConfig = {
accountId: '123456',
authStrategy: {
clientId: 'foo',
clientSecret: 'bar',
},
};
describe('Client V1 flow', () => {
beforeEach(() => {
nock_1.default.cleanAll();
nock_1.default.enableNetConnect();
});
afterEach(jest.clearAllMocks);
describe('success flows', () => {
test('class and constructor - Base', () => {
const client = new client_1.Client(testConfig);
expect(csdsClient_1.CsdsClient).toHaveBeenCalledTimes(1);
expect(client).toBeInstanceOf(client_1.Client);
expect(client).toBeInstanceOf(baseClient_1.BaseClient);
});
test('invoke method', async () => {
const lpEventSource = 'testSystem';
const externalSystem = 'testSystem2';
const result1 = [123];
const result2 = [456];
const scope = (0, nock_1.default)('https://test123.com', {
reqheaders: {
'Content-Type': 'application/json',
'X-Request-ID': value => true,
Authorization: value => true,
},
})
.post(`/api/account/123456/events/fooBar/invoke?v=1&skillId=&externalSystem=${lpEventSource}`)
.once()
.reply(200, result1)
.persist()
.post(`/api/account/le12345/events/fooBar/invoke?v=1&skillId=&externalSystem=${externalSystem}`)
.once()
.reply(200, result2)
.persist();
const client1 = new client_1.Client(testConfig);
const response1 = client1.invoke({
eventId: 'fooBar',
lpEventSource,
body: {
payload: {},
},
});
await expect(response1).resolves.toBeNonEmptyObject();
expect((await response1).body).toEqual(result1);
const client2 = new client_1.Client({ ...testConfig, accountId: 'le12345' });
const response2 = client2.invoke({
eventId: 'fooBar',
externalSystem,
body: {
payload: {},
},
});
await expect(response2).resolves.toBeNonEmptyObject();
expect((await response2).body).toEqual(result2);
expect(scope.isDone()).toBe(true);
});
test('getLambdas method', async () => {
const lambda = [{ uuid: 'a-b-c-d' }];
const scope = (0, nock_1.default)('https://test123.com')
.get('/api/account/123456/lambdas/?eventId=&state=&externalSystem=testSystem&userId=&v=1')
.once()
.reply(200, lambda)
.persist();
const client = new client_1.Client({ ...testConfig, accountId: ACCOUNT_ID });
const response = client.getLambdas({
externalSystem: 'testSystem',
});
await expect(response).resolves.toBeNonEmptyObject();
expect((await response).body).toEqual(lambda);
expect(scope.isDone()).toBe(true);
});
test('should retry on receiving a network error', async () => {
const errorCode = { code: 'ECONNRESET' };
const scope = (0, nock_1.default)('https://test123.com')
.post('/api/account/123456/lambdas/this-is-a-uuid/invoke?v=1&skillId=&externalSystem=test-system')
.times(3)
.replyWithError(errorCode);
const client = new client_1.Client(testConfig);
const response = await client.invoke({
lambdaUuid: 'this-is-a-uuid',
externalSystem: 'test-system',
body: {
payload: {},
},
});
expect(response.retryCount).toEqual(3);
expect(scope.isDone()).toBe(true);
});
test('invocation metrics', async () => {
const lpEventSource = 'testSystem';
let onInvokeCalled = false;
class MyMetricCollector {
onInvoke(invocationData) {
expect(invocationData.lpEventSource).toEqual(lpEventSource);
expect(invocationData.externalSystem).toBeUndefined();
onInvokeCalled = true;
return;
}
onGetLambdas(invocationData) {
return;
}
onIsImplemented(invocationData) {
return;
}
}
const result1 = [123];
const scope = (0, nock_1.default)('https://test123.com')
.post(`/api/account/123456/events/fooBar/invoke?v=1&skillId=&externalSystem=${lpEventSource}`)
.once()
.reply(202, result1)
.persist();
const client1 = new client_1.Client(testConfig, {
metricCollector: new MyMetricCollector(),
});
await client1.invoke({
eventId: 'fooBar',
lpEventSource,
body: {
payload: {},
},
});
expect(onInvokeCalled).toBe(true);
expect(scope.isDone()).toBe(true);
});
test('invocation metrics should contain deprecated externalSystem', async () => {
const lpEventSource = 'testSystem';
let onInvokeCalled = false;
class MyMetricCollector {
onInvoke(invocationData) {
expect(invocationData.lpEventSource).toEqual(lpEventSource);
expect(invocationData.externalSystem).toEqual(lpEventSource);
onInvokeCalled = true;
return;
}
onGetLambdas(invocationData) {
return;
}
onIsImplemented(invocationData) {
return;
}
}
const result1 = [123];
const scope = (0, nock_1.default)('https://test123.com')
.post(`/api/account/123456/events/fooBar/invoke?v=1&skillId=&externalSystem=${lpEventSource}`)
.once()
.reply(202, result1)
.persist();
const client1 = new client_1.Client(testConfig, {
metricCollector: new MyMetricCollector(),
});
await client1.invoke({
eventId: 'fooBar',
externalSystem: lpEventSource,
body: {
payload: {},
},
});
expect(onInvokeCalled).toBe(true);
expect(scope.isDone()).toBe(true);
});
});
describe('Unhappy flows', () => {
test('should throw if Functions returns a none-okay status code', async () => {
const scope = (0, nock_1.default)('https://test123.com')
.post('/api/account/123456/lambdas/this-is-a-uuid/invoke?v=1&skillId=&externalSystem=test-system')
.times(3)
.reply(502)
.persist();
const config = { ...testConfig, failOnErrorStatusCode: true };
const client = new client_1.Client(config);
try {
await client.invoke({
lambdaUuid: 'this-is-a-uuid',
externalSystem: 'test-system',
body: {
payload: {},
},
});
}
catch (error) {
expect(error).toMatchObject({
name: 'FaaSInvokeError',
message: expect.stringContaining('502 - Bad Gateway'),
});
expect(scope.isDone()).toBe(true);
}
});
test('should throw if network errors are raised continuously', async () => {
const errorCode = { code: 'ECONNRESET' };
const scope = (0, nock_1.default)('https://test123.com')
.post('/api/account/123456/lambdas/this-is-a-uuid/invoke?v=1&skillId=&externalSystem=test-system')
.times(3)
.replyWithError(errorCode);
const config = { ...testConfig, failOnErrorStatusCode: true };
const client = new client_1.Client(config);
try {
await client.invoke({
lambdaUuid: 'this-is-a-uuid',
externalSystem: 'test-system',
body: {
payload: {},
},
});
}
catch (error) {
expect(error).toMatchObject({
name: 'FaaSInvokeError',
});
expect(scope.isDone()).toBe(true);
}
});
});
});
//# sourceMappingURL=client.v1.test.js.map