diff --git a/README.md b/README.md index 4bc0999..66a051d 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Using this library along with [kiegroup/act-js](https://github.com/kiegroup/act- - [Initialization options](#initialization-options) - [Mock an api](#mock-an-api) - [Mock the entire endpoint](#mock-the-entire-endpoint) - - [Mock an endpoint for specific parameter(s)](#mock-an-endpoint-for-specific-parameters) + - [Mock an endpoint for specific parameter(s) and header(s)](#mock-an-endpoint-for-specific-parameters-and-headers) - [Replying with a response](#replying-with-a-response) - [Reply once](#reply-once) - [Reply N times](#reply-n-times) @@ -81,7 +81,7 @@ moctokit.rest.projects .reply({ status: 200, data: { owner_url: "whatever url" } }); ``` -#### Mock an endpoint for specific parameter(s) +#### Mock an endpoint for specific parameter(s) and header(s) You can mock an endpoint for certain paramters. So only if the call to the api has parameters which match the values you defined it will be get the mocked response. @@ -96,6 +96,16 @@ const moctokit = new Moctokit(); moctokit.rest.projects .createForRepo({ owner: "kie", repo: /d.+/, name: "project" }) .reply({ status: 200, data: { owner_url: "whatever url" } }); + +/** + * Mocks the same api as above but only for requests which match the same parameters as above as well contains the following 2 request headers: + * 1. "custom-header" with value as "value" + * 2. "test-header" with value as any number + */ +moctokit.rest.projects + .createForRepo({ owner: "kie", repo: /d.+/, name: "project" }) + .matchReqHeaders({"custom-header": "value", "test-header": /\d+/}) + .reply({ status: 200, data: { owner_url: "whatever url" } }); ``` ### Replying with a response diff --git a/package-lock.json b/package-lock.json index d7c26c6..8a2b789 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@kie/mock-github", - "version": "1.0.2", + "version": "1.0.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@kie/mock-github", - "version": "1.0.2", + "version": "1.0.3", "license": "SEE LICENSE IN LICENSE", "dependencies": { "@octokit/openapi-types-ghec": "^14.0.0", diff --git a/package.json b/package.json index 74bf5e5..36edb77 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kie/mock-github", - "version": "1.0.2", + "version": "1.0.3", "description": "A bunch of tools to configure and create a local github environment to test your github actions in without having to clutter your github with test repositories, actions or hitting github api rate limits.", "main": "build/src/index.js", "types": "build/src/index.d.ts", diff --git a/src/endpoint-mocker/response/abstract-response-mocker.ts b/src/endpoint-mocker/response/abstract-response-mocker.ts index 6ece21a..ee19f98 100644 --- a/src/endpoint-mocker/response/abstract-response-mocker.ts +++ b/src/endpoint-mocker/response/abstract-response-mocker.ts @@ -1,14 +1,16 @@ import nock, { DataMatcherMap } from "nock"; -import { Response } from "@mg/endpoint-mocker/response/abstract-response-mocker.types"; +import { Header, Response } from "@mg/endpoint-mocker/response/abstract-response-mocker.types"; export abstract class ResponseMocker { - private interceptor: nock.Interceptor; private scope: nock.Scope; private responses: Response[]; + private headers: Header; private path: string | RegExp; private query?: DataMatcherMap; private requestBody?: DataMatcherMap; private method: string; + private baseUrl: string; + private allowUnmocked: boolean; constructor( baseUrl: string, @@ -18,13 +20,23 @@ export abstract class ResponseMocker { requestBody?: DataMatcherMap, allowUnmocked = false ) { + this.baseUrl = baseUrl; + this.allowUnmocked = allowUnmocked; this.scope = nock(baseUrl, { allowUnmocked }); this.responses = []; + this.headers = {}; this.path = path; this.query = query; this.requestBody = requestBody; this.method = method; - this.interceptor = this.createInterceptor(); + } + + matchReqHeaders(headers: Header) { + this.headers = {...this.headers, ...headers}; + if (Object.keys(this.headers).length > 0) { + this.scope = nock(this.baseUrl, { allowUnmocked: this.allowUnmocked, reqheaders: this.headers }); + } + return this; } setResponse(responses: Response | Response[]) { @@ -37,20 +49,21 @@ export abstract class ResponseMocker { } reply(response?: Response) { + let interceptor = this.createInterceptor(); if (response) { - this.scope = this.interceptor + this.scope = interceptor .times(response.repeat ?? 1) .reply(response.status, response.data as nock.Body, response.headers); - this.interceptor = this.createInterceptor(); } else { this.responses.forEach(res => { - this.scope = this.interceptor + this.scope = interceptor .times(res.repeat ?? 1) .reply(res.status, res.data as nock.Body, res.headers); - this.interceptor = this.createInterceptor(); + interceptor = this.createInterceptor(); }); this.responses = []; } + this.headers = {}; return this; } diff --git a/src/endpoint-mocker/response/abstract-response-mocker.types.ts b/src/endpoint-mocker/response/abstract-response-mocker.types.ts index 4b3356b..58fdd7e 100644 --- a/src/endpoint-mocker/response/abstract-response-mocker.types.ts +++ b/src/endpoint-mocker/response/abstract-response-mocker.types.ts @@ -1,4 +1,4 @@ -import { ReplyHeaders } from "nock"; +import { ReplyHeaders, RequestHeaderMatcher } from "nock"; export type Response = { status: S; @@ -6,3 +6,7 @@ export type Response = { headers?: ReplyHeaders repeat?: number }; + +export type Header = { + [key: string]: RequestHeaderMatcher +} diff --git a/test/moctokit/request-response-mocker.test.ts b/test/moctokit/request-response-mocker.test.ts index efd501b..3d10f87 100644 --- a/test/moctokit/request-response-mocker.test.ts +++ b/test/moctokit/request-response-mocker.test.ts @@ -180,6 +180,38 @@ describe.each(["get", "post", "delete", "put", "patch"])( expect(status).toBe(200); expect(data).toStrictEqual({ msg: "hello world" }); }); + + test("mock headers", async () => { + const requestMocker = new MoctokitRequestMocker(url, { + path: "/query/{param1}/query", + method: method as EndpointMethod, + parameters: { + path: ["param1"], + query: ["query1", "query2", "query3"], + body: [], + }, + }); + + requestMocker + .request({ + param1: "hello" + } as any) + .matchReqHeaders({ + "authorization": /bearer */, + }) + .reply({ status: 200, data: { msg: "hello world" } } as never); + + const { status, data } = await instance({ + method, + url: "/query/hello/query?query1=hello", + headers: { + authorization: "bearer some_token", + "custom-header": "value" + }, + }); + expect(status).toBe(200); + expect(data).toStrictEqual({ msg: "hello world" }); + }); test("setResponse: singular response", async () => { const requestMocker = new MoctokitRequestMocker(url, {