Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: implement cookie persistence using tough-cookie #2206

Merged
merged 10 commits into from
Jul 23, 2024
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ msw-*.tgz
.husky/_
.env
**/test-results
/test/modules/node/node-esm-tests

# Smoke test temporary files.
/package.json.copy
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@
"dependencies": {
"@bundled-es-modules/cookie": "^2.0.0",
"@bundled-es-modules/statuses": "^1.0.1",
"@bundled-es-modules/tough-cookie": "^0.1.6",
"@inquirer/confirm": "^3.0.0",
"@mswjs/cookies": "^1.1.0",
"@mswjs/interceptors": "^0.29.0",
"@open-draft/until": "^2.1.0",
"@types/cookie": "^0.6.0",
Expand Down
35 changes: 17 additions & 18 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 32 additions & 16 deletions src/core/utils/HttpResponse/decorators.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import statuses from '@bundled-es-modules/statuses'
import type { HttpResponseInit } from '../../HttpResponse'
import { Headers as HeadersPolyfill } from 'headers-polyfill'
import type { HttpResponseInit } from '../../HttpResponse'

const { message } = statuses

export const kSetCookie = Symbol('kSetCookie')

export interface HttpResponseDecoratedInit extends HttpResponseInit {
status: number
statusText: string
Expand Down Expand Up @@ -38,21 +40,35 @@ export function decorateResponse(
})
}

// Cookie forwarding is only relevant in the browser.
if (typeof document !== 'undefined') {
// Write the mocked response cookies to the document.
// Use `headers-polyfill` to get the Set-Cookie header value correctly.
// This is an alternative until TypeScript 5.2
// and Node.js v20 become the minimum supported version
// and getSetCookie in Headers can be used directly.
const responseCookies = HeadersPolyfill.prototype.getSetCookie.call(
init.headers,
)

for (const cookieString of responseCookies) {
// No need to parse the cookie headers because it's defined
// as the valid cookie string to begin with.
document.cookie = cookieString
const responseCookies = init.headers.get('set-cookie')

if (responseCookies) {
// Record the raw "Set-Cookie" response header provided
// in the HeadersInit. This is later used to store these cookies
// in cookie jar and return the right cookies in the "cookies"
// response resolver argument.
Object.defineProperty(response, kSetCookie, {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would love to store the cookies here directly but tough-cookie needs a URL to associate the cookies with. response.url is not always defined (this may be easier to solve). I don't like introducing a symbol just to pass the data around.

value: responseCookies,
enumerable: false,
writable: false,
})

// Cookie forwarding is only relevant in the browser.
if (typeof document !== 'undefined') {
// Write the mocked response cookies to the document.
// Use `headers-polyfill` to get the Set-Cookie header value correctly.
// This is an alternative until TypeScript 5.2
// and Node.js v20 become the minimum supported version
// and getSetCookie in Headers can be used directly.
const responseCookiePairs = HeadersPolyfill.prototype.getSetCookie.call(
init.headers,
)

for (const cookieString of responseCookiePairs) {
// No need to parse the cookie headers because it's defined
// as the valid cookie string to begin with.
document.cookie = cookieString
}
}
}

Expand Down
Loading
Loading