Skip to content

Commit

Permalink
fix: Handle multiple set-cookie headers
Browse files Browse the repository at this point in the history
  • Loading branch information
Brent Schmidt authored and tvsbrent committed Jan 28, 2022
1 parent 99dfde3 commit df54a2a
Show file tree
Hide file tree
Showing 10 changed files with 443 additions and 12 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
coverage/
node_modules/
sandbox/cypress/fixtures/private/
sandbox/cypress/integration/private/
sandbox/cypress/screenshots/
sandbox/cypress/videos/
secrets/
Expand Down
8 changes: 8 additions & 0 deletions lib/commands/entities/PlaybackRequestMatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ class PlaybackRequestMatcher {
* @type {string}
*/
#id = null;
/**
* @type {string}
*/
#method = null;
/**
* @type {string}
*/
Expand Down Expand Up @@ -41,6 +45,7 @@ class PlaybackRequestMatcher {
stale = false;

get id() { return this.#id; }
get method() { return this.#method; }
get matcher() { return this.#matcher; }
get minTimes() { return this.#minTimes; }
/**
Expand All @@ -64,6 +69,7 @@ class PlaybackRequestMatcher {
throw new Error('Invalid arguments');
}
this.#id = getRequestMatcherId(method, matcher, options);
this.#method = method;
this.#matcher = getMatcherAsString(matcher);
this.#minTimes = options.minTimes ?? 1;
/* c8 ignore next*/
Expand Down Expand Up @@ -136,6 +142,7 @@ class PlaybackRequestMatcher {
serialize() {
return {
id: this.#id,
method: this.#method,
matcher: this.#matcher,
minTimes: this.#minTimes,
ignoredAttributes: this.#ignoredAttributes,
Expand All @@ -147,6 +154,7 @@ class PlaybackRequestMatcher {

deserialize(data) {
this.#id = data.id;
this.#method = data.method;
this.#matcher = data.matcher;
this.#minTimes = data.minTimes;
this.#ignoredAttributes = data.ignoredAttributes;
Expand Down
10 changes: 8 additions & 2 deletions lib/commands/entities/PlaybackResponse.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ function getResponseBodyType(body) {
}

function serializeResponseBody(body, bodyType) {
if (bodyType === null) {
return undefined;
}
if (bodyType === 'ArrayBuffer') {
return arrayBufferToBase64(new Uint8Array(body));
} else if (bodyType === 'json') {
Expand All @@ -28,10 +31,13 @@ function serializeResponseBody(body, bodyType) {
return body;
}
/* c8 ignore next*/
throw new Error(`Unknown body type: ${bodyType}`);
throw new Error(`Cannot serialize unknown body type: ${bodyType}`);
}

function deserializeResponseBody(body, bodyType) {
if (bodyType === null) {
return undefined;
}
if (bodyType === 'ArrayBuffer') {
return base64ToArrayBuffer(body);
} else if (bodyType === 'json') {
Expand All @@ -40,7 +46,7 @@ function deserializeResponseBody(body, bodyType) {
return body;
}
/* c8 ignore next*/
throw new Error(`Unknown body type: ${bodyType}`);
throw new Error(`Cannot deserialize unknown body type: ${bodyType}`);
}

class PlaybackResponse {
Expand Down
1 change: 1 addition & 0 deletions lib/commands/entities/tests/PlaybackRequestMap.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ describe('PlaybackRequestMap', () => {
matchers: [{
id: 'mock-request-matcher-id',
ignoredAttributes: [],
method: 'GET',
matcher: '/example',
minTimes: 2,
responses: [
Expand Down
9 changes: 8 additions & 1 deletion lib/commands/entities/tests/PlaybackRequestMatcher.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ function createSerializedRequestMatcher(id, minTimes, responseCount, ignoredAttr
for (let i = 0; i < responseCount; i++) {
responses.push({
id: `mock-intercepted-response-id-${i + 1}`,
method: 'GET',
matcher: '/foo/bar',
statusCode: 200,
statusMessage: 'OK',
body: 'body-string',
Expand Down Expand Up @@ -74,12 +76,16 @@ describe('PlaybackRequestMatcher', () => {

describe('deserialization', () => {
it('works', () => {
// Arrange
const serialized = createSerializedRequestMatcher('mock-id', 2, 3);
// Act
const matcher = new PlaybackRequestMatcher(createSerializedRequestMatcher('mock-id', 2, 3));
const matcher = new PlaybackRequestMatcher(serialized);

// Assert
expect(matcher.id).to.equal('mock-id');
expect(matcher.minTimes).to.equal(2);
expect(matcher.method).to.equal(serialized.method);
expect(matcher.matcher).to.equal(serialized.matcher);
expect(matcher.stale).to.be.true;
for (let i = 1; i <= 3; i++) {
expect(matcher.getResponse(`mock-intercepted-response-id-${i}`)).property('hits').to.equal(1);
Expand Down Expand Up @@ -108,6 +114,7 @@ describe('PlaybackRequestMatcher', () => {
expect(serialized).to.deep.equal({
id: 'mock-request-id',
ignoredAttributes: [],
method: 'GET',
matcher: 'http://example.com/',
minTimes: 5,
responses: [{
Expand Down
14 changes: 8 additions & 6 deletions lib/commands/entities/tests/PlaybackResponse.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ describe('PlaybackResponse', () => {
{ body: '{"foo":"bar"}', bodyType: 'json', expected: { foo: 'bar' } },
{ body: 'body-string', bodyType: 'string', expected: 'body-string' },
{ body: 'Y2hlZXNl', bodyType: 'ArrayBuffer', expected: new Uint8Array(Buffer.from('Y2hlZXNl', 'base64')) },
{ body: undefined, bodyType: null, expected: undefined},
];

for (const { body, bodyType, expected } of cases) {
Expand Down Expand Up @@ -115,13 +116,14 @@ describe('PlaybackResponse', () => {
});

const cases = [
{ body: { foo: 'bar' }, bodyType: 'json', expected: '{"foo":"bar"}' },
{ body: 'body-string', bodyType: 'string', expected: 'body-string' },
{ body: new Uint8Array(Buffer.from('Y2hlZXNl', 'base64')), bodyType: 'ArrayBuffer', expected: 'Y2hlZXNl' },
{ body: { foo: 'bar' }, expectedBodyType: 'json', expected: '{"foo":"bar"}' },
{ body: 'body-string', expectedBodyType: 'string', expected: 'body-string' },
{ body: new Uint8Array(Buffer.from('Y2hlZXNl', 'base64')), expectedBodyType: 'ArrayBuffer', expected: 'Y2hlZXNl' },
{ body: undefined, expectedBodyType: null, expected: undefined },
];

for (const { body, bodyType, expected } of cases) {
it(`should handle a bodyType of "${bodyType}"`, () => {
for (const { body, expectedBodyType, expected } of cases) {
it(`should handle a bodyType of "${expectedBodyType}"`, () => {
const playbackResponse = new PlaybackResponse(...createConstructorArgs(body));

// Act
Expand All @@ -132,7 +134,7 @@ describe('PlaybackResponse', () => {
expect(serialized.statusCode).to.equal(200);
expect(serialized.statusMessage).to.equal('OK');
expect(serialized.body).to.equal(expected);
expect(serialized.bodyType).to.equal(bodyType);
expect(serialized.bodyType).to.equal(expectedBodyType);
expect(serialized.headers).to.deep.equal({ 'mock-header': 'yes' });
});
}
Expand Down
12 changes: 10 additions & 2 deletions lib/commands/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ afterEach(function playbackAfterEach() {
message: 'Checking for pending requests...',
consoleProps: () => ({
'Pending Requests': [],
'All Requests': [],
})
});

Expand All @@ -78,11 +79,13 @@ afterEach(function playbackAfterEach() {
})
.then(() => {
if (map.hasPendingRequests()) {
const pendingRequests = map.getPendingRequests().map(request => request.matcher);
const pendingRequests = map.getPendingRequests().map(request => `${request.method} ${request.matcher}`);
const allRequests = map.getAll().map(request => `${request.method} ${request.matcher}`);
// Update the log for the error state.
log.set('message', `${pendingRequests.length} pending requests.`)
.set('consoleProps', () => ({
'Pending Requests': pendingRequests,
'All Requests': allRequests,
}))
.error()
.end();
Expand Down Expand Up @@ -116,7 +119,12 @@ const playback = {
if (isPlaybackMode('playback')) {
const response = map.getResponse(id, req, options);
if (response) {
req.reply(response);
try {
req.reply(response.statusCode,response.body, response.headers);
} catch (e) {
console.error(response);
throw e;
}
return;
} else if (!isPlaybackMode('hybrid')) {
// TODO: Improve error message.
Expand Down
2 changes: 2 additions & 0 deletions sandbox/cypress/support/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
// https://on.cypress.io/configuration
// ***********************************************************

import '@testing-library/cypress/add-commands';

// Import commands.js using ES2015 syntax:
import './commands'

Expand Down
Loading

0 comments on commit df54a2a

Please sign in to comment.