<commit_before>var
  _ = require('lodash'),
  q = require('q'),
  InternalError = require('kuzzle-common-objects').Errors.internalError,
  RequestObject = require('kuzzle-common-objects').Models.requestObject;

/**
 * @param {Kuzzle} kuzzle
 * @param options
 * @constructor
 */
function Repository (kuzzle, options) {
  this.collection = options.collection;
  this.index = options.index;
  this.ttl = options.ttl || kuzzle.config.repositories.cacheTTL;
  this.ObjectConstructor = options.ObjectConstructor;
  this.writeLayer = options.writeLayer;

  this.readEngine = options.readEngine || kuzzle.services.list.readEngine;
  this.cacheEngine = options.cacheEngine || kuzzle.services.list.internalCache;

  /*
    If no custom write engine layer is provided, fallback to the standard Kuzzle write workers
   */
  if (!this.writeLayer) {
    this.writeLayer = {
      execute: requestObject => {
        kuzzle.pluginsManager.trigger('data:before' + requestObject.action.charAt(0).toUpperCase() + requestObject.action.slice(1), requestObject);
        return kuzzle.workerListener.add(requestObject);
      }
    };
  }
}

/**
 *
 * @param {string} id
 * @returns {Promise} resolves on a new ObjectConstructor()
 */
Repository.prototype.loadOneFromDatabase = function (id) {
  var
    requestObject,
    result;

  requestObject = new RequestObject({
    controller: 'read',
    action: 'get',
    collection: this.collection,
    index: this.index,
    body: {
      _id: id
    }
  });

  return this.readEngine.get(requestObject)
    .then(response => {
      if (response._id) {
        result = new this.ObjectConstructor();
        if (response._source) {
          return q(_.assignIn(result, response._source, {_id: response._id}));
        }
        return q(_.assignIn(result, response));
      }
      return q(null);
    })
    .catch(error => {
      if (error.status === 404) {
        // no content found, we return null without failing
        return q(null);
      }

      return q.reject(error);
    });
};

/**
 *
 * @param ids
 * @returns {*|promise}
 */
Repository.prototype.loadMultiFromDatabase = function (_ids) {
  var
    requestObject,
    promises,
    ids = [];

  if (!_.isArray(_ids)) {
    return q.reject(new InternalError('Bad argument: ' + _ids.toString() + ' is not an array.'));
  }
  _ids.forEach(element => {
    if (!_.isObject(element)) {
      ids.push(element);
    }
    else {
      ids.push(element._id);
    }
  });

  requestObject = new RequestObject({
    controller: 'read',
    action: 'mget',
    collection: this.collection,
    index: this.index,
    body: {
      ids: ids
    }
  });

  return this.readEngine.mget(requestObject)
    .then(response => {
      if (!response.hits || response.hits.length === 0) {
        return q([]);
      }

      promises = response.hits
        .filter(document => document.found)
        .map(document => {
          var object = new this.ObjectConstructor();

          //return this.hydrate(object, data);
          return _.assignIn(object, document._source, {_id: document._id});
        });

      return q.all(promises);
    });
};

/**
 * Search in database corresponding repository according to a filter
 *
 * @param {Object} filter
 * @param {Number} from manage pagination
 * @param {Number} size manage pagination
 * @param {Boolean} hydrate. True if the result must be hydrated
 *
 * @returns {promise}
 */
Repository.prototype.search = function (filter, from, size) {
  var
    deferred = q.defer(),
    requestObject;

  requestObject = new RequestObject({
    controller: 'read',
    action: 'search',
    collection: this.collection,
    index: this.index,
    body: {
      filter: filter,
      from: from || 0,
      size: size || 20
    }
  });

  this.readEngine.search(requestObject)
    .then(response => {
      if (!response.hits || response.hits.length === 0) {
        return deferred.resolve({total: 0, hits: []});
      }

      return deferred.resolve({total: response.total, hits: response.hits.map((document) => {
        return _.assignIn({}, document._source, {_id: document._id});
      })});
    })
    .catch(function (error) {
      deferred.reject(error);
    });

  return deferred.promise;
};

/**
 * Loads an object from Cache. Returns a promise that resolves either to the
 * retrieved object of null in case it is not found.
 *
 * The opts object currently accepts one optional parameter: key, which forces
 * the cache key to fetch.
 * In case the key is not provided, it defauls to <collection>/id, i.e.: _kuzzle/users/12
 *
 * @param {String} id The id of the object to get
 * @param {Object} opts Optional options.
 * @returns {Promise}
 */
Repository.prototype.loadFromCache = function (id, opts) {
  var
    options = opts || {},
    key = options.key || this.index + '/' + this.collection + '/' + id;

  return this.cacheEngine.get(key)
    .then(response => {
      var object;

      if (response === null) {
        return q(null);
      }

      object = new this.ObjectConstructor();

      return q(_.assignIn(object, JSON.parse(response)));
    })
    .catch(err => q.reject(new InternalError(err)));
};

/**
 * Loads an object from Cache or from the Database if not available in Cache.
 * Returns a promise that resolves either to the
 * retrieved object of null in case it is not found.
 *
 * If the object is not found in Cache and found in the Database,
 * it will be written to cache also.
 *
 * The opts object currently accepts one optional parameter: key, which forces
 * the cache key to fetch.
 * In case the key is not provided, it defauls to <collection>/id, i.e.: _kuzzle/users/12
 *
 * @param {String} id The id of the object to get
 * @param {Object} opts Optional options.
 * @returns {Promise}
 */
Repository.prototype.load = function (id, opts) {
  var deferred = q.defer();

  if (!this.cacheEngine) {
    return this.loadOneFromDatabase(id);
  }

  this.loadFromCache(id, opts)
    .then(object => {
      if (object === null) {
        if (!this.readEngine) {
          deferred.resolve(null);
          return deferred.promise;
        }
        this.loadOneFromDatabase(id)
          .then(objectFromDatabase => {
            if (objectFromDatabase !== null) {
              this.persistToCache(objectFromDatabase);
            }
            deferred.resolve(objectFromDatabase);
          })
          .catch(err => {
            deferred.reject(err);
          });
      }
      else {
        this.refreshCacheTTL(object);
        deferred.resolve(object);
      }
    })
    .catch(err => {
      deferred.reject(err);
    });

  return deferred.promise;
};

/**
 * Persists the given object in the collection that is attached to the repository.
 *
 * @param {Profile|Role|User} object The object to persist
 * @param {Object} opts The persistence options
 * @returns {Promise}
 */
Repository.prototype.persistToDatabase = function (object, opts) {
  var
    options = opts || {},
    method = options.method || 'createOrReplace',
    requestObject = new RequestObject({
      controller: 'write',
      action: method,
      collection: this.collection,
      index: this.index,
      _id: object._id,
      body: this.serializeToDatabase(object)
    });

  return this.writeLayer.execute(requestObject);
};

/**
 * Given an object id, delete it from the configured storage engines
 *
 * @param {String} id   The id of the object to delete
 * The opts optional parameters currently accepts only 1 option:
 *   key: if provided, removes the given key instead of the default one (<collection>/<id>)
 * @param {Object} opts optional options for the current operation
 * @returns {Promise}
 */
Repository.prototype.delete = function (id, opts) {
  var promises = [];

  if (this.cacheEngine) {
    promises.push(this.deleteFromCache(id, opts));
  }
  if (this.writeLayer) {
    promises.push(this.deleteFromDatabase(id));
  }

  return q.all(promises);
};

/**
 * Delete repository from database according to its id
 * @param id
 */
Repository.prototype.deleteFromDatabase = function (id) {
  var
    requestObject;

  requestObject = new RequestObject({
    controller: 'write',
    action: 'delete',
    collection: this.collection,
    index: this.index,
    body: {
      _id: id
    }
  });

  return this.writeLayer.execute(requestObject);
};

/**
 * Persists the given ObjectConstructor object in cache.
 * The opts optional parameters currently accept 2 options:
 *   key: if provided, stores the object to the given key instead of the default one (<collection>/<id>)
 *   ttl: if provided, overrides the default ttl set on the repository for the current operation.
 *
 * @param {Object} object the object to persist
 * @param {Object} opts optional options for the current operation
 * @returns {Promise}
 */
Repository.prototype.persistToCache = function (object, opts) {
  var
    options = opts || {},
    key = options.key || this.index + '/' + this.collection + '/' + object._id,
    ttl = this.ttl,
    doThen = response => {
      if (response === 'OK') {
        return q(object);
      }
      return q.reject(response);
    };

  if (options.ttl !== undefined) {
    ttl = options.ttl;
  }
  if (ttl === false) {
    return this.cacheEngine.set(key, JSON.stringify(this.serializeToCache(object)))
      .then(doThen);
  }

  return this.cacheEngine.volatileSet(key, JSON.stringify(this.serializeToCache(object)), ttl)
    .then(doThen);
};

/**
 * Removes the object from the Cache Engine
 * The opts optional parameters currently accepts only 1 option:
 *   key: if provided, removes the given key instead of the default one (<collection>/<id>)
 *
 * @param {String} id
 * @param {Object} opts optional options for the current operation
 * @returns {Promise}
 */
Repository.prototype.deleteFromCache = function (id, opts) {
  var
    options = opts || {},
    key = options.key || this.index + '/' + this.collection + '/' + id;

  return this.cacheEngine.remove(key);
};

Repository.prototype.refreshCacheTTL = function (object, opts) {
  var
    options = opts || {},
    key = options.key || this.index + '/' + this.collection + '/' + object._id,
    ttl = this.ttl;

  if (options.ttl !== undefined) {
    ttl = options.ttl;
  }

  if (ttl === false) {
    return this.cacheEngine.persist(key);
  }

  return this.cacheEngine.expire(key, ttl);
};

Repository.prototype.expireFromCache = function (object, opts) {
  var
    options = opts || {},
    key = options.key || this.index + '/' + this.collection + '/' + object._id;

  return this.cacheEngine.expire(key, -1);
};

/**
 * Serializes the object before being persisted to cache.
 *
 * @param {Object} object The object to serialize
 * @returns {Object}
 */
Repository.prototype.serializeToCache = function (object) {
  return _.assign({}, object);
};

/**
 * Serializes the object before being persisted to the database.
 *
 * @param {Object} object The object to serialize
 * @returns {Object}
 */
Repository.prototype.serializeToDatabase = function (object) {
  return object;
};

module.exports = Repository;
<commit_msg>nitpick<commit_after>var
  _ = require('lodash'),
  q = require('q'),
  InternalError = require('kuzzle-common-objects').Errors.internalError,
  RequestObject = require('kuzzle-common-objects').Models.requestObject;

/**
 * @param {Kuzzle} kuzzle
 * @param options
 * @constructor
 */
function Repository (kuzzle, options) {
  this.collection = options.collection;
  this.index = options.index;
  this.ttl = options.ttl || kuzzle.config.repositories.cacheTTL;
  this.ObjectConstructor = options.ObjectConstructor;
  this.writeLayer = options.writeLayer;

  this.readEngine = options.readEngine || kuzzle.services.list.readEngine;
  this.cacheEngine = options.cacheEngine || kuzzle.services.list.internalCache;

  /*
    If no custom write engine layer is provided, fallback to the standard Kuzzle write workers
   */
  if (!this.writeLayer) {
    this.writeLayer = {
      execute: requestObject => {
        kuzzle.pluginsManager.trigger('data:before' + requestObject.action.charAt(0).toUpperCase() + requestObject.action.slice(1), requestObject);
        return kuzzle.workerListener.add(requestObject);
      }
    };
  }
}

/**
 *
 * @param {string} id
 * @returns {Promise} resolves on a new ObjectConstructor()
 */
Repository.prototype.loadOneFromDatabase = function (id) {
  var
    requestObject,
    result;

  requestObject = new RequestObject({
    controller: 'read',
    action: 'get',
    collection: this.collection,
    index: this.index,
    body: {
      _id: id
    }
  });

  return this.readEngine.get(requestObject)
    .then(response => {
      if (response._id) {
        result = new this.ObjectConstructor();
        if (response._source) {
          return q(_.assignIn(result, response._source, {_id: response._id}));
        }
        return q(_.assignIn(result, response));
      }
      return q(null);
    })
    .catch(error => {
      if (error.status === 404) {
        // no content found, we return null without failing
        return q(null);
      }

      return q.reject(error);
    });
};

/**
 *
 * @param ids
 * @returns {*|promise}
 */
Repository.prototype.loadMultiFromDatabase = function (_ids) {
  var
    requestObject,
    promises,
    ids = [];

  if (!_.isArray(_ids)) {
    return q.reject(new InternalError('Bad argument: ' + _ids.toString() + ' is not an array.'));
  }
  _ids.forEach(element => {
    if (!_.isObject(element)) {
      ids.push(element);
    }
    else {
      ids.push(element._id);
    }
  });

  requestObject = new RequestObject({
    controller: 'read',
    action: 'mget',
    collection: this.collection,
    index: this.index,
    body: {
      ids: ids
    }
  });

  return this.readEngine.mget(requestObject)
    .then(response => {
      if (!response.hits || response.hits.length === 0) {
        return q([]);
      }

      promises = response.hits
        .filter(document => document.found)
        .map(document => {
          var object = new this.ObjectConstructor();

          return _.assignIn(object, document._source, {_id: document._id});
        });

      return q.all(promises);
    });
};

/**
 * Search in database corresponding repository according to a filter
 *
 * @param {Object} filter
 * @param {Number} from manage pagination
 * @param {Number} size manage pagination
 * @param {Boolean} hydrate. True if the result must be hydrated
 *
 * @returns {promise}
 */
Repository.prototype.search = function (filter, from, size) {
  var
    deferred = q.defer(),
    requestObject;

  requestObject = new RequestObject({
    controller: 'read',
    action: 'search',
    collection: this.collection,
    index: this.index,
    body: {
      filter: filter,
      from: from || 0,
      size: size || 20
    }
  });

  this.readEngine.search(requestObject)
    .then(response => {
      if (!response.hits || response.hits.length === 0) {
        return deferred.resolve({total: 0, hits: []});
      }

      return deferred.resolve({total: response.total, hits: response.hits.map((document) => {
        return _.assignIn({}, document._source, {_id: document._id});
      })});
    })
    .catch(function (error) {
      deferred.reject(error);
    });

  return deferred.promise;
};

/**
 * Loads an object from Cache. Returns a promise that resolves either to the
 * retrieved object of null in case it is not found.
 *
 * The opts object currently accepts one optional parameter: key, which forces
 * the cache key to fetch.
 * In case the key is not provided, it defauls to <collection>/id, i.e.: _kuzzle/users/12
 *
 * @param {String} id The id of the object to get
 * @param {Object} opts Optional options.
 * @returns {Promise}
 */
Repository.prototype.loadFromCache = function (id, opts) {
  var
    options = opts || {},
    key = options.key || this.index + '/' + this.collection + '/' + id;

  return this.cacheEngine.get(key)
    .then(response => {
      var object;

      if (response === null) {
        return q(null);
      }

      object = new this.ObjectConstructor();

      return q(_.assignIn(object, JSON.parse(response)));
    })
    .catch(err => q.reject(new InternalError(err)));
};

/**
 * Loads an object from Cache or from the Database if not available in Cache.
 * Returns a promise that resolves either to the
 * retrieved object of null in case it is not found.
 *
 * If the object is not found in Cache and found in the Database,
 * it will be written to cache also.
 *
 * The opts object currently accepts one optional parameter: key, which forces
 * the cache key to fetch.
 * In case the key is not provided, it defauls to <collection>/id, i.e.: _kuzzle/users/12
 *
 * @param {String} id The id of the object to get
 * @param {Object} opts Optional options.
 * @returns {Promise}
 */
Repository.prototype.load = function (id, opts) {
  var deferred = q.defer();

  if (!this.cacheEngine) {
    return this.loadOneFromDatabase(id);
  }

  this.loadFromCache(id, opts)
    .then(object => {
      if (object === null) {
        if (!this.readEngine) {
          deferred.resolve(null);
          return deferred.promise;
        }
        this.loadOneFromDatabase(id)
          .then(objectFromDatabase => {
            if (objectFromDatabase !== null) {
              this.persistToCache(objectFromDatabase);
            }
            deferred.resolve(objectFromDatabase);
          })
          .catch(err => {
            deferred.reject(err);
          });
      }
      else {
        this.refreshCacheTTL(object);
        deferred.resolve(object);
      }
    })
    .catch(err => {
      deferred.reject(err);
    });

  return deferred.promise;
};

/**
 * Persists the given object in the collection that is attached to the repository.
 *
 * @param {Profile|Role|User} object The object to persist
 * @param {Object} opts The persistence options
 * @returns {Promise}
 */
Repository.prototype.persistToDatabase = function (object, opts) {
  var
    options = opts || {},
    method = options.method || 'createOrReplace',
    requestObject = new RequestObject({
      controller: 'write',
      action: method,
      collection: this.collection,
      index: this.index,
      _id: object._id,
      body: this.serializeToDatabase(object)
    });

  return this.writeLayer.execute(requestObject);
};

/**
 * Given an object id, delete it from the configured storage engines
 *
 * @param {String} id   The id of the object to delete
 * The opts optional parameters currently accepts only 1 option:
 *   key: if provided, removes the given key instead of the default one (<collection>/<id>)
 * @param {Object} opts optional options for the current operation
 * @returns {Promise}
 */
Repository.prototype.delete = function (id, opts) {
  var promises = [];

  if (this.cacheEngine) {
    promises.push(this.deleteFromCache(id, opts));
  }
  if (this.writeLayer) {
    promises.push(this.deleteFromDatabase(id));
  }

  return q.all(promises);
};

/**
 * Delete repository from database according to its id
 * @param id
 */
Repository.prototype.deleteFromDatabase = function (id) {
  var
    requestObject;

  requestObject = new RequestObject({
    controller: 'write',
    action: 'delete',
    collection: this.collection,
    index: this.index,
    body: {
      _id: id
    }
  });

  return this.writeLayer.execute(requestObject);
};

/**
 * Persists the given ObjectConstructor object in cache.
 * The opts optional parameters currently accept 2 options:
 *   key: if provided, stores the object to the given key instead of the default one (<collection>/<id>)
 *   ttl: if provided, overrides the default ttl set on the repository for the current operation.
 *
 * @param {Object} object the object to persist
 * @param {Object} opts optional options for the current operation
 * @returns {Promise}
 */
Repository.prototype.persistToCache = function (object, opts) {
  var
    options = opts || {},
    key = options.key || this.index + '/' + this.collection + '/' + object._id,
    ttl = this.ttl,
    doThen = response => {
      if (response === 'OK') {
        return q(object);
      }
      return q.reject(response);
    };

  if (options.ttl !== undefined) {
    ttl = options.ttl;
  }
  if (ttl === false) {
    return this.cacheEngine.set(key, JSON.stringify(this.serializeToCache(object)))
      .then(doThen);
  }

  return this.cacheEngine.volatileSet(key, JSON.stringify(this.serializeToCache(object)), ttl)
    .then(doThen);
};

/**
 * Removes the object from the Cache Engine
 * The opts optional parameters currently accepts only 1 option:
 *   key: if provided, removes the given key instead of the default one (<collection>/<id>)
 *
 * @param {String} id
 * @param {Object} opts optional options for the current operation
 * @returns {Promise}
 */
Repository.prototype.deleteFromCache = function (id, opts) {
  var
    options = opts || {},
    key = options.key || this.index + '/' + this.collection + '/' + id;

  return this.cacheEngine.remove(key);
};

Repository.prototype.refreshCacheTTL = function (object, opts) {
  var
    options = opts || {},
    key = options.key || this.index + '/' + this.collection + '/' + object._id,
    ttl = this.ttl;

  if (options.ttl !== undefined) {
    ttl = options.ttl;
  }

  if (ttl === false) {
    return this.cacheEngine.persist(key);
  }

  return this.cacheEngine.expire(key, ttl);
};

Repository.prototype.expireFromCache = function (object, opts) {
  var
    options = opts || {},
    key = options.key || this.index + '/' + this.collection + '/' + object._id;

  return this.cacheEngine.expire(key, -1);
};

/**
 * Serializes the object before being persisted to cache.
 *
 * @param {Object} object The object to serialize
 * @returns {Object}
 */
Repository.prototype.serializeToCache = function (object) {
  return _.assign({}, object);
};

/**
 * Serializes the object before being persisted to the database.
 *
 * @param {Object} object The object to serialize
 * @returns {Object}
 */
Repository.prototype.serializeToDatabase = function (object) {
  return object;
};

module.exports = Repository;
<|endoftext|>


<commit_before>var expect = require('chai').expect,
    sinon = require('sinon');

describe('different case url', function() {
    var testrun;
    describe('lowercase', function() {
        before(function(done) {
            this.run({
                collection: {
                    item: [{
                        request: {
                            url: 'http://postman-echo.com/post',
                            method: 'POST'
                        }
                    }]
                }
            }, function(err, result) {
                testrun = result;
                done(err);
            });
        });

        it('should process request when url is in lowercase', function() {
            sinon.assert.calledOnce(testrun.start);
            sinon.assert.calledOnce(testrun.done);
            sinon.assert.calledWith(testrun.done.getCall(0), null);
            sinon.assert.calledOnce(testrun.request);
            sinon.assert.calledWith(testrun.request.getCall(0), null);
            sinon.assert.calledOnce(testrun.response);
            sinon.assert.calledWith(testrun.response.getCall(0), null);

            expect(testrun.response.getCall(0).args[2]).to.have.property('code', 200);
            expect(testrun.response.getCall(0).args[2].stream.toString()).to.include('https://postman-echo.com/post');
        });
    });

    describe('uppercase', function() {
        before(function(done) {
            this.run({
                collection: {
                    item: [{
                        request: {
                            url: 'HTTP://POSTMAN-ECHO.COM/POST',
                            method: 'POST'
                        }
                    }]
                }
            }, function(err, result) {
                testrun = result;
                done(err);
            });
        });

        it('should process request when url is in uppercase', function() {
            sinon.assert.calledOnce(testrun.start);
            sinon.assert.calledOnce(testrun.done);
            sinon.assert.calledWith(testrun.done.getCall(0), null);
            sinon.assert.calledOnce(testrun.request);
            sinon.assert.calledWith(testrun.request.getCall(0), null);
            sinon.assert.calledOnce(testrun.response);
            sinon.assert.calledWith(testrun.response.getCall(0), null);

            expect(testrun.response.getCall(0).args[2]).to.have.property('code', 200);
            expect(testrun.response.getCall(0).args[2].stream.toString()).to.include('https://postman-echo.com/POST');
        });
    });

    describe('mixed Case', function() {
        before(function(done) {
            this.run({
                collection: {
                    item: [{
                        request: {
                            url: 'HtTp://POSTMAN-ECHO.COM/POST',
                            method: 'POST'
                        }
                    }]
                }
            }, function(err, result) {
                testrun = result;
                done(err);
            });
        });

        it('should process request when url is in mixed case', function() {
            sinon.assert.calledOnce(testrun.start);
            sinon.assert.calledOnce(testrun.done);
            sinon.assert.calledWith(testrun.done.getCall(0), null);
            sinon.assert.calledWith(testrun.done.getCall(0), null);
            sinon.assert.calledOnce(testrun.request);
            sinon.assert.calledWith(testrun.request.getCall(0), null);
            sinon.assert.calledOnce(testrun.response);
            sinon.assert.calledWith(testrun.response.getCall(0), null);

            expect(testrun.response.getCall(0).args[2]).to.have.property('code', 200);
            expect(testrun.response.getCall(0).args[2].stream.toString()).to.include('https://postman-echo.com/POST');

        });
    });

    describe('mixed Case with https', function() {
        before(function(done) {
            this.run({
                collection: {
                    item: [{
                        request: {
                            url: 'HtTpS://POsTMaN-ecHo.cOm/PosT',
                            method: 'POST'
                        }
                    }]
                }
            }, function(err, result) {
                testrun = result;
                done(err);
            });
        });

        it('should process https request when url is in mixed case : HtTpS://...', function() {
            sinon.assert.calledOnce(testrun.start);
            sinon.assert.calledOnce(testrun.done);
            sinon.assert.calledWith(testrun.done.getCall(0), null);
            sinon.assert.calledWith(testrun.done.getCall(0), null);
            sinon.assert.calledOnce(testrun.request);
            sinon.assert.calledWith(testrun.request.getCall(0), null);
            sinon.assert.calledOnce(testrun.response);
            sinon.assert.calledWith(testrun.response.getCall(0), null);

            expect(testrun.response.getCall(0).args[2]).to.have.property('code', 200);
            expect(testrun.response.getCall(0).args[2].stream.toString()).to.include('https://postman-echo.com/PosT');

        });
    });

});
<commit_msg>Test : Modify integration tests for URL case insensitivity<commit_after>var expect = require('chai').expect,
    sinon = require('sinon');

describe.only('different case url', function() {
    var testrun;
    describe('lowercase', function() {
        before(function(done) {
            this.run({
                collection: {
                    item: [{
                        request: {
                            url: 'http://postman-echo.com/post',
                            method: 'POST'
                        }
                    }]
                }
            }, function(err, result) {
                testrun = result;
                done(err);
            });
        });

        it('should process request when url is in lowercase', function() {
            sinon.assert.calledOnce(testrun.start);
            sinon.assert.calledOnce(testrun.done);
            sinon.assert.calledWith(testrun.done.getCall(0), null);
            sinon.assert.calledOnce(testrun.request);
            sinon.assert.calledWith(testrun.request.getCall(0), null);
            sinon.assert.calledOnce(testrun.response);
            sinon.assert.calledWith(testrun.response.getCall(0), null);

            expect(testrun.response.getCall(0).args[2]).to.have.property('code', 200);
            expect(testrun.response.getCall(0).args[2].stream.toString()).to.include('https://postman-echo.com/post');
        });
    });

    describe('uppercase', function() {
        before(function(done) {
            this.run({
                collection: {
                    item: [{
                        request: {
                            url: 'HTTP://POSTMAN-ECHO.COM/POST',
                            method: 'POST'
                        }
                    }]
                }
            }, function(err, result) {
                testrun = result;
                done(err);
            });
        });

        it('should process request when url is in uppercase', function() {
            sinon.assert.calledOnce(testrun.start);
            sinon.assert.calledOnce(testrun.done);
            sinon.assert.calledWith(testrun.done.getCall(0), null);
            sinon.assert.calledOnce(testrun.request);
            sinon.assert.calledWith(testrun.request.getCall(0), null);
            sinon.assert.calledOnce(testrun.response);
            sinon.assert.calledWith(testrun.response.getCall(0), null);

            expect(testrun.response.getCall(0).args[2]).to.have.property('code', 200);
            expect(testrun.response.getCall(0).args[2].stream.toString()).to.include('https://postman-echo.com/POST');
        });
    });

    describe('mixed Case', function() {
        before(function(done) {
            this.run({
                collection: {
                    item: [{
                        request: {
                            url: 'HtTp://POSTMAN-ECHO.COM/POST',
                            method: 'POST'
                        }
                    }]
                }
            }, function(err, result) {
                testrun = result;
                done(err);
            });
        });

        it('should process request when url is in mixed case', function() {
            sinon.assert.calledOnce(testrun.start);
            sinon.assert.calledOnce(testrun.done);
            sinon.assert.calledWith(testrun.done.getCall(0), null);
            sinon.assert.calledWith(testrun.done.getCall(0), null);
            sinon.assert.calledOnce(testrun.request);
            sinon.assert.calledWith(testrun.request.getCall(0), null);
            sinon.assert.calledOnce(testrun.response);
            sinon.assert.calledWith(testrun.response.getCall(0), null);

            expect(testrun.response.getCall(0).args[2]).to.have.property('code', 200);
            expect(testrun.response.getCall(0).args[2].stream.toString()).to.include('https://postman-echo.com/POST');

        });
    });

    describe('mixed Case with https', function() {
        before(function(done) {
            this.run({
                collection: {
                    item: [{
                        request: {
                            url: 'HtTpS://POsTMaN-ecHo.cOm/PosT',
                            method: 'POST'
                        }
                    }]
                }
            }, function(err, result) {
                testrun = result;
                done(err);
            });
        });

        it('should process https request when url is in mixed case : HtTpS://...', function() {
            sinon.assert.calledOnce(testrun.start);
            sinon.assert.calledOnce(testrun.done);
            sinon.assert.calledWith(testrun.done.getCall(0), null);
            sinon.assert.calledWith(testrun.done.getCall(0), null);
            sinon.assert.calledOnce(testrun.request);
            sinon.assert.calledWith(testrun.request.getCall(0), null);
            sinon.assert.calledOnce(testrun.response);
            sinon.assert.calledWith(testrun.response.getCall(0), null);

            expect(testrun.response.getCall(0).args[2]).to.have.property('code', 200);
            expect(testrun.response.getCall(0).args[2].stream.toString()).to.include('https://postman-echo.com/PosT');

        });
    });

});
<|endoftext|>


<commit_before> 'use strict';

 L.Popup.Angular = L.Popup.extend({
     onAdd: function(map) {

         this._map = map;

         if (!this._container) {
             this._initLayout();
         }

         var animFade = map.options.fadeAnimation;

         if (animFade) {
             L.DomUtil.setOpacity(this._container, 0);
         }
         map._panes.popupPane.appendChild(this._container);

         map.on(this._getEvents(), this);

         var that = this;

         angular.element(document).ready(function() {
             //Angular magic
             that._compile();

             that.update();

             if (animFade) {
                 L.DomUtil.setOpacity(that._container, 1);
             }

             that.fire('open');

             map.fire('popupopen', {
                 popup: that
             });

             if (that._source) {
                 that._source.fire('popupopen', {
                     popup: that
                 });
             }
        });
     },
     _compile: function() {
         var that = this;
         var $injector = angular.element(document).injector();
         var $rootScope = $injector.get('$rootScope'),
             $compile = $injector.get('$compile'),
             $controller = $injector.get('$controller');

         this._scope = $rootScope.$new(true);
         this._element = angular.element(this._contentNode);
         this._element.html(this.options.template);

         this._$content = {
             _callbacks: [],
             on: function(callback) {
                 that._$content._callbacks.push(callback);
             }
         };

         if (this.options.controller) {
             var controller = $controller(this.options.controller, {
                 '$scope': this._scope,
                 '$map': this._map,
                 '$options': this.options,
                 '$content': this._$content
             });

             if (this.options.controllerAs) {
                 this._scope[this.options.controllerAs] = controller;
             }

             this._element.data('$ngControllerController', controller);
             this._element.children().data('$ngControllerController', controller);
         }

         $compile(this._element)(this._scope);
         this._scope.$apply();
     },
     _updateContent: function() {
         if (!this._content) {
             return;
         }

         if (typeof this._content === 'string' || typeof this._content === 'object') {
             var that = this;
             this._$content._callbacks.map(function(callback) {
                 callback(that._content);
             });

             if (this.options.controllerAs) {
                 this._scope[this.options.controllerAs].$content = this._content;
             } else {
                 this._scope.$content = this._content;
             }

             this._scope.$apply();
             this._scope.$evalAsync(function() {
                 that._adjustPan();
                 that.fire('contentupdate');
             });
         }
     },
     onRemove: function(map) {
         if (this._scope) {
             this._scope.$destroy();
         }
         if(this._$content){
            this._$content._callbacks = [];
         }

         L.Popup.prototype.onRemove.call(this, map);
     }
 });

 L.popup.angular = function(options) {
     return new L.Popup.Angular(options);
 };<commit_msg>changes to support leaflet 1.0.0-rc.1<commit_after> 'use strict';

 L.Popup.Angular = L.Popup.extend({
     onAdd: function(map) {
         this._zoomAnimated = this._zoomAnimated && this.options.zoomAnimation;

         if (!this._container) {
             this._initLayout();
         }

         if (map._fadeAnimated) {
             L.DomUtil.setOpacity(this._container, 0);
         }

         var that = this;

         angular.element(document).ready(function() {
             //Angular magic
             that._compile();

             clearTimeout(that._removeTimeout);
             that.getPane().appendChild(that._container);
             that.update();

             if (map._fadeAnimated) {
                 L.DomUtil.setOpacity(that._container, 1);
             }

             map.fire('popupopen', {popup: that});

             if (that._source) {
                 that._source.fire('popupopen', {popup: that}, true);
                 that._source.on('preclick', L.DomEvent.stopPropagation);
             }
        });
     },
     _compile: function() {
         var that = this;
         var $injector = angular.element(document).injector();
         var $rootScope = $injector.get('$rootScope'),
             $compile = $injector.get('$compile'),
             $controller = $injector.get('$controller');

         this._scope = $rootScope.$new(true);
         this._element = angular.element(this._contentNode);
         this._element.html(this.options.template);

         this._$content = {
             _callbacks: [],
             on: function(callback) {
                 that._$content._callbacks.push(callback);
             }
         };

         if (this.options.controller) {
             var controller = $controller(this.options.controller, {
                 '$scope': this._scope,
                 '$map': this._map,
                 '$options': this.options,
                 '$content': this._$content
             });

             if (this.options.controllerAs) {
                 this._scope[this.options.controllerAs] = controller;
             }

             this._element.data('$ngControllerController', controller);
             this._element.children().data('$ngControllerController', controller);
         }

         $compile(this._element)(this._scope);
         this._scope.$apply();
     },
     update: function() {
         if (!(this._map && this._content)) {
             return;
         }

         if (typeof this._content === 'string' || typeof this._content === 'object') {
             var that = this;

             this._container.style.visibility = 'hidden';

             this._$content._callbacks.map(function(callback) {
                 callback(that._content);
             });

             if (this.options.controllerAs) {
                 this._scope[this.options.controllerAs].$content = this._content;
             } else {
                 this._scope.$content = this._content;
             }

             this._scope.$apply();
             this._scope.$evalAsync(function() {
                 that.fire('contentupdate');
                 that._updateLayout();
                 that._updatePosition();

                 that._container.style.visibility = '';

                 that._adjustPan();
             });
         }
     },
     onRemove: function(map) {
         if (this._scope) {
             this._scope.$destroy();
         }
         if(this._$content){
            this._$content._callbacks = [];
         }

         L.Popup.prototype.onRemove.call(this, map);
     }
 });

 L.popup.angular = function(options) {
     return new L.Popup.Angular(options);
 };<|endoftext|>


<commit_before>/**
 * node-compress-commons
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/ctalkington/node-compress-commons/blob/master/LICENSE-MIT
 */
var inherits = require('util').inherits;
var crc32 = require('buffer-crc32');
var CRC32Stream = require('crc32-stream');
var DeflateCRC32Stream = CRC32Stream.DeflateCRC32Stream;

var ArchiveOutputStream = require('../archive-output-stream');
var ZipArchiveEntry = require('./zip-archive-entry');
var GeneralPurposeBit = require('./general-purpose-bit');

var constants = require('./constants');
var util = require('../../util');
var zipUtil = require('./util');

var ZipArchiveOutputStream = module.exports = function(options) {
  if (!(this instanceof ZipArchiveOutputStream)) {
    return new ZipArchiveOutputStream(options);
  }

  options = this.options = this._defaults(options);

  ArchiveOutputStream.call(this, options);

  this._entry = null;
  this._entries = [];
  this._archive = {
    centralLength: 0,
    centralOffset: 0,
    comment: '',
    finish: false,
    finished: false,
    processing: false
  };
};

inherits(ZipArchiveOutputStream, ArchiveOutputStream);

ZipArchiveOutputStream.prototype._afterAppend = function(zae) {
  this._entries.push(zae);
  this._writeDataDescriptor(zae);

  this._archive.processing = false;
  this._entry = null;

  if (this._archive.finish && !this._archive.finished) {
    this._finish();
  }
};

ZipArchiveOutputStream.prototype._appendBuffer = function(ae, source, callback) {
  if (source.length === 0) {
    ae.setMethod(constants.METHOD_STORED);
  }

  var method = ae.getMethod();

  if (method === constants.METHOD_STORED) {
    ae.setSize(source.length);
    ae.setCompressedSize(source.length);
    ae.setCrc(crc32.unsigned(source));
  }

  this._writeLocalFileHeader(ae);

  if (method === constants.METHOD_STORED) {
    this.write(source);
    this._afterAppend(ae);
    callback(null, ae);
    return;
  } else if (method === constants.METHOD_DEFLATED) {
    this._smartStream(ae, callback).end(source);
    return;
  } else {
    callback(new Error('compression method ' + method + ' not implemented'));
    return;
  }
};

ZipArchiveOutputStream.prototype._appendStream = function(ae, source, callback) {
  ae.getGeneralPurposeBit().useDataDescriptor(true);

  this._writeLocalFileHeader(ae);

  var smart = this._smartStream(ae, callback);
  source.pipe(smart);
};

ZipArchiveOutputStream.prototype._defaults = function(o) {
  if (typeof o !== 'object') {
    o = {};
  }

  if (typeof o.zlib !== 'object') {
    o.zlib = {};
  }

  if (typeof o.zlib.level !== 'number') {
    o.zlib.level = constants.ZLIB_BEST_SPEED;
  }

  return o;
};

ZipArchiveOutputStream.prototype._finish = function() {
  this._archive.centralOffset = this.offset;

  this._entries.forEach(function(ae) {
    this._writeCentralFileHeader(ae);
  }.bind(this));

  this._archive.centralLength = this.offset - this._archive.centralOffset;

  this._writeCentralDirectoryZip64();
  this._writeCentralDirectoryEnd();

  this._archive.processing = false;
  this._archive.finish = true;
  this._archive.finished = true;
  this.end();
};

ZipArchiveOutputStream.prototype._normalizeEntry = function(ae) {
  if (ae.getMethod() === -1) {
    ae.setMethod(constants.METHOD_DEFLATED);
  }

  if (ae.getMethod() === constants.METHOD_DEFLATED) {
    ae.getGeneralPurposeBit().useDataDescriptor(true);
    ae.setVersionNeededToExtract(constants.MIN_VERSION_DATA_DESCRIPTOR);
  }

  if (ae.getTime() === -1) {
    ae.setTime(new Date());
  }

  ae._offsets = {
    file: 0,
    data: 0,
    contents: 0,
  };
};

ZipArchiveOutputStream.prototype._smartStream = function(ae, callback) {
  var deflate = ae.getMethod() === constants.METHOD_DEFLATED;
  var process = deflate ? new DeflateCRC32Stream(this.options.zlib) : new CRC32Stream();

  function handleStuff(err) {
    ae.setCrc(process.digest());
    ae.setSize(process.size());
    ae.setCompressedSize(process.size(true));
    this._afterAppend(ae);
    callback(null, ae);
  }

  process.once('error', callback);
  process.once('end', handleStuff.bind(this));

  process.pipe(this, { end: false });

  return process;
};

ZipArchiveOutputStream.prototype._writeCentralDirectoryEnd = function() {
  var records = this._entries.length;
  var size = this._archive.centralLength;
  var offset = this._archive.centralOffset;

  if (this.isZip64()) {
    records = constants.ZIP64_MAGIC_SHORT;
    size = constants.ZIP64_MAGIC;
    offset = constants.ZIP64_MAGIC;
  }

  // signature
  this.write(zipUtil.getLongBytes(constants.SIG_EOCD));

  // disk numbers
  this.write(constants.SHORT_ZERO);
  this.write(constants.SHORT_ZERO);

  // number of entries
  this.write(zipUtil.getShortBytes(records));
  this.write(zipUtil.getShortBytes(records));

  // length and location of CD
  this.write(zipUtil.getLongBytes(size));
  this.write(zipUtil.getLongBytes(offset));

  // archive comment
  var comment = this.getComment();
  var commentLength = Buffer.byteLength(comment);
  this.write(zipUtil.getShortBytes(commentLength));
  this.write(comment);
};

ZipArchiveOutputStream.prototype._writeCentralDirectoryZip64 = function() {
  if (!this.isZip64()) {
    return;
  }

  // signature
  this.write(constants.SIG_ZIP64_EOCD);

  // size of the ZIP64 EOCD record
  this.write(zipUtil.getEightBytes((constants.SHORT * 2) + (constants.LONG * 2) + (8 * 4)));

  // version made by
  this.write(zipUtil.getShortBytes((ae.getPlatform() << 8) | constants.VERSION_MADEBY));

  // version needed to extract
  this.write(zipUtil.getShortBytes(ae.getVersionNeededToExtract()));

  // disk numbers
  this.write(constants.LONG_ZERO);
  this.write(constants.LONG_ZERO);

  // number of entries
  this.write(zipUtil.getEightBytes(this._entries.length));
  this.write(zipUtil.getEightBytes(this._entries.length));

  // length and location of CD
  this.write(zipUtil.getEightBytes(this._archive.centralLength));
  this.write(zipUtil.getEightBytes(this._archive.centralOffset));

  // extensible data sector
  // not implemented at this time

  // end of central directory locator
  this.write(costants.SIG_ZIP64_EOCD_LOC);

  // disk number holding the ZIP64 EOCD record
  this.write(constants.LONG_ZERO);

  // relative offset of the ZIP64 EOCD record
  this.write(zipUtil.getEightBytes(this._archive.centralOffset + this._archive.centralLength));

  // total number of disks
  this.write(this.getLongBytes(1));
};

ZipArchiveOutputStream.prototype._writeCentralFileHeader = function(ae) {
  var gpb = ae.getGeneralPurposeBit();
  var method = ae.getMethod();
  var offsets = ae._offsets;

  var extraBuf;
  var size = ae.getSize();
  var compressedSize = ae.getCompressedSize();

  if (ae.isZip64() || offsets.file > constants.ZIP64_MAGIC) {
    size = constants.ZIP64_MAGIC;
    compressedSize = constants.ZIP64_MAGIC;

    ae.setVersionNeededToExtract(constants.MIN_VERSION_ZIP64);

    extraBuf = new Buffer(28);
    extraBuf.write(zipUtil.getShortBytes(constants.ZIP64_EXTRA_ID));
    extraBuf.write(zipUtil.getShortBytes(24));
    extraBuf.write(zipUtil.getEightBytes(ae.getSize()));
    extraBuf.write(zipUtil.getEightBytes(ae.getCompressedSize()));
    extraBuf.write(zipUtil.getEightBytes(offsets.file));
    ae.setExtra(extraBuf);
  }

  // signature
  this.write(zipUtil.getLongBytes(constants.SIG_CFH));

  // version made by
  this.write(zipUtil.getShortBytes((ae.getPlatform() << 8) | constants.VERSION_MADEBY));

  // version to extract and general bit flag
  this.write(zipUtil.getShortBytes(ae.getVersionNeededToExtract()));
  this.write(gpb.encode());

  // compression method
  this.write(zipUtil.getShortBytes(method));

  // datetime
  this.write(zipUtil.getLongBytes(ae.getTimeDos()));

  // crc32 checksum
  this.write(zipUtil.getLongBytes(ae.getCrc()));

  // sizes
  this.write(zipUtil.getLongBytes(compressedSize));
  this.write(zipUtil.getLongBytes(size));

  var name = ae.getName();
  var comment = ae.getComment();
  var extra = ae.getCentralDirectoryExtra();

  if (gpb.usesUTF8ForNames()) {
    name = new Buffer(name);
    comment = new Buffer(comment);
  }

  // name length
  this.write(zipUtil.getShortBytes(name.length));

  // extra length
  this.write(zipUtil.getShortBytes(extra.length));

  // comments length
  this.write(zipUtil.getShortBytes(comment.length));

  // disk number start
  this.write(constants.SHORT_ZERO);

  // internal attributes
  this.write(zipUtil.getShortBytes(ae.getInternalAttributes()));

  // external attributes
  this.write(zipUtil.getLongBytes(ae.getExternalAttributes()));

  // relative offset of LFH
  if (offsets.file > constants.ZIP64_MAGIC) {
    this.write(zipUtil.getLongBytes(constants.ZIP64_MAGIC));
  } else {
    this.write(zipUtil.getLongBytes(offsets.file));
  }

  // name
  this.write(name);

  // extra
  this.write(extra);

  // comment
  this.write(comment);
};

ZipArchiveOutputStream.prototype._writeDataDescriptor = function(ae) {
  if (!ae.getGeneralPurposeBit().usesDataDescriptor()) {
    return;
  }

  // signature
  this.write(zipUtil.getLongBytes(constants.SIG_DD));

  // crc32 checksum
  this.write(zipUtil.getLongBytes(ae.getCrc()));

  // sizes
  if (ae.isZip64()) {
    this.write(zipUtil.getEightBytes(ae.getCompressedSize()));
    this.write(zipUtil.getEightBytes(ae.getSize()));
  } else {
    this.write(zipUtil.getLongBytes(ae.getCompressedSize()));
    this.write(zipUtil.getLongBytes(ae.getSize()));
  }
};

ZipArchiveOutputStream.prototype._writeLocalFileHeader = function(ae) {
  var gpb = ae.getGeneralPurposeBit();
  var method = ae.getMethod();
  var name = ae.getName();
  var extra = ae.getLocalFileDataExtra();

  if (gpb.usesUTF8ForNames()) {
    name = new Buffer(name);
  }

  ae._offsets.file = this.offset;

  // signature
  this.write(zipUtil.getLongBytes(constants.SIG_LFH));

  // version to extract and general bit flag
  this.write(zipUtil.getShortBytes(ae.getVersionNeededToExtract()));
  this.write(gpb.encode());

  // compression method
  this.write(zipUtil.getShortBytes(method));

  // datetime
  this.write(zipUtil.getLongBytes(ae.getTimeDos()));

  ae._offsets.data = this.offset;

  if (ae.getGeneralPurposeBit().usesDataDescriptor()) {
    // zero fill and set later
    this.write(constants.LONG_ZERO);
    this.write(constants.LONG_ZERO);
    this.write(constants.LONG_ZERO);
  } else {
    // crc32 checksum and sizes
    this.write(zipUtil.getLongBytes(ae.getCrc()));
    this.write(zipUtil.getLongBytes(ae.getCompressedSize()));
    this.write(zipUtil.getLongBytes(ae.getSize()));
  }

  // name length
  this.write(zipUtil.getShortBytes(name.length));

  // extra length
  this.write(zipUtil.getShortBytes(extra.length));

  // name
  this.write(name);

  // extra
  this.write(extra);

  ae._offsets.contents = this.offset;
};

ZipArchiveOutputStream.prototype.getComment = function(comment) {
  return this._archive.comment !== null ? this._archive.comment : '';
};

ZipArchiveOutputStream.prototype.isZip64 = function() {
  return this._entries.length > constants.ZIP64_MAGIC_SHORT || this._archive.centralLength > constants.ZIP64_MAGIC || this._archive.centralOffset > constants.ZIP64_MAGIC;
};

ZipArchiveOutputStream.prototype.setComment = function(comment) {
  this._archive.comment = comment;
};<commit_msg>zip: use existing gpb variable.<commit_after>/**
 * node-compress-commons
 *
 * Copyright (c) 2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/ctalkington/node-compress-commons/blob/master/LICENSE-MIT
 */
var inherits = require('util').inherits;
var crc32 = require('buffer-crc32');
var CRC32Stream = require('crc32-stream');
var DeflateCRC32Stream = CRC32Stream.DeflateCRC32Stream;

var ArchiveOutputStream = require('../archive-output-stream');
var ZipArchiveEntry = require('./zip-archive-entry');
var GeneralPurposeBit = require('./general-purpose-bit');

var constants = require('./constants');
var util = require('../../util');
var zipUtil = require('./util');

var ZipArchiveOutputStream = module.exports = function(options) {
  if (!(this instanceof ZipArchiveOutputStream)) {
    return new ZipArchiveOutputStream(options);
  }

  options = this.options = this._defaults(options);

  ArchiveOutputStream.call(this, options);

  this._entry = null;
  this._entries = [];
  this._archive = {
    centralLength: 0,
    centralOffset: 0,
    comment: '',
    finish: false,
    finished: false,
    processing: false
  };
};

inherits(ZipArchiveOutputStream, ArchiveOutputStream);

ZipArchiveOutputStream.prototype._afterAppend = function(zae) {
  this._entries.push(zae);
  this._writeDataDescriptor(zae);

  this._archive.processing = false;
  this._entry = null;

  if (this._archive.finish && !this._archive.finished) {
    this._finish();
  }
};

ZipArchiveOutputStream.prototype._appendBuffer = function(ae, source, callback) {
  if (source.length === 0) {
    ae.setMethod(constants.METHOD_STORED);
  }

  var method = ae.getMethod();

  if (method === constants.METHOD_STORED) {
    ae.setSize(source.length);
    ae.setCompressedSize(source.length);
    ae.setCrc(crc32.unsigned(source));
  }

  this._writeLocalFileHeader(ae);

  if (method === constants.METHOD_STORED) {
    this.write(source);
    this._afterAppend(ae);
    callback(null, ae);
    return;
  } else if (method === constants.METHOD_DEFLATED) {
    this._smartStream(ae, callback).end(source);
    return;
  } else {
    callback(new Error('compression method ' + method + ' not implemented'));
    return;
  }
};

ZipArchiveOutputStream.prototype._appendStream = function(ae, source, callback) {
  ae.getGeneralPurposeBit().useDataDescriptor(true);

  this._writeLocalFileHeader(ae);

  var smart = this._smartStream(ae, callback);
  source.pipe(smart);
};

ZipArchiveOutputStream.prototype._defaults = function(o) {
  if (typeof o !== 'object') {
    o = {};
  }

  if (typeof o.zlib !== 'object') {
    o.zlib = {};
  }

  if (typeof o.zlib.level !== 'number') {
    o.zlib.level = constants.ZLIB_BEST_SPEED;
  }

  return o;
};

ZipArchiveOutputStream.prototype._finish = function() {
  this._archive.centralOffset = this.offset;

  this._entries.forEach(function(ae) {
    this._writeCentralFileHeader(ae);
  }.bind(this));

  this._archive.centralLength = this.offset - this._archive.centralOffset;

  this._writeCentralDirectoryZip64();
  this._writeCentralDirectoryEnd();

  this._archive.processing = false;
  this._archive.finish = true;
  this._archive.finished = true;
  this.end();
};

ZipArchiveOutputStream.prototype._normalizeEntry = function(ae) {
  if (ae.getMethod() === -1) {
    ae.setMethod(constants.METHOD_DEFLATED);
  }

  if (ae.getMethod() === constants.METHOD_DEFLATED) {
    ae.getGeneralPurposeBit().useDataDescriptor(true);
    ae.setVersionNeededToExtract(constants.MIN_VERSION_DATA_DESCRIPTOR);
  }

  if (ae.getTime() === -1) {
    ae.setTime(new Date());
  }

  ae._offsets = {
    file: 0,
    data: 0,
    contents: 0,
  };
};

ZipArchiveOutputStream.prototype._smartStream = function(ae, callback) {
  var deflate = ae.getMethod() === constants.METHOD_DEFLATED;
  var process = deflate ? new DeflateCRC32Stream(this.options.zlib) : new CRC32Stream();

  function handleStuff(err) {
    ae.setCrc(process.digest());
    ae.setSize(process.size());
    ae.setCompressedSize(process.size(true));
    this._afterAppend(ae);
    callback(null, ae);
  }

  process.once('error', callback);
  process.once('end', handleStuff.bind(this));

  process.pipe(this, { end: false });

  return process;
};

ZipArchiveOutputStream.prototype._writeCentralDirectoryEnd = function() {
  var records = this._entries.length;
  var size = this._archive.centralLength;
  var offset = this._archive.centralOffset;

  if (this.isZip64()) {
    records = constants.ZIP64_MAGIC_SHORT;
    size = constants.ZIP64_MAGIC;
    offset = constants.ZIP64_MAGIC;
  }

  // signature
  this.write(zipUtil.getLongBytes(constants.SIG_EOCD));

  // disk numbers
  this.write(constants.SHORT_ZERO);
  this.write(constants.SHORT_ZERO);

  // number of entries
  this.write(zipUtil.getShortBytes(records));
  this.write(zipUtil.getShortBytes(records));

  // length and location of CD
  this.write(zipUtil.getLongBytes(size));
  this.write(zipUtil.getLongBytes(offset));

  // archive comment
  var comment = this.getComment();
  var commentLength = Buffer.byteLength(comment);
  this.write(zipUtil.getShortBytes(commentLength));
  this.write(comment);
};

ZipArchiveOutputStream.prototype._writeCentralDirectoryZip64 = function() {
  if (!this.isZip64()) {
    return;
  }

  // signature
  this.write(constants.SIG_ZIP64_EOCD);

  // size of the ZIP64 EOCD record
  this.write(zipUtil.getEightBytes((constants.SHORT * 2) + (constants.LONG * 2) + (8 * 4)));

  // version made by
  this.write(zipUtil.getShortBytes((ae.getPlatform() << 8) | constants.VERSION_MADEBY));

  // version needed to extract
  this.write(zipUtil.getShortBytes(ae.getVersionNeededToExtract()));

  // disk numbers
  this.write(constants.LONG_ZERO);
  this.write(constants.LONG_ZERO);

  // number of entries
  this.write(zipUtil.getEightBytes(this._entries.length));
  this.write(zipUtil.getEightBytes(this._entries.length));

  // length and location of CD
  this.write(zipUtil.getEightBytes(this._archive.centralLength));
  this.write(zipUtil.getEightBytes(this._archive.centralOffset));

  // extensible data sector
  // not implemented at this time

  // end of central directory locator
  this.write(costants.SIG_ZIP64_EOCD_LOC);

  // disk number holding the ZIP64 EOCD record
  this.write(constants.LONG_ZERO);

  // relative offset of the ZIP64 EOCD record
  this.write(zipUtil.getEightBytes(this._archive.centralOffset + this._archive.centralLength));

  // total number of disks
  this.write(this.getLongBytes(1));
};

ZipArchiveOutputStream.prototype._writeCentralFileHeader = function(ae) {
  var gpb = ae.getGeneralPurposeBit();
  var method = ae.getMethod();
  var offsets = ae._offsets;

  var extraBuf;
  var size = ae.getSize();
  var compressedSize = ae.getCompressedSize();

  if (ae.isZip64() || offsets.file > constants.ZIP64_MAGIC) {
    size = constants.ZIP64_MAGIC;
    compressedSize = constants.ZIP64_MAGIC;

    ae.setVersionNeededToExtract(constants.MIN_VERSION_ZIP64);

    extraBuf = new Buffer(28);
    extraBuf.write(zipUtil.getShortBytes(constants.ZIP64_EXTRA_ID));
    extraBuf.write(zipUtil.getShortBytes(24));
    extraBuf.write(zipUtil.getEightBytes(ae.getSize()));
    extraBuf.write(zipUtil.getEightBytes(ae.getCompressedSize()));
    extraBuf.write(zipUtil.getEightBytes(offsets.file));
    ae.setExtra(extraBuf);
  }

  // signature
  this.write(zipUtil.getLongBytes(constants.SIG_CFH));

  // version made by
  this.write(zipUtil.getShortBytes((ae.getPlatform() << 8) | constants.VERSION_MADEBY));

  // version to extract and general bit flag
  this.write(zipUtil.getShortBytes(ae.getVersionNeededToExtract()));
  this.write(gpb.encode());

  // compression method
  this.write(zipUtil.getShortBytes(method));

  // datetime
  this.write(zipUtil.getLongBytes(ae.getTimeDos()));

  // crc32 checksum
  this.write(zipUtil.getLongBytes(ae.getCrc()));

  // sizes
  this.write(zipUtil.getLongBytes(compressedSize));
  this.write(zipUtil.getLongBytes(size));

  var name = ae.getName();
  var comment = ae.getComment();
  var extra = ae.getCentralDirectoryExtra();

  if (gpb.usesUTF8ForNames()) {
    name = new Buffer(name);
    comment = new Buffer(comment);
  }

  // name length
  this.write(zipUtil.getShortBytes(name.length));

  // extra length
  this.write(zipUtil.getShortBytes(extra.length));

  // comments length
  this.write(zipUtil.getShortBytes(comment.length));

  // disk number start
  this.write(constants.SHORT_ZERO);

  // internal attributes
  this.write(zipUtil.getShortBytes(ae.getInternalAttributes()));

  // external attributes
  this.write(zipUtil.getLongBytes(ae.getExternalAttributes()));

  // relative offset of LFH
  if (offsets.file > constants.ZIP64_MAGIC) {
    this.write(zipUtil.getLongBytes(constants.ZIP64_MAGIC));
  } else {
    this.write(zipUtil.getLongBytes(offsets.file));
  }

  // name
  this.write(name);

  // extra
  this.write(extra);

  // comment
  this.write(comment);
};

ZipArchiveOutputStream.prototype._writeDataDescriptor = function(ae) {
  if (!ae.getGeneralPurposeBit().usesDataDescriptor()) {
    return;
  }

  // signature
  this.write(zipUtil.getLongBytes(constants.SIG_DD));

  // crc32 checksum
  this.write(zipUtil.getLongBytes(ae.getCrc()));

  // sizes
  if (ae.isZip64()) {
    this.write(zipUtil.getEightBytes(ae.getCompressedSize()));
    this.write(zipUtil.getEightBytes(ae.getSize()));
  } else {
    this.write(zipUtil.getLongBytes(ae.getCompressedSize()));
    this.write(zipUtil.getLongBytes(ae.getSize()));
  }
};

ZipArchiveOutputStream.prototype._writeLocalFileHeader = function(ae) {
  var gpb = ae.getGeneralPurposeBit();
  var method = ae.getMethod();
  var name = ae.getName();
  var extra = ae.getLocalFileDataExtra();

  if (gpb.usesUTF8ForNames()) {
    name = new Buffer(name);
  }

  ae._offsets.file = this.offset;

  // signature
  this.write(zipUtil.getLongBytes(constants.SIG_LFH));

  // version to extract and general bit flag
  this.write(zipUtil.getShortBytes(ae.getVersionNeededToExtract()));
  this.write(gpb.encode());

  // compression method
  this.write(zipUtil.getShortBytes(method));

  // datetime
  this.write(zipUtil.getLongBytes(ae.getTimeDos()));

  ae._offsets.data = this.offset;

  // crc32 checksum and sizes
  if (gpb.usesDataDescriptor()) {
    this.write(constants.LONG_ZERO);
    this.write(constants.LONG_ZERO);
    this.write(constants.LONG_ZERO);
  } else {
    this.write(zipUtil.getLongBytes(ae.getCrc()));
    this.write(zipUtil.getLongBytes(ae.getCompressedSize()));
    this.write(zipUtil.getLongBytes(ae.getSize()));
  }

  // name length
  this.write(zipUtil.getShortBytes(name.length));

  // extra length
  this.write(zipUtil.getShortBytes(extra.length));

  // name
  this.write(name);

  // extra
  this.write(extra);

  ae._offsets.contents = this.offset;
};

ZipArchiveOutputStream.prototype.getComment = function(comment) {
  return this._archive.comment !== null ? this._archive.comment : '';
};

ZipArchiveOutputStream.prototype.isZip64 = function() {
  return this._entries.length > constants.ZIP64_MAGIC_SHORT || this._archive.centralLength > constants.ZIP64_MAGIC || this._archive.centralOffset > constants.ZIP64_MAGIC;
};

ZipArchiveOutputStream.prototype.setComment = function(comment) {
  this._archive.comment = comment;
};<|endoftext|>


<commit_before>var Promise = require('bluebird'),
request = Promise.promisify(require('request')),
_ = require('lodash'),
movieDb = require('../config').vendor.movie_db,
rotten = require('../config').vendor.rotten_tomatoes,
models = require('../models'),
Movie = require('../models').movie,
Genre = require('../models').genre;

exports.getMovieInfo = function (movie_id) {

    // Check database first
    return Movie.find({
        where: {
            movie_id: movie_id
        }
    })
    .then(function (result) {
        // Found in db?
        if (!result) throw new Error('Not Found');

        return Promise.all([
            result.getGenres(),
            result.getActors(),
            result.getDirectors(),
            result.getReviews(),
            result.getSimilar()])
        .spread(function (genres, actors, directors, reviews, similar) {
            result = result.dataValues;
            result.genres = _.pluck(genres, 'type');
            result.cast = actors;
            result.directors = _.pluck(directors, 'name');
            result.reviews = reviews;
            result.similar_movies = similar;

            return result;
        });

    })
    .catch(function (ex) {
        // Get fresh info from api.
        return request(movieDb.formatUri(movieDb.uris.movie_info + encodeURIComponent(movie_id)) + '&append_to_response=credits,similar_movies')
        .spread(function (res, body) {
            if (res.statusCode !== 200)
                if (res.statusCode === 404) throw api.createError(404, "NotFound");
                else throw api.createError(500, "ApiError");
            return JSON.parse(body);
        })
        .then(function (result) {

            movie_id = result.id;

            // Extract Relevant Movie Info
            return {
                movie_id: result.id,
                imdb_id: result.imdb_id,
                title: result.title,
                poster_url: result.poster_path,
                synopsis: result.overview,
                release_date: new Date(Date.parse(result.release_date || 0)),
                runtime: result.runtime,
                year: new Date(Date.parse(result.release_date)).getFullYear(),
                studio: _.chain(result.production_companies).pluck('name').first().valueOf(),

                genres: _.pluck(result.genres, 'name'),

                cast: _.chain(result.credits.cast).map(function (item) {
                    return {
                        name: item.name,
                        character: item.character,
                        poster_url: item.profile_path
                    };
                }).first(10).valueOf(),

                directors: _.chain(result.credits.crew).where({ job: 'Director' }).pluck('name').valueOf(),
                producers: _.chain(result.credits.crew).where({ job: 'Producer'}).pluck('name').valueOf(),
                similar_movies: _.chain(result.similar_movies.results).map(function (item) {
                    return {
                        similar_movie_id: item.id,
                        title: item.title,
                        poster_url: item.poster_path
                    };
                }).valueOf(),
                reviews: []
            };
        })
            // Get info from Rotten Tomatoes
        .then(function (movie_info) {
                console.log(movie_info);
            return request(rotten.formatUri('movie_alias.json?type=imdb&id=' + movie_info.imdb_id.replace('tt', '')))
            .spread(function (res, body) {
                    console.log(res.statusCode);
                if (res.statusCode !== 200) throw api.createError(500, "ApiError");
                return JSON.parse(body);
            })
                // Extract Rotten Tomatoes Info
            .then(function (result) {
                    console.log(result);
                movie_info = _.extend(movie_info, {
                    mpaa_rating: result.mpaa_rating,
                    critic_score: result.ratings.critics_score,
                    audience_score: result.ratings.audience_score
                });

                return result.id;
            })
            .then(function (movie_rotten_id) {
                return request(rotten.formatUri('movies/' + movie_rotten_id + '/reviews.json'))
                .spread(function (res, body) {
                    if (res.statusCode !== 200) throw api.createError(500, "ApiError");
                    return JSON.parse(body);
                })
                .then(function (result) {
                    movie_info.reviews = _.chain(result.reviews).map(function (item) {
                        return {
                            critic_name: item.critic,
                            date: new Date(Date.parse(item.date)),
                            fresh: item.freshness === 'fresh',
                            quote: item.quote
                        }
                    }).valueOf();

                    return movie_info;
                });
            })
            .catch(function (err) {
                console.log(err);
                return movie_info;
            });
        })
        .then(function (movie_info) {

            // Save Movie to DB
            Movie.create(movie_info)
                // Save Genres
            .then(function (movie) {
                return Promise.all(_.map(movie_info.genres, function (genre) {
                    return Genre.create({
                        movie_id: movie_info.movie_id,
                        type: genre
                    });
                }))
            })
                // Save Cast
            .then(function () {
                return Promise.all(_.map(movie_info.cast, function (actor) {
                    return models.actor.create(_.extend(actor, { movie_id: movie_info.movie_id }));
                }));
            })
                // Save Directors
            .then(function () {
                return Promise.all(_.map(movie_info.directors, function (director) {
                    return models.director.create({ movie_id: movie_info.movie_id, name: director });
                }))
            })
                // Save Similar Movies
            .then(function () {
                return Promise.all(_.map(movie_info.similar_movies, function (movie) {
                    return models.similar_movie.create(_.extend(movie, { movie_id: movie_info.movie_id }));
                }));
            })
                // Save Reviews
            .then(function () {
                return Promise.all(_.map(movie_info.reviews, function (review) {
                    return models.review.create(_.extend(review, { movie_id: movie_info.movie_id }));
                }));
            })
            .catch(function (err) {
                // TODO: silent error?
                console.log("Error Saving Movie");
                console.log(err);
            });

            return _.omit(movie_info, 'imdb_id');
        });
    });
};

exports.getPopularMovies = function () {
    return request(movieDb.formatUri(movieDb.uris.popular))
    .spread(function (res, body) {
        if (res.statusCode !== 200) throw api.createError(500, "ApiError");
        var result = JSON.parse(body);
        return result.results;
    })
};
<commit_msg>removed debug log lines<commit_after>var Promise = require('bluebird'),
request = Promise.promisify(require('request')),
_ = require('lodash'),
movieDb = require('../config').vendor.movie_db,
rotten = require('../config').vendor.rotten_tomatoes,
models = require('../models'),
Movie = require('../models').movie,
Genre = require('../models').genre;

exports.getMovieInfo = function (movie_id) {

    // Check database first
    return Movie.find({
        where: {
            movie_id: movie_id
        }
    })
    .then(function (result) {
        // Found in db?
        if (!result) throw new Error('Not Found');

        return Promise.all([
            result.getGenres(),
            result.getActors(),
            result.getDirectors(),
            result.getReviews(),
            result.getSimilar()])
        .spread(function (genres, actors, directors, reviews, similar) {
            result = result.dataValues;
            result.genres = _.pluck(genres, 'type');
            result.cast = actors;
            result.directors = _.pluck(directors, 'name');
            result.reviews = reviews;
            result.similar_movies = similar;

            return result;
        });

    })
    .catch(function (ex) {
        // Get fresh info from api.
        return request(movieDb.formatUri(movieDb.uris.movie_info + encodeURIComponent(movie_id)) + '&append_to_response=credits,similar_movies')
        .spread(function (res, body) {
            if (res.statusCode !== 200)
                if (res.statusCode === 404) throw api.createError(404, "NotFound");
                else throw api.createError(500, "ApiError");
            return JSON.parse(body);
        })
        .then(function (result) {

            movie_id = result.id;

            // Extract Relevant Movie Info
            return {
                movie_id: result.id,
                imdb_id: result.imdb_id,
                title: result.title,
                poster_url: result.poster_path,
                synopsis: result.overview,
                release_date: new Date(Date.parse(result.release_date || 0)),
                runtime: result.runtime,
                year: new Date(Date.parse(result.release_date)).getFullYear(),
                studio: _.chain(result.production_companies).pluck('name').first().valueOf(),

                genres: _.pluck(result.genres, 'name'),

                cast: _.chain(result.credits.cast).map(function (item) {
                    return {
                        name: item.name,
                        character: item.character,
                        poster_url: item.profile_path
                    };
                }).first(10).valueOf(),

                directors: _.chain(result.credits.crew).where({ job: 'Director' }).pluck('name').valueOf(),
                producers: _.chain(result.credits.crew).where({ job: 'Producer'}).pluck('name').valueOf(),
                similar_movies: _.chain(result.similar_movies.results).map(function (item) {
                    return {
                        similar_movie_id: item.id,
                        title: item.title,
                        poster_url: item.poster_path
                    };
                }).valueOf(),
                reviews: []
            };
        })
            // Get info from Rotten Tomatoes
        .then(function (movie_info) {
            return request(rotten.formatUri('movie_alias.json?type=imdb&id=' + movie_info.imdb_id.replace('tt', '')))
            .spread(function (res, body) {
                if (res.statusCode !== 200) throw api.createError(500, "ApiError");
                return JSON.parse(body);
            })
                // Extract Rotten Tomatoes Info
            .then(function (result) {
                movie_info = _.extend(movie_info, {
                    mpaa_rating: result.mpaa_rating,
                    critic_score: result.ratings.critics_score,
                    audience_score: result.ratings.audience_score
                });

                return result.id;
            })
            .then(function (movie_rotten_id) {
                return request(rotten.formatUri('movies/' + movie_rotten_id + '/reviews.json'))
                .spread(function (res, body) {
                    if (res.statusCode !== 200) throw api.createError(500, "ApiError");
                    return JSON.parse(body);
                })
                .then(function (result) {
                    movie_info.reviews = _.chain(result.reviews).map(function (item) {
                        return {
                            critic_name: item.critic,
                            date: new Date(Date.parse(item.date)),
                            fresh: item.freshness === 'fresh',
                            quote: item.quote
                        }
                    }).valueOf();

                    return movie_info;
                });
            })
            .catch(function (err) {
                console.log(err);
                return movie_info;
            });
        })
        .then(function (movie_info) {

            // Save Movie to DB
            Movie.create(movie_info)
                // Save Genres
            .then(function (movie) {
                return Promise.all(_.map(movie_info.genres, function (genre) {
                    return Genre.create({
                        movie_id: movie_info.movie_id,
                        type: genre
                    });
                }))
            })
                // Save Cast
            .then(function () {
                return Promise.all(_.map(movie_info.cast, function (actor) {
                    return models.actor.create(_.extend(actor, { movie_id: movie_info.movie_id }));
                }));
            })
                // Save Directors
            .then(function () {
                return Promise.all(_.map(movie_info.directors, function (director) {
                    return models.director.create({ movie_id: movie_info.movie_id, name: director });
                }))
            })
                // Save Similar Movies
            .then(function () {
                return Promise.all(_.map(movie_info.similar_movies, function (movie) {
                    return models.similar_movie.create(_.extend(movie, { movie_id: movie_info.movie_id }));
                }));
            })
                // Save Reviews
            .then(function () {
                return Promise.all(_.map(movie_info.reviews, function (review) {
                    return models.review.create(_.extend(review, { movie_id: movie_info.movie_id }));
                }));
            })
            .catch(function (err) {
                // TODO: silent error?
                console.log("Error Saving Movie");
                console.log(err);
            });

            return _.omit(movie_info, 'imdb_id');
        });
    });
};

exports.getPopularMovies = function () {
    return request(movieDb.formatUri(movieDb.uris.popular))
    .spread(function (res, body) {
        if (res.statusCode !== 200) throw api.createError(500, "ApiError");
        var result = JSON.parse(body);
        return result.results;
    })
};
<|endoftext|>


<commit_before>var
    $ = jQuery;

(function ($module) {
    "use strict";

    var setButtonsAction = function () {

        var
            btnClose = $("a.jtime-ui-modal-btn-close"),
            modal = $module.modal(),
            time;

        $(document).keydown(function (e) {
            if (e.keyCode === 27) {
                modal.minimize();
            }
        });

        btnClose.click(function (e) {
            modal.close();
        });

    };

    $module.modal = function () {
        return {
            create: function (params) {
                var
                    body = $("body"),
                    wrapperModal,
                    modalMask,
                    modal,
                    header,
                    btnClose,
                    content;

                if ($(".jtime-ui-wrapper-modal").length < 1) {
                    wrapperModal = $("

")
                        .addClass("jtime-ui-wrapper-modal");
                    modalMask = $("

")
                        .addClass("jtime-ui-modal-mask basicss-fixed basicss-transparent");
                    modal = $("

").addClass("jtime-ui-modal");
                    header = $("

").addClass("jtime-ui-modal-header");
                    btnClose = $("")
                        .addClass("jtime-ui-modal-btn-close button");
                    content = $("

").addClass("jtime-ui-modal-content");

                    body.append(wrapperModal);

                    wrapperModal
                        .append(modalMask)
                        .append(modal);

                    modal
                        .append(header)
                        .css({
                            "max-height": $(document).height(),
                            "max-width": $(window).width()
                        });

                    header.append(btnClose);
                    modal.append(content);

                    setButtonsAction();
                } else {
                    wrapperModal = $(".jtime-ui-wrapper-modal");
                    modal = wrapperModal.find(".jtime-ui-modal");
                    modalMask = wrapperModal.find(".jtime-ui-modal-mask");

                    wrapperModal.show();
                    modal.show();
                }

                // todas as linhas de um bloco function são executadas
                // numa porrada só executa somente quando estiver visível
                if (wrapperModal.is(":visible")) {
                    modalMask
                        .replaceToggleClass("basicss-transparent",
                                            "basicss-opacity-transition");
                }

                modal.centralizeOn($(document));

                if (params.load) {
                    params.load(modal);
                }

            },

            minimize: function () {
                var
                    wrapperModal = $(".jtime-ui-wrapper-modal"),
                    modalMask = wrapperModal.find(".jtime-ui-modal-mask"),
                    time = 0;

                $(".jtime-ui-modal").hide();

                modalMask.replaceToggleClass("basicss-transparent", "basicss-opacity-transition");

                time = parseFloat(
                    modalMask.css("transition-duration")
                ) * 1000;
                setTimeout(function () {
                    $(".jtime-ui-wrapper-modal").hide();
                }, time);
            },

            close: function () {
                var
                    wrapperModal = $(".jtime-ui-wrapper-modal"),
                    modalMask = wrapperModal.find(".jtime-ui-modal-mask"),
                    time = 0;

                $(".jtime-ui-modal").hide();

                modalMask.replaceToggleClass("basicss-transparent", "basicss-opacity-transition");

                time = parseFloat(
                    modalMask.css("transition-duration")
                ) * 1000;
                setTimeout(function () {
                    $(".jtime-ui-wrapper-modal").remove();
                }, time);
            }
        }

    };

})(jTime.ui);

//var maximizeModal = function () {
    //jtime-ui-wrapper-modal e modal ficam hide
    //trocar transparencia de wrapperModal
//};

// minimize = ->
  // atribuir classe
  // colocar left: 0; bottom: 0 e mostrar só o header

// afterLoad = (url, execute)->
//   $(".modal").load url, ->
//     $(this).find(".jtime-ui-modal-content").load url, ->
//       execute.each
          // ...
//<commit_msg>ajusta centralização de modal<commit_after>var
    $ = jQuery;

(function ($module) {
    "use strict";

    var setButtonsAction = function () {

        var
            btnClose = $("a.jtime-ui-modal-btn-close"),
            modal = $module.modal(),
            time;

        $(document).keydown(function (e) {
            if (e.keyCode === 27) {
                modal.minimize();
            }
        });

        btnClose.click(function (e) {
            modal.close();
        });

    };

    $module.modal = function () {
        return {
            create: function (args) {
                var
                    body = $("body"),
                    wrapperModal,
                    modalMask,
                    modal,
                    header,
                    btnClose,
                    content;

                if ($(".jtime-ui-wrapper-modal").length < 1) {
                    wrapperModal = $("

")
                        .addClass("jtime-ui-wrapper-modal");
                    modalMask = $("

")
                        .addClass("jtime-ui-modal-mask basicss-fixed basicss-transparent");
                    // talvez será interessando deixá-lo invisible
                    modal = $("

").addClass("jtime-ui-modal basicss-hidden");
                    header = $("

").addClass("jtime-ui-modal-header");
                    btnClose = $("")
                        .addClass("jtime-ui-modal-btn-close button");
                    content = $("

").addClass("jtime-ui-modal-content");

                    body.append(wrapperModal);

                    wrapperModal
                        .append(modalMask)
                        .append(modal);

                    modal
                        .append(header)
                        .css({
                            "max-height": $(document).height(),
                            "max-width": $(window).width()
                        });

                    header.append(btnClose);
                    modal.append(content);

                    setButtonsAction();
                } else {
                    wrapperModal = $(".jtime-ui-wrapper-modal");
                    modal = wrapperModal.find(".jtime-ui-modal");
                    modalMask = wrapperModal.find(".jtime-ui-modal-mask");

                    wrapperModal.show();
                    modal.show();
                }

                // todas as linhas de um bloco function são executadas
                // numa porrada só executa somente quando estiver visível
                if (wrapperModal.is(":visible")) {
                    modalMask
                        .replaceToggleClass("basicss-transparent",
                                            "basicss-opacity-transition");
                }

                // callback
                if (args.load) {
                    args.load(modal);
                }

                content.get(0).addEventListener("DOMNodeInserted",
                    function (e) {
                        modal.centralizeOn($(document));
                        modal.show();
                    },
                false);

            },

            minimize: function () {
                var
                    wrapperModal = $(".jtime-ui-wrapper-modal"),
                    modalMask = wrapperModal.find(".jtime-ui-modal-mask"),
                    time = 0;

                $(".jtime-ui-modal").hide();

                modalMask.replaceToggleClass("basicss-transparent", "basicss-opacity-transition");

                time = parseFloat(
                    modalMask.css("transition-duration")
                ) * 1000;
                setTimeout(function () {
                    $(".jtime-ui-wrapper-modal").hide();
                }, time);
            },

            close: function () {
                var
                    wrapperModal = $(".jtime-ui-wrapper-modal"),
                    modalMask = wrapperModal.find(".jtime-ui-modal-mask"),
                    time = 0;

                $(".jtime-ui-modal").hide();

                modalMask.replaceToggleClass("basicss-transparent", "basicss-opacity-transition");

                time = parseFloat(
                    modalMask.css("transition-duration")
                ) * 1000;
                setTimeout(function () {
                    $(".jtime-ui-wrapper-modal").remove();
                }, time);
            }
        }

    };

})(jTime.ui);

//var maximizeModal = function () {
    //jtime-ui-wrapper-modal e modal ficam hide
    //trocar transparencia de wrapperModal
//};

// minimize = ->
  // atribuir classe
  // colocar left: 0; bottom: 0 e mostrar só o header

// afterLoad = (url, execute)->
//   $(".modal").load url, ->
//     $(this).find(".jtime-ui-modal-content").load url, ->
//       execute.each
          // ...
//<|endoftext|>


<commit_before>/**
 * Created by chiamakanwosu on 06/01/2017.
 */
const books = require('../books.json');
const book2 = require('../book2.json');
const emptyBook = require('../emptyBook.json');
const invalidBook = require('../invalidBook.json');
(() => {
  describe('invertedIndex', ()=> {
    const index = new InvertedIndex();
    const emptyJson = [];
    const invalidString = 'I am a girl';
    describe('Read book data', ()=> {
      it('should read the JSON file and assert that it is not empty says', () => {
        expect(index.isValidJson(emptyJson)).toBe(false);
      });

      it('Ensures the file content is actually a valid JSON Array', ()=>{
        expect(index.isValidJson(invalidString)).toBe(false);
      })

    });
    describe('Populate Index', () => {
      index.createIndex('book.json', books);
      it('should verify that the index is created', () => {
        expect(index.indices.length).toBeGreaterThan(0);
      });
      it('should verify the index maps the string keys to the correct' +
        ' objects in the JSON array', () => {
        index.searchIndex('Alice, elf');
        expect(index.temp_search).toEqual([0, 1]);
      });
      it('Should verify that multiple index could be built', () => {
        index.createIndex('book2.json', book2);
        expect(index.indices.length).toEqual(2);
      });
    });
    describe('Search index', () => {
      it('should ensure search does not take too long to execute', () => {
        const runtimeThreshold = 1000;
        const currentMillisecond =  new Date().getMilliseconds();
        index.searchIndex('Alice', ['Fellowship', ['dwarf'], 'in']);
        const finalMilliseconds =  new Date().getMilliseconds();
        const timeDifference = finalMilliseconds - currentMillisecond;
        expect(timeDifference).toBeLessThan(runtimeThreshold);
      });

      it('should ensure searchIndex can handle an array of search terms', () => {
        const searchTerms = ['Alice', 'ring'];
        index.searchIndex(searchTerms);
        expect(index.temp_search).toEqual([0, 1]);
      });

      it('should be able to search a specific index', () => {
        index.searchIndex('pelican', 1);
        expect(index.temp_search).toEqual([2]);
      });
    });
  });
})();
<commit_msg>delete jasmine/build/<commit_after><|endoftext|>