From f63a664563d925eec400800d2c38db106c5dddf8 Mon Sep 17 00:00:00 2001 From: Maxim Pismenskiy Date: Tue, 21 Jul 2020 18:38:00 +0300 Subject: [PATCH] feat: add deviceInfo to flpPipe, extraction httpBatch --- src/main/ts/index.ts | 1 + src/main/ts/pipes/deviceInfo.ts | 1 - src/main/ts/pipes/flp.ts | 45 +++++-------------- src/main/ts/pipes/httpBatch.ts | 35 +++++++++++++++ src/test/ts/pipes/flp.ts | 78 ++++++++++++++++++--------------- 5 files changed, 88 insertions(+), 72 deletions(-) create mode 100644 src/main/ts/pipes/httpBatch.ts diff --git a/src/main/ts/index.ts b/src/main/ts/index.ts index eff4373..ee94f49 100644 --- a/src/main/ts/index.ts +++ b/src/main/ts/index.ts @@ -1,6 +1,7 @@ export { createHttpPipe, IHttpPipeOpts, IHttpHeaders } from './pipes/http' export { createHttpPipeFallback } from './pipes/httpFallback' export { createMaskerPipe, panMaskerPipe } from './pipes/masker' +export { createHttpBatchPipe } from './pipes/httpBatch' export { createFlpPipeline, eventifyPipe } from './pipes/flp' export { createDeviceInfoPipe, getDeviceInfo } from './pipes/deviceInfo' export { createTransmitter, createTransmittable } from './transmitter' diff --git a/src/main/ts/pipes/deviceInfo.ts b/src/main/ts/pipes/deviceInfo.ts index ac8d85d..704b50d 100644 --- a/src/main/ts/pipes/deviceInfo.ts +++ b/src/main/ts/pipes/deviceInfo.ts @@ -26,7 +26,6 @@ export const createDeviceInfoPipe = (): IPipe => ({ type, execute ({ data }: ITransmittable): IPromise { const output = set(clone(data), 'meta.deviceInfo', getDeviceInfo()) - return Promise.resolve([null, output]) }, }) diff --git a/src/main/ts/pipes/flp.ts b/src/main/ts/pipes/flp.ts index a7fe165..8a16f57 100644 --- a/src/main/ts/pipes/flp.ts +++ b/src/main/ts/pipes/flp.ts @@ -1,18 +1,11 @@ import StackTrace from 'stacktrace-js' -import { HttpMethod, IClientEventDto, LogLevel } from '@qiwi/substrate' +import { IClientEventDto, LogLevel } from '@qiwi/substrate' import { IPipe, ITransmittable, TPipeline } from '../interfaces' import { panMaskerPipe } from './masker' -import { IHttpHeaders } from './http' -import { createHttpPipeFallback } from './httpFallback' +import { createHttpBatchPipe, IHttpBatchPipeOpts } from './httpBatch' +import { createDeviceInfoPipe } from './deviceInfo' import { identity } from '../utils' -export type IFlpOptions = { - url: string | string[], - method: HttpMethod, - batchUrl?: string | string [], - headers?: IHttpHeaders, -} - const DEFAULT_LEVEL = LogLevel.INFO export const type = 'flp-eventify' @@ -74,28 +67,10 @@ export const eventifyPipe: IPipe = { }, } -export const createFlpPipeline = ({ url, batchUrl, headers, method }: IFlpOptions): TPipeline => { - const opts = ([] as string[]) - .concat(url) - .map(url => ({ url, headers, method })) - - const batchOpts = batchUrl - ? ([] as string[]) - .concat(batchUrl) - .map(url => ({ url, headers, method })) - : opts - - const httpPipe = createHttpPipeFallback(opts) - const httpPipeBatch = createHttpPipeFallback(batchOpts) - - const httpPipeResolver: IPipe = ({ - type: httpPipe.type, - execute (...args) { - return Array.isArray(args[0].data.events) - ? httpPipeBatch.execute(...args) - : httpPipe.execute(...args) - }, - }) - - return [panMaskerPipe, eventifyPipe, httpPipeResolver] -} +export const createFlpPipeline = + ({ url, batchUrl, headers, method }: IHttpBatchPipeOpts): TPipeline => [ + panMaskerPipe, + eventifyPipe, + createDeviceInfoPipe(), + createHttpBatchPipe({ url, batchUrl, headers, method }), + ] diff --git a/src/main/ts/pipes/httpBatch.ts b/src/main/ts/pipes/httpBatch.ts new file mode 100644 index 0000000..151b21a --- /dev/null +++ b/src/main/ts/pipes/httpBatch.ts @@ -0,0 +1,35 @@ +import { IPipe } from '../interfaces' +import { createHttpPipeFallback } from './httpFallback' +import { HttpMethod } from '@qiwi/substrate' +import { IHttpHeaders } from './http' + +export type IHttpBatchPipeOpts = { + url: string | string[], + method: HttpMethod, + batchUrl?: string | string [], + headers?: IHttpHeaders, +} + +export const createHttpBatchPipe = ({ url, batchUrl, headers, method }: IHttpBatchPipeOpts): IPipe => { + const opts = ([] as string[]) + .concat(url) + .map(url => ({ url, headers, method })) + + const batchOpts = batchUrl + ? ([] as string[]) + .concat(batchUrl) + .map(url => ({ url, headers, method })) + : opts + + const httpPipe = createHttpPipeFallback(opts) + const httpPipeBatch = createHttpPipeFallback(batchOpts) + + return ({ + type: httpPipe.type, + execute (...args) { + return Array.isArray(args[0].data.events) + ? httpPipeBatch.execute(...args) + : httpPipe.execute(...args) + }, + }) +} diff --git a/src/test/ts/pipes/flp.ts b/src/test/ts/pipes/flp.ts index c63b6e9..586c1dd 100644 --- a/src/test/ts/pipes/flp.ts +++ b/src/test/ts/pipes/flp.ts @@ -63,22 +63,20 @@ describe('flpPipeline', () => { const res = await transmitter.push(['4539246180805047', '5101754226671617']) expect(res).toEqual([null, ['4539 **** **** 5047', '5101 **** **** 1617']]) - expect(spy).toHaveBeenCalledWith(batchUrl, { - method: HttpMethod.POST, - body: JSON.stringify({ - events: [{ - message: '4539 **** **** 5047', - meta: {}, - level: 'info', - }, { - message: '5101 **** **** 1617', - meta: {}, - level: 'info', - }], - }), - headers: { - 'Content-Type': 'application/json', - }, + expect(spy.mock.calls[0][0]).toBe(batchUrl) + expect(spy.mock.calls[0][1]?.method).toBe(HttpMethod.POST) + expect(spy.mock.calls[0][1]?.headers).toMatchObject({ 'Content-Type': 'application/json' }) + // @ts-ignore + expect(JSON.parse(spy.mock.calls[0][1].body)).toMatchObject({ + events: [{ + message: '4539 **** **** 5047', + meta: {}, + level: 'info', + }, { + message: '5101 **** **** 1617', + meta: {}, + level: 'info', + }], }) spy.mockClear() @@ -93,16 +91,20 @@ describe('flpPipeline', () => { const res = await transmitter.push('0000000000000000') expect(res).toEqual([null, '0000 **** **** 0000']) - expect(spy).toHaveBeenCalledWith(url, { - method: HttpMethod.POST, - body: JSON.stringify({ - message: '0000 **** **** 0000', - meta: {}, - level: 'info', - }), - headers: { - 'Content-Type': 'application/json', + expect(spy.mock.calls[0][0]).toBe(url) + expect(spy.mock.calls[0][1]?.method).toBe(HttpMethod.POST) + expect(spy.mock.calls[0][1]?.headers).toMatchObject({ 'Content-Type': 'application/json' }) + // @ts-ignore + expect(JSON.parse(spy.mock.calls[0][1].body)).toMatchObject({ + message: '0000 **** **** 0000', + meta: { + deviceInfo: { + browser: expect.any(Object), + model: expect.any(Object), + os: expect.any(Object), + }, }, + level: 'info', }) spy.mockClear() @@ -117,19 +119,23 @@ describe('flpPipeline', () => { const res = await transmitter.push({ data: 'data', message: 'message' }) expect(res).toEqual([null, { data: 'data', message: 'message' }]) - expect(spy).toHaveBeenCalledWith(url, { - method: HttpMethod.POST, - body: JSON.stringify({ - message: 'message', - meta: {}, - level: 'info', - data: 'data', - }), - headers: { - 'Content-Type': 'application/json', + + expect(spy.mock.calls[0][0]).toBe(url) + expect(spy.mock.calls[0][1]?.method).toBe(HttpMethod.POST) + expect(spy.mock.calls[0][1]?.headers).toMatchObject({ 'Content-Type': 'application/json' }) + // @ts-ignore + expect(JSON.parse(spy.mock.calls[0][1].body)).toMatchObject({ + message: 'message', + meta: { + deviceInfo: { + browser: expect.any(Object), + model: expect.any(Object), + os: expect.any(Object), + }, }, + level: 'info', + data: 'data', }) - spy.mockClear() })