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

Response cookies could be parsed #481

Open
nitrocode opened this issue May 16, 2018 · 5 comments
Open

Response cookies could be parsed #481

nitrocode opened this issue May 16, 2018 · 5 comments

Comments

@nitrocode
Copy link

nitrocode commented May 16, 2018

Thank you for the great package. I use it all the time in my tests.

I'm testing response cookies and I realized in order to get response cookies I need to do something like this

.expect(res => {
    console.log(res.headers['set-cookie'][0]);
});

And then dig through the set cookie header to verify that the correct cookie was returned. To make this easier, I converted the set-cookie header array to a dictionary using the cookie module

> const cookie = require('cookie');
> cookie.parse('cookieName=cookieValue; path=/; expires=Thu, 16 May 2019 19:00:43 GMT; domain=.google.co; httponly')
{
  cookieName: 'cookieValue',
  path: '/',
  expires: 'Thu, 16 May 2019 19:00:43 GMT',
  domain: '.google.co'
}

If this was part of supertest and could be used as an object off of the response object, it would be very helpful. I imagine a format something like this:

> res.cookies
{
  cookieName: { 
    value: 'cookieValue',
    path: '/',
    expires: 'Thu, 16 May 2019 19:00:43 GMT',
    domain: '.google.com'
  }, 
cookieName2: { 
    value: 'cookieValue2',
    path: '/',
    expires: 'Thu, 16 May 2019 19:00:43 GMT',
    domain: '.yahoo.com'
  }, 
}

What do you think? Good idea? Would you accept a PR for this?

@Bessonov
Copy link

Bessonov commented Aug 4, 2018

cookie module is broken because of misleading name. This module is capable to parse cookie header only and not set-cookie header. For example, you miss secure and httpOnly fields. For me, a module named cookie should do everything with cookies: create, verify, parse, modify, delete at least in browser and node.

See:

Shame on this module.

I use https://github.com/nfriedly/set-cookie-parser for my tests. Even it would be nice to get it built-in, I think this isn't required, because you get it very cheap:

agent
	.get('/test')
	.set('Accept', 'application/json')
	.expect((res: IncomingMessage) => {
		should(cookieParser.parse(res)
			// compare only important values, can be extracted in a utility function
			.map((c: Cookie) => {
				return {
				name: c.name,
				path: c.path,
				httpOnly: !!c.httpOnly,
				maxAge: c.maxAge,
				secure: c.secure
			}}))
			.deepEqual([
				{
					name: 'a',
					maxAge: 60,
					path: '/',
					httpOnly: true,
					secure: true
				},
				{
					name: 'b',
					maxAge: 60,
					path: '/',
					httpOnly: false,
					secure: true
				},
			])
	})
	.expect(204, done)

@nitrocode
Copy link
Author

@Bessonov I like your approach! I agree the cookie module isn't the best option. I'm sure there are other modules that do support the flags you mentioned.

Even with your helpful approach, it would be very nice to have the ability to go through a json dictionary of cookie names and their corresponding flags via res.cookies.

@LuisOsta
Copy link

Has there been any move towards this? I use supertest a lot and it would be a great feature

@the-vampiire
Copy link

the-vampiire commented Jul 4, 2019

@LuisOsta havent seen anything on this so i wrote a small parser (~15 lines). feel free to drop it into your codebase. heres the gist, it includes jest tests as well
https://gist.github.com/the-vampiire/a564af41ed0ce8eb7c30dbe6c0f627d8

output shape

const cookies = {
  cookieName: {
    value: 'cookie value',
    flags: {
      flagName: 'flag value',
      booleanFlag: true, // boolean flags (no value) are given true as their value
    },
  },
};

usage

const app = require('./app');
const request = require('supertest');
const { extractCookies } = require('./utils/extract-cookies');

test('some test needing cookie details', async () => {
  const res = await request(app).post('/tokens', { ...data });
  const cookies = extractCookies(res.headers); // or res.header alias
  // do tests on cookies, cookies.cookieName.[value, flags.[flagName]]
});

@willrust
Copy link

willrust commented Jan 23, 2023

Getting cookies from the agent worked for me.

import { Cookie, CookieAccessInfo } from 'cookiejar';

it('Has expected cookie', async () => {
    const agent = request.agent(app);
    const response = await agent.post('/tokens');
    const someCookie:Cookie = agent.jar.getCookie('someCookieName', CookieAccessInfo.All);

    expect(someCookie).toBeDefined();
    expect(someCookie?.value).toBe('someTokenValue');
});

agent.jar.getCookie returns Cookie | undefined.
Cookie type def includes: name, value, expiration_date...

There's also getCookies(accessInfo: CookieAccessInfo) if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants