Skip to content

Commit

Permalink
fix: support multiple header values with matchers
Browse files Browse the repository at this point in the history
Fixes #964
  • Loading branch information
mefellows committed Dec 2, 2022
1 parent 2dc966e commit ccd95bb
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 7 deletions.
14 changes: 11 additions & 3 deletions src/v3/ffi.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
/* eslint-disable import/first */
import { forEachObjIndexed } from 'ramda';
import { ConsumerInteraction } from '@pact-foundation/pact-core/src/consumer/index';
import { isArray } from 'util';
import { TemplateHeaders, V3Request, V3Response } from './types';
import { matcherValueOrString } from './matchers';
import { MatchersV3 } from '../v3';

type TemplateHeaderArrayValue = string[] | MatchersV3.Matcher<string>[];

export const setRequestDetails = (
interaction: ConsumerInteraction,
req: V3Request
): void => {
interaction.withRequest(req.method, matcherValueOrString(req.path));
forEachObjIndexed((v, k) => {
interaction.withRequestHeader(k, 0, matcherValueOrString(v));
if (Array.isArray(v)) {
(v as TemplateHeaderArrayValue).forEach((header, index) => {
interaction.withRequestHeader(k, index, matcherValueOrString(header));
});
} else {
interaction.withRequestHeader(k, 0, matcherValueOrString(v));
}
}, req.headers);

forEachObjIndexed((v, k) => {
if (isArray(v)) {
if (Array.isArray(v)) {
(v as unknown[]).forEach((vv, i) => {
interaction.withQuery(k, i, matcherValueOrString(vv));
});
Expand All @@ -37,6 +44,7 @@ export const setResponseDetails = (
}, res.headers);
};

// TODO: this might need to consider an array of values
export const contentTypeFromHeaders = (
headers: TemplateHeaders | undefined,
defaultContentType: string
Expand Down
7 changes: 5 additions & 2 deletions src/v3/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,11 @@ export interface V3ProviderState {
parameters?: JsonMap;
}

export type TemplateHeaders = {
[header: string]: string | MatchersV3.Matcher<string>;
export declare type TemplateHeaders = {
[header: string]:
| string
| MatchersV3.Matcher<string>
| (MatchersV3.Matcher<string> | string)[];
};

export type TemplateQuery = Record<
Expand Down
18 changes: 16 additions & 2 deletions src/v4/http/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ 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 { AnyTemplate, matcherValueOrString } from '../../v3/matchers';
import { AnyTemplate, Matcher, matcherValueOrString } from '../../v3/matchers';
import {
PactV4Options,
PluginConfig,
Expand Down Expand Up @@ -34,6 +34,8 @@ import {
} from '../../v3/display';
import logger from '../../common/logger';

type TemplateHeaderArrayValue = string[] | Matcher<string>[];

export class UnconfiguredInteraction implements V4UnconfiguredInteraction {
// tslint:disable:no-empty-function
constructor(
Expand Down Expand Up @@ -138,7 +140,19 @@ export class RequestBuilder implements V4RequestBuilder {

headers(headers: TemplateHeaders) {
forEachObjIndexed((v, k) => {
this.interaction.withRequestHeader(`${k}`, 0, matcherValueOrString(v));
if (Array.isArray(v)) {
(v as TemplateHeaderArrayValue).forEach(
(header: string | Matcher<string>, index: number) => {
this.interaction.withRequestHeader(
`${k}`,
index,
matcherValueOrString(header)
);
}
);
} else {
this.interaction.withRequestHeader(`${k}`, 0, matcherValueOrString(v));
}
}, headers);

return this;
Expand Down

0 comments on commit ccd95bb

Please sign in to comment.