'use strict';

const assert = require('assert');
const request = require('supertest');
const Koa = require('../..');

describe('ctx.cookies.set()', () => {
  it('should set an unsigned cookie', async () => {
    const app = new Koa();

    app.use((ctx, next) => {
      ctx.cookies.set('name', 'jon');
      ctx.status = 204;
    });

    const server = app.listen();

    const res = await request(server)
      .get('/')
      .expect(204);

    const cookie = res.headers['set-cookie'].some(cookie => /^name=/.test(cookie));
    assert.equal(cookie, true);
  });

  describe('with .signed', () => {
    describe('when no .keys are set', () => {
      it('should error', () => {
        const app = new Koa();

        app.use((ctx, next) => {
          try {
            ctx.cookies.set('foo', 'bar', { signed: true });
          } catch (err) {
            ctx.body = err.message;
          }
        });

        return request(app.listen())
          .get('/')
          .expect('.keys required for signed cookies');
      });
    });

    it('should send a signed cookie', async () => {
      const app = new Koa();

      app.keys = ['a', 'b'];

      app.use((ctx, next) => {
        ctx.cookies.set('name', 'jon', { signed: true });
        ctx.status = 204;
      });

      const server = app.listen();

      const res = await request(server)
        .get('/')
        .expect(204);

      const cookies = res.headers['set-cookie'];

      assert.equal(cookies.some(cookie => /^name=/.test(cookie)), true);
      assert.equal(cookies.some(cookie => /(,|^)name\.sig=/.test(cookie)), true);
    });
  });

  describe('with secure', () => {
    it('should get secure from request', async () => {
      const app = new Koa();

      app.proxy = true;
      app.keys = ['a', 'b'];

      app.use(ctx => {
        ctx.cookies.set('name', 'jon', { signed: true });
        ctx.status = 204;
      });

      const server = app.listen();

      const res = await request(server)
        .get('/')
        .set('x-forwarded-proto', 'https') // mock secure
        .expect(204);

      const cookies = res.headers['set-cookie'];
      assert.equal(cookies.some(cookie => /^name=/.test(cookie)), true);
      assert.equal(cookies.some(cookie => /(,|^)name\.sig=/.test(cookie)), true);
      assert.equal(cookies.every(cookie => /secure/.test(cookie)), true);
    });
  });
});