Skip to content

Commit

Permalink
fix: support multiple response cookies using "ctx.cookie()" (#1311)
Browse files Browse the repository at this point in the history
* fix: support multiple response cookies

* chore: use "clearCookies" in tests
  • Loading branch information
kettanaito committed Jul 4, 2022
1 parent b736dcc commit 66c3ad8
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 14 deletions.
31 changes: 27 additions & 4 deletions src/context/cookie.test.ts
Expand Up @@ -4,13 +4,36 @@
import * as cookieUtils from 'cookie'
import { cookie } from './cookie'
import { response } from '../response'
import { clearCookies } from '../../test/support/utils'

test('sets a given cookie on the response', async () => {
const result = await response(cookie('my-cookie', 'arbitrary-value'))
beforeAll(() => {
clearCookies()
})

afterEach(() => {
clearCookies()
})

expect(result.headers.get('set-cookie')).toEqual('my-cookie=arbitrary-value')
test('sets a given response cookie', async () => {
const result = await response(cookie('myCookie', 'value'))

expect(result.headers.get('set-cookie')).toBe('myCookie=value')

// Propagates the response cookies on the document.
const allCookies = cookieUtils.parse(document.cookie)
expect(allCookies).toHaveProperty('my-cookie', 'arbitrary-value')
expect(allCookies).toEqual({ myCookie: 'value' })
})

test('supports setting multiple response cookies', async () => {
const result = await response(
cookie('firstCookie', 'yes'),
cookie('secondCookie', 'no'),
)

expect(result.headers.get('set-cookie')).toBe(
'secondCookie=no, firstCookie=yes',
)

const allCookies = cookieUtils.parse(document.cookie)
expect(allCookies).toEqual({ firstCookie: 'yes', secondCookie: 'no' })
})
2 changes: 1 addition & 1 deletion src/context/cookie.ts
Expand Up @@ -12,7 +12,7 @@ export const cookie = (
): ResponseTransformer => {
return (res) => {
const serializedCookie = cookieUtils.serialize(name, value, options)
res.headers.set('Set-Cookie', serializedCookie)
res.headers.append('Set-Cookie', serializedCookie)

if (typeof document !== 'undefined') {
document.cookie = serializedCookie
Expand Down
5 changes: 2 additions & 3 deletions src/utils/request/getRequestCookies.test.ts
Expand Up @@ -2,7 +2,7 @@
* @jest-environment jsdom
*/
import { getRequestCookies } from './getRequestCookies'
import { createMockedRequest } from '../../../test/support/utils'
import { clearCookies, createMockedRequest } from '../../../test/support/utils'

beforeAll(() => {
// Emulate some `document.cookie` value.
Expand All @@ -11,8 +11,7 @@ beforeAll(() => {
})

afterAll(() => {
// Clean up the `document.cookie` value.
document.cookie = ''
clearCookies()
})

test('returns all document cookies given "include" credentials', () => {
Expand Down
6 changes: 3 additions & 3 deletions src/utils/request/setRequestCookies.test.ts
Expand Up @@ -3,14 +3,14 @@
*/
import { Headers } from 'headers-polyfill/lib'
import { setRequestCookies } from './setRequestCookies'
import { createMockedRequest } from '../../../test/support/utils'
import { clearCookies, createMockedRequest } from '../../../test/support/utils'

beforeAll(() => {
document.cookie = ''
clearCookies()
})

afterEach(() => {
document.cookie = ''
clearCookies()
})

test('preserves request cookies when there are no document cookies to infer', () => {
Expand Down
9 changes: 8 additions & 1 deletion test/rest-api/cookies.mocks.ts
Expand Up @@ -3,12 +3,19 @@ import { setupWorker, rest } from 'msw'
const worker = setupWorker(
rest.get('/user', (req, res, ctx) => {
return res(
ctx.cookie('my-cookie', 'value'),
ctx.cookie('myCookie', 'value'),
ctx.json({
mocked: true,
}),
)
}),
rest.get('/order', (req, res, ctx) => {
return res(
ctx.cookie('firstCookie', 'yes'),
ctx.cookie('secondCookie', 'no'),
ctx.json({ mocked: true }),
)
}),
)

worker.start()
22 changes: 20 additions & 2 deletions test/rest-api/cookies.test.ts
Expand Up @@ -10,7 +10,6 @@ test('allows setting cookies on the mocked response', async () => {
const runtime = await createRuntime()

const res = await runtime.request('/user')

const headers = await res.allHeaders()
const body = await res.json()

Expand All @@ -25,5 +24,24 @@ test('allows setting cookies on the mocked response', async () => {
return document.cookie
})
const allCookies = cookieUtils.parse(cookieString)
expect(allCookies).toHaveProperty('my-cookie', 'value')
expect(allCookies).toEqual({ myCookie: 'value' })
})

test('allows setting multiple response cookies', async () => {
const runtime = await createRuntime()

const res = await runtime.request('/order')
const headers = await res.allHeaders()

expect(headers).toHaveProperty('x-powered-by', 'msw')
expect(headers).not.toHaveProperty('set-cookie')

const cookieString = await runtime.page.evaluate(() => {
return document.cookie
})
const allCookies = cookieUtils.parse(cookieString)
expect(allCookies).toEqual({
firstCookie: 'yes',
secondCookie: 'no',
})
})
8 changes: 8 additions & 0 deletions test/support/utils.ts
Expand Up @@ -80,3 +80,11 @@ export function promisifyChildProcess(
})
})
}

export function clearCookies(): void {
document.cookie.split(';').forEach((cookie) => {
document.cookie = cookie
.replace(/^ +/, '')
.replace(/=.*/, `=;expires=${new Date(0).toUTCString()};path=/`)
})
}

0 comments on commit 66c3ad8

Please sign in to comment.