<commit_before>/* eslint import/no-extraneous-dependencies: ["error", {"devDependencies": true}] */
'use strict';

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

const User = require('../../models/User');
const dntUsers = require('../fixtures/dnt-users');
const users = require('../fixtures/users');
const checkins = require('../fixtures/checkins.js');
const photos = require('../fixtures/photos.js');
const mockery = require('mockery');

const getUserData = auth.getUserData;

describe('POST /steder/:sted/besok', () => {
  let appMocked;
  let authMocked;

  before(() => mockery.enable({
    useCleanCache: true,
    warnOnReplace: false,
    warnOnUnregistered: false,
  }));

  before(() => mockery.registerMock('node-fetch', () => Promise.resolve({
    status: 200,
    json: () => ({
      _id: '400000000000000000000000',
      geojson: {
        type: 'Point',
        coordinates: [
          8.31323888888889,
          61.63635277777777,
        ],
      },
    }),
  })));

  before(() => {
    appMocked = request(require('../../index')); // eslint-disable-line global-require
  });

  before(() => {
    authMocked = require('../../lib/auth'); // eslint-disable-line global-require

    authMocked.getUserData = () => Promise.resolve(dntUsers[1]);
  });

  after(() => {
    authMocked.getUserData = getUserData;
  });

  after(() => mockery.deregisterMock('node-fetch'));
  after(() => mockery.disable());

  const url = '/api/dev/steder/400000000000000000000000/besok';
  const checkinData = {
    lon: 8.312466144561768,
    lat: 61.63644183145977,
    timestamp: '2016-08-01T23:59:59.923Z',
    public: false,
  };

  it('returns error for missing user auth', () => (
    appMocked.post(url)
      .send(checkinData)
      .expect(401)
      .expect({
        code: 401,
        message: 'X-User-Id header is required',
      })
  ));

  it('returns error for invalid coordinates', () => (
    appMocked.post(url)
      .set('X-User-Id', '1234')
      .set('X-User-Token', 'abc<PASSWORD>')
      .send({ lon: 1337, lat: 4444 })
      .expect(400)
      .expect(res => {
        assert.equal(res.body.code, 400);
        assert.equal(res.body.message, 'Checkin validation failed');
        assert.equal(typeof res.body.errors['location.coordinates.0'], 'object');
        assert.equal(typeof res.body.errors['location.coordinates.1'], 'object');
      })
  ));

  it('returns error for checkins from the future', () => {
    const checkinDataBeforeTimeout = JSON.parse(JSON.stringify(checkinData));
    const now = new Date();
    checkinDataBeforeTimeout.timestamp = now.setHours(now.getHours() + 24);
    return appMocked.post(url)
      .set('X-User-Id', '1234')
      .set('X-User-Token', 'abc<PASSWORD>')
      .send(checkinDataBeforeTimeout)
      .expect(400)
      .expect(res => {
        assert.equal(typeof res.body.errors.timestamp, 'object');
        assert.equal(/from the future/.test(res.body.errors.timestamp.message), true);
        assert.equal(res.body.code, 400);
        assert.equal(res.body.message, 'Checkin validation failed');
      });
  });

  it('returns error for second checkin before checkin timeout', () => {
    const checkinDataBeforeTimeout = JSON.parse(JSON.stringify(checkinData));
    const checkinTimestamp = new Date(checkins[0].timestamp);
    const invalidCheckinTimestamp = new Date(checkinTimestamp.setSeconds(
      checkinTimestamp.getSeconds() + parseInt(process.env.CHECKIN_TIMEOUT, 10) - 1 // eslint-disable-line no-mixed-operators, max-len
    ));
    checkinDataBeforeTimeout.timestamp = invalidCheckinTimestamp.toISOString();

    return appMocked.post(url)
      .set('X-User-Id', '1234')
      .set('X-User-Token', '<PASSWORD>')
      .send(checkinDataBeforeTimeout)
      .expect(400)
      .expect(res => {
        assert.equal(typeof res.body.errors.timestamp, 'object');
        assert.equal(res.body.code, 400);
        assert.equal(res.body.message, 'Checkin validation failed');
      });
  });

  it('returns error for duplicate checkin', () => {
    const duplicateCheckin = JSON.parse(JSON.stringify(checkins[0]));
    duplicateCheckin.lat = duplicateCheckin.location.coordinates[1];
    duplicateCheckin.lon = duplicateCheckin.location.coordinates[0];

    delete duplicateCheckin._id;
    delete duplicateCheckin.location;

    return appMocked.post(url)
      .set('X-User-Id', '1234')
      .set('X-User-Token', '<PASSWORD>')
      .send(duplicateCheckin)
      .expect(400)
      .expect(res => {
        assert.equal(typeof res.body.errors.timestamp, 'object');
        assert.equal(res.body.code, 400);
        assert.equal(res.body.message, 'Checkin validation failed');
      });
  });

  it('stores one and rejects one when two timestamped are posted at the same time', () => {
    const checkin1 = appMocked.post(url)
      .set('X-User-Id', '1234')
      .set('X-User-Token', '<PASSWORD>')
      .send(checkinData);

    const checkin2 = appMocked.post(url)
      .set('X-User-Id', '1234')
      .set('X-User-Token', '<PASSWORD>')
      .send(checkinData);

    return Promise.all([checkin1, checkin2]).then(all => {
      const stored = all.find(r => r.status === 200);
      const rejected = all.find(r => r.status === 400);

      assert(all.length, 2);
      assert(stored);
      assert(rejected);
      assert(rejected.body.errors.timestamp);
    });
  });

  it('stores new valid checkin to the database', () => (
    appMocked.post(url)
      .set('X-User-Id', '1234')
      .set('X-User-Token', '<PASSWORD>')
      .send(checkinData)
      .expect(200)
      .expect('Location', /api\/dev\/steder\/400000000000000000000000/)
      .expect(res => {
        const { data, message } = res.body;
        assert.equal(message, 'Ok');
        assert.equal(data.ntb_steder_id, '400000000000000000000000');
        assert.deepEqual(data.location, {
          coordinates: [checkinData.lon, checkinData.lat],
          type: 'Point',
        });
        assert.equal(data.user._id, 1234);<commit_msg>test(checkin): use filter instead of find<commit_after>/* eslint import/no-extraneous-dependencies: ["error", {"devDependencies": true}] */
'use strict';

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

const User = require('../../models/User');
const dntUsers = require('../fixtures/dnt-users');
const users = require('../fixtures/users');
const checkins = require('../fixtures/checkins.js');
const photos = require('../fixtures/photos.js');
const mockery = require('mockery');

const getUserData = auth.getUserData;

describe('POST /steder/:sted/besok', () => {
  let appMocked;
  let authMocked;

  before(() => mockery.enable({
    useCleanCache: true,
    warnOnReplace: false,
    warnOnUnregistered: false,
  }));

  before(() => mockery.registerMock('node-fetch', () => Promise.resolve({
    status: 200,
    json: () => ({
      _id: '400000000000000000000000',
      geojson: {
        type: 'Point',
        coordinates: [
          8.31323888888889,
          61.63635277777777,
        ],
      },
    }),
  })));

  before(() => {
    appMocked = request(require('../../index')); // eslint-disable-line global-require
  });

  before(() => {
    authMocked = require('../../lib/auth'); // eslint-disable-line global-require

    authMocked.getUserData = () => Promise.resolve(dntUsers[1]);
  });

  after(() => {
    authMocked.getUserData = getUserData;
  });

  after(() => mockery.deregisterMock('node-fetch'));
  after(() => mockery.disable());

  const url = '/api/dev/steder/400000000000000000000000/besok';
  const checkinData = {
    lon: 8.312466144561768,
    lat: 61.63644183145977,
    timestamp: '2016-08-01T23:59:59.923Z',
    public: false,
  };

  it('returns error for missing user auth', () => (
    appMocked.post(url)
      .send(checkinData)
      .expect(401)
      .expect({
        code: 401,
        message: 'X-User-Id header is required',
      })
  ));

  it('returns error for invalid coordinates', () => (
    appMocked.post(url)
      .set('X-User-Id', '1234')
      .set('X-User-Token', '<PASSWORD>')
      .send({ lon: 1337, lat: 4444 })
      .expect(400)
      .expect(res => {
        assert.equal(res.body.code, 400);
        assert.equal(res.body.message, 'Checkin validation failed');
        assert.equal(typeof res.body.errors['location.coordinates.0'], 'object');
        assert.equal(typeof res.body.errors['location.coordinates.1'], 'object');
      })
  ));

  it('returns error for checkins from the future', () => {
    const checkinDataBeforeTimeout = JSON.parse(JSON.stringify(checkinData));
    const now = new Date();
    checkinDataBeforeTimeout.timestamp = now.setHours(now.getHours() + 24);
    return appMocked.post(url)
      .set('X-User-Id', '1234')
      .set('X-User-Token', '<PASSWORD>')
      .send(checkinDataBeforeTimeout)
      .expect(400)
      .expect(res => {
        assert.equal(typeof res.body.errors.timestamp, 'object');
        assert.equal(/from the future/.test(res.body.errors.timestamp.message), true);
        assert.equal(res.body.code, 400);
        assert.equal(res.body.message, 'Checkin validation failed');
      });
  });

  it('returns error for second checkin before checkin timeout', () => {
    const checkinDataBeforeTimeout = JSON.parse(JSON.stringify(checkinData));
    const checkinTimestamp = new Date(checkins[0].timestamp);
    const invalidCheckinTimestamp = new Date(checkinTimestamp.setSeconds(
      checkinTimestamp.getSeconds() + parseInt(process.env.CHECKIN_TIMEOUT, 10) - 1 // eslint-disable-line no-mixed-operators, max-len
    ));
    checkinDataBeforeTimeout.timestamp = invalidCheckinTimestamp.toISOString();

    return appMocked.post(url)
      .set('X-User-Id', '1234')
      .set('X-User-Token', '<PASSWORD>')
      .send(checkinDataBeforeTimeout)
      .expect(400)
      .expect(res => {
        assert.equal(typeof res.body.errors.timestamp, 'object');
        assert.equal(res.body.code, 400);
        assert.equal(res.body.message, 'Checkin validation failed');
      });
  });

  it('returns error for duplicate checkin', () => {
    const duplicateCheckin = JSON.parse(JSON.stringify(checkins[0]));
    duplicateCheckin.lat = duplicateCheckin.location.coordinates[1];
    duplicateCheckin.lon = duplicateCheckin.location.coordinates[0];

    delete duplicateCheckin._id;
    delete duplicateCheckin.location;

    return appMocked.post(url)
      .set('X-User-Id', '1234')
      .set('X-User-Token', '<PASSWORD>')
      .send(duplicateCheckin)
      .expect(400)
      .expect(res => {
        assert.equal(typeof res.body.errors.timestamp, 'object');
        assert.equal(res.body.code, 400);
        assert.equal(res.body.message, 'Checkin validation failed');
      });
  });

  it('stores one and rejects one when two timestamped are posted at the same time', () => {
    const checkin1 = appMocked.post(url)
      .set('X-User-Id', '1234')
      .set('X-User-Token', '<PASSWORD>')
      .send(checkinData);

    const checkin2 = appMocked.post(url)
      .set('X-User-Id', '1234')
      .set('X-User-Token', '<PASSWORD>')
      .send(checkinData);

    return Promise.all([checkin1, checkin2]).then(all => {
      const stored = all.filter(r => r.status === 200);
      const rejected = all.filter(r => r.status === 400);

      assert.equal(stored.length, 1);
      assert.equal(rejected.length, 1);
      assert(rejected[0].body.errors.timestamp);
    });
  });

  it('stores new valid checkin to the database', () => (
    appMocked.post(url)
      .set('X-User-Id', '1234')
      .set('X-User-Token', '<PASSWORD>')
      .send(checkinData)
      .expect(200)
      .expect('Location', /api\/dev\/steder\/400000000000000000000000/)
      .expect(res => {
        const { data, message } = res.body;
        assert.equal(message, 'Ok');
        assert.equal(data.ntb_steder_id, '400000000000000000000000');
        assert.deepEqual(data.location, {
          coordinates: [checkinData.lon, checkinData.lat],
          type: 'Point',
        });
        assert.equal(data.user._id, 1234);
{'fraction_non_alphanumeric': 0.1717670286278381, 'fraction_numerical': 0.045409674234945706, 'mean_word_length': 3.0056013179571663, 'pattern_counts': {'":': 2, '<': 17, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 12, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1177282', 'n_tokens_mistral': 4281, 'n_tokens_neox': 3835, 'n_words': 692}