<commit_before>/* global app, chai, sinon, AppPort, SidebarApp */
/* jshint expr:true */
"use strict";

var expect = chai.expect;

describe("SidebarApp", function() {

  var sandbox;

  beforeEach(function() {
    sandbox = sinon.sandbox.create();

    // mozSocial "mock"
    window.navigator.mozSocial = {
      getWorker: function() {
        return {port: {}};
      }
    };

    sandbox.stub(app.views, "AppView");
    sandbox.stub(AppPort.prototype, "post");
  });

  afterEach(function() {
    sandbox.restore();
    app.options.DEBUG = false;
  });

  describe("#constructor", function() {
    beforeEach(function() {
      // User prototype methods stubs
      sandbox.stub(app.models.User.prototype, "on");

      // jQuery.cookie stubs
      sandbox.stub(window.jQuery, "removeCookie");
    });

    it("should create an AppView", function() {
      new SidebarApp();

      sinon.assert.calledOnce(app.views.AppView);
    });

    it("should create an AppPport", function() {
      var sidebarApp = new SidebarApp();

      expect(sidebarApp.appPort).to.be.an.instanceOf(AppPort);
    });

    it("should create a user", function() {
      var sidebarApp = new SidebarApp();

      expect(sidebarApp.user).to.be.an.instanceOf(app.models.User);
    });

    it("should create a user list", function() {
      var sidebarApp = new SidebarApp();

      expect(sidebarApp.users).to.be.an.instanceOf(app.models.UserSet);
    });

    it("should post talkilla.sidebar-ready to the worker", function() {
      var sidebarApp = new SidebarApp();

      sinon.assert.calledOnce(sidebarApp.appPort.post);
      sinon.assert.calledWithExactly(sidebarApp.appPort.post,
                                     "talkilla.sidebar-ready");
    });

    it("should listen to the `talkilla.debug` event when debug is enabled",
      function() {
        sandbox.stub(AppPort.prototype, "on");
        app.options.DEBUG = true;
        var sidebarApp = new SidebarApp({nick: "toto"});

        sinon.assert.called(sidebarApp.appPort.on);
        sinon.assert.calledWith(sidebarApp.appPort.on, "talkilla.debug");
      });

    it("should listen to the `talkilla.users` event and update user list",
      function() {
        var sidebarApp = new SidebarApp();

        sidebarApp.appPort.trigger("talkilla.users", [
          {nick: "bob"},
          {nick: "bill"}
        ]);

        expect(sidebarApp.users).to.have.length.of(2);
        expect(sidebarApp.users.at(0).get('nick')).to.equal("bill");
        expect(sidebarApp.users.at(1).get('nick')).to.equal("bob");
      });
  });

  describe("#openConversation", function() {
    it("should post the talkilla.conversation-open event", function() {
      var sidebarApp = new SidebarApp();

      sidebarApp.openConversation("jb");

      sinon.assert.called(sidebarApp.appPort.post,
                          "talkilla.conversation-open");
      sinon.assert.calledWithExactly(sidebarApp.appPort.post,
                                     "talkilla.conversation-open",
                                     {peer: "jb"});
    });
  });

  describe("events", function() {

    var sidebarApp;

    beforeEach(function() {
      sidebarApp = new SidebarApp();
      sidebarApp.user.set("nick", "toto");

      sandbox.stub(sidebarApp.http, "post");
      sandbox.stub(app.utils, "notifyUI");
    });

    describe("talkilla.spa-connected", function() {
      beforeEach(function() {
        var sidebarApp = new SidebarApp();
        // Skipping events triggered in the constructor
        sidebarApp.appPort.post.reset();
      });

      it("should set the user presence", function() {
        sidebarApp.appPort.trigger("talkilla.spa-connected");

        expect(sidebarApp.user.get("presence")).to.equal("connected");
      });

      it("should set the SPA capabilities", function() {
        var capabilities = ["call", "move"];

        sidebarApp.appPort.trigger("talkilla.spa-connected",
                                   {capabilities: capabilities});

        expect(sidebarApp.spa.get("capabilities")).eql(capabilities);
      });
    });

    describe("talkilla.server-reconnection", function() {
        var sidebarApp;

        beforeEach(function() {
          app.views.AppView.prototype._onServerReconnection = sandbox.stub();
          sidebarApp = new SidebarApp();
          sidebarApp.appPort.post.reset();
        });

        it("should call the onServerReconnection method on the view",
          function() {
            sidebarApp.appPort.trigger("talkilla.server-reconnection",
                                       {timeout: 42, attempt: 2});
            sinon.assert.calledOnce(sidebarApp.view._onServerReconnection);
            sinon.assert.calledWithExactly(
              sidebarApp.view._onServerReconnection, {timeout: 42, attempt: 2});
          });
      });

    describe("talkilla.spa-error", function() {

      it("should not call clear() on the user model", function() {
        sandbox.stub(sidebarApp.user, "clear");

        sidebarApp.appPort.trigger("talkilla.spa-error");

        sinon.assert.notCalled(sidebarApp.user.clear);
      });

      it("should notify the user of an error", function() {
        sidebarApp.appPort.trigger("talkilla.spa-error");

        sinon.assert.calledOnce(app.utils.notifyUI);
        sinon.assert.calledWithExactly(app.utils.notifyUI,
          sinon.match.string, 'error');
      });

    });

    describe("signout-requested", function() {

      beforeEach(function() {
        sidebarApp.appPort.post.reset();
      });

      it("should reset users' state", function() {
        sidebarApp.user.trigger("signout-requested");

        expect(sidebarApp.user.nick).to.equal(undefined);
        expect(sidebarApp.users.length).to.equal(0);
      });

      it("should ask the SPA to forget credentials", function() {
        sidebarApp.user.trigger("signout-requested");

        sinon.assert.calledTwice(sidebarApp.appPort.post);
        sinon.assert.calledWithExactly(sidebarApp.appPort.post,
                                       "talkilla.spa-forget-credentials",
                                       "TalkillaSPA");
      });

      it("should disable the SPA", function() {
        sidebarApp.user.trigger("signout-requested");

        sinon.assert.calledTwice(sidebarApp.appPort.post);
        sinon.assert.calledWithExactly(
          sidebarApp.appPort.post, "talkilla.spa-disable", "TalkillaSPA");
      });

    });

    describe("signout (from user model)", function() {
      it("should clear the user model on signout", function() {
        sandbox.stub(sidebarApp.user, "clear");

        sidebarApp.user.trigger("signout");

        sinon.assert.called(sidebarApp.user.clear);
      });

      it("should reset the users model on signout", function() {
        sandbox.stub(sidebarApp.users, "reset");

        sidebarApp.user.trigger("signout");

        sinon.assert.called(sidebarApp.users.reset);
      });
    });

    describe("talkilla.worker-ready", function() {

      beforeEach(function() {
        sandbox.stub(sidebarApp.services.google, "initialize");
      });

      it("should initialize the google services", function() {
        sidebarApp.appPort.trigger("talkilla.worker-ready");

        sinon.assert.calledOnce(sidebarApp.services.google.initialize);
      });

    });

    describe("social.user-profile", function() {

      it("should set the user's nick", function() {
        var userData = {
          iconURL: "fake icon url",
          portrait: "fake portrait",
          userName: "foo",
          displayName: "fake display name",
          profileURL: "fake profile url"
        };

        sidebarApp.appPort.trigger("social.user-profile", userData);

        expect(sidebarApp.user.get("nick")).to.equal("foo");
      });

    });

    describe("SPA `dial` event", function() {
      it("should open a conversation passing dialed number", function() {
        sidebarApp.spa.trigger("dial", "123");

        sinon.assert.called(sidebarApp.appPort.post,
                            "talkilla.conversation-open");
        sinon.assert.calledWithExactly(sidebarApp.appPort.post,
                                       "talkilla.conversation-open",
                                       {peer: "123"});
      });
    });

  });
});
<commit_msg>talkilla.spa-error has been merged into talkilla.error; fix tests to reflect this<commit_after>/* global app, chai, sinon, AppPort, SidebarApp */
/* jshint expr:true */
"use strict";

var expect = chai.expect;

describe("SidebarApp", function() {

  var sandbox;

  beforeEach(function() {
    sandbox = sinon.sandbox.create();

    // mozSocial "mock"
    window.navigator.mozSocial = {
      getWorker: function() {
        return {port: {}};
      }
    };

    sandbox.stub(app.views, "AppView");
    sandbox.stub(AppPort.prototype, "post");
  });

  afterEach(function() {
    sandbox.restore();
    app.options.DEBUG = false;
  });

  describe("#constructor", function() {
    beforeEach(function() {
      // User prototype methods stubs
      sandbox.stub(app.models.User.prototype, "on");

      // jQuery.cookie stubs
      sandbox.stub(window.jQuery, "removeCookie");
    });

    it("should create an AppView", function() {
      new SidebarApp();

      sinon.assert.calledOnce(app.views.AppView);
    });

    it("should create an AppPport", function() {
      var sidebarApp = new SidebarApp();

      expect(sidebarApp.appPort).to.be.an.instanceOf(AppPort);
    });

    it("should create a user", function() {
      var sidebarApp = new SidebarApp();

      expect(sidebarApp.user).to.be.an.instanceOf(app.models.User);
    });

    it("should create a user list", function() {
      var sidebarApp = new SidebarApp();

      expect(sidebarApp.users).to.be.an.instanceOf(app.models.UserSet);
    });

    it("should post talkilla.sidebar-ready to the worker", function() {
      var sidebarApp = new SidebarApp();

      sinon.assert.calledOnce(sidebarApp.appPort.post);
      sinon.assert.calledWithExactly(sidebarApp.appPort.post,
                                     "talkilla.sidebar-ready");
    });

    it("should listen to the `talkilla.debug` event when debug is enabled",
      function() {
        sandbox.stub(AppPort.prototype, "on");
        app.options.DEBUG = true;
        var sidebarApp = new SidebarApp({nick: "toto"});

        sinon.assert.called(sidebarApp.appPort.on);
        sinon.assert.calledWith(sidebarApp.appPort.on, "talkilla.debug");
      });

    it("should listen to the `talkilla.users` event and update user list",
      function() {
        var sidebarApp = new SidebarApp();

        sidebarApp.appPort.trigger("talkilla.users", [
          {nick: "bob"},
          {nick: "bill"}
        ]);

        expect(sidebarApp.users).to.have.length.of(2);
        expect(sidebarApp.users.at(0).get('nick')).to.equal("bill");
        expect(sidebarApp.users.at(1).get('nick')).to.equal("bob");
      });
  });

  describe("#openConversation", function() {
    it("should post the talkilla.conversation-open event", function() {
      var sidebarApp = new SidebarApp();

      sidebarApp.openConversation("jb");

      sinon.assert.called(sidebarApp.appPort.post,
                          "talkilla.conversation-open");
      sinon.assert.calledWithExactly(sidebarApp.appPort.post,
                                     "talkilla.conversation-open",
                                     {peer: "jb"});
    });
  });

  describe("events", function() {

    var sidebarApp;

    beforeEach(function() {
      sidebarApp = new SidebarApp();
      sidebarApp.user.set("nick", "toto");

      sandbox.stub(sidebarApp.http, "post");
      sandbox.stub(app.utils, "notifyUI");
    });

    describe("talkilla.spa-connected", function() {
      beforeEach(function() {
        var sidebarApp = new SidebarApp();
        // Skipping events triggered in the constructor
        sidebarApp.appPort.post.reset();
      });

      it("should set the user presence", function() {
        sidebarApp.appPort.trigger("talkilla.spa-connected");

        expect(sidebarApp.user.get("presence")).to.equal("connected");
      });

      it("should set the SPA capabilities", function() {
        var capabilities = ["call", "move"];

        sidebarApp.appPort.trigger("talkilla.spa-connected",
                                   {capabilities: capabilities});

        expect(sidebarApp.spa.get("capabilities")).eql(capabilities);
      });
    });

    describe("talkilla.server-reconnection", function() {
        var sidebarApp;

        beforeEach(function() {
          app.views.AppView.prototype._onServerReconnection = sandbox.stub();
          sidebarApp = new SidebarApp();
          sidebarApp.appPort.post.reset();
        });

        it("should call the onServerReconnection method on the view",
          function() {
            sidebarApp.appPort.trigger("talkilla.server-reconnection",
                                       {timeout: 42, attempt: 2});
            sinon.assert.calledOnce(sidebarApp.view._onServerReconnection);
            sinon.assert.calledWithExactly(
              sidebarApp.view._onServerReconnection, {timeout: 42, attempt: 2});
          });
      });

    describe("talkilla.error", function() {

      it("should not call clear() on the user model", function() {
        sandbox.stub(sidebarApp.user, "clear");

        sidebarApp.appPort.trigger("talkilla.error");

        sinon.assert.notCalled(sidebarApp.user.clear);
      });

      it("should notify the user of an error", function() {
        sidebarApp.appPort.trigger("talkilla.error");

        sinon.assert.calledOnce(app.utils.notifyUI);
        sinon.assert.calledWithExactly(app.utils.notifyUI,
          sinon.match.string, 'error');
      });

    });

    describe("signout-requested", function() {

      beforeEach(function() {
        sidebarApp.appPort.post.reset();
      });

      it("should reset users' state", function() {
        sidebarApp.user.trigger("signout-requested");

        expect(sidebarApp.user.nick).to.equal(undefined);
        expect(sidebarApp.users.length).to.equal(0);
      });

      it("should ask the SPA to forget credentials", function() {
        sidebarApp.user.trigger("signout-requested");

        sinon.assert.calledTwice(sidebarApp.appPort.post);
        sinon.assert.calledWithExactly(sidebarApp.appPort.post,
                                       "talkilla.spa-forget-credentials",
                                       "TalkillaSPA");
      });

      it("should disable the SPA", function() {
        sidebarApp.user.trigger("signout-requested");

        sinon.assert.calledTwice(sidebarApp.appPort.post);
        sinon.assert.calledWithExactly(
          sidebarApp.appPort.post, "talkilla.spa-disable", "TalkillaSPA");
      });

    });

    describe("signout (from user model)", function() {
      it("should clear the user model on signout", function() {
        sandbox.stub(sidebarApp.user, "clear");

        sidebarApp.user.trigger("signout");

        sinon.assert.called(sidebarApp.user.clear);
      });

      it("should reset the users model on signout", function() {
        sandbox.stub(sidebarApp.users, "reset");

        sidebarApp.user.trigger("signout");

        sinon.assert.called(sidebarApp.users.reset);
      });
    });

    describe("talkilla.worker-ready", function() {

      beforeEach(function() {
        sandbox.stub(sidebarApp.services.google, "initialize");
      });

      it("should initialize the google services", function() {
        sidebarApp.appPort.trigger("talkilla.worker-ready");

        sinon.assert.calledOnce(sidebarApp.services.google.initialize);
      });

    });

    describe("social.user-profile", function() {

      it("should set the user's nick", function() {
        var userData = {
          iconURL: "fake icon url",
          portrait: "fake portrait",
          userName: "foo",
          displayName: "fake display name",
          profileURL: "fake profile url"
        };

        sidebarApp.appPort.trigger("social.user-profile", userData);

        expect(sidebarApp.user.get("nick")).to.equal("foo");
      });

    });

    describe("SPA `dial` event", function() {
      it("should open a conversation passing dialed number", function() {
        sidebarApp.spa.trigger("dial", "123");

        sinon.assert.called(sidebarApp.appPort.post,
                            "talkilla.conversation-open");
        sinon.assert.calledWithExactly(sidebarApp.appPort.post,
                                       "talkilla.conversation-open",
                                       {peer: "123"});
      });
    });

  });
});
<|endoftext|>


<commit_before>Activities = new Mongo.Collection('activities');

var ActivitiesSchema = new SimpleSchema({
  residentIds: {
    type: Array,
    label: 'Resident'
  },
  'residentIds.$': {
    type: String,
    autoform: {
      options: function() {
        // Get all Homes
        var homes = Homes.find().fetch();

        // Create an array of Home IDs
        var homeIDs = _.map(homes, function (home) {
          return home._id;
        });

        // Create select options for residents input
        // Grouping residents by home
        var residentSelectOptions = _.map(homeIDs, function (homeID) {
          // Find the name of this home
          var homeName = Homes.findOne(homeID).name;

          // Get all residents of this home
          var homeResidents = Residents.find({homeId: homeID}).fetch();

          // Create a residents array with name/ID pairs for label/value
          var residentOptions = _.map(homeResidents, function (homeResident) {
            // Combine resident first name and last initial
            var residentName = homeResident.firstName + ' ' + homeResident.lastInitial;

            // Create option for this resident, with ID as the value
            return {label: residentName, value: homeResident._id};
          });

          // Return residents and home as option group
          return {optgroup: homeName, options: residentOptions};
        });

        return residentSelectOptions;
      }
    }
  },
  activityTypeId: {
    type: String,
    label: 'Activity Type',
    autoform: {
      options: function() {
        // Get all activity types from db
        var activityTypes = ActivityTypes.find().fetch();

        // Create an options array of activity types with label and value pairs
        var activityTypesOptions = _.map(activityTypes, function(activityType) {
          return {
            label: activityType.name,
            value: activityType._id
          };
        });

        return activityTypesOptions;
      }
    }
  },
  activityDate: {
    type: Date,
    autoform: {
      afFieldInput: {
        type: "pickadate"
      }
    }
  },
  duration: {
    type: Number,
    label: "Duration (in minutes)"
  },
  facilitatorRole : {
    type: String,
    label: "Facilitator role",
    autoform: {
      options: function() {
        // Get all roles from db
        var roles = Meteor.roles.find().fetch();

        // Create an options array of roles with label (name) and value (id) pairs
        var rolesOptions = _.map(roles, function(role) {
          return {
            label: role.name,
            value: role._id
          };
        });

        return rolesOptions;
      }
    }
  },
  createdById: {
    type: String,
    label: "Created by user ID",
    autoValue: function () {
      if (this.isInsert) {
        // return the active user ID
        return this.userId;
      }
    },
    autoform: {
      type: "hidden"
    }
  }
});

Activities.attachSchema(ActivitiesSchema);

Activities.helpers({
  residentNames: function () {
    // Get the Resident ID;
    var residentIds = this.residentIds;

    // Get Resident(s) from Residents collection, by ID(s)
    var residents = Residents.find({'_id': {$in: residentIds}}).fetch();

    // Create an array of resident names
    var residentNamesArray = _.map(residents, function (resident) {
      return resident.firstName;
    });

    // Return the resident name(s), joining with ", "
    return residentNamesArray.join(", ");
  },
  activityType: function () {
    // Get the Activity Type ID
    var activityTypeId = this.activityTypeId;

    // Get Activity Type from Activity Types collection, by ID
    var activityType = ActivityTypes.findOne(activityTypeId);

    // Return the Activity Type name
    return activityType.name;
  },
  activityDateFormatted: function () {
    // Get activity date
    var activityDate = this.activityDate;

    // Format activity date
    var activityDateFormatted = moment(activityDate).format("D.M.YYYY");

    return activityDateFormatted;
  }
});
<commit_msg>Renamed to facilitatorRoleId field.<commit_after>Activities = new Mongo.Collection('activities');

var ActivitiesSchema = new SimpleSchema({
  residentIds: {
    type: Array,
    label: 'Resident'
  },
  'residentIds.$': {
    type: String,
    autoform: {
      options: function() {
        // Get all Homes
        var homes = Homes.find().fetch();

        // Create an array of Home IDs
        var homeIDs = _.map(homes, function (home) {
          return home._id;
        });

        // Create select options for residents input
        // Grouping residents by home
        var residentSelectOptions = _.map(homeIDs, function (homeID) {
          // Find the name of this home
          var homeName = Homes.findOne(homeID).name;

          // Get all residents of this home
          var homeResidents = Residents.find({homeId: homeID}).fetch();

          // Create a residents array with name/ID pairs for label/value
          var residentOptions = _.map(homeResidents, function (homeResident) {
            // Combine resident first name and last initial
            var residentName = homeResident.firstName + ' ' + homeResident.lastInitial;

            // Create option for this resident, with ID as the value
            return {label: residentName, value: homeResident._id};
          });

          // Return residents and home as option group
          return {optgroup: homeName, options: residentOptions};
        });

        return residentSelectOptions;
      }
    }
  },
  activityTypeId: {
    type: String,
    label: 'Activity Type',
    autoform: {
      options: function() {
        // Get all activity types from db
        var activityTypes = ActivityTypes.find().fetch();

        // Create an options array of activity types with label and value pairs
        var activityTypesOptions = _.map(activityTypes, function(activityType) {
          return {
            label: activityType.name,
            value: activityType._id
          };
        });

        return activityTypesOptions;
      }
    }
  },
  activityDate: {
    type: Date,
    autoform: {
      afFieldInput: {
        type: "pickadate"
      }
    }
  },
  duration: {
    type: Number,
    label: "Duration (in minutes)"
  },
  facilitatorRoleId: {
    type: String,
    label: "Facilitator role",
    autoform: {
      options: function() {
        // Get all roles from db
        var roles = Meteor.roles.find().fetch();

        // Create an options array of roles with label (name) and value (id) pairs
        var rolesOptions = _.map(roles, function(role) {
          return {
            label: role.name,
            value: role._id
          };
        });

        return rolesOptions;
      }
    }
  },
  createdById: {
    type: String,
    label: "Created by user ID",
    autoValue: function () {
      if (this.isInsert) {
        // return the active user ID
        return this.userId;
      }
    },
    autoform: {
      type: "hidden"
    }
  }
});

Activities.attachSchema(ActivitiesSchema);

Activities.helpers({
  residentNames: function () {
    // Get the Resident ID;
    var residentIds = this.residentIds;

    // Get Resident(s) from Residents collection, by ID(s)
    var residents = Residents.find({'_id': {$in: residentIds}}).fetch();

    // Create an array of resident names
    var residentNamesArray = _.map(residents, function (resident) {
      return resident.firstName;
    });

    // Return the resident name(s), joining with ", "
    return residentNamesArray.join(", ");
  },
  activityType: function () {
    // Get the Activity Type ID
    var activityTypeId = this.activityTypeId;

    // Get Activity Type from Activity Types collection, by ID
    var activityType = ActivityTypes.findOne(activityTypeId);

    // Return the Activity Type name
    return activityType.name;
  },
  activityDateFormatted: function () {
    // Get activity date
    var activityDate = this.activityDate;

    // Format activity date
    var activityDateFormatted = moment(activityDate).format("D.M.YYYY");

    return activityDateFormatted;
  }
});
<|endoftext|>


<commit_before>var path = require('path')

// implements a rough version of
// http://webpack.github.io/docs/configuration.html#resolve-alias
module.exports = function resolveAlias(source, aliases) {

  for (var alias in aliases) {
    var match = matchAlias(source, alias, aliases[alias])
    if (match) return match
  }

  // fail out
  return source
}

function matchAlias(source, alias, value) {
  var isExact = (alias[alias.length - 1] === '$')
    , isFile = (path.extname(value) !== '')
    , segments = source.split(path.sep)

  if (isExact) alias = alias.slice(0, -1)

  if (segments[0] === alias) {
    // always return exact match
    if (segments.length === 1) return value

    // prefix match on exact match for file is an error
    if (isFile && (isExact || !/^[./]/.test(value))) {
      throw new Error('can\'t match file with exact alias prefix')
    }

    // otherwise, prefix match is fine for non-file paths
    if (!isExact && !isFile) return [value].concat(segments.slice(1)).join(path.sep)
  }

}
<commit_msg>resolve-alias fixes for Windows (always use / for aliasing paths)<commit_after>var path = require('path')

// implements a rough version of
// http://webpack.github.io/docs/configuration.html#resolve-alias
module.exports = function resolveAlias(source, aliases) {

  for (var alias in aliases) {
    var match = matchAlias(source, alias, aliases[alias])
    if (match) return match
  }

  // fail out
  return source
}

// using '/' only for consistency with Webpack docs
var sep = '/'
function matchAlias(source, alias, value) {
  var isExact = (alias[alias.length - 1] === '$')
    , isFile = (path.extname(value) !== '')
    , segments = source.split(sep)

  if (isExact) alias = alias.slice(0, -1)

  if (segments[0] === alias) {
    // always return exact match
    if (segments.length === 1) return value

    // prefix match on exact match for file is an error
    if (isFile && (isExact || !/^[./]/.test(value))) {
      throw new Error('can\'t match file with exact alias prefix')
    }

    // otherwise, prefix match is fine for non-file paths
    if (!isExact && !isFile) return [value].concat(segments.slice(1)).join(sep)
  }

}
<|endoftext|>


<commit_before>import RelationshipsControl from 'hyrax/relationships/control'
import SaveWorkControl from 'hyrax/save_work/save_work_control'
import AdminSetWidget from 'hyrax/editor/admin_set_widget'

export default class {
  constructor(element) {
    this.element = element
    this.adminSetWidget = new AdminSetWidget(element.find('select[id$="_admin_set_id"]'))
    this.sharingTabElement = $('#tab-share')

    this.sharingTab()
    this.relationshipsControl()
    this.saveWorkControl()
    this.saveWorkFixed()
  }

  // Display the sharing tab if they select an admin set that permits sharing
  sharingTab() {
    if(this.adminSetWidget && !this.adminSetWidget.isEmpty()) {
      this.adminSetWidget.on('change', (data) => this.sharingTabVisiblity(data))
      this.sharingTabVisiblity(this.adminSetWidget.isSharing())
    }
  }

  sharingTabVisiblity(visible) {
      if (visible)
         this.sharingTabElement.removeClass('hidden')
      else
         this.sharingTabElement.addClass('hidden')
  }

  relationshipsControl() {
      new RelationshipsControl(this.element.find('[data-behavior="child-relationships"]'),
                               'work_members_attributes',
                               'tmpl-child-work')
  }

  saveWorkControl() {
      new SaveWorkControl(this.element.find("#form-progress"), this.adminSetWidget)
  }

  saveWorkFixed() {
      // Fixedsticky will polyfill position:sticky
      this.element.find('#savewidget').fixedsticky()
  }
}
<commit_msg>Pass the correct attribute to sharingTabVisibility. Fixes #676<commit_after>import RelationshipsControl from 'hyrax/relationships/control'
import SaveWorkControl from 'hyrax/save_work/save_work_control'
import AdminSetWidget from 'hyrax/editor/admin_set_widget'

export default class {
  constructor(element) {
    this.element = element
    this.adminSetWidget = new AdminSetWidget(element.find('select[id$="_admin_set_id"]'))
    this.sharingTabElement = $('#tab-share')

    this.sharingTab()
    this.relationshipsControl()
    this.saveWorkControl()
    this.saveWorkFixed()
  }

  // Display the sharing tab if they select an admin set that permits sharing
  sharingTab() {
    if(this.adminSetWidget && !this.adminSetWidget.isEmpty()) {
      this.adminSetWidget.on('change', () => this.sharingTabVisiblity(this.adminSetWidget.isSharing()))
      this.sharingTabVisiblity(this.adminSetWidget.isSharing())
    }
  }

  sharingTabVisiblity(visible) {
      if (visible)
         this.sharingTabElement.removeClass('hidden')
      else
         this.sharingTabElement.addClass('hidden')
  }

  relationshipsControl() {
      new RelationshipsControl(this.element.find('[data-behavior="child-relationships"]'),
                               'work_members_attributes',
                               'tmpl-child-work')
  }

  saveWorkControl() {
      new SaveWorkControl(this.element.find("#form-progress"), this.adminSetWidget)
  }

  saveWorkFixed() {
      // Fixedsticky will polyfill position:sticky
      this.element.find('#savewidget').fixedsticky()
  }
}
<|endoftext|>


<commit_before>const setupOnce = require('setup_once');

(function(){

  let LayoutPicker = Backbone.View.extend({

    events: {
      'click .radio-group__option': 'updateSelected',
    },

    updateSelected(e) {
      let $target = $(e.target);
      if (!$target.hasClass('radio-group__option')) {
        // for bubbling
        $target = $target.parents('.radio-group__option')
      }
      const name = $target.find('.layout-settings__title').text();
      $target.parents('.layout-settings').find('.layout-settings__current').text(name);
      $target.parents('.layout-settings').find('.radio-group__option').removeClass('active');
      $target.addClass('active');
      this.updatePlan($target);
    },

    updatePlan($target) {
      const $input = $target.find(`#${$target.attr('for')}`);
      if ($input.attr('name') === 'page[follow_up_liquid_layout_id]') {
        this.$('#page_follow_up_plan_with_liquid').prop('checked', true);
      }
    },

  });

  $.subscribe("layout:edit", function(){
    setupOnce('.layout-settings', LayoutPicker);
  });
}());
<commit_msg>get layout selection UI working on pages/new<commit_after>const setupOnce = require('setup_once');

(function(){

  let LayoutPicker = Backbone.View.extend({

    events: {
      'click .radio-group__option': 'updateSelected',
    },

    updateSelected(e) {
      let $target = $(e.target);
      if (!$target.hasClass('radio-group__option')) {
        // for bubbling
        $target = $target.parents('.radio-group__option')
      }
      const name = $target.find('.layout-settings__title').text();
      $target.parents('.layout-settings').find('.layout-settings__current').text(name);
      $target.parents('.layout-settings').find('.radio-group__option').removeClass('active');
      $target.addClass('active');
      this.updatePlan($target);
    },

    updatePlan($target) {
      const $input = $target.find(`#${$target.attr('for')}`);
      if ($input.attr('name') === 'page[follow_up_liquid_layout_id]') {
        this.$('#page_follow_up_plan_with_liquid').prop('checked', true);
      }
    },

  });

  $.subscribe("layout:edit pages:new", function(){
    setupOnce('.layout-settings', LayoutPicker);
  });
}());
<|endoftext|>


<commit_before>/*
 * Copyright 2013-2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'settings/js/widgets/community-widget',
    'test/test-utils',
    'jasmine-jquery'
], function(CommunityWidget, utils) {

    describe('Community widget', function() {
        var strings = utils.createStringMap('confirmOkText', 'confirmMessage', 'confirmTitle', 'connectionSecurity',
            'databaseLabel', 'disable', 'disabled', 'enable', 'enabled', 'fromLabel', 'hostPlaceholder', 'loading',
            'loginTypeLabel', 'passwordLabel', 'passwordRedacted', 'passwordDescription', 'portPlaceholder', 'toDescription',
            'toLabel', 'usernameLabel', 'validateButton', 'validateFailed', 'validateSuccess');

        var initialConfig = {
            community: {host: 'example.com', port: 9003, protocol: 'HTTPS', productType: 'UASERVER', indexErrorMessage: 'What\'s an index?'},
            method: 'LDAP'
        };

        beforeEach(function() {
            jasmine.addMatchers({
                toDisplayConfig: function() {
                    return {
                        compare: function(actual, config) {
                            var $el = actual;

                            var actualConfig = _.extend({
                                community: {
                                    host: $el.find('input[name="host"]').val(),
                                    port: Number($el.find('input[name="port"]').val()),
                                    protocol: $el.find('select[name="protocol"]').val()
                                },
                                method: $el.find('select[name="login-type"]').val()
                            }, config);

                            var pass = _.isEqual(config, actualConfig);

                            return {
                                pass: pass,
                                message: function() {
                                    return 'Expected "' + $el.get(0).outerHTML + '"' +
                                        (pass ? ' not ' : '') +
                                        ' to display config "' + JSON.stringify(config) + '"';
                                }
                            };
                        }
                    }
                },
                toContainOptions: function() {
                    return {
                        compare: function(actual, options) {
                            // Doesn't account for duplicates.
                            var $select = actual;
                            var $options = $select.find('option');

                            if ($options.length !== options.length) {
                                return false;
                            }

                            var isMatch = true;

                            _.each(options, function(value) {
                                if (isMatch && $options.filter('[value="' + value + '"]').length !== 1) {
                                    isMatch = false;
                                }
                            });

                            return {
                                pass: isMatch,
                                message: function() {
                                    return 'Expected "' + $select.get(0).outerHTML + '"' + (isMatch ? ' not ' : '') + ' to contain options "' + JSON.stringify(options) + '"';
                                }
                            };
                        }
                    };
                }
            });

            this.widget = new CommunityWidget({
                configItem: 'login',
                description: 'This widget controls Site Admin\'s connection to your Community server.',
                indexErrorMessage: 'What\'s an index?',
                productType: 'UASERVER',
                securityTypesUrl: '/securitytypes',
                strings: strings,
                title: 'Community'
            });

            this.typesModel = this.widget.securityTypesModel;
            spyOn(this.typesModel, 'fetch');
            this.widget.render();
            this.$loginType = this.widget.$('select[name="login-type"]');
            this.$aciDetails = this.widget.$('div.control-group').eq(0);
        });

        it('should render correctly', function() {
            expect(this.widget.$el).toDisplayConfig({community: {host: '', port: 0, protocol: 'HTTP'}, method: null});
            expect(this.$loginType).toHaveAttr('disabled');
            expect(this.$aciDetails).not.toHaveClass('success');
            expect(this.$aciDetails).not.toHaveClass('error');
        });

        _.each(['cas', 'external'], function(type) {
            it('should correctly handle the non-community "' + type + '" login type', function() {
                var currentConfig = _.defaults({method: type}, initialConfig);
                var communityTypes = ['autonomy', 'LDAP'];
                this.widget.updateConfig(currentConfig);

                expect(this.widget.$el).toDisplayConfig(currentConfig);
                expect(this.$loginType).toHaveAttr('disabled');

                this.widget.lastValidationConfig = currentConfig;
                this.widget.handleValidation(currentConfig, {valid: true});
                this.typesModel.securityTypes = communityTypes;
                this.typesModel.trigger('change');

                expect(this.$loginType).toContainOptions(_.union(communityTypes, type));
                expect(this.$loginType).not.toHaveAttr('disabled');
                expect(this.widget.$el).toDisplayConfig(currentConfig);
            });
        });

        describe('after a config update', function() {
            beforeEach(function() {
                this.widget.updateConfig(initialConfig);
            });

            it('should display the correct config', function() {
                expect(this.widget.$el).toDisplayConfig(initialConfig);
            });

            it('should return the correct config', function() {
                expect(this.widget.getConfig()).toEqual(initialConfig);
            });

            it('should keep the login types input disabled', function() {
                expect(this.$loginType).toHaveAttr('disabled');
            });

            it('should apply error formatting after failed validation', function() {
                this.widget.lastValidationConfig = initialConfig;
                this.widget.handleValidation(initialConfig, {valid: false});

                expect(this.$aciDetails).toHaveClass('error');
                expect(this.$aciDetails).not.toHaveClass('success');
                expect(this.typesModel.fetch).not.toHaveBeenCalled();
            });

            it('should fail client side validation with an empty host input', function() {
                var $host = this.widget.$('input[name="host"]');
                var $clientValidationSpan = this.widget.$('.settings-client-validation');

                this.widget.lastValidationConfig = initialConfig;
                this.widget.handleValidation(initialConfig, {valid: true});

                expect(this.widget.$el).not.toHaveClass('success');
                expect(this.$aciDetails).toHaveClass('success');
                expect($clientValidationSpan).toHaveClass('hide');

                $host.val('').trigger('change');

                expect(this.widget.$el).not.toHaveClass('success');
                expect(this.$aciDetails).not.toHaveClass('success');
                expect(this.$aciDetails).not.toHaveClass('error');
                expect($clientValidationSpan).toHaveClass('hide');

                var isValid = this.widget.validateInputs();

                expect(isValid).toBeFalsy();
                expect(this.widget.$el).not.toHaveClass('success');
                expect(this.$aciDetails).toHaveClass('error');
                expect(this.$aciDetails).not.toHaveClass('success');
                expect($clientValidationSpan).toHaveClass('hide');

                $host.val('yoda').trigger('change');

                expect(this.widget.$el).not.toHaveClass('success');
                expect(this.$aciDetails).not.toHaveClass('error');
                expect(this.$aciDetails).not.toHaveClass('success');
                expect($clientValidationSpan).toHaveClass('hide');

                $host.val(initialConfig.community.host).trigger('change');

                expect(this.widget.$el).not.toHaveClass('success');
                expect(this.$aciDetails).toHaveClass('success');
                expect(this.$aciDetails).not.toHaveClass('error');
                expect($clientValidationSpan).toHaveClass('hide');
            });

            describe('after a change to the port input', function() {
                beforeEach(function() {
                    this.$port = this.widget.$('input[name="port"]').val(123).trigger('change');
                });

                it('should not apply the validation response when it returns', function() {
                    this.widget.lastValidationConfig = initialConfig;
                    this.widget.handleValidation(initialConfig, {valid: true});

                    expect(this.$aciDetails).not.toHaveClass('success');

                    this.$port.val(9003).trigger('change');

                    expect(this.$aciDetails).toHaveClass('success');
                    expect(this.$aciDetails).not.toHaveClass('error');
                });
            });

            describe('after successful validation', function() {
                beforeEach(function() {
                    this.widget.lastValidationConfig = initialConfig;
                    this.widget.handleValidation(initialConfig, {valid: true});
                });

                it('should apply success formatting to the aci details inputs', function() {
                    expect(this.$aciDetails).toHaveClass('success');
                    expect(this.$aciDetails).not.toHaveClass('error');
                    expect(this.widget.$el).not.toHaveClass('success');
                    expect(this.widget.$el).not.toHaveClass('error');
                });

                it('should keep the login types input disabled and fetch new security types', function() {
                    expect(this.$loginType).toHaveAttr('disabled');
                    expect(this.typesModel.fetch).toHaveBeenCalled();
                    expect(this.typesModel.fetch).toHaveCallCount(1);

                    expect(this.typesModel.fetch).toHaveBeenCalledWith({data: {
                        host: initialConfig.community.host,
                        port: initialConfig.community.port,
                        protocol: initialConfig.community.protocol
                    }});
                });

                it('should correctly handle new security types containing the currently selected type', function() {
                    var newTypes = this.typesModel.securityTypes = ['yoda', 'LDAP', 'autonomy'];
                    this.typesModel.trigger('change');

                    expect(this.$loginType).not.toHaveAttr('disabled');
                    expect(this.widget.$el).toDisplayConfig(initialConfig);
                    expect(this.$loginType).toContainOptions(newTypes);
                });

                describe('after change to the host input', function() {
                    beforeEach(function() {
                        this.$host = this.$aciDetails.find('[name="host"]');
                        this.$host.val('my-new-host.com').trigger('change');
                    });

                    it('should clear validation formatting', function() {
                        expect(this.$aciDetails).not.toHaveClass('success');
                        expect(this.$aciDetails).not.toHaveClass('error');
                    });

                    it('should not enable the login types input on new security types', function() {
                        this.typesModel.securityTypes = ['autonomy', 'LDAP'];
                        this.typesModel.trigger('change');

                        expect(this.$loginType).toHaveAttr('disabled');

                        this.$host.val('example.com').trigger('change');

                        expect(this.$loginType).not.toHaveAttr('disabled');
                    });

                    it('should return validation formatting if it is changed back', function() {
                        this.$host.val('example.com').trigger('change');

                        expect(this.$aciDetails).toHaveClass('success');
                        expect(this.$aciDetails).not.toHaveClass('error');
                    });

                    it('should return the correct config', function() {
                        expect(this.widget.getConfig()).toEqual(_.defaults({
                            community: _.defaults({
                                host: 'my-new-host.com'
                            }, initialConfig.community)
                        }, initialConfig));
                    });

                    it('should trigger validation on clicking Test Connection', function() {
                        spyOn(this.widget, 'trigger');
                        this.widget.$('[name="validate"]').click();

                        expect(this.widget.trigger).toHaveBeenCalledWith('validate');
                    });
                });
            });
        });
    });

});<commit_msg>Fix matcher.<commit_after>/*
 * Copyright 2013-2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'settings/js/widgets/community-widget',
    'test/test-utils',
    'jasmine-jquery'
], function(CommunityWidget, utils) {

    describe('Community widget', function() {
        var strings = utils.createStringMap('confirmOkText', 'confirmMessage', 'confirmTitle', 'connectionSecurity',
            'databaseLabel', 'disable', 'disabled', 'enable', 'enabled', 'fromLabel', 'hostPlaceholder', 'loading',
            'loginTypeLabel', 'passwordLabel', 'passwordRedacted', 'passwordDescription', 'portPlaceholder', 'toDescription',
            'toLabel', 'usernameLabel', 'validateButton', 'validateFailed', 'validateSuccess');

        var initialConfig = {
            community: {host: 'example.com', port: 9003, protocol: 'HTTPS', productType: 'UASERVER', indexErrorMessage: 'What\'s an index?'},
            method: 'LDAP'
        };

        beforeEach(function() {
            jasmine.addMatchers({
                toDisplayConfig: function() {
                    return {
                        compare: function(actual, config) {
                            var $el = actual;

                            var actualConfig = {
                                // need to account for things like productType which don't go in the DOM
                                community: _.defaults({
                                    host: $el.find('input[name="host"]').val(),
                                    port: Number($el.find('input[name="port"]').val()),
                                    protocol: $el.find('select[name="protocol"]').val()
                                }, config.community),
                                method: $el.find('select[name="login-type"]').val()
                            };

                            var pass = _.isEqual(config, actualConfig);

                            return {
                                pass: pass,
                                message: function() {
                                    return 'Expected "' + JSON.stringify(actualConfig) + '"' +
                                        (pass ? ' not ' : '') +
                                        ' to display config "' + JSON.stringify(config) + '"';
                                }
                            };
                        }
                    }
                },
                toContainOptions: function() {
                    return {
                        compare: function(actual, options) {
                            // Doesn't account for duplicates.
                            var $select = actual;
                            var $options = $select.find('option');

                            if ($options.length !== options.length) {
                                return false;
                            }

                            var isMatch = true;

                            _.each(options, function(value) {
                                if (isMatch && $options.filter('[value="' + value + '"]').length !== 1) {
                                    isMatch = false;
                                }
                            });

                            return {
                                pass: isMatch,
                                message: function() {
                                    return 'Expected "' + $select.get(0).outerHTML + '"' + (isMatch ? ' not ' : '') + ' to contain options "' + JSON.stringify(options) + '"';
                                }
                            };
                        }
                    };
                }
            });

            this.widget = new CommunityWidget({
                configItem: 'login',
                description: "This widget controls Site Admin's connection to your Community server.",
                indexErrorMessage: "What's an index?",
                productType: 'UASERVER',
                securityTypesUrl: '/securitytypes',
                strings: strings,
                title: 'Community'
            });

            this.typesModel = this.widget.securityTypesModel;
            spyOn(this.typesModel, 'fetch');
            this.widget.render();
            this.$loginType = this.widget.$('select[name="login-type"]');
            this.$aciDetails = this.widget.$('div.control-group').eq(0);
        });

        it('should render correctly', function() {
            expect(this.widget.$el).toDisplayConfig({community: {host: '', port: 0, protocol: 'HTTP'}, method: null});
            expect(this.$loginType).toHaveAttr('disabled');
            expect(this.$aciDetails).not.toHaveClass('success');
            expect(this.$aciDetails).not.toHaveClass('error');
        });

        _.each(['cas', 'external'], function(type) {
            it('should correctly handle the non-community "' + type + '" login type', function() {
                var currentConfig = _.defaults({method: type}, initialConfig);
                var communityTypes = ['autonomy', 'LDAP'];
                this.widget.updateConfig(currentConfig);

                expect(this.widget.$el).toDisplayConfig(currentConfig);
                expect(this.$loginType).toHaveAttr('disabled');

                this.widget.lastValidationConfig = currentConfig;
                this.widget.handleValidation(currentConfig, {valid: true});
                this.typesModel.securityTypes = communityTypes;
                this.typesModel.trigger('change');

                expect(this.$loginType).toContainOptions(_.union(communityTypes, type));
                expect(this.$loginType).not.toHaveAttr('disabled');
                expect(this.widget.$el).toDisplayConfig(currentConfig);
            });
        });

        describe('after a config update', function() {
            beforeEach(function() {
                this.widget.updateConfig(initialConfig);
            });

            it('should display the correct config', function() {
                expect(this.widget.$el).toDisplayConfig(initialConfig);
            });

            it('should return the correct config', function() {
                expect(this.widget.getConfig()).toEqual(initialConfig);
            });

            it('should keep the login types input disabled', function() {
                expect(this.$loginType).toHaveAttr('disabled');
            });

            it('should apply error formatting after failed validation', function() {
                this.widget.lastValidationConfig = initialConfig;
                this.widget.handleValidation(initialConfig, {valid: false});

                expect(this.$aciDetails).toHaveClass('error');
                expect(this.$aciDetails).not.toHaveClass('success');
                expect(this.typesModel.fetch).not.toHaveBeenCalled();
            });

            it('should fail client side validation with an empty host input', function() {
                var $host = this.widget.$('input[name="host"]');
                var $clientValidationSpan = this.widget.$('.settings-client-validation');

                this.widget.lastValidationConfig = initialConfig;
                this.widget.handleValidation(initialConfig, {valid: true});

                expect(this.widget.$el).not.toHaveClass('success');
                expect(this.$aciDetails).toHaveClass('success');
                expect($clientValidationSpan).toHaveClass('hide');

                $host.val('').trigger('change');

                expect(this.widget.$el).not.toHaveClass('success');
                expect(this.$aciDetails).not.toHaveClass('success');
                expect(this.$aciDetails).not.toHaveClass('error');
                expect($clientValidationSpan).toHaveClass('hide');

                var isValid = this.widget.validateInputs();

                expect(isValid).toBeFalsy();
                expect(this.widget.$el).not.toHaveClass('success');
                expect(this.$aciDetails).toHaveClass('error');
                expect(this.$aciDetails).not.toHaveClass('success');
                expect($clientValidationSpan).toHaveClass('hide');

                $host.val('yoda').trigger('change');

                expect(this.widget.$el).not.toHaveClass('success');
                expect(this.$aciDetails).not.toHaveClass('error');
                expect(this.$aciDetails).not.toHaveClass('success');
                expect($clientValidationSpan).toHaveClass('hide');

                $host.val(initialConfig.community.host).trigger('change');

                expect(this.widget.$el).not.toHaveClass('success');
                expect(this.$aciDetails).toHaveClass('success');
                expect(this.$aciDetails).not.toHaveClass('error');
                expect($clientValidationSpan).toHaveClass('hide');
            });

            describe('after a change to the port input', function() {
                beforeEach(function() {
                    this.$port = this.widget.$('input[name="port"]').val(123).trigger('change');
                });

                it('should not apply the validation response when it returns', function() {
                    this.widget.lastValidationConfig = initialConfig;
                    this.widget.handleValidation(initialConfig, {valid: true});

                    expect(this.$aciDetails).not.toHaveClass('success');

                    this.$port.val(9003).trigger('change');

                    expect(this.$aciDetails).toHaveClass('success');
                    expect(this.$aciDetails).not.toHaveClass('error');
                });
            });

            describe('after successful validation', function() {
                beforeEach(function() {
                    this.widget.lastValidationConfig = initialConfig;
                    this.widget.handleValidation(initialConfig, {valid: true});
                });

                it('should apply success formatting to the aci details inputs', function() {
                    expect(this.$aciDetails).toHaveClass('success');
                    expect(this.$aciDetails).not.toHaveClass('error');
                    expect(this.widget.$el).not.toHaveClass('success');
                    expect(this.widget.$el).not.toHaveClass('error');
                });

                it('should keep the login types input disabled and fetch new security types', function() {
                    expect(this.$loginType).toHaveAttr('disabled');
                    expect(this.typesModel.fetch).toHaveBeenCalled();
                    expect(this.typesModel.fetch).toHaveCallCount(1);

                    expect(this.typesModel.fetch).toHaveBeenCalledWith({data: {
                        host: initialConfig.community.host,
                        port: initialConfig.community.port,
                        protocol: initialConfig.community.protocol
                    }});
                });

                it('should correctly handle new security types containing the currently selected type', function() {
                    var newTypes = this.typesModel.securityTypes = ['yoda', 'LDAP', 'autonomy'];
                    this.typesModel.trigger('change');

                    expect(this.$loginType).not.toHaveAttr('disabled');
                    expect(this.widget.$el).toDisplayConfig(initialConfig);
                    expect(this.$loginType).toContainOptions(newTypes);
                });

                describe('after change to the host input', function() {
                    beforeEach(function() {
                        this.$host = this.$aciDetails.find('[name="host"]');
                        this.$host.val('my-new-host.com').trigger('change');
                    });

                    it('should clear validation formatting', function() {
                        expect(this.$aciDetails).not.toHaveClass('success');
                        expect(this.$aciDetails).not.toHaveClass('error');
                    });

                    it('should not enable the login types input on new security types', function() {
                        this.typesModel.securityTypes = ['autonomy', 'LDAP'];
                        this.typesModel.trigger('change');

                        expect(this.$loginType).toHaveAttr('disabled');

                        this.$host.val('example.com').trigger('change');

                        expect(this.$loginType).not.toHaveAttr('disabled');
                    });

                    it('should return validation formatting if it is changed back', function() {
                        this.$host.val('example.com').trigger('change');

                        expect(this.$aciDetails).toHaveClass('success');
                        expect(this.$aciDetails).not.toHaveClass('error');
                    });

                    it('should return the correct config', function() {
                        expect(this.widget.getConfig()).toEqual(_.defaults({
                            community: _.defaults({
                                host: 'my-new-host.com'
                            }, initialConfig.community)
                        }, initialConfig));
                    });

                    it('should trigger validation on clicking Test Connection', function() {
                        spyOn(this.widget, 'trigger');
                        this.widget.$('[name="validate"]').click();

                        expect(this.widget.trigger).toHaveBeenCalledWith('validate');
                    });
                });
            });
        });
    });

});<|endoftext|>


<commit_before>// Admin javascript manifest
//
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require jquery-ui/i18n/datepicker-da
//= require jquery-ui/i18n/datepicker-de
//= require jquery-ui/i18n/datepicker-es
//= require jquery-ui/i18n/datepicker-fr
//= require jquery-ui/i18n/datepicker-he
//= require jquery-ui/i18n/datepicker-it
//= require jquery-ui/i18n/datepicker-ja
//= require jquery-ui/i18n/datepicker-lt
//= require jquery-ui/i18n/datepicker-nb
//= require jquery-ui/i18n/datepicker-nl
//= require jquery-ui/i18n/datepicker-pl
//= require jquery-ui/i18n/datepicker-pt-BR
//= require jquery-ui/i18n/datepicker-ro
//= require jquery-ui/i18n/datepicker-ru
//= require jquery-ui/i18n/datepicker-zh-CN
//= require jquery-ui/i18n/datepicker-zh-TW
//= require datetimepicker
//= require bootstrap
//= require quicktags
//= require tagmanager
//= require typeahead
//= require sidebar
//= require spinnable
//= require lightbox
//
//= require_self

/* typewatch() borrowed from
 * http://stackoverflow.com/questions/2219924/idiomatic-jquery-delayed-event-only-after-a-short-pause-in-typing-e-g-timew
 */
var typewatch = (function(){
  var timer = 0;
  return function(callback, ms){
    clearTimeout (timer);
    timer = setTimeout(callback, ms);
  }
})();

function autosave_request(e) {
  $('#article_form').keyup(function() {
    typewatch(function() {
      $.ajax({
        type: "POST",
        url: '/admin/content/autosave',
        data: $("#article_form").serialize()});
    }, 5000)
  });
}

function tag_manager() {
  var tagApi = jQuery("#article_keywords").tagsManager({
    prefilled: $('#article_keywords').val()
  });

  jQuery("#article_keywords").typeahead({
    name: 'tags',
    limit: 15,
    prefetch: '/admin/content/auto_complete_for_article_keywords'
  }).on('typeahead:selected', function (e, d) {
    tagApi.tagsManager("pushTag", d.value);
  });
}

function save_article_tags() {
  $('#article_keywords').val($('#article_form').find('input[name="hidden-article[keywords]"]').val());
}

function doneTyping () {
  $( "#save-bar").fadeIn(2000, function() {

  });
}

function set_savebar() {
  var typingTimer;
  var doneTypingInterval = 3000;

  $( "#article_body_and_extended" ).keydown(function() {
    $( "#save-bar").fadeOut(2000, function() {

    });
    clearTimeout(typingTimer);
  });

  $('#article_body_and_extended').keyup(function(){
    typingTimer = setTimeout(doneTyping, doneTypingInterval);
  });
}

// From http://www.shawnolson.net/scripts/public_smo_scripts.js
function check_all(checkbox) {
  var form = checkbox.form, z = 0;
  for(z=0; z<form.length;z++){
    if(form[z].type == 'checkbox' && form[z].name != 'checkall'){
      form[z].checked = checkbox.checked;
    }
  }
}

$(document).ready(function() {
  $('#article_form').each(function(e){autosave_request(e)});
  $('#article_form').submit(function(e){save_article_tags()});
  $('#article_form').each(function(e){tag_manager()});
  $('#article_body_and_extended').each(function(e){set_savebar()});

  // DatePickers
  $('.datepicker').each(function() {
    $(this).datepicker($.datepicker.regional[this.dataset.locale]);
  });

  // Date time picker (not related to date picker at all!)
  $( "#article_published_at" ).datetimepicker();

  // DropDown
  $(".dropdown-toggle").dropdown();
});

$(document).delegate('*[data-toggle="lightbox"]', 'click',
    function(event) {
      event.preventDefault();
      $(this).ekkoLightbox();
    });
<commit_msg>Remove button fade-out effect<commit_after>// Admin javascript manifest
//
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require jquery-ui/i18n/datepicker-da
//= require jquery-ui/i18n/datepicker-de
//= require jquery-ui/i18n/datepicker-es
//= require jquery-ui/i18n/datepicker-fr
//= require jquery-ui/i18n/datepicker-he
//= require jquery-ui/i18n/datepicker-it
//= require jquery-ui/i18n/datepicker-ja
//= require jquery-ui/i18n/datepicker-lt
//= require jquery-ui/i18n/datepicker-nb
//= require jquery-ui/i18n/datepicker-nl
//= require jquery-ui/i18n/datepicker-pl
//= require jquery-ui/i18n/datepicker-pt-BR
//= require jquery-ui/i18n/datepicker-ro
//= require jquery-ui/i18n/datepicker-ru
//= require jquery-ui/i18n/datepicker-zh-CN
//= require jquery-ui/i18n/datepicker-zh-TW
//= require datetimepicker
//= require bootstrap
//= require quicktags
//= require tagmanager
//= require typeahead
//= require sidebar
//= require spinnable
//= require lightbox
//
//= require_self

/* typewatch() borrowed from
 * http://stackoverflow.com/questions/2219924/idiomatic-jquery-delayed-event-only-after-a-short-pause-in-typing-e-g-timew
 */
var typewatch = (function(){
  var timer = 0;
  return function(callback, ms){
    clearTimeout (timer);
    timer = setTimeout(callback, ms);
  }
})();

function autosave_request(e) {
  $('#article_form').keyup(function() {
    typewatch(function() {
      $.ajax({
        type: "POST",
        url: '/admin/content/autosave',
        data: $("#article_form").serialize()});
    }, 5000)
  });
}

function tag_manager() {
  var tagApi = jQuery("#article_keywords").tagsManager({
    prefilled: $('#article_keywords').val()
  });

  jQuery("#article_keywords").typeahead({
    name: 'tags',
    limit: 15,
    prefetch: '/admin/content/auto_complete_for_article_keywords'
  }).on('typeahead:selected', function (e, d) {
    tagApi.tagsManager("pushTag", d.value);
  });
}

function save_article_tags() {
  $('#article_keywords').val($('#article_form').find('input[name="hidden-article[keywords]"]').val());
}

// From http://www.shawnolson.net/scripts/public_smo_scripts.js
function check_all(checkbox) {
  var form = checkbox.form, z = 0;
  for(z=0; z<form.length;z++){
    if(form[z].type == 'checkbox' && form[z].name != 'checkall'){
      form[z].checked = checkbox.checked;
    }
  }
}

$(document).ready(function() {
  $('#article_form').each(function(e){autosave_request(e)});
  $('#article_form').submit(function(e){save_article_tags()});
  $('#article_form').each(function(e){tag_manager()});

  // DatePickers
  $('.datepicker').each(function() {
    $(this).datepicker($.datepicker.regional[this.dataset.locale]);
  });

  // Date time picker (not related to date picker at all!)
  $( "#article_published_at" ).datetimepicker();

  // DropDown
  $(".dropdown-toggle").dropdown();
});

$(document).delegate('*[data-toggle="lightbox"]', 'click',
    function(event) {
      event.preventDefault();
      $(this).ekkoLightbox();
    });
<|endoftext|>


<commit_before>var FeatureDao = require('../../../../lib/features/user/featureDao.js')
  , GeoPackageManager = require('../../../../lib/geoPackageManager.js')
  , BoundingBox = require('../../../../lib/boundingBox.js')
  , fs = require('fs')
  , path = require('path')
  , should = require('chai').should();

describe('FeatureDao tests', function() {

  describe('Non indexed test', function() {
    var geoPackage;
    beforeEach('create the GeoPackage connection', function(done) {
      var filename = path.join(__dirname, '..', '..', '..', 'fixtures', 'rivers.gpkg');
      GeoPackageManager.open(filename, function(err, gp) {
        geoPackage = gp;
        done();
      });
    });

    afterEach('close the geopackage connection', function() {
      geoPackage.close();
    });

    it('should read the geometry', function(done) {
      geoPackage.getFeatureDaoWithTableName('FEATURESriversds', function(err, featureDao) {
        featureDao.getSrs(function(err, srs) {
          featureDao.queryForEach(function(err, row, rowDone) {
            var currentRow = featureDao.getFeatureRow(row);
            var geometry = currentRow.getGeometry();
            should.exist(geometry);
            rowDone();
          }, done);
        });
      });
    });

    it('should query for a row with property_1 equal to Gila', function(done) {
      geoPackage.getFeatureDaoWithTableName('FEATURESriversds', function(err, featureDao) {
        featureDao.queryForEqWithFieldAndValue('property_1', 'Gila', function(err, row, rowDone) {
          row.property_1.should.be.equal('Gila');
          rowDone();
        }, done);
      });
    });
  });

  describe('Indexed test', function() {
    var geoPackage;
    var featureDao;

    var originalFilename = path.join(__dirname, '..', '..', '..', 'fixtures', 'rivers_indexed.gpkg');
    var filename = path.join(__dirname, '..', '..', '..', 'fixtures', 'tmp', 'rivers_indexed.gpkg');

    function copyGeopackage(orignal, copy, callback) {
      if (typeof(process) !== 'undefined' && process.version) {
        var fsExtra = require('fs-extra');
        fsExtra.copy(originalFilename, filename, callback);
      } else {
        filename = originalFilename;
        callback();
      }
    }

    beforeEach('should open the geopackage', function(done) {
      copyGeopackage(originalFilename, filename, function(err) {
        GeoPackageManager.open(filename, function(err, gp) {
          geoPackage = gp;
          should.not.exist(err);
          should.exist(gp);
          should.exist(gp.getDatabase().getDBConnection());
          gp.getPath().should.be.equal(filename);
          geoPackage.getFeatureDaoWithTableName('rivers', function(err, riverFeatureDao) {
            featureDao = riverFeatureDao;
            done();
          });
        });
      });
    });

    afterEach('should close the geopackage', function(done) {
      geoPackage.close();
      if (typeof(process) !== 'undefined' && process.version) {
        fs.unlink(filename, done);
      } else {
        done();
      }
    });

    it('should query for indexed geometries', function(done) {
      var count = 0;
      var bbox = new BoundingBox(-12863648.645994272, -12865751.85860068, 6655573.571054254, 6651886.678768059);
      featureDao.queryIndexedFeaturesWithWebMercatorBoundingBox(bbox, function(err, featureRow, rowCallback) {
        should.exist(featureRow.getValueWithColumnName('geom'));
        should.exist(featureRow.getValueWithColumnName('id'));
        should.exist(featureRow.getValueWithColumnName('property_0'));
        should.exist(featureRow.getValueWithColumnName('property_1'));
        should.exist(featureRow.getValueWithColumnName('property_2'));
        count++;
        rowCallback();
      }, function(err) {
        console.log('count', count);
        done();
      });
    });
  });

});
<commit_msg>copy the geopackage file before running the test<commit_after>var FeatureDao = require('../../../../lib/features/user/featureDao.js')
  , FeatureColumn = require('../../../../lib/features/user/featureColumn')
  , DataTypes = require('../../../../lib/db/dataTypes')
  , GeoPackageManager = require('../../../../lib/geoPackageManager.js')
  , BoundingBox = require('../../../../lib/boundingBox.js')
  , GeometryData = require('../../../../lib/geom/geometryData')
  , testSetup = require('../../../fixtures/testSetup')
  , SetupFeatureTable = require('../../../fixtures/setupFeatureTable')
  , wkx = require('wkx')
  , fs = require('fs')
  , path = require('path')
  , should = require('chai').should();

describe('FeatureDao tests', function() {

  describe('Non indexed test', function() {
    var geoPackage;

    function copyGeopackage(orignal, copy, callback) {
      if (typeof(process) !== 'undefined' && process.version) {
        var fsExtra = require('fs-extra');
        fsExtra.copy(originalFilename, filename, callback);
      } else {
        filename = originalFilename;
        callback();
      }
    }

    beforeEach('create the GeoPackage connection', function(done) {
      var originalFilename = path.join(__dirname, '..', '..', '..', 'fixtures', 'rivers.gpkg');
      var filename = path.join(__dirname, '..', '..', '..', 'fixtures', 'tmp', 'rivers.gpkg');
      copyGeopackage(originalFilename, filename, function() {
        GeoPackageManager.open(filename, function(err, gp) {
          geoPackage = gp;
          done();
        });
      });
    });

    afterEach('close the geopackage connection', function() {
      geoPackage.close();
    });

    it('should read the geometry', function(done) {
      geoPackage.getFeatureDaoWithTableName('FEATURESriversds', function(err, featureDao) {
        featureDao.getSrs(function(err, srs) {
          featureDao.queryForEach(function(err, row, rowDone) {
            var currentRow = featureDao.getFeatureRow(row);
            var geometry = currentRow.getGeometry();
            should.exist(geometry);
            rowDone();
          }, done);
        });
      });
    });

    it('should query for a row with property_1 equal to Gila', function(done) {
      geoPackage.getFeatureDaoWithTableName('FEATURESriversds', function(err, featureDao) {
        featureDao.queryForEqWithFieldAndValue('property_1', 'Gila', function(err, row, rowDone) {
          row.property_1.should.be.equal('Gila');
          rowDone();
        }, done);
      });
    });

  });

  describe.skip('Rivers 2 tests', function(){
    var geoPackage;
    beforeEach('create the GeoPackage connection', function(done) {
      var filename = path.join(__dirname, '..', '..', '..', 'fixtures', 'rivers2.gpkg');
      GeoPackageManager.open(filename, function(err, gp) {
        geoPackage = gp;
        done();
      });
    });

    afterEach('close the geopackage connection', function() {
      geoPackage.close();
    });

    it('should index the geopackage', function(done) {
      this.timeout(5000);
      geoPackage.getFeatureDaoWithTableName('FEATURESriversds', function(err, featureDao) {
        console.log('featureDao', featureDao);
        featureDao.featureTableIndex.index(function(progress) {
          console.log('progress', progress);
        }, function(err) {
          console.log('indexed with err', err);
          done();
        });
      });
    });
  });

  describe('Indexed test', function() {
    var geoPackage;
    var featureDao;

    var originalFilename = path.join(__dirname, '..', '..', '..', 'fixtures', 'rivers_indexed.gpkg');
    var filename = path.join(__dirname, '..', '..', '..', 'fixtures', 'tmp', 'rivers_indexed.gpkg');

    function copyGeopackage(orignal, copy, callback) {
      if (typeof(process) !== 'undefined' && process.version) {
        var fsExtra = require('fs-extra');
        fsExtra.copy(originalFilename, filename, callback);
      } else {
        filename = originalFilename;
        callback();
      }
    }

    beforeEach('should open the geopackage', function(done) {
      copyGeopackage(originalFilename, filename, function(err) {
        GeoPackageManager.open(filename, function(err, gp) {
          geoPackage = gp;
          should.not.exist(err);
          should.exist(gp);
          should.exist(gp.getDatabase().getDBConnection());
          gp.getPath().should.be.equal(filename);
          geoPackage.getFeatureDaoWithTableName('rivers', function(err, riverFeatureDao) {
            featureDao = riverFeatureDao;
            done();
          });
        });
      });
    });

    afterEach('should close the geopackage', function(done) {
      geoPackage.close();
      if (typeof(process) !== 'undefined' && process.version) {
        fs.unlink(filename, done);
      } else {
        done();
      }
    });

    it('should query for indexed geometries', function(done) {
      var count = 0;
      var bbox = new BoundingBox(-12863648.645994272, -12865751.85860068, 6655573.571054254, 6651886.678768059);
      featureDao.queryIndexedFeaturesWithWebMercatorBoundingBox(bbox, function(err, featureRow, rowCallback) {
        should.exist(featureRow.getValueWithColumnName('geom'));
        should.exist(featureRow.getValueWithColumnName('id'));
        should.exist(featureRow.getValueWithColumnName('property_0'));
        should.exist(featureRow.getValueWithColumnName('property_1'));
        should.exist(featureRow.getValueWithColumnName('property_2'));
        count++;
        rowCallback();
      }, function(err) {
        console.log('count', count);
        done();
      });
    });
  });

  describe.skip('Query tests', function() {
    var geopackage;
    var queryTestFeatureDao;
    var testGeoPackage = path.join(__dirname, '..', '..', '..', 'fixtures', 'tmp', 'test.gpkg');

    beforeEach('should create the GeoPackage', function(done) {
      testSetup.deleteGeoPackage(testGeoPackage, function() {
        testSetup.createGeoPackage(testGeoPackage, function(err, gp) {
          geopackage = gp;

          var geometryColumns = SetupFeatureTable.buildGeometryColumns('QueryTest', 'geom', wkx.Types.wkt.Point);
          var boundingBox = new BoundingBox(-180, 180, -80, 80);

          var columns = [];

          columns.push(FeatureColumn.createPrimaryKeyColumnWithIndexAndName(0, 'id'));
          columns.push(FeatureColumn.createGeometryColumn(1, 'geom', wkx.Types.wkt.Point, false, null));
          columns.push(FeatureColumn.createColumnWithIndex(2, 'name', DataTypes.GPKGDataType.GPKG_DT_TEXT, false, ""));

          var box1 = {
            "type": "Polygon",
            "coordinates": [
              [
                [
                  0,
                  0
                ],
                [
                  2,
                  0
                ],
                [
                  2,
                  2
                ],
                [
                  0,
                  2
                ],
                [
                  0,
                  0
                ]
              ]
            ]
          };

          var box2 = {
            "type": "Polygon",
            "coordinates": [
              [
                [
                  -1,
                  1
                ],
                [
                  1,
                  1
                ],
                [
                  1,
                  3
                ],
                [
                  -1,
                  3
                ],
                [
                  -1,
                  1
                ]
              ]
            ]
          };

          var line = {
            "type": "LineString",
            "coordinates": [
              [
                2,
                3
              ],
              [
                -1,
                0
              ]
            ]
          };

          var point = {
            "type": "Point",
            "coordinates": [
              0.5,
              1.5
            ]
          };

          var createRow = function(geoJson, name, featureDao, callback) {
            featureDao.getSrs(function(err, srs) {
              var featureRow = featureDao.newRow();
              var geometryData = new GeometryData();
              geometryData.setSrsId(srs.srs_id);
              var geometry = wkx.Geometry.parseGeoJSON(geoJson);
              geometryData.setGeometry(geometry);
              featureRow.setGeometry(geometryData);
              featureRow.setValueWithColumnName('name', name);

              featureDao.create(featureRow, callback);
            });
          }
          // create the features
          // Two intersecting boxes with a line going through the intersection and a point on the line
          // ---------- / 3
          // | 1  ____|/_____
          // |    |  /|  2  |
          // |____|_/_|     |
          //      |/        |
          //      /_________|
          //     /
          geopackage.createFeatureTableWithGeometryColumns(geometryColumns, boundingBox, 4326, columns, function(err, result) {
            geopackage.getFeatureDaoWithTableName('QueryTest', function(err, featureDao) {
              queryTestFeatureDao = featureDao;
              console.log('featureDao',featureDao);
              createRow(box1, 'box1', featureDao, function() {
                createRow(box2, 'box2', featureDao, function() {
                  createRow(line, 'line', featureDao, function() {
                    createRow(point, 'point', featureDao, function() {
                      featureDao.featureTableIndex.index(function() {
                        console.log('progress', arguments);
                      }, function(err) {
                        should.not.exist(err);
                        done();
                      });
                    });
                  });
                });
              });
            });
          });
        });
      });
    });

    it('should query for box 1', function(done) {
      // var bb = new BoundingBox(minLongitudeOrBoundingBox, maxLongitude, minLatitude, maxLatitude)
      var bb = new BoundingBox(.4, .6, 1.4, 1.6);
      queryTestFeatureDao.queryIndexedFeaturesWithBoundingBox(bb, function(err, row, rowCallback) {
        console.log('row', row);
        rowCallback();
      }, function(){
        console.log('done');
        done();
      });
    });
  });

});
<|endoftext|>