UNPKG

wa-chat-server

Version:

Watson Assistant powered chat server

439 lines (438 loc) 22.9 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WatsonWrapperTest = void 0; const ConversationServiceMock_1 = require("../mock/ConversationServiceMock"); const ConversationServicesMock_1 = require("../mock/ConversationServicesMock"); const ConversationAPIMock_1 = require("../mock/ConversationAPIMock"); const MessageResponseMock_1 = require("../mock/MessageResponseMock"); const MessageRequestMock_1 = require("../mock/MessageRequestMock"); const WAChatServerConfigMock_1 = require("../mock/WAChatServerConfigMock"); const WatsonWrapper_1 = require("../../class/WatsonWrapper"); const ConversationServiceValidationException_1 = require("../../exception/ConversationServiceValidationException"); const ConversationServiceRuntimeException_1 = require("../../exception/ConversationServiceRuntimeException"); const SchemaValidationException_1 = require("../../exception/SchemaValidationException"); const Logger_1 = require("../../class/Logger/Logger"); const LoggerDriverMock_1 = require("../mock/LoggerDriverMock"); const SessionMock_1 = require("../mock/SessionMock"); class WatsonWrapperTest { constructor() { this.schemaDir = ''; this.config = new WAChatServerConfigMock_1.WAChatServerConfigMock(); } getLogger(check = false, silence = true) { return new Logger_1.Logger(this.config, new LoggerDriverMock_1.LoggerDriverMock(check, silence)); } getWatsonSimpleRequest(extraParams = {}) { return { output: { generic: [ { // eslint-disable-next-line @typescript-eslint/camelcase response_type: 'text', text: 'Ignored', }, ], }, context: Object.assign({ 'request-service': 'SERVICE_NAME', 'request-params-PARAM1': 'VALUE1' }, extraParams), }; } getWatsonSimpleRequestCleanedCtx(extraParams = {}) { const retVal = { 'request-service': null, 'request-params-PARAM1': null, }; Object.keys(extraParams).forEach((key) => { retVal[key] = null; }); return retVal; } getSimpleJsonSchema(type) { return { type: 'object', properties: { PARAM1: { type }, }, }; } getWatsonComplexRequest() { return this.getWatsonSimpleRequest({ 'request-params-PARAM2-PARAM3': 'VALUE3', }); } /** * Parameters from meta are added to Watson context */ metaParametersTest() { it('meta-parameters', () => __awaiter(this, void 0, void 0, function* () { const services = new ConversationServicesMock_1.ConversationServicesMock(); const meta = { url: 'URL', userAgent: 'AGENT', resolution: 'RESOLUTION', }; const adapter = new ConversationAPIMock_1.ConversationAPIMock() .addResponse(MessageResponseMock_1.MessageResponseMock.okResponseWithResult(Object.assign(Object.assign({}, this.getWatsonSimpleRequest()), { context: {} }))) .addRequestValidator((msg) => { const client = msg.context.client; return expect(client).toStrictEqual(meta); }); const request = new MessageRequestMock_1.MessageRequestMock(); const session = new SessionMock_1.SessionMock(); const watson = new WatsonWrapper_1.WatsonWrapper(this.getLogger(), adapter, services, [], [], request, meta, session); yield watson.getResponse(); })); } /** * An exception must be thrown if the watson context variable $request-service specifies * an unknown service */ conversationServiceUnknownServiceTest() { it('conversation-service-unknown-service', () => __awaiter(this, void 0, void 0, function* () { const services = new ConversationServicesMock_1.ConversationServicesMock(); const adapter = new ConversationAPIMock_1.ConversationAPIMock().addResponse(MessageResponseMock_1.MessageResponseMock.okResponseWithResult(this.getWatsonSimpleRequest())); const request = new MessageRequestMock_1.MessageRequestMock(); const session = new SessionMock_1.SessionMock(); const watson = new WatsonWrapper_1.WatsonWrapper(this.getLogger(), adapter, services, [], [], request, null, session); return expect(watson.getResponse()).rejects.toStrictEqual(new ConversationServiceValidationException_1.ConversationServiceValidationException("Conversation service 'SERVICE_NAME' received in $request-service not registered")); })); } /** * Verifies that the watson context variables $request-params-* are correctly transformed to * the conversation service request */ conversationServiceRequestComputationTest() { it('conversation-service-request-computation', () => __awaiter(this, void 0, void 0, function* () { expect.assertions(1); const services = new ConversationServicesMock_1.ConversationServicesMock(); const service = new ConversationServiceMock_1.ConversationServiceMock({ logger: this.getLogger(), services, requestValidation: false, responseValidation: false, }); service.requestValidator = (request) => { return expect(request).toStrictEqual({ PARAM1: 'VALUE1', PARAM2: { PARAM3: 'VALUE3' }, }); }; services.serviceMock = service; yield service.loadSchemas(); const adapter = new ConversationAPIMock_1.ConversationAPIMock().addResponse(MessageResponseMock_1.MessageResponseMock.okResponseWithResult(this.getWatsonComplexRequest())); const request = new MessageRequestMock_1.MessageRequestMock(); const session = new SessionMock_1.SessionMock(); const watson = new WatsonWrapper_1.WatsonWrapper(this.getLogger(), adapter, services, [], [], request, null, session); yield watson.getResponse(); })); } /** * Tests that en error is throws if the conversation service requires a request validation * and the request is not in line with the corresponding JSON schema */ conversationServiceInvalidRequestTest() { it('conversation-service-invalid-request', () => __awaiter(this, void 0, void 0, function* () { expect.assertions(1); const services = new ConversationServicesMock_1.ConversationServicesMock(); const service = new ConversationServiceMock_1.ConversationServiceMock({ logger: this.getLogger(), services, requestValidation: true, responseValidation: false, }); services.serviceMock = service; services.schemaPathToSchema.set(`${this.schemaDir}/request/Mock.json`, JSON.stringify(this.getSimpleJsonSchema('number'))); yield service.loadSchemas(); const adapter = new ConversationAPIMock_1.ConversationAPIMock() .addResponse(MessageResponseMock_1.MessageResponseMock.okResponseWithResult(this.getWatsonSimpleRequest())) .addRequestValidator(() => null) .addRequestValidator((msg) => { const errorText = msg.context.response.error; return expect(errorText.startsWith('Error: Conversation service Mock: request validation failed - ')).toStrictEqual(true); }); const request = new MessageRequestMock_1.MessageRequestMock(); const session = new SessionMock_1.SessionMock(); const watson = new WatsonWrapper_1.WatsonWrapper(this.getLogger(), adapter, services, [], [], request, null, session); yield watson.getResponse(); })); } /** * Tests that a simple conversation service with no request/response validation results in * a second watson call and that the service response is correctly mapped to the watson context * of this second call */ conversationServiceWithoutValidationTest() { it('conversation-service-without-validation', () => __awaiter(this, void 0, void 0, function* () { expect.assertions(1); const services = new ConversationServicesMock_1.ConversationServicesMock(); const service = new ConversationServiceMock_1.ConversationServiceMock({ logger: this.getLogger(), services, requestValidation: false, responseValidation: false, }); service.response = { a: 'A' }; services.serviceMock = service; yield service.loadSchemas(); const adapter = new ConversationAPIMock_1.ConversationAPIMock() .addResponse(MessageResponseMock_1.MessageResponseMock.okResponseWithResult(this.getWatsonSimpleRequest())) .addRequestValidator(() => null) .addRequestValidator((msg) => { const { context, intents } = msg; return expect({ context, intents }).toStrictEqual({ context: Object.assign({ response: { result: { a: 'A' }, } }, this.getWatsonSimpleRequestCleanedCtx()), intents: [ { intent: 'response1', confidence: 1.0, }, ], }); }); const request = new MessageRequestMock_1.MessageRequestMock(); const session = new SessionMock_1.SessionMock(); const watson = new WatsonWrapper_1.WatsonWrapper(this.getLogger(), adapter, services, [], [], request, null, session); yield watson.getResponse(); })); } /** * An error must be thrown if the conversation service requires a response validation and * the returned object is not in line with the corresponding JSON schema */ conversationServiceInvalidResponseTest() { it('conversation-service-invalid-response', () => __awaiter(this, void 0, void 0, function* () { expect.assertions(1); const services = new ConversationServicesMock_1.ConversationServicesMock(); const service = new ConversationServiceMock_1.ConversationServiceMock({ logger: this.getLogger(), services, requestValidation: false, responseValidation: true, }); service.response = { PARAM1: 'A' }; services.serviceMock = service; services.schemaPathToSchema.set(`${this.schemaDir}/response/Mock.json`, JSON.stringify(this.getSimpleJsonSchema('number'))); yield service.loadSchemas(); const adapter = new ConversationAPIMock_1.ConversationAPIMock().addResponse(MessageResponseMock_1.MessageResponseMock.okResponseWithResult(this.getWatsonSimpleRequest())); const request = new MessageRequestMock_1.MessageRequestMock(); const session = new SessionMock_1.SessionMock(); const watson = new WatsonWrapper_1.WatsonWrapper(this.getLogger(), adapter, services, [], [], request, null, session); try { yield watson.getResponse(); } catch (e) { const instanceTest = e instanceof SchemaValidationException_1.SchemaValidationException; const text = 'Error: Conversation service Mock: response validation failed - '; const textTest = e.toString().startsWith(text); return expect(instanceTest && textTest).toStrictEqual(true); } })); } /** * The failure of the conversation service must result in a second watson call; information about * the failure must be correclty propagated to the watson context */ conversationServiceFailureTest() { it('conversation-service-failure', () => __awaiter(this, void 0, void 0, function* () { expect.assertions(1); const services = new ConversationServicesMock_1.ConversationServicesMock(); const service = new ConversationServiceMock_1.ConversationServiceMock({ logger: this.getLogger(), services, requestValidation: false, responseValidation: false, }); service.response = new Error('E'); services.serviceMock = service; yield service.loadSchemas(); const adapter = new ConversationAPIMock_1.ConversationAPIMock() .addResponse(MessageResponseMock_1.MessageResponseMock.okResponseWithResult(this.getWatsonSimpleRequest())) .addRequestValidator(() => null) .addRequestValidator((msg) => { const { context, intents } = msg; return expect({ context, intents }).toStrictEqual({ context: Object.assign({ response: { error: 'Error: E' } }, this.getWatsonSimpleRequestCleanedCtx()), intents: [ { intent: 'error1', confidence: 1.0, }, ], }); }); const request = new MessageRequestMock_1.MessageRequestMock(); const session = new SessionMock_1.SessionMock(); const watson = new WatsonWrapper_1.WatsonWrapper(this.getLogger(), adapter, services, [], [], request, null, session); yield watson.getResponse(); })); } conversationServiceResponseMappingToRootTest() { it('conversation-service-response-mapping-to-root', () => __awaiter(this, void 0, void 0, function* () { expect.assertions(1); const services = new ConversationServicesMock_1.ConversationServicesMock(); const service = new ConversationServiceMock_1.ConversationServiceMock({ logger: this.getLogger(), services, requestValidation: false, responseValidation: false, }); service.response = { a: 'A' }; services.serviceMock = service; yield service.loadSchemas(); const adapter = new ConversationAPIMock_1.ConversationAPIMock() .addResponse(MessageResponseMock_1.MessageResponseMock.okResponseWithResult(this.getWatsonSimpleRequest({ 'request-resultTarget': '', }))) .addRequestValidator(() => null) .addRequestValidator((msg) => { const { context, intents } = msg; return expect({ context, intents }).toStrictEqual({ context: Object.assign({ a: 'A' }, this.getWatsonSimpleRequestCleanedCtx({ 'request-resultTarget': '', })), intents: [ { intent: 'response1', confidence: 1.0, }, ], }); }); const request = new MessageRequestMock_1.MessageRequestMock(); const session = new SessionMock_1.SessionMock(); const watson = new WatsonWrapper_1.WatsonWrapper(this.getLogger(), adapter, services, [], [], request, null, session); yield watson.getResponse(); })); } conversationServiceResponseMappingToCustomLocTest() { it('conversation-service-response-mapping-to-custom-location', () => __awaiter(this, void 0, void 0, function* () { expect.assertions(1); const services = new ConversationServicesMock_1.ConversationServicesMock(); const service = new ConversationServiceMock_1.ConversationServiceMock({ logger: this.getLogger(), services, requestValidation: false, responseValidation: false, }); service.response = { a: 'A' }; services.serviceMock = service; yield service.loadSchemas(); const adapter = new ConversationAPIMock_1.ConversationAPIMock() .addResponse(MessageResponseMock_1.MessageResponseMock.okResponseWithResult(this.getWatsonSimpleRequest({ 'request-resultTarget': 'my.special.location', }))) .addRequestValidator(() => null) .addRequestValidator((msg) => { const { context, intents } = msg; return expect({ context, intents }).toStrictEqual({ context: Object.assign({ my: { special: { location: { a: 'A', }, }, } }, this.getWatsonSimpleRequestCleanedCtx({ 'request-resultTarget': 'my.special.location', })), intents: [ { intent: 'response1', confidence: 1.0, }, ], }); }); const request = new MessageRequestMock_1.MessageRequestMock(); const session = new SessionMock_1.SessionMock(); const watson = new WatsonWrapper_1.WatsonWrapper(this.getLogger(), adapter, services, [], [], request, null, session); yield watson.getResponse(); })); } conversationServiceErrorMappingToCustomLocTest() { it('conversation-service-error-mapping-to-custom-location', () => __awaiter(this, void 0, void 0, function* () { expect.assertions(1); const services = new ConversationServicesMock_1.ConversationServicesMock(); const service = new ConversationServiceMock_1.ConversationServiceMock({ logger: this.getLogger(), services, requestValidation: false, responseValidation: false, }); service.response = new Error('E'); services.serviceMock = service; yield service.loadSchemas(); const adapter = new ConversationAPIMock_1.ConversationAPIMock() .addResponse(MessageResponseMock_1.MessageResponseMock.okResponseWithResult(this.getWatsonSimpleRequest({ 'request-errorTarget': 'my.error', }))) .addRequestValidator(() => null) .addRequestValidator((msg) => { const { context, intents } = msg; return expect({ context, intents }).toStrictEqual({ context: Object.assign({ my: { error: 'Error: E' } }, this.getWatsonSimpleRequestCleanedCtx({ 'request-errorTarget': 'my.error', })), intents: [ { intent: 'error1', confidence: 1.0, }, ], }); }); const request = new MessageRequestMock_1.MessageRequestMock(); const session = new SessionMock_1.SessionMock(); const watson = new WatsonWrapper_1.WatsonWrapper(this.getLogger(), adapter, services, [], [], request, null, session); yield watson.getResponse(); })); } conversationServiceUnsupportedPrimitiveResponseMappingTest() { it('conversation-service-unsupported-primitive-response-mapping', () => __awaiter(this, void 0, void 0, function* () { expect.assertions(1); const services = new ConversationServicesMock_1.ConversationServicesMock(); const service = new ConversationServiceMock_1.ConversationServiceMock({ logger: this.getLogger(), services, requestValidation: false, responseValidation: false, }); service.response = 0; services.serviceMock = service; yield service.loadSchemas(); const adapter = new ConversationAPIMock_1.ConversationAPIMock().addResponse(MessageResponseMock_1.MessageResponseMock.okResponseWithResult(this.getWatsonSimpleRequest({ 'request-resultTarget': '', }))); const request = new MessageRequestMock_1.MessageRequestMock(); const session = new SessionMock_1.SessionMock(); const watson = new WatsonWrapper_1.WatsonWrapper(this.getLogger(), adapter, services, [], [], request, null, session); return expect(watson.getResponse()).rejects.toStrictEqual(new ConversationServiceRuntimeException_1.ConversationServiceRuntimeException("Not possible to map primitive value '0' to context")); })); } test() { return __awaiter(this, void 0, void 0, function* () { this.metaParametersTest(); this.conversationServiceUnknownServiceTest(); this.conversationServiceRequestComputationTest(); this.conversationServiceInvalidRequestTest(); this.conversationServiceWithoutValidationTest(); this.conversationServiceInvalidResponseTest(); this.conversationServiceFailureTest(); this.conversationServiceResponseMappingToRootTest(); this.conversationServiceResponseMappingToCustomLocTest(); this.conversationServiceErrorMappingToCustomLocTest(); this.conversationServiceUnsupportedPrimitiveResponseMappingTest(); }); } } exports.WatsonWrapperTest = WatsonWrapperTest; new WatsonWrapperTest().test();