A got call with a tough-cookie CookieJar where the response has a set-cookie header rejects if run in Jest. The repro repo below contains both a yarn start script that runs in plain Node and succeeds, and a yarn test script that runs the same code in Jest.
https://github.com/sindresorhus/got/issues/811 was closed in favor of https://github.com/facebook/jest/issues/4305, however it seems that, at least after the got refactor, util.promisify itself in Jest is not the problem - got's role in this appears to be the "Horrible tough-cookie check" - removing the following !Reflect.has conditional (making the two assignments unconditional) resolves the issue.
https://github.com/sindresorhus/got/blob/41795d739c2a6a2908cbb7c7bff310004fcc09ec/source/normalize-arguments.ts#L172
However, I would not dare to make that change without input from @szmarczak or @sindresorhus because I do not have context on what it is there to guard against in the first place.
Jest's new role in this is very likely due to something like https://github.com/facebook/jest/issues/2549, but that is unlikely to be fixed in Jest anytime soon.
Rejects with
TypeError: cb is not a function
at next (node_modules/tough-cookie/lib/cookie.js:1090:9)
at MemoryCookieStore.Object.<anonymous>.MemoryCookieStore.putCookie (node_modules/tough-cookie/lib/memstore.js:124:3)
at withCookie (node_modules/tough-cookie/lib/cookie.js:1109:13)
at MemoryCookieStore.Object.<anonymous>.MemoryCookieStore.findCookie (node_modules/tough-cookie/lib/memstore.js:61:12)
at CookieJar.Object.<anonymous>.CookieJar.setCookie (node_modules/tough-cookie/lib/cookie.js:1113:9)
at internal/util.js:297:30
at node_modules/got/dist/source/request-as-event-emitter.js:76:90
at Array.map (<anonymous>)
at ClientRequest.handleResponse (node_modules/got/dist/source/request-as-event-emitter.js:76:47)
at ClientRequest.origin.emit (node_modules/@szmarczak/http-timer/dist/source/index.js:39:20)
Sets the cookie into the cookie jar with no error.
https://github.com/jeysal/got-tough-cookie-jest-bug-repro
Oh okay 馃憤 still seems like a bit of a hack here but as said I don't have the context, it might be legit 馃槄
Workaround that worked for me:
const cookieJar = new CookieJar()
const compatCookieJar = {
setCookie: (rawCookie: string, url: string) =>
new Promise((resolve, reject) =>
cookieJar.setCookie(rawCookie, url, (err, value) =>
err ? reject(err) : resolve(value)
)
),
getCookieString: async (url: string) =>
new Promise((resolve, reject) =>
cookieJar.getCookieString(url, (err, value) =>
err ? reject(err) : resolve(value)
)
)
}
await got(uri, { cookieJar: compatCookieJar });
Ours was
setCookie = promisify((rawCookie, url, cb) => jar.setCookie(rawCookie, url, {}, cb));
Object.defineProperty(setCookie, 'length', { value: 2 });
const getCookieString = promisify((url, cb) => jar.getCookieString(url, {}, cb));
Object.defineProperty(getCookieString, 'length', { value: 1 });
Most helpful comment
Workaround that worked for me: