<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) 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 Settings', function() {

  var view, service, db, models, utils, juju, env, conn, container,
      inspector, Y, jujuViews, charmData;

  before(function(done) {
    var requires = ['juju-gui', 'juju-views', 'juju-tests-utils',
      'juju-charm-store', 'juju-charm-models', 'node-event-simulate'];
    Y = YUI(GlobalConfig).use(requires, function(Y) {
          utils = Y.namespace('juju-tests.utils');
          models = Y.namespace('juju.models');
          jujuViews = Y.namespace('juju.views');
          juju = Y.namespace('juju');
          charmData = utils.loadFixture(
              'data/mediawiki-api-response.json',
              true);
          done();
        });

  });

  beforeEach(function() {
    container = utils.makeContainer(this, 'container');
    conn = new utils.SocketStub();
    db = new models.Database();
    env = juju.newEnvironment({conn: conn});
    env.update_annotations = function() {};
  });

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

  var setUpInspector = function(options) {
    var charm = new models.Charm(charmData.charm),
        charmId = charm.get('id');
    db.charms.add(charm);
    if (options && options.useGhost) {
      service = db.services.ghostService(charm);
    } else {
      var parsedConfig = {};
      // because a test deletes the config data we need a check to
      // stop it from falling over.
      if (charm.get('options')) {
        Y.Object.each(charm.get('options'), function(val, key) {
          // For boolean fields the default is false, so we need to check
          // undefined directly.
          if (val['default'] !== undefined) {
            parsedConfig[key] = val['default'];
          } else {
            parsedConfig[key] = '';
          }
        });
      }
      service = new models.Service({
        id: 'mediawiki',
        charm: charmId,
        exposed: false,
        config: parsedConfig
      });
      db.services.add(service);
      db.onDelta({data: {result: [
        ['unit', 'add', {id: 'mediawiki/0', agent_state: 'pending'}],
        ['unit', 'add', {id: 'mediawiki/1', agent_state: 'pending'}],
        ['unit', 'add', {id: 'mediawiki/2', agent_state: 'pending'}]
      ]}});
    }
    var fakeStore = new Y.juju.charmworld.APIv3({});
    fakeStore.iconpath = function() {
      return 'charm icon url';
    };
    view = new jujuViews.environment({
      container: container,
      db: db,
      env: env,
      store: fakeStore
    });
    view.render();
    Y.Node.create([
      '
'
    ].join('')).appendTo(container);
    return view.createServiceInspector(service, {databinding: {interval: 0}});
  };

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

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

  it('properly renders a service without charm options', function() {
    // Mutate charmData before the render.
    delete charmData.charm.options;
    inspector = setUpInspector();
    // Verify the viewlet rendered, previously it would raise.
    assert.isObject(container.one('.config-file'));
    // Restore the test global
    charmData = utils.loadFixture('data/mediawiki-api-response.json', true);
  });

  it('properly renders charm options with booleans', function() {
    inspector = setUpInspector();
    // Verify the viewlet rendered, previously it would raise.
    assert.isObject(container.one('.config-file'));
    // Restore the test global
    charmData = utils.loadFixture('data/mediawiki-api-response.json', true);

    // Verify we find our checkbox Also note that it's hidden because we're
    // using the slider markup and styling for boolean fields.
    assert.equal(
        container.all('input.hidden-checkbox').size(),
        1,
        'did not render one boolean field');

    // Verify that the textual representation is there.
    assert.equal(
        container.all('.textvalue').size(),
        1,
        'can not find the textual value for the checkbox.');

    // And the value will toggle with the checkbox
    var debugContainer = container.one('.toggle-debug').get('parentNode');
    assert.equal(
        debugContainer.one('.textvalue').get('text').replace(/\s/g, ''),
        'false');
    debugContainer.one('label').simulate('click');
    assert.equal(
        debugContainer.one('.textvalue').get('text').replace(/\s/g, ''),
        'true');
  });

  /**** Begin service destroy UI tests. ****/

  it('has a button to destroy the service', function() {
    inspector = setUpInspector();
    assert.isObject(container.one('.destroy-service-trigger span'));
  });

  it('shows the destroy service prompt if the trigger is clicked', function() {
    inspector = setUpInspector();
    var promptBox = container.one('.destroy-service-prompt');
    assert.isTrue(promptBox.hasClass('closed'));
    container.one('.destroy-service-trigger span').simulate('click');
    assert.isFalse(promptBox.hasClass('closed'));
  });

  it('hides the destroy service prompt if cancel is clicked', function() {
    inspector = setUpInspector();
    var promptBox = container.one('.destroy-service-prompt');
    assert.isTrue(promptBox.hasClass('closed'));
    // First we have to open the prompt.
    container.one('.destroy-service-trigger span').simulate('click');
    assert.isFalse(promptBox.hasClass('closed'));
    // Now we can close it.
    container.one('.cancel-destroy').simulate('click');
    assert.isTrue(promptBox.hasClass('closed'));
  });

  it('initiates a destroy if the "Destroy" button is clicked', function(done) {
    inspector = setUpInspector();
    var promptBox = container.one('.destroy-service-prompt');
    // First we have to open the prompt.
    container.one('.destroy-service-trigger span').simulate('click');
    assert.isFalse(promptBox.hasClass('closed'));
    // If the test times out, it failed (because the expected function call
    // didn't happen).
    inspector.initiateServiceDestroy = function() {
      done();
    };
    container.one('.initiate-destroy').simulate('click');
  });

  it('wires up UI elements to handlers for service inspector', function() {
    // There are UI elements and they all have to be wired up to something.
    inspector = setUpInspector();
    var events = inspector.constructor.prototype.events;
    assert.equal(
        typeof events['.destroy-service-trigger span'].click, 'string');
    assert.equal(typeof events['.initiate-destroy'].click, 'string');
    assert.equal(typeof events['.cancel-destroy'].click, 'string');
  });

  it('responds to service removal failure by alerting the user', function() {
    var notificationAdded;

    inspector = setUpInspector();

    var SERVICE_NAME = 'the name of the service being removed';
    var evt = {
      err: true,
      service_name: SERVICE_NAME
    };

    var db = {
      notifications: {
        add: function(notification) {
          var attrs = notification.getAttrs();
          // The notification has the required attributes.
          assert.isTrue(attrs.hasOwnProperty('title'));
          assert.isTrue(attrs.hasOwnProperty('message'));
          // The service name is mentioned in the error message.
          assert.notEqual(attrs.message.indexOf(SERVICE_NAME, -1));
          assert.equal(attrs.level, 'error');
          assert.deepEqual(attrs.modelId, ['service', 'mediawiki']);
          notificationAdded = true;
        }
      }
    };

    inspector._destroyServiceCallback(service, db, evt);
    assert.isTrue(notificationAdded);
  });

  /**** End service destroy UI tests. ****/

  it('saves changes to settings values', function() {
    inspector = setUpInspector();
    env.connect();
    var vmContainer = inspector.get('container'),
        input = vmContainer.one('textarea[name=admins]'),
        button = vmContainer.one('.configuration-buttons .confirm');

    assert.equal(db.services.item(0).get('config').admins, '');
    input.set('value', 'foo');
    // Force the databinding to notice the change in-line.
    inspector.bindingEngine._nodeChanged(
        input, inspector.views.config);
    button.simulate('click');
    var message = env.ws.last_message();
    assert.equal('foo', message.Params.Options.admins);
    // Send back a success message.
    env.ws.msg({RequestId: message.RequestId});
    assert.equal(button.getHTML(), 'Save changes');
    assert.isTrue(input.hasClass('change-saved'));
  });

  it('can cancel changes', function() {
    // Set up.
    inspector = setUpInspector();
    env.connect();
    var viewlet = getViewlet(inspector);
    var node = viewlet.get('container')
                      .one('textarea[data-bind="config.admins"]');
    var parentNode = node.ancestor('.settings-wrapper');
    inspector.get('model').set('config', {admins: 'g:s'});
    changeForm(viewlet, 'admins', 'k:t');
    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'), 'g:s');
    // 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.
    inspector = setUpInspector();
    env.connect();
    var viewlet = getViewlet(inspector);
    var node = viewlet.get('container').one('textarea[name="admins"]');
    var parentNode = node.ancestor('.settings-wrapper');
    changeForm(viewlet, 'admins', 'k:t');
    inspector.get('model').set('config', {admins: 'g:s'});
    assert.equal(
        parentNode.all('[name=admins].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'), 'g:s');
    // 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.
    inspector = setUpInspector();
    env.connect();
    var viewlet = getViewlet(inspector);
    var node = viewlet.get('container').one('textarea[name="admins"]');
    var parentNode = node.ancestor('.settings-wrapper');
    changeForm(viewlet, 'admins', 'k:t');
    inspector.get('model').set('config', {admins: 'g:s'});
    node.simulate('click');
    assert.equal(
        parentNode.all('[name=admins].conflict').size(),
        1,
        'did not find the conflict node');
    // Act.
    viewlet.get('container').one('button.cancel').simulate('click');
    // Validate.
    assert.equal(node.get('value'), 'g:s');
    // 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('[name=admins].conflict').size(),
        0,
        'found the conflict node');
  });

});
<commit_msg>Added tests for the config file upload in the service config inspector<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) 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 Settings', function() {

  var view, service, db, models, utils, juju, env, conn, container,
      inspector, Y, jujuViews, charmData;

  before(function(done) {
    var requires = ['juju-gui', 'juju-views', 'juju-tests-utils',
      'juju-charm-store', 'juju-charm-models', 'node-event-simulate'];
    Y = YUI(GlobalConfig).use(requires, function(Y) {
          utils = Y.namespace('juju-tests.utils');
          models = Y.namespace('juju.models');
          jujuViews = Y.namespace('juju.views');
          juju = Y.namespace('juju');
          charmData = utils.loadFixture(
              'data/mediawiki-api-response.json',
              true);
          done();
        });

  });

  beforeEach(function() {
    container = utils.makeContainer(this, 'container');
    conn = new utils.SocketStub();
    db = new models.Database();
    env = juju.newEnvironment({conn: conn});
    env.update_annotations = function() {};
  });

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

  var setUpInspector = function(options) {
    var charm = new models.Charm(charmData.charm),
        charmId = charm.get('id');
    db.charms.add(charm);
    if (options && options.useGhost) {
      service = db.services.ghostService(charm);
    } else {
      var parsedConfig = {};
      // because a test deletes the config data we need a check to
      // stop it from falling over.
      if (charm.get('options')) {
        Y.Object.each(charm.get('options'), function(val, key) {
          // For boolean fields the default is false, so we need to check
          // undefined directly.
          if (val['default'] !== undefined) {
            parsedConfig[key] = val['default'];
          } else {
            parsedConfig[key] = '';
          }
        });
      }
      service = new models.Service({
        id: 'mediawiki',
        charm: charmId,
        exposed: false,
        config: parsedConfig
      });
      db.services.add(service);
      db.onDelta({data: {result: [
        ['unit', 'add', {id: 'mediawiki/0', agent_state: 'pending'}],
        ['unit', 'add', {id: 'mediawiki/1', agent_state: 'pending'}],
        ['unit', 'add', {id: 'mediawiki/2', agent_state: 'pending'}]
      ]}});
    }
    var fakeStore = new Y.juju.charmworld.APIv3({});
    fakeStore.iconpath = function() {
      return 'charm icon url';
    };
    view = new jujuViews.environment({
      container: container,
      db: db,
      env: env,
      store: fakeStore
    });
    view.render();
    Y.Node.create([
      '
'
    ].join('')).appendTo(container);
    return view.createServiceInspector(service, {databinding: {interval: 0}});
  };

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

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

  it('properly renders a service without charm options', function() {
    // Mutate charmData before the render.
    delete charmData.charm.options;
    inspector = setUpInspector();
    // Verify the viewlet rendered, previously it would raise.
    assert.isObject(container.one('.config-file'));
    // Restore the test global
    charmData = utils.loadFixture('data/mediawiki-api-response.json', true);
  });

  it('properly renders charm options with booleans', function() {
    inspector = setUpInspector();
    // Verify the viewlet rendered, previously it would raise.
    assert.isObject(container.one('.config-file'));
    // Restore the test global
    charmData = utils.loadFixture('data/mediawiki-api-response.json', true);

    // Verify we find our checkbox Also note that it's hidden because we're
    // using the slider markup and styling for boolean fields.
    assert.equal(
        container.all('input.hidden-checkbox').size(),
        1,
        'did not render one boolean field');

    // Verify that the textual representation is there.
    assert.equal(
        container.all('.textvalue').size(),
        1,
        'can not find the textual value for the checkbox.');

    // And the value will toggle with the checkbox
    var debugContainer = container.one('.toggle-debug').get('parentNode');
    assert.equal(
        debugContainer.one('.textvalue').get('text').replace(/\s/g, ''),
        'false');
    debugContainer.one('label').simulate('click');
    assert.equal(
        debugContainer.one('.textvalue').get('text').replace(/\s/g, ''),
        'true');
  });

  /**** Begin service destroy UI tests. ****/

  it('has a button to destroy the service', function() {
    inspector = setUpInspector();
    assert.isObject(container.one('.destroy-service-trigger span'));
  });

  it('shows the destroy service prompt if the trigger is clicked', function() {
    inspector = setUpInspector();
    var promptBox = container.one('.destroy-service-prompt');
    assert.isTrue(promptBox.hasClass('closed'));
    container.one('.destroy-service-trigger span').simulate('click');
    assert.isFalse(promptBox.hasClass('closed'));
  });

  it('hides the destroy service prompt if cancel is clicked', function() {
    inspector = setUpInspector();
    var promptBox = container.one('.destroy-service-prompt');
    assert.isTrue(promptBox.hasClass('closed'));
    // First we have to open the prompt.
    container.one('.destroy-service-trigger span').simulate('click');
    assert.isFalse(promptBox.hasClass('closed'));
    // Now we can close it.
    container.one('.cancel-destroy').simulate('click');
    assert.isTrue(promptBox.hasClass('closed'));
  });

  it('initiates a destroy if the "Destroy" button is clicked', function(done) {
    inspector = setUpInspector();
    var promptBox = container.one('.destroy-service-prompt');
    // First we have to open the prompt.
    container.one('.destroy-service-trigger span').simulate('click');
    assert.isFalse(promptBox.hasClass('closed'));
    // If the test times out, it failed (because the expected function call
    // didn't happen).
    inspector.initiateServiceDestroy = function() {
      done();
    };
    container.one('.initiate-destroy').simulate('click');
  });

  it('wires up UI elements to handlers for service inspector', function() {
    // There are UI elements and they all have to be wired up to something.
    inspector = setUpInspector();
    var events = inspector.constructor.prototype.events;
    assert.equal(
        typeof events['.destroy-service-trigger span'].click, 'string');
    assert.equal(typeof events['.initiate-destroy'].click, 'string');
    assert.equal(typeof events['.cancel-destroy'].click, 'string');
  });

  it('responds to service removal failure by alerting the user', function() {
    var notificationAdded;

    inspector = setUpInspector();

    var SERVICE_NAME = 'the name of the service being removed';
    var evt = {
      err: true,
      service_name: SERVICE_NAME
    };

    var db = {
      notifications: {
        add: function(notification) {
          var attrs = notification.getAttrs();
          // The notification has the required attributes.
          assert.isTrue(attrs.hasOwnProperty('title'));
          assert.isTrue(attrs.hasOwnProperty('message'));
          // The service name is mentioned in the error message.
          assert.notEqual(attrs.message.indexOf(SERVICE_NAME, -1));
          assert.equal(attrs.level, 'error');
          assert.deepEqual(attrs.modelId, ['service', 'mediawiki']);
          notificationAdded = true;
        }
      }
    };

    inspector._destroyServiceCallback(service, db, evt);
    assert.isTrue(notificationAdded);
  });

  /**** End service destroy UI tests. ****/

  describe('config file upload', function() {
    it('hides the configuration inputs when a file is uploaded', function() {
      inspector = setUpInspector();
      var fileContents = 'yaml yaml yaml';
      inspector.views.config
               .onFileLoaded('a.yaml', {target: {result: fileContents}});
      assert.deepEqual(inspector.configFileContent, fileContents);
      var settings = inspector.get('container')
                              .all('.charm-settings, .settings-wrapper.toggle');
      settings.each(function(node) {
        assert.equal(node.getStyle('display'), 'none');
      });
    });

    it('restores file input when config is removed', function() {
      inspector = setUpInspector();
      container = inspector.get('container');
      var fileContents = 'yaml yaml yaml';
      inspector.views.config
               .onFileLoaded('a.yaml', {target: {result: fileContents}});
      assert.equal(inspector.configFileContent, fileContents);
      var settings = container.all('.charm-settings, .settings-wrapper.toggle');
      settings.each(function(node) {
        assert.equal(node.getStyle('display'), 'none');
      });
      // Load the file.
      inspector.views.config
               .onFileLoaded('a.yaml', {target: {result: fileContents}});
      // And then click to remove it.
      container.one('.config-file .fakebutton').simulate('click');
      // The content should be gone now.
      assert.equal(inspector.configFileContent, undefined);
      assert.equal(container.one('.config-file input').get('files').size(), 0);
      assert.equal(
          container.one('.config-file .fakebutton').getContent(),
          'Import config file...'
      );
    });

    it('is able to set_config with configuration from a file', function(done) {
      inspector = setUpInspector();
      container = inspector.views.config.get('container');
      var env = view.get('env');
      var config_raw = 'admins: \n user:pass';
      var oldSetConfig = env.set_config;
      env.set_config = function(
          serviceName, config, data, serviceConfig, callback) {
        assert.equal(serviceName, 'mediawiki');
        assert.isNull(config);
        assert.equal(data, config_raw);
        assert.isObject(serviceConfig);
        assert.isFunction(callback);
        env.set_config = oldSetConfig;
        done();
      };
      inspector.views.config
               .onFileLoaded('a.yaml', {target: {result: config_raw}});
      var confirmBtn = container.one('.confirm');
      confirmBtn.simulate('click');
    });
  });

  it('saves changes to settings values', function() {
    inspector = setUpInspector();
    env.connect();
    var vmContainer = inspector.get('container'),
        input = vmContainer.one('textarea[name=admins]'),
        button = vmContainer.one('.configuration-buttons .confirm');

    assert.equal(db.services.item(0).get('config').admins, '');
    input.set('value', 'foo');
    // Force the databinding to notice the change in-line.
    inspector.bindingEngine._nodeChanged(
        input, inspector.views.config);
    button.simulate('click');
    var message = env.ws.last_message();
    assert.equal('foo', message.Params.Options.admins);
    // Send back a success message.
    env.ws.msg({RequestId: message.RequestId});
    assert.equal(button.getHTML(), 'Save changes');
    assert.isTrue(input.hasClass('change-saved'));
  });

  it('can cancel changes', function() {
    // Set up.
    inspector = setUpInspector();
    env.connect();
    var viewlet = getViewlet(inspector);
    var node = viewlet.get('container')
                      .one('textarea[data-bind="config.admins"]');
    var parentNode = node.ancestor('.settings-wrapper');
    inspector.get('model').set('config', {admins: 'g:s'});
    changeForm(viewlet, 'admins', 'k:t');
    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'), 'g:s');
    // 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.
    inspector = setUpInspector();
    env.connect();
    var viewlet = getViewlet(inspector);
    var node = viewlet.get('container').one('textarea[name="admins"]');
    var parentNode = node.ancestor('.settings-wrapper');
    changeForm(viewlet, 'admins', 'k:t');
    inspector.get('model').set('config', {admins: 'g:s'});
    assert.equal(
        parentNode.all('[name=admins].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'), 'g:s');
    // 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.
    inspector = setUpInspector();
    env.connect();
    var viewlet = getViewlet(inspector);
    var node = viewlet.get('container').one('textarea[name="admins"]');
    var parentNode = node.ancestor('.settings-wrapper');
    changeForm(viewlet, 'admins', 'k:t');
    inspector.get('model').set('config', {admins: 'g:s'});
    node.simulate('click');
    assert.equal(
        parentNode.all('[name=admins].conflict').size(),
        1,
        'did not find the conflict node');
    // Act.
    viewlet.get('container').one('button.cancel').simulate('click');
    // Validate.
    assert.equal(node.get('value'), 'g:s');
    // 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('[name=admins].conflict').size(),
        0,
        'found the conflict node');
  });

});
<|endoftext|>


<commit_before>//Click on icon to slide in modal. Click on option in modal to change view.

function namify(string) {
  return string.split('-').map(function(val) {return val[0].toUpperCase() + val.slice(1)}).join(' ');
}

$('#nav-icon').on('click', function() {
  console.log('nav click');
  $navMenu = $('nav');

  $navMenu.show().animate({right: '+=50%'});
});

$('nav').on('click', 'li', function() {
  var navSelection = $(this).data('selection');

  $('nav').hide().css('right', '-50%')
  $('header').removeClass().addClass(navSelection + '-header-color');
  $('header > h1').text(namify(navSelection));
  $('main').empty();

  if(navSelection !== 'gamerizer') {
    $('main').load('html/' + navSelection + '.html', function() {
      $.getScript('scripts/' + navSelection + '.js');
    });
  }
});
<commit_msg>Cleaned up nav click-event function.<commit_after>//Click on icon to slide in modal. Click on option in modal to change view.

function namify(string) {
  return string.split('-').map(function(val) {return val[0].toUpperCase() + val.slice(1)}).join(' ');
}

$('#nav-icon').on('click', function() {
  $('nav').show().animate({right: '+=50%'});
});

$('nav').on('click', 'li', function() {
  var navSelection = $(this).data('selection');

  $('nav').hide().css('right', '-50%')
  $('header').removeClass().addClass(navSelection + '-header-color');
  $('header > h1').text(namify(navSelection));
  $('main').empty();

  if(navSelection !== 'gamerizer') {
    $('main').load('html/' + navSelection + '.html', function() {
      $.getScript('scripts/' + navSelection + '.js');
    });
  }
});
<|endoftext|>


<commit_before>'use strict';

var titleize = require('titleize');
var chalk = require('chalk');
var DEFAULT_PLUGIN_OPTIONS = require('./defaultPluginOptions');

var _promptOptions = [];

module.exports = function() {

	return {
		getNewCommandPromptOptions: getNewCommandPromptOptions
	}

}

function getNewCommandPromptOptions() {
	 return setPromptOptionsData();
}

function setPromptOptionsData() {
	_promptOptions.push(getProjectTypePromptOptions());
	_promptOptions.push(getProjectNamePromptOptions());
	_promptOptions.push(getProjectAuthorPromptOptions())
	_promptOptions.push(getProjectDescriptionPromptOptions());
	_promptOptions.push(getCartridgeModulesPromptOptions())
	_promptOptions.push(getUserConfirmCopyPromptOptions())

	return Promise.resolve(_promptOptions);
}

function getCartridgeModulesPromptOptions() {
	return {
		type: 'checkbox',
		name: 'cartridgeModules',
		message: 'What modules would you like included?',
		choices: DEFAULT_PLUGIN_OPTIONS
	}
}

function getProjectTypePromptOptions() {
	return {
		type: 'list',
		name: 'projectType',
		message: 'What is the project type?',
		choices: [
			'Dot NET',
			'Static Website'
		]
	}
}

function getProjectNamePromptOptions() {
	return {
		type: 'input',
		name: 'projectName',
		message: 'What is the project name?',
		validate: function(value) { return inputNotEmpty(value, 'Project Name'); },
	}
}

function getProjectAuthorPromptOptions() {
	return {
		type: 'input',
		name: 'projectAuthor',
		message: 'Who is the author of the project?',
		validate: function(value) { return inputNotEmpty(value, 'Author'); },
		filter: function(value) { return titleize(value); }
	}
}

function getProjectDescriptionPromptOptions() {
	return {
		type: 'input',
		name: 'projectDescription',
		message: 'What is the project description?',
		default: function () { return ''; }
	}
}

function getUserConfirmCopyPromptOptions() {
	return {
		type: 'confirm',
		name: 'isOkToCopyFiles',
		message: 'Read to start setup! Press enter to confirm',
		default: true
	}
}

function inputNotEmpty(value, fieldName) {
	var isValid = (value !== '');

	return (isValid) ? true : fieldName + ' cannot be empty' ;
}
<commit_msg>Fix a typo in the promptOptions<commit_after>'use strict';

var titleize = require('titleize');
var chalk = require('chalk');
var DEFAULT_PLUGIN_OPTIONS = require('./defaultPluginOptions');

var _promptOptions = [];

module.exports = function() {

	return {
		getNewCommandPromptOptions: getNewCommandPromptOptions
	}

}

function getNewCommandPromptOptions() {
	 return setPromptOptionsData();
}

function setPromptOptionsData() {
	_promptOptions.push(getProjectTypePromptOptions());
	_promptOptions.push(getProjectNamePromptOptions());
	_promptOptions.push(getProjectAuthorPromptOptions())
	_promptOptions.push(getProjectDescriptionPromptOptions());
	_promptOptions.push(getCartridgeModulesPromptOptions())
	_promptOptions.push(getUserConfirmCopyPromptOptions())

	return Promise.resolve(_promptOptions);
}

function getCartridgeModulesPromptOptions() {
	return {
		type: 'checkbox',
		name: 'cartridgeModules',
		message: 'What modules would you like included?',
		choices: DEFAULT_PLUGIN_OPTIONS
	}
}

function getProjectTypePromptOptions() {
	return {
		type: 'list',
		name: 'projectType',
		message: 'What is the project type?',
		choices: [
			'Dot NET',
			'Static Website'
		]
	}
}

function getProjectNamePromptOptions() {
	return {
		type: 'input',
		name: 'projectName',
		message: 'What is the project name?',
		validate: function(value) { return inputNotEmpty(value, 'Project Name'); },
	}
}

function getProjectAuthorPromptOptions() {
	return {
		type: 'input',
		name: 'projectAuthor',
		message: 'Who is the author of the project?',
		validate: function(value) { return inputNotEmpty(value, 'Author'); },
		filter: function(value) { return titleize(value); }
	}
}

function getProjectDescriptionPromptOptions() {
	return {
		type: 'input',
		name: 'projectDescription',
		message: 'What is the project description?',
		default: function () { return ''; }
	}
}

function getUserConfirmCopyPromptOptions() {
	return {
		type: 'confirm',
		name: 'isOkToCopyFiles',
		message: 'Ready to start setup! Press enter to confirm',
		default: true
	}
}

function inputNotEmpty(value, fieldName) {
	var isValid = (value !== '');

	return (isValid) ? true : fieldName + ' cannot be empty' ;
}
<|endoftext|>


<commit_before>#!/usr/bin/env node

// To invoke this from the commandline you need the following to env vars to exist:
//
// S3_BUCKET_NAME
// TRAVIS_BRANCH
// TRAVIS_TAG
// TRAVIS_COMMIT
// S3_SECRET_ACCESS_KEY
// S3_ACCESS_KEY_ID
//
// Once you have those you execute with the following:
//
// ```sh
// ./bin/publish_to_s3.js
// ```
var S3Publisher = require('ember-publisher');
var configPath = require('path').join(__dirname, '../config/s3ProjectConfig.js');
publisher = new S3Publisher({ projectConfigPath: configPath });

// Always use wildcard section of project config.
// This is useful when the including library does not
// require channels (like in ember.js / ember-data).
publisher.currentBranch = function() {
  return (process.env.TRAVIS_BRANCH === 'master') ? 'wildcard' : 'no-op';
};
publisher.publish();

<commit_msg>Update S3 publishing credentials<commit_after>#!/usr/bin/env node

// To invoke this from the commandline you need the following to env vars to exist:
//
// S3_BUCKET_NAME
// TRAVIS_BRANCH
// TRAVIS_TAG
// TRAVIS_COMMIT
// S3_SECRET_ACCESS_KEY
// S3_ACCESS_KEY_ID
//
// Once you have those you execute with the following:
//
// ```sh
// ./bin/publish_to_s3.js
// ```
var S3Publisher = require('ember-publisher');
var configPath = require('path').join(__dirname, '../config/s3ProjectConfig.js');
-publisher = new S3Publisher({
-  projectConfigPath: configPath,
 -  S3_BUCKET_NAME: 'rsvpjs-builds',
 -  S3_ACCESS_KEY_ID: process.env.AWS_ACCESS_KEY_ID,
 -  S3_SECRET_ACCESS_KEY: process.env.AWS_SECRET_ACCESS_KEY
 -});

// Always use wildcard section of project config.
// This is useful when the including library does not
// require channels (like in ember.js / ember-data).
publisher.currentBranch = function() {
  return (process.env.TRAVIS_BRANCH === 'master') ? 'wildcard' : 'no-op';
};
publisher.publish();

<|endoftext|>


<commit_before>/*
Scroll Class
Version: 3.0
Developer: Jonathan Chute
Year: 2016
*/
(function( $ ) {
    $.fn.scrollClass = function(options) {
        if($(this)[0] === undefined) return;

        var errStyle = 'font-style: italic; color: #FF7722;';

        var settings = $.extend( {
                'target': ['top'],
                'class': ['scrolled'],
                'showDirections': false
            }, options );

        var mainObj = $(this),
            currPos = {top: $(window).scrollTop(), left: $(window).scrollLeft()},
            prevPos = currPos;

        settings.target = convertToArray(settings.target);
        settings.class  = convertToArray(settings.class);

        // Set Classes
        for(var i = 0; i < settings.target.length; i++) {
            if(settings.class[i] === undefined || settings.class[i] === '') {
                if(i == 0) {
                    settings.class[i] = 'scrolled';
                } else {
                    settings.class[i] = settings.class[0] + '-' + i;
                }
            }
        }

        // Set Targets
        for(var i = 0; i < settings.target.length; i++) {
            // When a jQuery Element is used
            if(settings.target[i] instanceof jQuery) {
                if(settings.target[i].length > 0) {
                    for(var x = 0; x < settings.target[i].length; x++) {
                        if(x == 0) continue;
                        settings.target.splice(i + x, 0, settings.target[i].eq(x).offset().top);
                        settings.class.splice(i + x, 0, settings.class[i] + '-' + x);
                    }
                    settings.target.splice(i, 1, settings.target[i].first().offset().top);
                } else {
                    settings.target[i] = undefined;
                }
            }

            if(settings.target[i] === undefined) {
                console.log('%cWarning: An element is missing from the page. The rule has been ignored.', errStyle);
                settings.target.splice(i, 1);
                settings.class.splice(i, 1);
                i--;
            } else {
                settings.target[i] = convertToPixel(settings.target[i], i);
            }
        }

        function checkScroll() {
            currPos = {top: $(window).scrollTop(), left: $(window).scrollLeft()};

            for(var i = 0; i < settings.target.length; i++) {
                if(currPos.top >= settings.target[i]) {
                    mainObj.addClass(settings.class[i]);
                } else {
                    mainObj.removeClass(settings.class[i]);
                }
            }

            if(settings.showDirections && currPos.left == prevPos.left) {
                mainObj.removeClass('no-scroll up-scroll down-scroll');
                if(currPos.top > prevPos.top) {
                    if(prevPos.top > 0) {
                        mainObj.addClass('down-scroll');
                    } else {
                        mainObj.addClass('up-scroll');
                    }
                } else if(currPos.top < prevPos.top){
                    if(prevPos.top < $(document).height() - $(window).height()) {
                        mainObj.addClass('up-scroll');
                    } else {
                        mainObj.addClass('down-scroll');
                    }
                } else {
                    mainObj.addClass('no-scroll');
                }
            }

            prevPos = currPos;
        } checkScroll(); $(window).scroll(checkScroll);

        function addSuffix(number) {
            number = number.toString();
            if(number.slice(-1) == 1 && number != 11) number += 'st';
            else if(number.slice(-1) == 2 && number != 12) number += 'nd';
            else if(number.slice(-1) == 3 && number != 13) number += 'rd';
            else number += 'th';
            return number;
        }

        function convertToArray(value) {
            if(value.constructor !== Array) {
                value = [value];
            }
            return value;
        }

        function convertToPixel(value, index) {
            value = value.toString();

            var docHeight = $(document).height(),
                winHeight = $(window).height(),
                winWidth = $(window).innerWidth(),
                unit = '';

            if(value.slice(-1) == '%') {
                unit = '%';
                value = value.slice(0, -1);
            }
            if($.inArray(value.slice(-2), ['px', 'vw', 'vh']) != -1) {
                unit = value.slice(-2);
                value = value.slice(0, -2)
            }

            if(value == 'top') value = 1;
            if(value == 'middle') value = (docHeight / 2) - (winHeight / 2);
            if(value == 'bottom') value = docHeight - winHeight;

            if(unit == '%') value = value * (docHeight / 100);
            if(unit == 'vh') value = value * (winHeight / 100);
            if(unit == 'vw') value = value * (winWidth / 100);

            if(isNaN(value)) {
                console.log('%cWarning: "' + value + '" is not a valid value for "target".', errStyle);

                value = -1;
            }

            return parseInt(value);
        }
    };
})( jQuery );
<commit_msg>Update scrollclass.js<commit_after>/*
Scroll Class
Version: 3.1
Developer: Jonathan Chute
Year: 2016
*/
(function( $ ) {
    $.fn.scrollClass = function(options) {
        if($(this)[0] === undefined) return;

        var errStyle = 'font-style: italic; color: #FF7722;';

        var settings = $.extend( {
                'target': ['top'],
                'class': ['scrolled'],
                'showDirections': false
            }, options );

        var mainObj = $(this),
            currPos = {top: $(window).scrollTop(), left: $(window).scrollLeft()},
            prevPos = currPos;

        settings.target = convertToArray(settings.target);
        settings.class  = convertToArray(settings.class);

        // Set Classes
        for(var i = 0; i < settings.target.length; i++) {
            if(settings.class[i] === undefined || settings.class[i] === '') {
                if(i == 0) {
                    settings.class[i] = 'scrolled';
                } else {
                    settings.class[i] = settings.class[0] + '-' + i;
                }
            }
        }

        // Set Targets
        for(var i = 0; i < settings.target.length; i++) {
            // When a jQuery Element is used
            if(settings.target[i] instanceof jQuery) {
                if(settings.target[i].length > 0) {
                    for(var x = 0; x < settings.target[i].length; x++) {
                        if(x == 0) continue;
                        settings.target.splice(i + x, 0, settings.target[i].eq(x).offset().top);
                        settings.class.splice(i + x, 0, settings.class[i] + '-' + x);
                    }
                    settings.target.splice(i, 1, settings.target[i].first().offset().top);
                } else {
                    settings.target[i] = undefined;
                }
            }

            if(settings.target[i] === undefined) {
                console.log('%cWarning: An element is missing from the page. The rule has been ignored.', errStyle);
                settings.target.splice(i, 1);
                settings.class.splice(i, 1);
                i--;
            }
        }

        function checkScroll() {
            currPos = {top: $(window).scrollTop(), left: $(window).scrollLeft()};

            for(var i = 0; i < settings.target.length; i++) {
                if(currPos.top >= convertToPixel(settings.target[i], i)) {
                    mainObj.addClass(settings.class[i]);
                } else {
                    mainObj.removeClass(settings.class[i]);
                }
            }

            if(settings.showDirections && currPos.left == prevPos.left) {
                mainObj.removeClass('no-scroll up-scroll down-scroll');
                if(currPos.top > prevPos.top) {
                    if(prevPos.top > 0) {
                        mainObj.addClass('down-scroll');
                    } else {
                        mainObj.addClass('up-scroll');
                    }
                } else if(currPos.top < prevPos.top){
                    if(prevPos.top < $(document).height() - $(window).height()) {
                        mainObj.addClass('up-scroll');
                    } else {
                        mainObj.addClass('down-scroll');
                    }
                } else {
                    mainObj.addClass('no-scroll');
                }
            }

            prevPos = currPos;
        }

        checkScroll(); $(window).scroll(checkScroll);

        function addSuffix(number) {
            number = number.toString();
            if(number.slice(-1) == 1 && number != 11) number += 'st';
            else if(number.slice(-1) == 2 && number != 12) number += 'nd';
            else if(number.slice(-1) == 3 && number != 13) number += 'rd';
            else number += 'th';
            return number;
        }

        function convertToArray(value) {
            if(value.constructor !== Array) {
                value = [value];
            }
            return value;
        }

        function convertToPixel(value, index) {
            value = value.toString();

            var bodyHeight = $('body').height(),
                bodyWidth = $('body').width(),
                winHeight = $(window).height(),
                unit = '';

            if(value.slice(-1) == '%') {
                unit = '%';
                value = value.slice(0, -1);
            }
            if($.inArray(value.slice(-2), ['px', 'vw', 'vh']) != -1) {
                unit = value.slice(-2);
                value = value.slice(0, -2)
            }

            if(value == 'top') value = 1;
            if(value == 'middle') value = (bodyHeight / 2) - (winHeight / 2);
            if(value == 'bottom') value = bodyHeight - winHeight;

            console.log('Document Height: ' + bodyHeight);
            console.log('Window Height: ' + winHeight);

            if(unit == '%') value = value * (bodyHeight / 100);
            if(unit == 'vh') value = value * (winHeight / 100);
            if(unit == 'vw') value = value * (bodyWidth / 100);

            if(isNaN(value)) {
                console.log('%cWarning: "' + value + '" is not a valid value for "target".', errStyle);

                value = -1;
            }

            return parseInt(value);
        }
    };
})( jQuery );
<|endoftext|>


<commit_before>'use strict';

var colors = require('colors');
var expect = require('chai').expect;
var path = require('path');
var sinon = require('sinon');
var _ = require('underscore');

describe('cli : facade : publish', function(){

  var Registry = require('../../cli/domain/registry'),
      registry = new Registry(),
      consoleMock = require('../mocks/console'),
      Local = require('../../cli/domain/local'),
      local = new Local(),
      PublishFacade = require('../../cli/facade/publish'),
      publishFacade = new PublishFacade({ registry: registry, local: local, logger: consoleMock }),
      logs;

  var execute = function(done){
    consoleMock.reset();
    publishFacade({ componentPath: path.resolve('test/fixtures/components/hello-world/') });
    logs = consoleMock.get();
    setTimeout(_.isFunction(done) ? done : _.noop, 10);
  };

  afterEach(consoleMock.reset);

  describe('when publishing component', function(){

    describe('when api is not valid', function(){

      beforeEach(function(done){
        sinon.stub(registry, 'get').yields('an error!');
        execute(done);
      });

      afterEach(function(){
        registry.get.restore();
      });

      it('should show an error', function(){
        expect(logs[0]).to.equal('an error!'.red);
      });
    });

    describe('when api is valid', function(){

      beforeEach(function(done){
        sinon.stub(registry, 'get').yields(null, ['http://www.api.com']);
        execute(done);
      });

      afterEach(function(){
        registry.get.restore();
      });

      it('should show a message', function(){
        expect(logs[0]).to.include('Packaging -> ');
        expect(logs[0]).to.include('components/hello-world/_package');
      });

      describe('when packaging', function(){

        describe('when a component is not valid', function(){

          beforeEach(function(done){
            sinon.stub(local, 'package').yields('the component is not valid');
            execute(done);
          });

          afterEach(function(){
            local.package.restore();
          });

          it('should show an error', function(){
            expect(logs[1]).to.equal('An error happened when creating the package: the component is not valid'.red);
          });
        });

        describe('when a component is valid', function(){

          describe('when creating tar.gz archive', function(){

            beforeEach(function(){
              sinon.stub(local, 'package').yields(null, {
                name: 'hello-world',
                version: '1.0.0'
              });
              sinon.stub(local, 'compress').yields(null);
            });

            afterEach(function(){
              local.package.restore();
              local.compress.restore();
            });

            it('should show a message', function(){
              expect(logs[1]).to.include('Compressing -> ');
              expect(logs[1]).to.include('components/hello-world/package.tar.gz');
            });

            describe('when publishing', function(){

              it('should show a message', function(done){
                sinon.stub(registry, 'putComponent').yields('blabla');
                execute(function(){
                  expect(logs[2]).to.include('Publishing -> ');
                  registry.putComponent.restore();
                  done();
                });
              });

              describe('when error happens', function(){

                beforeEach(function(done){
                  sinon.stub(registry, 'putComponent').yields('nope!');
                  execute(done);
                });

                afterEach(function(){
                  registry.putComponent.restore();
                });

                it('should show an error', function(){
                  expect(logs[3]).to.include('An error happened when publishing the component: nope!');
                });
              });

              describe('when it succeeds', function(){

                var stub;
                beforeEach(function(done){
                  sinon.stub(registry, 'putComponent').yields(null, 'yay');
                  stub = sinon.stub(local, 'cleanup');
                  execute(done);
                });

                afterEach(function(){
                  registry.putComponent.restore();
                  local.cleanup.restore();
                });

                it('should show a message', function(){
                  expect(logs[3]).to.include('Component published -> ');
                  expect(logs[3]).to.include('http://www.api.com/hello-world/1.0.0');
                });

                it('should remove the compressed package', function(){
                  expect(stub.calledOnce).to.be.true;
                });
              });
            });
          });
        });
      });
    });
  });
});
<commit_msg>Test fix<commit_after>'use strict';

var colors = require('colors');
var expect = require('chai').expect;
var path = require('path');
var sinon = require('sinon');
var _ = require('underscore');

describe('cli : facade : publish', function(){

  var Registry = require('../../cli/domain/registry'),
      registry = new Registry(),
      consoleMock = require('../mocks/console'),
      Local = require('../../cli/domain/local'),
      local = new Local(),
      PublishFacade = require('../../cli/facade/publish'),
      publishFacade = new PublishFacade({ registry: registry, local: local, logger: consoleMock }),
      logs;

  var execute = function(){
    consoleMock.reset();
    publishFacade({ componentPath: path.resolve('test/fixtures/components/hello-world/') });
    logs = consoleMock.get();
  };

  afterEach(consoleMock.reset);

  describe('when publishing component', function(){

    describe('when api is not valid', function(){

      beforeEach(function(){
        sinon.stub(registry, 'get').yields('an error!');
        execute();
      });

      afterEach(function(){
        registry.get.restore();
      });

      it('should show an error', function(){
        expect(logs[0]).to.equal('an error!'.red);
      });
    });

    describe('when api is valid', function(){

      beforeEach(function(){
        sinon.stub(registry, 'get').yields(null, ['http://www.api.com']);
      });

      afterEach(function(){
        registry.get.restore();
      });

      it('should show a message', function(){
        sinon.stub(local, 'package').yields('the component is not valid');
        execute();
        local.package.restore();
        expect(logs[0]).to.include('Packaging -> ');
        expect(logs[0]).to.include('components/hello-world/_package');
      });

      describe('when packaging', function(){

        describe('when a component is not valid', function(){

          beforeEach(function(){
            sinon.stub(local, 'package').yields('the component is not valid');
            execute();
          });

          afterEach(function(){
            local.package.restore();
          });

          it('should show an error', function(){
            expect(logs[1]).to.equal('An error happened when creating the package: the component is not valid'.red);
          });
        });

        describe('when a component is valid', function(){

          describe('when creating tar.gz archive', function(){

            beforeEach(function(){
              sinon.stub(local, 'package').yields(null, {
                name: 'hello-world',
                version: '1.0.0'
              });
              sinon.stub(local, 'compress').yields(null);
              execute();
            });

            afterEach(function(){
              local.package.restore();
              local.compress.restore();
            });

            it('should show a message', function(){
              expect(logs[1]).to.include('Compressing -> ');
              expect(logs[1]).to.include('components/hello-world/package.tar.gz');
            });

            describe('when publishing', function(){

              it('should show a message', function(){
                sinon.stub(registry, 'putComponent').yields('blabla');
                execute();
                expect(logs[2]).to.include('Publishing -> ');
                registry.putComponent.restore();
              });

              describe('when error happens', function(){

                beforeEach(function(){
                  sinon.stub(registry, 'putComponent').yields('nope!');
                  execute();
                });

                afterEach(function(){
                  registry.putComponent.restore();
                });

                it('should show an error', function(){
                  expect(logs[3]).to.include('An error happened when publishing the component: nope!');
                });
              });

              describe('when it succeeds', function(){

                var stub;
                beforeEach(function(){
                  sinon.stub(registry, 'putComponent').yields(null, 'yay');
                  stub = sinon.stub(local, 'cleanup');
                  execute();
                });

                afterEach(function(){
                  registry.putComponent.restore();
                  local.cleanup.restore();
                });

                it('should show a message', function(){
                  expect(logs[3]).to.include('Component published -> ');
                  expect(logs[3]).to.include('http://www.api.com/hello-world/1.0.0');
                });

                it('should remove the compressed package', function(){
                  expect(stub.calledOnce).to.be.true;
                });
              });
            });
          });
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>var keystone = require('../../../../index.js');
var demand = require('must');

keystone.mongoose = require('../../../helpers/getMongooseConnection.js');

keystone.import('../models');

var DependsOn = keystone.list('DependsOn');

describe('Test dependsOn and required', function() {

    it('Ignore required if evalDependsOn is not `true` by setting `state` to `draft`', function(done) {
        // remove any Post documents
        DependsOn.model.find({}).remove(function(error) {
            if (error) {
                done(error);
            }

			var newPost = new DependsOn.model({
				title: 'new post',
				state: 'draft'
			});

            newPost.save(done);

        });
    });

    it('Save will fail if `state` set to `published` and `publishedDate` is not defined', function(done) {
        // remove any Post documents
        DependsOn.model.find({}).remove(function(error) {
            if (error) {
                done(error);
            }

			var newPost = new DependsOn.model({
				title: 'new post',
				state: 'published'
			});
            newPost.save(function(err) {
				demand(err).be.a.object();
				done();
			});

        });

    });

    it('Save will succeed if `state` set to `published` and `publishedDate` is defined', function(done) {

        // remove any Post documents
        DependsOn.model.find({}).remove(function(error) {
            if (error) {
                done(error);
            }

			var newPost = new DependsOn.model({
				title: 'new post',
				state: 'published',
				publishedDate: new Date()
			});
            newPost.save(done);

        });
    });

    after(function(done) {
        // remove any remaining test data
        DependsOn.model.find({}).remove(function(error) {
            done(error);
        });
    });
});
<commit_msg>Fixing inconsistent whitespace in dependsOn test<commit_after>var keystone = require('../../../../index.js');
var demand = require('must');

keystone.mongoose = require('../../../helpers/getMongooseConnection.js');

keystone.import('../models');

var DependsOn = keystone.list('DependsOn');

describe('Test dependsOn and required', function() {

	it('Ignore required if evalDependsOn is not `true` by setting `state` to `draft`', function(done) {
		// remove any Post documents
		DependsOn.model.find({}).remove(function(error) {
			if (error) {
				done(error);
			}

			var newPost = new DependsOn.model({
				title: 'new post',
				state: 'draft'
			});

			newPost.save(done);

		});
	});

	it('Save will fail if `state` set to `published` and `publishedDate` is not defined', function(done) {
		// remove any Post documents
		DependsOn.model.find({}).remove(function(error) {
			if (error) {
				done(error);
			}

			var newPost = new DependsOn.model({
				title: 'new post',
				state: 'published'
			});
			newPost.save(function(err) {
				demand(err).be.a.object();
				done();
			});

		});

	});

	it('Save will succeed if `state` set to `published` and `publishedDate` is defined', function(done) {

		// remove any Post documents
		DependsOn.model.find({}).remove(function(error) {
			if (error) {
				done(error);
			}

			var newPost = new DependsOn.model({
				title: 'new post',
				state: 'published',
				publishedDate: new Date()
			});
			newPost.save(done);

		});
	});

	after(function(done) {
		// remove any remaining test data
		DependsOn.model.find({}).remove(function(error) {
			done(error);
		});
	});
});
<|endoftext|>


<commit_before>import _$ from 'jquery';
import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
import jsdom from 'jsdom';
import chai, { expect } from 'chai';
import chaiJquery from 'chai-jquery';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import reducers from 'reducers';

global.document = jsdom.jsdom('<!doctype html>');
global.window = global.document.defaultView;
global.navigator = global.window.navigator;
const $ = _$(window);

chaiJquery(chai, chai.util, $);

function renderComponent(ComponentClass, props = {}, state = {}) {
  const componentInstance =  TestUtils.renderIntoDocument(
    <Provider store={createStore(reducers, state)}>
      <ComponentClass {...props} />
    </Provider>
  );

  return $(ReactDOM.findDOMNode(componentInstance));
}

$.fn.simulate = function(eventName, value) {
  if (value) {
    this.val(value);
  }
  TestUtils.Simulate[eventName](this[0]);
};

export { renderComponent, expect };
<commit_msg>eslint<commit_after>import _$ from 'jquery';
import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
import jsdom from 'jsdom';
import chai, { expect } from 'chai';
import assert from 'assert';
import chaiJquery from 'chai-jquery';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import reducers from 'reducers';

global.document = jsdom.jsdom('<!doctype html>');
global.window = global.document.defaultView;
global.navigator = global.window.navigator;
const $ = _$(window);

chaiJquery(chai, chai.util, $);

const renderComponent = (ComponentClass, props = {}, state = {}) => {
  const componentInstance = TestUtils.renderIntoDocument(
    <Provider store={createStore(reducers, state)}>
      <ComponentClass {...props} />
    </Provider>
  );

  // eslint-disable-next-line react/no-find-dom-node
  return $(ReactDOM.findDOMNode(componentInstance));
};

$.fn.simulate = (eventName, value) => {
  if (value) {
    this.val(value);
  }
  TestUtils.Simulate[eventName](this[0]);
};

export { renderComponent, expect, assert };
<|endoftext|>


<commit_before>import winston from 'winston';
import toggl from 'toggl-got';
import moment from 'moment';
import queue from '../queue';

const { TOGGL_WORKSPACE_ID } = process.env;

export default async function (_, done) {
  try {
    const promises = [];
    const since = moment().startOf('day').toISOString();
    const until = moment().toISOString();

    const { body } = await toggl(
      `details?workspace_id=${TOGGL_WORKSPACE_ID}&since=${since}&until=${until}&user_agent=jiggl`,
      { endpoint: 'https://toggl.com/reports/api/v2/' }
    );

    for (const entry of body.data) {
      // Filter out time entries not in TEST project when in debug mode
      if (process.env.DEBUG && entry.project.indexOf('TEST') < 0) {
        winston.debug(`Skipping time entry ${entry.id}`);
        continue;
      }

      promises.push(queue.create('sync time entry', entry).priority('medium').save());
    }

    await Promise.all(promises);

    winston.info('Sucessfully schronised time entries');
    return done();
  } catch (err) {
    winston.error('Failed to synchronise time entries', err);
    return done(err);
  }
}
<commit_msg>refactor: add maximum per page for toggl report<commit_after>import winston from 'winston';
import toggl from 'toggl-got';
import moment from 'moment';
import queue from '../queue';

const { TOGGL_WORKSPACE_ID } = process.env;

export default async function (_, done) {
  try {
    const promises = [];
    const since = moment().startOf('day').toISOString();
    const until = moment().toISOString();

    const { body } = await toggl(
      `details?workspace_id=${TOGGL_WORKSPACE_ID}&since=${since}&until=${until}&per_page=50&user_agent=jiggl`, // eslint-disable-line max-len
      { endpoint: 'https://toggl.com/reports/api/v2/' }
    );

    for (const entry of body.data) {
      // Filter out time entries not in TEST project when in debug mode
      if (process.env.DEBUG && entry.project.indexOf('TEST') < 0) {
        winston.debug(`Skipping time entry ${entry.id}`);
        continue;
      }

      promises.push(queue.create('sync time entry', entry).priority('medium').save());
    }

    await Promise.all(promises);

    winston.info('Sucessfully schronised time entries');
    return done();
  } catch (err) {
    winston.error('Failed to synchronise time entries', err);
    return done(err);
  }
}
<|endoftext|>


<commit_before>// Define widget
setTimeout(function() {
	$.widget("ui.suggestions", {
		_init: function() {
			this.init();
		},

		init: function() {
			var self = this;
			var timer = null;
			var prevVal = null;

			$("#suggestions").hide();

			function doSearch() {
				var val = self.element.val();

				console.log(val);

				if (!val.length) {
					$("#suggestions").hide();
					return;
				}

				if (prevVal && val == prevVal || !val.length) {
					return;
				}

				prevVal = val;
				z_event("show_suggestions", {value: val});

				$("#suggestions").show();
			}

			self.element.on('keyup', function() {
				if (timer) {
					clearTimeout(timer);
				}

				timer = setTimeout(doSearch, 300);
			});

			$(document).mouseup(function (e) {
			    var container = $(".search-form");

			    if (!container.is(e.target) // if the target of the click isn't the container...
			        && container.has(e.target).length === 0) // ... nor a descendant of the container
			    {
			        $("#suggestions").hide();
			    }
			});
		}
	});

	// Add to widget manager.
	$.widgetManager();
}, 200);<commit_msg>[search] console log weggehaald<commit_after>// Define widget
setTimeout(function() {
	$.widget("ui.suggestions", {
		_init: function() {
			this.init();
		},

		init: function() {
			var self = this;
			var timer = null;
			var prevVal = null;

			$("#suggestions").hide();

			function doSearch() {
				var val = self.element.val();

				if (!val.length) {
					$("#suggestions").hide();
					return;
				}

				if (prevVal && val == prevVal || !val.length) {
					return;
				}

				prevVal = val;
				z_event("show_suggestions", {value: val});

				$("#suggestions").show();
			}

			self.element.on('keyup', function() {
				if (timer) {
					clearTimeout(timer);
				}

				timer = setTimeout(doSearch, 300);
			});

			$(document).mouseup(function (e) {
			    var container = $(".search-form");

			    if (!container.is(e.target) // if the target of the click isn't the container...
			        && container.has(e.target).length === 0) // ... nor a descendant of the container
			    {
			        $("#suggestions").hide();
			    }
			});
		}
	});

	// Add to widget manager.
	$.widgetManager();
}, 200);<|endoftext|>


<commit_before>/**
 *
 * @param pem
 * @returns {*}
 */
"use strict";

/**
 *
 * @param pem
 * @returns {*}
 */
module.exports = function (pem) {

    if (typeof pem !== "string") {
        pem = String(pem);
    }

    var certText = pem.split(/(\r\n|\r|\n)+/g);
    certText = certText.filter(function (line) {
        return line.trim().length !== 0;
    });

    var m = /^-----BEGIN RSA (PRIVATE|PUBLIC) KEY-----/.exec(certText[0]);
    if (!m) return undefined;

    var type = m[1].toLowerCase();

    if (certText.slice(-1)[0] !== ("-----END RSA " + m[1] + " KEY-----")) {
        return undefined;
    }

    var buf = Buffer(certText.slice(1, -1).join(""), "base64");

    var field = {};
    var size = {};
    var offset = {
        private: buf[1] & 0x80 ? buf[1] - 0x80 + 5 : 7,
        public: buf[1] & 0x80 ? buf[1] - 0x80 + 2 : 2
    }[type];

    /**
     *
     * @returns
     * @private
     */
    function __read() {
        var s = buf.readUInt8(offset + 1);

        if (s & 0x80) {
            var n = s - 0x80;
            s = buf[[
                "readUInt8", "readUInt16BE"
            ][n - 1]](offset + 2);
            offset += n;
        }

        offset += 2;

        var b = buf.slice(offset, offset + s);
        offset += s;
        return b;
    }

    field.modulus = __read();

    field.bits = (field.modulus.length - 1) * 8 + Math.ceil(
            Math.log(field.modulus[0] + 1) / Math.log(2)
        );
    field.publicExponent = parseInt(__read().toString("hex"), 16);

    if (type === "private") {
        field.privateExponent = __read();
        field.prime1 = __read();
        field.prime2 = __read();
        field.exponent1 = __read();
        field.exponent2 = __read();
        field.coefficient = __read();
    }

    return field;
};
<commit_msg>Update rsa-unpack.js<commit_after>/**
 * Modified from original at https://github.com/substack/rsa-unpack.git
 */

/**
 *
 * @param pem
 * @returns {*}
 */
"use strict";

/**
 *
 * @param pem
 * @returns {*}
 */
module.exports = function (pem) {

    if (typeof pem !== "string") {
        pem = String(pem);
    }

    var certText = pem.split(/(\r\n|\r|\n)+/g);
    certText = certText.filter(function (line) {
        return line.trim().length !== 0;
    });

    var m = /^-----BEGIN RSA (PRIVATE|PUBLIC) KEY-----/.exec(certText[0]);
    if (!m) return undefined;

    var type = m[1].toLowerCase();

    if (certText.slice(-1)[0] !== ("-----END RSA " + m[1] + " KEY-----")) {
        return undefined;
    }

    var buf = Buffer(certText.slice(1, -1).join(""), "base64");

    var field = {};
    var size = {};
    var offset = {
        private: buf[1] & 0x80 ? buf[1] - 0x80 + 5 : 7,
        public: buf[1] & 0x80 ? buf[1] - 0x80 + 2 : 2
    }[type];

    /**
     *
     * @returns
     * @private
     */
    function __read() {
        var s = buf.readUInt8(offset + 1);

        if (s & 0x80) {
            var n = s - 0x80;
            s = buf[[
                "readUInt8", "readUInt16BE"
            ][n - 1]](offset + 2);
            offset += n;
        }

        offset += 2;

        var b = buf.slice(offset, offset + s);
        offset += s;
        return b;
    }

    field.modulus = __read();

    field.bits = (field.modulus.length - 1) * 8 + Math.ceil(
            Math.log(field.modulus[0] + 1) / Math.log(2)
        );
    field.publicExponent = parseInt(__read().toString("hex"), 16);

    if (type === "private") {
        field.privateExponent = __read();
        field.prime1 = __read();
        field.prime2 = __read();
        field.exponent1 = __read();
        field.exponent2 = __read();
        field.coefficient = __read();
    }

    return field;
};
<|endoftext|>