From 60190c3cfad7a000aa566df2a5a7bb9d234bca52 Mon Sep 17 00:00:00 2001 From: mefellows Date: Thu, 13 Jul 2023 21:07:22 +1000 Subject: [PATCH] feat: add a status matcher to the V4 interface --- src/dsl/message.ts | 3 ++- src/v3/matchers.ts | 36 ++++++++++++++++-------------------- src/v3/types.ts | 10 ++++++++++ src/v4/http/index.ts | 16 ++++++++++++---- src/v4/http/types.ts | 5 +++-- 5 files changed, 43 insertions(+), 27 deletions(-) diff --git a/src/dsl/message.ts b/src/dsl/message.ts index 5c8f5d59e..0b5af97d5 100644 --- a/src/dsl/message.ts +++ b/src/dsl/message.ts @@ -1,5 +1,6 @@ import { AnyJson } from '../common/jsonTypes'; import { Matcher } from './matchers'; +import { Matcher as MatcherV4 } from '../v3/matchers'; /** * Metadata is a map containing message context, @@ -8,7 +9,7 @@ import { Matcher } from './matchers'; * @module Message */ export interface Metadata { - [name: string]: string | Matcher; + [name: string]: string | Matcher | MatcherV4; } /** diff --git a/src/v3/matchers.ts b/src/v3/matchers.ts index 59cdf8a36..97fab2b87 100644 --- a/src/v3/matchers.ts +++ b/src/v3/matchers.ts @@ -9,8 +9,6 @@ import { MinLikeMatcher, ProviderStateInjectedValue, RulesMatcher, - HTTPResponseStatusClass, - StatusCodeMatcher, V3RegexMatcher, } from './types'; @@ -84,26 +82,24 @@ export const eachValueMatches = ( 'pact:matcher:type': 'eachValue', rules: Array.isArray(matchers) ? matchers : [matchers], value: example, - // Unsure if the full object is provided, or just a template k/v pair - // value: { - // [keyTemplate]: template, - // }, }); -/** - * Matches HTTP status codes by their range description, or by a list of specific codes. - * - * @param example Example status code to use - * @param range Allowed status codes - */ -export const matchStatus = ( - example: number, - range: HTTPResponseStatusClass | number[] -): StatusCodeMatcher => ({ - value: example, - 'pact:matcher:type': 'statusCode', - status: range, -}); +// Waiting on https://github.com/pact-foundation/pact-reference/issues/296 + +// /** +// * Matches HTTP status codes by their range description, or by a list of specific codes. +// * +// * @param example Example status code to use +// * @param range Allowed status codes +// */ +// export const matchStatus = ( +// example: number, +// range: HTTPResponseStatusClass | number[] +// ): StatusCodeMatcher => ({ +// value: example, +// 'pact:matcher:type': 'statusCode', +// status: range, +// }); /** * Array where each element must match the given template diff --git a/src/v3/types.ts b/src/v3/types.ts index 3c5501391..3d8799c83 100644 --- a/src/v3/types.ts +++ b/src/v3/types.ts @@ -174,6 +174,16 @@ export enum HTTPResponseStatusClass { ClientError = 'clientError', // Server errors (500–599) ServerError = 'serverError', + // Informational responses (100–199) + '1XX' = 'information', + // Successful responses (200–299) + '2XX' = 'success', + // Redirects (300–399) + '3XX' = 'redirect', + // Client errors (400–499) + '4XX' = 'clientError', + // Server errors (500–599) + '5XX' = 'serverError', // Non-error response(< 400) NonError = 'nonError', // Any error response (>= 400) diff --git a/src/v4/http/index.ts b/src/v4/http/index.ts index f62508015..b700c6dad 100644 --- a/src/v4/http/index.ts +++ b/src/v4/http/index.ts @@ -3,7 +3,12 @@ import { ConsumerInteraction, ConsumerPact } from '@pact-foundation/pact-core'; import { JsonMap } from '../../common/jsonTypes'; import { forEachObjIndexed } from 'ramda'; import { Path, TemplateHeaders, TemplateQuery, V3MockServer } from '../../v3'; -import { Matcher, matcherValueOrString } from '../../v3/matchers'; +import { + Matcher, + StatusCodeMatcher, + matcherValueOrString, + reify, +} from '../../v3/matchers'; import { PactV4Options, PluginConfig, @@ -126,8 +131,11 @@ export class InteractionwithRequest implements V4InteractionwithRequest { protected cleanupFn: () => void ) {} - willRespondWith(status: number, builder?: V4ResponseBuilderFunc) { - this.interaction.withStatus(status); + willRespondWith( + status: number | StatusCodeMatcher, + builder?: V4ResponseBuilderFunc + ) { + this.interaction.withStatus(reify(status) as number); if (typeof builder === 'function') { builder(new ResponseBuilder(this.interaction)); @@ -309,7 +317,7 @@ export class InteractionWithPluginRequest status: number, builder?: V4PluginResponseBuilderFunc ): V4InteractionWithPluginResponse { - this.interaction.withStatus(status); + this.interaction.withStatus(reify(status) as number); if (typeof builder === 'function') { builder(new ResponseWithPluginBuilder(this.interaction)); diff --git a/src/v4/http/types.ts b/src/v4/http/types.ts index 9e5ea7877..5bcaba78b 100644 --- a/src/v4/http/types.ts +++ b/src/v4/http/types.ts @@ -2,6 +2,7 @@ import { JsonMap } from '../../common/jsonTypes'; import { Path, SpecificationVersion, + StatusCodeMatcher, TemplateHeaders, TemplateQuery, V3MockServer, @@ -71,7 +72,7 @@ export interface V4InteractionWithCompleteRequest { export interface V4InteractionwithRequest { willRespondWith( - status: number, + status: number | StatusCodeMatcher, builder?: V4ResponseBuilderFunc ): V4InteractionWithResponse; } @@ -137,7 +138,7 @@ export interface V4InteractionWithPlugin { export interface V4InteractionWithPluginRequest { willRespondWith( - status: number, + status: number | StatusCodeMatcher, builder?: V4PluginResponseBuilderFunc ): V4InteractionWithPluginResponse; }