<commit_before>import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import moment from 'moment';
import { waitForResource } from 'ilios-common';

module('Unit | Model | Offering', function (hooks) {
  setupTest(hooks);

  test('check allInstructors', async function (assert) {
    assert.expect(11);
    const offering = this.owner.lookup('service:store').createRecord('offering');
    const store = this.owner.lookup('service:store');

    let allInstructors = await waitForResource(offering, 'allInstructors');

    assert.strictEqual(allInstructors.length, 0);

    const user1 = store.createRecord('user', { displayName: 'Beta' });
    const user2 = store.createRecord('user', { displayName: 'Alpha' });
    const user3 = store.createRecord('user', { displayName: 'Omega' });
    offering.get('instructors').pushObject(user1);
    const instructorGroup1 = store.createRecord('instructor-group', {
      users: [user2],
    });
    const instructorGroup2 = store.createRecord('instructor-group', {
      users: [user3],
    });
    offering.get('instructorGroups').pushObjects([instructorGroup1, instructorGroup2]);

    allInstructors = await waitForResource(offering, 'allInstructors');

    assert.strictEqual(allInstructors.length, 3);
    assert.ok(allInstructors.includes(user1));
    assert.ok(allInstructors.includes(user2));
    assert.ok(allInstructors.includes(user3));

    const user4 = store.createRecord('user', {
      firstName: 'Larry',
      lastName: 'Lazy',
    });
    const user5 = store.createRecord('user', { displayName: 'Gamma' });
    offering.get('instructors').pushObject(user4);
    const instructorGroup3 = store.createRecord('instructor-group', {
      users: [user5],
    });
    offering.get('instructorGroups').pushObject(instructorGroup3);

    allInstructors = await waitForResource(offering, 'allInstructors');

    assert.strictEqual(allInstructors.length, 5);
    assert.strictEqual(allInstructors[0].fullName, 'Alpha');
    assert.strictEqual(allInstructors[1].fullName, 'Beta');
    assert.strictEqual(allInstructors[2].fullName, 'Gamma');
    assert.strictEqual(allInstructors[3].fullName, 'Larry Lazy');
    assert.strictEqual(allInstructors[4].fullName, 'Omega');
  });

  test('duration', function (assert) {
    const store = this.owner.lookup('service:store');
    const model = store.createRecord('offering', {});
    assert.strictEqual(model.get('durationHours'), 0);
    assert.strictEqual(model.get('durationMinutes'), 0);
    model.set('startDate', moment().toDate());
    model.set('endDate', moment().add(90, 'minutes').toDate());

    assert.strictEqual(model.get('durationHours'), 1);
    assert.strictEqual(model.get('durationMinutes'), 30);

    model.set('startDate', moment().toDate());
    model.set('endDate', moment().add(30, 'minutes').toDate());

    assert.strictEqual(model.get('durationHours'), 0);
    assert.strictEqual(model.get('durationMinutes'), 30);

    model.set('startDate', moment().toDate());
    model.set('endDate', moment().add(60, 'minutes').toDate());

    assert.strictEqual(model.get('durationHours'), 1);
    assert.strictEqual(model.get('durationMinutes'), 0);
  });

  test('check allLearners', async function (assert) {
    assert.expect(11);
    const offering = this.owner.lookup('service:store').createRecord('offering');
    const store = this.owner.lookup('service:store');

    let allLearners = await waitForResource(offering, 'allLearners');
    assert.strictEqual(allLearners.length, 0);

    const user1 = store.createRecord('user', { displayName: 'Beta' });
    const user2 = store.createRecord('user', { displayName: 'Alpha' });
    const user3 = store.createRecord('user', { displayName: 'Omega' });
    offering.get('learners').pushObject(user1);
    const learnerGroup1 = store.createRecord('learner-group', {
      users: [user2],
    });
    const learnerGroup2 = store.createRecord('learner-group', {
      users: [user3],
    });
    offering.get('learnerGroups').pushObjects([learnerGroup1, learnerGroup2]);

    allLearners = await waitForResource(offering, 'allLearners');

    assert.strictEqual(allLearners.length, 3);
    assert.ok(allLearners.includes(user1));
    assert.ok(allLearners.includes(user2));
    assert.ok(allLearners.includes(user3));

    const user4 = store.createRecord('user', {
      firstName: 'Larry',
      lastName: 'Lazy',
    });
    const user5 = store.createRecord('user', { displayName: 'Gamma' });
    offering.get('learners').pushObject(user4);
    const learnerGroup3 = store.createRecord('learner-group', {
      users: [user5],
    });
    offering.get('learnerGroups').pushObject(learnerGroup3);

    allLearners = await waitForResource(offering, 'allLearners');

    assert.strictEqual(allLearners.length, 5);
    assert.strictEqual(allLearners[0].fullName, 'Alpha');
    assert.strictEqual(allLearners[1].fullName, 'Beta');
    assert.strictEqual(allLearners[2].fullName, 'Gamma');
    assert.strictEqual(allLearners[3].fullName, 'Larry Lazy');
    assert.strictEqual(allLearners[4].fullName, 'Omega');
  });

  test('startDayOfYear', function (assert) {
    const startDate = new Date('December 17, 1995 03:24:00');
    const offering = this.owner.lookup('service:store').createRecord('offering', { startDate });
    const startDayOfYear = offering.startDayOfYear;
    assert.strictEqual(startDayOfYear, '351');
  });

  test('startYear', function (assert) {
    const startDate = new Date('December 17, 1995 03:24:00');
    const offering = this.owner.lookup('service:store').createRecord('offering', { startDate });
    const startYear = offering.startYear;
    assert.strictEqual(startYear, '1995');
  });

  test('startTime', function (assert) {
    const startDate = new Date('December 17, 1995 03:24:00');
    const offering = this.owner.lookup('service:store').createRecord('offering', { startDate });
    const startTime = offering.startTime;
    assert.strictEqual(startTime, '0324');
  });

  test('startYearAndDayOfYear', function (assert) {
    const startDate = new Date('December 17, 1995 03:24:00');
    const offering = this.owner.lookup('service:store').createRecord('offering', { startDate });
    const startYearAndDayOfYear = offering.startYearAndDayOfYear;
    assert.strictEqual(startYearAndDayOfYear, '3511995');
  });

  test('endDayOfYear', function (assert) {
    const endDate = new Date('December 17, 1995 03:24:00');
    const offering = this.owner.lookup('service:store').createRecord('offering', { endDate });
    const endDayOfYear = offering.endDayOfYear;
    assert.strictEqual(endDayOfYear, '351');
  });

  test('endYear', function (assert) {
    const endDate = new Date('December 17, 1995 03:24:00');
    const offering = this.owner.lookup('service:store').createRecord('offering', { endDate });
    const endYear = offering.endYear;
    assert.strictEqual(endYear, '1995');
  });

  test('endTime', function (assert) {
    const endDate = new Date('December 17, 1995 03:24:00');
    const offering = this.owner.lookup('service:store').createRecord('offering', { endDate });
    const endTime = offering.endTime;
    assert.strictEqual(endTime, '0324');
  });

  test('endYearAndDayOfYear', function (assert) {
    const endDate = new Date('December 17, 1995 03:24:00');
    const offering = this.owner.lookup('service:store').createRecord('offering', { endDate });
    const endYearAndDayOfYear = offering.endYearAndDayOfYear;
    assert.strictEqual(endYearAndDayOfYear, '3511995');
  });

  test('getAllInstructors', async function (assert) {
    const store = this.owner.lookup('service:store');
    const instructor1 = store.createRecord('user');
    const instructor2 = store.createRecord('user');
    const instructor3 = store.createRecord('user');
    const instructor4 = store.createRecord('user');
    const instructorGroup1 = store.createRecord('instructorGroup', {
      users: [instructor1, instructor2],
    });
    const instructorGroup2 = store.createRecord('instructorGroup', {
      users: [instructor3],
    });
    const model = store.createRecord('offering', {
      instructorGroups: [instructorGroup1, instructorGroup2],
      instructors: [instructor1, instructor3, instructor4],
    });
    const allInstructors = await model.getAllInstructors();
    assert.strictEqual(allInstructors.length, 4);
    assert.ok(allInstructors.includes(instructor1));
    assert.ok(allInstructors.includes(instructor2));
    assert.ok(allInstructors.includes(instructor3));
    assert.ok(allInstructors.includes(instructor4));
  });

  test('getAllInstructors - no instructors', async function (assert) {
    const store = this.owner.lookup('service:store');
    const model = store.createRecord('offering');
    const allInstructors = await model.getAllInstructors();
    assert.strictEqual(allInstructors.length, 0);
  });
});
<commit_msg>Replace moment with luxon in test<commit_after>import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { DateTime } from 'luxon';
import { waitForResource } from 'ilios-common';

module('Unit | Model | Offering', function (hooks) {
  setupTest(hooks);

  test('check allInstructors', async function (assert) {
    assert.expect(11);
    const offering = this.owner.lookup('service:store').createRecord('offering');
    const store = this.owner.lookup('service:store');

    let allInstructors = await waitForResource(offering, 'allInstructors');

    assert.strictEqual(allInstructors.length, 0);

    const user1 = store.createRecord('user', { displayName: 'Beta' });
    const user2 = store.createRecord('user', { displayName: 'Alpha' });
    const user3 = store.createRecord('user', { displayName: 'Omega' });
    offering.get('instructors').pushObject(user1);
    const instructorGroup1 = store.createRecord('instructor-group', {
      users: [user2],
    });
    const instructorGroup2 = store.createRecord('instructor-group', {
      users: [user3],
    });
    offering.get('instructorGroups').pushObjects([instructorGroup1, instructorGroup2]);

    allInstructors = await waitForResource(offering, 'allInstructors');

    assert.strictEqual(allInstructors.length, 3);
    assert.ok(allInstructors.includes(user1));
    assert.ok(allInstructors.includes(user2));
    assert.ok(allInstructors.includes(user3));

    const user4 = store.createRecord('user', {
      firstName: 'Larry',
      lastName: 'Lazy',
    });
    const user5 = store.createRecord('user', { displayName: 'Gamma' });
    offering.get('instructors').pushObject(user4);
    const instructorGroup3 = store.createRecord('instructor-group', {
      users: [user5],
    });
    offering.get('instructorGroups').pushObject(instructorGroup3);

    allInstructors = await waitForResource(offering, 'allInstructors');

    assert.strictEqual(allInstructors.length, 5);
    assert.strictEqual(allInstructors[0].fullName, 'Alpha');
    assert.strictEqual(allInstructors[1].fullName, 'Beta');
    assert.strictEqual(allInstructors[2].fullName, 'Gamma');
    assert.strictEqual(allInstructors[3].fullName, 'Larry Lazy');
    assert.strictEqual(allInstructors[4].fullName, 'Omega');
  });

  test('duration', function (assert) {
    const store = this.owner.lookup('service:store');
    const model = store.createRecord('offering', {});
    assert.strictEqual(model.get('durationHours'), 0);
    assert.strictEqual(model.get('durationMinutes'), 0);
    model.set('startDate', DateTime.now().toJSDate());
    model.set('endDate', DateTime.now().plus({ minutes: 90 }).toJSDate());

    assert.strictEqual(model.get('durationHours'), 1);
    assert.strictEqual(model.get('durationMinutes'), 30);

    model.set('startDate', DateTime.now().toJSDate());
    model.set('endDate', DateTime.now().plus({ minutes: 30 }).toJSDate());

    assert.strictEqual(model.get('durationHours'), 0);
    assert.strictEqual(model.get('durationMinutes'), 30);

    model.set('startDate', DateTime.now().toJSDate());
    model.set('endDate', DateTime.now().plus({ minutes: 60 }).toJSDate());

    assert.strictEqual(model.get('durationHours'), 1);
    assert.strictEqual(model.get('durationMinutes'), 0);
  });

  test('check allLearners', async function (assert) {
    assert.expect(11);
    const offering = this.owner.lookup('service:store').createRecord('offering');
    const store = this.owner.lookup('service:store');

    let allLearners = await waitForResource(offering, 'allLearners');
    assert.strictEqual(allLearners.length, 0);

    const user1 = store.createRecord('user', { displayName: 'Beta' });
    const user2 = store.createRecord('user', { displayName: 'Alpha' });
    const user3 = store.createRecord('user', { displayName: 'Omega' });
    offering.get('learners').pushObject(user1);
    const learnerGroup1 = store.createRecord('learner-group', {
      users: [user2],
    });
    const learnerGroup2 = store.createRecord('learner-group', {
      users: [user3],
    });
    offering.get('learnerGroups').pushObjects([learnerGroup1, learnerGroup2]);

    allLearners = await waitForResource(offering, 'allLearners');

    assert.strictEqual(allLearners.length, 3);
    assert.ok(allLearners.includes(user1));
    assert.ok(allLearners.includes(user2));
    assert.ok(allLearners.includes(user3));

    const user4 = store.createRecord('user', {
      firstName: 'Larry',
      lastName: 'Lazy',
    });
    const user5 = store.createRecord('user', { displayName: 'Gamma' });
    offering.get('learners').pushObject(user4);
    const learnerGroup3 = store.createRecord('learner-group', {
      users: [user5],
    });
    offering.get('learnerGroups').pushObject(learnerGroup3);

    allLearners = await waitForResource(offering, 'allLearners');

    assert.strictEqual(allLearners.length, 5);
    assert.strictEqual(allLearners[0].fullName, 'Alpha');
    assert.strictEqual(allLearners[1].fullName, 'Beta');
    assert.strictEqual(allLearners[2].fullName, 'Gamma');
    assert.strictEqual(allLearners[3].fullName, 'Larry Lazy');
    assert.strictEqual(allLearners[4].fullName, 'Omega');
  });

  test('startDayOfYear', function (assert) {
    const startDate = new Date('December 17, 1995 03:24:00');
    const offering = this.owner.lookup('service:store').createRecord('offering', { startDate });
    const startDayOfYear = offering.startDayOfYear;
    assert.strictEqual(startDayOfYear, '351');
  });

  test('startYear', function (assert) {
    const startDate = new Date('December 17, 1995 03:24:00');
    const offering = this.owner.lookup('service:store').createRecord('offering', { startDate });
    const startYear = offering.startYear;
    assert.strictEqual(startYear, '1995');
  });

  test('startTime', function (assert) {
    const startDate = new Date('December 17, 1995 03:24:00');
    const offering = this.owner.lookup('service:store').createRecord('offering', { startDate });
    const startTime = offering.startTime;
    assert.strictEqual(startTime, '0324');
  });

  test('startYearAndDayOfYear', function (assert) {
    const startDate = new Date('December 17, 1995 03:24:00');
    const offering = this.owner.lookup('service:store').createRecord('offering', { startDate });
    const startYearAndDayOfYear = offering.startYearAndDayOfYear;
    assert.strictEqual(startYearAndDayOfYear, '3511995');
  });

  test('endDayOfYear', function (assert) {
    const endDate = new Date('December 17, 1995 03:24:00');
    const offering = this.owner.lookup('service:store').createRecord('offering', { endDate });
    const endDayOfYear = offering.endDayOfYear;
    assert.strictEqual(endDayOfYear, '351');
  });

  test('endYear', function (assert) {
    const endDate = new Date('December 17, 1995 03:24:00');
    const offering = this.owner.lookup('service:store').createRecord('offering', { endDate });
    const endYear = offering.endYear;
    assert.strictEqual(endYear, '1995');
  });

  test('endTime', function (assert) {
    const endDate = new Date('December 17, 1995 03:24:00');
    const offering = this.owner.lookup('service:store').createRecord('offering', { endDate });
    const endTime = offering.endTime;
    assert.strictEqual(endTime, '0324');
  });

  test('endYearAndDayOfYear', function (assert) {
    const endDate = new Date('December 17, 1995 03:24:00');
    const offering = this.owner.lookup('service:store').createRecord('offering', { endDate });
    const endYearAndDayOfYear = offering.endYearAndDayOfYear;
    assert.strictEqual(endYearAndDayOfYear, '3511995');
  });

  test('getAllInstructors', async function (assert) {
    const store = this.owner.lookup('service:store');
    const instructor1 = store.createRecord('user');
    const instructor2 = store.createRecord('user');
    const instructor3 = store.createRecord('user');
    const instructor4 = store.createRecord('user');
    const instructorGroup1 = store.createRecord('instructorGroup', {
      users: [instructor1, instructor2],
    });
    const instructorGroup2 = store.createRecord('instructorGroup', {
      users: [instructor3],
    });
    const model = store.createRecord('offering', {
      instructorGroups: [instructorGroup1, instructorGroup2],
      instructors: [instructor1, instructor3, instructor4],
    });
    const allInstructors = await model.getAllInstructors();
    assert.strictEqual(allInstructors.length, 4);
    assert.ok(allInstructors.includes(instructor1));
    assert.ok(allInstructors.includes(instructor2));
    assert.ok(allInstructors.includes(instructor3));
    assert.ok(allInstructors.includes(instructor4));
  });

  test('getAllInstructors - no instructors', async function (assert) {
    const store = this.owner.lookup('service:store');
    const model = store.createRecord('offering');
    const allInstructors = await model.getAllInstructors();
    assert.strictEqual(allInstructors.length, 0);
  });
});
<|endoftext|>


<commit_before><commit_msg>LivefyreStream#_read should not call LivefyreStreamClient if its no longer supposed to be reading<commit_after><|endoftext|>


<commit_before>"use strict";

var App = App || {};

let SocialServiceModel = function() {
  let self = {
    data: null,

    filters: {},
    searchTerm: ""
  };

  init();

  function init() {

  }

  function loadData(dataPath) {
    return new Promise(function(resolve, reject) {
      d3.csv(dataPath, function(err, data) {
        if (err) reject(err);

        self.data = data;

        //filter out empty entries
        self.data = data.filter((d) => {
          let isNotEmpty = false;
          for(let property in d){
            if(typeof d[property] === "string" && d[property].length > 0){
              isNotEmpty = true;
            }
          }

          return isNotEmpty;
        });
        resolve();
      })
    });
  }

  function getData() {
    return self.data;
  }

  function getFilteredData(serviceFilters) {
    self.filters = serviceFilters;
    // if (Object.keys(serviceFilters).length == 0) {
    //   return self.data;
    // }
    //
    // return _.filter(self.data, function(el) {
    //   for (let property of Object.keys(serviceFilters)) {
    //     if (el[property] == 1) {
    //       return true;
    //     }
    //   }
    //
    //   return false;
    // });

    return getSearchAndFilterSubset();
  }

  // just searching by name for now
  function getSearchedData(term) {
    self.searchTerm = _.lowerCase(term);

    return getSearchAndFilterSubset();
  }

  function getSearchAndFilterSubset() {

    let filteredData = Object.keys(self.filters).length == 0 ? self.data :
      _.filter(self.data, function(el) {
        for (let property of Object.keys(self.filters)) {
          if (el[property] == 1) {
            return true;
          }
        }

        return false;
      });

    let searchData = self.searchTerm.length === 0 ? self.data :
      _.filter(self.data, el => _.includes(_.lowerCase(el["Organization Name"]), self.searchTerm));

    return _.intersection(filteredData, searchData);

  }

  function getDataByFilter(filterFn){
    return _.filter(self.data,filterFn);
  }

  function getDataWithinBounds(bounds) {
    let lat = d3.extent(bounds, b => b.lat);
    let lng = d3.extent(bounds, b => b.lng);

    // return _.filter(self.data, service => service.Y >= lat[0] && service.Y < lat[1] && service.X >= lng[0] && service.X < lng[1]);
    return getDataByFilter((service) => {
      let serviceLat = +service.Latitude, serviceLng = +service.Longitude;
      return serviceLat >= lat[0] && serviceLat < lat[1] && serviceLng >= lng[0] && serviceLng < lng[1];
    });
  }

  return {
    loadData,
    getData,
    getFilteredData,
    getSearchedData,
    getDataWithinBounds,
    getDataByFilter
  };
};
<commit_msg>implemented data download controller usage for service model<commit_after>"use strict";

var App = App || {};

let SocialServiceModel = function() {
  let self = {
    data: null,

    filters: {},
    searchTerm: ""
  };

  init();

  function init() {

  }

  function loadData(dataPath) {
    return App.controllers.dataDownload.getCsv(dataPath)
      .then(function (data) {
        self.data = data;

        //filter out empty entries
        self.data = data.filter(function (d) {
          let isNotEmpty = false;
          for (const property in d) {
            if (typeof d[property] === "string" && d[property].length > 0) {
              isNotEmpty = true;
            }
          }
          return isNotEmpty;
        });
        return;
      });
  }

  function getData() {
    return self.data;
  }

  function getFilteredData(serviceFilters) {
    self.filters = serviceFilters;
    return getSearchAndFilterSubset();
  }

  // just searching by name for now
  function getSearchedData(term) {
    self.searchTerm = _.lowerCase(term);
    return getSearchAndFilterSubset();
  }

  function getSearchAndFilterSubset() {
    let filteredData = Object.keys(self.filters).length == 0 ? self.data :
      _.filter(self.data, function(el) {
        for (let property of Object.keys(self.filters)) {
          if (el[property] == 1) {
            return true;
          }
        }
        return false;
      });

    let searchData = self.searchTerm.length === 0 ? self.data :
      _.filter(self.data, el => _.includes(_.lowerCase(el["Organization Name"]), self.searchTerm));

    return _.intersection(filteredData, searchData);

  }

  function getDataByFilter(filterFn){
    return _.filter(self.data,filterFn);
  }

  function getDataWithinBounds(bounds) {
    const lat = d3.extent(bounds, b => b.lat);
    const lng = d3.extent(bounds, b => b.lng);

    return getDataByFilter((service) => {
      const serviceLat = +service.Latitude, serviceLng = +service.Longitude;
      return (serviceLat >= lat[0] && serviceLat < lat[1]) &&
        (serviceLng >= lng[0] && serviceLng < lng[1]);
    });
  }

  return {
    loadData,
    getData,
    getFilteredData,
    getSearchedData,
    getDataWithinBounds,
    getDataByFilter
  };
};
<|endoftext|>


<commit_before>/*
 * mobile slider unit tests
 */

(function($){
	var onChangeCnt = 0;
	window.onChangeCounter = function() {
		onChangeCnt++;
	}
	module('jquery.mobile.slider.js');

	var keypressTest = function(opts){
		var slider = $(opts.selector),
		    val = window.parseFloat(slider.val()),
				handle = slider.siblings('.ui-slider').find('.ui-slider-handle');

		expect( opts.keyCodes.length );

		$.each(opts.keyCodes, function(i, elem){

			// stub the keycode value and trigger the keypress
			$.Event.prototype.keyCode = $.mobile.keyCode[elem];
			handle.trigger('keydown');

			val += opts.increment;
			same(val, window.parseFloat(slider.val(), 10), "new value is " + opts.increment + " different");
		});
	};

	test( "slider should move right with up, right, and page up keypress", function(){
		keypressTest({
			selector: '#range-slider-up',
			keyCodes: ['UP', 'RIGHT', 'PAGE_UP'],
			increment: 1
		});
	});

	test( "slider should move left with down, left, and page down keypress", function(){
		keypressTest({
			selector: '#range-slider-down',
			keyCodes: ['DOWN', 'LEFT', 'PAGE_DOWN'],
			increment: -1
		});
	});

	test( "slider should move to range minimum on end keypress", function(){
		var selector = "#range-slider-end",
				initialVal = window.parseFloat($(selector).val(), 10),
		    max = window.parseFloat($(selector).attr('max'), 10);

		keypressTest({
			selector: selector,
			keyCodes: ['END'],
			increment: max - initialVal
		});
	});

	test( "slider should move to range minimum on end keypress", function(){
		var selector = "#range-slider-home",
				initialVal = window.parseFloat($(selector).val(), 10);

		keypressTest({
			selector: selector,
			keyCodes: ['HOME'],
			increment: 0 - initialVal
		});
	});

	test( "slider should move positive by steps on keypress", function(){
		keypressTest({
			selector: "#stepped",
			keyCodes: ['RIGHT'],
			increment: 10
		});
	});

	test( "slider should move negative by steps on keypress", function(){
		keypressTest({
			selector: "#stepped",
			keyCodes: ['LEFT'],
			increment: -10
		});
	});

	test( "slider should validate input value on blur", function(){
		var slider = $("#range-slider-up");
		slider.focus();
		slider.val(200);
		same(slider.val(), "200");
		slider.blur();
		same(slider.val(), slider.attr('max'));
	});

	test( "slider should not validate input on keyup", function(){
		var slider = $("#range-slider-up");
		slider.focus();
		slider.val(200);
		same(slider.val(), "200");
		slider.keyup();
		same(slider.val(), "200");
	});

	test( "input type should degrade to number when slider is created", function(){
		same($("#range-slider-up").attr( "type" ), "number");
	});

	// generic switch test function
	var sliderSwitchTest = function(opts){
		var slider = $("#slider-switch"),
			  handle = slider.siblings('.ui-slider').find('a'),
		    switchValues = {
					'off' : 0,
					'on' : 1
				};

		// One for the select and one for the aria-valuenow
		expect( opts.keyCodes.length * 2 );

		$.each(opts.keyCodes, function(i, elem){
			// reset the values
			slider[0].selectedIndex = switchValues[opts.start];
			handle.attr({'aria-valuenow' : opts.start });

			// stub the keycode and trigger the event
			$.Event.prototype.keyCode = $.mobile.keyCode[elem];
			handle.trigger('keydown');

			same(handle.attr('aria-valuenow'), opts.finish, "handle value is " + opts.finish);
			same(slider[0].selectedIndex, switchValues[opts.finish], "select input has correct index");
		});
	};

	test( "switch should select on with up, right, page up and end", function(){
		sliderSwitchTest({
			start: 'off',
			finish: 'on',
			keyCodes: ['UP', 'RIGHT', 'PAGE_UP', 'END']
		});
	});

	test( "switch should select off with down, left, page down and home", function(){
		sliderSwitchTest({
			start: 'on',
			finish: 'off',
		  keyCodes: ['DOWN', 'LEFT', 'PAGE_DOWN', 'HOME']
		});
	});

	test( "onchange should not be called on create", function(){
		equals(onChangeCnt, 0, "onChange should not have been called");
	});

	test( "onchange should be called onchange", function(){
		onChangeCnt = 0;
		$( "#onchange" ).slider( "refresh", 50 );
		equals(onChangeCnt, 1, "onChange should have been called once");
	});

	test( "slider controls will create when inside a container that receives a 'create' event", function(){
		ok( !$("#enhancetest").appendTo(".ui-page-active").find(".ui-slider").length, "did not have enhancements applied" );
		ok( $("#enhancetest").trigger("create").find(".ui-slider").length, "enhancements applied" );
	});
})(jQuery);<commit_msg>Added slider unit test for issue 2315 - Flip toggle switch with change event bound, triggers multiple times<commit_after>/*
 * mobile slider unit tests
 */

(function($){
	var onChangeCnt = 0;
	window.onChangeCounter = function() {
		onChangeCnt++;
	}
	module('jquery.mobile.slider.js');

	var keypressTest = function(opts){
		var slider = $(opts.selector),
		    val = window.parseFloat(slider.val()),
				handle = slider.siblings('.ui-slider').find('.ui-slider-handle');

		expect( opts.keyCodes.length );

		$.each(opts.keyCodes, function(i, elem){

			// stub the keycode value and trigger the keypress
			$.Event.prototype.keyCode = $.mobile.keyCode[elem];
			handle.trigger('keydown');

			val += opts.increment;
			same(val, window.parseFloat(slider.val(), 10), "new value is " + opts.increment + " different");
		});
	};

	test( "slider should move right with up, right, and page up keypress", function(){
		keypressTest({
			selector: '#range-slider-up',
			keyCodes: ['UP', 'RIGHT', 'PAGE_UP'],
			increment: 1
		});
	});

	test( "slider should move left with down, left, and page down keypress", function(){
		keypressTest({
			selector: '#range-slider-down',
			keyCodes: ['DOWN', 'LEFT', 'PAGE_DOWN'],
			increment: -1
		});
	});

	test( "slider should move to range minimum on end keypress", function(){
		var selector = "#range-slider-end",
				initialVal = window.parseFloat($(selector).val(), 10),
		    max = window.parseFloat($(selector).attr('max'), 10);

		keypressTest({
			selector: selector,
			keyCodes: ['END'],
			increment: max - initialVal
		});
	});

	test( "slider should move to range minimum on end keypress", function(){
		var selector = "#range-slider-home",
				initialVal = window.parseFloat($(selector).val(), 10);

		keypressTest({
			selector: selector,
			keyCodes: ['HOME'],
			increment: 0 - initialVal
		});
	});

	test( "slider should move positive by steps on keypress", function(){
		keypressTest({
			selector: "#stepped",
			keyCodes: ['RIGHT'],
			increment: 10
		});
	});

	test( "slider should move negative by steps on keypress", function(){
		keypressTest({
			selector: "#stepped",
			keyCodes: ['LEFT'],
			increment: -10
		});
	});

	test( "slider should validate input value on blur", function(){
		var slider = $("#range-slider-up");
		slider.focus();
		slider.val(200);
		same(slider.val(), "200");
		slider.blur();
		same(slider.val(), slider.attr('max'));
	});

	test( "slider should not validate input on keyup", function(){
		var slider = $("#range-slider-up");
		slider.focus();
		slider.val(200);
		same(slider.val(), "200");
		slider.keyup();
		same(slider.val(), "200");
	});

	test( "input type should degrade to number when slider is created", function(){
		same($("#range-slider-up").attr( "type" ), "number");
	});

	// generic switch test function
	var sliderSwitchTest = function(opts){
		var slider = $("#slider-switch"),
			  handle = slider.siblings('.ui-slider').find('a'),
		    switchValues = {
					'off' : 0,
					'on' : 1
				};

		// One for the select and one for the aria-valuenow
		expect( opts.keyCodes.length * 2 );

		$.each(opts.keyCodes, function(i, elem){
			// reset the values
			slider[0].selectedIndex = switchValues[opts.start];
			handle.attr({'aria-valuenow' : opts.start });

			// stub the keycode and trigger the event
			$.Event.prototype.keyCode = $.mobile.keyCode[elem];
			handle.trigger('keydown');

			same(handle.attr('aria-valuenow'), opts.finish, "handle value is " + opts.finish);
			same(slider[0].selectedIndex, switchValues[opts.finish], "select input has correct index");
		});
	};

	test( "switch should select on with up, right, page up and end", function(){
		sliderSwitchTest({
			start: 'off',
			finish: 'on',
			keyCodes: ['UP', 'RIGHT', 'PAGE_UP', 'END']
		});
	});

	test( "switch should select off with down, left, page down and home", function(){
		sliderSwitchTest({
			start: 'on',
			finish: 'off',
		  keyCodes: ['DOWN', 'LEFT', 'PAGE_DOWN', 'HOME']
		});
	});

	test( "onchange should not be called on create", function(){
		equals(onChangeCnt, 0, "onChange should not have been called");
	});

	test( "onchange should be called onchange", function(){
		onChangeCnt = 0;
		$( "#onchange" ).slider( "refresh", 50 );
		equals(onChangeCnt, 1, "onChange should have been called once");
	});

	test( "slider controls will create when inside a container that receives a 'create' event", function(){
		ok( !$("#enhancetest").appendTo(".ui-page-active").find(".ui-slider").length, "did not have enhancements applied" );
		ok( $("#enhancetest").trigger("create").find(".ui-slider").length, "enhancements applied" );
	});

	test( "toggle switch should fire one change event when clicked", function(){
		var control = $( "#slider-switch" ),
			widget = control.data( "slider" ),
			slider = widget.slider,
			handle = widget.handle,
			changeCount = 0,
			changeFunc = function( e ) {
				ok( control[0].selectedIndex !== currentValue, "change event should only be triggered if the value changes");
				++changeCount;
			},
			event = null,
			offset = handle.offset(),
			currentValue = control[0].selectedIndex;

		function createEvent( name, target, x, y )
		{
			var event = $.Event( name );
			event.target = target;
			event.pageX = x;
			event.pageY = y;
			return event;
		}

		control.bind( "change", changeFunc );

		// The toggle switch actually updates on mousedown and mouseup events, so we go through
		// the motions of generating all the events that happen during a click to make sure that
		// during all of those events, the value only changes once.

		slider.trigger( createEvent( "mousedown", handle[ 0 ], offset.left + 10, offset.top + 10 ) );
		slider.trigger( createEvent( "mouseup", handle[ 0 ], offset.left + 10, offset.top + 10 ) );
		slider.trigger( createEvent( "click", handle[ 0 ], offset.left + 10, offset.top + 10 ) );

		control.unbind( "change", changeFunc );

		ok( control[0].selectedIndex !== currentValue, "value did change");
		same( changeCount, 1, "change event should be fired once during a click" );
	});
})(jQuery);<|endoftext|>


<commit_before>'use strict';

const BaseEmbed = require('./BaseEmbed.js');

const dispositions = ['\\⚫\\⚫\\⚫\\⚫\\⚫', '\\⚫\\⚫\\⚫\\⚫\\⚪', '\\⚫\\⚫\\⚫\\⚪\\⚪', '\\⚫\\⚫\\⚪\\⚪\\⚪', '\\⚫\\⚪\\⚪\\⚪\\⚪', '\\⚪\\⚪\\⚪\\⚪\\⚪'];

/**
 * Generates enemy embeds
 */
class WeaponEmbed extends BaseEmbed {
  /**
   * @param {Genesis} bot - An instance of Genesis
   * @param {Enhancement} weapon - The enhancement to send info on
   */
  constructor(bot, weapon) {
    super();
    if (weapon && typeof weapon !== 'undefined') {
      this.title = weapon.name;
      this.url = weapon.url || '';
      this.thumbnail = { url: weapon.thumbnail || '' };
      this.description = `${weapon.type} ${weapon.subtype ? `| ${weapon.subtype}` : ''}`;
      this.footer = { text: `Drops from: ${weapon.location}` };
      this.color = weapon.color;
      this.fields = [];

      if (weapon.color) {
        this.color = weapon.color;
      }

      if (weapon.primary) {
        this.fields.push({
          name: 'Primary Fire',
          value: `**Trigger:** ${weapon.primary.trigger}\n` +
          `**Projectile:** ${weapon.primary.projectile}\n` +
          `**Rate:** ${weapon.primary.rate}\n` +
          `**Flight:**: ${weapon.primary.flight || '-'}\n` +
          `**Noise:** ${weapon.primary.noise}\n` +
          `**Accuracy:** ${weapon.primary.accuracy}\n` +
          `**Reload:** ${weapon.primary.reload}\n` +
          `**Damage:** ${weapon.primary.damage}\n` +
          `**Impact:** ${weapon.primary.impact}\n` +
          `**Puncture:** ${weapon.primary.puncture}\n` +
          `**Slash:** ${weapon.primary.slash}\n` +
          `**Critical Chance:** ${weapon.primary.crit_chance}\n` +
          `**Critical Multiplier:** ${weapon.primary.crit_mult}\n` +
          `**Status Chance:** ${weapon.primary.status_chance}`,
          inline: true,
        });
      } else {
        const things = [{
          name: 'Rate',
          value: String(weapon.rate),
          inline: true,
        },
        {
          name: 'Damage',
          value: weapon.damage,
          inline: true,
        },
        {
          name: 'Critical Chance',
          value: weapon.crit_chance,
          inline: true,
        },
        {
          name: 'Critical Multiplier',
          value: weapon.crit_mult,
          inline: true,
        },
        {
          name: 'Status Chance',
          value: weapon.status_chance,
          inline: true,
        },
        {
          name: 'Polarities',
          value: weapon.polarities,
          inline: true,
        }];
        this.fields.push(...things);
      }

      if (weapon.secondary) {
        this.fields.push({
          name: 'Secondary Fire',
          value: `**Trigger:** ${weapon.secondary.trigger}\n` +
          `**Projectile:** ${weapon.secondary.projectile}\n` +
          `**Rate:** ${weapon.secondary.rate}\n` +
          `**Flight:**: ${weapon.secondary.flight || '-'}\n` +
          `**Noise:** ${weapon.secondary.noise}\n` +
          `**Accuracy:** ${weapon.secondary.accuracy}\n` +
          `**Reload:** ${weapon.secondary.reload}\n` +
          `**Damage:** ${weapon.secondary.damage}\n` +
          `**Impact:** ${weapon.secondary.impact}\n` +
          `**Puncture:** ${weapon.secondary.puncture}\n` +
          `**Slash:** ${weapon.secondary.slash}\n` +
          `**Critical Chance:** ${weapon.secondary.crit_chance}\n` +
          `**Critical Multiplier:** ${weapon.secondary.crit_mult}\n` +
          `**Status Chance:** ${weapon.secondary.status_chance}`,
          inline: true,
        });
      }

      if (weapon.noise) {
        this.fields.push({
          name: 'Noise Level',
          value: weapon.noise,
          inline: true,
        });
      }

      if (weapon.projectile) {
        this.fields.push({
          name: 'Projectile',
          value: weapon.projectile,
          inline: true,
        });
      }
      if (weapon.trigger) {
        this.fields.push({
          name: 'Trigger Type',
          value: weapon.trigger,
          inline: true,
        });
      }
      if (weapon.impact) {
        this.fields.push({
          name: 'Impact',
          value: weapon.impact,
          inline: true,
        });
      }
      if (weapon.puncture) {
        this.fields.push({
          name: 'Puncture',
          value: weapon.puncture,
          inline: true,
        });
      }
      if (weapon.slash) {
        this.fields.push({
          name: 'Slash',
          value: weapon.slash,
          inline: true,
        });
      }
      if (weapon.flight) {
        this.fields.push({
          name: 'Flight Speed',
          value: weapon.flight,
          inline: true,
        });
      }
      if (weapon.magazine) {
        this.fields.push({
          name: 'Magazine Size',
          value: String(weapon.magazine),
          inline: true,
        });
      }
      if (weapon.ammo) {
        this.fields.push({
          name: 'Ammo Max',
          value: weapon.ammo,
          inline: true,
        });
      }
      if (weapon.accuracy) {
        this.fields.push({
          name: 'Accuracy',
          value: String(weapon.accuracy),
          inline: true,
        });
      }
      if (weapon.reload) {
        this.fields.push({
          name: 'Reload Speed',
          value: weapon.reload || '-',
          inline: true,
        });
      }
      if (weapon.riven_disposition) {
        this.fields.push({
          name: 'Riven Disposition',
          value: dispositions[weapon.riven_disposition],
          inline: true,
        });
      }
    } else {
      this.title = 'Invalid Query';
      this.color = 0xff6961;
      this.footer = undefined;
    }
  }
}

module.exports = WeaponEmbed;
<commit_msg>remove locations from weapons<commit_after>'use strict';

const BaseEmbed = require('./BaseEmbed.js');

const dispositions = ['\\⚫\\⚫\\⚫\\⚫\\⚫', '\\⚫\\⚫\\⚫\\⚫\\⚪', '\\⚫\\⚫\\⚫\\⚪\\⚪', '\\⚫\\⚫\\⚪\\⚪\\⚪', '\\⚫\\⚪\\⚪\\⚪\\⚪', '\\⚪\\⚪\\⚪\\⚪\\⚪'];

/**
 * Generates enemy embeds
 */
class WeaponEmbed extends BaseEmbed {
  /**
   * @param {Genesis} bot - An instance of Genesis
   * @param {Enhancement} weapon - The enhancement to send info on
   */
  constructor(bot, weapon) {
    super();
    if (weapon && typeof weapon !== 'undefined') {
      this.title = weapon.name;
      this.url = weapon.url || '';
      this.thumbnail = { url: weapon.thumbnail || '' };
      this.description = `${weapon.type} ${weapon.subtype ? `| ${weapon.subtype}` : ''}`;
      this.color = weapon.color;
      this.fields = [];

      if (weapon.color) {
        this.color = weapon.color;
      }

      if (weapon.primary) {
        this.fields.push({
          name: 'Primary Fire',
          value: `**Trigger:** ${weapon.primary.trigger}\n` +
          `**Projectile:** ${weapon.primary.projectile}\n` +
          `**Rate:** ${weapon.primary.rate}\n` +
          `**Flight:**: ${weapon.primary.flight || '-'}\n` +
          `**Noise:** ${weapon.primary.noise}\n` +
          `**Accuracy:** ${weapon.primary.accuracy}\n` +
          `**Reload:** ${weapon.primary.reload}\n` +
          `**Damage:** ${weapon.primary.damage}\n` +
          `**Impact:** ${weapon.primary.impact}\n` +
          `**Puncture:** ${weapon.primary.puncture}\n` +
          `**Slash:** ${weapon.primary.slash}\n` +
          `**Critical Chance:** ${weapon.primary.crit_chance}\n` +
          `**Critical Multiplier:** ${weapon.primary.crit_mult}\n` +
          `**Status Chance:** ${weapon.primary.status_chance}`,
          inline: true,
        });
      } else {
        const things = [{
          name: 'Rate',
          value: String(weapon.rate),
          inline: true,
        },
        {
          name: 'Damage',
          value: weapon.damage,
          inline: true,
        },
        {
          name: 'Critical Chance',
          value: weapon.crit_chance,
          inline: true,
        },
        {
          name: 'Critical Multiplier',
          value: weapon.crit_mult,
          inline: true,
        },
        {
          name: 'Status Chance',
          value: weapon.status_chance,
          inline: true,
        },
        {
          name: 'Polarities',
          value: weapon.polarities,
          inline: true,
        }];
        this.fields.push(...things);
      }

      if (weapon.secondary) {
        this.fields.push({
          name: 'Secondary Fire',
          value: `**Trigger:** ${weapon.secondary.trigger}\n` +
          `**Projectile:** ${weapon.secondary.projectile}\n` +
          `**Rate:** ${weapon.secondary.rate}\n` +
          `**Flight:**: ${weapon.secondary.flight || '-'}\n` +
          `**Noise:** ${weapon.secondary.noise}\n` +
          `**Accuracy:** ${weapon.secondary.accuracy}\n` +
          `**Reload:** ${weapon.secondary.reload}\n` +
          `**Damage:** ${weapon.secondary.damage}\n` +
          `**Impact:** ${weapon.secondary.impact}\n` +
          `**Puncture:** ${weapon.secondary.puncture}\n` +
          `**Slash:** ${weapon.secondary.slash}\n` +
          `**Critical Chance:** ${weapon.secondary.crit_chance}\n` +
          `**Critical Multiplier:** ${weapon.secondary.crit_mult}\n` +
          `**Status Chance:** ${weapon.secondary.status_chance}`,
          inline: true,
        });
      }

      if (weapon.noise) {
        this.fields.push({
          name: 'Noise Level',
          value: weapon.noise,
          inline: true,
        });
      }

      if (weapon.projectile) {
        this.fields.push({
          name: 'Projectile',
          value: weapon.projectile,
          inline: true,
        });
      }
      if (weapon.trigger) {
        this.fields.push({
          name: 'Trigger Type',
          value: weapon.trigger,
          inline: true,
        });
      }
      if (weapon.impact) {
        this.fields.push({
          name: 'Impact',
          value: weapon.impact,
          inline: true,
        });
      }
      if (weapon.puncture) {
        this.fields.push({
          name: 'Puncture',
          value: weapon.puncture,
          inline: true,
        });
      }
      if (weapon.slash) {
        this.fields.push({
          name: 'Slash',
          value: weapon.slash,
          inline: true,
        });
      }
      if (weapon.flight) {
        this.fields.push({
          name: 'Flight Speed',
          value: weapon.flight,
          inline: true,
        });
      }
      if (weapon.magazine) {
        this.fields.push({
          name: 'Magazine Size',
          value: String(weapon.magazine),
          inline: true,
        });
      }
      if (weapon.ammo) {
        this.fields.push({
          name: 'Ammo Max',
          value: weapon.ammo,
          inline: true,
        });
      }
      if (weapon.accuracy) {
        this.fields.push({
          name: 'Accuracy',
          value: String(weapon.accuracy),
          inline: true,
        });
      }
      if (weapon.reload) {
        this.fields.push({
          name: 'Reload Speed',
          value: weapon.reload || '-',
          inline: true,
        });
      }
      if (weapon.riven_disposition) {
        this.fields.push({
          name: 'Riven Disposition',
          value: dispositions[weapon.riven_disposition],
          inline: true,
        });
      }
    } else {
      this.title = 'Invalid Query';
      this.color = 0xff6961;
      this.footer = undefined;
    }
  }
}

module.exports = WeaponEmbed;
<|endoftext|>


<commit_before>import {spawnSync} from 'child_process';

import {REINDEX_URL, REINDEX_TOKEN} from '../src/config.js';

let command = `node_modules/.bin/reindex -u ${REINDEX_URL} -t ${REINDEX_TOKEN} schema-relay data/schema.json`;
console.log(command)
spawnSync('node', command.split(" "), {stdio: 'inherit'})
<commit_msg>allow more than one command for schema operations<commit_after>import {spawnSync} from 'child_process';
import process from 'process';

import {REINDEX_URL, REINDEX_TOKEN} from '../src/config.js';

let command = `node_modules/.bin/reindex -u ${REINDEX_URL} -t ${REINDEX_TOKEN} ${process.argv[2]} data/schema.json`;
console.log(command)
spawnSync('node', command.split(" "), {stdio: 'inherit'})
<|endoftext|>


<commit_before>/**
 * TODO: remove Injector deps form here and use lodash same methods
 */
import Injector from '../components/injector';

export default class ObjectTransition {
  constructor(source) {
    /**
     * public attributes
     */
    this.transition = new Map();
    this.source = source;

    this.parse = Injector.get('$parse');
    this.pushCounter = 0;
  }

  getTransition() {
    return this.transition;
  }

  /**
   * Scope methods
   */
  getter(key) {
    var parse = this.parse;
    return parse(key);
  }

  setter(key) {
    return this.getter(key).assign;
  }

  get(key) {
    var getter = this.getter(key);
    var source = this.source;
    return getter(source);
  }

  assign(key) {
    var source = this.source;
    return this.getter(key).bind(null, source);
  }

  clearTransition() {
    this.transition.clear();
  }

  commit(key, value) {
    var scopeState = this.getTransition();
    scopeState.set(key, value);
  }

  push() {
    this.pushCounter++;

    if (arguments.length == 2) {
      this.commit.apply(this, arguments);
    } else if (!!arguments.length) {
      throw new Error('Wrong arguments for ObjectTransition.push');
    }

    var transition = this.getTransition();

    // Workaround
    var keys = [];
    transition.forEach((value, key) => keys.push(key));

    var source = this.source;
    transition.forEach((value, key) => {
      var setter = this.setter(key);
      setter(source, value);
    });

    this.clearTransition();
  }
}

<commit_msg>object-transition  - using lodash get/set methods instead of angular $parse<commit_after>import getter from 'lodash/objects/get';
import setter from 'lodash/objects/set';

export default class ObjectTransition {
  constructor(source) {
    /**
     * public attributes
     */
    this.transition = new Map();
    this.source = source;

    this.pushCounter = 0;
  }

  getTransition() {
    return this.transition;
  }

  /**
   * Scope methods
   */
  set(key, value) {
    var source = this.source;
    return setter(source, key, value);
  }

  get(key) {
    var source = this.source;
    return getter(source, key);
  }

  clearTransition() {
    this.transition.clear();
  }

  commit(key, value) {
    var transition = this.getTransition();
    transition.set(key, value);
  }

  push() {
    this.pushCounter++;

    if (arguments.length == 2) {
      this.commit.apply(this, arguments);
    } else if (!!arguments.length) {
      throw new Error('Wrong arguments for ObjectTransition.push');
    }

    var transition = this.getTransition();

    // Workaround
    var keys = [];
    transition.forEach((value, key) => keys.push(key));

    transition.forEach((value, key) => {
      this.set(key, value);
    });

    this.clearTransition();
  }
}

<|endoftext|>


<commit_before>/**
 * Copyright (c) 2012, Martin Borho.
 * Licensed under the Affero General Public License version 3 or later.
 * See LICENSE for details.
 */
var nconf = require('nconf')
    , lib = require('../lib')
    , express = require('express')
    , socket_io = require('socket.io')
    , passport = require('passport')
    , request = require('request')
    , LocalStrategy = require('passport-local').Strategy
    , sessionStore = new express.session.MemoryStore({ reapInterval: 60000 * 10 })
    , parseCookie = require('connect').utils.parseCookie
    , sanitize = require('validator').sanitize
    , _base_path = __dirname+'/..';

nconf.use('file', { file: _base_path+'/config.json' });
nconf.load();

// db connection
var db = lib.storage.getDb(nconf.get('db'))

// libs and services
if(nconf.get('twitter:enabled')) {
    var twit = new lib.twitter.Twitter(nconf.get('twitter'), db);
    twit.userstream(nconf.get('twitter:user'));
}

if(nconf.get('superfeedr:enabled')) {
    lib.superfeedr.listen(db, nconf.get('superfeedr'));
}

if(nconf.get('poller:enabled')) {
    var poller = new lib.Poller(db);
    poller.start();
}

var connector = new lib.connector.Connector(db);

var app = express.createServer();
var io = socket_io.listen(app);
io.set('log level', 2)
var _SOCKET_ENDPOINT = '';

passport.use(new LocalStrategy(
    function(username, password, done) {
        if(username == nconf.get('app:user') && password == nconf.get('app:password')) {
            return done(null, {id: username});
        } else {
            return done(null, false);
        }
    }
));

passport.serializeUser(function(user, done) {
    done(null, user.id);
});

passport.deserializeUser(function(id, done) {
//   User.findOne(id, function (err, user) {
    done(null,  {id: id});
//   });
});

function checkSession(req, res, next) {
    if(req.user !== undefined) {
        next();
        return;
    }
    res.writeHead(301, {'Location':'/login'});
    res.end();
}

function checkAjaxSession(req, res, next) {
    if(req.user !== undefined) {
        next();
        return;
    }
    console.log('AJAX UNAUTHORIZED');
    res.writeHead(401);
    res.end();
}

// express configuration
app.configure(function() {
    app.use(express.static(_base_path + '/lib/static'));
    app.set('views', _base_path + '/lib/views');
    app.set('view engine', 'ejs');
    app.use(express.cookieParser());
    app.use(express.bodyParser());
    app.use(express.session({store: sessionStore, secret: 'keyboard cat' }));
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(app.router);
    //app.use(basic_auth);
});

// routes
app.get('/login', function(req, res){
    res.render('login', {layout: false});
});

app.post('/login',
  passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login' })
);

app.get('/logout', function(req, res){
  req.logOut();
  res.redirect('/');
});

app.get('/', checkSession,  function(req, res){
    res.render('index', {locals: {
        title: 'Silozippr',
        docs: false,//docs,
        socket_endpoint: _SOCKET_ENDPOINT
    }});
});

app.get('/api/list/docs', checkAjaxSession, function(req, res){
    var skey = (req.query["id"]) ? sanitize(req.query["id"]).xss() : false;
    var startkey = (req.query["startkey"]) ? sanitize(req.query["startkey"]).xss() : false;
    if(skey && skey !== "") {
        connector.get_source_docs(res, skey, startkey);
    } else {
        connector.get_index_docs(res, startkey);
    }
});

app.get('/api/source/clear', checkAjaxSession, function(req, res) {
    var skey = (req.query["id"]) ? sanitize(req.query["id"]).xss() : false;
    if(skey) connector.clear_source(res, skey);
});

app.get('/api/toc/get', checkAjaxSession, function(req, res) {
    var skey = (req.query["id"]) ? sanitize(req.query["id"]).xss() : false;
    connector.get_toc(res, skey);
});

app.post('/api/subs/add', checkAjaxSession, function(req, res) {
    connector.add_sub(req, res, nconf.get('superfeedr:enabled'));
});

app.post('/api/subs/remove', checkAjaxSession, function(req, res) {
    connector.remove_sub(req, res, nconf.get('superfeedr:enabled'));
});

app.get('/api/subs/list', checkAjaxSession, function(req, res) {
    connector.get_subs(req, res);
});

app.post('/api/tweet', checkAjaxSession, function(req, res) {
    var text = (req.body.text) ? sanitize(req.body.text).xss() : false;
    if(text && twit !== undefined) {
        twit.tweet(res, text);
    } else {
        return res.json({success:false});
    }
});

app.post('/api/retweet', checkAjaxSession, function(req, res) {
    var doc_id = (req.body.id) ? sanitize(req.body.id).xss() : false;
    if(doc_id && twit !== undefined) {
        db.get(doc_id, function(err, doc) {
            if(err || doc.custom === undefined) return res.json({success:false});
            return twit.retweet(res, doc.custom.id);
        });
    } else {
        return res.json({success:false});
    }
});

app.get('/api/url/short', checkAjaxSession, function(req, res) {
    var longurl = (req.query["url"]) ? sanitize(req.query["url"]).xss() : false;
    var api_url = 'http://is.gd/api.php?longurl='+encodeURIComponent(longurl);
    if(longurl) {
        console.log(longurl);
        var api_req = request(api_url, function (error, response, body) {
            if (!error && response.statusCode == 200) {
                res.json({success:true, short: body, long: longurl});
            } else {
                res.json({success:false});
            }
        });
    }
});

io.set('authorization', function (data, accept) {
    var cookies = parseCookie(data.headers.cookie),
        sessionId = cookies['connect.sid'];
    if(!sessionId) {
        console.log('no session id');
        return accept('No session id transmitted.', false);
    } else {
        sessionStore.get(sessionId, function(err, session) {
            if(err) {
                return accept(err, false);
            } else if(session) {
                data.sessionId = sessionId;
                data.user = session.passport.user;
                return accept(null, true);
            }
            return accept('No cookie transmitted.', false);
        });
    }
});

var pipe = io.sockets.on('connection', function (socket) {
    socket.on('removeDoc', function (doc) {
//         console.log(socket.handshake.sessionId+' :: '+socket.handshake.user);
        connector.remove_doc(socket, doc);
    });
    socket.on('removeDocs', function (data) {
        connector.remove_docs(socket, data);
    });
    socket.on('getFeedDocs', function (data) {
        if(data) {
            connector.get_feed_docs(socket, data);
        } else {
            connector.get_index_docs(socket);
        }
    });
});

var initializeStream = function() {
    db.info(function(err, info) {
        var query = {};
        if (err) {
            throw new Error(JSON.stringify(err));
            console.log("error on stream reconnect");
            console.log(JSON.stringify(err));
        }
        console.log("db info fetched");
        query = {
                include_docs:true,
                since:info.update_seq
        }
        console.log("Changes stream starting");
        db.changes(query).on('response', function (res) {
            res.on('data', function (change) {
                console.log("doc received from couchdb");
                if(change.deleted == undefined
                    && (change.doc.type == "newsitem"
                            || change.doc.type == "tweet"
                                    || change.doc.type == "xmpp")) {
                    connector.process_pushed(change.doc, pipe);
                } /*else {
                    pipe.emit('syncDeleted', { doc: change.doc });
                }*/
            });
            res.on('end', function () {
                console.log("Changes stream ended, try restarting");
                initializeStream();
            });
        });
    });
};
initializeStream();

process.on('uncaughtException', function (err) {
  console.log('\n##### Caught exception: ######\n');
  console.log(err);
  console.log('\n#############################\n');
});

app.listen(nconf.get('app:port'), function () {
  var addr = app.address();
  console.log(' app listening on http://' + addr.address + ':' + addr.port);
});
<commit_msg>changed handling if _changes stream reconnection<commit_after>/**
 * Copyright (c) 2012, Martin Borho.
 * Licensed under the Affero General Public License version 3 or later.
 * See LICENSE for details.
 */
var nconf = require('nconf')
    , lib = require('../lib')
    , express = require('express')
    , socket_io = require('socket.io')
    , passport = require('passport')
    , request = require('request')
    , LocalStrategy = require('passport-local').Strategy
    , sessionStore = new express.session.MemoryStore({ reapInterval: 60000 * 10 })
    , parseCookie = require('connect').utils.parseCookie
    , sanitize = require('validator').sanitize
    , _base_path = __dirname+'/..';

nconf.use('file', { file: _base_path+'/config.json' });
nconf.load();

// db connection
var db = lib.storage.getDb(nconf.get('db'))

// libs and services
if(nconf.get('twitter:enabled')) {
    var twit = new lib.twitter.Twitter(nconf.get('twitter'), db);
    twit.userstream(nconf.get('twitter:user'));
}

if(nconf.get('superfeedr:enabled')) {
    lib.superfeedr.listen(db, nconf.get('superfeedr'));
}

if(nconf.get('poller:enabled')) {
    var poller = new lib.Poller(db);
    poller.start();
}

var connector = new lib.connector.Connector(db);

var app = express.createServer();
var io = socket_io.listen(app);
io.set('log level', 2)
var _SOCKET_ENDPOINT = '';

passport.use(new LocalStrategy(
    function(username, password, done) {
        if(username == nconf.get('app:user') && password == nconf.get('app:password')) {
            return done(null, {id: username});
        } else {
            return done(null, false);
        }
    }
));

passport.serializeUser(function(user, done) {
    done(null, user.id);
});

passport.deserializeUser(function(id, done) {
//   User.findOne(id, function (err, user) {
    done(null,  {id: id});
//   });
});

function checkSession(req, res, next) {
    if(req.user !== undefined) {
        next();
        return;
    }
    res.writeHead(301, {'Location':'/login'});
    res.end();
}

function checkAjaxSession(req, res, next) {
    if(req.user !== undefined) {
        next();
        return;
    }
    console.log('AJAX UNAUTHORIZED');
    res.writeHead(401);
    res.end();
}

// express configuration
app.configure(function() {
    app.use(express.static(_base_path + '/lib/static'));
    app.set('views', _base_path + '/lib/views');
    app.set('view engine', 'ejs');
    app.use(express.cookieParser());
    app.use(express.bodyParser());
    app.use(express.session({store: sessionStore, secret: 'keyboard cat' }));
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(app.router);
    //app.use(basic_auth);
});

// routes
app.get('/login', function(req, res){
    res.render('login', {layout: false});
});

app.post('/login',
  passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login' })
);

app.get('/logout', function(req, res){
  req.logOut();
  res.redirect('/');
});

app.get('/', checkSession,  function(req, res){
    res.render('index', {locals: {
        title: 'Silozippr',
        docs: false,//docs,
        socket_endpoint: _SOCKET_ENDPOINT
    }});
});

app.get('/api/list/docs', checkAjaxSession, function(req, res){
    var skey = (req.query["id"]) ? sanitize(req.query["id"]).xss() : false;
    var startkey = (req.query["startkey"]) ? sanitize(req.query["startkey"]).xss() : false;
    if(skey && skey !== "") {
        connector.get_source_docs(res, skey, startkey);
    } else {
        connector.get_index_docs(res, startkey);
    }
});

app.get('/api/source/clear', checkAjaxSession, function(req, res) {
    var skey = (req.query["id"]) ? sanitize(req.query["id"]).xss() : false;
    if(skey) connector.clear_source(res, skey);
});

app.get('/api/toc/get', checkAjaxSession, function(req, res) {
    var skey = (req.query["id"]) ? sanitize(req.query["id"]).xss() : false;
    connector.get_toc(res, skey);
});

app.post('/api/subs/add', checkAjaxSession, function(req, res) {
    connector.add_sub(req, res, nconf.get('superfeedr:enabled'));
});

app.post('/api/subs/remove', checkAjaxSession, function(req, res) {
    connector.remove_sub(req, res, nconf.get('superfeedr:enabled'));
});

app.get('/api/subs/list', checkAjaxSession, function(req, res) {
    connector.get_subs(req, res);
});

app.post('/api/tweet', checkAjaxSession, function(req, res) {
    var text = (req.body.text) ? sanitize(req.body.text).xss() : false;
    if(text && twit !== undefined) {
        twit.tweet(res, text);
    } else {
        return res.json({success:false});
    }
});

app.post('/api/retweet', checkAjaxSession, function(req, res) {
    var doc_id = (req.body.id) ? sanitize(req.body.id).xss() : false;
    if(doc_id && twit !== undefined) {
        db.get(doc_id, function(err, doc) {
            if(err || doc.custom === undefined) return res.json({success:false});
            return twit.retweet(res, doc.custom.id);
        });
    } else {
        return res.json({success:false});
    }
});

app.get('/api/url/short', checkAjaxSession, function(req, res) {
    var longurl = (req.query["url"]) ? sanitize(req.query["url"]).xss() : false;
    var api_url = 'http://is.gd/api.php?longurl='+encodeURIComponent(longurl);
    if(longurl) {
        console.log(longurl);
        var api_req = request(api_url, function (error, response, body) {
            if (!error && response.statusCode == 200) {
                res.json({success:true, short: body, long: longurl});
            } else {
                res.json({success:false});
            }
        });
    }
});

io.set('authorization', function (data, accept) {
    var cookies = parseCookie(data.headers.cookie),
        sessionId = cookies['connect.sid'];
    if(!sessionId) {
        console.log('no session id');
        return accept('No session id transmitted.', false);
    } else {
        sessionStore.get(sessionId, function(err, session) {
            if(err) {
                return accept(err, false);
            } else if(session) {
                data.sessionId = sessionId;
                data.user = session.passport.user;
                return accept(null, true);
            }
            return accept('No cookie transmitted.', false);
        });
    }
});

var pipe = io.sockets.on('connection', function (socket) {
    socket.on('removeDoc', function (doc) {
//         console.log(socket.handshake.sessionId+' :: '+socket.handshake.user);
        connector.remove_doc(socket, doc);
    });
    socket.on('removeDocs', function (data) {
        connector.remove_docs(socket, data);
    });
    socket.on('getFeedDocs', function (data) {
        if(data) {
            connector.get_feed_docs(socket, data);
        } else {
            connector.get_index_docs(socket);
        }
    });
});

var initializeStream = function() {
    db.info(function(err, info) {
        var query = {};
        if (err) {
            throw new Error(JSON.stringify(err));
            console.log("error on stream reconnect");
            console.log(JSON.stringify(err));
        }
        console.log("db info fetched");
        query = {
                include_docs:true,
                since:info.update_seq
        }
        console.log("Changes stream starting");
        db.changes(query).on('response', function (res) {
            res.on('data', function (change) {
                if(change.deleted == undefined
                    && (change.doc.type == "newsitem"
                            || change.doc.type == "tweet"
                                    || change.doc.type == "xmpp")) {
                    connector.process_pushed(change.doc, pipe);
                } /*else {
                    pipe.emit('syncDeleted', { doc: change.doc });
                }*/
            });
            res.on('end', function () {
                console.log("Changes stream ended, try restarting");
                setTimeout(initializeStream, 15000);
            });
        });
    });
};
initializeStream();

process.on('uncaughtException', function (err) {
  console.log('\n##### Caught exception: ######\n');
  console.log(err);
  console.log('\n#############################\n');
});

app.listen(nconf.get('app:port'), function () {
  var addr = app.address();
  console.log(' app listening on http://' + addr.address + ':' + addr.port);
});
<|endoftext|>


<commit_before>import React from "react";
import {
  defaults, assign, keys, isFunction, partialRight, pick, without, isEmpty, defaultsDeep, merge
} from "lodash";
import Events from "./events";
import Collection from "./collection";
import VictoryTransition from "../victory-transition/victory-transition";

//  used for checking state changes. Expected components can be passed in via options
const defaultComponents = [
  { name: "parent", index: "parent" }, { name: "data" }, { name: "labels" }
];

export default (WrappedComponent, options) => {
  return class addEvents extends WrappedComponent {

    componentWillMount() {
      if (isFunction(super.componentWillMount)) {
        super.componentWillMount();
      }
      const getScopedEvents = Events.getScopedEvents.bind(this);
      this.getEvents = partialRight(Events.getEvents.bind(this), getScopedEvents);
      this.getEventState = Events.getEventState.bind(this);
      const calculatedValues = this.getCalculatedValues(this.props);
      this.cacheValues(calculatedValues);
    }

    componentWillReceiveProps(nextProps) {
      const externalEventMutations = nextProps.externalEventMutations;
      if (externalEventMutations) {
        this.externalMutation = Events.getExternalMutations(
          externalEventMutations, this.baseProps, this.state
        );
        this.setState(defaultsDeep({}, this.externalMutation, this.state));
      }
    }

    shouldComponentUpdate(nextProps) {
      const calculatedValues = this.getCalculatedValues(nextProps);
      // re-render without additional checks when component is animated
      if (this.props.animate || this.props.animating) {
        this.cacheValues(calculatedValues);
        return true;
      }
      // check for any state changes triggered by events or shared events
      const calculatedState = this.getStateChanges(nextProps, calculatedValues);
      if (!Collection.areVictoryPropsEqual(this.calculatedState, calculatedState)) {
        this.cacheValues(calculatedValues);
        this.calculatedState = calculatedState;
        return true;
      }

      // check whether props have changed
      if (!Collection.areVictoryPropsEqual(this.props, nextProps)) {
        this.cacheValues(calculatedValues);
        return true;
      }
      return false;
    }

    // compile all state changes from own and parent state. Order doesn't matter, as any state
    // state change should trigger a re-render
    getStateChanges(props, calculatedValues) {
      const { hasEvents, getSharedEventState } = calculatedValues;
      if (!hasEvents) { return {}; }

      options = options || {};
      const components = options.components || defaultComponents;
      return components.map((component) => {
        if (!props.standalone && component.name === "parent") {
           // don't check for changes on parent props for non-standalone components
          return undefined;
        } else {
          return typeof component.index !== "undefined" ?
            this.getState(component.index, component.name, getSharedEventState) :
            calculatedValues.dataKeys.map(
              (key) => this.getState(key, component.name, getSharedEventState)
            );
        }
      }).filter(Boolean);
    }

    getCalculatedValues(props) {
      const { sharedEvents } = props;
      const components = WrappedComponent.expectedComponents;
      const componentEvents = Events.getComponentEvents(props, components);
      const getSharedEventState = sharedEvents && isFunction(sharedEvents.getEventState) ?
        sharedEvents.getEventState : () => undefined;
      const baseProps = this.getBaseProps(props, getSharedEventState);
      const dataKeys = keys(baseProps).filter((key) => key !== "parent");
      const hasEvents = props.events || props.sharedEvents || componentEvents;
      const events = this.getAllEvents(props);
      return {
        componentEvents, getSharedEventState, baseProps, dataKeys, hasEvents, events
      };
    }

    cacheValues(obj) {
      keys(obj).forEach((key) => {
        this[key] = obj[key];
      });
    }

    getBaseProps(props, getSharedEventState) {
      getSharedEventState = getSharedEventState || this.getSharedEventState;
      const sharedParentState = getSharedEventState("parent", "parent");
      const parentState = this.getEventState("parent", "parent");
      const baseParentProps = defaults({}, parentState, sharedParentState);
      const parentPropsList = baseParentProps.parentControlledProps;
      const parentProps = parentPropsList ? pick(baseParentProps, parentPropsList) : {};
      const modifiedProps = defaults({}, parentProps, props);
      return isFunction(WrappedComponent.getBaseProps) ?
        WrappedComponent.getBaseProps(modifiedProps) : {};
    }

    getAllEvents(props) {
      if (Array.isArray(this.componentEvents)) {
        return Array.isArray(props.events) ?
          this.componentEvents.concat(...props.events) : this.componentEvents;
      }
      return props.events;
    }

    getState(key, type, getSharedEventState) {
      getSharedEventState = getSharedEventState || this.getSharedEventState;
      const baseState = defaults(
        {}, this.getEventState(key, type), getSharedEventState(key, type)
      );
      return isEmpty(baseState) ? undefined : baseState;
    }

    getComponentProps(component, type, index) {
      const { role } = WrappedComponent;
      const key = this.dataKeys && this.dataKeys[index] || index;
      const baseProps = this.baseProps[key][type] || this.baseProps[key];
      if (!baseProps && !this.hasEvents) {
        return undefined;
      }
      if (this.hasEvents) {
        const baseEvents = this.getEvents(this.props, type, key);
        const componentProps = defaults(
          { index, key: `${role}-${type}-${key}` },
          this.getEventState(key, type),
          this.getSharedEventState(key, type),
          component.props,
          baseProps
        );
        const events = defaults(
          {}, Events.getPartialEvents(baseEvents, key, componentProps), componentProps.events
        );
        return assign(
          {}, componentProps, { events }
        );
      }
      return defaults(
        { index, key: `${role}-${type}-${key}` },
        component.props,
        baseProps
      );
    }

    renderContainer(component, children) {
      const isContainer = component.type && component.type.role === "container";
      const parentProps = isContainer ? this.getComponentProps(component, "parent", "parent") : {};
      return React.cloneElement(component, parentProps, children);
    }

    animateComponent(props, animationWhitelist) {
      return (
        <VictoryTransition animate={props.animate} animationWhitelist={animationWhitelist}>
          {React.createElement(this.constructor, props)}
        </VictoryTransition>
      );
    }

    // Used by `VictoryLine` and `VictoryArea`
    renderContinuousData(props) {
      const { dataComponent, labelComponent, groupComponent } = props;
      const dataKeys = without(this.dataKeys, "all");
      const labelComponents = dataKeys.reduce((memo, key) => {
        const labelProps = this.getComponentProps(labelComponent, "labels", key);
        if (labelProps && typeof labelProps.text !== "undefined" && labelProps.text !== null) {
          memo = memo.concat(React.cloneElement(labelComponent, labelProps));
        }
        return memo;
      }, []);
      const dataProps = this.getComponentProps(dataComponent, "data", "all");
      const children = [React.cloneElement(dataComponent, dataProps), ...labelComponents];
      return this.renderContainer(groupComponent, children);
    }

    renderData(props) {
      const { dataComponent, labelComponent, groupComponent } = props;
      const dataComponents = this.dataKeys.map((_dataKey, index) => {
        const dataProps = this.getComponentProps(dataComponent, "data", index);
        return React.cloneElement(dataComponent, dataProps);
      });

      const labelComponents = this.dataKeys.map((_dataKey, index) => {
        const labelProps = this.getComponentProps(labelComponent, "labels", index);
        if (typeof labelProps.text !== "undefined" && labelProps.text !== null) {
          return React.cloneElement(labelComponent, labelProps);
        }
        return undefined;
      }).filter(Boolean);

      const children = [...dataComponents, ...labelComponents];
      return this.renderContainer(groupComponent, children);
    }
  };
};
<commit_msg>fix scu logic<commit_after>import React from "react";
import {
  defaults, assign, keys, isFunction, partialRight, pick, without, isEmpty, defaultsDeep, merge
} from "lodash";
import Events from "./events";
import Collection from "./collection";
import VictoryTransition from "../victory-transition/victory-transition";

//  used for checking state changes. Expected components can be passed in via options
const defaultComponents = [
  { name: "parent", index: "parent" }, { name: "data" }, { name: "labels" }
];

export default (WrappedComponent, options) => {
  return class addEvents extends WrappedComponent {

    componentWillMount() {
      if (isFunction(super.componentWillMount)) {
        super.componentWillMount();
      }
      const getScopedEvents = Events.getScopedEvents.bind(this);
      this.getEvents = partialRight(Events.getEvents.bind(this), getScopedEvents);
      this.getEventState = Events.getEventState.bind(this);
      const calculatedValues = this.getCalculatedValues(this.props);
      this.cacheValues(calculatedValues);
    }

    componentWillReceiveProps(nextProps) {
      const { externalEventMutations, sharedEvents } = nextProps;
      if (externalEventMutations && !sharedEvents) {
        this.externalMutation = Events.getExternalMutations(
          externalEventMutations, this.baseProps, this.state
        );
        this.setState(this.externalMutation);
      }
    }

    shouldComponentUpdate(nextProps, nextState) {
      const calculatedValues = this.getCalculatedValues(nextProps);
      // re-render without additional checks when component is animated
      if (this.props.animate || this.props.animating) {
        this.cacheValues(calculatedValues);
        return true;
      }

      // check for any state changes triggered by events or shared events
      const calculatedState = this.getStateChanges(nextProps, calculatedValues);
      if (!Collection.areVictoryPropsEqual(this.calculatedState, calculatedState)) {
        this.cacheValues(calculatedValues);
        this.calculatedState = calculatedState;
        return true;
      }

      // check whether props have changed
      if (!Collection.areVictoryPropsEqual(this.props, nextProps)) {
        this.cacheValues(calculatedValues);
        return true;
      }

      // check whether state has changed
      if (!Collection.areVictoryPropsEqual(this.state, nextState)) {
        this.cacheValues(calculatedValues);
        return true;
      }

      return false;
    }

    // compile all state changes from own and parent state. Order doesn't matter, as any state
    // state change should trigger a re-render
    getStateChanges(props, calculatedValues) {
      const { hasEvents, getSharedEventState } = calculatedValues;
      if (!hasEvents) { return {}; }

      options = options || {};
      const components = options.components || defaultComponents;
      return components.map((component) => {
        if (!props.standalone && component.name === "parent") {
           // don't check for changes on parent props for non-standalone components
          return undefined;
        } else {
          return typeof component.index !== "undefined" ?
            this.getState(component.index, component.name, getSharedEventState) :
            calculatedValues.dataKeys.map(
              (key) => this.getState(key, component.name, getSharedEventState)
            );
        }
      }).filter(Boolean);
    }

    getCalculatedValues(props) {
      const { sharedEvents } = props;
      const components = WrappedComponent.expectedComponents;
      const componentEvents = Events.getComponentEvents(props, components);
      const getSharedEventState = sharedEvents && isFunction(sharedEvents.getEventState) ?
        sharedEvents.getEventState : () => undefined;
      const baseProps = this.getBaseProps(props, getSharedEventState);
      const dataKeys = keys(baseProps).filter((key) => key !== "parent");
      const hasEvents = props.events || props.sharedEvents || componentEvents;
      const events = this.getAllEvents(props);
      return {
        componentEvents, getSharedEventState, baseProps, dataKeys, hasEvents, events
      };
    }

    cacheValues(obj) {
      keys(obj).forEach((key) => {
        this[key] = obj[key];
      });
    }

    getBaseProps(props, getSharedEventState) {
      getSharedEventState = getSharedEventState || this.getSharedEventState;
      const sharedParentState = getSharedEventState("parent", "parent");
      const parentState = this.getEventState("parent", "parent");
      const baseParentProps = defaults({}, parentState, sharedParentState);
      const parentPropsList = baseParentProps.parentControlledProps;
      const parentProps = parentPropsList ? pick(baseParentProps, parentPropsList) : {};
      const modifiedProps = defaults({}, parentProps, props);
      return isFunction(WrappedComponent.getBaseProps) ?
        WrappedComponent.getBaseProps(modifiedProps) : {};
    }

    getAllEvents(props) {
      if (Array.isArray(this.componentEvents)) {
        return Array.isArray(props.events) ?
          this.componentEvents.concat(...props.events) : this.componentEvents;
      }
      return props.events;
    }

    getState(key, type, getSharedEventState) {
      getSharedEventState = getSharedEventState || this.getSharedEventState;
      const baseState = defaults(
        {}, this.getEventState(key, type), getSharedEventState(key, type)
      );
      return isEmpty(baseState) ? undefined : baseState;
    }

    getComponentProps(component, type, index) {
      const { role } = WrappedComponent;
      const key = this.dataKeys && this.dataKeys[index] || index;
      const baseProps = this.baseProps[key][type] || this.baseProps[key];
      if (!baseProps && !this.hasEvents) {
        return undefined;
      }
      if (this.hasEvents) {
        const baseEvents = this.getEvents(this.props, type, key);
        const componentProps = defaults(
          { index, key: `${role}-${type}-${key}` },
          this.getEventState(key, type),
          this.getSharedEventState(key, type),
          component.props,
          baseProps
        );
        const events = defaults(
          {}, Events.getPartialEvents(baseEvents, key, componentProps), componentProps.events
        );
        return assign(
          {}, componentProps, { events }
        );
      }
      return defaults(
        { index, key: `${role}-${type}-${key}` },
        component.props,
        baseProps
      );
    }

    renderContainer(component, children) {
      const isContainer = component.type && component.type.role === "container";
      const parentProps = isContainer ? this.getComponentProps(component, "parent", "parent") : {};
      return React.cloneElement(component, parentProps, children);
    }

    animateComponent(props, animationWhitelist) {
      return (
        <VictoryTransition animate={props.animate} animationWhitelist={animationWhitelist}>
          {React.createElement(this.constructor, props)}
        </VictoryTransition>
      );
    }

    // Used by `VictoryLine` and `VictoryArea`
    renderContinuousData(props) {
      const { dataComponent, labelComponent, groupComponent } = props;
      const dataKeys = without(this.dataKeys, "all");
      const labelComponents = dataKeys.reduce((memo, key) => {
        const labelProps = this.getComponentProps(labelComponent, "labels", key);
        if (labelProps && typeof labelProps.text !== "undefined" && labelProps.text !== null) {
          memo = memo.concat(React.cloneElement(labelComponent, labelProps));
        }
        return memo;
      }, []);
      const dataProps = this.getComponentProps(dataComponent, "data", "all");
      const children = [React.cloneElement(dataComponent, dataProps), ...labelComponents];
      return this.renderContainer(groupComponent, children);
    }

    renderData(props) {
      const { dataComponent, labelComponent, groupComponent } = props;
      const dataComponents = this.dataKeys.map((_dataKey, index) => {
        const dataProps = this.getComponentProps(dataComponent, "data", index);
        return React.cloneElement(dataComponent, dataProps);
      });

      const labelComponents = this.dataKeys.map((_dataKey, index) => {
        const labelProps = this.getComponentProps(labelComponent, "labels", index);
        if (typeof labelProps.text !== "undefined" && labelProps.text !== null) {
          return React.cloneElement(labelComponent, labelProps);
        }
        return undefined;
      }).filter(Boolean);

      const children = [...dataComponents, ...labelComponents];
      return this.renderContainer(groupComponent, children);
    }
  };
};
<|endoftext|>


<commit_before>var express = require('express');
var http = require('http');
var path = require('path');
var util = require('util');

var auth = require('../lib/auth.js');
var conf = require('../lib/config.js');
var connections = require('../lib/connections.js');
var db = require('../lib/db.js');
var error = require('../lib/error.js');
var msgid = require('../lib/msgid.js');
var Subscriber = require('../lib/subscriber.js').Subscriber;

function stringOrNull(arg) {
  if (arg == null)
    return null;
  return String(arg);
}

function sendError(res, err) {
  if (err instanceof error.UserError) {
    // Blegh.
    if (err.code == 401)
      res.set('WWW-Authenticate', 'Bearer');
    res.send(err.code, err.msg);
  } else {
    res.send(500);
  }
}

var subscriber = new Subscriber();

var app = express();

app.use(express.bodyParser());
// CORS ALL THE THINGS. We won't use cookies and this is different
// from Access-Control-Allow-Credentials. So we're fine.
app.use(function(req, res, next) {
  res.set('Access-Control-Allow-Origin', '*');
  next();
});

function requireUser(req, res, next) {
  // IE9 CORS (really XDomainRequest) doesn't allow custom headers.
  // And even with CORS, an Authorization header would require a
  // preflight. Allow passing the token in the query string. Google
  // does this for their APIs.
  //
  // TODO(davidben): Allow passing it into the Authorization header
  // anyway. Non-browser clients might appreciate a more HTTP-like
  // header. Google uses
  //
  //   Authorization: Bearer ${token}
  //
  // which seems sane enough. But to be Proper, I ought to look up
  // exactly how to parse those.
  //
  // See http://self-issued.info/docs/draft-ietf-oauth-v2-bearer.html
  var token = req.query.access_token;
  if (!token) {
    // Appease the HTTP gods who say you need a WWW-Authenticate
    // header when you send back 401. Hopefully this'll prevent a
    // browser prompt. They're bad about not prompting...
    res.set('WWW-Authenticate', 'Bearer');
    res.send(401, 'Auth token required');
    return;
  }
  auth.checkAuthToken(token).then(function(user) {
    req.user = user;
    next();
  }, function(err) {
    sendError(res, err);
    console.error(err);
  });
}

app.post('/api/v1/auth', function(req, res) {
  // TODO(davidben): Real authentication!
  var principal = req.body.principal;
  if (typeof principal !== "string") {
    res.send(400, 'Principal expected');
    return;
  }
  db.getUser(principal).then(function(user) {
    var token = auth.makeAuthToken(user);
    res.set('Content-Type', 'text/plain');
    res.send(200, token);
  }, function(err) {
    sendError(res, err);
    console.error(err);
  }).done();
});

app.get('/api/v1/ping', requireUser, function(req, res) {
  res.json(200, { pong: 1 });
});

app.get('/api/v1/subscriptions', requireUser, function(req, res) {
  db.getUserSubscriptions(req.user).then(function(subs) {
    res.json(200, subs);
  }, function(err) {
    sendError(res, err);
    console.error(err);
  }).done();
});

function isValidSub(sub) {
  if (typeof sub !== "object")
    return false;
  if (typeof sub.class !== 'string')
    return false;
  if (sub.instance !== null && typeof sub.instance !== 'string')
    return false;
  if (typeof sub.recipient !== 'string')
    return false;
  return true;
}

app.post('/api/v1/subscribe', requireUser, function(req, res) {
  if (!isValidSub(req.body.subscription)) {
    // TODO(davidben): Nicer error message.
    res.send(400, 'Subscription triple expected');
    return;
  }
  subscriber.addUserSubscription(
    req.user, req.body.subscription, req.body.credentials
  ).then(function(sub) {
    res.json(200, sub);
  }, function(err) {
    sendError(res, err);
    console.error(err);
  }).done();
});

app.post('/api/v1/unsubscribe', requireUser, function(req, res) {
  if (!isValidSub(req.body.subscription)) {
    // TODO(davidben): Nicer error message.
    res.send(400, 'Subscription triple expected');
    return;
  }
  subscriber.removeUserSubscription(
    req.user,
    req.body.subscription
  ).then(function() {
    res.json(200, { unsubscribed: true });
  }, function(err) {
    sendError(res, err);
    console.error(err);
  }).done();
});

app.get('/api/v1/messages', requireUser, function(req, res) {
  var offset = stringOrNull(req.query.offset);
  if (offset) {
    offset = msgid.unseal(offset);
  } else {
    // Punt the empty string too.
    offset = null;
  }
  db.getMessages(
    req.user, stringOrNull(offset), {
      inclusive: Boolean(req.query.inclusive|0),
      reverse: Boolean(req.query.reverse|0),
      limit: req.query.count|0
    }
  ).then(function(result) {
    result.messages.forEach(function(msg) {
      msg.id = msgid.seal(msg.id);
    });
    res.json(200, result);
  }, function(err) {
    sendError(res, err);
    console.error(err);
  }).done();
});

app.use(express.static(path.join(__dirname, '../static')));

var server = http.createServer(app);
var connectionManager = connections.listen(server, subscriber);

// Load active subscriptions from the database.
console.log('Starting subscriber...');
subscriber.start().then(function() {
  // And now we're ready to start doing things.
  console.log('...started');
  server.listen(conf.get('port'), conf.get('ip'), function() {
    var addy = server.address();
    console.log('running on http://' + addy.address + ":" + addy.port);
  });
}).done();

// Cancel subscriptions on exit.
['SIGINT', 'SIGQUIT', 'SIGTERM'].forEach(function(sig) {
  process.on(sig, function() {
    console.log('Canceling subscriptions...');
    subscriber.shutdown().then(function() {
      console.log('Bye');
      process.exit();
    }).done();
  });
});
<commit_msg>Simplify some code<commit_after>var express = require('express');
var http = require('http');
var path = require('path');
var util = require('util');

var auth = require('../lib/auth.js');
var conf = require('../lib/config.js');
var connections = require('../lib/connections.js');
var db = require('../lib/db.js');
var error = require('../lib/error.js');
var msgid = require('../lib/msgid.js');
var Subscriber = require('../lib/subscriber.js').Subscriber;

function sendError(res, err) {
  if (err instanceof error.UserError) {
    // Blegh.
    if (err.code == 401)
      res.set('WWW-Authenticate', 'Bearer');
    res.send(err.code, err.msg);
  } else {
    res.send(500);
  }
}

var subscriber = new Subscriber();

var app = express();

app.use(express.bodyParser());
// CORS ALL THE THINGS. We won't use cookies and this is different
// from Access-Control-Allow-Credentials. So we're fine.
app.use(function(req, res, next) {
  res.set('Access-Control-Allow-Origin', '*');
  next();
});

function requireUser(req, res, next) {
  // IE9 CORS (really XDomainRequest) doesn't allow custom headers.
  // And even with CORS, an Authorization header would require a
  // preflight. Allow passing the token in the query string. Google
  // does this for their APIs.
  //
  // TODO(davidben): Allow passing it into the Authorization header
  // anyway. Non-browser clients might appreciate a more HTTP-like
  // header. Google uses
  //
  //   Authorization: Bearer ${token}
  //
  // which seems sane enough. But to be Proper, I ought to look up
  // exactly how to parse those.
  //
  // See http://self-issued.info/docs/draft-ietf-oauth-v2-bearer.html
  var token = req.query.access_token;
  if (!token) {
    // Appease the HTTP gods who say you need a WWW-Authenticate
    // header when you send back 401. Hopefully this'll prevent a
    // browser prompt. They're bad about not prompting...
    res.set('WWW-Authenticate', 'Bearer');
    res.send(401, 'Auth token required');
    return;
  }
  auth.checkAuthToken(token).then(function(user) {
    req.user = user;
    next();
  }, function(err) {
    sendError(res, err);
    console.error(err);
  });
}

app.post('/api/v1/auth', function(req, res) {
  // TODO(davidben): Real authentication!
  var principal = req.body.principal;
  if (typeof principal !== "string") {
    res.send(400, 'Principal expected');
    return;
  }
  db.getUser(principal).then(function(user) {
    var token = auth.makeAuthToken(user);
    res.set('Content-Type', 'text/plain');
    res.send(200, token);
  }, function(err) {
    sendError(res, err);
    console.error(err);
  }).done();
});

app.get('/api/v1/ping', requireUser, function(req, res) {
  res.json(200, { pong: 1 });
});

app.get('/api/v1/subscriptions', requireUser, function(req, res) {
  db.getUserSubscriptions(req.user).then(function(subs) {
    res.json(200, subs);
  }, function(err) {
    sendError(res, err);
    console.error(err);
  }).done();
});

function isValidSub(sub) {
  if (typeof sub !== "object")
    return false;
  if (typeof sub.class !== 'string')
    return false;
  if (sub.instance !== null && typeof sub.instance !== 'string')
    return false;
  if (typeof sub.recipient !== 'string')
    return false;
  return true;
}

app.post('/api/v1/subscribe', requireUser, function(req, res) {
  if (!isValidSub(req.body.subscription)) {
    // TODO(davidben): Nicer error message.
    res.send(400, 'Subscription triple expected');
    return;
  }
  subscriber.addUserSubscription(
    req.user, req.body.subscription, req.body.credentials
  ).then(function(sub) {
    res.json(200, sub);
  }, function(err) {
    sendError(res, err);
    console.error(err);
  }).done();
});

app.post('/api/v1/unsubscribe', requireUser, function(req, res) {
  if (!isValidSub(req.body.subscription)) {
    // TODO(davidben): Nicer error message.
    res.send(400, 'Subscription triple expected');
    return;
  }
  subscriber.removeUserSubscription(
    req.user,
    req.body.subscription
  ).then(function() {
    res.json(200, { unsubscribed: true });
  }, function(err) {
    sendError(res, err);
    console.error(err);
  }).done();
});

app.get('/api/v1/messages', requireUser, function(req, res) {
  var offset = req.query.offset;
  if (offset) {
    offset = msgid.unseal(offset);
  } else {
    // Punt the empty string too.
    offset = null;
  }
  db.getMessages(
    req.user, offset, {
      inclusive: Boolean(req.query.inclusive|0),
      reverse: Boolean(req.query.reverse|0),
      limit: req.query.count|0
    }
  ).then(function(result) {
    result.messages.forEach(function(msg) {
      msg.id = msgid.seal(msg.id);
    });
    res.json(200, result);
  }, function(err) {
    sendError(res, err);
    console.error(err);
  }).done();
});

app.use(express.static(path.join(__dirname, '../static')));

var server = http.createServer(app);
var connectionManager = connections.listen(server, subscriber);

// Load active subscriptions from the database.
console.log('Starting subscriber...');
subscriber.start().then(function() {
  // And now we're ready to start doing things.
  console.log('...started');
  server.listen(conf.get('port'), conf.get('ip'), function() {
    var addy = server.address();
    console.log('running on http://' + addy.address + ":" + addy.port);
  });
}).done();

// Cancel subscriptions on exit.
['SIGINT', 'SIGQUIT', 'SIGTERM'].forEach(function(sig) {
  process.on(sig, function() {
    console.log('Canceling subscriptions...');
    subscriber.shutdown().then(function() {
      console.log('Bye');
      process.exit();
    }).done();
  });
});
<|endoftext|>