From e2312579002432105bb23350d39d24935bfac2b3 Mon Sep 17 00:00:00 2001 From: Angelito Salud Date: Thu, 12 Dec 2019 16:42:21 +0800 Subject: [PATCH] applied crank utils --- package-lock.json | 5 + package.json | 1 + src/client/constants/operators.ts | 8 ++ src/core/base-step.ts | 61 ++---------- src/steps/lead-field-equals.ts | 10 +- test/client/client-wrapper.ts | 149 ++++++++++++++++++++---------- 6 files changed, 132 insertions(+), 102 deletions(-) create mode 100644 src/client/constants/operators.ts diff --git a/package-lock.json b/package-lock.json index 40baeec..9617f58 100644 --- a/package-lock.json +++ b/package-lock.json @@ -164,6 +164,11 @@ "tslib": "^1.8.1" } }, + "@run-crank/utilities": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@run-crank/utilities/-/utilities-0.1.0.tgz", + "integrity": "sha512-BVFb2pCQmf1CUZFoBZu4II21q6nQcjXC4jUZbuL/wSvI2qHSL1TXRq9tjBR5ywLcjVLylIB8i1whsh/q9pAxdQ==" + }, "@sinonjs/commons": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.6.0.tgz", diff --git a/package.json b/package.json index f0bf167..9da6c64 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "typescript": "^3.5.1" }, "dependencies": { + "@run-crank/utilities": "^0.1.0", "adal-node": "^0.2.1", "chai-as-promised": "^7.1.1", "dynamics-web-api": "^1.5.10", diff --git a/src/client/constants/operators.ts b/src/client/constants/operators.ts new file mode 100644 index 0000000..5bbdbbc --- /dev/null +++ b/src/client/constants/operators.ts @@ -0,0 +1,8 @@ +export const baseOperators = [ + 'be', + 'not be', + 'contain', + 'not contain', + 'be less than', + 'be greater than', +]; diff --git a/src/core/base-step.ts b/src/core/base-step.ts index 38392db..03740d8 100644 --- a/src/core/base-step.ts +++ b/src/core/base-step.ts @@ -1,7 +1,7 @@ import { StepDefinition, FieldDefinition, Step as PbStep, RunStepResponse } from '../proto/cog_pb'; import { Value } from 'google-protobuf/google/protobuf/struct_pb'; import { ClientWrapper } from '../client/client-wrapper'; -import * as moment from 'moment'; +import * as util from '@run-crank/utilities'; export interface StepInterface { getId(): string; @@ -23,25 +23,13 @@ export abstract class BaseStep { protected stepType: StepDefinition.Type; protected expectedFields: Field[]; - operatorFailMessages = { - be: 'Expected %s field to be %s, but it was actually %s', - notbe: 'Expected %s field not to be %s, but it was also %s', - contain: 'Expected %s field to contain %s, but it is not contained in %s', - notcontain: 'Expected %s field not to contain %s, but it is contained in %s', - begreaterthan: '%s field is expected to be greater than %s, but its value was %s', - belessthan: '%s field is expected to be less than %s, but its value was %s', - }; - - operatorSuccessMessages = { - be: 'The %s field was set to %s, as expected', - notbe: 'The %s field was not set to %s, as expected', - contain: 'The %s field contains %s, as expected', - notcontain: 'The %s field does not contain %s, as expected', - begreaterthan: 'The %s field was greater than %s, as expected', - belessthan: 'The %s field was less than %s, as expected', - }; - - constructor(protected client: ClientWrapper) {} + public operatorFailMessages; + public operatorSuccessMessages; + + constructor(protected client: ClientWrapper) { + this.operatorFailMessages = util.operatorFailMessages; + this.operatorSuccessMessages = util.operatorSuccessMessages; + } getId(): string { return this.constructor.name; @@ -72,38 +60,7 @@ export abstract class BaseStep { } compare(operator: string, actualValue: string, value:string): boolean { - const validOperators = ['be', 'not be', 'contain', 'not contain', 'be greater than', 'be less than']; - const dateTimeFormat = /\d{4}-\d{2}-\d{2}(?:.?\d{2}:\d{2}:\d{2})?/; - - if (validOperators.includes(operator.toLowerCase())) { - if (operator == 'be') { - return actualValue == value; - } else if (operator == 'not be') { - return actualValue != value; - } else if (operator == 'contain') { - return actualValue.includes(value); - } else if (operator == 'not contain') { - return !actualValue.includes(value); - } else if (operator == 'be greater than') { - if (dateTimeFormat.test(actualValue) && dateTimeFormat.test(value)) { - return moment(actualValue).isAfter(value); - } else if (!isNaN(Number(actualValue)) && !isNaN(Number(value))) { - return parseFloat(actualValue) > parseFloat(value); - } else { - throw new Error(`Couldn't check that ${actualValue} > ${value}. The ${operator} operator can only be used with numeric or date values.`); - } - } else if (operator == 'be less than') { - if (dateTimeFormat.test(actualValue) && dateTimeFormat.test(value)) { - return moment(actualValue).isBefore(value); - } else if (!isNaN(Number(actualValue)) && !isNaN(Number(value))) { - return parseFloat(actualValue) < parseFloat(value); - } else { - throw new Error(`Couldn't check that ${actualValue} < ${value}. The ${operator} operator can only be used with numeric or date values.`); - } - } - } else { - throw new Error(`${operator}" is an invalid operator. Please provide one of: ${validOperators.join(', ')}`); - } + return util.compare(operator, actualValue, value); } protected pass(message: string, messageArgs: any[] = []): RunStepResponse { diff --git a/src/steps/lead-field-equals.ts b/src/steps/lead-field-equals.ts index 4f9863c..857c0c8 100644 --- a/src/steps/lead-field-equals.ts +++ b/src/steps/lead-field-equals.ts @@ -2,6 +2,8 @@ import { BaseStep, Field, StepInterface } from '../core/base-step'; import { Step, FieldDefinition, StepDefinition, RunStepResponse } from '../proto/cog_pb'; +import * as util from '@run-crank/utilities'; +import { baseOperators } from '../client/constants/operators'; export class LeadFieldEquals extends BaseStep implements StepInterface { @@ -53,7 +55,13 @@ export class LeadFieldEquals extends BaseStep implements StepInterface { ]); } } catch (e) { - return this.error('There was a problem checking the Lead: %s', [e.toString()]); + if (e instanceof util.UnknownOperatorError) { + return this.error('%s Please provide one of: %s', [e.message, baseOperators.join(', ')]); + } + if (e instanceof util.InvalidOperandError) { + return this.error('There was an error during validation of account field: %s', [e.message]); + } + return this.error('There was an error during validation of account field: %s', [e.message]); } } diff --git a/test/client/client-wrapper.ts b/test/client/client-wrapper.ts index 415d9eb..2469f77 100644 --- a/test/client/client-wrapper.ts +++ b/test/client/client-wrapper.ts @@ -1,49 +1,100 @@ -import * as chai from 'chai'; -import { default as sinon } from 'ts-sinon'; -import * as sinonChai from 'sinon-chai'; -import * as justForIdeTypeHinting from 'chai-as-promised'; -import 'mocha'; - -import { ClientWrapper } from '../../src/client/client-wrapper'; -import { Metadata } from 'grpc'; - -chai.use(sinonChai); - -describe('ClientWrapper', () => { - const expect = chai.expect; - let dynamicsClientStub: any; - let adalStub: any; - // let metadata: Metadata; - // let clientWrapperUnderTest: ClientWrapper; - - beforeEach(() => { - dynamicsClientStub = sinon.stub(); - adalStub = sinon.stub(); - adalStub.acquireTokenWithClientCredentials = sinon.stub(); - }); - - // it('authenticates', () => { - // // Construct grpc metadata and assert the client was authenticated. - // const expectedCallArgs = { - // tenantId: 'Some/UserAgent String', - // resource: 'Some/Resource String', - // clientId: 'Some/ClientId String', - // clientSecret: 'Some/ClientSecret String', - // }; - // metadata = new Metadata(); - // metadata.add('tenantId', expectedCallArgs.tenantId); - // metadata.add('resource', expectedCallArgs.resource); - // metadata.add('clientId', expectedCallArgs.clientId); - // metadata.add('clientSecret', expectedCallArgs.clientSecret); - - // adalStub.acquireTokenWithClientCredentials.resolves('sampleToken'); - // const config = { - // webApiUrl: 'Some/Resource String/api/adata/v9.0/', - // onTokenRefresh: 'sampleToken', - // }; - - // // Assert that the underlying API client was authenticated correctly. - // clientWrapperUnderTest = new ClientWrapper(metadata, dynamicsClientStub, adalStub); - // expect(dynamicsClientStub).to.have.been.calledWith(config); - // }); -}); +// import * as chai from 'chai'; +// import { default as sinon } from 'ts-sinon'; +// import * as sinonChai from 'sinon-chai'; +// import * as justForIdeTypeHinting from 'chai-as-promised'; +// import 'mocha'; + +// import { ClientWrapper } from '../../src/client/client-wrapper'; +// import { Metadata } from 'grpc'; + +// chai.use(sinonChai); + +// describe('ClientWrapper', () => { +// const expect = chai.expect; +// let dynamicsClientStub: any; +// let dynamicsClientConstructorStub: any; +// let adalStub: any; +// let adalContextStub: any; +// let requestClientStub: any; +// let metadata: Metadata; +// let clientWrapperUnderTest: ClientWrapper; +// beforeEach(() => { +// dynamicsClientStub = sinon.stub(); +// dynamicsClientConstructorStub = sinon.stub(); +// dynamicsClientConstructorStub.returns(dynamicsClientStub); +// adalStub = sinon.stub(); +// adalStub.AuthenticationContext = sinon.stub(); +// adalContextStub = sinon.stub(); +// adalContextStub.acquireTokenWithClientCredentials = sinon.stub(); +// adalStub.AuthenticationContext.returns(adalContextStub); +// requestClientStub = sinon.stub(); +// }); + +// it('authenticates', () => { +// // Construct grpc metadata and assert the client was authenticated. +// const expectedCallArgs = { +// resource: 'Some/Resource String', +// clientId: 'Some/ClientId String', +// clientSecret: 'Some/ClientSecret String', +// }; +// metadata = new Metadata(); +// metadata.add('resource', expectedCallArgs.resource); +// metadata.add('clientId', expectedCallArgs.clientId); +// metadata.add('clientSecret', expectedCallArgs.clientSecret); + +// function acquireToken(dynamicsWebApiCallback) { +// adalContextStub.acquireTokenWithClientCredentials.calledWith( +// expectedCallArgs.resource, +// expectedCallArgs.clientId, +// expectedCallArgs.clientSecret, +// (error, token) => { +// dynamicsWebApiCallback(token); +// }, +// ); +// } +// adalContextStub.acquireTokenWithClientCredentials.resolves('sampleToken'); +// requestClientStub.resolves('someTenantId'); + +// const args = { +// webApiUrl: `${expectedCallArgs.resource}/api/data/v9.0/`, +// onTokenRefresh: acquireToken, +// }; + +// // Assert that the underlying API client was authenticated correctly. +// clientWrapperUnderTest = new ClientWrapper(metadata, dynamicsClientConstructorStub, adalStub, requestClientStub); +// // expect(dynamicsClientConstructorStub).to.have.been.calledWith(args); +// expect(dynamicsClientConstructorStub).to.have.returned(dynamicsClientStub); +// }); + +// // describe('Entity', () => { +// // beforeEach(() => { +// // dynamicsClientConstructorStub = sinon.stub(); +// // dynamicsClientConstructorStub.returns(dynamicsClientStub); +// // dynamicsClientStub = sinon.stub(); +// // dynamicsClientStub.createRequest = sinon.stub(); +// // adalStub = sinon.stub(); +// // adalStub.acquireTokenWithClientCredentials = sinon.stub(); +// // }); + +// // it('create:resolves', () => { +// // // Construct grpc metadata and assert the client was authenticated. +// // const expectedCallArgs = { +// // resource: 'Some/Resource String', +// // clientId: 'Some/ClientId String', +// // clientSecret: 'Some/ClientSecret String', +// // }; +// // metadata = new Metadata(); +// // metadata.add('resource', expectedCallArgs.resource); +// // metadata.add('clientId', expectedCallArgs.clientId); +// // metadata.add('clientSecret', expectedCallArgs.clientSecret); + +// // const sampleRequest = { +// // someData: 'sampleData', +// // }; + +// // // Assert that the underlying API client was authenticated correctly. +// // clientWrapperUnderTest = new ClientWrapper(metadata, dynamicsClientConstructorStub, adalStub); +// // expect(dynamicsClientStub.createRequest).has.been.calledWith(); +// // }); +// // }); +// });