Skip to content

Commit ccd95bb

Browse files
committed
fix: support multiple header values with matchers
Fixes #964
1 parent 2dc966e commit ccd95bb

File tree

3 files changed

+32
-7
lines changed

3 files changed

+32
-7
lines changed

src/v3/ffi.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,29 @@
11
/* eslint-disable import/first */
22
import { forEachObjIndexed } from 'ramda';
33
import { ConsumerInteraction } from '@pact-foundation/pact-core/src/consumer/index';
4-
import { isArray } from 'util';
54
import { TemplateHeaders, V3Request, V3Response } from './types';
65
import { matcherValueOrString } from './matchers';
76
import { MatchersV3 } from '../v3';
87

8+
type TemplateHeaderArrayValue = string[] | MatchersV3.Matcher<string>[];
9+
910
export const setRequestDetails = (
1011
interaction: ConsumerInteraction,
1112
req: V3Request
1213
): void => {
1314
interaction.withRequest(req.method, matcherValueOrString(req.path));
1415
forEachObjIndexed((v, k) => {
15-
interaction.withRequestHeader(k, 0, matcherValueOrString(v));
16+
if (Array.isArray(v)) {
17+
(v as TemplateHeaderArrayValue).forEach((header, index) => {
18+
interaction.withRequestHeader(k, index, matcherValueOrString(header));
19+
});
20+
} else {
21+
interaction.withRequestHeader(k, 0, matcherValueOrString(v));
22+
}
1623
}, req.headers);
1724

1825
forEachObjIndexed((v, k) => {
19-
if (isArray(v)) {
26+
if (Array.isArray(v)) {
2027
(v as unknown[]).forEach((vv, i) => {
2128
interaction.withQuery(k, i, matcherValueOrString(vv));
2229
});
@@ -37,6 +44,7 @@ export const setResponseDetails = (
3744
}, res.headers);
3845
};
3946

47+
// TODO: this might need to consider an array of values
4048
export const contentTypeFromHeaders = (
4149
headers: TemplateHeaders | undefined,
4250
defaultContentType: string

src/v3/types.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,11 @@ export interface V3ProviderState {
5555
parameters?: JsonMap;
5656
}
5757

58-
export type TemplateHeaders = {
59-
[header: string]: string | MatchersV3.Matcher<string>;
58+
export declare type TemplateHeaders = {
59+
[header: string]:
60+
| string
61+
| MatchersV3.Matcher<string>
62+
| (MatchersV3.Matcher<string> | string)[];
6063
};
6164

6265
export type TemplateQuery = Record<

src/v4/http/index.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { ConsumerInteraction, ConsumerPact } from '@pact-foundation/pact-core';
33
import { JsonMap } from '../../common/jsonTypes';
44
import { forEachObjIndexed } from 'ramda';
55
import { Path, TemplateHeaders, TemplateQuery, V3MockServer } from '../../v3';
6-
import { AnyTemplate, matcherValueOrString } from '../../v3/matchers';
6+
import { AnyTemplate, Matcher, matcherValueOrString } from '../../v3/matchers';
77
import {
88
PactV4Options,
99
PluginConfig,
@@ -34,6 +34,8 @@ import {
3434
} from '../../v3/display';
3535
import logger from '../../common/logger';
3636

37+
type TemplateHeaderArrayValue = string[] | Matcher<string>[];
38+
3739
export class UnconfiguredInteraction implements V4UnconfiguredInteraction {
3840
// tslint:disable:no-empty-function
3941
constructor(
@@ -138,7 +140,19 @@ export class RequestBuilder implements V4RequestBuilder {
138140

139141
headers(headers: TemplateHeaders) {
140142
forEachObjIndexed((v, k) => {
141-
this.interaction.withRequestHeader(`${k}`, 0, matcherValueOrString(v));
143+
if (Array.isArray(v)) {
144+
(v as TemplateHeaderArrayValue).forEach(
145+
(header: string | Matcher<string>, index: number) => {
146+
this.interaction.withRequestHeader(
147+
`${k}`,
148+
index,
149+
matcherValueOrString(header)
150+
);
151+
}
152+
);
153+
} else {
154+
this.interaction.withRequestHeader(`${k}`, 0, matcherValueOrString(v));
155+
}
142156
}, headers);
143157

144158
return this;

0 commit comments

Comments
 (0)