From c7acd66ed802a214bc7e7505a5d34a96a6be2b13 Mon Sep 17 00:00:00 2001 From: Andreas Weber Date: Sun, 16 Jul 2023 20:43:39 +0200 Subject: [PATCH] feat: add import of global asserts and import of onResponse Hooks (#488) --- CHANGELOG.md | 2 ++ src/models/httpFile.ts | 1 + src/models/httpRegion.ts | 13 +++++--- .../regionScopedVariablesInterceptor.ts | 7 ++-- src/store/httpFile.ts | 4 +++ src/store/httpRegion.ts | 11 ++----- src/test/assert/status.spec.ts | 19 +++++++++++ src/utils/httpRegionUtils.ts | 32 ++++++++++++++++--- src/utils/processorContextUtils.ts | 3 +- 9 files changed, 70 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf953531..d8d35386 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ### Features - add method `$getOAuth2Response` to javascript context (#499) +- add `HttpClientProvider` and `JavascriptProvider` to httpyac API +- allow global Asserts and `onRequest`/ `onResponse` hooks and import global Asserts from other Http Files (#488) ## [6.5.1] (2023-06-13) diff --git a/src/models/httpFile.ts b/src/models/httpFile.ts index 486c7f2f..4a1e87b3 100644 --- a/src/models/httpFile.ts +++ b/src/models/httpFile.ts @@ -7,6 +7,7 @@ export interface HttpFile { readonly rootDir?: PathLike; readonly hooks: HttpFileHooks; readonly httpRegions: Array; + readonly globalHttpRegions: Array; activeEnvironment?: string[]; findHttpRegion(name: string): HttpRegion | undefined; diff --git a/src/models/httpRegion.ts b/src/models/httpRegion.ts index 3afd269b..27ab57aa 100644 --- a/src/models/httpRegion.ts +++ b/src/models/httpRegion.ts @@ -22,6 +22,13 @@ export type PartialProperty & Partial; +export interface RequestClientHooks { + onRequest: OnRequestHook; + onStreaming: OnStreaming; + onResponse: OnResponseHook; + responseLogging: ResponseLoggingHook; +} + export interface HttpRegion { request?: Request; response?: HttpResponse; @@ -30,12 +37,8 @@ export interface HttpRegion { testResults?: Array; responseRefs?: Array; variablesPerEnv: Record; - readonly hooks: { + readonly hooks: RequestClientHooks & { execute: ExecuteHook; - onRequest: OnRequestHook; - onStreaming: OnStreaming; - onResponse: OnResponseHook; - responseLogging: ResponseLoggingHook; }; isGlobal(): boolean; clone(httpFile?: HttpFile): HttpRegion; diff --git a/src/plugins/core/execute/regionScopedVariablesInterceptor.ts b/src/plugins/core/execute/regionScopedVariablesInterceptor.ts index 1afa0cfe..e333ac81 100644 --- a/src/plugins/core/execute/regionScopedVariablesInterceptor.ts +++ b/src/plugins/core/execute/regionScopedVariablesInterceptor.ts @@ -14,10 +14,13 @@ export class RegionScopedVariablesInterceptor implements HookInterceptor<[models const context = hookContext.args[0]; const env = toEnvironmentKey(context.httpFile.activeEnvironment); if (context.config?.useRegionScopedVariables) { - const httpRegions = context.httpFile.httpRegions.filter(obj => obj.isGlobal()); const regionScopedVariables: RegionScopedVariableOptions = context.options; regionScopedVariables.variables = context.variables; - context.variables = Object.assign({}, context.variables, ...httpRegions.map(obj => obj.variablesPerEnv[env])); + context.variables = Object.assign( + {}, + context.variables, + ...context.httpFile.globalHttpRegions.map(obj => obj.variablesPerEnv[env]) + ); } else { context.variables = Object.assign( context.variables, diff --git a/src/store/httpFile.ts b/src/store/httpFile.ts index 705fce59..25ca0c15 100644 --- a/src/store/httpFile.ts +++ b/src/store/httpFile.ts @@ -22,4 +22,8 @@ export class HttpFile implements models.HttpFile { public findHttpRegion(name: string): models.HttpRegion | undefined { return this.httpRegions.find(obj => obj.metaData?.name === name && !obj.metaData.disabled); } + + public get globalHttpRegions() { + return this.httpRegions.filter(obj => obj.isGlobal() && !obj.metaData.disabled); + } } diff --git a/src/store/httpRegion.ts b/src/store/httpRegion.ts index 213d300c..1ea04172 100644 --- a/src/store/httpRegion.ts +++ b/src/store/httpRegion.ts @@ -1,5 +1,5 @@ import * as models from '../models'; -import { toEnvironmentKey } from '../utils'; +import { toEnvironmentKey, addHttpFileRequestClientHooks } from '../utils'; import { Hook, HookCancel } from 'hookpoint'; export class HttpRegion implements models.HttpRegion { @@ -74,14 +74,7 @@ export class HttpRegion implements models.HttpRegion { ...context, httpFile: this.httpFile, httpRegion: this, - hooks: { - onRequest: this.hooks.onRequest.merge(this.httpFile.hooks.onRequest) as models.OnRequestHook, - onResponse: this.hooks.onResponse.merge(this.httpFile.hooks.onResponse) as models.OnResponseHook, - onStreaming: this.hooks.onStreaming.merge(this.httpFile.hooks.onStreaming) as models.OnStreaming, - responseLogging: this.hooks.responseLogging.merge( - this.httpFile.hooks.responseLogging - ) as models.ResponseLoggingHook, - }, + hooks: addHttpFileRequestClientHooks(this.hooks, this.httpFile), isMainContext, }); if (!this.isGlobal()) { diff --git a/src/test/assert/status.spec.ts b/src/test/assert/status.spec.ts index 27989fe7..0449d60f 100644 --- a/src/test/assert/status.spec.ts +++ b/src/test/assert/status.spec.ts @@ -24,6 +24,25 @@ describe('assert.status', () => { expect(httpFile.httpRegions[0].testResults?.[0].result).toBeTruthy(); expect(httpFile.httpRegions[0].testResults?.[0].message).toBe('status == 200'); }); + it('should be equal to 200 with global assert', async () => { + initFileProvider(); + await localServer.forGet('/get').thenReply(200); + const httpFile = await parseHttp(` + ?? status == 200 + ### + GET /get + + `); + + const responses = await sendHttpFile(httpFile, { + host: `http://localhost:${localServer.port}`, + }); + expect(responses.length).toBe(1); + expect(responses[0].statusCode).toBe(200); + expect(httpFile.httpRegions[1].testResults?.length).toBe(1); + expect(httpFile.httpRegions[1].testResults?.[0].result).toBeTruthy(); + expect(httpFile.httpRegions[1].testResults?.[0].message).toBe('status == 200'); + }); it('should not be equal 200', async () => { initFileProvider(); await localServer.forGet('/get').thenReply(201); diff --git a/src/utils/httpRegionUtils.ts b/src/utils/httpRegionUtils.ts index 79280781..082ac8cd 100644 --- a/src/utils/httpRegionUtils.ts +++ b/src/utils/httpRegionUtils.ts @@ -56,12 +56,34 @@ export async function executeGlobalScripts(context: { httpFile: models.HttpFile; options: Record; }): Promise { - for (const httpRegion of context.httpFile.httpRegions) { - if (httpRegion.isGlobal() && !httpRegion.metaData.disabled) { - if (!(await httpRegion.execute(context))) { - return false; - } + for (const httpRegion of context.httpFile.globalHttpRegions) { + if (!(await httpRegion.execute(context))) { + return false; } } return true; } + +export function addHttpFileRequestClientHooks( + requestClientHooks: models.RequestClientHooks, + httpFile: models.HttpFile +): models.RequestClientHooks { + return { + onRequest: httpFile.hooks.onRequest.merge( + ...httpFile.globalHttpRegions.map(obj => obj.hooks.onRequest), + requestClientHooks.onRequest + ) as models.OnRequestHook, + onResponse: httpFile.hooks.onResponse.merge( + requestClientHooks.onResponse, + ...httpFile.globalHttpRegions.map(obj => obj.hooks.onResponse) + ) as models.OnResponseHook, + onStreaming: httpFile.hooks.onStreaming.merge( + requestClientHooks.onStreaming, + ...httpFile.globalHttpRegions.map(obj => obj.hooks.onStreaming) + ) as models.OnStreaming, + responseLogging: httpFile.hooks.responseLogging.merge( + requestClientHooks.responseLogging, + ...httpFile.globalHttpRegions.map(obj => obj.hooks.responseLogging) + ) as models.ResponseLoggingHook, + }; +} diff --git a/src/utils/processorContextUtils.ts b/src/utils/processorContextUtils.ts index 55bf0fcc..4f03b7a1 100644 --- a/src/utils/processorContextUtils.ts +++ b/src/utils/processorContextUtils.ts @@ -1,6 +1,6 @@ import { log, fileProvider } from '../io'; import * as models from '../models'; -import { executeGlobalScripts } from './httpRegionUtils'; +import { addHttpFileRequestClientHooks, executeGlobalScripts } from './httpRegionUtils'; import { replaceFilePath } from './variableUtils'; interface ImportProcessorContext extends models.ProcessorContext { @@ -60,6 +60,7 @@ export async function importHttpFileInContext( activeEnvironment: context.httpFile.activeEnvironment, } ); + context.hooks = addHttpFileRequestClientHooks(context.hooks, ref); context.options.httpFiles.push({ base: context.httpFile, ref }); return ref; });