I'm trying to test how my application handles cookies or the lack of cookies. So far I have just two simple tests that I want to try.
How the tests should behave
Test 1: I set document.cookie
to some value & my function returns the cookie as an object
Test 2: I set document.cookie
back to empty string & my function returns undefined
How the tests actually behave
Test 1: document.cookie
is set and my function returns the proper object
Test 2: `document.cookie1 is set back to empty string, but still returns the object from the previous test.
I could just run test # 2 first, but that just avoids the problem rather than fix the problem.
Plus, I would like to understand why the problem is happening.
Why can't I set or modify the document object after my initial change to document.cookie
?
I've also tried document.cookie = ''
in the beforeEach
and that didn't work either.
Jest Test
test('if the browser has a session cookie, then its data will be returned as an object', () => {
document.cookie =
'session={"userId":8,"expiration":1660938823,"accessToken":"fakeAccessToken","refreshToken":"fakeRefreshToken"}';
const data = cookieData();
expect(data).toEqual(EXPECTED_STRUCTURE);
});
test('if the browser does not have a session cookie, then undefined will be returned', () => {
document.cookie = '';
const data = cookieData();
expect(data).toBe(undefined);
});
const EXPECTED_STRUCTURE = {
userId: 8,
expiration: 1660938823,
accessToken: 'fakeAccessToken',
refreshToken: 'fakeRefreshToken'
};
Code
export const cookieData = (): ICustomCookieStructure | undefined => {
try {
const cookies = document.cookie.split(COOKIES_SEPARATOR);
const cookieIndex = cookies.findIndex((el) =>
el.includes(TARGET_COOKIE_PREFIX)
);
if (cookieIndex === -1) return undefined;
const cookieContent = cookies[cookieIndex].replace(
TARGET_COOKIE_PREFIX,
''
);
const contentDecoded = decodeURIComponent(cookieContent);
const contentParsed = JSON.parse(contentDecoded);
if (Object.keys(contentParsed).length) {
return {
userId: contentParsed.userId,
expiration: Number(contentParsed.expiration),
accessToken: contentParsed.accessToken,
refreshToken: contentParsed.refreshToken
};
}
} catch (e: any) {
throw new Error(
`Failed to either get or parse cookie from browser: ${e.message}`
);
}
return undefined;
};
CodePudding user response:
I figured out a solution to the problem, although I still don't understand why I couldn't set document.cookie more than once.
Here was the way around it:
const mockFunction = jest.fn();
beforeAll(() => {
Object.defineProperty(document, 'cookie', {
get: mockFunction
});
});
beforeEach(() => {
mockFunction.mockReturnValue('');
});
test('if browser has our cookie, then its data will be returned', () => {
mockFunction.mockReturnValue(COOKIE_VALUE);
const data = cookieData();
expect(data).toEqual(EXPECTED_STRUCTURE);
});
test('if browser does not have our cookie, then undefined will be returned', () => {
const data = cookieData();
expect(data).toBe(undefined);
});
CodePudding user response:
I assume it's because once document.cookie
is assigned it get's treated as readonly. I had something similar happening recently as well. What you can do though is something similar to this:
Object.defineProperty(document.documentElement, "lang", {
value: null,
configurable: true,
});
So for your specific case you could try:
Object.defineProperty(document, "cookie", {
value: '',
configurable: true,
});