<commit_before>var Backbone = require('backbone');
var _ = require('underscore');
var ConfigModel = require('../../../../../../../javascripts/cartodb3/data/config-model');
var VisDefinitionModel = require('../../../../../../../javascripts/cartodb3/data/vis-definition-model');
var ExportMapModel = require('../../../../../../../javascripts/cartodb3/data/export-map-definition-model');
var ExportView = require('../../../../../../../javascripts/cartodb3/editor/components/modals/export-map/modal-export-map-view');
var templateExportMapDownload = require('../../../../../../../javascripts/cartodb3/editor/components/modals/export-map/export-map-download.tpl')

describe('editor/components/modals/export-map/modal-export-map-view', function () {
  beforeEach(function () {
    var configModel = new ConfigModel({
      base_url: '/u/pepe'
    });

    this.visDefinitionModel = new VisDefinitionModel({
      name: 'Patatas Bravas',
      id: 'v-123'
    }, {
      configModel: configModel
    });

    this.exportMapModel = new ExportMapModel({
      visualization_id: this.visDefinitionModel.get('id'),
    }, {
      configModel: configModel
    });

    this.view = new ExportView({
      modalModel: new Backbone.Model(),
      exportMapModel: this.exportMapModel,
      renderOpts: {
          name: this.visDefinitionModel.get('name')
      }
    });

    spyOn(this.view, '_renderCompleteView').and.callFake(function () {
      this.$el.html(templateExportMapDownload());
    })

    this.view.render();
  });

  describe('render', function () {
    it('should render confirmation view if state is undefined', function () {
      expect(this.view.$el.html()).toContain(_t('editor.maps.export.confirmation.title', {
        name: this.visDefinitionModel.get('name')
      }));
      expect(this.view.$el.html()).toContain(_t('editor.maps.export.confirmation.desc'));
      expect(this.view.$el.html()).toContain(_t('editor.maps.export.confirmation.cancel'));
      expect(this.view.$el.html()).toContain(_t('editor.maps.export.confirmation.confirm'));
    });

    it('should render pending view when pending state', function () {
      var state = 'pending';

      this.exportMapModel.set('state', state);
      this.view.render();

      expect(this.view.$el.html()).toContain(state.charAt(0).toUpperCase() + state.slice(1) + ' ...');
    });

    it('should render uploading view when uploading', function () {
      var state = 'uploading';

      this.exportMapModel.set('state', state);
      this.view.render();

      expect(this.view.$el.html()).toContain(state.charAt(0).toUpperCase() + state.slice(1) + ' ...');
    });

    it('should render exporting view when exporting', function () {
      var state = 'exporting';

      this.exportMapModel.set('state', state);
      this.view.render();

      expect(this.view.$el.html()).toContain(state.charAt(0).toUpperCase() + state.slice(1) + ' ...');
    });

    it('should render complete view when complete', function () {
      this.exportMapModel.set('state', 'complete');
      this.view.render();

      expect(this.view.$el.html()).toContain(_t('editor.maps.export.download.title'));
      expect(this.view.$el.html()).toContain(_t('editor.maps.export.download.tip'));
      expect(this.view.$el.html()).toContain(_t('editor.maps.export.download.desc'));
      expect(this.view.$el.html()).toContain(_t('editor.maps.export.download.confirm'));
    });

    it('should render error view when failure', function () {
      this.exportMapModel.set('state', 'failure');
      this.view.render();

      expect(this.view.$el.html()).toContain(_t('editor.maps.export.error.title'));
      expect(this.view.$el.html()).toContain(_t('editor.maps.export.error.desc'));
    });
  });

  afterEach(function () {
    this.view.clean();
  });
});
<commit_msg>fix linting<commit_after>var Backbone = require('backbone');
var ConfigModel = require('../../../../../../../javascripts/cartodb3/data/config-model');
var VisDefinitionModel = require('../../../../../../../javascripts/cartodb3/data/vis-definition-model');
var ExportMapModel = require('../../../../../../../javascripts/cartodb3/data/export-map-definition-model');
var ExportView = require('../../../../../../../javascripts/cartodb3/editor/components/modals/export-map/modal-export-map-view');
var templateExportMapDownload = require('../../../../../../../javascripts/cartodb3/editor/components/modals/export-map/export-map-download.tpl');

describe('editor/components/modals/export-map/modal-export-map-view', function () {
  beforeEach(function () {
    var configModel = new ConfigModel({
      base_url: '/u/pepe'
    });

    this.visDefinitionModel = new VisDefinitionModel({
      name: 'Patatas Bravas',
      id: 'v-123'
    }, {
      configModel: configModel
    });

    this.exportMapModel = new ExportMapModel({
      visualization_id: this.visDefinitionModel.get('id')
    }, {
      configModel: configModel
    });

    this.view = new ExportView({
      modalModel: new Backbone.Model(),
      exportMapModel: this.exportMapModel,
      renderOpts: {
        name: this.visDefinitionModel.get('name')
      }
    });

    spyOn(this.view, '_renderCompleteView').and.callFake(function () {
      this.$el.html(templateExportMapDownload());
    });

    this.view.render();
  });

  describe('render', function () {
    it('should render confirmation view if state is undefined', function () {
      expect(this.view.$el.html()).toContain(_t('editor.maps.export.confirmation.title', {
        name: this.visDefinitionModel.get('name')
      }));
      expect(this.view.$el.html()).toContain(_t('editor.maps.export.confirmation.desc'));
      expect(this.view.$el.html()).toContain(_t('editor.maps.export.confirmation.cancel'));
      expect(this.view.$el.html()).toContain(_t('editor.maps.export.confirmation.confirm'));
    });

    it('should render pending view when pending state', function () {
      var state = 'pending';

      this.exportMapModel.set('state', state);
      this.view.render();

      expect(this.view.$el.html()).toContain(state.charAt(0).toUpperCase() + state.slice(1) + ' ...');
    });

    it('should render uploading view when uploading', function () {
      var state = 'uploading';

      this.exportMapModel.set('state', state);
      this.view.render();

      expect(this.view.$el.html()).toContain(state.charAt(0).toUpperCase() + state.slice(1) + ' ...');
    });

    it('should render exporting view when exporting', function () {
      var state = 'exporting';

      this.exportMapModel.set('state', state);
      this.view.render();

      expect(this.view.$el.html()).toContain(state.charAt(0).toUpperCase() + state.slice(1) + ' ...');
    });

    it('should render complete view when complete', function () {
      this.exportMapModel.set('state', 'complete');
      this.view.render();

      expect(this.view.$el.html()).toContain(_t('editor.maps.export.download.title'));
      expect(this.view.$el.html()).toContain(_t('editor.maps.export.download.tip'));
      expect(this.view.$el.html()).toContain(_t('editor.maps.export.download.desc'));
      expect(this.view.$el.html()).toContain(_t('editor.maps.export.download.confirm'));
    });

    it('should render error view when failure', function () {
      this.exportMapModel.set('state', 'failure');
      this.view.render();

      expect(this.view.$el.html()).toContain(_t('editor.maps.export.error.title'));
      expect(this.view.$el.html()).toContain(_t('editor.maps.export.error.desc'));
    });
  });

  afterEach(function () {
    this.view.clean();
  });
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Top-Level of foam package
 * @exports foam
 */
foam = {
  isServer: typeof process === 'object',
  core:     {},
  Array:    Array.prototype,
  Function: Function.prototype,
  Number:   Number.prototype,
  Object:   Object.prototype,
  String:   String.prototype,
  Date:     Date.prototype,
};

/** Setup nodejs-like 'global' on web */
if ( ! foam.isServer ) global = this;

/*
 * A LIB is a collection of static constants, properties and functions.
 */
foam.LIB = function LIB(model) {
  var proto;

  function defineProperty(proto, key, map) {
    if ( ! map.value || proto === Object.prototype || proto === Array.prototype )
      Object.defineProperty.apply(this, arguments);
    else
      proto[key] = map.value;
  }

  proto = model.name ? foam[model.name] || ( foam[model.name] = {} ) : foam;

  if ( model.properties ) for ( var i = 0 ; i < model.properties.length ; i++ ) {
    var p = model.properties[i];
    defineProperty(
      proto,
      p.name,
      { get: p.getter, enumerable: false });
  }

  for ( key in model.constants )
    defineProperty(
      proto,
      key,
      { value: model.constants[key], writable: true, enumerable: false });

  if ( model.methods ) for ( var i = 0 ; i < model.methods.length ; i++ ) {
    var m = model.methods[i];
    defineProperty(
      proto,
      m.name,
      { value: m.code || m, writable: true, enumerable: false });
  }
};

/*
 * Add Unique Identifiers (UIDs) to all Objects.
 * UID's are created when first accessed.
 */
foam.LIB({
  name: 'Object',

  properties: [
    {
      name: '$UID',
      getter: (function() {
        var id = 1;
        return function() {
          if ( Object.hasOwnProperty.call(this, '$UID__') ) return this.$UID__;
          Object.defineProperty(this, '$UID__', {value: id, enumerable: false});
          id++;
          return this.$UID__;
        };
      })()
    }
  ]
});

foam.LIB({
  name: 'Number',

  methods: [
    function compareTo(o) { return ( o == this ) ? 0 : this < o ? -1 : 1; },
  ]
});

foam.LIB({
  name: 'String',

  methods: [
    function compareTo(o) { return ( o == this ) ? 0 : this < o ? -1 : 1; },

    /** Adds hashCode functionality to all strings. */
    function hashCode() {
      var hash = 0;
      if ( this.length == 0 ) return hash;

      for (i = 0; i < this.length; i++) {
        var code = this.charCodeAt(i);
        hash = ((hash << 5) - hash) + code;
        hash &= hash;
      }

      return hash;
    }
  ]
});

foam.LIB({
  name: 'Array',
  methods: [
    function diff(other) {
      /** Finds elements added (found in other, not in this) and removed
          (found in this, not in other). Repeated values are treated
          as separate elements, but ordering changes are ignored. */
      var added = other.slice(0);
      var removed = [];
      for ( var i = 0 ; i < this.length ; i++ ) {
        for ( var j = 0 ; j < added.length ; j++ ) {
          if ( this[i].compareTo(added[j]) == 0 ) {
            added.splice(j, 1);
            j--;
            break;
          }
        }
        if ( j == added.length ) removed.push(this[i]);
      }
      return { added: added, removed: removed };
    },
    function clone() {
      /** Returns a deep copy of this array and its contents. */
      var ret = new Array(this.length);
      for ( var i = 0; i < this.length; i++ ) {
        ret[i] = ( this[i].clone ) ? this[i].clone() : this[i];
      }
      return ret;
    },
    function shallowClone() {
      /** Returns a new array containing the same elements as this. */
      return this.slice();
    }
  ]
});

foam.LIB({
  name: 'Date',
  methods: [
    function toRelativeDateString(){
      // TODO i18n: make this translatable
      var seconds = Math.floor((Date.now() - this.getTime())/1000);

      if ( seconds < 60 ) return 'moments ago';

      var minutes = Math.floor((seconds)/60);

      if ( minutes == 1 ) return '1 minute ago';

      if ( minutes < 60 ) return minutes + ' minutes ago';

      var hours = Math.floor(minutes/60);
      if ( hours == 1 ) return '1 hour ago';

      if ( hours < 24 ) return hours + ' hours ago';

      var days = Math.floor(hours / 24);
      if ( days == 1 ) return '1 day ago';

      if ( days < 7 ) return days + ' days ago';

      if ( days < 365 ) {
        var year = 1900+this.getYear();
        var noyear = this.toDateString().replace(' ' + year, '');
        return noyear.substring(4);
      }

      return this.toDateString().substring(4);
    },

    function equals(o) {
      if ( ! o ) return false;
      if ( ! o.getTime ) return false;
      return this.getTime() === o.getTime();
    },

    function compareTo(o){
      if ( o === this ) return 0;
      if ( ! o ) return 1;
      var d = this.getTime() - o.getTime();
      return d == 0 ? 0 : d > 0 ? 1 : -1;
    }
  ]
});

foam.LIB({
  name: 'array',

  methods: [
    function argsToArray(args) {
      /** convenience method to turn 'arguments' into a real array */
      return foam.fn.appendArguments([], args, 0);
    }
  ]
});

foam.LIB({
  name: 'events',

  methods: [
    function oneTime(listener) {
      /** Create a "one-time" listener which unsubscribes itself after its first invocation. **/
      return function(subscription) {
        listener.apply(this, foam.array.argsToArray(arguments));
        subscription.destroy();
      };
    },

    function consoleLog(listener) {
      /** Log all listener invocations to console. **/
      return function() {
        var args = foam.array.argsToArray(arguments);
        console.log(args);
        listener && listener.apply(this, args);
      };
    }
  ]
});

foam.LIB({
  name: 'fn',

  methods: [
    function memoize1(f) {
      // Faster version of memoize() when only dealing with one argument.
      var cache = {};
      var g = function(arg) {
        console.assert(arguments.length == 1, "Memoize1'ed functions must take exactly one argument.");
        var key = arg ? arg.toString() : '';
        if ( ! cache.hasOwnProperty(key) ) cache[key] = f.call(this, arg);
        return cache[key];
      };
      foam.fn.setName(g, 'memoize1(' + f.name + ')');
      return g;
    },

    function setName(f, name) {
      /** Set a function's name for improved debugging and profiling **/
      Object.defineProperty(f, 'name', {value: name, configurable: true});
    },

    function appendArguments(a, args, start) {
      /** Convenience method to append 'arguments' onto a real array **/
      for ( var i = start ; i < args.length ; i++ ) a.push(args[i]);
      return a;
    },

    function argsStr(f) {
      /** Finds the function(...) declaration arguments part. Strips newlines. */
      return f.toString().replace(/(\r\n|\n|\r)/gm,"").match(/^function(\s+[_$\w]+|\s*)\((.*?)\)/)[2] || '';
    },

    function argsArray(f) {
      /**
       * Return a function's arguments as an array.
       * Ex. args(function(a,b) {...}) == ['a', 'b']
       **/
      var args = foam.fn.argsStr(f);
      if ( ! args ) return [];
      args += ',';

      var ret = [];
      // [ ws /* anything */ ] ws arg_name ws [ /* anything */ ],
      var argMatcher = /(\s*\/\*.*?\*\/)?\s*([\w_$]+)\s*(\/\*.*?\*\/)?\s*\,+/g;
      var typeMatch;
      while ((typeMatch = argMatcher.exec(args)) !== null) {
        ret.push(typeMatch[2]);
      }
      return ret;
    },

    // ???: Is this needed?
    /*
    function passProperties(args, f) {
      return function passProperties() {
        var self = this;
        return f.apply(this, args.map(function(arg) { return self[arg]; }));
      };
    }
    */
  ]
});

// Disable setName if not supported on this platform.
try {
  foam.fn.setName(function() {}, '');
} catch (x) {
  foam.LIB({
    name: 'fn',
    methods: [ function setName() { /* NOP */ } ]
  });
}

foam.LIB({
  name: 'string',

  methods: [
    {
      name: 'constantize',
      code: foam.fn.memoize1(function(str) {
        // switchFromCamelCaseToConstantFormat to SWITCH_FROM_CAMEL_CASE_TO_CONSTANT_FORMAT
        return str.replace(/[a-z][^0-9a-z_]/g, function(a) {
          return a.substring(0,1) + '_' + a.substring(1,2);
        }).toUpperCase();
      })
    },

    function pad(str, size) {
      // Right pads to size if size > 0, Left pads to -size if size < 0
      return size < 0 ?
        (new Array(-size).join(' ') + str).slice(size)       :
        (str + new Array(size).join(' ')).substring(0, size) ;
    },

    function multiline(f) {
      // Function for returning multi-line strings from commented functions.
      // Ex. var str = multiline(function() { /* multi-line string here */ });
      if ( typeof f === 'string' ) return f;
      var s = f.toString();
      var start = s.indexOf('/*');
      var end   = s.lastIndexOf('*/');
      return s.substring(start+2, end);
    }
  ]
});

(function() {

  function set(X, key, value) {
    /** Update a Context binding. **/
    X[key] = value;

    // TODO:
    // if ( GLOBAL.SimpleReadOnlyValue && key !== '$' && key !== '$$' )
    // X[key + '$'] = SimpleReadOnlyValue.create({value: value});
  }

  function setDynamic(X, key, dValue) {
    Object.defineProperty(
      X,
      key,
      {
        get: function() { return dValue.get(); },
        configurable: true
      }
    );

    if ( key !== '$' && key !== '$$' ) X[key + '$'] = dValue;
  }

  var ROOT = global;

  function lookup_(id) {
    var path = id.split('.');
    var root = ROOT;
    for ( var i = 0 ; root && i < path.length ; i++ )
      root = root[path[i]];
    return root;
  }

  var X = {
    lookup: function(id) {
      return id && ( lookup_('foam.core.' + id) || lookup_(id) );
    },

    register: function(cls) {
      var path = cls.id.split('.');
      var root = ROOT;
      for ( var i = 0 ; i < path.length-1 ; i++ ) {
        root = root[path[i]] || ( root[path[i]] = {} );
      }
      root[path[path.length-1]] = cls;
    },

    sub: function sub(opt_args, opt_name) {
      var sub = Object.create(this);

      if ( opt_args ) for ( var key in opt_args ) {
        if ( opt_args.hasOwnProperty(key) ) {
          var asDyn = key !== '$' && key != '$$' && key.charAt(key.length-1) == '$';
          if ( asDyn ) {
            setDynamic(sub, key.substring(0, key.length-1), opt_args[key]);
          } else {
            set(sub, key, opt_args[key]);
          }
        }
      }

      if ( opt_name )
        Object.defineProperty(sub, 'NAME', {value: opt_name, enumerable: false});

      return sub;
    }
  };

  foam.X = X;

  for ( var key in X ) foam[key] = X[key].bind(X);
})();
<commit_msg>Added capitalize and labelize to foam.string.<commit_after>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Top-Level of foam package
 * @exports foam
 */
foam = {
  isServer: typeof process === 'object',
  core:     {},
  Array:    Array.prototype,
  Function: Function.prototype,
  Number:   Number.prototype,
  Object:   Object.prototype,
  String:   String.prototype,
  Date:     Date.prototype,
};

/** Setup nodejs-like 'global' on web */
if ( ! foam.isServer ) global = this;

/*
 * A LIB is a collection of static constants, properties and functions.
 */
foam.LIB = function LIB(model) {
  var proto;

  function defineProperty(proto, key, map) {
    if ( ! map.value || proto === Object.prototype || proto === Array.prototype )
      Object.defineProperty.apply(this, arguments);
    else
      proto[key] = map.value;
  }

  proto = model.name ? foam[model.name] || ( foam[model.name] = {} ) : foam;

  if ( model.properties ) for ( var i = 0 ; i < model.properties.length ; i++ ) {
    var p = model.properties[i];
    defineProperty(
      proto,
      p.name,
      { get: p.getter, enumerable: false });
  }

  for ( key in model.constants )
    defineProperty(
      proto,
      key,
      { value: model.constants[key], writable: true, enumerable: false });

  if ( model.methods ) for ( var i = 0 ; i < model.methods.length ; i++ ) {
    var m = model.methods[i];
    defineProperty(
      proto,
      m.name,
      { value: m.code || m, writable: true, enumerable: false });
  }
};

/*
 * Add Unique Identifiers (UIDs) to all Objects.
 * UID's are created when first accessed.
 */
foam.LIB({
  name: 'Object',

  properties: [
    {
      name: '$UID',
      getter: (function() {
        var id = 1;
        return function() {
          if ( Object.hasOwnProperty.call(this, '$UID__') ) return this.$UID__;
          Object.defineProperty(this, '$UID__', {value: id, enumerable: false});
          id++;
          return this.$UID__;
        };
      })()
    }
  ]
});

foam.LIB({
  name: 'Number',

  methods: [
    function compareTo(o) { return ( o == this ) ? 0 : this < o ? -1 : 1; },
  ]
});

foam.LIB({
  name: 'String',

  methods: [
    function compareTo(o) { return ( o == this ) ? 0 : this < o ? -1 : 1; },

    /** Adds hashCode functionality to all strings. */
    function hashCode() {
      var hash = 0;
      if ( this.length == 0 ) return hash;

      for (i = 0; i < this.length; i++) {
        var code = this.charCodeAt(i);
        hash = ((hash << 5) - hash) + code;
        hash &= hash;
      }

      return hash;
    }
  ]
});

foam.LIB({
  name: 'Array',
  methods: [
    function diff(other) {
      /** Finds elements added (found in other, not in this) and removed
          (found in this, not in other). Repeated values are treated
          as separate elements, but ordering changes are ignored. */
      var added = other.slice(0);
      var removed = [];
      for ( var i = 0 ; i < this.length ; i++ ) {
        for ( var j = 0 ; j < added.length ; j++ ) {
          if ( this[i].compareTo(added[j]) == 0 ) {
            added.splice(j, 1);
            j--;
            break;
          }
        }
        if ( j == added.length ) removed.push(this[i]);
      }
      return { added: added, removed: removed };
    },
    function clone() {
      /** Returns a deep copy of this array and its contents. */
      var ret = new Array(this.length);
      for ( var i = 0; i < this.length; i++ ) {
        ret[i] = ( this[i].clone ) ? this[i].clone() : this[i];
      }
      return ret;
    },
    function shallowClone() {
      /** Returns a new array containing the same elements as this. */
      return this.slice();
    }
  ]
});

foam.LIB({
  name: 'Date',
  methods: [
    function toRelativeDateString(){
      // TODO i18n: make this translatable
      var seconds = Math.floor((Date.now() - this.getTime())/1000);

      if ( seconds < 60 ) return 'moments ago';

      var minutes = Math.floor((seconds)/60);

      if ( minutes == 1 ) return '1 minute ago';

      if ( minutes < 60 ) return minutes + ' minutes ago';

      var hours = Math.floor(minutes/60);
      if ( hours == 1 ) return '1 hour ago';

      if ( hours < 24 ) return hours + ' hours ago';

      var days = Math.floor(hours / 24);
      if ( days == 1 ) return '1 day ago';

      if ( days < 7 ) return days + ' days ago';

      if ( days < 365 ) {
        var year = 1900+this.getYear();
        var noyear = this.toDateString().replace(' ' + year, '');
        return noyear.substring(4);
      }

      return this.toDateString().substring(4);
    },

    function equals(o) {
      if ( ! o ) return false;
      if ( ! o.getTime ) return false;
      return this.getTime() === o.getTime();
    },

    function compareTo(o){
      if ( o === this ) return 0;
      if ( ! o ) return 1;
      var d = this.getTime() - o.getTime();
      return d == 0 ? 0 : d > 0 ? 1 : -1;
    }
  ]
});

foam.LIB({
  name: 'array',

  methods: [
    function argsToArray(args) {
      /** convenience method to turn 'arguments' into a real array */
      return foam.fn.appendArguments([], args, 0);
    }
  ]
});

foam.LIB({
  name: 'events',

  methods: [
    function oneTime(listener) {
      /** Create a "one-time" listener which unsubscribes itself after its first invocation. **/
      return function(subscription) {
        listener.apply(this, foam.array.argsToArray(arguments));
        subscription.destroy();
      };
    },

    function consoleLog(listener) {
      /** Log all listener invocations to console. **/
      return function() {
        var args = foam.array.argsToArray(arguments);
        console.log(args);
        listener && listener.apply(this, args);
      };
    }
  ]
});

foam.LIB({
  name: 'fn',

  methods: [
    function memoize1(f) {
      // Faster version of memoize() when only dealing with one argument.
      var cache = {};
      var g = function(arg) {
        console.assert(arguments.length == 1, "Memoize1'ed functions must take exactly one argument.");
        var key = arg ? arg.toString() : '';
        if ( ! cache.hasOwnProperty(key) ) cache[key] = f.call(this, arg);
        return cache[key];
      };
      foam.fn.setName(g, 'memoize1(' + f.name + ')');
      return g;
    },

    function setName(f, name) {
      /** Set a function's name for improved debugging and profiling **/
      Object.defineProperty(f, 'name', {value: name, configurable: true});
    },

    function appendArguments(a, args, start) {
      /** Convenience method to append 'arguments' onto a real array **/
      for ( var i = start ; i < args.length ; i++ ) a.push(args[i]);
      return a;
    },

    function argsStr(f) {
      /** Finds the function(...) declaration arguments part. Strips newlines. */
      return f.toString().replace(/(\r\n|\n|\r)/gm,"").match(/^function(\s+[_$\w]+|\s*)\((.*?)\)/)[2] || '';
    },

    function argsArray(f) {
      /**
       * Return a function's arguments as an array.
       * Ex. args(function(a,b) {...}) == ['a', 'b']
       **/
      var args = foam.fn.argsStr(f);
      if ( ! args ) return [];
      args += ',';

      var ret = [];
      // [ ws /* anything */ ] ws arg_name ws [ /* anything */ ],
      var argMatcher = /(\s*\/\*.*?\*\/)?\s*([\w_$]+)\s*(\/\*.*?\*\/)?\s*\,+/g;
      var typeMatch;
      while ((typeMatch = argMatcher.exec(args)) !== null) {
        ret.push(typeMatch[2]);
      }
      return ret;
    },

    // ???: Is this needed?
    /*
    function passProperties(args, f) {
      return function passProperties() {
        var self = this;
        return f.apply(this, args.map(function(arg) { return self[arg]; }));
      };
    }
    */
  ]
});

// Disable setName if not supported on this platform.
try {
  foam.fn.setName(function() {}, '');
} catch (x) {
  foam.LIB({
    name: 'fn',
    methods: [ function setName() { /* NOP */ } ]
  });
}

foam.LIB({
  name: 'string',

  methods: [
    {
      name: 'constantize',
      code: foam.fn.memoize1(function(str) {
        // switchFromCamelCaseToConstantFormat to SWITCH_FROM_CAMEL_CASE_TO_CONSTANT_FORMAT
        return str.replace(/[a-z][^0-9a-z_]/g, function(a) {
          return a.substring(0,1) + '_' + a.substring(1,2);
        }).toUpperCase();
      })
    },

    {
      name: 'labelize',
      code: foam.fn.memoize1(function(str) {
        if ( str === '' ) return str;
        return this.capitalize(str.replace(/[a-z][A-Z]/g, function (a) { return a.charAt(0) + ' ' + a.charAt(1); }));
      })
    },

    {
      name: 'capitalize',
      code: foam.fn.memoize1(function(str) {
        // switchFromProperyName to //SwitchFromPropertyName
        return str[0].toUpperCase() + str.substring(1);
      })
    },

    function pad(str, size) {
      // Right pads to size if size > 0, Left pads to -size if size < 0
      return size < 0 ?
        (new Array(-size).join(' ') + str).slice(size)       :
        (str + new Array(size).join(' ')).substring(0, size) ;
    },

    function multiline(f) {
      // Function for returning multi-line strings from commented functions.
      // Ex. var str = multiline(function() { /* multi-line string here */ });
      if ( typeof f === 'string' ) return f;
      var s = f.toString();
      var start = s.indexOf('/*');
      var end   = s.lastIndexOf('*/');
      return s.substring(start+2, end);
    }
  ]
});

(function() {

  function set(X, key, value) {
    /** Update a Context binding. **/
    X[key] = value;

    // TODO:
    // if ( GLOBAL.SimpleReadOnlyValue && key !== '$' && key !== '$$' )
    // X[key + '$'] = SimpleReadOnlyValue.create({value: value});
  }

  function setDynamic(X, key, dValue) {
    Object.defineProperty(
      X,
      key,
      {
        get: function() { return dValue.get(); },
        configurable: true
      }
    );

    if ( key !== '$' && key !== '$$' ) X[key + '$'] = dValue;
  }

  var ROOT = global;

  function lookup_(id) {
    var path = id.split('.');
    var root = ROOT;
    for ( var i = 0 ; root && i < path.length ; i++ )
      root = root[path[i]];
    return root;
  }

  var X = {
    lookup: function(id) {
      return id && ( lookup_('foam.core.' + id) || lookup_(id) );
    },

    register: function(cls) {
      var path = cls.id.split('.');
      var root = ROOT;
      for ( var i = 0 ; i < path.length-1 ; i++ ) {
        root = root[path[i]] || ( root[path[i]] = {} );
      }
      root[path[path.length-1]] = cls;
    },

    sub: function sub(opt_args, opt_name) {
      var sub = Object.create(this);

      if ( opt_args ) for ( var key in opt_args ) {
        if ( opt_args.hasOwnProperty(key) ) {
          var asDyn = key !== '$' && key != '$$' && key.charAt(key.length-1) == '$';
          if ( asDyn ) {
            setDynamic(sub, key.substring(0, key.length-1), opt_args[key]);
          } else {
            set(sub, key, opt_args[key]);
          }
        }
      }

      if ( opt_name )
        Object.defineProperty(sub, 'NAME', {value: opt_name, enumerable: false});

      return sub;
    }
  };

  foam.X = X;

  for ( var key in X ) foam[key] = X[key].bind(X);
})();
<|endoftext|>


<commit_before>/**
 * Created by isc on 12/05/15.
 */
angular.module('myApp.controllers')
	.controller('EvidenceCtrl', ['$document', '$sce', '$scope', '$http',
		'defaults', '$controller', 'Session', '$rootScope', 'camomileService',

		function ($document, $sce, $scope, $http, defaults, $controller, Session, $rootScope, camomileService) {

			/*import MissPlete from './MissPlete.js';

        	new MissPlete({
            	input: document.querySelector('input[name="entry_input"]'),

            	options: [["Barcelona", "BCN"], ["San Francisco", "SF"]]
        	});*/

			$controller('CommonCtrl', {
				$scope: $scope,
				$http: $http,
				defaults: defaults,
				Session: Session
			});

			$scope.model.incomingQueue = $rootScope.queues.evidenceIn;
			$scope.model.outgoingQueue = $rootScope.queues.evidenceOut;

			$scope.model.q = {};

			$scope.model.user_input = {};

			$scope.model.updateIsDisplayedVideo = function (activate) {
				$scope.model.isDisplayedVideo = activate;
			};

			// initialize page state
			$scope.model.updateIsDisplayedVideo(false);

			var _getVideo = function (id_medium, callback) {

				if ($scope.model.useDefaultVideoPath) {
					callback(null, $sce.trustAsResourceUrl(camomileService.getMediumURL(id_medium, 'webm')));
				} else {
					camomileService.getMedium(id_medium, function (err, medium) {
						callback(err, $sce.trustAsResourceUrl($scope.model.videoPath + '/' + medium.url + '.mp4'));
					});
				}
			};

			// Initializes the data from the queue
			// rename from "initQueueData" to "popQueueElement"
			$scope.model.popQueueElement = function () {

				// Get queue first element and pop it from the queue
				camomileService.dequeue($scope.model.incomingQueue, function (err, item) {

					if (err) {
						alert(item.error);
						$scope.$apply(function () {
							$scope.model.video = undefined;
							$scope.model.isDisplayedVideo = false;
							$scope.model.updateIsDisplayedVideo(false);
						});

						return;
					}

					//$scope.model.resetTransparentPlan();
					$scope.model.updateIsDisplayedVideo(true);

					if (item.modality === "pronounced") {
						alert("Audio evidence");
					}

					$scope.model.q = item;
					$scope.model.user_input.person_name = $scope.model.q.person_name;
					$scope.model.initialData = $scope.model.q.person_name;

					// Update the add entry button's status
					$scope.model.updateIsDisplayedVideo($scope.model.user_input.person_name != "");

					async.parallel({
							video: function (callback) {
								_getVideo($scope.model.q.medium_id, callback);
							},
							serverDate: function (callback) {
								camomileService.getDate(function (err, data) {
									callback(null, data.date);
								});
							}
						},
						function (err, results) {
							$scope.model.video = results.video;
							$scope.model.serverDate = results.serverDate;
							$scope.model.clientDate = Date.now();

							$scope.model.restrict_toggle = 2;
							$scope.model.current_time_temp = $scope.model.q.t;
							$scope.model.infbndsec = parseFloat($scope.model.q.t || 0);
							$scope.model.infbndsec-=5.0;
							if ($scope.model.infbndsec < 0) {
								$scope.model.infbndsec = 0;
							}
							$scope.model.supbndsec = parseFloat($scope.model.q.t || 0);
							$scope.model.supbndsec+=5.0;
							if ($scope.model.supbndsec > $scope.model.fullDuration) {
								$scope.model.supbndsec = $scope.model.fullDuration;
							}
							$scope.model.duration = $scope.model.supbndsec - $scope.model.infbndsec;

							$scope.$apply(function () {
								$scope.model.current_time = $scope.model.q.t;
							});

						});
				});
			};

			// Event launched when click on the save button.
			$scope.model.saveQueueElement = function (isEvidence) {

				if (isEvidence == "" && document.getElementById('evidence').src === "") {
					alert("Please draw a bounding box around the face.");
					return;
				}

				var item = {};

				//camomileService.me();

				item.log = {};
				item.log.user = Session.username;
				item.log.date = $scope.model.serverDate;
				item.log.duration = Date.now() - $scope.model.clientDate;

				item.input = {};
				item.input.corpus_id = $scope.model.q.corpus_id;
				item.input.medium_id = $scope.model.q.medium_id;
				item.input.modality = $scope.model.q.modality;
				item.input.person_name = $scope.model.initialData;
				item.input.t = $scope.model.q.t;

				var b_box = {};
				b_box.w = parseFloat(document.getElementById("Wbox").value);
				b_box.h = parseFloat(document.getElementById("Hbox").value);
				b_box.x = parseFloat(document.getElementById("Xbox").value);
				b_box.y = parseFloat(document.getElementById("Ybox").value);

				item.output = {};
				item.output.status = isEvidence;
				if (isEvidence == "yes") {
					item.output.person_name = $scope.model.user_input.person_name;
					item.output.t = $scope.model.current_time;
					item.output.image = document.getElementById('evidence').src;
					item.output.bounding_box = b_box;
				}

				document.getElementById('evidenceImages').style.display = "none";
				document.getElementById('evidence').src = "";
				document.getElementById('draw').children[0].width = document.getElementById('draw').children[0].width;
				document.getElementById("Wbox").value = "";
				document.getElementById("Hbox").value = "";
				document.getElementById("Xbox").value = "";
				document.getElementById("Ybox").value = "";

				camomileService.enqueue($scope.model.outgoingQueue, item, function (err, data) {

					if (err) {
						console.log("Something went wrong");
					} else {
						$scope.model.popQueueElement();
					}

				});
			};

			$document.on(
				"keydown",
				function (event) {
					var targetID = event.target.id;
					var button_checked = false;
					if (targetID == 'confirm' || targetID == 'cancel') {
						button_checked = true;
					}
					//enter
					if (event.keyCode == 13 && targetID != 'localServerInput') {
						//If the focus is on the check buttons, blur the focus first
						if (button_checked) {
							event.target.blur();
						}
						$scope.$apply(function () {
							$scope.model.saveQueueElement(true);
						});
					}
					//space
					if (event.keyCode == 32 && targetID != "entry_input") {
						if (button_checked) {
							event.target.blur();
						}
						$scope.$apply(function () {
							$scope.model.toggle_play();
						});
					}
					//esc-> skip
					if (event.keyCode == 27) {
						$scope.$apply(function () {
							//skip
							$scope.model.saveQueueElement(false);
						});
					}
					//Left
					if (event.keyCode == 37) {
						$scope.$apply(function () {
							if ($scope.model.current_time - 0.04 > $scope.model.infbndsec) {
								$scope.model.current_time = $scope.model.current_time - 0.04;
							} else {
								$scope.model.current_time = $scope.model.infbndsec;
							}
						});
					}
					//Right
					if (event.keyCode == 39) {
						$scope.$apply(function () {
							if ($scope.model.current_time + 0.04 < $scope.model.supbndsec) {
								$scope.model.current_time = $scope.model.current_time + 0.04;
							} else {
								$scope.model.current_time = $scope.model.supbndsec;
							}
						});
					}
					//Up
					if (event.keyCode == 38) {
						$scope.$apply(function () {
							if ($scope.model.current_time - 1 > $scope.model.infbndsec) {
								$scope.model.current_time = $scope.model.current_time - 1;
							} else {
								$scope.model.current_time = $scope.model.infbndsec;
							}
						});

					} //Down
					if (event.keyCode == 40) {
						$scope.$apply(function () {

							if ($scope.model.current_time + 1 < $scope.model.supbndsec) {
								$scope.model.current_time = $scope.model.current_time + 1;
							} else {
								$scope.model.current_time = $scope.model.supbndsec;
							}
						});
					}
				}
			);

		}
	]);

angular.module('myApp.controllers').directive('drawing', function(){
  return {
    restrict: 'E',
    scope: { localRectangles: '=rectangleList' },
    template: '<canvas class="drawing"></canvas>',
    link: function(scope, element){
    	// There are 3 canvas, one used to determine the zone to copy
    	// another one to extract the image and clip it, the last one to resize the image
      var canvasElement = element.children()[0];
      var ctx = canvasElement.getContext('2d');
      var canvasB = document.getElementById("recup");
      var ctxb = canvasB.getContext('2d');
      var canvasE = document.getElementById("evid");
      var ctxe = canvasE.getContext('2d');

      // The first canvas can be sized at the beginning
      canvasElement.width = document.getElementById("video-container").offsetWidth;
      canvasElement.height = document.getElementById("video-container").offsetHeight;

      // Are we drawing?
      var drawing = false;

      // the last coordinates before the current move
      var centerX;
      var centerY;

      element.children()[0].addEventListener('mousedown', function(event){
        reset();
        startX = event.offsetX;
        startY = event.offsetY;
        document.getElementById("player").pause();

        // begins new line
        ctx.beginPath();

        drawing = true;
      },false);

	  element.children()[0].addEventListener('mousemove', function(event){

        if(drawing){

        //document.getElementById('evid').style.display = "none";
        document.getElementById('evidenceImages').style.display = "none";

          // get current mouse position
          currentX = event.offsetX;
          currentY = event.offsetY;

          if((startX<currentX && startY<currentY) || (startX>currentX && startY>currentY)){
          	if(Math.abs(currentY-startY)<Math.abs(currentX-startX)) currentX = currentY-startY+startX;
          	else currentY = currentX-startX+startY;
          }
          else{
          	if(Math.abs(currentY-startY)<Math.abs(currentX-startX)) currentX = startY-currentY+startX;
          	else currentY = startX-currentX+startY;
    	  }

          // limit all the rectangle within the canvas and draw
          if(currentX >= 0 && currentX <= 360*document.getElementById('player').videoWidth/document.getElementById('player').videoHeight && currentY >= 0 && currentY <= 360){
            draw(startX, startY, currentX, currentY);
          }
        }

      },false);

      // canvas reset
      function reset(){
      	// This simple operation reset the canvas
       canvasElement.width = canvasElement.width;
       canvasB.width = canvasB.width;
       canvasE.width = canvasE.width;
      }

      element.children()[0].addEventListener('mouseup', function(event){
        // stop drawing
        drawing = false;
        //document.getElementById('evid').style.display = "";
        document.getElementById('evidenceImages').style.display = "inline-block";
      },false);

      function draw(startX, startY,
                    currentX, currentY, rotate){

        reset();
        var sizeX = currentX - startX;
        var sizeY = currentY - startY;

        ctx.rect(Math.min(startX,currentX),
                 Math.min(startY,currentY),
                 Math.abs(sizeX), Math.abs(sizeY));
        ctx.lineWidth = 3;
        // color gradient
        /*var gradient=ctx.createLinearGradient(Math.min(oppositeX,currentX),Math.min(oppositeY,currentY),Math.max(oppositeX,currentX),Math.max(oppositeY,currentY));
        gradient.addColorStop("0.05","red");
        gradient.addColorStop("0.15","blue");
        gradient.addColorStop("0.25","red");
        gradient.addColorStop("0.35","blue");
        gradient.addColorStop("0.45","red");
        gradient.addColorStop("0.55","blue");
        gradient.addColorStop("0.65","red");
        gradient.addColorStop("0.75","blue");
        gradient.addColorStop("0.85","red");
        gradient.addColorStop("0.95","blue");
        ctx.strokeStyle = gradient;*/
        // color
        ctx.strokeStyle = 'red';
        // draw it
        ctx.stroke();
        // Launch the copy process
        copy(Math.min(startX,currentX),Math.min(startY,currentY),Math.abs(sizeX),Math.abs(sizeY));
        document.getElementById("Xbox").value = Math.min(startX,currentX)/(360*document.getElementById('player').videoWidth/document.getElementById('player').videoHeight);
        document.getElementById("Ybox").value = Math.min(startY,currentY)/360;
        document.getElementById("Wbox").value = Math.abs(sizeX)/(360*document.getElementById('player').videoWidth/document.getElementById('player').videoHeight);
        document.getElementById("Hbox").value = Math.abs(sizeY)/360;
      }

      function copy(X, Y, sizeX, sizeY){

      	// Get the video source and size the second canvas according to the dimension (16:9 or 4:3)
        var src = document.getElementById('player');
        canvasB.width = 360*src.videoWidth/src.videoHeight;
        canvasB.height = 360;
        // Copy the image
        ctxb.drawImage(src,0,0,canvasB.width,canvasB.height);
        // Clip the image
        var btmp = ctxb.getImageData(X, Y, sizeX, sizeY);
        // Clear the second canvas to put the part of the image we want
        ctxb.clearRect(0,0,canvasB.width,canvasB.height);
        ctxb.putImageData(btmp,0,0);
        // Size of the last canvas
        canvasE.width = sizeX;
        canvasE.height = sizeY;
        // Copy from the second canvas to the third
        ctxe.putImageData(btmp,0,0);
        //dataURI JPEG output
        document.getElementById('evidence').src = canvasE.toDataURL("image/png", 1.0);
      }

    }
  };
});<commit_msg>Change the way the user is warned when the evidence is pronounced<commit_after>/**
 * Created by isc on 12/05/15.
 */
angular.module('myApp.controllers')
	.controller('EvidenceCtrl', ['$document', '$sce', '$scope', '$http',
		'defaults', '$controller', 'Session', '$rootScope', 'camomileService',

		function ($document, $sce, $scope, $http, defaults, $controller, Session, $rootScope, camomileService) {

			/*import MissPlete from './MissPlete.js';

        	new MissPlete({
            	input: document.querySelector('input[name="entry_input"]'),

            	options: [["Barcelona", "BCN"], ["San Francisco", "SF"]]
        	});*/

			$controller('CommonCtrl', {
				$scope: $scope,
				$http: $http,
				defaults: defaults,
				Session: Session
			});

			$scope.model.incomingQueue = $rootScope.queues.evidenceIn;
			$scope.model.outgoingQueue = $rootScope.queues.evidenceOut;

			$scope.model.q = {};

			$scope.model.user_input = {};

			$scope.model.updateIsDisplayedVideo = function (activate) {
				$scope.model.isDisplayedVideo = activate;
			};

			// initialize page state
			$scope.model.updateIsDisplayedVideo(false);

			var _getVideo = function (id_medium, callback) {

				if ($scope.model.useDefaultVideoPath) {
					callback(null, $sce.trustAsResourceUrl(camomileService.getMediumURL(id_medium, 'webm')));
				} else {
					camomileService.getMedium(id_medium, function (err, medium) {
						callback(err, $sce.trustAsResourceUrl($scope.model.videoPath + '/' + medium.url + '.mp4'));
					});
				}
			};

			// Initializes the data from the queue
			// rename from "initQueueData" to "popQueueElement"
			$scope.model.popQueueElement = function () {

				// Get queue first element and pop it from the queue
				camomileService.dequeue($scope.model.incomingQueue, function (err, item) {

					if (err) {
						alert(item.error);
						$scope.$apply(function () {
							$scope.model.video = undefined;
							$scope.model.isDisplayedVideo = false;
							$scope.model.updateIsDisplayedVideo(false);
						});

						return;
					}

					//$scope.model.resetTransparentPlan();
					$scope.model.updateIsDisplayedVideo(true);

					if (item.modality === "pronounced") {
						document.getElementById("message").innerHTML = "WARNING: The evidence is pronounced !";
					}

					$scope.model.q = item;
					$scope.model.user_input.person_name = $scope.model.q.person_name;
					$scope.model.initialData = $scope.model.q.person_name;

					// Update the add entry button's status
					$scope.model.updateIsDisplayedVideo($scope.model.user_input.person_name != "");

					async.parallel({
							video: function (callback) {
								_getVideo($scope.model.q.medium_id, callback);
							},
							serverDate: function (callback) {
								camomileService.getDate(function (err, data) {
									callback(null, data.date);
								});
							}
						},
						function (err, results) {
							$scope.model.video = results.video;
							$scope.model.serverDate = results.serverDate;
							$scope.model.clientDate = Date.now();

							$scope.model.restrict_toggle = 2;
							$scope.model.current_time_temp = $scope.model.q.t;
							$scope.model.infbndsec = parseFloat($scope.model.q.t || 0);
							$scope.model.infbndsec-=5.0;
							if ($scope.model.infbndsec < 0) {
								$scope.model.infbndsec = 0;
							}
							$scope.model.supbndsec = parseFloat($scope.model.q.t || 0);
							$scope.model.supbndsec+=5.0;
							if ($scope.model.supbndsec > $scope.model.fullDuration) {
								$scope.model.supbndsec = $scope.model.fullDuration;
							}
							$scope.model.duration = $scope.model.supbndsec - $scope.model.infbndsec;

							$scope.$apply(function () {
								$scope.model.current_time = $scope.model.q.t;
							});

						});
				});
			};

			// Event launched when click on the save button.
			$scope.model.saveQueueElement = function (isEvidence) {

				if (isEvidence == "" && document.getElementById('evidence').src === "") {
					alert("Please draw a bounding box around the face.");
					return;
				}

				var item = {};

				//camomileService.me();

				item.log = {};
				item.log.user = Session.username;
				item.log.date = $scope.model.serverDate;
				item.log.duration = Date.now() - $scope.model.clientDate;

				item.input = {};
				item.input.corpus_id = $scope.model.q.corpus_id;
				item.input.medium_id = $scope.model.q.medium_id;
				item.input.modality = $scope.model.q.modality;
				item.input.person_name = $scope.model.initialData;
				item.input.t = $scope.model.q.t;

				var b_box = {};
				b_box.w = parseFloat(document.getElementById("Wbox").value);
				b_box.h = parseFloat(document.getElementById("Hbox").value);
				b_box.x = parseFloat(document.getElementById("Xbox").value);
				b_box.y = parseFloat(document.getElementById("Ybox").value);

				item.output = {};
				item.output.status = isEvidence;
				if (isEvidence == "yes") {
					item.output.person_name = $scope.model.user_input.person_name;
					item.output.t = $scope.model.current_time;
					item.output.image = document.getElementById('evidence').src;
					item.output.bounding_box = b_box;
				}

				document.getElementById('evidenceImages').style.display = "none";
				document.getElementById('evidence').src = "";
				document.getElementById('draw').children[0].width = document.getElementById('draw').children[0].width;
				document.getElementById("Wbox").value = "";
				document.getElementById("Hbox").value = "";
				document.getElementById("Xbox").value = "";
				document.getElementById("Ybox").value = "";

				camomileService.enqueue($scope.model.outgoingQueue, item, function (err, data) {

					if (err) {
						console.log("Something went wrong");
					} else {
						$scope.model.popQueueElement();
					}

				});
			};

			$document.on(
				"keydown",
				function (event) {
					var targetID = event.target.id;
					var button_checked = false;
					if (targetID == 'confirm' || targetID == 'cancel') {
						button_checked = true;
					}
					//enter
					if (event.keyCode == 13 && targetID != 'localServerInput') {
						//If the focus is on the check buttons, blur the focus first
						if (button_checked) {
							event.target.blur();
						}
						$scope.$apply(function () {
							$scope.model.saveQueueElement(true);
						});
					}
					//space
					if (event.keyCode == 32 && targetID != "entry_input") {
						if (button_checked) {
							event.target.blur();
						}
						$scope.$apply(function () {
							$scope.model.toggle_play();
						});
					}
					//esc-> skip
					if (event.keyCode == 27) {
						$scope.$apply(function () {
							//skip
							$scope.model.saveQueueElement(false);
						});
					}
					//Left
					if (event.keyCode == 37) {
						$scope.$apply(function () {
							if ($scope.model.current_time - 0.04 > $scope.model.infbndsec) {
								$scope.model.current_time = $scope.model.current_time - 0.04;
							} else {
								$scope.model.current_time = $scope.model.infbndsec;
							}
						});
					}
					//Right
					if (event.keyCode == 39) {
						$scope.$apply(function () {
							if ($scope.model.current_time + 0.04 < $scope.model.supbndsec) {
								$scope.model.current_time = $scope.model.current_time + 0.04;
							} else {
								$scope.model.current_time = $scope.model.supbndsec;
							}
						});
					}
					//Up
					if (event.keyCode == 38) {
						$scope.$apply(function () {
							if ($scope.model.current_time - 1 > $scope.model.infbndsec) {
								$scope.model.current_time = $scope.model.current_time - 1;
							} else {
								$scope.model.current_time = $scope.model.infbndsec;
							}
						});

					} //Down
					if (event.keyCode == 40) {
						$scope.$apply(function () {

							if ($scope.model.current_time + 1 < $scope.model.supbndsec) {
								$scope.model.current_time = $scope.model.current_time + 1;
							} else {
								$scope.model.current_time = $scope.model.supbndsec;
							}
						});
					}
				}
			);

		}
	]);

angular.module('myApp.controllers').directive('drawing', function(){
  return {
    restrict: 'E',
    scope: { localRectangles: '=rectangleList' },
    template: '<canvas class="drawing"></canvas>',
    link: function(scope, element){
    	// There are 3 canvas, one used to determine the zone to copy
    	// another one to extract the image and clip it, the last one to resize the image
      var canvasElement = element.children()[0];
      var ctx = canvasElement.getContext('2d');
      var canvasB = document.getElementById("recup");
      var ctxb = canvasB.getContext('2d');
      var canvasE = document.getElementById("evid");
      var ctxe = canvasE.getContext('2d');

      // The first canvas can be sized at the beginning
      canvasElement.width = document.getElementById("video-container").offsetWidth;
      canvasElement.height = document.getElementById("video-container").offsetHeight;

      // Are we drawing?
      var drawing = false;

      // the last coordinates before the current move
      var centerX;
      var centerY;

      element.children()[0].addEventListener('mousedown', function(event){
        reset();
        startX = event.offsetX;
        startY = event.offsetY;
        document.getElementById("player").pause();

        // begins new line
        ctx.beginPath();

        drawing = true;
      },false);

	  element.children()[0].addEventListener('mousemove', function(event){

        if(drawing){

        //document.getElementById('evid').style.display = "none";
        document.getElementById('evidenceImages').style.display = "none";

          // get current mouse position
          currentX = event.offsetX;
          currentY = event.offsetY;

          if((startX<currentX && startY<currentY) || (startX>currentX && startY>currentY)){
          	if(Math.abs(currentY-startY)<Math.abs(currentX-startX)) currentX = currentY-startY+startX;
          	else currentY = currentX-startX+startY;
          }
          else{
          	if(Math.abs(currentY-startY)<Math.abs(currentX-startX)) currentX = startY-currentY+startX;
          	else currentY = startX-currentX+startY;
    	  }

          // limit all the rectangle within the canvas and draw
          if(currentX >= 0 && currentX <= 360*document.getElementById('player').videoWidth/document.getElementById('player').videoHeight && currentY >= 0 && currentY <= 360){
            draw(startX, startY, currentX, currentY);
          }
        }

      },false);

      // canvas reset
      function reset(){
      	// This simple operation reset the canvas
       canvasElement.width = canvasElement.width;
       canvasB.width = canvasB.width;
       canvasE.width = canvasE.width;
      }

      element.children()[0].addEventListener('mouseup', function(event){
        // stop drawing
        drawing = false;
        //document.getElementById('evid').style.display = "";
        document.getElementById('evidenceImages').style.display = "inline-block";
      },false);

      function draw(startX, startY,
                    currentX, currentY, rotate){

        reset();
        var sizeX = currentX - startX;
        var sizeY = currentY - startY;

        ctx.rect(Math.min(startX,currentX),
                 Math.min(startY,currentY),
                 Math.abs(sizeX), Math.abs(sizeY));
        ctx.lineWidth = 3;
        // color gradient
        /*var gradient=ctx.createLinearGradient(Math.min(oppositeX,currentX),Math.min(oppositeY,currentY),Math.max(oppositeX,currentX),Math.max(oppositeY,currentY));
        gradient.addColorStop("0.05","red");
        gradient.addColorStop("0.15","blue");
        gradient.addColorStop("0.25","red");
        gradient.addColorStop("0.35","blue");
        gradient.addColorStop("0.45","red");
        gradient.addColorStop("0.55","blue");
        gradient.addColorStop("0.65","red");
        gradient.addColorStop("0.75","blue");
        gradient.addColorStop("0.85","red");
        gradient.addColorStop("0.95","blue");
        ctx.strokeStyle = gradient;*/
        // color
        ctx.strokeStyle = 'red';
        // draw it
        ctx.stroke();
        // Launch the copy process
        copy(Math.min(startX,currentX),Math.min(startY,currentY),Math.abs(sizeX),Math.abs(sizeY));
        document.getElementById("Xbox").value = Math.min(startX,currentX)/(360*document.getElementById('player').videoWidth/document.getElementById('player').videoHeight);
        document.getElementById("Ybox").value = Math.min(startY,currentY)/360;
        document.getElementById("Wbox").value = Math.abs(sizeX)/(360*document.getElementById('player').videoWidth/document.getElementById('player').videoHeight);
        document.getElementById("Hbox").value = Math.abs(sizeY)/360;
      }

      function copy(X, Y, sizeX, sizeY){

      	// Get the video source and size the second canvas according to the dimension (16:9 or 4:3)
        var src = document.getElementById('player');
        canvasB.width = 360*src.videoWidth/src.videoHeight;
        canvasB.height = 360;
        // Copy the image
        ctxb.drawImage(src,0,0,canvasB.width,canvasB.height);
        // Clip the image
        var btmp = ctxb.getImageData(X, Y, sizeX, sizeY);
        // Clear the second canvas to put the part of the image we want
        ctxb.clearRect(0,0,canvasB.width,canvasB.height);
        ctxb.putImageData(btmp,0,0);
        // Size of the last canvas
        canvasE.width = sizeX;
        canvasE.height = sizeY;
        // Copy from the second canvas to the third
        ctxe.putImageData(btmp,0,0);
        //dataURI JPEG output
        document.getElementById('evidence').src = canvasE.toDataURL("image/png", 1.0);
      }

    }
  };
});<|endoftext|>


<commit_before>"use strict";

/**
 * @type {Chai.Assert}
 */
var assert = require('chai').assert
var xdTesting = require('../../lib/index')
var templates = xdTesting.templates
/**
 * @type {Q}
 */
var q = require('q')

describe('XD-MVC Maps @large', function () {
    var test = this;

    // Set test timeout
    test.timeout(180 * 1000)
    test.pauseTime = 5 * 1000

    xdTesting.baseUrl = "http://localhost:8080/maps.html"
    xdTesting.appFramework = xdTesting.adapter.xdmvc

    /**
     * @returns {WebdriverIO.Client}
     */
    xdTesting.appFramework.prototype.pairTwoDevicesViaMapsGui = function() {
        return this.devices
            .selectAny(device => {
                return device
                    // Pair any device with any other device
                    .app().injectEventLogger()
                    .click('#menu-button')
                    .waitUntil(() => {
                        return device
                            // Wait until an other device shows up in list
                            .isVisible('//*[@id="availableDeviceList"]//*[@class="id"]')
                            // If list does not contain other devices, refresh list and keep waiting
                            .then(isVisible => isVisible || device.click('#showDevices').then(() => {
                                return false
                            }))
                    })
                    // Click on device id
                    .click('//*[@id="availableDeviceList"]//*[@class="id"]')
                    .waitUntil(() => device
                    // Wait for connection event
                        .app().getEventCounter().then(counter => counter['XDconnection'] === 1))
            })
    }

    it('should pair via XDmvc.connectTo', function () {
        let options = {A: templates.devices.chrome(), B: templates.devices.chrome()}

        return xdTesting.multiremote(options).init()
            .app().pairDevicesViaXDMVC()
            .selectById('A', deviceA => deviceA
                .execute(function () {
                    return XDmvc.getConnectedDevices().length
                })
                .then(ret => assert.equal(ret.value, 1))
            )
            .end()
    })

    it('should pair via GUI', function () {
        let options = {A: templates.devices.chrome(), B: templates.devices.chrome()}

        return xdTesting.multiremote(options).init()
            .url(test.baseUrl)
            .app().pairTwoDevicesViaMapsGui()
            .end()
    })

    describe('should sync the map center on mirrored devices', function () {

        xdTesting.loadSetups().forEach(function (setup) {

            // Assemble setup name
            var setupName = Object.keys(setup.devices).map(key => setup.devices[key].name).join(', ')

            it('on ' + setupName, function () {

                let lastXDSyncCounts

                return xdTesting.multiremote(setup.devices).init()
                    .url(test.baseUrl)
                    .name(setupName)
                    .app().pairDevicesViaXDMVC()
                    .checkpoint('paired')
                    .selectById('A',
                        // Omit callback for A
                        () => {},
                        // Use the complement selection
                        allButA => allButA
                            .forEach(device => device
                                .execute(function () {
                                    return eventLogger.eventCounter.XDsync;
                                }).then(ret => {
                                    return {id: device.options.id, XDsync: ret.value}
                                })
                            )
                            .then(function() {
                                // Store last sync counter
                                lastXDSyncCounts = {}
                                Object.keys(arguments).map(key => arguments[key])
                                    .forEach(val => lastXDSyncCounts[val.id] = val.XDsync)
                            })
                    )
                    .selectById('A',
                        deviceA => deviceA
                            .execute(function () {
                                map.setCenter({lat: 47.3783569289, lng: 8.5487177968})
                            })
                            // TODO Wait until map tiles are loaded?
                            .checkpoint('set map center'),
                        allButA => allButA
                            .forEach(device => device
                                .waitUntil(() => device
                                    .execute(function (lastSyncCounter) {
                                        return eventLogger.eventCounter.XDsync > lastSyncCounter
                                    }, lastXDSyncCounts[device.options.id])
                                )
                                .checkpoint('wait for synchronisation')
                                .execute(function (id) {
                                    return {
                                        id: id,
                                        XDsync: eventLogger.eventCounter.XDsync,
                                        map_lat: map.getCenter().lat(),
                                        map_lng: map.getCenter().lng()
                                    };
                                }, device.options.id)
                                .then(ret => {
                                    let value = ret.value
                                    assert.isAbove(value.XDsync, lastXDSyncCounts[value.id], 'Number of syncs has not increased.')
                                    assert.approximately(value.map_lat, 47.3783569289, 0.0000000001)
                                    assert.approximately(value.map_lng, 8.5487177968, 0.0000000001)
                                })
                                // TODO Wait until map tiles are loaded?
                            )
                    )
                    .checkpoint('sync')
                    .end()
            })
        })
    })
})
<commit_msg>Refactor pairViaMapsGUI<commit_after>"use strict";

/**
 * @type {Chai.Assert}
 */
var assert = require('chai').assert
var xdTesting = require('../../lib/index')
var templates = xdTesting.templates
/**
 * @type {Q}
 */
var q = require('q')

describe('XD-MVC Maps @large', function () {
    var test = this;

    // Set test timeout
    test.timeout(180 * 1000)
    test.pauseTime = 5 * 1000

    xdTesting.baseUrl = "http://localhost:8080/maps.html"
    xdTesting.appFramework = xdTesting.adapter.xdmvc

    /**
     * @returns {WebdriverIO.Client}
     */
    xdTesting.appFramework.prototype.pairTwoDevicesViaMapsGui = function() {
        return this.devices
            .selectAny(device => device
                // Pair any device with any other device
                .app().injectEventLogger()
                .click('#menu-button')
                .waitUntil(() => device
                    // Wait until an other device shows up in list
                    .isVisible('//*[@id="availableDeviceList"]//*[@class="id"]')
                    // If list does not contain other devices, refresh list and keep waiting
                    .then(isVisible => isVisible || device.click('#showDevices').then(() => false))
                )
                // Click on device id
                .click('//*[@id="availableDeviceList"]//*[@class="id"]')
                .waitUntil(() => device
                // Wait for connection event
                    .app().getEventCounter().then(counter => counter['XDconnection'] === 1))
            )
    }

    it('should pair via XDmvc.connectTo', function () {
        let options = {A: templates.devices.chrome(), B: templates.devices.chrome()}

        return xdTesting.multiremote(options).init()
            .app().pairDevicesViaXDMVC()
            .selectById('A', deviceA => deviceA
                .execute(function () {
                    return XDmvc.getConnectedDevices().length
                })
                .then(ret => assert.equal(ret.value, 1))
            )
            .end()
    })

    it('should pair via GUI', function () {
        let options = {A: templates.devices.chrome(), B: templates.devices.chrome()}

        return xdTesting.multiremote(options).init()
            .url(test.baseUrl)
            .app().pairTwoDevicesViaMapsGui()
            .end()
    })

    describe('should sync the map center on mirrored devices', function () {

        xdTesting.loadSetups().forEach(function (setup) {

            // Assemble setup name
            var setupName = Object.keys(setup.devices).map(key => setup.devices[key].name).join(', ')

            it('on ' + setupName, function () {

                let lastXDSyncCounts

                return xdTesting.multiremote(setup.devices).init()
                    .url(test.baseUrl)
                    .name(setupName)
                    .app().pairDevicesViaXDMVC()
                    .checkpoint('paired')
                    .selectById('A',
                        // Omit callback for A
                        () => {},
                        // Use the complement selection
                        allButA => allButA
                            .forEach(device => device
                                .execute(function () {
                                    return eventLogger.eventCounter.XDsync;
                                }).then(ret => {
                                    return {id: device.options.id, XDsync: ret.value}
                                })
                            )
                            .then(function() {
                                // Store last sync counter
                                lastXDSyncCounts = {}
                                Object.keys(arguments).map(key => arguments[key])
                                    .forEach(val => lastXDSyncCounts[val.id] = val.XDsync)
                            })
                    )
                    .selectById('A',
                        deviceA => deviceA
                            .execute(function () {
                                map.setCenter({lat: 47.3783569289, lng: 8.5487177968})
                            })
                            // TODO Wait until map tiles are loaded?
                            .checkpoint('set map center'),
                        allButA => allButA
                            .forEach(device => device
                                .waitUntil(() => device
                                    .execute(function (lastSyncCounter) {
                                        return eventLogger.eventCounter.XDsync > lastSyncCounter
                                    }, lastXDSyncCounts[device.options.id])
                                )
                                .checkpoint('wait for synchronisation')
                                .execute(function (id) {
                                    return {
                                        id: id,
                                        XDsync: eventLogger.eventCounter.XDsync,
                                        map_lat: map.getCenter().lat(),
                                        map_lng: map.getCenter().lng()
                                    };
                                }, device.options.id)
                                .then(ret => {
                                    let value = ret.value
                                    assert.isAbove(value.XDsync, lastXDSyncCounts[value.id], 'Number of syncs has not increased.')
                                    assert.approximately(value.map_lat, 47.3783569289, 0.0000000001)
                                    assert.approximately(value.map_lng, 8.5487177968, 0.0000000001)
                                })
                                // TODO Wait until map tiles are loaded?
                            )
                    )
                    .checkpoint('sync')
                    .end()
            })
        })
    })
})
<|endoftext|>


<commit_before>/*global jQuery:false */
/*global chrome:false */

// TODO: Make singleton
// TODO: Safe callbacks
// DEPS: jQuery

var SettingsManager = function(defaultSettings) {
    'use strict';

    var _defaultSettings = defaultSettings || {};

    var _getDefaultSettings = function() {
        return _defaultSettings;
    };

    var _load = function(successCallback, errorCallback) {
        chrome.storage.sync.get(_getDefaultSettings(), function(settings){
            if (chrome.runtime.lastError && jQuery.isFunction(errorCallback)) {
                errorCallback();
            } else if (jQuery.isFunction(successCallback)) {
                successCallback(settings);
            }
        });
    };

    var _save = function(settings, successCallback, errorCallback) {
        chrome.storage.sync.set(settings, function() {
            if (chrome.runtime.lastError && jQuery.isFunction(errorCallback)) {
                errorCallback();
            } else if(jQuery.isFunction(successCallback)) {
                successCallback();
            }
        });
    };

    var _clear = function(successCallback, errorCallback) {
        chrome.storage.sync.clear(function() {
            if (chrome.runtime.lastError && jQuery.isFunction(errorCallback)) {
                errorCallback();
            } else {
                chrome.storage.sync.set(_getDefaultSettings(), function() {
                    if(chrome.runtime.lastError && jQuery.isFunction(errorCallback)) {
                        errorCallback();
                    } else if(jQuery.isFunction(successCallback)) {
                        successCallback();
                    }
                });
            }
        });
    };

    return {
        getDefaultSettings: _getDefaultSettings,
        load: _load,
        save: _save,
        clear: _clear
    };

};<commit_msg>-Added TODO<commit_after>/*global jQuery:false */
/*global chrome:false */

// TODO: Make singleton
// TODO: Safe callbacks
// TODO: Externs

var SettingsManager = function(defaultSettings) {
    'use strict';

    var _defaultSettings = defaultSettings || {};

    var _getDefaultSettings = function() {
        return _defaultSettings;
    };

    var _load = function(successCallback, errorCallback) {
        chrome.storage.sync.get(_getDefaultSettings(), function(settings){
            if (chrome.runtime.lastError && jQuery.isFunction(errorCallback)) {
                errorCallback();
            } else if (jQuery.isFunction(successCallback)) {
                successCallback(settings);
            }
        });
    };

    var _save = function(settings, successCallback, errorCallback) {
        chrome.storage.sync.set(settings, function() {
            if (chrome.runtime.lastError && jQuery.isFunction(errorCallback)) {
                errorCallback();
            } else if(jQuery.isFunction(successCallback)) {
                successCallback();
            }
        });
    };

    var _clear = function(successCallback, errorCallback) {
        chrome.storage.sync.clear(function() {
            if (chrome.runtime.lastError && jQuery.isFunction(errorCallback)) {
                errorCallback();
            } else {
                chrome.storage.sync.set(_getDefaultSettings(), function() {
                    if(chrome.runtime.lastError && jQuery.isFunction(errorCallback)) {
                        errorCallback();
                    } else if(jQuery.isFunction(successCallback)) {
                        successCallback();
                    }
                });
            }
        });
    };

    return {
        getDefaultSettings: _getDefaultSettings,
        load: _load,
        save: _save,
        clear: _clear
    };

};<|endoftext|>


<commit_before>const { request, expect } = require('../../test-helper');
const app = require('../../../app');

describe('Integration | Routes | index route', () => {
  it('should have api informations on root', (done) => {
    // Given
    const article = {
      imgLink: 'https://www.dropbox.com/s/fghmcj18maztdgv/img0.jpg?dl=1',
    };

    // When
    request(app)
      .get('/articles')
      .expect('Content-Type', /json/)
      .end((err, response) => {
        // Then
        expect(response.body).to.deep.equal([article]);
        if (err) {
          done(err);
        }
        done();
      });
  });
});
<commit_msg>bsr(REC-2) : fix last failing tests<commit_after>const { request, expect, sinon } = require('../../test-helper');
const app = require('../../../app');
const DropboxClient = require('../../../src/infrastructure/dropbox');

describe('Integration | Routes | articles route', () => {
  afterEach(() => {
    DropboxClient.getFile.restore();
  });

  it('should have api informations on root', (done) => {
    // Given
    const article = {
      imgLink: 'https://www.dropbox.com/s/fghmcj18maztdgv/img0.jpg?dl=1',
    };
    sinon.stub(DropboxClient, 'getFile').resolves();

    // When
    request(app)
      .get('/articles')
      .expect('Content-Type', /json/)
      .end((err, response) => {
        // Then
        expect(response.body).to.deep.equal([article, {}]);
        if (err) {
          done(err);
        }
        done();
      });
  });
});
<|endoftext|>


<commit_before>describe("Reformed Churches Locator", function() {

    afterEach(function() {
        // Remove the docs we just created
        // TODO: Figure out how to refactor this into a general function that can be used in all tests
        // dir.destroy()
        // TODO: Improve this to only remove the docs created by this test, rather
        //  than all docs.
        // $('#delete_all_docs').click()
        // Returns the page to display the home page as it should
        app.navigate(config.test_home_address, {trigger:true})
    });

    describe("'Find a church' page", function() {
        it("should not display an error", function() {
            app.navigate('find_a_church', { trigger: true })
            var content = $('#content').html()
            expect(content).toMatch('Find a church')
        });
    });

    describe("'Import a directory' page", function() {
        it("should not display an error", function() {
            app.navigate('import_directory', { trigger: true })
            var content = $('#content').html()
            expect(content).toMatch('downloading')
        });
        function trigger_url_field(){
            $('#url').val('http://opc.org/locator.html')
            $('#url').focus().keyup()
        }
        function directory_type_is_visible(){
            // The test should wait until the AJAX call completes
            // Check to see if the AJAX call returned here
            return $('#directory_type').is(':visible')
        }
        function click_state_radio_button(){
            $("#one_state_per_page").prop("checked",true)
            $("#one_state_per_page").click()
        }
        function state_drop_down_selector(){
            $('#state_drop_down_selector select[name=state]').click()
        }
        function state_page_is_visible(){
            return $('#state_page').is(':visible') || ($('#state_page').css('display') != 'none')
        }
        describe('url field', function(){
            it('should display step 2 when a valid URL is entered', function(){
                // TODO: Because this test writes to the database, decide whether
                //  the tests should run in a test copy of the database.
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML", 120000)
                runs(function(){
                    expect($('#directory_type').is(':visible')).toBe(true)
                })
            })
        })

        describe('state section', function(){
            it('should display when radio button is clicked', function(){
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(function(){
                    expect($('#state_page').is(':visible')).toBe(true)
                })
            })
        })
        describe('cong details', function(){
            it('should display when select box is clicked', function(){
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(state_drop_down_selector)
                waitsFor(function(){
                    return $('#cong_details_url_selector').is(':visible')
                },'cong_details_url_selector to be visible', 20000)
                runs(function(){
                    expect($('#cong_details_url_selector').is(':visible')).toBe(true)
                })
            })
        })
        describe('get congregation id', function(){
            it('should display when link is clicked', function(){
            	console.log (trigger_url_field)
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(state_drop_down_selector)

                waitsFor(function(){
                    return $('#cong_details_url_selector').is(':visible') &&
                        $('#cong_details_url_selector').html().indexOf('Directory of Congregations') != -1
                },'cong_details_url_selector to be visible', 20000)
                runs(function(){
                    // TODO: Write test to click on the element with this XPATH:
                    //  //*[@id="churchListTable"]/tbody/tr[2]/td[1]/a
                    // console.log($.xpath('//*[@id="churchListTable"]/tbody/tr[2]/td[1]/a'))
                    // $.xpath('//*[@id="churchListTable"]/tbody/tr[2]/td[1]/a').click()
                    console.log($('a[class=lista]')[0])
                    $('a[class=lista]')[0].click()
                })
                waitsFor(function(){
                    return $('#cong_details_url_selector').html().indexOf('Step 4.5') != -1
                },'cong_details_url_selector to display step 4.5', 4000)
                runs(function(){
                    expect($('#cong_details_url_selector').html()).toMatch('Step 4.5')
                })
            })
        })
    })
});

// General test-runner code
(function() {
    var jasmineEnv = jasmine.getEnv();
    jasmineEnv.updateInterval = 1000;
    var htmlReporter = new jasmine.HtmlReporter();
    jasmineEnv.addReporter(htmlReporter);
    jasmineEnv.specFilter = function(spec) {
        return htmlReporter.specFilter(spec);
    };
    var currentWindowOnload = window.onload;
    window.onload = function() {
        if (currentWindowOnload) {
            currentWindowOnload();
        }
        execJasmine();
    };
    function execJasmine() {
        jasmineEnv.execute();
        // Move Jasmine's symbolSummary to top of page to make it easy to see if
        //    some tests are not passing
        $('body').prepend('

')
        $('.banner').first().prepend($('.symbolSummary'))
    }
})();<commit_msg>Saved changes<commit_after>describe("Reformed Churches Locator", function() {

    afterEach(function() {
        // Remove the docs we just created
        // TODO: Figure out how to refactor this into a general function that can be used in all tests
        // dir.destroy()
        // TODO: Improve this to only remove the docs created by this test, rather
        //  than all docs.
        // $('#delete_all_docs').click()
        // Returns the page to display the home page as it should
        app.navigate(config.test_home_address, {trigger:true})
    });

    describe("'Find a church' page", function() {
        it("should not display an error", function() {
            app.navigate('find_a_church', { trigger: true })
            var content = $('#content').html()
            expect(content).toMatch('Find a church')
        });
    });

    describe("'Import a directory' page", function() {
        it("should not display an error", function() {
            app.navigate('import_directory', { trigger: true })
            var content = $('#content').html()
            expect(content).toMatch('downloading')
        });
        function trigger_url_field(){
            $('#url').val('http://opc.org/locator.html')
            $('#url').focus().keyup()
        }
        function directory_type_is_visible(){
            // The test should wait until the AJAX call completes
            // Check to see if the AJAX call returned here
            return $('#directory_type').is(':visible')
        }
        function click_state_radio_button(){
            $("#one_state_per_page").prop("checked",true)
            $("#one_state_per_page").click()
        }
        function state_drop_down_selector(){
            $('#state_drop_down_selector select[name=state]').click()
        }
        function state_page_is_visible(){
            return $('#state_page').is(':visible') || ($('#state_page').css('display') != 'none')
        }
        describe('url field', function(){
            it('should display step 2 when a valid URL is entered', function(){
                // TODO: Because this test writes to the database, decide whether
                //  the tests should run in a test copy of the database.
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML", 120000)
                runs(function(){
                    expect($('#directory_type').is(':visible')).toBe(true)
                })
            })
        })

        describe('state section', function(){
            it('should display when radio button is clicked', function(){
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(function(){
                    expect($('#state_page').is(':visible')).toBe(true)
                })
            })
        })
        describe('cong details', function(){
            it('should display when select box is clicked', function(){
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(state_drop_down_selector)
                waitsFor(function(){
                    return $('#cong_details_url_selector').is(':visible')
                },'cong_details_url_selector to be visible', 20000)
                runs(function(){
                    expect($('#cong_details_url_selector').is(':visible')).toBe(true)
                })
            })
        })
        describe('get congregation id', function(){
            it('should display when link is clicked', function(){
            	console.log (trigger_url_field)
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(state_drop_down_selector)

                waitsFor(function(){
                    return $('#cong_details_url_selector').is(':visible') &&
                        $('#cong_details_url_selector').html().indexOf('Directory of Congregations') != -1
                },'cong_details_url_selector to be visible', 20000)
                runs(function(){
                    // TODO: Write test to click on the element with this XPATH:
                    //  //*[@id="churchListTable"]/tbody/tr[2]/td[1]/a
                    // console.log($.xpath('//*[@id="churchListTable"]/tbody/tr[2]/td[1]/a'))
                    // $.xpath('//*[@id="churchListTable"]/tbody/tr[2]/td[1]/a').click()
                    console.log($('a[class=lista]')[0])
                    $('a[class=lista]')[0].click()
                })
                waitsFor(function(){
                    return $('#cong_details_url_selector').html().indexOf('Step 4.5') != -1
                },'cong_details_url_selector to display step 4.5', 4000)
                runs(function(){
                    expect($('#cong_details_url_selector').html()).toMatch('Step 4.5')
                })
            })
        })
     describe('cong_details_selector_page', function(){
            it('should display when button is clicked', function(){
            	console.log (trigger_url_field)
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(state_drop_down_selector)

                waitsFor(function(){
                    return $('#cong_details_url_selector').is(':visible') &&
                        $('#cong_details_url_selector').html().indexOf('Confirm which URL parameter') != -1
                },'cong_details_url_selector to be visible', 20000)
                 runs(function(){
                    // TODO: Write test to click on the element with this XPATH:
                    //  //*[@id="churchListTable"]/tbody/tr[2]/td[1]/a
                    // console.log($.xpath('//*[@id="churchListTable"]/tbody/tr[2]/td[1]/a'))
                    // $.xpath('//*[@id="churchListTable"]/tbody/tr[2]/td[1]/a').click()
                    console.log($('a[class=lista]')[0])
                    $('a[class=lista]')[0].click()
                })

                waitsFor(function(){
                    return $('#cong_details_url_selector').html().indexOf('Step 4.5') != -1
                },'cong_details_url_selector to display step 4.5', 4000)
                runs(function(){
                    $('#cong_details_url_selector #yes').click()
                })
                runs(function(){
                    expect($('#cong_details_url_selector').html()).toMatch('Step 4.5')
                    //TODO Start Here: modify this section to work in this test
                })
            })
        })
    })
});

// General test-runner code
(function() {
    var jasmineEnv = jasmine.getEnv();
    jasmineEnv.updateInterval = 1000;
    var htmlReporter = new jasmine.HtmlReporter();
    jasmineEnv.addReporter(htmlReporter);
    jasmineEnv.specFilter = function(spec) {
        return htmlReporter.specFilter(spec);
    };
    var currentWindowOnload = window.onload;
    window.onload = function() {
        if (currentWindowOnload) {
            currentWindowOnload();
        }
        execJasmine();
    };
    function execJasmine() {
        jasmineEnv.execute();
        // Move Jasmine's symbolSummary to top of page to make it easy to see if
        //    some tests are not passing
        $('body').prepend('

')
        $('.banner').first().prepend($('.symbolSummary'))
    }
})();<|endoftext|>