<commit_before>/*
This file is part of the Juju GUI, which lets users view and manage Juju
environments within a graphical interface (https://launchpad.net/juju-gui).
Copyright (C) 2012-2013 Canonical Ltd.

This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License version 3, as published by
the Free Software Foundation.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero
General Public License for more details.

You should have received a copy of the GNU Affero General Public License along
with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

'use strict';

describe('Inspector Constraints', function() {
  var container, env, inspector, juju, models, utils, view, views, Y, viewUtils;

  // Create a service model instance.
  var makeService = function(db) {
    var charmId = 'precise/django-42';
    db.charms.add({id: charmId, config: {}});
    var service = db.services.add({id: 'django', charm: charmId});
    db.onDelta({data: {result: [
      ['unit', 'add', {id: 'django/0', agent_state: 'pending'}]
    ]}});
    return service;
  };

  // Create a service inspector.
  var makeInspector = function(environmentView, service) {
    Y.Node.create('
').appendTo(container);
    inspector = environmentView.createServiceInspector(service,
        {databinding: {interval: 0}});
    return inspector;
  };

  // Create a fake response from the juju-core API server.
  var makeResponse = function(service, error) {
    var response = {RequestId: 1};
    if (error) {
      response.Error = 'bad wolf';
    } else {
      response.Response = {};
    }
    return response;
  };

  // Retrieve and return the constraints viewlet.
  var getViewlet = function(inspector) {
    return inspector.viewletManager.views.constraints;
  };

  // Change the value of the given key in the constraints form.
  // Return the corresponding node.
  var changeForm = function(viewlet, key, value) {
    var selector = 'input[name=' + key + '].constraint-field';
    var node = viewlet.container.one(selector);
    node.set('value', value);
    // Trigger bindingEngine to notice change.
    var bindingEngine = inspector.viewletManager.bindingEngine;
    bindingEngine._nodeChanged(node, viewlet);
    return node;
  };

  before(function(done) {
    var requirements = ['juju-gui', 'juju-tests-utils', 'juju-views',
      'node-event-simulate', 'juju-charm-store', 'juju-charm-models'];
    Y = YUI(GlobalConfig).use(requirements, function(Y) {
      juju = Y.namespace('juju');
      models = Y.namespace('juju.models');
      utils = Y.namespace('juju-tests.utils');
      views = Y.namespace('juju.views');
      viewUtils = Y.namespace('juju.views.utils');
      done();
    });
  });

  beforeEach(function(done) {
    container = utils.makeContainer(this, 'container');
    var conn = new utils.SocketStub();
    var db = new models.Database();
    var service = makeService(db);
    var fakeStore = new Y.juju.charmworld.APIv3({});
    fakeStore.iconpath = function() {
      return 'charm icon url';
    };
    env = juju.newEnvironment({conn: conn});
    env.update_annotations = function() {};
    env.connect();
    view = new views.environment({
      container: container,
      db: db,
      env: env,
      store: fakeStore
    });
    view.render();
    inspector = makeInspector(view, service);
    done();
  });

  afterEach(function(done) {
    delete view.inspector;
    view.destroy();
    env.after('destroy', function() { done(); });
    env.destroy();
  });

  it('renders the constraints form correctly', function() {
    assert.notEqual(
        0, env.genericConstraints.length, 'no generic constraints found');
    Y.Array.each(env.genericConstraints, function(key) {
      var node = container.one('input[name=' + key + '].constraint-field');
      assert.isNotNull(node, key + ' node not found');
    });
  });

  it('renders the values as empty strings when undefined', function() {
    inspector.model.set('constraints', {});
    Y.Array.each(env.genericConstraints, function(key) {
      var node = container.one('input[name=' + key + '].constraint-field');
      assert.strictEqual('', node.get('value'));
    });
  });

  it('renders the constraint titles correctly', function() {
    var constraintDescriptions = viewUtils.constraintDescriptions;

    Y.Array.each(env.genericConstraints, function(key) {
      var node = container.one('label[for=' + key + ']');
      var expectedTitle = constraintDescriptions[key].title;
      assert.strictEqual(expectedTitle, node.getHTML());
    });
  });

  it('renders initial service constraints', function() {
    var constraints = {arch: 'lcars', cpu: 'quantum'};
    inspector.model.set('constraints', constraints);
    inspector.render();
    Y.Object.each(constraints, function(value, key) {
      var node = container.one('input[name=' + key + '].constraint-field');
      assert.strictEqual(value, node.get('value'));
    });
  });

  it('binds service constraints', function() {
    Y.Array.each(env.genericConstraints, function(key) {
      var node = container.one('input[name=' + key + '].constraint-field');
      var expected = 'constraints.' + key;
      assert.strictEqual(expected, node.getData('bind'));
    });
  });

  it('can save constraints', function() {
    var expected = {arch: 'amd64', 'cpu-power': 100, mem: 4};
    // Change values in the form.
    Y.Object.each(expected, function(value, key) {
      var node = container.one('input[name=' + key + '].constraint-field');
      node.set('value', value);
    });
    // Save the changes.
    var saveButton = container.one('button.save-constraints');
    saveButton.simulate('click');
    var lastMessage = env.ws.last_message();
    // The set_constraint API method is correctly called.
    assert.equal('SetServiceConstraints', lastMessage.Request);
    // The expected constraints are passed in the API call.
    assert.deepEqual(expected, lastMessage.Params.Constraints);
  });

  it('handles error responses from the environment', function() {
    var saveButton = container.one('button.save-constraints');
    saveButton.simulate('click');
    env.ws.msg(makeResponse(inspector.model, true));
    var db = inspector.viewletManager.get('db');
    // An error response generates a notification.
    assert.strictEqual(1, db.notifications.size());
    var msg = db.notifications.item(0);
    assert.strictEqual('error', msg.get('level'));
    assert.strictEqual('Error setting service constraints', msg.get('title'));
    var serviceName = inspector.model.get('id');
    assert.strictEqual('Service name: ' + serviceName, msg.get('message'));
  });

  it('handles success responses from the environment', function() {
    var viewlet = getViewlet(inspector);
    changeForm(viewlet, 'arch', 'i386');
    var saveButton = container.one('button.save-constraints');
    saveButton.simulate('click');
    env.ws.msg(makeResponse(inspector.model, false));
    var input = container.one('input[name=arch].constraint-field');
    assert.isTrue(input.hasClass('change-saved'));
  });

  it('disables and re-enables the save button during the process', function() {
    var saveButton = container.one('button.save-constraints');
    assert.isFalse(saveButton.get('disabled'));
    saveButton.simulate('click');
    assert.isTrue(saveButton.get('disabled'));
    env.ws.msg(makeResponse(inspector.model));
    assert.isFalse(saveButton.get('disabled'));
  });

  it('clears changed values on save', function() {
    var viewlet = getViewlet(inspector);
    changeForm(viewlet, 'arch', 'i386');
    assert.lengthOf(Object.keys(viewlet.changedValues), 1);
    var saveButton = container.one('button.save-constraints');
    assert.equal(saveButton.getHTML(), 'Confirm');
    saveButton.simulate('click');
    env.ws.msg(makeResponse(inspector.model, false));
    assert.lengthOf(
        Object.keys(viewlet.changedValues),
        0,
        'changedValues is not empty after a save.');
    // There was an odd bug that caused this assertion to fail at one point.
    assert.equal(saveButton.getHTML(), 'Confirm');
  });

  it('shows and hides save controls appropriately', function() {
    var viewlet = getViewlet(inspector);
    var controls = container.one('.settings-constraints .controls');
    // Controls are hidden initially.
    assert.isTrue(controls.hasClass('closed'));
    // When the user changes a value, controls appear.
    changeForm(viewlet, 'arch', 'i386');
    assert.isFalse(controls.hasClass('closed'));
    // When the user manually changes back to an original value, controls
    // disappear.
    changeForm(viewlet, 'arch', '');
    assert.isTrue(controls.hasClass('closed'));
    // Controls reappear once again after making the change.
    changeForm(viewlet, 'arch', 'i386');
    assert.isFalse(controls.hasClass('closed'));
    // Saving the model will sync it, and the controls will disappear again.
    var saveButton = container.one('button.save-constraints');
    assert.equal(saveButton.getHTML(), 'Confirm');
    saveButton.simulate('click');
    env.ws.msg(makeResponse(inspector.model, false));
    assert.isTrue(controls.hasClass('closed'));
  });

  it('handles conflicts correctly', function() {
    var viewlet = getViewlet(inspector);
    changeForm(viewlet, 'arch', 'i386');
    inspector.model.set('constraints', {arch: 'lcars'});
    var node = viewlet.container.one('input[data-bind="constraints.arch"]');
    node.simulate('click');
    var wrapper = node.ancestor('.settings-wrapper');
    var option = wrapper.one('.resolver .config-field');
    assert.equal(option.getHTML(), 'lcars');
  });

  it('handles successive conflicts correctly', function() {
    var viewlet = getViewlet(inspector);
    changeForm(viewlet, 'arch', 'i386');
    inspector.model.set('constraints', {arch: 'lcars'});
    // This is the successive change.
    inspector.model.set('constraints', {arch: 'arm64'});
    var node = viewlet.container.one('input[data-bind="constraints.arch"]');
    node.simulate('click');
    var wrapper = node.ancestor('.settings-wrapper');
    var option = wrapper.one('.resolver .config-field');
    assert.equal(option.getHTML(), 'arm64');
  });

  it('can cancel changes', function() {
    // Set up.
    var viewlet = getViewlet(inspector);
    var node = viewlet.container.one('input[data-bind="constraints.arch"]');
    var parentNode = node.ancestor('.settings-wrapper');
    inspector.model.set('constraints', {arch: 'lcars'});
    changeForm(viewlet, 'arch', 'i386');
    assert.equal(
        parentNode.all('.modified').size(),
        1,
        'did not find a modified node');
    // Act.
    viewlet.container.one('button.cancel').simulate('click');
    // Validate.
    assert.equal(node.get('value'), 'lcars');
    // No modified markers are shown.
    // Verify the form is updated.
    assert.equal(
        parentNode.all('.modified').size(),
        0,
        'found a modified node');
  });

  it('can cancel pending conflicts', function() {
    // Set up.
    var viewlet = getViewlet(inspector);
    var node = viewlet.container.one('input[data-bind="constraints.arch"]');
    var parentNode = node.ancestor('.settings-wrapper');
    changeForm(viewlet, 'arch', 'i386');
    inspector.model.set('constraints', {arch: 'lcars'});
    assert.equal(
        parentNode.all('.conflict-pending').size(),
        1,
        'did not find a conflict-pending node');
    // Act.
    viewlet.container.one('button.cancel').simulate('click');
    // Validate.
    assert.equal(node.get('value'), 'lcars');
    // No conflict or modified markers are shown.
    assert.equal(
        parentNode.all('.modified').size(),
        0,
        'found a modified node');
    assert.equal(
        parentNode.all('.conflict-pending').size(),
        0,
        'found a conflict-pending node');
  });

  it('can cancel conflicts that are being resolved', function() {
    // Set up.
    var viewlet = getViewlet(inspector);
    var node = viewlet.container.one('input[data-bind="constraints.arch"]');
    var parentNode = node.ancestor('.settings-wrapper');
    changeForm(viewlet, 'arch', 'i386');
    inspector.model.set('constraints', {arch: 'lcars'});
    node.simulate('click');
    assert.equal(
        parentNode.all('input.conflict').size(),
        1,
        'did not find the conflict node');
    // Act.
    viewlet.container.one('button.cancel').simulate('click');
    // Validate.
    assert.equal(node.get('value'), 'lcars');
    // No conflict or modified markers are shown.
    assert.equal(
        parentNode.all('.modified').size(),
        0,
        'found a modified node');
    assert.equal(
        parentNode.all('.conflict-pending').size(),
        0,
        'found a conflict-pending node');
    assert.equal(
        parentNode.all('input.conflict').size(),
        0,
        'found the conflict node');
  });

});
<commit_msg>Fixed failing inspector constraints tests from viewlet to view changeover.<commit_after>/*
This file is part of the Juju GUI, which lets users view and manage Juju
environments within a graphical interface (https://launchpad.net/juju-gui).
Copyright (C) 2012-2013 Canonical Ltd.

This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License version 3, as published by
the Free Software Foundation.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero
General Public License for more details.

You should have received a copy of the GNU Affero General Public License along
with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

'use strict';

describe('Inspector Constraints', function() {
  var container, env, inspector, juju, models, utils, view, views, Y, viewUtils;

  // Create a service model instance.
  var makeService = function(db) {
    var charmId = 'precise/django-42';
    db.charms.add({id: charmId, config: {}});
    var service = db.services.add({id: 'django', charm: charmId});
    db.onDelta({data: {result: [
      ['unit', 'add', {id: 'django/0', agent_state: 'pending'}]
    ]}});
    return service;
  };

  // Create a service inspector.
  var makeInspector = function(environmentView, service) {
    Y.Node.create('
').appendTo(container);
    inspector = environmentView.createServiceInspector(service,
        {databinding: {interval: 0}});
    return inspector;
  };

  // Create a fake response from the juju-core API server.
  var makeResponse = function(service, error) {
    var response = {RequestId: 1};
    if (error) {
      response.Error = 'bad wolf';
    } else {
      response.Response = {};
    }
    return response;
  };

  // Retrieve and return the constraints viewlet.
  var getViewlet = function(inspector) {
    return inspector.viewletManager.views.Constraints;
  };

  // Change the value of the given key in the constraints form.
  // Return the corresponding node.
  var changeForm = function(viewlet, key, value) {
    var selector = 'input[name=' + key + '].constraint-field';
    var node = viewlet.get('container').one(selector);
    node.set('value', value);
    // Trigger bindingEngine to notice change.
    var bindingEngine = inspector.viewletManager.bindingEngine;
    bindingEngine._nodeChanged(node, viewlet);
    return node;
  };

  before(function(done) {
    var requirements = ['juju-gui', 'juju-tests-utils', 'juju-views',
      'node-event-simulate', 'juju-charm-store', 'juju-charm-models'];
    Y = YUI(GlobalConfig).use(requirements, function(Y) {
      juju = Y.namespace('juju');
      models = Y.namespace('juju.models');
      utils = Y.namespace('juju-tests.utils');
      views = Y.namespace('juju.views');
      viewUtils = Y.namespace('juju.views.utils');
      done();
    });
  });

  beforeEach(function(done) {
    container = utils.makeContainer(this, 'container');
    var conn = new utils.SocketStub();
    var db = new models.Database();
    var service = makeService(db);
    var fakeStore = new Y.juju.charmworld.APIv3({});
    fakeStore.iconpath = function() {
      return 'charm icon url';
    };
    env = juju.newEnvironment({conn: conn});
    env.update_annotations = function() {};
    env.connect();
    view = new views.environment({
      container: container,
      db: db,
      env: env,
      store: fakeStore
    });
    view.render();
    inspector = makeInspector(view, service);
    done();
  });

  afterEach(function(done) {
    delete view.inspector;
    view.destroy();
    env.after('destroy', function() { done(); });
    env.destroy();
  });

  it('renders the constraints form correctly', function() {
    assert.notEqual(
        0, env.genericConstraints.length, 'no generic constraints found');
    Y.Array.each(env.genericConstraints, function(key) {
      var node = container.one('input[name=' + key + '].constraint-field');
      assert.isNotNull(node, key + ' node not found');
    });
  });

  it('renders the values as empty strings when undefined', function() {
    inspector.model.set('constraints', {});
    Y.Array.each(env.genericConstraints, function(key) {
      var node = container.one('input[name=' + key + '].constraint-field');
      assert.strictEqual('', node.get('value'));
    });
  });

  it('renders the constraint titles correctly', function() {
    var constraintDescriptions = viewUtils.constraintDescriptions;

    Y.Array.each(env.genericConstraints, function(key) {
      var node = container.one('label[for=' + key + ']');
      var expectedTitle = constraintDescriptions[key].title;
      assert.strictEqual(expectedTitle, node.getHTML());
    });
  });

  it('renders initial service constraints', function() {
    var constraints = {arch: 'lcars', cpu: 'quantum'};
    inspector.model.set('constraints', constraints);
    inspector.render();
    Y.Object.each(constraints, function(value, key) {
      var node = container.one('input[name=' + key + '].constraint-field');
      assert.strictEqual(value, node.get('value'));
    });
  });

  it('binds service constraints', function() {
    Y.Array.each(env.genericConstraints, function(key) {
      var node = container.one('input[name=' + key + '].constraint-field');
      var expected = 'constraints.' + key;
      assert.strictEqual(expected, node.getData('bind'));
    });
  });

  it('can save constraints', function() {
    var expected = {arch: 'amd64', 'cpu-power': 100, mem: 4};
    // Change values in the form.
    Y.Object.each(expected, function(value, key) {
      var node = container.one('input[name=' + key + '].constraint-field');
      node.set('value', value);
    });
    // Save the changes.
    var saveButton = container.one('button.save-constraints');
    saveButton.simulate('click');
    var lastMessage = env.ws.last_message();
    // The set_constraint API method is correctly called.
    assert.equal('SetServiceConstraints', lastMessage.Request);
    // The expected constraints are passed in the API call.
    assert.deepEqual(expected, lastMessage.Params.Constraints);
  });

  it('handles error responses from the environment', function() {
    var saveButton = container.one('button.save-constraints');
    saveButton.simulate('click');
    env.ws.msg(makeResponse(inspector.model, true));
    var db = inspector.viewletManager.get('db');
    // An error response generates a notification.
    assert.strictEqual(1, db.notifications.size());
    var msg = db.notifications.item(0);
    assert.strictEqual('error', msg.get('level'));
    assert.strictEqual('Error setting service constraints', msg.get('title'));
    var serviceName = inspector.model.get('id');
    assert.strictEqual('Service name: ' + serviceName, msg.get('message'));
  });

  it('handles success responses from the environment', function() {
    var viewlet = getViewlet(inspector);
    changeForm(viewlet, 'arch', 'i386');
    var saveButton = container.one('button.save-constraints');
    saveButton.simulate('click');
    env.ws.msg(makeResponse(inspector.model, false));
    var input = container.one('input[name=arch].constraint-field');
    assert.isTrue(input.hasClass('change-saved'));
  });

  it('disables and re-enables the save button during the process', function() {
    var saveButton = container.one('button.save-constraints');
    assert.isFalse(saveButton.get('disabled'));
    saveButton.simulate('click');
    assert.isTrue(saveButton.get('disabled'));
    env.ws.msg(makeResponse(inspector.model));
    assert.isFalse(saveButton.get('disabled'));
  });

  it('clears changed values on save', function() {
    var viewlet = getViewlet(inspector);
    changeForm(viewlet, 'arch', 'i386');
    assert.lengthOf(Object.keys(viewlet.changedValues), 1);
    var saveButton = container.one('button.save-constraints');
    assert.equal(saveButton.getHTML(), 'Confirm');
    saveButton.simulate('click');
    env.ws.msg(makeResponse(inspector.model, false));
    assert.lengthOf(
        Object.keys(viewlet.changedValues),
        0,
        'changedValues is not empty after a save.');
    // There was an odd bug that caused this assertion to fail at one point.
    assert.equal(saveButton.getHTML(), 'Confirm');
  });

  it('shows and hides save controls appropriately', function() {
    var viewlet = getViewlet(inspector);
    var controls = container.one('.settings-constraints .controls');
    // Controls are hidden initially.
    assert.isTrue(controls.hasClass('closed'));
    // When the user changes a value, controls appear.
    changeForm(viewlet, 'arch', 'i386');
    assert.isFalse(controls.hasClass('closed'));
    // When the user manually changes back to an original value, controls
    // disappear.
    changeForm(viewlet, 'arch', '');
    assert.isTrue(controls.hasClass('closed'));
    // Controls reappear once again after making the change.
    changeForm(viewlet, 'arch', 'i386');
    assert.isFalse(controls.hasClass('closed'));
    // Saving the model will sync it, and the controls will disappear again.
    var saveButton = container.one('button.save-constraints');
    assert.equal(saveButton.getHTML(), 'Confirm');
    saveButton.simulate('click');
    env.ws.msg(makeResponse(inspector.model, false));
    assert.isTrue(controls.hasClass('closed'));
  });

  it('handles conflicts correctly', function() {
    var viewlet = getViewlet(inspector);
    changeForm(viewlet, 'arch', 'i386');
    inspector.model.set('constraints', {arch: 'lcars'});
    var node = viewlet.get('container')
                      .one('input[data-bind="constraints.arch"]');
    node.simulate('click');
    var wrapper = node.ancestor('.settings-wrapper');
    var option = wrapper.one('.resolver .config-field');
    assert.equal(option.getHTML(), 'lcars');
  });

  it('handles successive conflicts correctly', function() {
    var viewlet = getViewlet(inspector);
    changeForm(viewlet, 'arch', 'i386');
    inspector.model.set('constraints', {arch: 'lcars'});
    // This is the successive change.
    inspector.model.set('constraints', {arch: 'arm64'});
    var node = viewlet.get('container')
                      .one('input[data-bind="constraints.arch"]');
    node.simulate('click');
    var wrapper = node.ancestor('.settings-wrapper');
    var option = wrapper.one('.resolver .config-field');
    assert.equal(option.getHTML(), 'arm64');
  });

  it('can cancel changes', function() {
    // Set up.
    var viewlet = getViewlet(inspector);
    var node = viewlet.get('container')
                      .one('input[data-bind="constraints.arch"]');
    var parentNode = node.ancestor('.settings-wrapper');
    inspector.model.set('constraints', {arch: 'lcars'});
    changeForm(viewlet, 'arch', 'i386');
    assert.equal(
        parentNode.all('.modified').size(),
        1,
        'did not find a modified node');
    // Act.
    viewlet.get('container').one('button.cancel').simulate('click');
    // Validate.
    assert.equal(node.get('value'), 'lcars');
    // No modified markers are shown.
    // Verify the form is updated.
    assert.equal(
        parentNode.all('.modified').size(),
        0,
        'found a modified node');
  });

  it('can cancel pending conflicts', function() {
    // Set up.
    var viewlet = getViewlet(inspector);
    var node = viewlet.get('container')
                      .one('input[data-bind="constraints.arch"]');
    var parentNode = node.ancestor('.settings-wrapper');
    changeForm(viewlet, 'arch', 'i386');
    inspector.model.set('constraints', {arch: 'lcars'});
    assert.equal(
        parentNode.all('.conflict-pending').size(),
        1,
        'did not find a conflict-pending node');
    // Act.
    viewlet.get('container').one('button.cancel').simulate('click');
    // Validate.
    assert.equal(node.get('value'), 'lcars');
    // No conflict or modified markers are shown.
    assert.equal(
        parentNode.all('.modified').size(),
        0,
        'found a modified node');
    assert.equal(
        parentNode.all('.conflict-pending').size(),
        0,
        'found a conflict-pending node');
  });

  it('can cancel conflicts that are being resolved', function() {
    // Set up.
    var viewlet = getViewlet(inspector);
    var node = viewlet.get('container')
                      .one('input[data-bind="constraints.arch"]');
    var parentNode = node.ancestor('.settings-wrapper');
    changeForm(viewlet, 'arch', 'i386');
    inspector.model.set('constraints', {arch: 'lcars'});
    node.simulate('click');
    assert.equal(
        parentNode.all('input.conflict').size(),
        1,
        'did not find the conflict node');
    // Act.
    viewlet.get('container').one('button.cancel').simulate('click');
    // Validate.
    assert.equal(node.get('value'), 'lcars');
    // No conflict or modified markers are shown.
    assert.equal(
        parentNode.all('.modified').size(),
        0,
        'found a modified node');
    assert.equal(
        parentNode.all('.conflict-pending').size(),
        0,
        'found a conflict-pending node');
    assert.equal(
        parentNode.all('input.conflict').size(),
        0,
        'found the conflict node');
  });

});
<|endoftext|>


<commit_before>/* jshint node:true, expr:true */
'use strict';

var _sinon = require('sinon');
var _chai = require('chai');
_chai.use(require('sinon-chai'));
_chai.use(require('chai-as-promised'));

var expect = _chai.expect;
var _assertionHelper = require('../../lib/assertion-helper');

describe('object', function() {

    var EMPTY_FUNC = function() {
    };

    it('should expose methods required by the interface', function() {
        expect(_assertionHelper).to.have.property('getNotifySuccessHandler').and.to.be.a('function');
        expect(_assertionHelper).to.have.property('getNotifyFailureHandler').and.to.be.a('function');
        expect(_assertionHelper).to.have.property('getDelayedRunner').and.to.be.a('function');
        expect(_assertionHelper).to.have.property('getNotifyFailureHandler').and.to.be.a('function');
        expect(_assertionHelper).to.have.property('getResolver').and.to.be.a('function');
    });

    describe('getNotifySuccessHandler()', function() {
        it('should throw an error if invoked with an invalid done callback', function() {
            var error = 'invalid done callback method specified (arg #1)';

            function createHandler(done) {
                return function() {
                    return _assertionHelper.getNotifySuccessHandler(done);
                }
            }

            expect(createHandler()).to.throw(error);
            expect(createHandler(null)).to.throw(error);
            expect(createHandler('')).to.throw(error);
            expect(createHandler('foo')).to.throw(error);
            expect(createHandler(123)).to.throw(error);
            expect(createHandler(true)).to.throw(error);
            expect(createHandler({})).to.throw(error);
            expect(createHandler([])).to.throw(error);
        });

        it('should return a function when invoked', function() {
            var callback = _assertionHelper.getNotifySuccessHandler(EMPTY_FUNC);

            expect(callback).to.be.a('function');
        });

        it('should invoke the callback with no parameters when the return function is invoked', function() {
            var spy = _sinon.spy();

            var callback = _assertionHelper.getNotifySuccessHandler(spy);

            expect(spy).not.to.have.been.called;
            callback();
            expect(spy).to.have.been.calledOnce.calledWithExactly();
        });
    });

    describe('getNotifyFailureHandler()', function() {
        it('should throw an error if invoked with an invalid done callback', function() {
            var error = 'invalid done callback method specified (arg #1)';

            function createHandler(done) {
                return function() {
                    return _assertionHelper.getNotifyFailureHandler(done);
                }
            }

            expect(createHandler()).to.throw(error);
            expect(createHandler(null)).to.throw(error);
            expect(createHandler('')).to.throw(error);
            expect(createHandler('foo')).to.throw(error);
            expect(createHandler(123)).to.throw(error);
            expect(createHandler(true)).to.throw(error);
            expect(createHandler({})).to.throw(error);
            expect(createHandler([])).to.throw(error);
        });

        it('should return a function when invoked', function() {
            var callback = _assertionHelper.getNotifyFailureHandler(EMPTY_FUNC);

            expect(callback).to.be.a('function');
        });

        it('should invoke the callback with the error object when the return function is invoked', function() {
            var errorMessage = 'something went wrong';
            var spy = _sinon.spy();

            var callback = _assertionHelper.getNotifyFailureHandler(spy);

            expect(spy).not.to.have.been.called;
            callback(errorMessage);
            expect(spy).to.have.been.calledOnce.calledWithExactly(errorMessage);
        });
    });

    describe('getDelayedRunner()', function() {
        it('should throw an error if invoked with an invalid task wrapper', function() {
            var error = 'invalid task wrapper specified (arg #1)';

            function getDelayedRunner(task) {
                return function() {
                    return _assertionHelper.getDelayedRunner(task);
                }
            }

            expect(getDelayedRunner()).to.throw(error);
            expect(getDelayedRunner(null)).to.throw(error);
            expect(getDelayedRunner('')).to.throw(error);
            expect(getDelayedRunner('foo')).to.throw(error);
            expect(getDelayedRunner(123)).to.throw(error);
            expect(getDelayedRunner(true)).to.throw(error);
            expect(getDelayedRunner({})).to.throw(error);
            expect(getDelayedRunner([])).to.throw(error);
        });

        it('should throw an error if invoked with an invalid delay', function() {
            var error = 'invalid delay specified - should be a non negative number (arg #2)';

            function getDelayedRunner(delay) {
                return function() {
                    return _assertionHelper.getDelayedRunner(EMPTY_FUNC, delay);
                }
            }

            expect(getDelayedRunner()).to.throw(error);
            expect(getDelayedRunner(null)).to.throw(error);
            expect(getDelayedRunner('')).to.throw(error);
            expect(getDelayedRunner('foo')).to.throw(error);
            expect(getDelayedRunner(-123)).to.throw(error);
            expect(getDelayedRunner(true)).to.throw(error);
            expect(getDelayedRunner({})).to.throw(error);
            expect(getDelayedRunner([])).to.throw(error);
        });

        it('should return a function when invoked with correct parameters', function() {
            var runner = _assertionHelper.getDelayedRunner(EMPTY_FUNC, 100);

            expect(runner).to.be.a('function');
        });

        it('should return a promise when the runner function is invoked', function() {
            var runner = _assertionHelper.getDelayedRunner(EMPTY_FUNC, 100);
            var ret = runner();

            expect(ret).to.be.a('object');
            expect(ret).to.have.property('then').and.to.be.a('function');
        });

        it('should resolve the promise after a delay when the runner function is invoked with a non erroring task', function(done) {
            var delay = 100;
            var tolerance = 7;
            var runner = _assertionHelper.getDelayedRunner(EMPTY_FUNC, delay);
            var startTime = Date.now();
            var ret = runner();

            expect(ret).to.be.fulfilled.then(function() {
                try{
                    var endTime = Date.now();
                    expect(endTime - startTime).to.be.within(delay, delay + tolerance);
                    done();
                } catch (ex) {
                    done(ex);
                }
            }, function(err) {
                done(err);
            });
        });

        it('should reject the promise after a delay when the runner function is invoked with a erroring task', function(done) {
            var error = 'something went wrong';
            var delay = 100;
            var tolerance = 7;
            var runner = _assertionHelper.getDelayedRunner(function() {
                throw new Error(error);
            }, delay);
            var startTime = Date.now();
            var ret = runner();

            expect(ret).to.be.rejected.then(function() {
                try{
                    var endTime = Date.now();
                    expect(endTime - startTime).to.be.within(delay, delay + tolerance);
                    done();
                } catch (ex) {
                    done(ex);
                }
            }, function(err) {
                done(err);
            });
        });
    });

    describe('getResolver()', function() {

        function _getDeferred() {
            return {
                resolve: _sinon.spy(),
                reject: _sinon.spy()
            };
        }

        it('should throw an error if invoked without a valid deferred object', function() {
            var error = 'invalid deferred object specified for resolver (arg #1)';
            function invokeMethod(def) {
                return function() {
                   _assertionHelper.getResolver(def);
                };
            };

            expect(invokeMethod()).to.throw(error);
            expect(invokeMethod('string')).to.throw(error);
            expect(invokeMethod(123)).to.throw(error);
            expect(invokeMethod(true)).to.throw(error);
            expect(invokeMethod({})).to.throw(error);
            expect(invokeMethod([])).to.throw(error);
        });

        it('should return a function when invoked with a valid deferred object', function() {
            var def = _getDeferred();
            var callback = _assertionHelper.getResolver(def);

            expect(callback).to.be.a('function');
        });

        it('should resolve the deferred with correct arguments if the callback is invoked without an error', function() {
            var def = _getDeferred();
            var arg1 = 'data1';
            var arg2 = 'data2';
            var callback = _assertionHelper.getResolver(def);

            expect(def.resolve).to.not.have.been.called;
            expect(def.reject).to.not.have.been.called;

            callback(null);
            expect(def.resolve).to.have.been.calledWithExactly();
            expect(def.reject).to.not.have.been.called;
            def.resolve.reset();

            callback(null, arg1);
            expect(def.resolve).to.have.been.calledWithExactly(arg1);
            expect(def.reject).to.not.have.been.called;
            def.resolve.reset();

            callback(null, arg1, arg2);
            expect(def.resolve).to.have.been.calledWithExactly(arg1, arg2);
            expect(def.reject).to.not.have.been.called;
            def.resolve.reset();
        });

        it('should resolve the deferred with the specified arguments when the resolveArgs parameter is specified', function() {
            var def = _getDeferred();
            var arg1 = 'data1';
            var arg2 = 'data2';
            var resolveArgs = 'foo';
            var callback = _assertionHelper.getResolver(def, resolveArgs);

            expect(def.resolve).to.not.have.been.called;
            expect(def.reject).to.not.have.been.called;

            callback(null);
            expect(def.resolve).to.have.been.calledWithExactly(resolveArgs);
            expect(def.reject).to.not.have.been.called;
            def.resolve.reset();

            callback(null, arg1);
            expect(def.resolve).to.have.been.calledWithExactly(resolveArgs);
            expect(def.reject).to.not.have.been.called;
            def.resolve.reset();

            callback(null, arg1, arg2);
            expect(def.resolve).to.have.been.calledWithExactly(resolveArgs);
            expect(def.reject).to.not.have.been.called;
            def.resolve.reset();
        });

        it('should reject the deferred with the error if the callback is invoked with an error', function() {
            var def = _getDeferred();
            var error = 'something went wrong';
            var callback = _assertionHelper.getResolver(def);

            expect(def.resolve).to.not.have.been.called;
            expect(def.reject).to.not.have.been.called;

            callback(error);
            expect(def.resolve).to.not.have.been.called;
            expect(def.reject).to.have.been.calledWithExactly(error);
        });
    });
});
<commit_msg>Update tolerance values<commit_after>/* jshint node:true, expr:true */
'use strict';

var _sinon = require('sinon');
var _chai = require('chai');
_chai.use(require('sinon-chai'));
_chai.use(require('chai-as-promised'));

var expect = _chai.expect;
var _assertionHelper = require('../../lib/assertion-helper');

describe('object', function() {

    var EMPTY_FUNC = function() {
    };

    it('should expose methods required by the interface', function() {
        expect(_assertionHelper).to.have.property('getNotifySuccessHandler').and.to.be.a('function');
        expect(_assertionHelper).to.have.property('getNotifyFailureHandler').and.to.be.a('function');
        expect(_assertionHelper).to.have.property('getDelayedRunner').and.to.be.a('function');
        expect(_assertionHelper).to.have.property('getResolver').and.to.be.a('function');
    });

    describe('getNotifySuccessHandler()', function() {
        it('should throw an error if invoked with an invalid done callback', function() {
            var error = 'invalid done callback method specified (arg #1)';

            function createHandler(done) {
                return function() {
                    return _assertionHelper.getNotifySuccessHandler(done);
                }
            }

            expect(createHandler()).to.throw(error);
            expect(createHandler(null)).to.throw(error);
            expect(createHandler('')).to.throw(error);
            expect(createHandler('foo')).to.throw(error);
            expect(createHandler(123)).to.throw(error);
            expect(createHandler(true)).to.throw(error);
            expect(createHandler({})).to.throw(error);
            expect(createHandler([])).to.throw(error);
        });

        it('should return a function when invoked', function() {
            var callback = _assertionHelper.getNotifySuccessHandler(EMPTY_FUNC);

            expect(callback).to.be.a('function');
        });

        it('should invoke the callback with no parameters when the return function is invoked', function() {
            var spy = _sinon.spy();

            var callback = _assertionHelper.getNotifySuccessHandler(spy);

            expect(spy).not.to.have.been.called;
            callback();
            expect(spy).to.have.been.calledOnce.calledWithExactly();
        });
    });

    describe('getNotifyFailureHandler()', function() {
        it('should throw an error if invoked with an invalid done callback', function() {
            var error = 'invalid done callback method specified (arg #1)';

            function createHandler(done) {
                return function() {
                    return _assertionHelper.getNotifyFailureHandler(done);
                }
            }

            expect(createHandler()).to.throw(error);
            expect(createHandler(null)).to.throw(error);
            expect(createHandler('')).to.throw(error);
            expect(createHandler('foo')).to.throw(error);
            expect(createHandler(123)).to.throw(error);
            expect(createHandler(true)).to.throw(error);
            expect(createHandler({})).to.throw(error);
            expect(createHandler([])).to.throw(error);
        });

        it('should return a function when invoked', function() {
            var callback = _assertionHelper.getNotifyFailureHandler(EMPTY_FUNC);

            expect(callback).to.be.a('function');
        });

        it('should invoke the callback with the error object when the return function is invoked', function() {
            var errorMessage = 'something went wrong';
            var spy = _sinon.spy();

            var callback = _assertionHelper.getNotifyFailureHandler(spy);

            expect(spy).not.to.have.been.called;
            callback(errorMessage);
            expect(spy).to.have.been.calledOnce.calledWithExactly(errorMessage);
        });
    });

    describe('getDelayedRunner()', function() {
        it('should throw an error if invoked with an invalid task wrapper', function() {
            var error = 'invalid task wrapper specified (arg #1)';

            function getDelayedRunner(task) {
                return function() {
                    return _assertionHelper.getDelayedRunner(task);
                }
            }

            expect(getDelayedRunner()).to.throw(error);
            expect(getDelayedRunner(null)).to.throw(error);
            expect(getDelayedRunner('')).to.throw(error);
            expect(getDelayedRunner('foo')).to.throw(error);
            expect(getDelayedRunner(123)).to.throw(error);
            expect(getDelayedRunner(true)).to.throw(error);
            expect(getDelayedRunner({})).to.throw(error);
            expect(getDelayedRunner([])).to.throw(error);
        });

        it('should throw an error if invoked with an invalid delay', function() {
            var error = 'invalid delay specified - should be a non negative number (arg #2)';

            function getDelayedRunner(delay) {
                return function() {
                    return _assertionHelper.getDelayedRunner(EMPTY_FUNC, delay);
                }
            }

            expect(getDelayedRunner()).to.throw(error);
            expect(getDelayedRunner(null)).to.throw(error);
            expect(getDelayedRunner('')).to.throw(error);
            expect(getDelayedRunner('foo')).to.throw(error);
            expect(getDelayedRunner(-123)).to.throw(error);
            expect(getDelayedRunner(true)).to.throw(error);
            expect(getDelayedRunner({})).to.throw(error);
            expect(getDelayedRunner([])).to.throw(error);
        });

        it('should return a function when invoked with correct parameters', function() {
            var runner = _assertionHelper.getDelayedRunner(EMPTY_FUNC, 100);

            expect(runner).to.be.a('function');
        });

        it('should return a promise when the runner function is invoked', function() {
            var runner = _assertionHelper.getDelayedRunner(EMPTY_FUNC, 100);
            var ret = runner();

            expect(ret).to.be.a('object');
            expect(ret).to.have.property('then').and.to.be.a('function');
        });

        it('should resolve the promise after a delay when the runner function is invoked with a non erroring task', function(done) {
            var delay = 100;
            var tolerance = 10;
            var runner = _assertionHelper.getDelayedRunner(EMPTY_FUNC, delay);
            var startTime = Date.now();
            var ret = runner();

            expect(ret).to.be.fulfilled.then(function() {
                try{
                    var endTime = Date.now();
                    expect(endTime - startTime).to.be.within(delay, delay + tolerance);
                    done();
                } catch (ex) {
                    done(ex);
                }
            }, function(err) {
                done(err);
            });
        });

        it('should reject the promise after a delay when the runner function is invoked with a erroring task', function(done) {
            var error = 'something went wrong';
            var delay = 100;
            var tolerance = 7;
            var runner = _assertionHelper.getDelayedRunner(function() {
                throw new Error(error);
            }, delay);
            var startTime = Date.now();
            var ret = runner();

            expect(ret).to.be.rejected.then(function() {
                try{
                    var endTime = Date.now();
                    expect(endTime - startTime).to.be.within(delay, delay + tolerance);
                    done();
                } catch (ex) {
                    done(ex);
                }
            }, function(err) {
                done(err);
            });
        });
    });

    describe('getResolver()', function() {

        function _getDeferred() {
            return {
                resolve: _sinon.spy(),
                reject: _sinon.spy()
            };
        }

        it('should throw an error if invoked without a valid deferred object', function() {
            var error = 'invalid deferred object specified for resolver (arg #1)';
            function invokeMethod(def) {
                return function() {
                   _assertionHelper.getResolver(def);
                };
            };

            expect(invokeMethod()).to.throw(error);
            expect(invokeMethod('string')).to.throw(error);
            expect(invokeMethod(123)).to.throw(error);
            expect(invokeMethod(true)).to.throw(error);
            expect(invokeMethod({})).to.throw(error);
            expect(invokeMethod([])).to.throw(error);
        });

        it('should return a function when invoked with a valid deferred object', function() {
            var def = _getDeferred();
            var callback = _assertionHelper.getResolver(def);

            expect(callback).to.be.a('function');
        });

        it('should resolve the deferred with correct arguments if the callback is invoked without an error', function() {
            var def = _getDeferred();
            var arg1 = 'data1';
            var arg2 = 'data2';
            var callback = _assertionHelper.getResolver(def);

            expect(def.resolve).to.not.have.been.called;
            expect(def.reject).to.not.have.been.called;

            callback(null);
            expect(def.resolve).to.have.been.calledWithExactly();
            expect(def.reject).to.not.have.been.called;
            def.resolve.reset();

            callback(null, arg1);
            expect(def.resolve).to.have.been.calledWithExactly(arg1);
            expect(def.reject).to.not.have.been.called;
            def.resolve.reset();

            callback(null, arg1, arg2);
            expect(def.resolve).to.have.been.calledWithExactly(arg1, arg2);
            expect(def.reject).to.not.have.been.called;
            def.resolve.reset();
        });

        it('should resolve the deferred with the specified arguments when the resolveArgs parameter is specified', function() {
            var def = _getDeferred();
            var arg1 = 'data1';
            var arg2 = 'data2';
            var resolveArgs = 'foo';
            var callback = _assertionHelper.getResolver(def, resolveArgs);

            expect(def.resolve).to.not.have.been.called;
            expect(def.reject).to.not.have.been.called;

            callback(null);
            expect(def.resolve).to.have.been.calledWithExactly(resolveArgs);
            expect(def.reject).to.not.have.been.called;
            def.resolve.reset();

            callback(null, arg1);
            expect(def.resolve).to.have.been.calledWithExactly(resolveArgs);
            expect(def.reject).to.not.have.been.called;
            def.resolve.reset();

            callback(null, arg1, arg2);
            expect(def.resolve).to.have.been.calledWithExactly(resolveArgs);
            expect(def.reject).to.not.have.been.called;
            def.resolve.reset();
        });

        it('should reject the deferred with the error if the callback is invoked with an error', function() {
            var def = _getDeferred();
            var error = 'something went wrong';
            var callback = _assertionHelper.getResolver(def);

            expect(def.resolve).to.not.have.been.called;
            expect(def.reject).to.not.have.been.called;

            callback(error);
            expect(def.resolve).to.not.have.been.called;
            expect(def.reject).to.have.been.calledWithExactly(error);
        });
    });
});
<|endoftext|>


<commit_before>'use strict';

var expect = require('chai').expect;

var SessionStore = require('../../index');
var sessionStore = require('../session-store');
var TestManager = require('../test-manager');

describe('SessionStore#createDatabaseTable(cb)', function() {

	before(TestManager.tearDown);

	describe('when the session database table does not yet exist', function() {

		after(TestManager.tearDown);

		it('should create it', function(done) {

			sessionStore.createDatabaseTable(function(error) {

				if (error) {
					return done(new Error(error));
				}

				var sql = 'SELECT `session_id`, `data`, `expires` FROM `sessions`';
				var params = [];

				sessionStore.connection.query(sql, params, function(error, result) {

					if (error) {
						return done(new Error(error));
					}

					done();
				});
			});
		});
	});

	describe('when the session database table does not yet exist', function() {

		before(TestManager.setUp);

		it('should do nothing', function(done) {

			sessionStore.createDatabaseTable(function(error) {

				if (error) {
					return done(new Error(error));
				}

				done();
			});
		});
	});

	describe('when \'options.createDatabaseTable\' is set to FALSE', function() {

		var originalSync;

		before(function() {

			originalSync = SessionStore.prototype.createDatabaseTable;
		});

		afterEach(function() {

			SessionStore.prototype.createDatabaseTable = originalSync;
		});

		it('should not be called when a new sessionStore object is created', function(done) {

			var called = false;

			SessionStore.prototype.createDatabaseTable = function() {

				called = true;

				done(new Error('Sync method should not have been called'));
			};

			var options = require('../config/database');

			options.createDatabaseTable = false;

			new SessionStore(options, function(error) {

				if (called) {
					return;
				}

				if (error) {
					return done(new Error(error));
				}

				done();
			});
		});
	});

	describe('when \'options.createDatabaseTable\' is set to TRUE', function() {

		var options;
		var originalSync;

		beforeEach(function() {

			options = require('../config/database');
			options.createDatabaseTable = true;

			originalSync = SessionStore.prototype.createDatabaseTable;
		});

		afterEach(function() {

			SessionStore.prototype.createDatabaseTable = originalSync;
		});

		it('should be called when a new sessionStore object is created', function(done) {

			var called = false;

			SessionStore.prototype.createDatabaseTable = function(cb) {

				called = true;

				cb && cb();
			};

			new SessionStore(options, function(error) {

				if (error) {
					return done(new Error(error));
				}

				if (!called) {
					return done(new Error('Sync method should have been called'));
				}

				done();
			});
		});

		describe('\'options.schema\'', function() {

			var sessionStore;

			beforeEach(function(done) {

				options.schema = {
					tableName: 'testSessionTable',
					columnNames: {
						session_id: 'testColumnSessionId',
						expires: 'testColumnExpires',
						data: 'testColumnData'
					}
				};

				sessionStore = new SessionStore(options, done);
			});

			afterEach(function() {

				sessionStore.closeStore();
			});

			it('should create a database table with the correct name and columns', function(done) {

				var sql = 'SHOW COLUMNS FROM ??';
				var params = [options.schema.tableName];

				sessionStore.connection.query(sql, params, function(error, rows) {

					if (error) {
						return done(error);
					}

					expect(rows).to.be.an('array');
					expect(rows).to.have.length(3);
					expect(rows[0].Field).to.equal(options.schema.columnNames.session_id);
					expect(rows[1].Field).to.equal(options.schema.columnNames.expires);
					expect(rows[2].Field).to.equal(options.schema.columnNames.data);
					done();
				});
			});

			it('set() should work', function(done) {

				sessionStore.set('some-session-id', { some: 'data' }, done);
			});

			it('get(session_id, cb) should work', function(done) {

				var session_id = 'some-session-id';

				sessionStore.set(session_id, { some: 'data' }, function(error) {

					if (error) {
						return done(error);
					}

					sessionStore.get(session_id, done);
				});
			});

			it('destroy() should work', function(done) {

				sessionStore.destroy('some-session-id', done);
			});

			it('length() should work', function(done) {

				sessionStore.length(done);
			});

			it('clear() should work', function(done) {

				sessionStore.clear(done);
			});
		});
	});
});
<commit_msg>Fixed test description<commit_after>'use strict';

var expect = require('chai').expect;

var SessionStore = require('../../index');
var sessionStore = require('../session-store');
var TestManager = require('../test-manager');

describe('SessionStore#createDatabaseTable(cb)', function() {

	before(TestManager.tearDown);

	describe('when the session database table does not yet exist', function() {

		after(TestManager.tearDown);

		it('should create it', function(done) {

			sessionStore.createDatabaseTable(function(error) {

				if (error) {
					return done(new Error(error));
				}

				var sql = 'SELECT `session_id`, `data`, `expires` FROM `sessions`';
				var params = [];

				sessionStore.connection.query(sql, params, function(error, result) {

					if (error) {
						return done(new Error(error));
					}

					done();
				});
			});
		});
	});

	describe('when the session database table already exists', function() {

		before(TestManager.setUp);

		it('should do nothing', function(done) {

			sessionStore.createDatabaseTable(function(error) {

				if (error) {
					return done(new Error(error));
				}

				done();
			});
		});
	});

	describe('when \'options.createDatabaseTable\' is set to FALSE', function() {

		var originalSync;

		before(function() {

			originalSync = SessionStore.prototype.createDatabaseTable;
		});

		afterEach(function() {

			SessionStore.prototype.createDatabaseTable = originalSync;
		});

		it('should not be called when a new sessionStore object is created', function(done) {

			var called = false;

			SessionStore.prototype.createDatabaseTable = function() {

				called = true;

				done(new Error('Sync method should not have been called'));
			};

			var options = require('../config/database');

			options.createDatabaseTable = false;

			new SessionStore(options, function(error) {

				if (called) {
					return;
				}

				if (error) {
					return done(new Error(error));
				}

				done();
			});
		});
	});

	describe('when \'options.createDatabaseTable\' is set to TRUE', function() {

		var options;
		var originalSync;

		beforeEach(function() {

			options = require('../config/database');
			options.createDatabaseTable = true;

			originalSync = SessionStore.prototype.createDatabaseTable;
		});

		afterEach(function() {

			SessionStore.prototype.createDatabaseTable = originalSync;
		});

		it('should be called when a new sessionStore object is created', function(done) {

			var called = false;

			SessionStore.prototype.createDatabaseTable = function(cb) {

				called = true;

				cb && cb();
			};

			new SessionStore(options, function(error) {

				if (error) {
					return done(new Error(error));
				}

				if (!called) {
					return done(new Error('Sync method should have been called'));
				}

				done();
			});
		});

		describe('\'options.schema\'', function() {

			var sessionStore;

			beforeEach(function(done) {

				options.schema = {
					tableName: 'testSessionTable',
					columnNames: {
						session_id: 'testColumnSessionId',
						expires: 'testColumnExpires',
						data: 'testColumnData'
					}
				};

				sessionStore = new SessionStore(options, done);
			});

			afterEach(function() {

				sessionStore.closeStore();
			});

			it('should create a database table with the correct name and columns', function(done) {

				var sql = 'SHOW COLUMNS FROM ??';
				var params = [options.schema.tableName];

				sessionStore.connection.query(sql, params, function(error, rows) {

					if (error) {
						return done(error);
					}

					expect(rows).to.be.an('array');
					expect(rows).to.have.length(3);
					expect(rows[0].Field).to.equal(options.schema.columnNames.session_id);
					expect(rows[1].Field).to.equal(options.schema.columnNames.expires);
					expect(rows[2].Field).to.equal(options.schema.columnNames.data);
					done();
				});
			});

			it('set() should work', function(done) {

				sessionStore.set('some-session-id', { some: 'data' }, done);
			});

			it('get(session_id, cb) should work', function(done) {

				var session_id = 'some-session-id';

				sessionStore.set(session_id, { some: 'data' }, function(error) {

					if (error) {
						return done(error);
					}

					sessionStore.get(session_id, done);
				});
			});

			it('destroy() should work', function(done) {

				sessionStore.destroy('some-session-id', done);
			});

			it('length() should work', function(done) {

				sessionStore.length(done);
			});

			it('clear() should work', function(done) {

				sessionStore.clear(done);
			});
		});
	});
});
<|endoftext|>


<commit_before>describe("Mac tag autocomplete", function() {
  var $compile, $rootScope, $timeout, keys;

  function hasClass(element, className) {
    return element[0].className.indexOf(className) > -1;
  }

  beforeEach(module("Mac"));
  beforeEach(module("template/tag_autocomplete.html"));
  beforeEach(module("template/menu.html"));

  beforeEach(inject(function(_$compile_, _$rootScope_, _$timeout_, _keys_) {
    $compile = _$compile_;
    $rootScope = _$rootScope_;
    $timeout = _$timeout_;
    keys = _keys_;
  }));

  describe("basic initialization", function() {
    it("should be replaced by the template", function() {
      var element;
      element = $compile("<mac-tag-autocomplete></mac-tag-autocomplete>")($rootScope);
      $rootScope.$digest();
      return expect(hasClass(element, "mac-tag-autocomplete")).toBeTruthy();
    });

    it("should set default value and label attribute on mac-autocomplete", function() {
      var element, textInput;
      element = $compile("<mac-tag-autocomplete></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      expect(textInput.getAttribute("mac-autocomplete-label")).toBe("name");
    });

    it("should set value and label attribute on mac-autocomplete", function() {
      var element, textInput;
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-label='test-name' mac-tag-autocomplete-value='test-id'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      expect(textInput.getAttribute("mac-autocomplete-label")).toBe("test-name");
    });

    it("should pass empty string as key and value", function() {
      var element, textInput;
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-label='' mac-tag-autocomplete-value=''></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      expect(textInput.getAttribute("mac-autocomplete-label")).toBe('');
    });

    it("should set query attribute on mac-autocomplete", function() {
      var element, textInput;
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-query='query'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      expect(textInput.getAttribute("mac-autocomplete-query")).toBe("query");
    });

    it("should set delay attribute on mac-autocomplete", function() {
      var element, textInput;
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-delay='100'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      expect(textInput.getAttribute("mac-autocomplete-delay")).toBe("100");
    });

    it("should set the source attribute on mac-autocomplete", function() {
      var element, textInput;
      $rootScope.source = ["test", "test1", "test2"];
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-source='source'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      expect(textInput.getAttribute("mac-autocomplete-source")).toBe("macTagAutocomplete.source");
    });

    it("should have the same source function as the parent scope", function() {
      $rootScope.source = jasmine.createSpy("source");
      var element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-source='source'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      var elementScope = element.isolateScope();
      elementScope.macTagAutocomplete.source();

      expect($rootScope.source).toHaveBeenCalled();
    });

    // Add protractor for this use case
    it("should focus on autocomplete when click on tag autocomplete", function() {
      var element, textInput;
      $rootScope.source = ["test", "test1", "test2"];
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-source='source'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();

      textInput = element[0].querySelector(".mac-autocomplete");
      spyOn(textInput, 'focus');
      element.triggerHandler("click");

      expect(textInput.focus).toHaveBeenCalled();
    });

    it("should model -> view", function() {
      var element, textInput;
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-model='model'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      $rootScope.model = "Here";

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      expect(angular.element(textInput).val()).toBe("Here");
    });
  });

  describe("selected variable", function() {
    it("should have a placeholder", function() {
      $rootScope.selected = [];
      var element = $compile("<mac-tag-autocomplete\n  mac-tag-autocomplete-placeholder = \"'Testing'\"\n  mac-tag-autocomplete-selected='selected'>\n</mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();

      var textInputScope = element.isolateScope();
      expect(textInputScope.macTagAutocomplete.placeholder).toBe("Testing");
    });
  });

  describe("onKeyDown", function() {
    it("should fire keydown callback", function() {
      var element, textInput;
      $rootScope.keydown = jasmine.createSpy("keydown");
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-on-keydown='keydown()'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      browserTrigger(textInput, "keydown");

      expect($rootScope.keydown).toHaveBeenCalled();
    });

    it("should remove the last tag", function() {
      var element, textInput;
      $rootScope.keydown = jasmine.createSpy('keydown');
      $rootScope.selected = [
        {
          id: "tag1"
        }
      ];
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-selected='selected' mac-tag-autocomplete-on-keydown='keydown()'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      angular.element(textInput).triggerHandler({
        type: "keydown",
        which: keys.BACKSPACE
      });

      expect($rootScope.selected.length).toBe(0);
    });

    it("should push the text into selected", function() {
      var element, textInput;
      $rootScope.keydown = jasmine.createSpy('keydown')
      $rootScope.selected = [];
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-selected='selected' mac-tag-autocomplete-on-keydown='keydown()' mac-tag-autocomplete-disabled='true'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = angular.element(element[0].querySelector(".mac-autocomplete"));

      var elementScope = element.isolateScope();
      elementScope.macTagAutocomplete.textInput = "Testing";
      textInput.triggerHandler({
        type: "keydown",
        which: keys.ENTER
      });
      $timeout.flush();

      expect($rootScope.selected.length).toBe(1);
    });
  });

  describe("on select callback", function() {
    it("should fire callback", function() {
      var element, textInput;
      $rootScope.onEnter = jasmine.createSpy('onEnter')
      $rootScope.selected = [];
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-selected='selected' mac-tag-autocomplete-on-enter='onEnter(item)' mac-tag-autocomplete-disabled='true'></mac-tag-autocomplete>")($rootScope);
      $rootScope.$digest();

      textInput = element[0].querySelector(".mac-autocomplete");
      var elementScope = element.isolateScope();
      elementScope.macTagAutocomplete.textInput = "Testing";

      angular.element(textInput).triggerHandler({
        type: "keydown",
        which: keys.ENTER
      });
      $timeout.flush();

      expect($rootScope.onEnter).toHaveBeenCalled();
    });
  });
});
<commit_msg>test(macTagAutocomplete): Add unit tests for event directives<commit_after>describe("Mac tag autocomplete", function() {
  var $compile, $rootScope, $timeout, keys;

  function hasClass(element, className) {
    return element[0].className.indexOf(className) > -1;
  }

  beforeEach(module("Mac"));
  beforeEach(module("template/tag_autocomplete.html"));
  beforeEach(module("template/menu.html"));

  beforeEach(inject(function(_$compile_, _$rootScope_, _$timeout_, _keys_) {
    $compile = _$compile_;
    $rootScope = _$rootScope_;
    $timeout = _$timeout_;
    keys = _keys_;
  }));

  describe("basic initialization", function() {
    it("should be replaced by the template", function() {
      var element;
      element = $compile("<mac-tag-autocomplete></mac-tag-autocomplete>")($rootScope);
      $rootScope.$digest();
      return expect(hasClass(element, "mac-tag-autocomplete")).toBeTruthy();
    });

    it("should set default value and label attribute on mac-autocomplete", function() {
      var element, textInput;
      element = $compile("<mac-tag-autocomplete></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      expect(textInput.getAttribute("mac-autocomplete-label")).toBe("name");
    });

    it("should set value and label attribute on mac-autocomplete", function() {
      var element, textInput;
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-label='test-name' mac-tag-autocomplete-value='test-id'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      expect(textInput.getAttribute("mac-autocomplete-label")).toBe("test-name");
    });

    it("should pass empty string as key and value", function() {
      var element, textInput;
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-label='' mac-tag-autocomplete-value=''></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      expect(textInput.getAttribute("mac-autocomplete-label")).toBe('');
    });

    it("should set query attribute on mac-autocomplete", function() {
      var element, textInput;
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-query='query'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      expect(textInput.getAttribute("mac-autocomplete-query")).toBe("query");
    });

    it("should set delay attribute on mac-autocomplete", function() {
      var element, textInput;
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-delay='100'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      expect(textInput.getAttribute("mac-autocomplete-delay")).toBe("100");
    });

    it("should set the source attribute on mac-autocomplete", function() {
      var element, textInput;
      $rootScope.source = ["test", "test1", "test2"];
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-source='source'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      expect(textInput.getAttribute("mac-autocomplete-source")).toBe("macTagAutocomplete.source");
    });

    it("should have the same source function as the parent scope", function() {
      $rootScope.source = jasmine.createSpy("source");
      var element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-source='source'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      var elementScope = element.isolateScope();
      elementScope.macTagAutocomplete.source();

      expect($rootScope.source).toHaveBeenCalled();
    });

    // Add protractor for this use case
    it("should focus on autocomplete when click on tag autocomplete", function() {
      var element, textInput;
      $rootScope.source = ["test", "test1", "test2"];
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-source='source'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();

      textInput = element[0].querySelector(".mac-autocomplete");
      spyOn(textInput, 'focus');
      element.triggerHandler("click");

      expect(textInput.focus).toHaveBeenCalled();
    });

    it("should model -> view", function() {
      var element, textInput;
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-model='model'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      $rootScope.model = "Here";

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      expect(angular.element(textInput).val()).toBe("Here");
    });
  });

  describe("selected variable", function() {
    it("should have a placeholder", function() {
      $rootScope.selected = [];
      var element = $compile("<mac-tag-autocomplete\n  mac-tag-autocomplete-placeholder = \"'Testing'\"\n  mac-tag-autocomplete-selected='selected'>\n</mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();

      var textInputScope = element.isolateScope();
      expect(textInputScope.macTagAutocomplete.placeholder).toBe("Testing");
    });
  });

  describe("onKeyDown", function() {
    it("should fire keydown callback", function() {
      var element, textInput;
      $rootScope.keydown = jasmine.createSpy("keydown");
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-on-keydown='keydown()'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      browserTrigger(textInput, "keydown");

      expect($rootScope.keydown).toHaveBeenCalled();
    });

    it("should remove the last tag", function() {
      var element, textInput;
      $rootScope.keydown = jasmine.createSpy('keydown');
      $rootScope.selected = [
        {
          id: "tag1"
        }
      ];
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-selected='selected' mac-tag-autocomplete-on-keydown='keydown()'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = element[0].querySelector(".mac-autocomplete");

      angular.element(textInput).triggerHandler({
        type: "keydown",
        which: keys.BACKSPACE
      });

      expect($rootScope.selected.length).toBe(0);
    });

    it("should push the text into selected", function() {
      var element, textInput;
      $rootScope.keydown = jasmine.createSpy('keydown')
      $rootScope.selected = [];
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-selected='selected' mac-tag-autocomplete-on-keydown='keydown()' mac-tag-autocomplete-disabled='true'></mac-tag-autocomplete>")($rootScope);

      $rootScope.$digest();
      textInput = angular.element(element[0].querySelector(".mac-autocomplete"));

      var elementScope = element.isolateScope();
      elementScope.macTagAutocomplete.textInput = "Testing";
      textInput.triggerHandler({
        type: "keydown",
        which: keys.ENTER
      });
      $timeout.flush();

      expect($rootScope.selected.length).toBe(1);
    });
  });

  describe("on select callback", function() {
    it("should fire callback", function() {
      var element, textInput;
      $rootScope.onEnter = jasmine.createSpy('onEnter')
      $rootScope.selected = [];
      element = $compile("<mac-tag-autocomplete mac-tag-autocomplete-selected='selected' mac-tag-autocomplete-on-enter='onEnter(item)' mac-tag-autocomplete-disabled='true'></mac-tag-autocomplete>")($rootScope);
      $rootScope.$digest();

      textInput = element[0].querySelector(".mac-autocomplete");
      var elementScope = element.isolateScope();
      elementScope.macTagAutocomplete.textInput = "Testing";

      angular.element(textInput).triggerHandler({
        type: "keydown",
        which: keys.ENTER
      });
      $timeout.flush();

      expect($rootScope.onEnter).toHaveBeenCalled();
    });
  });

  describe('event callback', function() {
    it('should fire blur callback with parameters', function() {
      $rootScope.onBlurFn = function($event, ctrl, value) {
        expect($event).toBeDefined();
        expect(ctrl).toBeDefined();
        expect(value).toBe('');
      };
      var element = $compile('<mac-tag-autocomplete mac-tag-autocomplete-selected="selected" mac-tag-autocomplete-blur="onBlurFn($event, ctrl, value)"></mac-tag-autocomplete>')($rootScope);

      $rootScope.$digest();

      var textInput = element[0].querySelector('.mac-autocomplete');
      angular.element(textInput).triggerHandler('blur');

      $rootScope.$digest();
    });

    it('should fire blur callback', function() {
      $rootScope.onBlurFn = jasmine.createSpy('onBlurFn');
      var element = $compile('<mac-tag-autocomplete mac-tag-autocomplete-selected="selected" mac-tag-autocomplete-blur="onBlurFn()"></mac-tag-autocomplete>')($rootScope);

      $rootScope.$digest();

      var textInput = element[0].querySelector('.mac-autocomplete');
      angular.element(textInput).triggerHandler('blur');

      $rootScope.$digest();

      expect($rootScope.onBlurFn).toHaveBeenCalled();
    });

    it('should fire focus callback', function() {
      $rootScope.onFocusFn = jasmine.createSpy('onFocusFn');
      var element = $compile('<mac-tag-autocomplete mac-tag-autocomplete-selected="selected" mac-tag-autocomplete-focus="onFocusFn()"></mac-tag-autocomplete>')($rootScope);

      $rootScope.$digest();

      var textInput = element[0].querySelector('.mac-autocomplete');
      angular.element(textInput).triggerHandler('focus');

      $rootScope.$digest();

      expect($rootScope.onFocusFn).toHaveBeenCalled();
    });

    it('should fire keyup callback', function() {
      $rootScope.onKeyupFn = jasmine.createSpy('onKeyupFn');
      var element = $compile('<mac-tag-autocomplete mac-tag-autocomplete-selected="selected" mac-tag-autocomplete-keyup="onKeyupFn()"></mac-tag-autocomplete>')($rootScope);

      $rootScope.$digest();

      var textInput = element[0].querySelector('.mac-autocomplete');
      angular.element(textInput).triggerHandler('keyup');

      $rootScope.$digest();

      expect($rootScope.onKeyupFn).toHaveBeenCalled();
    });

    it('should fire keydown callback', function() {
      $rootScope.onKeydownFn = jasmine.createSpy('onKeydownFn');
      var element = $compile('<mac-tag-autocomplete mac-tag-autocomplete-selected="selected" mac-tag-autocomplete-keydown="onKeydownFn()"></mac-tag-autocomplete>')($rootScope);

      $rootScope.$digest();

      var textInput = element[0].querySelector('.mac-autocomplete');
      angular.element(textInput).triggerHandler('keydown');

      $rootScope.$digest();

      expect($rootScope.onKeydownFn).toHaveBeenCalled();
    });

    it('should fire keypress callback', function() {
      $rootScope.onKeypressFn = jasmine.createSpy('onKeypressFn');
      var element = $compile('<mac-tag-autocomplete mac-tag-autocomplete-selected="selected" mac-tag-autocomplete-keypress="onKeypressFn()"></mac-tag-autocomplete>')($rootScope);

      $rootScope.$digest();

      var textInput = element[0].querySelector('.mac-autocomplete');
      angular.element(textInput).triggerHandler('keypress');

      $rootScope.$digest();

      expect($rootScope.onKeypressFn).toHaveBeenCalled();
    });
  });
});
<|endoftext|>


<commit_before>import React from 'react';
import {shallow} from 'enzyme';
import EnableableOperation from '../../lib/models/enableable-operation';
import {checkoutStates} from '../../lib/controllers/pr-checkout-controller';
import CheckoutButton from '../../lib/views/checkout-button';

describe.only('Checkout button', function() {

  function buildApp(overrideProps = {}) {
    return (
      <CheckoutButton
        checkoutOp={new EnableableOperation(() => {}).disable(checkoutStates.CURRENT)}
        classNamePrefix=""
        {...overrideProps}
      />
    );
  }

  it('renders checkout button with proper class names', function() {
    const button = shallow(buildApp({
      classNames: ['not', 'necessary'],
      classNamePrefix: 'prefix--',
    })).find('.checkoutButton');
    assert.isTrue(button.hasClass('prefix--current'));
    assert.isTrue(button.hasClass('not'));
    assert.isTrue(button.hasClass('necessary'));
  });

  it('triggers its operation callback on click', function() {
    const cb = sinon.spy();
    const checkoutOp = new EnableableOperation(cb);
    const wrapper = shallow(buildApp({checkoutOp}));

    const button = wrapper.find('.checkoutButton');
    assert.strictEqual(button.text(), 'Checkout');
    button.simulate('click');
    assert.isTrue(cb.called);
  });

  it('renders as disabled with hover text set to the disablement message', function() {
    const checkoutOp = new EnableableOperation(() => {}).disable(checkoutStates.DISABLED, 'message');
    const wrapper = shallow(buildApp({checkoutOp}));

    const button = wrapper.find('.checkoutButton');
    assert.isTrue(button.prop('disabled'));
    assert.strictEqual(button.text(), 'Checkout');
    assert.strictEqual(button.prop('title'), 'message');
  });

  it('changes the button text when disabled because the PR is the current branch', function() {
    const checkoutOp = new EnableableOperation(() => {}).disable(checkoutStates.CURRENT, 'message');
    const wrapper = shallow(buildApp({checkoutOp}));

    const button = wrapper.find('.checkoutButton');
    assert.isTrue(button.prop('disabled'));
    assert.strictEqual(button.text(), 'Checked out');
    assert.strictEqual(button.prop('title'), 'message');
  });

  it('renders hidden', function() {
    const checkoutOp = new EnableableOperation(() => {}).disable(checkoutStates.HIDDEN, 'message');
    const wrapper = shallow(buildApp({checkoutOp}));

    assert.isFalse(wrapper.find('.checkoutButton').exists());
  });
});
<commit_msg>:fire: `.only`<commit_after>import React from 'react';
import {shallow} from 'enzyme';
import EnableableOperation from '../../lib/models/enableable-operation';
import {checkoutStates} from '../../lib/controllers/pr-checkout-controller';
import CheckoutButton from '../../lib/views/checkout-button';

describe('Checkout button', function() {

  function buildApp(overrideProps = {}) {
    return (
      <CheckoutButton
        checkoutOp={new EnableableOperation(() => {}).disable(checkoutStates.CURRENT)}
        classNamePrefix=""
        {...overrideProps}
      />
    );
  }

  it('renders checkout button with proper class names', function() {
    const button = shallow(buildApp({
      classNames: ['not', 'necessary'],
      classNamePrefix: 'prefix--',
    })).find('.checkoutButton');
    assert.isTrue(button.hasClass('prefix--current'));
    assert.isTrue(button.hasClass('not'));
    assert.isTrue(button.hasClass('necessary'));
  });

  it('triggers its operation callback on click', function() {
    const cb = sinon.spy();
    const checkoutOp = new EnableableOperation(cb);
    const wrapper = shallow(buildApp({checkoutOp}));

    const button = wrapper.find('.checkoutButton');
    assert.strictEqual(button.text(), 'Checkout');
    button.simulate('click');
    assert.isTrue(cb.called);
  });

  it('renders as disabled with hover text set to the disablement message', function() {
    const checkoutOp = new EnableableOperation(() => {}).disable(checkoutStates.DISABLED, 'message');
    const wrapper = shallow(buildApp({checkoutOp}));

    const button = wrapper.find('.checkoutButton');
    assert.isTrue(button.prop('disabled'));
    assert.strictEqual(button.text(), 'Checkout');
    assert.strictEqual(button.prop('title'), 'message');
  });

  it('changes the button text when disabled because the PR is the current branch', function() {
    const checkoutOp = new EnableableOperation(() => {}).disable(checkoutStates.CURRENT, 'message');
    const wrapper = shallow(buildApp({checkoutOp}));

    const button = wrapper.find('.checkoutButton');
    assert.isTrue(button.prop('disabled'));
    assert.strictEqual(button.text(), 'Checked out');
    assert.strictEqual(button.prop('title'), 'message');
  });

  it('renders hidden', function() {
    const checkoutOp = new EnableableOperation(() => {}).disable(checkoutStates.HIDDEN, 'message');
    const wrapper = shallow(buildApp({checkoutOp}));

    assert.isFalse(wrapper.find('.checkoutButton').exists());
  });
});
<|endoftext|>


<commit_before>export function runDesktopSearchTests(br) {
  test('Desktop search - succesful search', async t => {
    const { nav } = br;
    const testTextFound = 'theory';
    await t.expect(br.shell.visible).ok();
    await t.expect(br.BRcontainer.visible).ok();

    //assuring that the search bar is enabled
    await t.expect(nav.desktop.searchBox.exists).ok();
    await t.expect(nav.desktop.searchBox.visible).ok();

    //testing search for a word found in the book
    await t
      .selectText(nav.desktop.searchBox.child('.BRsearchInput'))
      .pressKey('delete');
    await t.typeText(nav.desktop.searchBox.child('.BRsearchInput'), testTextFound);
    await t.click((nav.desktop.searchBox).child('.BRsearchSubmit'));
    await t.expect(nav.desktop.querySign.exists).ok({timeout:30000});
    await t.expect(nav.desktop.querySign.child('div').exists).ok();
    await t.expect(nav.desktop.querySign.child('div').innerText).contains(testTextFound);
  });

  test('Desktop search - unsuccesful search', async t => {
    const { nav } = br;
    const testTextNotFound = 'xcjnierjnieunenojrnskz';
    await t.expect(br.shell.visible).ok();
    await t.expect(br.BRcontainer.visible).ok();

    //assuring that the search bar is enabled
    await t.expect(nav.desktop.searchBox.exists).ok();
    await t.expect(nav.desktop.searchBox.visible).ok();

    //testing search for a word not found in the book
    await t
      .selectText(nav.desktop.searchBox.child('.BRsearchInput'))
      .pressKey('delete');
    await t.typeText(nav.desktop.searchBox.child('.BRsearchInput'), testTextNotFound);
    await t.click((nav.desktop.searchBox).child('.BRsearchSubmit'));
    await t.expect(nav.desktop.querySign.child('div').withText(testTextNotFound).exists).notOk({timeout:40000});

  });
}
<commit_msg>Added url check for desktop search<commit_after>import { ClientFunction } from 'testcafe';

export function runDesktopSearchTests(br) {
  const testTextFound = 'theory';
  const testTextNotFound = 'xcjnierjnieunenojrnskz';

  test('Desktop search - succesful search', async t => {
    const { nav } = br;
    await t.expect(br.shell.visible).ok();
    await t.expect(br.BRcontainer.visible).ok();

    //assuring that the search bar is enabled
    await t.expect(nav.desktop.searchBox.exists).ok();
    await t.expect(nav.desktop.searchBox.visible).ok();

    //testing search for a word found in the book
    await t
      .selectText(nav.desktop.searchBox.child('.BRsearchInput'))
      .pressKey('delete');
    await t.typeText(nav.desktop.searchBox.child('.BRsearchInput'), testTextFound);
    await t.click((nav.desktop.searchBox).child('.BRsearchSubmit'));
    await t.expect(nav.desktop.querySign.exists).ok({timeout:30000});
    await t.expect(nav.desktop.querySign.child('div').exists).ok();
    await t.expect(nav.desktop.querySign.child('div').innerText).contains(testTextFound);

    const getPageUrl = ClientFunction(() => window.location.href.toString());
    await t.expect(getPageUrl()).contains(testTextFound);

  });

  test('Desktop search - unsuccesful search', async t => {
    const { nav } = br;
    await t.expect(br.shell.visible).ok();
    await t.expect(br.BRcontainer.visible).ok();

    //assuring that the search bar is enabled
    await t.expect(nav.desktop.searchBox.exists).ok();
    await t.expect(nav.desktop.searchBox.visible).ok();

    //testing search for a word not found in the book
    await t
      .selectText(nav.desktop.searchBox.child('.BRsearchInput'))
      .pressKey('delete');
    await t.typeText(nav.desktop.searchBox.child('.BRsearchInput'), testTextNotFound);
    await t.click((nav.desktop.searchBox).child('.BRsearchSubmit'));
    await t.expect(nav.desktop.querySign.child('div').withText(testTextNotFound).exists).notOk({timeout:40000});

    const getPageUrl = ClientFunction(() => window.location.href.toString());
    await t.expect(getPageUrl()).contains(testTextNotFound);
  });
  //checkUrl(testTextNotFound);

}
<|endoftext|>


<commit_before>import {
  UNHAPPY,
  NEUTRAL,
  HAPPY,
  POLL_LOADED,
  RESULTS_LOADED
} from "../constants";

const INITIAL_STATE = {
  poll: {},
  records: []
};

export default function charts(state=INITIAL_STATE, action) {
  switch(action.type) {
    case POLL_LOADED: {
      const {poll} = action;
      return {...state, poll};
    }
    case RESULTS_LOADED: {
      const {records} = action;
      return {...state, records};
    }
    default: {
      return state;
    }
  }
}

export function getAccumulatedVotes(state) {
  const {records} = state;

  const allDays = [];
  const byDays = {[UNHAPPY]: {}, [NEUTRAL]: {}, [HAPPY]: {}};
  records.forEach((r) => {
    const date = new Date(r.submitted);
    const month = date.getMonth() + 1;
    const day = date.getDate();
    const key = `${month < 10 ? "0" + month : month}-${day < 10 ? "0" + day : day}`;
    if (allDays.indexOf(key) < 0) {
      allDays.push(key);
    }
    byDays[r.note][key] = (byDays[r.note][key] || 0) + 1;
  });

  const sortedDays = allDays.sort();

  const accumulated = {
    labels: sortedDays,
    series: [
      sortedDays.map((d) => (byDays[UNHAPPY][d] || 0)),
      sortedDays.map((d) => (byDays[NEUTRAL][d] || 0)),
      sortedDays.map((d) => (byDays[HAPPY][d] || 0)),
    ]
  };
  return {
    total: records.length,
    chartsData: accumulated
  };
}
<commit_msg>Manage new year<commit_after>import {
  UNHAPPY,
  NEUTRAL,
  HAPPY,
  POLL_LOADED,
  RESULTS_LOADED
} from "../constants";

const INITIAL_STATE = {
  poll: {},
  records: []
};

export default function charts(state=INITIAL_STATE, action) {
  switch(action.type) {
    case POLL_LOADED: {
      const {poll} = action;
      return {...state, poll};
    }
    case RESULTS_LOADED: {
      const {records} = action;
      return {...state, records};
    }
    default: {
      return state;
    }
  }
}

export function getAccumulatedVotes(state) {
  const {records} = state;

  const allDays = [];
  const byDays = {[UNHAPPY]: {}, [NEUTRAL]: {}, [HAPPY]: {}};
  records.forEach((r) => {
    const date = new Date(r.submitted);
    const month = date.getMonth() + 1;
    const day = date.getDate();
    const key = `${date.getFullYear()}/${month < 10 ? "0" + month : month}/${day < 10 ? "0" + day : day}`;
    if (allDays.indexOf(key) < 0) {
      allDays.push(key);
    }
    byDays[r.note][key] = (byDays[r.note][key] || 0) + 1;
  });

  const sortedDays = allDays.sort();

  const accumulated = {
    labels: sortedDays.map((d) => d.replace(/^\d{4}\//, "")),
    series: [
      sortedDays.map((d) => (byDays[UNHAPPY][d] || 0)),
      sortedDays.map((d) => (byDays[NEUTRAL][d] || 0)),
      sortedDays.map((d) => (byDays[HAPPY][d] || 0)),
    ]
  };
  return {
    total: records.length,
    chartsData: accumulated
  };
}
<|endoftext|>