<commit_before>import request from 'supertest';
import app from '../src/app.js';
import * as db from '../src/db';
import del from 'del';
import MockDate from 'mockdate';
import { findNewNotifications } from '../src/routes';

jest.mock('../src/slack');
import * as slack from '../src/slack';
slack.postOnSlack.mockImplementation(() => Promise.resolve());
slack.postOnSlackMultipleChannels.mockImplementation(() => Promise.resolve());

describe('app', () => {

  describe('slackCommand', () => {

    beforeEach(async () => {
      await db.init(`db-${Math.random().toString(36).substr(2, 20)}`);
    });

    afterEach(async () => {
      await db.close();
    });

    afterAll(async () => {
      await del('db-*');
    });

    it('returns an error if Slack POST format is not respected', () => {
      return request(app).post('/slackCommand', { asdf: 'asdf' })
        .expect(422)
        .then((res) => {
          expect(typeof res.text).toBe('string');
          expect(res.text).toBe('command does not respect Slack POST format');
        });
    });

    it('shows an empty list of pledges with the list command', () => {
      return request(app).post('/slackCommand')
        .send('user_name=luca')
        .send('text=list')
        .expect(200)
        .then((res) => {
          expect(typeof res.text).toBe('string');
          // headers for lists are presents
          expect(res.text).toMatch('My pledges');
          expect(res.text).toMatch('My requests');
          // no pledge is present (empty lists)
          expect(res.text).not.toMatch('pledged to');
        });
    });

    it('notifies both requester and performer when a pledge is created', () => {
      return request(app).post('/slackCommand')
        .send('user_name=requester')
        .send('text=@performer pledge content by tomorrow')
        .expect(200)
        .then((res) => {
          expect(typeof res.text).toBe('string');
          // notification for requester sent as response to slack command
          expect(res.text).toMatch('You asked @performer to \"pledge content\" by tomorrow');
          // notification for performer
          expect(slack.postOnSlack.mock.calls[0][0].text)
            .toMatch('@requester asked you to \"pledge content\" by tomorrow');
          expect(slack.postOnSlack.mock.calls[0][0].channel)
            .toMatch('@performer');
        });
    });

    it('notifies both requester and performer when a pledge has expired', () => {
      MockDate.set(0, 0);
      return request(app).post('/slackCommand')
        .send('user_name=requester')
        .send('text=@performer pledge content by today at 10am')
        .expect(200)
        .then(async () => {
          const nExp = () =>
            slack.postOnSlackMultipleChannels.mock.calls.filter((c) => c[0].text.match(/expired/)).length;
          // just before, no notifications
          MockDate.set(32400000 - 1);
          await findNewNotifications();
          expect(nExp()).toBe(0);
          // right after, it notifies
          MockDate.set(32400000 + 1);
          await findNewNotifications();
          expect(nExp()).toBe(1);
          // after some time, does not notify twice
          MockDate.set(32400000 + 999);
          await findNewNotifications();
          expect(nExp()).toBe(1);
        });
    });

  });

});
<commit_msg>adjust interval based on timezone<commit_after>import request from 'supertest';
import app from '../src/app.js';
import * as db from '../src/db';
import del from 'del';
import MockDate from 'mockdate';
import { findNewNotifications } from '../src/routes';

jest.mock('../src/slack');
import * as slack from '../src/slack';
slack.postOnSlack.mockImplementation(() => Promise.resolve());
slack.postOnSlackMultipleChannels.mockImplementation(() => Promise.resolve());

describe('app', () => {

  describe('slackCommand', () => {

    beforeEach(async () => {
      await db.init(`db-${Math.random().toString(36).substr(2, 20)}`);
    });

    afterEach(async () => {
      await db.close();
    });

    afterAll(async () => {
      await del('db-*');
    });

    it('returns an error if Slack POST format is not respected', () => {
      return request(app).post('/slackCommand', { asdf: 'asdf' })
        .expect(422)
        .then((res) => {
          expect(typeof res.text).toBe('string');
          expect(res.text).toBe('command does not respect Slack POST format');
        });
    });

    it('shows an empty list of pledges with the list command', () => {
      return request(app).post('/slackCommand')
        .send('user_name=luca')
        .send('text=list')
        .expect(200)
        .then((res) => {
          expect(typeof res.text).toBe('string');
          // headers for lists are presents
          expect(res.text).toMatch('My pledges');
          expect(res.text).toMatch('My requests');
          // no pledge is present (empty lists)
          expect(res.text).not.toMatch('pledged to');
        });
    });

    it('notifies both requester and performer when a pledge is created', () => {
      return request(app).post('/slackCommand')
        .send('user_name=requester')
        .send('text=@performer pledge content by tomorrow')
        .expect(200)
        .then((res) => {
          expect(typeof res.text).toBe('string');
          // notification for requester sent as response to slack command
          expect(res.text).toMatch('You asked @performer to \"pledge content\" by tomorrow');
          // notification for performer
          expect(slack.postOnSlack.mock.calls[0][0].text)
            .toMatch('@requester asked you to \"pledge content\" by tomorrow');
          expect(slack.postOnSlack.mock.calls[0][0].channel)
            .toMatch('@performer');
        });
    });

    it('notifies both requester and performer when a pledge has expired', () => {
      const timezoneOffset = new Date().getTimezoneOffset();
      const interval = 10 * 60 * 60 * 1000; // 10 hours
      const adjInterval = interval + timezoneOffset * 60 * 1000;
      MockDate.set(0);
      return request(app).post('/slackCommand')
        .send('user_name=requester')
        .send('text=@performer pledge content by today at 10am')
        .expect(200)
        .then(async () => {
          const nExp = () =>
            slack.postOnSlackMultipleChannels.mock.calls.filter((c) => c[0].text.match(/expired/)).length;
          // just before, no notifications
          MockDate.set(adjInterval - 1);
          await findNewNotifications();
          expect(nExp()).toBe(0);
          // right after, it notifies
          MockDate.set(adjInterval + 1);
          await findNewNotifications();
          expect(nExp()).toBe(1);
          // after some time, does not notify twice
          MockDate.set(adjInterval + 999);
          await findNewNotifications();
          expect(nExp()).toBe(1);
        });
    });

  });

});
<|endoftext|>


<commit_before>module.exports = {
  // base path that will be used to resolve all patterns (eg. files, exclude)
  basePath: '',

  // frameworks to use
  // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
  frameworks: ['requirejs', 'fixture', 'jasmine', 'env'],

  // list of files / patterns to load in the browser
  files: [
    'node_modules/jquery/dist/jquery.js',
    'tests/assets/polyfills.js',
    'tests/bootstrap.js',
    'tests/assets/test.css',
    'tests/assets/fonts.css',
    'build/footwork.css',
    'tests/assets/customMatchers.js',
    'tests/assets/container.js',
    'tests/assets/tools.js',
    'tests/assets/reporter.js',
    { pattern: 'tests/assets/fonts/**/*.*', included: false },
    { pattern: 'tests/spec/**/*.js', included: false },
    { pattern: 'tests/assets/**/*.+(html|json|jsonp|js)', nocache: true, included: false },
    { pattern: 'node_modules/lodash/lodash.js', watched: false, included: false },
    { pattern: 'node_modules/requirejs-text/*.js', watched: false, included: false },
    { pattern: 'node_modules/jquery/dist/*.js', watched: false, included: false },
    { pattern: 'node_modules/html5-history-api/history.js', watched: false, included: true },
    { pattern: 'node_modules/whatwg-fetch/fetch.js', watched: false, included: true },
    { pattern: 'node_modules/babel-polyfill/dist/polyfill.js', watched: false, included: true },
    { pattern: 'node_modules/fetch-mock/es5/client-browserified.js', watched: false, included: false },
    // { pattern: 'bower_components/es5-shim/es5-shim.js', watched: false, included: false },

    { pattern: 'build/*.js', included: false },
    { pattern: 'dist/gh-footwork-logo.png', included: false }
  ],

  // list of files to exclude
  exclude: [
  ],

  // preprocess matching files before serving them to the browser
  // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
  preprocessors: {
    'tests/assets/**/*.html': ['html2js'],
    'tests/assets/**/*.json': ['json_fixtures']
  },

  // used by the fixture framework
  jsonFixturesPreprocessor: {
    variableName: '__json__'
  },

  // test results reporter to use
  // possible values: 'dots', 'progress'
  // available reporters: https://npmjs.org/browse/keyword/karma-reporter
  reporters: ['spec'],

  // web server port
  port: 9876,

  // enable / disable colors in the output (reporters and logs)
  colors: true,

  // level of logging
  // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
  // logLevel: config.LOG_WARN,

  // enable / disable watching file and executing tests whenever any file changes
  autoWatch: true,

  // start these browsers
  // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
  browsers: ['PhantomJS'],

  plugins: [
    'karma-html2js-preprocessor',
    'karma-jasmine',
    'karma-json-fixtures-preprocessor',
    'karma-fixture',
    'karma-phantomjs-launcher',
    'karma-requirejs',
    'karma-spec-reporter',
    'karma-env',
    'karma-coverage'
  ],

  client: {
    env: {
      AJAX_WAIT: 100, // time in ms to tell ajax-based tests to wait for
      JASMINE_TIMEOUT: 20000 // time that jasmine will wait for async requests to complete
    }
  },

  phantomjsLauncher: {
    // Have phantomjs exit if a ResourceError is encountered (useful if karma exits without killing phantom)
    exitOnResourceError: true
  },

  // Continuous Integration mode
  // if true, Karma captures browsers, runs the tests and exits
  singleRun: true,

  // Concurrency level
  // how many browser should be started simultaneous
  concurrency: Infinity
};
<commit_msg>adjusted karma test asset loading sequence<commit_after>module.exports = {
  // base path that will be used to resolve all patterns (eg. files, exclude)
  basePath: '',

  // frameworks to use
  // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
  frameworks: ['requirejs', 'fixture', 'jasmine', 'env'],

  // list of files / patterns to load in the browser
  files: [
    'node_modules/jquery/dist/jquery.js',

    'tests/assets/polyfills.js',
    'tests/assets/customMatchers.js',
    'tests/assets/container.js',
    'tests/assets/tools.js',
    'tests/assets/reporter.js',

    { pattern: 'tests/assets/fonts/**/*.*', included: false },
    { pattern: 'tests/spec/*.js', nocache: true, included: false },
    { pattern: 'tests/assets/**/*.+(html|json|jsonp|js)', nocache: true, included: false },
    { pattern: 'node_modules/lodash/lodash.js', watched: false, included: false },
    { pattern: 'node_modules/requirejs-text/*.js', watched: false, included: false },
    { pattern: 'node_modules/jquery/dist/*.js', watched: false, included: false },
    { pattern: 'node_modules/fetch-mock/es5/client-browserified.js', watched: false, included: false },

    { pattern: 'node_modules/babel-polyfill/dist/polyfill.js', watched: false, included: true },
    { pattern: 'node_modules/whatwg-fetch/fetch.js', watched: false, included: true },

    { pattern: 'build/*.js', included: false },
    { pattern: 'dist/gh-footwork-logo.png', included: false },

    'tests/assets/test.css',
    'tests/assets/fonts.css',
    'build/footwork.css',

    'tests/bootstrap.js'
  ],

  // list of files to exclude
  exclude: [
  ],

  // preprocess matching files before serving them to the browser
  // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
  preprocessors: {
    'tests/assets/**/*.html': ['html2js'],
    'tests/assets/**/*.json': ['json_fixtures']
  },

  // used by the fixture framework
  jsonFixturesPreprocessor: {
    variableName: '__json__'
  },

  // test results reporter to use
  // possible values: 'dots', 'progress'
  // available reporters: https://npmjs.org/browse/keyword/karma-reporter
  reporters: ['spec'],

  // web server port
  port: 9876,

  // enable / disable colors in the output (reporters and logs)
  colors: true,

  // level of logging
  // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
  // logLevel: config.LOG_WARN,

  // enable / disable watching file and executing tests whenever any file changes
  autoWatch: true,

  // start these browsers
  // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
  browsers: ['PhantomJS'],

  plugins: [
    'karma-html2js-preprocessor',
    'karma-jasmine',
    'karma-json-fixtures-preprocessor',
    'karma-fixture',
    'karma-phantomjs-launcher',
    'karma-requirejs',
    'karma-spec-reporter',
    'karma-env',
    'karma-coverage'
  ],

  client: {
    env: {
      AJAX_WAIT: 100, // time in ms to tell ajax-based tests to wait for
      JASMINE_TIMEOUT: 20000 // time that jasmine will wait for async requests to complete
    }
  },

  phantomjsLauncher: {
    // Have phantomjs exit if a ResourceError is encountered (useful if karma exits without killing phantom)
    exitOnResourceError: true
  },

  // Continuous Integration mode
  // if true, Karma captures browsers, runs the tests and exits
  singleRun: true,

  // Concurrency level
  // how many browser should be started simultaneous
  concurrency: Infinity
};
<|endoftext|>


<commit_before>/* jshint jasmine: true */
/* global Applait */
describe("Applait.Finder.prototype.splitname method", function () {

    var finder = new Applait.Finder();
    var splitname = finder.splitname("/sdcard/DCIM/100MZLLA/1.jpg");

    it("it should have the basename of the file with extension ", function (){
        expect(splitname.name).toBe("1.jpg");
    });

    it("it should have path to the file's directory", function (){
        expect(splitname.path).toBe("/sdcard/DCIM/100MZLLA");
    });
});

describe("Applait.Finder.prototype.checkhidden method", function() {

    describe("when this.hidden is true", function () {

        var finder = new Applait.Finder({ hidden: true });

        it("should return true when file path has hidden elements.", function (){
            expect(finder.checkhidden("/sdcard/DCIM/100MZLLA/.1.jpg")).toBe(true);
            expect(finder.checkhidden("/sdcard/DCIM/.100MZLLA/.1.jpg")).toBe(true);
            expect(finder.checkhidden("/sdcard/DCIM/.100MZLLA/1.jpg")).toBe(true);
        });

        it("should return true when file path does not have hidden elements.", function (){
            expect(finder.checkhidden("/sdcard/DCIM/100MZLLA/1.jpg")).toBe(true);
        });

    });

    describe("when this.hidden is false", function () {

        var finder = new Applait.Finder({ hidden: false });

        it("should return true when file path does not have hidden elements.", function (){
            expect(finder.checkhidden("/sdcard/DCIM/100MZLLA/1.jpg")).toBe(true);
        });

        it("should return false when file path has hidden elements.", function (){
            expect(finder.checkhidden("/sdcard/DCIM/100MZLLA/.1.jpg")).toBe(false);
            expect(finder.checkhidden("/sdcard/DCIM/.100MZLLA/.1.jpg")).toBe(false);
            expect(finder.checkhidden("/sdcard/DCIM/.100MZLLA/1.jpg")).toBe(false);
        });

    });

});

describe("Applait.Finder.prototype.log method", function () {

    var finder;

    beforeEach(function () {
        finder = new Applait.Finder();
    });

    describe("log method takes two argument", function () {

        it("finder.log.length should return 2", function (){
            expect(finder.log.length).toBe(2);
        });

    });

    describe("this.debugmode is true", function () {

        beforeEach(function () {
            finder.debugmode = true;
            spyOn(console, 'log');
            finder.log("number", [1,2,3]);
        });

        it("console.log should have been called", function (){
            expect(console.log).toHaveBeenCalled();
        });

        it("console.log should print both argument", function (){
            expect(console.log).toHaveBeenCalledWith("number", [1,2,3]);
        });

    });

    describe("this.debugmode is false", function () {

        beforeEach(function () {
            finder.debugmode = false;
            spyOn(console, 'log');
            finder.log("number", [3,4,5]);
        });

        it("console.log should not called", function (){
            expect(console.log).not.toHaveBeenCalled();
        });

        it("console.log should not print any argument", function (){
            expect(console.log).not.toHaveBeenCalledWith("number", [3,4,5]);
        });

    });

});

describe("Applait.Finder.prototype.matchname method", function () {

    describe("searchkey matches and this.checkhidden() is true/false", function () {

        var finder = new Applait.Finder();
        finder.searchkey = "Aa";
        finder.casesensitive = true;

        it("should return true if this.checkhidden() is true", function (){
            finder.checkhidden = function () {
                return true;
            };
            var matchname = finder.matchname("Aa.jpg", "/sdcard/DCIM/100MZLLA/Aa.jpg");

            expect(matchname).toBe(true);
        });

        it("should retun false if this.checkhidden() is false", function (){
            finder.checkhidden = function () {
                return false;
            };
            var matchname = finder.matchname(".Aa.jpg", "/sdcard/DCIM/100MZLLA/.Aa.jpg");

            expect(matchname).toBe(false);
        });

    });

    describe("this.casesensitive is true/false", function () {

        var finder = new Applait.Finder();
        finder.searchkey = "fb";
        finder.checkhidden = function () {
            return true;
        };

        it("should return false if this.casesensitive is true", function (){
            finder.casesensitive = true;
            var matchname = finder.matchname("FB.jpg", "/sdcard/DCIM/100MZLLA/FB.jpg");

            expect(matchname).toBe(false);
        });

        it("should retun true if this.casesensitive is false", function (){
            finder.casesensitive = false;
            var matchname = finder.matchname("FB.jpg", "/sdcard/DCIM/100MZLLA/FB.jpg");

            expect(matchname).toBe(true);
        });

    });

});

describe("Applait.Finder.prototype.storagecount method", function () {

    var finder = new Applait.Finder();

    it("should return exact number of current device storages", function () {
        // Try with 2 dummy elements as storages
        finder.storages = ["sdcard", "sdcard1"];
        expect(finder.storagecount()).toBe(2);

        // If `this,storages` is empty, it should be 0
        finder.storages = [];
        expect(finder.storagecount()).toBe(0);

    });

    it("should return 0 if navigator.getDeviceStorages is not available", function () {
        finder.storages = undefined;
        expect(finder.storagecount()).toBe(0);
    });
});
<commit_msg>Fix linting issues in tests<commit_after>/* jshint jasmine: true */
/* global Applait */
describe("Applait.Finder.prototype.splitname method", function () {

    var finder = new Applait.Finder();
    var splitname = finder.splitname("/sdcard/DCIM/100MZLLA/1.jpg");

    it("it should have the basename of the file with extension ", function (){
        expect(splitname.name).toBe("1.jpg");
    });

    it("it should have path to the file's directory", function (){
        expect(splitname.path).toBe("/sdcard/DCIM/100MZLLA");
    });
});

describe("Applait.Finder.prototype.checkhidden method", function() {

    describe("when this.hidden is true", function () {

        var finder = new Applait.Finder({ hidden: true });

        it("should return true when file path has hidden elements.", function (){
            expect(finder.checkhidden("/sdcard/DCIM/100MZLLA/.1.jpg")).toBe(true);
            expect(finder.checkhidden("/sdcard/DCIM/.100MZLLA/.1.jpg")).toBe(true);
            expect(finder.checkhidden("/sdcard/DCIM/.100MZLLA/1.jpg")).toBe(true);
        });

        it("should return true when file path does not have hidden elements.", function (){
            expect(finder.checkhidden("/sdcard/DCIM/100MZLLA/1.jpg")).toBe(true);
        });

    });

    describe("when this.hidden is false", function () {

        var finder = new Applait.Finder({ hidden: false });

        it("should return true when file path does not have hidden elements.", function (){
            expect(finder.checkhidden("/sdcard/DCIM/100MZLLA/1.jpg")).toBe(true);
        });

        it("should return false when file path has hidden elements.", function (){
            expect(finder.checkhidden("/sdcard/DCIM/100MZLLA/.1.jpg")).toBe(false);
            expect(finder.checkhidden("/sdcard/DCIM/.100MZLLA/.1.jpg")).toBe(false);
            expect(finder.checkhidden("/sdcard/DCIM/.100MZLLA/1.jpg")).toBe(false);
        });

    });

});

describe("Applait.Finder.prototype.log method", function () {

    var finder;

    beforeEach(function () {
        finder = new Applait.Finder();
    });

    describe("log method takes two argument", function () {

        it("finder.log.length should return 2", function (){
            expect(finder.log.length).toBe(2);
        });

    });

    describe("this.debugmode is true", function () {

        beforeEach(function () {
            finder.debugmode = true;
            spyOn(console, "log");
            finder.log("number", [1,2,3]);
        });

        it("console.log should have been called", function (){
            expect(console.log).toHaveBeenCalled();
        });

        it("console.log should print both argument", function (){
            expect(console.log).toHaveBeenCalledWith("number", [1,2,3]);
        });

    });

    describe("this.debugmode is false", function () {

        beforeEach(function () {
            finder.debugmode = false;
            spyOn(console, "log");
            finder.log("number", [3,4,5]);
        });

        it("console.log should not called", function (){
            expect(console.log).not.toHaveBeenCalled();
        });

        it("console.log should not print any argument", function (){
            expect(console.log).not.toHaveBeenCalledWith("number", [3,4,5]);
        });

    });

});

describe("Applait.Finder.prototype.matchname method", function () {

    describe("searchkey matches and this.checkhidden() is true/false", function () {

        var finder = new Applait.Finder();
        finder.searchkey = "Aa";
        finder.casesensitive = true;

        it("should return true if this.checkhidden() is true", function (){
            finder.checkhidden = function () {
                return true;
            };
            var matchname = finder.matchname("Aa.jpg", "/sdcard/DCIM/100MZLLA/Aa.jpg");

            expect(matchname).toBe(true);
        });

        it("should retun false if this.checkhidden() is false", function (){
            finder.checkhidden = function () {
                return false;
            };
            var matchname = finder.matchname(".Aa.jpg", "/sdcard/DCIM/100MZLLA/.Aa.jpg");

            expect(matchname).toBe(false);
        });

    });

    describe("this.casesensitive is true/false", function () {

        var finder = new Applait.Finder();
        finder.searchkey = "fb";
        finder.checkhidden = function () {
            return true;
        };

        it("should return false if this.casesensitive is true", function (){
            finder.casesensitive = true;
            var matchname = finder.matchname("FB.jpg", "/sdcard/DCIM/100MZLLA/FB.jpg");

            expect(matchname).toBe(false);
        });

        it("should retun true if this.casesensitive is false", function (){
            finder.casesensitive = false;
            var matchname = finder.matchname("FB.jpg", "/sdcard/DCIM/100MZLLA/FB.jpg");

            expect(matchname).toBe(true);
        });

    });

});

describe("Applait.Finder.prototype.storagecount method", function () {

    var finder = new Applait.Finder();

    it("should return exact number of current device storages", function () {
        // Try with 2 dummy elements as storages
        finder.storages = ["sdcard", "sdcard1"];
        expect(finder.storagecount()).toBe(2);

        // If `this,storages` is empty, it should be 0
        finder.storages = [];
        expect(finder.storagecount()).toBe(0);

    });

    it("should return 0 if navigator.getDeviceStorages is not available", function () {
        finder.storages = undefined;
        expect(finder.storagecount()).toBe(0);
    });
});
<|endoftext|>


<commit_before>const server = 'ws://127.0.0.1:3000';
const badServer = 'ws://127.0.0.1:777';

function promise(resolver=()=>{}) {
  let resolve;
  let reject;
  const promise = new Promise((res, rej)=>resolver(resolve = res, reject = rej));
  promise.resolve = resolve;
  promise.reject = reject;
  return promise;
}

describe('JS-Nexus', function() {
  setSpecHelper(NexusSpecHelpers);
  manageWebSockets();
  catchMissedEvents();

  describe('user:', function() {
    let user;
    beforeEach(async function(){
      user = await Nexus(server);
    });

    describe('getHosts()', function() {
      it('only returns active hosts', async function() {
        const host1 = await Nexus(server).host('Pac-Man');
        const host2 = await Nexus(server).host('Donkey Kong');

        let list = await user.getHosts();
        this.expectHostToBeListed(host1, list);
        this.expectHostToBeListed(host2, list);

        await host1.close();
        list = await user.getHosts();
        this.expectHostNotToBeListed(host1, list);
        this.expectHostToBeListed(host2, list);

        await host2.close();
        list = await user.getHosts();
        this.expectHostNotToBeListed(host1, list);
        this.expectHostNotToBeListed(host2, list);
      });
    });

    when('the server is down', function() {
      it('triggers an else', async function() {
        let caught = promise();
        let user = Nexus(badServer).else(caught.resolve);
        await caught;
        expect(user.type).toBe('User');
      });

      it('triggers a .else even if they tried to .join', async function() {
        let caught = promise();

        let user = Nexus(badServer)
          .else(() => caught.resolve())
          .join('The Game');
        await caught;

        expect(user.type).toBe('Dead');
      });

      it('triggers a .else even if they tried to .host', async function() {
        let caught = promise();

        let user = Nexus(badServer)
          .else(() => caught.resolve())
          .host('The Game');
        await caught;

        expect(user.type).toBe('Dead');
      });
    });
  });

  describe('client:', function() {
    let client;
    beforeEach(async function(){
      client = await timebox(Nexus(server));
    });

    it('can connect to a host by name', async function() {
      const name = 'Frogger';
      const host = await timebox(Nexus(server).host(name));

      const onNewClient = host.onNewClient.then((id, request) => {
        expect(id).toBe(1);
        expect(request).toEqual({
          type: 'CONNECT',
          hostName: name,
        });
      });
      await Promise.all([
        client.join(name),
        onNewClient,
      ]);
    });

    it('can connect to a host by id', async function() {
      const host = await timebox(Nexus(server).host("Asteroids"));

      const onNewClient = host.onNewClient.then((id, request) => {
        expect(id).toBe(1);
        expect(request).toEqual({
          type: 'CONNECT',
          hostID: host.id,
        });
      });
      await Promise.all([
        client.join(host.id),
        onNewClient,
      ]);
    });

    when('connected to a host', function() {
      beforeEach(async function() {
        this.host = await Nexus(server).host('Space Invaders');

        client.join(this.host.id);
        await this.host.onNewClient;
        await client.joined;
      });

      it('can send messages to the host', async function() {
        const msg = "Hello there!";
        client.send(msg);

        await this.host.onMessage.then((message, id) => {
          expect(message).toBe(msg);
          expect(id).toBe(1);
        });
      });

      it('can receive messages from the host', async function() {
        const msg = "General Kenobi";
        this.host.send(msg);

        const message = await client.onMessage;
        expect(message).toBe(msg);
      });
    });

    when('attempting to connect to a non-existent host', function() {
      it('triggers a .else', async function() {
        let caught = promise();

        client
          .join({ hostID: -18237867 })
          .else(caught.resolve);

        await caught;

        expect(client.type).toBe('User');
      });

      it('can become a host itself', async function() {
        client.joinOrHost('Defender');
        await client.whenHosting;
        expect(client.type).toBe('Host');

        const user2 = Nexus(server).joinOrHost('Defender');
        await user2.whenJoined;
        expect(user2.type).toBe('Client');
      });
    });
  });

  describe('host:', function() {
    let host;

    beforeEach(async function() {
      host = await Nexus(server).host('Tron');
    });

    when('it has clients', function() {
      let client1;
      let client2;
      let client3;

      beforeEach(async function() {
        client1 = await Nexus(server).join(host.id);
        client2 = await Nexus(server).join(host.id);
        client3 = await Nexus(server).join(host.id);
      });

      it('does not let a message from one client leak to others', async function() {
        let msg1=null;
        let msg2=null;
        let msg3=null;

        client1.onMessage(m => msg1=m);
        client2.onMessage(m => msg2=m);
        client3.onMessage(m => msg3=m);

        function verifySecret(msg, id) {
          expect(msg).toEqual('secret');
          expect(id).toEqual(2);
        }

        client2.send('secret');
        await host.onMessage.then(verifySecret);

        client2.send('another secret');
        const msg = await host.onMessage;
        expect(msg).toBe('another secret');

        expect(msg1).toBe(null);
        expect(msg2).toBe(null);
        expect(msg3).toBe(null);
      });

      it('can message exactly one of them at a time', async function() {
        let msg1=null;
        let msg2=null;
        let msg3=null;

        client1.onMessage(m => msg1=m);
        client2.onMessage(m => msg2=m);
        client3.onMessage(m => msg3=m);

        host.send('one', 1);

        await client1.onMessage;
        expect(msg1).toEqual('one');
        expect(msg2).not.toExist();
        expect(msg3).not.toExist();

        host.send('two', 2);

        await client2.onMessage;
        expect(msg1).toEqual('one');
        expect(msg2).toEqual('two');
        expect(msg3).not.toExist();

        host.send('three', 3);

        await client3.onMessage;
        expect(msg1).toEqual('one');
        expect(msg2).toEqual('two');
        expect(msg3).toEqual('three');
      });

      it('can message multiple clients', async function() {
        let msg1=null;
        let msg2=null;
        let msg3=null;

        client1.onMessage(m => msg1=m);
        client2.onMessage(m => msg2=m);
        client3.onMessage(m => msg3=m);

        const msgOneTwo = 'one and two';
        const msgTwoThree = 'two and three';

        host.send(msgOneTwo, [1, 2]);
        await Promise.all([
          client1.onMessage,
          client2.onMessage,
        ]);

        expect(msg1).toBe(msgOneTwo);
        expect(msg2).toBe(msgOneTwo);
        expect(msg3).toBe(null);

        host.send(msgTwoThree, [2, 3]);
        await Promise.all([
          client2.onMessage,
          client3.onMessage,
        ]);

        expect(msg1).toBe(msgOneTwo);
        expect(msg2).toBe(msgTwoThree);
        expect(msg3).toBe(msgTwoThree);
      });

      it('can message all clients', async function() {
        const msg = 'all';

        host.send(msg);
        await Promise.all([
          client1.onMessage,
          client2.onMessage,
          client3.onMessage,
        ]).then(([msg1, msg2, msg3]) => {
          expect(msg1).toBe(msg);
          expect(msg2).toBe(msg);
          expect(msg3).toBe(msg);
        });
      });

      it('gets notified when a client disconnects', async function() {
        let id;

        client1.close();
        id = await host.onLostClient;
        expect(id).toEqual(1);

        client2.close();
        id = await host.onLostClient;
        expect(id).toEqual(2);
      });

      it('disconnects all clients when it closes (and handle clients that are already closed or closing)', async function() {
        await client1.close(); // close 1 early
        host.close();
        const onClose2 = client2.close(); // close 2 at the same time as host
        const onClose3 = client3.onClose; // listen for 3 to close

        await onClose2;
        await onClose3.then((code, reason) => {
          expect(code).toEqual(1001);
          expect(reason).toEqual('Host was closed');
        });
      });
    });
  });

  describe('unhandled awaitableEvents:', function() {
    when('we connect to the server', function() {
      it('shows a warning', async function() {
        const user = Nexus(server);
        const [event] = await this.warningSpy('whenServerConnected');
        expect(event.type).toEqual('open');
      });
    });

    when('we fail to connect to the server', function() {
      it('shows a warning', async function() {
        const user = Nexus(badServer);
        const [error] = await this.warningSpy('whenServerConnected.onError');
        expect(error.message).toEqual('Server connection failed');
      });
    });

    when('we begin hosting', function() {
      it('shows a warning', async function() {
        const user = Nexus(server).host('Galaxian');
        const [hostType] = await this.warningSpy('whenHosting');
        expect(hostType.hostID).toExist();
      });
    });

    when('we join', function() {
      it('shows a warning', async function() {
        await Nexus(server).host('Galaxian');
        Nexus(server).join('Galaxian');

        const [hostType] = await this.warningSpy('whenJoined');
        expect(hostType.id).toExist();
      });
    });
  });
});
<commit_msg>Ensure warning when uncaught event: whenJoined.onError<commit_after>const server = 'ws://127.0.0.1:3000';
const badServer = 'ws://127.0.0.1:777';

function promise(resolver=()=>{}) {
  let resolve;
  let reject;
  const promise = new Promise((res, rej)=>resolver(resolve = res, reject = rej));
  promise.resolve = resolve;
  promise.reject = reject;
  return promise;
}

describe('JS-Nexus', function() {
  setSpecHelper(NexusSpecHelpers);
  manageWebSockets();
  catchMissedEvents();

  describe('user:', function() {
    let user;
    beforeEach(async function(){
      user = await Nexus(server);
    });

    describe('getHosts()', function() {
      it('only returns active hosts', async function() {
        const host1 = await Nexus(server).host('Pac-Man');
        const host2 = await Nexus(server).host('Donkey Kong');

        let list = await user.getHosts();
        this.expectHostToBeListed(host1, list);
        this.expectHostToBeListed(host2, list);

        await host1.close();
        list = await user.getHosts();
        this.expectHostNotToBeListed(host1, list);
        this.expectHostToBeListed(host2, list);

        await host2.close();
        list = await user.getHosts();
        this.expectHostNotToBeListed(host1, list);
        this.expectHostNotToBeListed(host2, list);
      });
    });

    when('the server is down', function() {
      it('triggers an else', async function() {
        let caught = promise();
        let user = Nexus(badServer).else(caught.resolve);
        await caught;
        expect(user.type).toBe('User');
      });

      it('triggers a .else even if they tried to .join', async function() {
        let caught = promise();

        let user = Nexus(badServer)
          .else(() => caught.resolve())
          .join('The Game');
        await caught;

        expect(user.type).toBe('Dead');
      });

      it('triggers a .else even if they tried to .host', async function() {
        let caught = promise();

        let user = Nexus(badServer)
          .else(() => caught.resolve())
          .host('The Game');
        await caught;

        expect(user.type).toBe('Dead');
      });
    });
  });

  describe('client:', function() {
    let client;
    beforeEach(async function(){
      client = await timebox(Nexus(server));
    });

    it('can connect to a host by name', async function() {
      const name = 'Frogger';
      const host = await timebox(Nexus(server).host(name));

      const onNewClient = host.onNewClient.then((id, request) => {
        expect(id).toBe(1);
        expect(request).toEqual({
          type: 'CONNECT',
          hostName: name,
        });
      });
      await Promise.all([
        client.join(name),
        onNewClient,
      ]);
    });

    it('can connect to a host by id', async function() {
      const host = await timebox(Nexus(server).host("Asteroids"));

      const onNewClient = host.onNewClient.then((id, request) => {
        expect(id).toBe(1);
        expect(request).toEqual({
          type: 'CONNECT',
          hostID: host.id,
        });
      });
      await Promise.all([
        client.join(host.id),
        onNewClient,
      ]);
    });

    when('connected to a host', function() {
      beforeEach(async function() {
        this.host = await Nexus(server).host('Space Invaders');

        client.join(this.host.id);
        await this.host.onNewClient;
        await client.joined;
      });

      it('can send messages to the host', async function() {
        const msg = "Hello there!";
        client.send(msg);

        await this.host.onMessage.then((message, id) => {
          expect(message).toBe(msg);
          expect(id).toBe(1);
        });
      });

      it('can receive messages from the host', async function() {
        const msg = "General Kenobi";
        this.host.send(msg);

        const message = await client.onMessage;
        expect(message).toBe(msg);
      });
    });

    when('attempting to connect to a non-existent host', function() {
      it('triggers a .else', async function() {
        let caught = promise();

        client
          .join({ hostID: -18237867 })
          .else(caught.resolve);

        await caught;

        expect(client.type).toBe('User');
      });

      it('can become a host itself', async function() {
        client.joinOrHost('Defender');
        await client.whenHosting;
        expect(client.type).toBe('Host');

        const user2 = Nexus(server).joinOrHost('Defender');
        await user2.whenJoined;
        expect(user2.type).toBe('Client');
      });
    });
  });

  describe('host:', function() {
    let host;

    beforeEach(async function() {
      host = await Nexus(server).host('Tron');
    });

    when('it has clients', function() {
      let client1;
      let client2;
      let client3;

      beforeEach(async function() {
        client1 = await Nexus(server).join(host.id);
        client2 = await Nexus(server).join(host.id);
        client3 = await Nexus(server).join(host.id);
      });

      it('does not let a message from one client leak to others', async function() {
        let msg1=null;
        let msg2=null;
        let msg3=null;

        client1.onMessage(m => msg1=m);
        client2.onMessage(m => msg2=m);
        client3.onMessage(m => msg3=m);

        function verifySecret(msg, id) {
          expect(msg).toEqual('secret');
          expect(id).toEqual(2);
        }

        client2.send('secret');
        await host.onMessage.then(verifySecret);

        client2.send('another secret');
        const msg = await host.onMessage;
        expect(msg).toBe('another secret');

        expect(msg1).toBe(null);
        expect(msg2).toBe(null);
        expect(msg3).toBe(null);
      });

      it('can message exactly one of them at a time', async function() {
        let msg1=null;
        let msg2=null;
        let msg3=null;

        client1.onMessage(m => msg1=m);
        client2.onMessage(m => msg2=m);
        client3.onMessage(m => msg3=m);

        host.send('one', 1);

        await client1.onMessage;
        expect(msg1).toEqual('one');
        expect(msg2).not.toExist();
        expect(msg3).not.toExist();

        host.send('two', 2);

        await client2.onMessage;
        expect(msg1).toEqual('one');
        expect(msg2).toEqual('two');
        expect(msg3).not.toExist();

        host.send('three', 3);

        await client3.onMessage;
        expect(msg1).toEqual('one');
        expect(msg2).toEqual('two');
        expect(msg3).toEqual('three');
      });

      it('can message multiple clients', async function() {
        let msg1=null;
        let msg2=null;
        let msg3=null;

        client1.onMessage(m => msg1=m);
        client2.onMessage(m => msg2=m);
        client3.onMessage(m => msg3=m);

        const msgOneTwo = 'one and two';
        const msgTwoThree = 'two and three';

        host.send(msgOneTwo, [1, 2]);
        await Promise.all([
          client1.onMessage,
          client2.onMessage,
        ]);

        expect(msg1).toBe(msgOneTwo);
        expect(msg2).toBe(msgOneTwo);
        expect(msg3).toBe(null);

        host.send(msgTwoThree, [2, 3]);
        await Promise.all([
          client2.onMessage,
          client3.onMessage,
        ]);

        expect(msg1).toBe(msgOneTwo);
        expect(msg2).toBe(msgTwoThree);
        expect(msg3).toBe(msgTwoThree);
      });

      it('can message all clients', async function() {
        const msg = 'all';

        host.send(msg);
        await Promise.all([
          client1.onMessage,
          client2.onMessage,
          client3.onMessage,
        ]).then(([msg1, msg2, msg3]) => {
          expect(msg1).toBe(msg);
          expect(msg2).toBe(msg);
          expect(msg3).toBe(msg);
        });
      });

      it('gets notified when a client disconnects', async function() {
        let id;

        client1.close();
        id = await host.onLostClient;
        expect(id).toEqual(1);

        client2.close();
        id = await host.onLostClient;
        expect(id).toEqual(2);
      });

      it('disconnects all clients when it closes (and handle clients that are already closed or closing)', async function() {
        await client1.close(); // close 1 early
        host.close();
        const onClose2 = client2.close(); // close 2 at the same time as host
        const onClose3 = client3.onClose; // listen for 3 to close

        await onClose2;
        await onClose3.then((code, reason) => {
          expect(code).toEqual(1001);
          expect(reason).toEqual('Host was closed');
        });
      });
    });
  });

  describe('unhandled awaitableEvents:', function() {
    when('we connect to the server', function() {
      it('shows a warning', async function() {
        const user = Nexus(server);
        const [event] = await this.warningSpy('whenServerConnected');
        expect(event.type).toEqual('open');
      });
    });

    when('we fail to connect to the server', function() {
      it('shows a warning', async function() {
        const user = Nexus(badServer);
        const [error] = await this.warningSpy('whenServerConnected.onError');
        expect(error.message).toEqual('Server connection failed');
      });
    });

    when('we begin hosting', function() {
      it('shows a warning', async function() {
        const user = Nexus(server).host('Galaxian');
        const [hostType] = await this.warningSpy('whenHosting');
        expect(hostType.hostID).toExist();
      });
    });

    when('we join', function() {
      it('shows a warning', async function() {
        await Nexus(server).host('Galaxian');
        Nexus(server).join('Galaxian');

        const [hostType] = await this.warningSpy('whenJoined');
        expect(hostType.id).toExist();
      });
    });

    when('we fail to join', function() {
      it('shows a warning', async function() {
        Nexus(server).join('Galaxian');

        const [error] = await this.warningSpy('whenJoined.onError');
        expect(error.message).toBe('Cannot connect to host');
      });
    });
  });
});
<|endoftext|>


<commit_before>const eventbriteCheckinsOnline = require('../src/index.js');
eventbriteCheckinsOnline.getAttendeesForEvent('<EVENTBRITE TOKEN>', '<EVENT ID>')
                                    .then(data => {
                                      console.log(data);

                                    });
<commit_msg>style(tests): Resolving a linting issue flagged by bithound<commit_after>const eventbriteCheckinsOnline = require('../src/index.js');
eventbriteCheckinsOnline.getAttendeesForEvent('<EVENTBRITE TOKEN>', '<EVENT ID>')
                                    .then(data => {
                                      console.log(data);
                                    });
<|endoftext|>


<commit_before>/*
	This function automatically handles all the client side events on custom
	list boxes. If onChange event occurs on a list then this function empties
	all the succeeding list boxes & automatically populates the immediate next
	list with appropriate data.
*/
function onCustomListBoxChange(element)
{
	//Get the element identifier
	var elementId = element.id;

	//Get the position of first occurrence of underscore
	var firstIndex = elementId.indexOf("_");

	//Get the position of last occurrence of underscore
	var lastIndex = elementId.lastIndexOf("_");

	//Retrieve the row number on which the list box is placed
	var rowNo = elementId.substring(firstIndex+1,lastIndex);

	//Retrieve the serial number of the list box
	var serialNo = elementId.substring(lastIndex+1);

	//Retrieve the list box name till the last underscore
	var customListBoxName = elementId.substring(0,lastIndex+1);

	//This loop automatically empties the succeeding list boxes
	for(var i=parseInt(serialNo)+1;;i++)
	{
		//Generating handle for each list
		var handleToListBox = document.getElementById(customListBoxName + i);

		if(handleToListBox == null)
		{
			break;
		}
		else
		{
			handleToListBox.options.length = 0;
			handleToListBox.options[0] = new Option('---','-1');
		}
	}

	//Temporary variable to hold array or hashtable instance
	var dataTable = outerMostDataTable.get(rowNo);

	if(dataTable != null)
	{
		//This loop retrieves the data from hashtable for immediate next list to be populated
		for(var i=0;i<=parseInt(serialNo);i++)
		{
			//Handle to preceeding list box
			var handleToListBox = document.getElementById(customListBoxName + i);

			//Value of preceeding list box
			var listBoxValue = handleToListBox.options[handleToListBox.selectedIndex].value;

			dataTable = dataTable.get(listBoxValue);
		}
	}

	//Populate the immediate next list box with appropriate data
	if(dataTable != null)
	{
		var handleToListBox = document.getElementById(customListBoxName + (parseInt(serialNo)+1));

		if(dataTable instanceof Array)
		{
			for(var i=0;i<dataTable.length;i++)
			{
				handleToListBox.options[i+1] = new Option(dataTable[i],dataTable[i]);
			}
		}
		else
		{
			var keys = dataTable.keys();
            var  j=0;
			for(var i=0;i<keys.length;i++)
			{
			  	var temp =  parseInt(keys[i]);  // Added by Santosh to cut down non-numeric values

				if(temp.toString() != "NaN")
				{

				  handleToListBox.options[j+1] = new Option(keys[i],keys[i]);
				  j++;
				}

			}

		}
	}
}

function onCustomListBoxChangeInAliquot(element,action)
{
   //Get the element identifier
	var elementId = element.id;

	//Get the position of first occurrence of underscore
	var firstIndex = elementId.indexOf("_");

	//Get the position of last occurrence of underscore
	var lastIndex = elementId.lastIndexOf("_");

	//Retrieve the row number on which the list box is placed
	var rowNo = elementId.substring(firstIndex+1,lastIndex);

	//Retrieve the serial number of the list box
	var serialNo = elementId.substring(lastIndex+1);
	//alert("customListBoxName-->" + customListBoxName);
	if(serialNo == 0)
	{

	   	document.forms[0].submittedFor.value = "ForwardTo";
		document.forms[0].action = action+"&rowNo="+rowNo;
	    document.forms[0].submit();

	}
	else
	{
	  onCustomListBoxChange(element);
    }
}<commit_msg>Select first position in the dropdowns and not ---<commit_after>/*
	This function automatically handles all the client side events on custom
	list boxes. If onChange event occurs on a list then this function empties
	all the succeeding list boxes & automatically populates the immediate next
	list with appropriate data.
*/
function onCustomListBoxChange(element)
{
	//Get the element identifier
	var elementId = element.id;

	//Get the position of first occurrence of underscore
	var firstIndex = elementId.indexOf("_");

	//Get the position of last occurrence of underscore
	var lastIndex = elementId.lastIndexOf("_");

	//Retrieve the row number on which the list box is placed
	var rowNo = elementId.substring(firstIndex+1,lastIndex);

	//Retrieve the serial number of the list box
	var serialNo = elementId.substring(lastIndex+1);

	//Retrieve the list box name till the last underscore
	var customListBoxName = elementId.substring(0,lastIndex+1);

	//This loop automatically empties the succeeding list boxes
	for(var i=parseInt(serialNo)+1;;i++)
	{
		//Generating handle for each list
		var handleToListBox = document.getElementById(customListBoxName + i);

		if(handleToListBox == null)
		{
			break;
		}
		else
		{
			handleToListBox.options.length = 0;
			handleToListBox.options[0] = new Option('---','-1');
		}
	}

	//Temporary variable to hold array or hashtable instance
	var dataTable = outerMostDataTable.get(rowNo);

	if(dataTable != null)
	{
		//This loop retrieves the data from hashtable for immediate next list to be populated
		for(var i=0;i<=parseInt(serialNo);i++)
		{
			//Handle to preceeding list box
			var handleToListBox = document.getElementById(customListBoxName + i);

			//Value of preceeding list box
			var listBoxValue = handleToListBox.options[handleToListBox.selectedIndex].value;

			dataTable = dataTable.get(listBoxValue);
		}
	}

	//Populate the immediate next list box with appropriate data
	if(dataTable != null)
	{
		var handleToListBox = document.getElementById(customListBoxName + (parseInt(serialNo)+1));

		if(dataTable instanceof Array)
		{
			for(var i=0;i<dataTable.length;i++)
			{
				handleToListBox.options[i+1] = new Option(dataTable[i],dataTable[i]);
			}
			handleToListBox.value = handleToListBox[1].value; // Added by Santosh to set first available position
		}
		else
		{
			var keys = dataTable.keys();
            var  j=0;
			for(var i=0;i<keys.length;i++)
			{
			  	var temp =  parseInt(keys[i]);  // Added by Santosh to cut down non-numeric values

				if(temp.toString() != "NaN")
				{

				  handleToListBox.options[j+1] = new Option(keys[i],keys[i]);
				  j++;
				}

			}

			if(handleToListBox.value == "-1") // Added by Santosh to set first available position
			{
			  handleToListBox.value = handleToListBox[1].value;
			  onCustomListBoxChange(handleToListBox);
		    }

		}

	}
}

function onCustomListBoxChangeInAliquot(element,action)
{
   //Get the element identifier
	var elementId = element.id;

	//Get the position of first occurrence of underscore
	var firstIndex = elementId.indexOf("_");

	//Get the position of last occurrence of underscore
	var lastIndex = elementId.lastIndexOf("_");

	//Retrieve the row number on which the list box is placed
	var rowNo = elementId.substring(firstIndex+1,lastIndex);

	//Retrieve the serial number of the list box
	var serialNo = elementId.substring(lastIndex+1);
	//alert("customListBoxName-->" + customListBoxName);
	if(serialNo == 0)
	{

	   	document.forms[0].submittedFor.value = "ForwardTo";
		document.forms[0].action = action+"&rowNo="+rowNo;
	    document.forms[0].submit();

	}
	else
	{
	  onCustomListBoxChange(element);
    }
}<|endoftext|>


<commit_before>const create = require("lodash/create")
const { observable } = require("kobs")
const seq = require("reaks/seq")

module.exports = args => ctx => {
  const { renderer, firstPage } = args
  const pages = []
  const pageIndex = observable(0, "navigator/pageIndex")
  const back = () => {
    const index = pageIndex()
    if (index === 0) {
      return
    }
    const page = pages[index]
    if (page.canExit) {
      return page.canExit().then(res => {
        if (res !== true) return
        pages.pop()
        pageIndex(index - 1)
      })
    }
    pages.pop()
    pageIndex(index - 1)
  }
  const next = page => {
    pages.push(page), pageIndex(pageIndex() + 1)
  }
  const subCtx = create(ctx, { back, next })
  pages.push(firstPage(subCtx))

  return seq([
    renderer(create(ctx, { pages, getPageIndex: pageIndex, back })),
    () => {
      document.addEventListener("backbutton", back)
      return () => document.removeEventListener("backbutton", back)
    },
  ])
}
<commit_msg>navigator next() now takes context as 2nd argument<commit_after>const create = require("lodash/create")
const { observable } = require("kobs")
const seq = require("reaks/seq")

module.exports = args => ctx => {
  const { renderer, firstPage } = args
  const pages = []
  const pageIndex = observable(0, "navigator/pageIndex")
  const back = () => {
    const index = pageIndex()
    if (index === 0) {
      return
    }
    const page = pages[index]
    if (page.canExit) {
      return page.canExit().then(res => {
        if (res !== true) return
        pages.pop()
        pageIndex(index - 1)
      })
    }
    pages.pop()
    pageIndex(index - 1)
  }
  const next = (page, ctx) => {
    let ctxPage = page(ctx)
    // TODO: remove backward-compat one day
    if (!ctx) {
      console.warn("deprecated: navigator.next(): ctx should be provided")
      ctxPage = page
    }
    pages.push(ctxPage), pageIndex(pageIndex() + 1)
  }
  const subCtx = create(ctx, { back, next })
  pages.push(firstPage(subCtx))

  return seq([
    renderer(create(ctx, { pages, getPageIndex: pageIndex, back })),
    () => {
      document.addEventListener("backbutton", back)
      return () => document.removeEventListener("backbutton", back)
    },
  ])
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
/*
   Copyright 2016 The Trustees of University of Arizona

   Licensed under the Apache License, Version 2.0 (the "License" );
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

var util = require('util');
var utils = require('./utils.js');
var clientConfig = require('./client_config.js');
var restler = require('restler');
var minimist = require('minimist');
var fs = require('fs');
var async = require('async');
var prompt = require('prompt');
var username = require('username');
var exec = require('child_process').exec;
var execSync = require('child_process').execSync;

function parse_args(args) {
    var options = {
        session_name: "",
        session_key: "",
        ms_url: "",
        user: "",
        volume: "",
        anonymous: false,
        anonymous_gateway: "",
        gateway_config_path: "",
        config_path: "",
    };

    // skip first two args
    // 1: node
    // 2: *.js script
    var argv = minimist(args.slice(2));

    // parse
    options.session_name = argv.session_name || "",
    options.session_key = argv.session_key || "",
    options.ms_url = argv.m || "";
    options.user = argv.u || "";
    options.volume = argv.v || "";
    options.anonymous = argv.a || false;
    options.anonymous_gateway = argv.anonymous_gateway || "";
    options.gateway_config_path = argv.gateway_conf || "";
    options.config_path = argv.c || "./client_config.json";
    return options;
}

function process_prompt(conf, callback) {
    prompt.start();
    var prop = [{
        description: "Enter session name",
        type: "string",
        name: "session_name",
        required: true,
        ask: function() {
            if(conf.session_name == undefined || conf.session_name.length == 0) {
                return true;
            }
            return false;
        }
    },
    {
        description: "Enter session key",
        type: "string",
        name: "session_key",
        required: true,
        ask: function() {
            if(conf.session_key == undefined || conf.session_key.length == 0) {
                return true;
            }
            return false;
        }
    }];

    prompt.get(prop, function(err, result) {
        if(err) {
            callback(err, null);
        }

        if(result.session_name) {
            conf.session_name = result.session_name;
        }

        if(result.session_key) {
            conf.session_key = result.session_key;
        }

        callback(null, conf);
    });
}

function check_config(conf) {
    if(conf.session_name && conf.session_key &&
        conf.ms_url && conf.user && conf.volume && conf.service_hosts && conf.service_hosts.length > 0 && conf.service_port > 0) {
        if(conf.anonymous) {
            if(conf.gateways && conf.gateways.length == 1) {
                return true;
            }
        } else {
            if(conf.gateways && conf.gateways.length > 0 &&
                conf.gateway_cert_paths && conf.gateway_cert_paths.length > 0 &&
                conf.gateways.length == conf.gateway_cert_paths.length &&
                conf.service_hosts.length <= conf.gateways.length) {
                return true;
            }
        }
    }
    return false;
}

function assign_gateways(anonymous, hosts, gateways, certs) {
    var len = hosts.length;
    var assignment = [];
    for(var i=0;i<len;i++) {
        var host = hosts[i];
        var gateway;
        var cert;

        if(anonymous) {
            gateway = gateways[0];
            cert = null;
        } else {
            gateway = gateways[i];
            cert = certs[i];
        }

        assignment.push({
            "host": host,
            "gateway": gateway,
            "cert_path": cert,
        });
    }
    return assignment;
}

function setup_gateway(node_host, node_port, session_name, session_key, ms_url, user, volume, gateway, anonymous, cert_path, callback) {
    // test
    var url = util.format("http://%s:%d/gateway/setup", node_host, node_port);
    var complete_callback = function(result, response) {
        if(result instanceof Error) {
            utils.log_error(util.format("[%s:%d] %s", node_host, node_port, result));
            callback(result, null);
        } else {
            utils.log_info(util.format("[%s:%d] %s", node_host, node_port, JSON.stringify(result)));
            callback(null, node_host);
        }
    };

    var data_object = {
        'session_name': session_name,
        'session_key': session_key,
        'ms_url': ms_url,
        'user': user,
        'volume': volume,
        'gateway': gateway,
        'anonymous': anonymous
    };

    if(anonymous) {
        restler.post(url, {
            multipart: true,
            data: data_object
        }).on('complete', complete_callback);
    } else {
        fs.stat(cert_path, function(err, stat) {
            if(err) {
                utils.log_error("Error occurred - "+ err);
                callback(util.format("Cannot open cert: %s", cert_path), null);
                return;
            }

            data_object["cert"] = restler.file(cert_path, null, stat.size, null, null);

            restler.post(url, {
                multipart: true,
                data: data_object
            }).on('complete', complete_callback);
        });
    }
}

function setup_hadoop_credential(hadoop_user, session_name, session_key, callback) {
    /*
        hadoop credential create \
                    fs.hsyndicate.session.session_name.key \
                    -v session_key \
                    -provider jceks://hdfs/user/iychoi/.syndicate/hsyndicate.jceks
    */
    /*
        hadoop dfs -D hadoop.security.credential.provider.path=jceks://hdfs/user/iychoi/.syndicate/hsyndicate.jceks -ls
    */

    utils.log_info(util.format("setting up a hadoop credential for %s", session_name));

    var provider_path = util.format("jceks://hdfs/user/%s/.syndicate/hsyndicate.jceks", hadoop_user);
    var cmd = util.format("hadoop credential create %s -v %s -provider %s", session_name, session_key, provider_path);
    utils.log_debug(cmd);
    var child = exec(cmd, function(error, stdout, stderr) {
        if (error) {
            callback(error, null);
            return;
        }
        callback(null, stdout);
    });
}

function is_hadoop_available() {
    var cmd = "hadoop version";
    try {
        var stdout = execSync(cmd);
        return true;
    } catch (e) {
        // exitcode is not 0
        return false;
    }
}

(function main() {
    utils.log_info("Setup a gateway");

    var param = parse_args(process.argv);
    var gateways = [];
    if(param.anonymous) {
        gateways.push(param.anonymous_gateway);
    }

    var client_config = clientConfig.get_config(param.config_path, {
        "session_name": param.session_name,
        "session_key": param.session_key,
        "ms_url": param.ms_url,
        "user": param.user,
        "volume": param.volume,
        "anonymous": param.anonymous,
        "gateways": gateways
    });
    if(client_config == null) {
        utils.log_error("cannot read configuration");
        process.exit(1);
    }

    if(param.gateway_config_path) {
        var gateway_config = clientConfig.get_config(param.gateway_config_path);
        client_config = clientConfig.overwrite_config(client_config, gateway_config);
    }

    try {
        async.waterfall([
            function(cb) {
                process_prompt(client_config, function(err, configuration) {
                    if(err) {
                        cb(new Error("arguments are not given properly"), null);
                        return;
                    }

                    if(!check_config(configuration)) {
                        cb(new Error("arguments are not given properly"), null);
                        return;
                    }

                    cb(null, configuration);
                    return;
                });
            },
            function(configuration, cb) {
                var gateway_assignment = assign_gateways(configuration.anonymous, configuration.service_hosts, configuration.gateways, configuration.gateway_cert_paths);
                if(gateway_assignment.length <= 0) {
                    cb(new Error("Failed to assign gateways to hosts"), null);
                    return;
                } else {
                    cb(null, {
                        configuration: configuration,
                        gateway_assignment: gateway_assignment
                    });
                    return;
                }
            },
            function(result, cb) {
                // register gateways
                var calls = {};

                var configuration = result.configuration;
                var gateway_assignment = result.gateway_assignment;

                gateway_assignment.forEach(function(assignment) {
                    calls[assignment.host] = function(callback) {
                        setup_gateway(assignment.host, configuration.service_port, configuration.session_name, configuration.session_key,
                            configuration.ms_url, configuration.user, configuration.volume, assignment.gateway, configuration.anonymous, assignment.cert_path, callback);
                    };
                });

                async.parallel(calls, function(err, results) {
                    if(err) {
                        cb(err, null);
                        return;
                    }

                    utils.log_info(util.format("Setup a gateway of a user (%s) and a volume (%s)", configuration.user, configuration.volume));
                    utils.log_info(util.format("Use a session name (%s) to access", configuration.session_name));

                    if(is_hadoop_available()) {
                        var hadoop_user = username.sync();
                        setup_hadoop_credential(hadoop_user, configuration.session_name, configuration.session_key, function(err, data) {
                            if(err) {
                                utils.log_error(util.format("Could not setup a hadoop credential: %s", err));
                                return;
                            }
                            utils.log_info(util.format("Successfully setup a hadoop credential: %s", configuration.session_name));
                        });
                    } else {
                        utils.log_info("Hadoop is not accessible - ignoring setting up a hadoop credential");
                    }

                    cb(null, results);
                    return;
                });
            }
        ], function(err, data) {
            if(err) {
                utils.log_error(err);
                process.exit(1);
            }
            process.exit(0);
        });
    } catch (e) {
        utils.log_error(util.format("Exception occured: %s", e));
        process.exit(1);
    }
})();
<commit_msg>Match hadoop credential pattern<commit_after>#!/usr/bin/env node
/*
   Copyright 2016 The Trustees of University of Arizona

   Licensed under the Apache License, Version 2.0 (the "License" );
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

var util = require('util');
var utils = require('./utils.js');
var clientConfig = require('./client_config.js');
var restler = require('restler');
var minimist = require('minimist');
var fs = require('fs');
var async = require('async');
var prompt = require('prompt');
var username = require('username');
var exec = require('child_process').exec;
var execSync = require('child_process').execSync;

function parse_args(args) {
    var options = {
        session_name: "",
        session_key: "",
        ms_url: "",
        user: "",
        volume: "",
        anonymous: false,
        anonymous_gateway: "",
        gateway_config_path: "",
        config_path: "",
    };

    // skip first two args
    // 1: node
    // 2: *.js script
    var argv = minimist(args.slice(2));

    // parse
    options.session_name = argv.session_name || "",
    options.session_key = argv.session_key || "",
    options.ms_url = argv.m || "";
    options.user = argv.u || "";
    options.volume = argv.v || "";
    options.anonymous = argv.a || false;
    options.anonymous_gateway = argv.anonymous_gateway || "";
    options.gateway_config_path = argv.gateway_conf || "";
    options.config_path = argv.c || "./client_config.json";
    return options;
}

function process_prompt(conf, callback) {
    prompt.start();
    var prop = [{
        description: "Enter session name",
        type: "string",
        name: "session_name",
        required: true,
        ask: function() {
            if(conf.session_name == undefined || conf.session_name.length == 0) {
                return true;
            }
            return false;
        }
    },
    {
        description: "Enter session key",
        type: "string",
        name: "session_key",
        required: true,
        ask: function() {
            if(conf.session_key == undefined || conf.session_key.length == 0) {
                return true;
            }
            return false;
        }
    }];

    prompt.get(prop, function(err, result) {
        if(err) {
            callback(err, null);
        }

        if(result.session_name) {
            conf.session_name = result.session_name;
        }

        if(result.session_key) {
            conf.session_key = result.session_key;
        }

        callback(null, conf);
    });
}

function check_config(conf) {
    if(conf.session_name && conf.session_key &&
        conf.ms_url && conf.user && conf.volume && conf.service_hosts && conf.service_hosts.length > 0 && conf.service_port > 0) {
        if(conf.anonymous) {
            if(conf.gateways && conf.gateways.length == 1) {
                return true;
            }
        } else {
            if(conf.gateways && conf.gateways.length > 0 &&
                conf.gateway_cert_paths && conf.gateway_cert_paths.length > 0 &&
                conf.gateways.length == conf.gateway_cert_paths.length &&
                conf.service_hosts.length <= conf.gateways.length) {
                return true;
            }
        }
    }
    return false;
}

function assign_gateways(anonymous, hosts, gateways, certs) {
    var len = hosts.length;
    var assignment = [];
    for(var i=0;i<len;i++) {
        var host = hosts[i];
        var gateway;
        var cert;

        if(anonymous) {
            gateway = gateways[0];
            cert = null;
        } else {
            gateway = gateways[i];
            cert = certs[i];
        }

        assignment.push({
            "host": host,
            "gateway": gateway,
            "cert_path": cert,
        });
    }
    return assignment;
}

function setup_gateway(node_host, node_port, session_name, session_key, ms_url, user, volume, gateway, anonymous, cert_path, callback) {
    // test
    var url = util.format("http://%s:%d/gateway/setup", node_host, node_port);
    var complete_callback = function(result, response) {
        if(result instanceof Error) {
            utils.log_error(util.format("[%s:%d] %s", node_host, node_port, result));
            callback(result, null);
        } else {
            utils.log_info(util.format("[%s:%d] %s", node_host, node_port, JSON.stringify(result)));
            callback(null, node_host);
        }
    };

    var data_object = {
        'session_name': session_name,
        'session_key': session_key,
        'ms_url': ms_url,
        'user': user,
        'volume': volume,
        'gateway': gateway,
        'anonymous': anonymous
    };

    if(anonymous) {
        restler.post(url, {
            multipart: true,
            data: data_object
        }).on('complete', complete_callback);
    } else {
        fs.stat(cert_path, function(err, stat) {
            if(err) {
                utils.log_error("Error occurred - "+ err);
                callback(util.format("Cannot open cert: %s", cert_path), null);
                return;
            }

            data_object["cert"] = restler.file(cert_path, null, stat.size, null, null);

            restler.post(url, {
                multipart: true,
                data: data_object
            }).on('complete', complete_callback);
        });
    }
}

function setup_hadoop_credential(hadoop_user, session_name, session_key, callback) {
    /*
        hadoop credential create \
                    fs.hsyndicate.session.session_name.key \
                    -v session_key \
                    -provider jceks://hdfs/user/iychoi/.syndicate/hsyndicate.jceks
    */
    /*
        hadoop dfs -D hadoop.security.credential.provider.path=jceks://hdfs/user/iychoi/.syndicate/hsyndicate.jceks -ls
    */

    utils.log_info(util.format("setting up a hadoop credential for %s", session_name));

    var provider_path = util.format("jceks://hdfs/user/%s/.syndicate/hsyndicate.jceks", hadoop_user);
    var name_pattern = util.format("fs.hsyndicate.session.%s.key", session_name);

    var cmd = util.format("hadoop credential create %s -v %s -provider %s", name_pattern, session_key, provider_path);
    utils.log_debug(cmd);
    var child = exec(cmd, function(error, stdout, stderr) {
        if (error) {
            callback(error, null);
            return;
        }
        callback(null, stdout);
    });
}

function is_hadoop_available() {
    var cmd = "hadoop version";
    try {
        var stdout = execSync(cmd);
        return true;
    } catch (e) {
        // exitcode is not 0
        return false;
    }
}

(function main() {
    utils.log_info("Setup a gateway");

    var param = parse_args(process.argv);
    var gateways = [];
    if(param.anonymous) {
        gateways.push(param.anonymous_gateway);
    }

    var client_config = clientConfig.get_config(param.config_path, {
        "session_name": param.session_name,
        "session_key": param.session_key,
        "ms_url": param.ms_url,
        "user": param.user,
        "volume": param.volume,
        "anonymous": param.anonymous,
        "gateways": gateways
    });
    if(client_config == null) {
        utils.log_error("cannot read configuration");
        process.exit(1);
    }

    if(param.gateway_config_path) {
        var gateway_config = clientConfig.get_config(param.gateway_config_path);
        client_config = clientConfig.overwrite_config(client_config, gateway_config);
    }

    try {
        async.waterfall([
            function(cb) {
                process_prompt(client_config, function(err, configuration) {
                    if(err) {
                        cb(new Error("arguments are not given properly"), null);
                        return;
                    }

                    if(!check_config(configuration)) {
                        cb(new Error("arguments are not given properly"), null);
                        return;
                    }

                    cb(null, configuration);
                    return;
                });
            },
            function(configuration, cb) {
                var gateway_assignment = assign_gateways(configuration.anonymous, configuration.service_hosts, configuration.gateways, configuration.gateway_cert_paths);
                if(gateway_assignment.length <= 0) {
                    cb(new Error("Failed to assign gateways to hosts"), null);
                    return;
                } else {
                    cb(null, {
                        configuration: configuration,
                        gateway_assignment: gateway_assignment
                    });
                    return;
                }
            },
            function(result, cb) {
                // register gateways
                var calls = {};

                var configuration = result.configuration;
                var gateway_assignment = result.gateway_assignment;

                gateway_assignment.forEach(function(assignment) {
                    calls[assignment.host] = function(callback) {
                        setup_gateway(assignment.host, configuration.service_port, configuration.session_name, configuration.session_key,
                            configuration.ms_url, configuration.user, configuration.volume, assignment.gateway, configuration.anonymous, assignment.cert_path, callback);
                    };
                });

                async.parallel(calls, function(err, results) {
                    if(err) {
                        cb(err, null);
                        return;
                    }

                    utils.log_info(util.format("Setup a gateway of a user (%s) and a volume (%s)", configuration.user, configuration.volume));
                    utils.log_info(util.format("Use a session name (%s) to access", configuration.session_name));

                    if(is_hadoop_available()) {
                        var hadoop_user = username.sync();
                        setup_hadoop_credential(hadoop_user, configuration.session_name, configuration.session_key, function(err, data) {
                            if(err) {
                                utils.log_error(util.format("Could not setup a hadoop credential: %s", err));
                                return;
                            }
                            utils.log_info(util.format("Successfully setup a hadoop credential: %s", configuration.session_name));
                        });
                    } else {
                        utils.log_info("Hadoop is not accessible - ignoring setting up a hadoop credential");
                    }

                    cb(null, results);
                    return;
                });
            }
        ], function(err, data) {
            if(err) {
                utils.log_error(err);
                process.exit(1);
            }
            process.exit(0);
        });
    } catch (e) {
        utils.log_error(util.format("Exception occured: %s", e));
        process.exit(1);
    }
})();
<|endoftext|>


<commit_before>import * as utils from 'src/utils';
import {registerBidder} from 'src/adapters/bidderFactory';
import { config } from 'src/config';
const BIDDER_CODE = 'visx';
const ENDPOINT_URL = '//t.visx.net/hb';
const TIME_TO_LIVE = 360;
const DEFAULT_CUR = 'EUR';
const ADAPTER_SYNC_URL = '//t.visx.net/push_sync';
const LOG_ERROR_MESS = {
  noAuid: 'Bid from response has no auid parameter - ',
  noAdm: 'Bid from response has no adm parameter - ',
  noBid: 'Array of bid objects is empty',
  noPlacementCode: 'Can\'t find in requested bids the bid with auid - ',
  emptyUids: 'Uids should not be empty',
  emptySeatbid: 'Seatbid array from response has an empty item',
  emptyResponse: 'Response is empty',
  hasEmptySeatbidArray: 'Response has empty seatbid array',
  hasNoArrayOfBids: 'Seatbid from response has no array of bid objects - '
};
export const spec = {
  code: BIDDER_CODE,
  isBidRequestValid: function(bid) {
    return !!bid.params.uid;
  },
  buildRequests: function(validBidRequests) {
    const auids = [];
    const bidsMap = {};
    const bids = validBidRequests || [];
    const currency =
      config.getConfig(`currency.bidderCurrencyDefault.${BIDDER_CODE}`) ||
      config.getConfig('currency.adServerCurrency') ||
      DEFAULT_CUR;
    let priceType = 'net';
    let reqId;

    bids.forEach(bid => {
      if (bid.params.priceType === 'gross') {
        priceType = 'gross';
      }
      if (!bidsMap[bid.params.uid]) {
        bidsMap[bid.params.uid] = [bid];
        auids.push(bid.params.uid);
      } else {
        bidsMap[bid.params.uid].push(bid);
      }
      reqId = bid.bidderRequestId;
    });

    const payload = {
      u: utils.getTopWindowUrl(),
      pt: priceType,
      auids: auids.join(','),
      test: 1,
      r: reqId,
      cur: currency,
    };

    if (bidderRequest && bidderRequest.gdprConsent) {
      if (bidderRequest.gdprConsent.consentString) {
        payload.gdpr_consent = bidderRequest.gdprConsent.consentString;
      }
      payload.gdpr_applies =
        (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean')
          ? Number(bidderRequest.gdprConsent.gdprApplies) : 1;
    }

    return {
      method: 'GET',
      url: ENDPOINT_URL,
      data: payload,
      bidsMap: bidsMap,
    };
  },
  interpretResponse: function(serverResponse, bidRequest) {
    serverResponse = serverResponse && serverResponse.body;
    const bidResponses = [];
    const bidsMap = bidRequest.bidsMap;
    const priceType = bidRequest.data.pt;
    const currency = bidRequest.data.cur;

    let errorMessage;

    if (!serverResponse) errorMessage = LOG_ERROR_MESS.emptyResponse;
    else if (serverResponse.seatbid && !serverResponse.seatbid.length) {
      errorMessage = LOG_ERROR_MESS.hasEmptySeatbidArray;
    }

    if (!errorMessage && serverResponse.seatbid) {
      serverResponse.seatbid.forEach(respItem => {
        _addBidResponse(_getBidFromResponse(respItem), bidsMap, priceType, currency, bidResponses);
      });
    }
    if (errorMessage) utils.logError(errorMessage);
    return bidResponses;
  },
  getUserSyncs: function(syncOptions, serverResponses, gdprConsent) {
    if (syncOptions.pixelEnabled) {
      var query = [];
      if (gdprConsent) {
        if (gdprConsent.consentString) {
          query.push('gdpr_consent=' + encodeURIComponent(gdprConsent.consentString));
        }
        query.push('gdpr_applies=' + encodeURIComponent(
          (typeof gdprConsent.gdprApplies === 'boolean')
            ? Number(gdprConsent.gdprApplies) : 1));
      }
      return [{
        type: 'image',
        url: ADAPTER_SYNC_URL + (query.length ? '?' + query.join('&') : '')
      }];
    }
  }
};

function _getBidFromResponse(respItem) {
  if (!respItem) {
    utils.logError(LOG_ERROR_MESS.emptySeatbid);
  } else if (!respItem.bid) {
    utils.logError(LOG_ERROR_MESS.hasNoArrayOfBids + JSON.stringify(respItem));
  } else if (!respItem.bid[0]) {
    utils.logError(LOG_ERROR_MESS.noBid);
  }
  return respItem && respItem.bid && respItem.bid[0];
}

function _addBidResponse(serverBid, bidsMap, priceType, currency, bidResponses) {
  if (!serverBid) return;
  let errorMessage;
  if (!serverBid.auid) errorMessage = LOG_ERROR_MESS.noAuid + JSON.stringify(serverBid);
  if (!serverBid.adm) errorMessage = LOG_ERROR_MESS.noAdm + JSON.stringify(serverBid);
  else {
    const awaitingBids = bidsMap[serverBid.auid];
    if (awaitingBids) {
      awaitingBids.forEach(bid => {
        const bidResponse = {
          requestId: bid.bidId,
          cpm: serverBid.price,
          width: serverBid.w,
          height: serverBid.h,
          creativeId: serverBid.auid,
          currency: currency || DEFAULT_CUR,
          netRevenue: priceType !== 'gross',
          ttl: TIME_TO_LIVE,
          ad: serverBid.adm,
          dealId: serverBid.dealid
        };
        bidResponses.push(bidResponse);
      });
    } else {
      errorMessage = LOG_ERROR_MESS.noPlacementCode + serverBid.auid;
    }
  }
  if (errorMessage) {
    utils.logError(errorMessage);
  }
}

registerBidder(spec);
<commit_msg>Add absent argument in buildRequests function definition in VIX.X Bid Adapter<commit_after>import * as utils from 'src/utils';
import {registerBidder} from 'src/adapters/bidderFactory';
import { config } from 'src/config';
const BIDDER_CODE = 'visx';
const ENDPOINT_URL = '//t.visx.net/hb';
const TIME_TO_LIVE = 360;
const DEFAULT_CUR = 'EUR';
const ADAPTER_SYNC_URL = '//t.visx.net/push_sync';
const LOG_ERROR_MESS = {
  noAuid: 'Bid from response has no auid parameter - ',
  noAdm: 'Bid from response has no adm parameter - ',
  noBid: 'Array of bid objects is empty',
  noPlacementCode: 'Can\'t find in requested bids the bid with auid - ',
  emptyUids: 'Uids should not be empty',
  emptySeatbid: 'Seatbid array from response has an empty item',
  emptyResponse: 'Response is empty',
  hasEmptySeatbidArray: 'Response has empty seatbid array',
  hasNoArrayOfBids: 'Seatbid from response has no array of bid objects - '
};
export const spec = {
  code: BIDDER_CODE,
  isBidRequestValid: function(bid) {
    return !!bid.params.uid;
  },
  buildRequests: function(validBidRequests, bidderRequest) {
    const auids = [];
    const bidsMap = {};
    const bids = validBidRequests || [];
    const currency =
      config.getConfig(`currency.bidderCurrencyDefault.${BIDDER_CODE}`) ||
      config.getConfig('currency.adServerCurrency') ||
      DEFAULT_CUR;
    let priceType = 'net';
    let reqId;

    bids.forEach(bid => {
      if (bid.params.priceType === 'gross') {
        priceType = 'gross';
      }
      if (!bidsMap[bid.params.uid]) {
        bidsMap[bid.params.uid] = [bid];
        auids.push(bid.params.uid);
      } else {
        bidsMap[bid.params.uid].push(bid);
      }
      reqId = bid.bidderRequestId;
    });

    const payload = {
      u: utils.getTopWindowUrl(),
      pt: priceType,
      auids: auids.join(','),
      test: 1,
      r: reqId,
      cur: currency,
    };

    if (bidderRequest && bidderRequest.gdprConsent) {
      if (bidderRequest.gdprConsent.consentString) {
        payload.gdpr_consent = bidderRequest.gdprConsent.consentString;
      }
      payload.gdpr_applies =
        (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean')
          ? Number(bidderRequest.gdprConsent.gdprApplies) : 1;
    }

    return {
      method: 'GET',
      url: ENDPOINT_URL,
      data: payload,
      bidsMap: bidsMap,
    };
  },
  interpretResponse: function(serverResponse, bidRequest) {
    serverResponse = serverResponse && serverResponse.body;
    const bidResponses = [];
    const bidsMap = bidRequest.bidsMap;
    const priceType = bidRequest.data.pt;
    const currency = bidRequest.data.cur;

    let errorMessage;

    if (!serverResponse) errorMessage = LOG_ERROR_MESS.emptyResponse;
    else if (serverResponse.seatbid && !serverResponse.seatbid.length) {
      errorMessage = LOG_ERROR_MESS.hasEmptySeatbidArray;
    }

    if (!errorMessage && serverResponse.seatbid) {
      serverResponse.seatbid.forEach(respItem => {
        _addBidResponse(_getBidFromResponse(respItem), bidsMap, priceType, currency, bidResponses);
      });
    }
    if (errorMessage) utils.logError(errorMessage);
    return bidResponses;
  },
  getUserSyncs: function(syncOptions, serverResponses, gdprConsent) {
    if (syncOptions.pixelEnabled) {
      var query = [];
      if (gdprConsent) {
        if (gdprConsent.consentString) {
          query.push('gdpr_consent=' + encodeURIComponent(gdprConsent.consentString));
        }
        query.push('gdpr_applies=' + encodeURIComponent(
          (typeof gdprConsent.gdprApplies === 'boolean')
            ? Number(gdprConsent.gdprApplies) : 1));
      }
      return [{
        type: 'image',
        url: ADAPTER_SYNC_URL + (query.length ? '?' + query.join('&') : '')
      }];
    }
  }
};

function _getBidFromResponse(respItem) {
  if (!respItem) {
    utils.logError(LOG_ERROR_MESS.emptySeatbid);
  } else if (!respItem.bid) {
    utils.logError(LOG_ERROR_MESS.hasNoArrayOfBids + JSON.stringify(respItem));
  } else if (!respItem.bid[0]) {
    utils.logError(LOG_ERROR_MESS.noBid);
  }
  return respItem && respItem.bid && respItem.bid[0];
}

function _addBidResponse(serverBid, bidsMap, priceType, currency, bidResponses) {
  if (!serverBid) return;
  let errorMessage;
  if (!serverBid.auid) errorMessage = LOG_ERROR_MESS.noAuid + JSON.stringify(serverBid);
  if (!serverBid.adm) errorMessage = LOG_ERROR_MESS.noAdm + JSON.stringify(serverBid);
  else {
    const awaitingBids = bidsMap[serverBid.auid];
    if (awaitingBids) {
      awaitingBids.forEach(bid => {
        const bidResponse = {
          requestId: bid.bidId,
          cpm: serverBid.price,
          width: serverBid.w,
          height: serverBid.h,
          creativeId: serverBid.auid,
          currency: currency || DEFAULT_CUR,
          netRevenue: priceType !== 'gross',
          ttl: TIME_TO_LIVE,
          ad: serverBid.adm,
          dealId: serverBid.dealid
        };
        bidResponses.push(bidResponse);
      });
    } else {
      errorMessage = LOG_ERROR_MESS.noPlacementCode + serverBid.auid;
    }
  }
  if (errorMessage) {
    utils.logError(errorMessage);
  }
}

registerBidder(spec);
<|endoftext|>