<commit_before>
var assert     = require('assert');
var express    = require('express');
var bodyParser = require('body-parser');
var request    = require('supertest');
var ht         = require('hudson-taylor');
var s          = require('ht-schema');

var hte = require('../');

describe("HT Express", function() {

  it("should return response from method", function(done) {

    var client = getClientWithServices({ s1: { m1: function(data, callback) {
      return callback(null, 'hello world');
    } } });

    var app = express();
    app.get('/', hte(client, "s1", "m1"));

    request(app)
      .get('/')
      .expect(200)
      .expect('hello world')
      .end(done);

  });

  it("should return correct json headers if response is an object", function(done) {

    var client = getClientWithServices({ s1: { m1: function(data, callback) {
      return callback(null, data);
    } } });

    var app = express();
    app.use(bodyParser.json());
    app.get('/', hte(client, "s1", "m1"));

    var data = {
      hello: "world"
    };

    request(app)
      .get('/')
      .expect(200)
      .expect("Content-Type", "application/json; charset=utf-8")
      .send(data)
      .end(function(err, res) {
        assert.ifError(err);
        assert.deepEqual(res.body, data);
        done();
    });

  });

  it("should return custom code if statusCode is set in response", function(done) {

     var client = getClientWithServices({ s1: { m1: function(data, callback) {
      return callback(null, {
        statusCode: 201,
        something: 'else'
      });
    } } });

    var app = express();
    app.post('/', hte(client, "s1", "m1"));

    request(app)
      .post('/')
      .expect(201)
      .expect({ something: 'else' })
      .end(done);

  });

  it("should only pull data from body by default", function(done) {

    var client = getClientWithServices({ s1: { m1: function(data, callback) {
      assert.deepEqual(data, {
        hello: 'world'
      });
      done();
    } } });

    var app = express();
    app.use(bodyParser.json());
    app.post('/', hte(client, "s1", "m1"));

    request(app)
      .post('/')
      .query({
        not: "used"
      })
      .send({
        hello: "world"
      })
      .expect(200)
      .end();

  });

  it("should pull data from other places if specified", function(done) {

    var client = getClientWithServices({ s1: { m1: function(data, callback) {
      assert.deepEqual(data, {
        hello: 'world',
        is:    'used'
      });
      done();
    } } });

    var app = express();
    app.use(bodyParser.json());
    app.post('/', hte(client, "s1", "m1", [ 'body', 'query' ]));

    request(app)
      .post('/')
      .query({
        is: "used"
      })
      .send({
        hello: "world"
      })
      .expect(200)
      .end();

  });

  it("should return 400 if there was a validation error", function(done) {

    var client = getClientWithServices({ s1: { m1: {
      fn: function(data, callback) {
        return callback();
      },
      schema: s.Number()
    } } });

    var app = express();
    app.get('/', hte(client, "s1", "m1"));

    request(app)
      .get('/')
      .expect(400)
      .end(function(err, res) {
        assert.ifError(err);
        assert.equal(res.text, 'required Number, received object');
        done();
    });

  });

  it("should return 500 if statusCode is not set in error", function(done) {

    var client = getClientWithServices({ s1: { m1: function(data, callback) {
      return callback({
        something: 'else'
      });
    } } });

    var app = express();
    app.post('/', hte(client, "s1", "m1"));

    request(app)
      .post('/')
      .expect(500)
      .end(done);

  });

  it("should return custom code if statusCode is set in error", function(done) {

    var client = getClientWithServices({ s1: { m1: function(data, callback) {
      return callback({
        statusCode: 501,
        something: 'else'
      });
    } } });

    var app = express();
    app.post('/', hte(client, "s1", "m1"));

    request(app)
      .post('/')
      .expect(501)
      .end(done);

  });

  it("should return 500 if error is not an object", function(done) {

    var client = getClientWithServices({ s1: { m1: function(data, callback) {
      return callback("error");
    } } });

    var app = express();
    app.get('/', hte(client, "s1", "m1"));

    request(app)
      .get('/')
      .expect(500)
      .end(function(err, res) {
        assert.ifError(err);
        assert.equal(res.text, "error");
        done();
    });

  });

});

function getClientWithServices(services) {
  /*
    services should look something like:
    {
      service1: {
        method1: function(data, callback) {

        },
        method2: {
          fn: function(data, callback) {},
          schema: s.String()
        }
      },
      service2: ..etc
    }
  */
  var client = new ht.Client();
  for(var service in services) {
    var t = new ht.Transports.Local();
    var s = new ht.Service(t);
    for(var method in services[service]) {
      var p = services[service][method];
      if(typeof p === 'function') p = { fn: p };
      s.on(method, p.schema, p.fn);
    }
    client.add(service, t);
  }
  return client;
}
<commit_msg>data merge test<commit_after>
var assert     = require('assert');
var express    = require('express');
var bodyParser = require('body-parser');
var request    = require('supertest');
var ht         = require('hudson-taylor');
var s          = require('ht-schema');

var hte = require('../');

describe("HT Express", function() {

  it("should return response from method", function(done) {

    var client = getClientWithServices({ s1: { m1: function(data, callback) {
      return callback(null, 'hello world');
    } } });

    var app = express();
    app.get('/', hte(client, "s1", "m1"));

    request(app)
      .get('/')
      .expect(200)
      .expect('hello world')
      .end(done);

  });

  it("should return correct json headers if response is an object", function(done) {

    var client = getClientWithServices({ s1: { m1: function(data, callback) {
      return callback(null, data);
    } } });

    var app = express();
    app.use(bodyParser.json());
    app.get('/', hte(client, "s1", "m1"));

    var data = {
      hello: "world"
    };

    request(app)
      .get('/')
      .expect(200)
      .expect("Content-Type", "application/json; charset=utf-8")
      .send(data)
      .end(function(err, res) {
        assert.ifError(err);
        assert.deepEqual(res.body, data);
        done();
    });

  });

  it("should return custom code if statusCode is set in response", function(done) {

     var client = getClientWithServices({ s1: { m1: function(data, callback) {
      return callback(null, {
        statusCode: 201,
        something: 'else'
      });
    } } });

    var app = express();
    app.post('/', hte(client, "s1", "m1"));

    request(app)
      .post('/')
      .expect(201)
      .expect({ something: 'else' })
      .end(done);

  });

  it("should only pull data from body by default", function(done) {

    var client = getClientWithServices({ s1: { m1: function(data, callback) {
      assert.deepEqual(data, {
        hello: 'world'
      });
      done();
    } } });

    var app = express();
    app.use(bodyParser.json());
    app.post('/', hte(client, "s1", "m1"));

    request(app)
      .post('/')
      .query({
        not: "used"
      })
      .send({
        hello: "world"
      })
      .expect(200)
      .end();

  });

  it("should pull data from other places if specified", function(done) {

    var client = getClientWithServices({ s1: { m1: function(data, callback) {
      assert.deepEqual(data, {
        hello: 'world',
        is:    'used'
      });
      done();
    } } });

    var app = express();
    app.use(bodyParser.json());
    app.post('/', hte(client, "s1", "m1", [ 'body', 'query' ]));

    request(app)
      .post('/')
      .query({
        is: "used"
      })
      .send({
        hello: "world"
      })
      .expect(200)
      .end();

  });

  it("should merge data properly", function(done) {

    var client = getClientWithServices({ s1: { m1: function(data, callback) {
      assert.deepEqual(data, {
        one:   1,
        two:   22,
        three: 333
      });
      done();
    } } });

    var app = express();
    app.use(bodyParser.json());
    app.post('/:three', hte(client, "s1", "m1", [ 'body', 'query', 'params' ]));

    request(app)
      .post('/333')
      .query({
        two:   22,
        three: 33
      })
      .send({
        one:   1,
        two:   2,
        three: 3
      })
      .expect(200)
      .end();

  });

  it("should return 400 if there was a validation error", function(done) {

    var client = getClientWithServices({ s1: { m1: {
      fn: function(data, callback) {
        return callback();
      },
      schema: s.Number()
    } } });

    var app = express();
    app.get('/', hte(client, "s1", "m1"));

    request(app)
      .get('/')
      .expect(400)
      .end(function(err, res) {
        assert.ifError(err);
        assert.equal(res.text, 'required Number, received object');
        done();
    });

  });

  it("should return 500 if statusCode is not set in error", function(done) {

    var client = getClientWithServices({ s1: { m1: function(data, callback) {
      return callback({
        something: 'else'
      });
    } } });

    var app = express();
    app.post('/', hte(client, "s1", "m1"));

    request(app)
      .post('/')
      .expect(500)
      .end(done);

  });

  it("should return custom code if statusCode is set in error", function(done) {

    var client = getClientWithServices({ s1: { m1: function(data, callback) {
      return callback({
        statusCode: 501,
        something: 'else'
      });
    } } });

    var app = express();
    app.post('/', hte(client, "s1", "m1"));

    request(app)
      .post('/')
      .expect(501)
      .end(done);

  });

  it("should return 500 if error is not an object", function(done) {

    var client = getClientWithServices({ s1: { m1: function(data, callback) {
      return callback("error");
    } } });

    var app = express();
    app.get('/', hte(client, "s1", "m1"));

    request(app)
      .get('/')
      .expect(500)
      .end(function(err, res) {
        assert.ifError(err);
        assert.equal(res.text, "error");
        done();
    });

  });

});

function getClientWithServices(services) {
  /*
    services should look something like:
    {
      service1: {
        method1: function(data, callback) {

        },
        method2: {
          fn: function(data, callback) {},
          schema: s.String()
        }
      },
      service2: ..etc
    }
  */
  var client = new ht.Client();
  for(var service in services) {
    var t = new ht.Transports.Local();
    var s = new ht.Service(t);
    for(var method in services[service]) {
      var p = services[service][method];
      if(typeof p === 'function') p = { fn: p };
      s.on(method, p.schema, p.fn);
    }
    client.add(service, t);
  }
  return client;
}
<|endoftext|>


<commit_before>/**
 * 节点组相关的 API
 * @author heroic
 */

/**
 * Module dependencies
 */
var async = require('async'),
  _ = require('lodash'),
  models = require('../models'),
  Section = models.Section;

/**
 * 获取节点组列表
 * @param  {Object}   options
 *  - query          optional   查询条件，默认查询全部
 *  - notPaged       optional   不分页则传入 true，默认 false
 *  - pageIndex      optional   当前页数，默认 1
 *  - pageSize       optional   返回的记录数，默认 20
 *  - sort  {Object} optional   排序规则，默认按创建时间倒序
 * @param  {Function} callback
 *  - err
 *  - results
 *    - totalCount    符合查询条件节点组记录总数
 *    - sections      节点组列表
 */
exports.query = function(options, callback) {
  options = options || {};
  var conditions = options.query || options.conditions || {};

  Section.paginate(conditions, options, function(err, count, sections) {
    if (err) {
      return callback(err);
    }

    // `notPaged === true` 的情况
    if (typeof sections === 'undefined') {
      return callback(null, { sections: count });
    }

    callback(null, {
      totalCount: count,
      sections: sections
    });
  });
};<commit_msg>增加节点组 API<commit_after>/**
 * 节点组相关的 API
 * @author heroic
 */

/**
 * Module dependencies
 */
var async = require('async'),
  _ = require('lodash'),
  models = require('../models'),
  Section = models.Section;

/**
 * 获取节点组列表
 * @param  {Object}   options
 *  - query          optional   查询条件，默认查询全部
 *  - notPaged       optional   不分页则传入 true，默认 false
 *  - pageIndex      optional   当前页数，默认 1
 *  - pageSize       optional   返回的记录数，默认 20
 *  - sort  {Object} optional   排序规则，默认按创建时间倒序
 * @param  {Function} callback
 *  - err
 *  - results
 *    - totalCount    符合查询条件节点组记录总数
 *    - sections      节点组列表
 */
exports.query = function(options, callback) {
  options = options || {};
  var conditions = options.query || options.conditions || {};

  Section.paginate(conditions, options, function(err, count, sections) {
    if (err) {
      return callback(err);
    }

    // `notPaged === true` 的情况
    if (typeof sections === 'undefined') {
      return callback(null, { sections: count });
    }

    callback(null, {
      totalCount: count,
      sections: sections
    });
  });
};

/**
 * 根据条件获取单个节点组
 * @param  {Object}   conditions 查询条件
 * @param  {Function} callback
 *  - err
 *  - section
 */
exports.get = function(conditions, callback) {
  Section.findOne(conditions, callback);
};

/**
 * 创建节点组
 * @param  {Object}   sectionData  节点组对象
 * @param  {Function} callback
 *  - err
 *  - section
 */
exports.create = function(sectionData, callback) {
  Section.create(sectionData, callback);
};

/**
 * 根据主键编辑节点组
 * @param  {Object}   sectionData  节点组对象
 *  - _id|id   required    节点组 id
 * @param  {Function} callback
 *  - err
 *  - section
 */
exports.edit = function(sectionData, callback) {
  var id = sectionData.id || sectionData._id;
  sectionData = _.omit(sectionData, '_id');

  async.waterfall([
    function getSection(next) {
      Section.findById(id, function(err, section) {
        next(err, section);
      });
    },
    function updateSection(section, next) {
      if (!section) {
        return next(null, section);
      }
      _.extend(section, sectionData);
      section.save(function(err, section) {
        next(err, section);
      });
    }
  ], callback);
};

/**
 * 根据主键删除节点组
 * @param  {String}   id       节点组 id
 * @param  {Function} callback
 *  - err
 *  - section
 */
exports.remove = function(id, callback) {
  async.waterfall([
    function getSection(next) {
      Section.findById(id, function(err, section) {
        next(err, section);
      });
    },
    function removeSection(section, next) {
      if (!section) {
        return next(null, section);
      }
      section.remove(function(err, section) {
        next(err, section);
      });
    }
  ], callback);
};<|endoftext|>


<commit_before>"use strict";

const Task = require('./Task'),
    gulp = require('gulp'),
    path = require('path'),
    watchify = require('watchify'),
    browserify = require('browserify'),
    babelify = require('babelify'),
    source = require('vinyl-source-stream'),
    gulpif = require('gulp-if'),
    streamify = require('gulp-streamify'),
    uglify = require('gulp-uglify'),
    header = require('gulp-header'),
    transform = require('vinyl-transform'),
    exorcist = require('exorcist'),
    tsify = require('tsify'),
    refresh = require('gulp-livereload');

class JSTask extends Task {

    constructor(buildHelper) {
        super(buildHelper);
        this.command = "js";
        this.availableToModule = false;
    }

    action() {
        var options = this._buildHelper.options,
            target = this._buildHelper.currentTarget,
            buildHelper = this._buildHelper;

        var browserifyOptions = {
                entries: [path.resolve(options.targets, target, 'bootstrapper.' + buildHelper.options.typescript ? 'ts' : 'js')],
                basedir: this._buildHelper.CWD,
                debug: !this._buildHelper.isRelease(),
                cache: {},
                packageCache: {},
                fullPaths: true
            },
            bundleStream = this._buildHelper.isWatching() ? watchify(browserify(browserifyOptions), {
                poll: /^win/.test(process.platform)
            }) : browserify(browserifyOptions);

        if (options.typescript)
            bundleStream = bundleStream.plugin(tsify, options.typescript);
        if (options.babel)
            bundleStream = bundleStream.transform(babelify, options.babel);

        if (this._buildHelper.isWatching())
            bundleStream.on('update', rebundle);

        function rebundle() {
            return bundleStream.bundle()
                .on('error', function (err) {
                    console.error(err.message);
                    this.emit("end");
                })
                .pipe(source(buildHelper.BUNDLE_FILENAME + '.js'))
                .pipe(gulpif(buildHelper.isRelease(), streamify(uglify())))
                .pipe(gulpif(buildHelper.isRelease(), header('/*\n\n${name} : ${version}\n\n*/\n\n', {
                    name: options.projectPackage.name,
                    version: options.projectPackage.version
                })))
                .pipe(gulpif(!buildHelper.isRelease(), transform(function () {
                    return exorcist(buildHelper.getTemporaryDirectory() + 'js/' + buildHelper.BUNDLE_FILENAME + '.map.js');
                })))
                .pipe(gulp.dest(buildHelper.getTemporaryDirectory() + 'js'))
                .pipe(refresh({
                    start: buildHelper.isWatching(),
                    port: buildHelper.options.liveReloadPort
                }));
        }

        return rebundle();
    }
}

module.exports = JSTask;<commit_msg>Fix bootstrapper path resolve<commit_after>"use strict";

const Task = require('./Task'),
    gulp = require('gulp'),
    path = require('path'),
    watchify = require('watchify'),
    browserify = require('browserify'),
    babelify = require('babelify'),
    source = require('vinyl-source-stream'),
    gulpif = require('gulp-if'),
    streamify = require('gulp-streamify'),
    uglify = require('gulp-uglify'),
    header = require('gulp-header'),
    transform = require('vinyl-transform'),
    exorcist = require('exorcist'),
    tsify = require('tsify'),
    refresh = require('gulp-livereload');

class JSTask extends Task {

    constructor(buildHelper) {
        super(buildHelper);
        this.command = "js";
        this.availableToModule = false;
    }

    action() {
        var options = this._buildHelper.options,
            target = this._buildHelper.currentTarget,
            buildHelper = this._buildHelper;

        var browserifyOptions = {
                entries: [path.resolve(options.targets, target, 'bootstrapper.' + (buildHelper.options.typescript ? 'ts' : 'js'))],
                basedir: this._buildHelper.CWD,
                debug: !this._buildHelper.isRelease(),
                cache: {},
                packageCache: {},
                fullPaths: true
            },
            bundleStream = this._buildHelper.isWatching() ? watchify(browserify(browserifyOptions), {
                poll: /^win/.test(process.platform)
            }) : browserify(browserifyOptions);

        if (options.typescript)
            bundleStream = bundleStream.plugin(tsify, options.typescript);
        if (options.babel)
            bundleStream = bundleStream.transform(babelify, options.babel);

        if (this._buildHelper.isWatching())
            bundleStream.on('update', rebundle);

        function rebundle() {
            return bundleStream.bundle()
                .on('error', function (err) {
                    console.error(err.message);
                    this.emit("end");
                })
                .pipe(source(buildHelper.BUNDLE_FILENAME + '.js'))
                .pipe(gulpif(buildHelper.isRelease(), streamify(uglify())))
                .pipe(gulpif(buildHelper.isRelease(), header('/*\n\n${name} : ${version}\n\n*/\n\n', {
                    name: options.projectPackage.name,
                    version: options.projectPackage.version
                })))
                .pipe(gulpif(!buildHelper.isRelease(), transform(function () {
                    return exorcist(buildHelper.getTemporaryDirectory() + 'js/' + buildHelper.BUNDLE_FILENAME + '.map.js');
                })))
                .pipe(gulp.dest(buildHelper.getTemporaryDirectory() + 'js'))
                .pipe(refresh({
                    start: buildHelper.isWatching(),
                    port: buildHelper.options.liveReloadPort
                }));
        }

        return rebundle();
    }
}

module.exports = JSTask;<|endoftext|>


<commit_before>define(['apiclientcore', 'localassetmanager', 'events'], function (apiclientcorefactory, localassetmanager, events) {
    'use strict';

    var localPrefix = 'local:';
    var localViewPrefix = 'localview:';

    /**
     * Creates a new api client instance
     * @param {String} serverAddress
     * @param {String} clientName s
     * @param {String} applicationVersion
     */
    return function (serverAddress, clientName, applicationVersion, deviceName, deviceId, devicePixelRatio) {

        var apiclientcore = new apiclientcorefactory(serverAddress, clientName, applicationVersion, deviceName, deviceId, devicePixelRatio);

        var self = Object.assign(this, apiclientcore);

        events.on(apiclientcore, 'websocketmessage', onWebSocketMessage);

        Object.defineProperty(self, 'onAuthenticated', {
            get: function () { return apiclientcore.onAuthenticated; },
            set: function (newValue) { apiclientcore.onAuthenticated = newValue; }
        });

        Object.defineProperty(self, 'enableAutomaticBitrateDetection', {
            get: function () { return apiclientcore.enableAutomaticBitrateDetection; },
            set: function (newValue) { apiclientcore.enableAutomaticBitrateDetection = newValue; }
        });

        function getCurrentUser() {

            if (apiclientcore.isLoggedIn()) {
                return apiclientcore.getCurrentUser();
            }

            // TODO: Need to select a user some way if we don't have a user id
            var id = apiclientcore.getCurrentUserId();
            var user = localassetmanager.loadOfflineUser(id);

            return Promise.resolve(user);
        };

        function getUserViews(userId) {

            return apiclientcore.getUserViews(userId).then(function (result) {

                var serverInfo = apiclientcore.serverInfo();

                if (serverInfo) {

                    return getLocalView(serverInfo.Id, userId).then(function (localView) {

                        if (localView) {

                            result.Items.push(localView);
                            result.TotalRecordCount++;
                        }

                        return Promise.resolve(result);
                    });
                }

                return Promise.resolve(result);
            });
        }

        function getLocalView(serverId, userId) {

            return localassetmanager.getViews(serverId, userId).then(function (views) {

                var localView = null;

                if (views.length > 0) {

                    localView = {
                        Name: 'Offline Items',
                        ServerId: serverId,
                        Id: 'localview',
                        Type: 'localview'
                    };
                }

                return Promise.resolve(localView);
            });
        }

        function getItems(userId, options) {

            var serverInfo = apiclientcore.serverInfo();
            var i;

            if (serverInfo && options.ParentId === 'localview') {

                return localassetmanager.getViews(serverInfo.Id, userId).then(function (items) {
                    var result = {
                        Items: items,
                        TotalRecordCount: items.length
                    };

                    return Promise.resolve(result);
                });

            } else if (serverInfo && options && (isLocalId(options.ParentId) || isLocalViewId(options.ParentId))) {

                return localassetmanager.getViewItems(serverInfo.Id, userId, options).then(function (items) {

                    items.forEach(function (item) {
                        adjustGuidProperties(item);
                    });

                    items.sort(function (a, b) { return a.SortName.toLowerCase().localeCompare(b.SortName.toLowerCase()); });

                    var result = {
                        Items: items,
                        TotalRecordCount: items.length
                    };

                    return Promise.resolve(result);
                });
            } else if (options && options.ExcludeItemIds && options.ExcludeItemIds.length) {

                var exItems = options.ExcludeItemIds.split(',');

                for (i = 0; i < exItems.length; i++) {
                    if (isLocalId(exItems[i])) {
                        return Promise.resolve(createEmptyList());
                    }
                }
            } else if (options && options.Ids && options.Ids.length) {

                var ids = options.Ids.split(',');
                var hasLocal = false;

                for (i = 0; i < ids.length; i++) {
                    if (isLocalId(ids[i])) {
                        hasLocal = true;
                    }
                }

                if (hasLocal) {
                    return localassetmanager.getItemsFromIds(serverInfo.Id, ids).then(function (items) {

                        items.forEach(function (item) {
                            adjustGuidProperties(item);
                        });

                        var result = {
                            Items: items,
                            TotalRecordCount: items.length
                        };

                        return Promise.resolve(result);
                    });
                }
            }

            return apiclientcore.getItems(userId, options);
        }

        function getItem(userId, itemId) {

            if (itemId) {
                itemId = itemId.toString();
            }

            var serverInfo;

            if (isLocalViewId(itemId)) {

                serverInfo = apiclientcore.serverInfo();

                if (serverInfo) {
                    return localassetmanager.getViews(serverInfo.Id, userId).then(function (items) {

                        var views = items.filter(function (item) {
                            return item.Id === itemId;
                        });

                        if (views.length > 0) {
                            return Promise.resolve(views[0]);
                        }

                        // TODO: Test consequence of this
                        return Promise.reject();
                    });
                }
            }

            if (isLocalId(itemId)) {

                serverInfo = apiclientcore.serverInfo();

                if (serverInfo) {
                    return localassetmanager.getLocalItem(serverInfo.Id, stripLocalPrefix(itemId)).then(function (item) {

                        adjustGuidProperties(item.Item);

                        return Promise.resolve(item.Item);
                    });
                }
            }

            return apiclientcore.getItem(userId, itemId);
        }

        function adjustGuidProperties(downloadedItem) {

            downloadedItem.Id = convertGuidToLocal(downloadedItem.Id);
            downloadedItem.SeriesId = convertGuidToLocal(downloadedItem.SeriesId);

            downloadedItem.AlbumId = convertGuidToLocal(downloadedItem.AlbumId);
            downloadedItem.ParentId = convertGuidToLocal(downloadedItem.ParentId);
            downloadedItem.ParentThumbItemId = convertGuidToLocal(downloadedItem.ParentThumbItemId);
            downloadedItem.ParentPrimaryImageItemId = convertGuidToLocal(downloadedItem.ParentPrimaryImageItemId);
            downloadedItem.PrimaryImageItemId = convertGuidToLocal(downloadedItem.PrimaryImageItemId);
            downloadedItem.ParentLogoItemId = convertGuidToLocal(downloadedItem.ParentLogoItemId);
            downloadedItem.ParentBackdropItemID = convertGuidToLocal(downloadedItem.ParentBackdropItemID);

            downloadedItem.ParentBackdropImageTags = null;
        }

        function convertGuidToLocal(guid) {

            if (!guid) {
                return null;
            }

            if (isLocalId(guid)) {
                return guid;
            }

            return 'local:' + guid;
        }

        function getNextUpEpisodes(options) {

            if (options.SeriesId) {
                if (isLocalId(options.SeriesId)) {
                    return Promise.resolve(createEmptyList());
                }
            }

            return apiclientcore.getNextUpEpisodes(options);
        }

        function getSeasons(itemId, options) {

            if (isLocalId(itemId)) {
                options.ParentId = itemId;
                return getItems(apiclientcore.getCurrentUserId(), options);
            }

            return apiclientcore.getSeasons(itemId, options);
        }

        function getEpisodes(itemId, options) {

            if (isLocalId(options.SeasonId)) {
                options.ParentId = options.SeasonId;
                return getItems(apiclientcore.getCurrentUserId(), options);
            }

            return apiclientcore.getEpisodes(itemId, options);
        }

        function getThemeMedia(userId, itemId, inherit) {

            if (isLocalViewId(itemId) || isLocalId(itemId)) {
                return Promise.reject();
            }

            return apiclientcore.getThemeMedia(userId, itemId, inherit);
        }

        function getSimilarItems(itemId, options) {

            if (isLocalId(itemId)) {
                return Promise.resolve(createEmptyList());
            }

            return apiclientcore.getSimilarItems(itemId, options);
        }

        function updateFavoriteStatus(userId, itemId, isFavorite) {

            if (isLocalId(itemId)) {
                return Promise.resolve();
            }

            return apiclientcore.updateFavoriteStatus(userId, itemId, isFavorite);
        }

        function getScaledImageUrl(itemId, options) {

            if (isLocalId(itemId)
                || (options && options.itemid && isLocalId(options.itemid))) {

                var serverInfo = apiclientcore.serverInfo();
                var id = stripLocalPrefix(itemId);

                return localassetmanager.getImageUrl(serverInfo.Id, id, options.type, 0);
            }

            return apiclientcore.getScaledImageUrl(itemId, options);
        }

        function onWebSocketMessage(e, msg) {

            events.trigger(self, 'websocketmessage', [msg]);
        }

        function getPlaybackInfo(itemId, options, deviceProfile) {

            if (isLocalId(itemId)) {
                return localassetmanager.getLocalItem(apiclientcore.serverId(), stripLocalPrefix(itemId)).then(function (item) {

                    // TODO: This was already done during the sync process, right? If so, remove it
                    var mediaSources = item.Item.MediaSources.map(function (m) {
                        m.SupportsDirectPlay = true;
                        m.SupportsDirectStream = false;
                        m.SupportsTranscoding = false;
                        return m;
                    });

                    return {
                        MediaSources: mediaSources
                    };
                });
            }

            return apiclientcore.getPlaybackInfo(itemId, options, deviceProfile);
        }

        function reportPlaybackStart(options) {

            if (!options) {
                throw new Error("null options");
            }

            if (isLocalId(options.ItemId)) {
                return Promise.resolve();
            }

            return apiclientcore.reportPlaybackStart(options);
        }

        function reportPlaybackProgress(options) {

            if (!options) {
                throw new Error("null options");
            }

            if (isLocalId(options.ItemId)) {
                return Promise.resolve();
            }

            return apiclientcore.reportPlaybackProgress(options);
        }

        function reportPlaybackStopped(options) {

            if (!options) {
                throw new Error("null options");
            }

            if (isLocalId(options.ItemId)) {
                return Promise.resolve();
            }

            return apiclientcore.reportPlaybackStopped(options);
        }

        function getIntros(itemId) {

            if (isLocalId(itemId)) {
                return Promise.resolve({
                    Items: [],
                    TotalRecordCount: 0
                });
            }

            return apiclientcore.getIntros(itemId);
        }

        // **************** Helper functions

        function isLocalId(str) {
            return startsWith(str, localPrefix);
        }

        function isLocalViewId(str) {
            return startsWith(str, localViewPrefix);
        }

        function stripLocalPrefix(str) {
            var res = stripStart(str, localPrefix);
            res = stripStart(res, localViewPrefix);

            return res;
        }

        function startsWith(str, find) {

            if (str && find && str.length > find.length) {
                if (str.indexOf(find) === 0) {
                    return true;
                }
            }

            return false;
        }

        function stripStart(str, find) {
            if (startsWith(str, find)) {
                return str.substr(find.length);
            }

            return str;
        }

        function createEmptyList() {
            var result = {
                Items: [],
                TotalRecordCount: 0
            };

            return result;
        }

        // What to do with detectBitrate? When the app calls into apiclientex, this doesn't
        // mean that we're offline. We could be online or offline...
        self.detectBitrate = function () {
            return Promise.reject();
        };

        self.getCurrentUser = getCurrentUser;
        self.getUserViews = getUserViews;
        self.getItems = getItems;
        self.getItem = getItem;
        self.getSeasons = getSeasons;
        self.getEpisodes = getEpisodes;
        self.getThemeMedia = getThemeMedia;
        self.getNextUpEpisodes = getNextUpEpisodes;
        self.getSimilarItems = getSimilarItems;
        self.updateFavoriteStatus = updateFavoriteStatus;
        self.getScaledImageUrl = getScaledImageUrl;
        self.getPlaybackInfo = getPlaybackInfo;
        self.reportPlaybackStart = reportPlaybackStart;
        self.reportPlaybackProgress = reportPlaybackProgress;
        self.reportPlaybackStopped = reportPlaybackStopped;
        self.getIntros = getIntros;
    };

});<commit_msg>update sync<commit_after>define(['apiclientcore', 'localassetmanager', 'events'], function (apiclientcorefactory, localassetmanager, events) {
    'use strict';

    var localPrefix = 'local:';
    var localViewPrefix = 'localview:';

    /**
     * Creates a new api client instance
     * @param {String} serverAddress
     * @param {String} clientName s
     * @param {String} applicationVersion
     */
    return function (serverAddress, clientName, applicationVersion, deviceName, deviceId, devicePixelRatio) {

        var apiclientcore = new apiclientcorefactory(serverAddress, clientName, applicationVersion, deviceName, deviceId, devicePixelRatio);

        var self = Object.assign(this, apiclientcore);

        events.on(apiclientcore, 'websocketmessage', onWebSocketMessage);

        Object.defineProperty(self, 'onAuthenticated', {
            get: function () { return apiclientcore.onAuthenticated; },
            set: function (newValue) { apiclientcore.onAuthenticated = newValue; }
        });

        Object.defineProperty(self, 'enableAutomaticBitrateDetection', {
            get: function () { return apiclientcore.enableAutomaticBitrateDetection; },
            set: function (newValue) { apiclientcore.enableAutomaticBitrateDetection = newValue; }
        });

        function getCurrentUser() {

            if (apiclientcore.isLoggedIn()) {
                return apiclientcore.getCurrentUser();
            }

            // TODO: Need to select a user some way if we don't have a user id
            var id = apiclientcore.getCurrentUserId();
            var user = localassetmanager.loadOfflineUser(id);

            return Promise.resolve(user);
        };

        function getUserViews(userId) {

            return apiclientcore.getUserViews(userId).then(function (result) {

                var serverInfo = apiclientcore.serverInfo();

                if (serverInfo) {

                    return getLocalView(serverInfo.Id, userId).then(function (localView) {

                        if (localView) {

                            result.Items.push(localView);
                            result.TotalRecordCount++;
                        }

                        return Promise.resolve(result);
                    });
                }

                return Promise.resolve(result);
            });
        }

        function getLocalView(serverId, userId) {

            return localassetmanager.getViews(serverId, userId).then(function (views) {

                var localView = null;

                if (views.length > 0) {

                    localView = {
                        Name: 'Offline Items',
                        ServerId: serverId,
                        Id: 'localview',
                        Type: 'localview'
                    };
                }

                return Promise.resolve(localView);
            });
        }

        function getItems(userId, options) {

            var serverInfo = apiclientcore.serverInfo();
            var i;

            if (serverInfo && options.ParentId === 'localview') {

                return localassetmanager.getViews(serverInfo.Id, userId).then(function (items) {
                    var result = {
                        Items: items,
                        TotalRecordCount: items.length
                    };

                    return Promise.resolve(result);
                });

            } else if (serverInfo && options && (isLocalId(options.ParentId) || isLocalViewId(options.ParentId))) {

                return localassetmanager.getViewItems(serverInfo.Id, userId, options).then(function (items) {

                    items.forEach(function (item) {
                        adjustGuidProperties(item);
                    });

                    items.sort(function (a, b) { return a.SortName.toLowerCase().localeCompare(b.SortName.toLowerCase()); });

                    var result = {
                        Items: items,
                        TotalRecordCount: items.length
                    };

                    return Promise.resolve(result);
                });
            } else if (options && options.ExcludeItemIds && options.ExcludeItemIds.length) {

                var exItems = options.ExcludeItemIds.split(',');

                for (i = 0; i < exItems.length; i++) {
                    if (isLocalId(exItems[i])) {
                        return Promise.resolve(createEmptyList());
                    }
                }
            } else if (options && options.Ids && options.Ids.length) {

                var ids = options.Ids.split(',');
                var hasLocal = false;

                for (i = 0; i < ids.length; i++) {
                    if (isLocalId(ids[i])) {
                        hasLocal = true;
                    }
                }

                if (hasLocal) {
                    return localassetmanager.getItemsFromIds(serverInfo.Id, ids).then(function (items) {

                        items.forEach(function (item) {
                            adjustGuidProperties(item);
                        });

                        var result = {
                            Items: items,
                            TotalRecordCount: items.length
                        };

                        return Promise.resolve(result);
                    });
                }
            }

            return apiclientcore.getItems(userId, options);
        }

        function getItem(userId, itemId) {

            if (itemId) {
                itemId = itemId.toString();
            }

            var serverInfo;

            if (isLocalViewId(itemId)) {

                serverInfo = apiclientcore.serverInfo();

                if (serverInfo) {
                    return localassetmanager.getViews(serverInfo.Id, userId).then(function (items) {

                        var views = items.filter(function (item) {
                            return item.Id === itemId;
                        });

                        if (views.length > 0) {
                            return Promise.resolve(views[0]);
                        }

                        // TODO: Test consequence of this
                        return Promise.reject();
                    });
                }
            }

            if (isLocalId(itemId)) {

                serverInfo = apiclientcore.serverInfo();

                if (serverInfo) {
                    return localassetmanager.getLocalItem(serverInfo.Id, stripLocalPrefix(itemId)).then(function (item) {

                        adjustGuidProperties(item.Item);

                        return Promise.resolve(item.Item);
                    });
                }
            }

            return apiclientcore.getItem(userId, itemId);
        }

        function adjustGuidProperties(downloadedItem) {

            downloadedItem.Id = convertGuidToLocal(downloadedItem.Id);
            downloadedItem.SeriesId = convertGuidToLocal(downloadedItem.SeriesId);
            downloadedItem.SeasonId = convertGuidToLocal(downloadedItem.SeasonId);

            downloadedItem.AlbumId = convertGuidToLocal(downloadedItem.AlbumId);
            downloadedItem.ParentId = convertGuidToLocal(downloadedItem.ParentId);
            downloadedItem.ParentThumbItemId = convertGuidToLocal(downloadedItem.ParentThumbItemId);
            downloadedItem.ParentPrimaryImageItemId = convertGuidToLocal(downloadedItem.ParentPrimaryImageItemId);
            downloadedItem.PrimaryImageItemId = convertGuidToLocal(downloadedItem.PrimaryImageItemId);
            downloadedItem.ParentLogoItemId = convertGuidToLocal(downloadedItem.ParentLogoItemId);
            downloadedItem.ParentBackdropItemID = convertGuidToLocal(downloadedItem.ParentBackdropItemID);

            downloadedItem.ParentBackdropImageTags = null;
        }

        function convertGuidToLocal(guid) {

            if (!guid) {
                return null;
            }

            if (isLocalId(guid)) {
                return guid;
            }

            return 'local:' + guid;
        }

        function getNextUpEpisodes(options) {

            if (options.SeriesId) {
                if (isLocalId(options.SeriesId)) {
                    return Promise.resolve(createEmptyList());
                }
            }

            return apiclientcore.getNextUpEpisodes(options);
        }

        function getSeasons(itemId, options) {

            if (isLocalId(itemId)) {
                options.ParentId = itemId;
                return getItems(apiclientcore.getCurrentUserId(), options);
            }

            return apiclientcore.getSeasons(itemId, options);
        }

        function getEpisodes(itemId, options) {

            if (isLocalId(options.SeasonId)) {
                options.ParentId = options.SeasonId;
                return getItems(apiclientcore.getCurrentUserId(), options);
            }

            return apiclientcore.getEpisodes(itemId, options);
        }

        function getThemeMedia(userId, itemId, inherit) {

            if (isLocalViewId(itemId) || isLocalId(itemId)) {
                return Promise.reject();
            }

            return apiclientcore.getThemeMedia(userId, itemId, inherit);
        }

        function getSimilarItems(itemId, options) {

            if (isLocalId(itemId)) {
                return Promise.resolve(createEmptyList());
            }

            return apiclientcore.getSimilarItems(itemId, options);
        }

        function updateFavoriteStatus(userId, itemId, isFavorite) {

            if (isLocalId(itemId)) {
                return Promise.resolve();
            }

            return apiclientcore.updateFavoriteStatus(userId, itemId, isFavorite);
        }

        function getScaledImageUrl(itemId, options) {

            if (isLocalId(itemId)
                || (options && options.itemid && isLocalId(options.itemid))) {

                var serverInfo = apiclientcore.serverInfo();
                var id = stripLocalPrefix(itemId);

                return localassetmanager.getImageUrl(serverInfo.Id, id, options.type, 0);
            }

            return apiclientcore.getScaledImageUrl(itemId, options);
        }

        function onWebSocketMessage(e, msg) {

            events.trigger(self, 'websocketmessage', [msg]);
        }

        function getPlaybackInfo(itemId, options, deviceProfile) {

            if (isLocalId(itemId)) {
                return localassetmanager.getLocalItem(apiclientcore.serverId(), stripLocalPrefix(itemId)).then(function (item) {

                    // TODO: This was already done during the sync process, right? If so, remove it
                    var mediaSources = item.Item.MediaSources.map(function (m) {
                        m.SupportsDirectPlay = true;
                        m.SupportsDirectStream = false;
                        m.SupportsTranscoding = false;
                        return m;
                    });

                    return {
                        MediaSources: mediaSources
                    };
                });
            }

            return apiclientcore.getPlaybackInfo(itemId, options, deviceProfile);
        }

        function reportPlaybackStart(options) {

            if (!options) {
                throw new Error("null options");
            }

            if (isLocalId(options.ItemId)) {
                return Promise.resolve();
            }

            return apiclientcore.reportPlaybackStart(options);
        }

        function reportPlaybackProgress(options) {

            if (!options) {
                throw new Error("null options");
            }

            if (isLocalId(options.ItemId)) {
                return Promise.resolve();
            }

            return apiclientcore.reportPlaybackProgress(options);
        }

        function reportPlaybackStopped(options) {

            if (!options) {
                throw new Error("null options");
            }

            if (isLocalId(options.ItemId)) {
                return Promise.resolve();
            }

            return apiclientcore.reportPlaybackStopped(options);
        }

        function getIntros(itemId) {

            if (isLocalId(itemId)) {
                return Promise.resolve({
                    Items: [],
                    TotalRecordCount: 0
                });
            }

            return apiclientcore.getIntros(itemId);
        }

        // **************** Helper functions

        function isLocalId(str) {
            return startsWith(str, localPrefix);
        }

        function isLocalViewId(str) {
            return startsWith(str, localViewPrefix);
        }

        function stripLocalPrefix(str) {
            var res = stripStart(str, localPrefix);
            res = stripStart(res, localViewPrefix);

            return res;
        }

        function startsWith(str, find) {

            if (str && find && str.length > find.length) {
                if (str.indexOf(find) === 0) {
                    return true;
                }
            }

            return false;
        }

        function stripStart(str, find) {
            if (startsWith(str, find)) {
                return str.substr(find.length);
            }

            return str;
        }

        function createEmptyList() {
            var result = {
                Items: [],
                TotalRecordCount: 0
            };

            return result;
        }

        // What to do with detectBitrate? When the app calls into apiclientex, this doesn't
        // mean that we're offline. We could be online or offline...
        self.detectBitrate = function () {
            return Promise.reject();
        };

        self.getCurrentUser = getCurrentUser;
        self.getUserViews = getUserViews;
        self.getItems = getItems;
        self.getItem = getItem;
        self.getSeasons = getSeasons;
        self.getEpisodes = getEpisodes;
        self.getThemeMedia = getThemeMedia;
        self.getNextUpEpisodes = getNextUpEpisodes;
        self.getSimilarItems = getSimilarItems;
        self.updateFavoriteStatus = updateFavoriteStatus;
        self.getScaledImageUrl = getScaledImageUrl;
        self.getPlaybackInfo = getPlaybackInfo;
        self.reportPlaybackStart = reportPlaybackStart;
        self.reportPlaybackProgress = reportPlaybackProgress;
        self.reportPlaybackStopped = reportPlaybackStopped;
        self.getIntros = getIntros;
    };

});<|endoftext|>


<commit_before>var assert   = require('assert')
var Mod      = require('../')
var Moment   = require('moment');
var mongoose = require('mongoose')

var MomentSchema;
var MongooseMoment;
var Schema   = mongoose.Schema;

describe('MongooseMoment', function(){
	before(function(){
		MomentSchema = Mod(mongoose);
		MongooseMoment = mongoose.Types.Moment;
	});

	it('has a version', function(){
		assert.equal(require('../package').version, Mod.version);
	});

	it('is a function', function(){
		assert.equal('function', typeof MomentSchema);
	});

	it('extends mongoose.Schema.Types', function(){
		assert.ok(Schema.Types.Moment);
		assert.equal(MomentSchema, Schema.Types.Moment);
	});

	it('extends mongoose.Types', function(){
		assert.ok(mongoose.Types.Moment);
	});

	/** The Moment constructor was created as an anonymous function, so Moment.name = ''. This means you must use a String to set the field type in the schema, instead of being able to use the constructor.
	 * Fixing this would require a moment.js code change.
	*/
	it('can be used in schemas', function(){
		var s = new Schema({ m: 'Moment' });
		var m = s.path('m')
		assert.ok(m instanceof mongoose.SchemaType);
		assert.equal('function', typeof m.get);
	});

	describe('integration', function(){
		var db, S, schema, id;

		before(function(done){
			db = mongoose.createConnection('localhost', 'mongoose_moment')
			db.once('open', function () {
				schema = new Schema({
						m: 'Moment'
					, docs: [{ m: 'Moment' }]
				});
				S = db.model('MomentModel', schema);
				db.db.dropDatabase(function(){
					done();
				});
			});
		});

		after(function(done){
			db.db.dropDatabase(function () {
				db.close(done);
			});
		});

		describe('casts', function(){
			it('null', function(done){
				var s = new S({ m: null });
				assert.equal(s.m, null);
				done();
			});

			it('dates', function(done){
				var s = new S({ m: '2013-02-08' });
				assert.ok(Moment.isMoment(s.m), 'isMoment('+s.m+') = false');
				assert.ok(new Moment('2013-02-08').isSame(s.m), "correct value");
				done();
			});

			it('non-castables produce _saveErrors', function(done){
				var schema = new Schema({ date: 'Moment' }, { strict: 'throw' });
				var M = db.model('throws', schema);
				var m = new M({ date: "not a real date" });
				m.save(function (err) {
					console.log( err );
					assert.ok(err, 'error expected');
					assert.equal('moment', err.type, 'wrong type');
					assert.equal('CastError', err.name, 'wrong name');
					done();
				});
			});
		});

		describe('with db', function(){
			var id;
			// mongoose.set('debug', true);

			it('save', function(done){

				var s = new S({
						m: new Moment("12-25-1995", "MM-DD-YYYY")
					, docs: [null, { m: new Moment({years: 2010, months: 3, days: 5, hours: 15, minutes: 10, seconds: 3, milliseconds: 123}) } ]
				});
				s.save(function (err) {
					assert.ifError(err);
					id = s.id;
					done();
				})
			});

			it('findById', function(done){
				S.findById(id, function (err, doc) {
					assert.ifError(err);
					assert.ok(Moment.isMoment(doc.m));
					assert.ok(doc.m.isSame(new Moment("12-25-1995", "MM-DD-YYYY")));
					assert.equal(null, doc.docs[0]);
					assert.ok(Moment.isMoment(doc.docs[1].m));
					assert.ok(doc.docs[1].m.isSame(new Moment({years: 2010, months: 3, days: 5, hours: 15, minutes: 10, seconds: 3, milliseconds: 123})));
					done();
				});
			});

			it('findOne matching null', function(done){
				S.create({ m: null }, function (err, doc_) {
					assert.ifError(err);
					S.findOne({ m: null }, function (err, doc) {
						assert.ifError(err);
						assert.equal(doc.id, doc_.id, 'id mismatch');
						done();
					});
				});
			});

			it('find with instanceof Moment', function(done){
				S.find({ 'docs.m': new Moment({years: 2010, months: 3, days: 5, hours: 15, minutes: 10, seconds: 3, milliseconds: 123}).valueOf() }, function (err, docs) {
					assert.ifError(err);
					assert.equal(1, docs.length, 'expected 1 result, got '+docs.length);
					var doc = docs[0];
					assert.equal(id, doc.id, 'id mismatch');
					done();
				});
			});

			it('find with string', function(done){
				S.find({ 'docs.m': new Moment('2010-04-05T15:10:03.123').valueOf() }, function (err, docs) {
					assert.ifError(err);
					assert.equal(1, docs.length, 'expected 1 result, got '+docs.length);
					var doc = docs[0];
					assert.equal(id, doc.id);
					done();
				});
			});

			it('find with string $in', function(done){
				S.find({ 'docs.m': { $in: [new Moment('2010-04-05T15:10:03.123').valueOf(), new Moment('2010-04-06T15:10:03.123').valueOf(), new Moment('2010-04-07T15:10:03.123').valueOf()] }}, function (err, docs) {
					assert.ifError(err);
					assert.equal(1, docs.length);
					var doc = docs[0];
					assert.equal(id, doc.id);
					done();
				});
			});

			it('find with between', function(done) {
				S.where('docs.m').between(new Moment('2010-04-05'), new Moment('2010-04-07') ).exec(function(err, docs) {
					assert.ifError(err);
					assert.equal(1, docs.length);
					var doc = docs[0];
					assert.equal(id, doc.id);
					done();
				});
			});

			describe('is updateable', function(){
				it('in general', function(done){
					S.findById(id, function (err, doc) {
						assert.ifError(err);

						// doc.m = new Moment("12-25-1995", "MM-DD-YYYY");
						// assert.ok(!doc.isModified('m'));

						// doc.m = "Mon Dec 25 1995 00:00:00 GMT-0800";
						// assert.ok(!doc.isModified('m'));

						doc.m = new Moment("12-26-1995", "MM-DD-YYYY");
						doc.save(function (err) {
							assert.ifError(err);
							S.findById(id, function (err, doc) {
								assert.ifError(err);
								assert.ok(doc.m.isSame(new Moment("12-26-1995", "MM-DD-YYYY")));
								done();
							});
						});
					});
				});
			});

		});
	});
});
<commit_msg>solve merge conflict<commit_after>var assert   = require('assert')
var Mod      = require('../')
var Moment   = require('moment');
var mongoose = require('mongoose')

var MomentSchema;
var MongooseMoment;
var Schema   = mongoose.Schema;

describe('MongooseMoment', function(){
	before(function(){
		MomentSchema = Mod(mongoose);
		MongooseMoment = mongoose.Types.Moment;
	});

	it('has a version', function(){
		assert.equal(require('../package').version, Mod.version);
	});

	it('is a function', function(){
		assert.equal('function', typeof MomentSchema);
	});

	it('extends mongoose.Schema.Types', function(){
		assert.ok(Schema.Types.Moment);
		assert.equal(MomentSchema, Schema.Types.Moment);
	});

	it('extends mongoose.Types', function(){
		assert.ok(mongoose.Types.Moment);
	});

	/** The Moment constructor was created as an anonymous function, so Moment.name = ''. This means you must use a String to set the field type in the schema, instead of being able to use the constructor.
	 * Fixing this would require a moment.js code change.
	*/
	it('can be used in schemas', function(){
		var s = new Schema({ m: 'Moment' });
		var m = s.path('m')
		assert.ok(m instanceof mongoose.SchemaType);
		assert.equal('function', typeof m.get);
	});

	describe('integration', function(){
		var db, S, schema, id;

		before(function(done){
			db = mongoose.createConnection('localhost', 'mongoose_moment')
			db.once('open', function () {
				schema = new Schema({
						m: 'Moment'
					, docs: [{ m: 'Moment' }]
				});
				S = db.model('MomentModel', schema);
				db.db.dropDatabase(function(){
					done();
				});
			});
		});

		after(function(done){
			db.db.dropDatabase(function () {
				db.close(done);
			});
		});

		describe('casts', function(){
			it('null', function(done){
				var s = new S({ m: null });
				assert.equal(s.m, null);
				done();
			});

			it('dates', function(done){
				var s = new S({ m: '2013-02-08' });
				assert.ok(Moment.isMoment(s.m), 'isMoment('+s.m+') = false');
				assert.ok(new Moment('2013-02-08').isSame(s.m), "correct value");
				done();
			});
		});

		describe('with db', function(){
			var id;
			// mongoose.set('debug', true);

			it('save', function(done){

				var s = new S({
						m: new Moment("12-25-1995", "MM-DD-YYYY")
					, docs: [null, { m: new Moment({years: 2010, months: 3, days: 5, hours: 15, minutes: 10, seconds: 3, milliseconds: 123}) } ]
				});
				s.save(function (err) {
					assert.ifError(err);
					id = s.id;
					done();
				})
			});

			it('findById', function(done){
				S.findById(id, function (err, doc) {
					assert.ifError(err);
					assert.ok(Moment.isMoment(doc.m));
					assert.ok(doc.m.isSame(new Moment("12-25-1995", "MM-DD-YYYY")));
					assert.equal(null, doc.docs[0]);
					assert.ok(Moment.isMoment(doc.docs[1].m));
					assert.ok(doc.docs[1].m.isSame(new Moment({years: 2010, months: 3, days: 5, hours: 15, minutes: 10, seconds: 3, milliseconds: 123})));
					done();
				});
			});

			it('findOne matching null', function(done){
				S.create({ m: null }, function (err, doc_) {
					assert.ifError(err);
					S.findOne({ m: null }, function (err, doc) {
						assert.ifError(err);
						assert.equal(doc.id, doc_.id, 'id mismatch');
						done();
					});
				});
			});

			it('find with instanceof Moment', function(done){
				S.find({ 'docs.m': new Moment({years: 2010, months: 3, days: 5, hours: 15, minutes: 10, seconds: 3, milliseconds: 123}).valueOf() }, function (err, docs) {
					assert.ifError(err);
					assert.equal(1, docs.length, 'expected 1 result, got '+docs.length);
					var doc = docs[0];
					assert.equal(id, doc.id, 'id mismatch');
					done();
				});
			});

			it('find with string', function(done){
				S.find({ 'docs.m': new Moment('2010-04-05T15:10:03.123').valueOf() }, function (err, docs) {
					assert.ifError(err);
					assert.equal(1, docs.length, 'expected 1 result, got '+docs.length);
					var doc = docs[0];
					assert.equal(id, doc.id);
					done();
				});
			});

			it('find with string $in', function(done){
				S.find({ 'docs.m': { $in: [new Moment('2010-04-05T15:10:03.123').valueOf(), new Moment('2010-04-06T15:10:03.123').valueOf(), new Moment('2010-04-07T15:10:03.123').valueOf()] }}, function (err, docs) {
					assert.ifError(err);
					assert.equal(1, docs.length);
					var doc = docs[0];
					assert.equal(id, doc.id);
					done();
				});
			});

			it('find with between', function(done) {
				S.where('docs.m').between(new Moment('2010-04-05'), new Moment('2010-04-07') ).exec(function(err, docs) {
					assert.ifError(err);
					assert.equal(1, docs.length);
					var doc = docs[0];
					assert.equal(id, doc.id);
					done();
				});
			});

			describe('is updateable', function(){
				it('in general', function(done){
					S.findById(id, function (err, doc) {
						assert.ifError(err);

						// doc.m = new Moment("12-25-1995", "MM-DD-YYYY");
						// assert.ok(!doc.isModified('m'));

						// doc.m = "Mon Dec 25 1995 00:00:00 GMT-0800";
						// assert.ok(!doc.isModified('m'));

						doc.m = new Moment("12-26-1995", "MM-DD-YYYY");
						doc.save(function (err) {
							assert.ifError(err);
							S.findById(id, function (err, doc) {
								assert.ifError(err);
								assert.ok(doc.m.isSame(new Moment("12-26-1995", "MM-DD-YYYY")));
								done();
							});
						});
					});
				});
			});

		});
	});
});
<|endoftext|>


<commit_before>const Plugin = require('broccoli-plugin'),
  path = require('path'),
  exec = require("child_process").exec,
  fs = require('fs-extra');

// Create a subclass Mkdocs derived from Plugin
MkDocs.prototype = Object.create(Plugin.prototype);
MkDocs.prototype.constructor = MkDocs;
function MkDocs(inputNodes, options) {
  options = options || {};
  Plugin.call(this, inputNodes, {
    annotation: options.annotation
  });
  this.options = options;
}

MkDocs.prototype.copyToSrc = function(file) {
  let base = process.cwd();
  fs.ensureDirSync(`${base}/public/site`);
  return new Promise( (res, rej) => {
    fs.copy(file, `${base}/public/site`, function(err) {
      if (err) rej(err);
      res();
    });
  });
};

MkDocs.prototype.build = function () {
  let srcDir = this.inputPaths[0],
    outputPath = this.outputPath,
    processOriginalPath = process.cwd();
  return new Promise((res, rej) => {
    const command = "mkdocs build";
    fs.ensureDirSync(`${outputPath}/site`);
    console.log(`chdir : ${srcDir}`);
    process.chdir(srcDir);
    exec(command, (error, stdout) => {
      process.chdir(processOriginalPath);
      error ? rej(error): res(`${srcDir}/site`);
    });
  }).then(this.copyToSrc)
};

module.exports = MkDocs;
<commit_msg>added new build option for mkdocs<commit_after>const Plugin = require('broccoli-plugin'),
  path = require('path'),
  exec = require("child_process").exec,
  fs = require('fs-extra');

// Create a subclass Mkdocs derived from Plugin
MkDocs.prototype = Object.create(Plugin.prototype);
MkDocs.prototype.constructor = MkDocs;
function MkDocs(inputNodes, options) {
  options = options || {};
  Plugin.call(this, inputNodes, {
    annotation: options.annotation
  });
  this.options = options;
}

MkDocs.prototype.copyToSrc = function(file) {
  let base = process.cwd();
  return new Promise( (res, rej) => {
    fs.copy(file, `${base}/public/documentation/site`, function(err) {
      if (err) rej(err);
      res();
    });
  });
};

MkDocs.prototype.build = function () {
  let srcDir = `${this.inputPaths[0]}/documentation`,
    outputPath = this.outputPath,
    processOriginalPath = process.cwd();
  return new Promise((res, rej) => {
    const command = "mkdocs build";
    fs.ensureDirSync(`${outputPath}/site`);
    process.chdir(srcDir);
    exec(command, (error, stdout) => {
      process.chdir(processOriginalPath);
      error ? rej(error): res(`${srcDir}/site`);
    });
  }).then(this.copyToSrc)
};

module.exports = MkDocs;
<|endoftext|>


<commit_before>var request = require('supertest'),
    utils = require('../lib/utils');

//var geboMongoose = require('gebo-mongoose-connection');
//var mongoose = geboMongoose.get(true);
//geboMongoose.once('mongoose-connect', function() {
//    mongoose.connection.db.close();
//  });

var events = require('events'),
    event = new events.EventEmitter();

var nconf = require('nconf');
nconf.file({ file: 'gebo.json' });
var TEST_DB = utils.getMongoDbName(nconf.get('testEmail'));

/**
 * Test modes
 */
exports.testModes = {

    setUp: function(callback) {
        delete require.cache[require.resolve('../lib/native-mongo-connection')];
        delete require.cache[require.resolve('gebo-mongoose-connection')];
        delete require.cache[require.resolve('../index')];
        callback();
    },

    tearDown: function(callback) {
        delete require.cache[require.resolve('../lib/native-mongo-connection')];
        delete require.cache[require.resolve('gebo-mongoose-connection')];
        delete require.cache[require.resolve('../index')];
        callback();
    },

    'Should go into test mode when the parameter is set to true': function(test) {
        test.expect(2);
        var gebo = require('../index')(true);

        gebo.nativeMongoConnection.once('native-connect', function() {
            gebo.nativeMongoConnection.get(function(nativeConn) {
                test.equal(nativeConn.databaseName, TEST_DB);

                // Test gebo-mongoose-connection
                test.equal(gebo.mongoose.connection.name, TEST_DB);
                gebo.mongoose.connection.db.close();
                test.done();
              });
          });
    },

    'Should go into production mode when the parameter is not set': function(test) {
        test.expect(2);
        var gebo = require('../index')();
        gebo.nativeMongoConnection.once('native-connect', function() {
            gebo.nativeMongoConnection.get(function(nativeConn) {
                test.equal(nativeConn.databaseName, utils.getMongoDbName(nconf.get('email')));

                // Test gebo-mongoose-connection
                test.equal(gebo.mongoose.connection.name, utils.getMongoDbName(nconf.get('email')));
                gebo.mongoose.connection.db.close();
                test.done();
              });
          });
    },

    'Should go into production mode when the parameter is set to false': function(test) {
        test.expect(2);
        var gebo = require('../index')(false);
        gebo.nativeMongoConnection.once('native-connect', function() {
            gebo.nativeMongoConnection.get(function(nativeConn) {
                test.equal(nativeConn.databaseName, utils.getMongoDbName(nconf.get('email')));

                // Test gebo-mongoose-connection
                test.equal(gebo.mongoose.connection.name, utils.getMongoDbName(nconf.get('email')));
                gebo.mongoose.connection.db.close();
                test.done();
              });
          });
    },

};

/**
 * This ensures that a connection is made to the
 * test databases
 */
var mongooseConnection = require('gebo-mongoose-connection'),
    nativeMongoConnection = require('../lib/native-mongo-connection').get(true, function(){});

/**
 * Add an action
 */
exports.actionAdd = {

    'Should be able to add an action': function(test) {
        test.expect(3);
        var gebo = require('../index')(true);
        test.equal(gebo.actions.testAction, undefined);

        // Create a new action
        function testAction() {
                return 'testAction, yeah yeah!';
              };

        gebo.actions.add(testAction);

        test.equal(typeof gebo.actions.testAction, 'function');
        test.equal(gebo.actions.testAction(), 'testAction, yeah yeah!');

        test.done();
    },
};

/**
 * Add a schema
 */
exports.schemaAdd = {

    'Should be able to add a schema': function(test) {
        test.expect(3);
        var gebo = require('../index')(true);
        test.equal(gebo.schemata.test, undefined);

        var testSchema = require('./schemata/mocks/test1');
        gebo.schemata.add('test', testSchema);

        test.equal(typeof gebo.schemata.test, 'function');
        var db = new gebo.schemata.test();
        test.equal(typeof db, 'object');

        test.done();
    },

    'Should be able to add a schemata object': function(test) {
        test.expect(6);

        var gebo = require('../index')(true);
        test.equal(gebo.schemata.test1, undefined);
        test.equal(gebo.schemata.test2, undefined);

        var testSchemata = require('./schemata/mocks');
        gebo.schemata.add(testSchemata);

        test.equal(typeof gebo.schemata.test1, 'function');
        var db = new gebo.schemata.test1();
        test.equal(typeof db, 'object');

        test.equal(typeof gebo.schemata.test2, 'function');
        db = new gebo.schemata.test2()
        test.equal(typeof db, 'object');

        test.done();
    },
};

/**
 * utils
 */
exports.utils = {
    'Return a mongo-friendly database name': function(test) {
        test.expect(1);
        var gebo = require('../index')(true);
        var dbName = gebo.utils.getMongoDbName('dan@example.com');
        test.equal(dbName, 'dan_at_example_dot_com');
        test.done();
    },
};

/**
 * schemata
 */
exports.schemata = {
    'Return schemata objects with which to instantiate mongoose models': function(test) {
        test.expect(5);
        var gebo = require('../index')(true);

        var dbName = new gebo.schemata.agent();
        var friendo = new dbName.friendoModel({
                name: 'Some guy',
                email: 'some@guy.com',
                gebo: 'https://somegebo.com',
            });

        test.equal(friendo.name, 'Some guy');
        test.equal(friendo.email, 'some@guy.com');
        test.equal(friendo.gebo, 'https://somegebo.com');

        dbName = new gebo.schemata.gebo();
        var registrant = new dbName.registrantModel({
                name: 'Some guy',
                email: 'some@guy.com',
            });

        test.equal(registrant.name, 'Some guy');
        test.equal(registrant.email, 'some@guy.com');

        test.done();
    },
};

/**
 * enable
 */
var _gebo;
exports.enable = {

    setUp: function(callback) {
        delete require.cache[require.resolve('../index')];
        delete require.cache[require.resolve('./mocks/full-action-module')];
        delete require.cache[require.resolve('./mocks/no-actions')];
        delete require.cache[require.resolve('./mocks/no-schema')];
        delete require.cache[require.resolve('./mocks/schema')];
        delete require.cache[require.resolve('./mocks/actions')];
        _gebo = require('..')(true);
        callback();
    },

    tearDown: function(callback) {
        // Why on earth do I have to do this? The cache deletions
        // have no impact on which schemata and actions are
        // included within the gebo. I delete these modules
        // before each test, look in the gebo after each require,
        // and there they be.
        _gebo.schemata.remove('mocks');
        _gebo.actions.remove('mocks');
        callback();
    },

    'Add schema and actions from action module': function(test) {
        test.expect(4);
        _gebo.enable('mocks', require('./mocks/full-action-module'));

        test.equal(typeof _gebo.schemata.mocks, 'function');
        var db = new _gebo.schemata.mocks();
        test.equal(typeof db.someModel, 'function');
        test.equal(typeof _gebo.actions.mocks.someAction, 'function');
        //test.equal(_gebo.actions.mocks.someAction(), 'Hi, guy!');
        _gebo.actions.mocks.someAction().
            then(function(results) {
                test.equal(results, 'Hi, guy!');
                test.done();
              }).
            catch(function(err) {
                test.ok(false, err);
                test.done();
              });
    },

    'Don\'t barf if no schema is included in the action module': function(test) {
        test.expect(3);
        _gebo.enable('mocks', require('./mocks/no-schema'));
        test.equal(_gebo.schemata.mocks, undefined);
        test.equal(typeof _gebo.actions.mocks.someAction, 'function');
        //test.equal(_gebo.actions.mocks.someAction(), 'Hi, guy!');
        _gebo.actions.mocks.someAction().
            then(function(results) {
                test.equal(results, 'Hi, guy!');
                test.done();
              }).
            catch(function(err) {
                test.ok(false, err);
                test.done();
              });
    },

    'Don\'t barf if no actions are included in the action module': function(test) {
        test.expect(3);
        _gebo.enable('mocks', require('./mocks/no-actions'));

        test.equal(typeof _gebo.schemata.mocks, 'function');
        var db = new _gebo.schemata.mocks();
        test.equal(typeof db.someModel, 'function');
        test.equal(_gebo.actions.mocks, undefined);
        test.done();
    },
};

/**
 * These tests ensure that all the expected HTTP codes get
 * returned at the right time
 */
var _goodMessage = {
        sender: 'someguy@example.com',
        performative: 'request',
        action: 'ls',
        content: {
            resource: 'files',
            fields: ['_id', 'name', 'lastModified'],
        },
        access_token: 'SomeAccessToken',
    };

var geboDb, agentDb;

exports.api = {

    setUp: function(callback) {
        _gebo = require('..')(true);

        // The gebo, by default, redirects all requests to
        // HTTPS. This removes the redirecting function from
        // the middleware stack, which the tests don't like.
        var index = utils.getIndexOfObject(_gebo.server._router.stack, 'name', 'requireHttps');
        if (index > -1) {
          _gebo.server._router.stack.splice(index, 1);
        }

        // Set up permissions and a token for a friendo
        geboDb = new _gebo.schemata.gebo();
        var registrant = new geboDb.registrantModel({
                name: 'Some guy',
                email: 'someguy@example.com',
            });

        agentDb = new _gebo.schemata.agent();
        var friendo = new agentDb.friendoModel({
                name: 'Some guy',
                email: 'someguy@example.com',
                gebo: 'https://somegebo.com',
            });

        friendo.permissions.push({ resource: 'ls',
                                   read: true,
                                   write: false,
                                   execute: false,
                                 });

        friendo.save(function(err) {
            if (err) {
              console.log(err);
            }
            callback();
          });
    },

    tearDown: function(callback) {
        geboDb.connection.db.dropDatabase(function(err) {
            if (err) {
              console.log(err)
            }
            agentDb.connection.db.dropDatabase(function(err) {
                if (err) {
                  console.log(err)
                }
                callback();
              });
          });
    },

    'Respond with 200 when a well-formed request has been received': function(test) {
        request(_gebo.server).
            post('/perform').
            send(_goodMessage).
            expect(200, test.done);
    },

/*
     ------ Testing a Typical Request -----
             HttpCode: 200
             Content-Type: application/json; charset=utf-8

              ------ Testing an Invalid API Key -----
              HttpCode: 401
              Content-Type: application/json; charset=utf-8

              {
                          "error": {
                                          "code": 123,
                                                  "message": "The token provided is invalid"
                                                              }
              }

     ------ Testing an Invalid Content Type Header -----
             HttpCode: 400
             Content-Type: application/json; charset=utf-8

             {
                         "error": {
                                         "code": 123,
                                                 "message": "The request could not be understood by the server."
                                                             }
             }

      ------ Testing an Invalid Sender -----
              HttpCode: 401
              Content-Type: application/json; charset=utf-8

              {
                          "error": {
                                          "code": 123,
                                                  "message": "The token provided is invalid"
                                                              }
              }

       ------ Testing an Invalid Performative -----
               HttpCode: 501
               Content-Type: application/json; charset=utf-8

               {
                           "error": {
                                           "code": 123,
                                                   "message": "The performative is not recognized"
                                                               }
               }

        ------ Testing an Invalid Action -----
                HttpCode: 501
                Content-Type: application/json; charset=utf-8

                {
                            "error": {
                                            "code": 123,
                                                    "message": "I don't know how to _______"
                                                                }
                }

         ------ Testing an Invalid Content -----
                 HttpCode: 501
                 Content-Type: application/json; charset=utf-8

                 {
                             "error": {
                                             "code": 123,
                                                     "message": "Content format is not available"
                                                                 }
                 }

*/

};
<commit_msg>Get passing 200 response tests<commit_after>var request = require('supertest'),
    utils = require('../lib/utils');

//var geboMongoose = require('gebo-mongoose-connection');
//var mongoose = geboMongoose.get(true);
//geboMongoose.once('mongoose-connect', function() {
//    mongoose.connection.db.close();
//  });

var events = require('events'),
    event = new events.EventEmitter();

var nconf = require('nconf');
nconf.file({ file: 'gebo.json' });
var TEST_DB = utils.getMongoDbName(nconf.get('testEmail'));

/**
 * Test modes
 */
exports.testModes = {

    setUp: function(callback) {
        delete require.cache[require.resolve('../lib/native-mongo-connection')];
        delete require.cache[require.resolve('gebo-mongoose-connection')];
        delete require.cache[require.resolve('../index')];
        callback();
    },

    tearDown: function(callback) {
        delete require.cache[require.resolve('../lib/native-mongo-connection')];
        delete require.cache[require.resolve('gebo-mongoose-connection')];
        delete require.cache[require.resolve('../index')];
        callback();
    },

    'Should go into test mode when the parameter is set to true': function(test) {
        test.expect(2);
        var gebo = require('../index')(true);

        gebo.nativeMongoConnection.once('native-connect', function() {
            gebo.nativeMongoConnection.get(function(nativeConn) {
                test.equal(nativeConn.databaseName, TEST_DB);

                // Test gebo-mongoose-connection
                test.equal(gebo.mongoose.connection.name, TEST_DB);
                gebo.mongoose.connection.db.close();
                test.done();
              });
          });
    },

    'Should go into production mode when the parameter is not set': function(test) {
        test.expect(2);
        var gebo = require('../index')();
        gebo.nativeMongoConnection.once('native-connect', function() {
            gebo.nativeMongoConnection.get(function(nativeConn) {
                test.equal(nativeConn.databaseName, utils.getMongoDbName(nconf.get('email')));

                // Test gebo-mongoose-connection
                test.equal(gebo.mongoose.connection.name, utils.getMongoDbName(nconf.get('email')));
                gebo.mongoose.connection.db.close();
                test.done();
              });
          });
    },

    'Should go into production mode when the parameter is set to false': function(test) {
        test.expect(2);
        var gebo = require('../index')(false);
        gebo.nativeMongoConnection.once('native-connect', function() {
            gebo.nativeMongoConnection.get(function(nativeConn) {
                test.equal(nativeConn.databaseName, utils.getMongoDbName(nconf.get('email')));

                // Test gebo-mongoose-connection
                test.equal(gebo.mongoose.connection.name, utils.getMongoDbName(nconf.get('email')));
                gebo.mongoose.connection.db.close();
                test.done();
              });
          });
    },

};

/**
 * This ensures that a connection is made to the
 * test databases
 */
var mongooseConnection = require('gebo-mongoose-connection'),
    nativeMongoConnection = require('../lib/native-mongo-connection').get(true, function(){});

/**
 * Add an action
 */
exports.actionAdd = {

    'Should be able to add an action': function(test) {
        test.expect(3);
        var gebo = require('../index')(true);
        test.equal(gebo.actions.testAction, undefined);

        // Create a new action
        function testAction() {
                return 'testAction, yeah yeah!';
              };

        gebo.actions.add(testAction);

        test.equal(typeof gebo.actions.testAction, 'function');
        test.equal(gebo.actions.testAction(), 'testAction, yeah yeah!');

        test.done();
    },
};

/**
 * Add a schema
 */
exports.schemaAdd = {

    'Should be able to add a schema': function(test) {
        test.expect(3);
        var gebo = require('../index')(true);
        test.equal(gebo.schemata.test, undefined);

        var testSchema = require('./schemata/mocks/test1');
        gebo.schemata.add('test', testSchema);

        test.equal(typeof gebo.schemata.test, 'function');
        var db = new gebo.schemata.test();
        test.equal(typeof db, 'object');

        test.done();
    },

    'Should be able to add a schemata object': function(test) {
        test.expect(6);

        var gebo = require('../index')(true);
        test.equal(gebo.schemata.test1, undefined);
        test.equal(gebo.schemata.test2, undefined);

        var testSchemata = require('./schemata/mocks');
        gebo.schemata.add(testSchemata);

        test.equal(typeof gebo.schemata.test1, 'function');
        var db = new gebo.schemata.test1();
        test.equal(typeof db, 'object');

        test.equal(typeof gebo.schemata.test2, 'function');
        db = new gebo.schemata.test2()
        test.equal(typeof db, 'object');

        test.done();
    },
};

/**
 * utils
 */
exports.utils = {
    'Return a mongo-friendly database name': function(test) {
        test.expect(1);
        var gebo = require('../index')(true);
        var dbName = gebo.utils.getMongoDbName('dan@example.com');
        test.equal(dbName, 'dan_at_example_dot_com');
        test.done();
    },
};

/**
 * schemata
 */
exports.schemata = {
    'Return schemata objects with which to instantiate mongoose models': function(test) {
        test.expect(5);
        var gebo = require('../index')(true);

        var dbName = new gebo.schemata.agent();
        var friendo = new dbName.friendoModel({
                name: 'Some guy',
                email: 'some@guy.com',
                gebo: 'https://somegebo.com',
            });

        test.equal(friendo.name, 'Some guy');
        test.equal(friendo.email, 'some@guy.com');
        test.equal(friendo.gebo, 'https://somegebo.com');

        dbName = new gebo.schemata.gebo();
        var registrant = new dbName.registrantModel({
                name: 'Some guy',
                email: 'some@guy.com',
            });

        test.equal(registrant.name, 'Some guy');
        test.equal(registrant.email, 'some@guy.com');

        test.done();
    },
};

/**
 * enable
 */
var _gebo;
exports.enable = {

    setUp: function(callback) {
        delete require.cache[require.resolve('../index')];
        delete require.cache[require.resolve('./mocks/full-action-module')];
        delete require.cache[require.resolve('./mocks/no-actions')];
        delete require.cache[require.resolve('./mocks/no-schema')];
        delete require.cache[require.resolve('./mocks/schema')];
        delete require.cache[require.resolve('./mocks/actions')];
        _gebo = require('..')(true);
        callback();
    },

    tearDown: function(callback) {
        // Why on earth do I have to do this? The cache deletions
        // have no impact on which schemata and actions are
        // included within the gebo. I delete these modules
        // before each test, look in the gebo after each require,
        // and there they be.
        _gebo.schemata.remove('mocks');
        _gebo.actions.remove('mocks');
        callback();
    },

    'Add schema and actions from action module': function(test) {
        test.expect(4);
        _gebo.enable('mocks', require('./mocks/full-action-module'));

        test.equal(typeof _gebo.schemata.mocks, 'function');
        var db = new _gebo.schemata.mocks();
        test.equal(typeof db.someModel, 'function');
        test.equal(typeof _gebo.actions.mocks.someAction, 'function');
        //test.equal(_gebo.actions.mocks.someAction(), 'Hi, guy!');
        _gebo.actions.mocks.someAction().
            then(function(results) {
                test.equal(results, 'Hi, guy!');
                test.done();
              }).
            catch(function(err) {
                test.ok(false, err);
                test.done();
              });
    },

    'Don\'t barf if no schema is included in the action module': function(test) {
        test.expect(3);
        _gebo.enable('mocks', require('./mocks/no-schema'));
        test.equal(_gebo.schemata.mocks, undefined);
        test.equal(typeof _gebo.actions.mocks.someAction, 'function');
        //test.equal(_gebo.actions.mocks.someAction(), 'Hi, guy!');
        _gebo.actions.mocks.someAction().
            then(function(results) {
                test.equal(results, 'Hi, guy!');
                test.done();
              }).
            catch(function(err) {
                test.ok(false, err);
                test.done();
              });
    },

    'Don\'t barf if no actions are included in the action module': function(test) {
        test.expect(3);
        _gebo.enable('mocks', require('./mocks/no-actions'));

        test.equal(typeof _gebo.schemata.mocks, 'function');
        var db = new _gebo.schemata.mocks();
        test.equal(typeof db.someModel, 'function');
        test.equal(_gebo.actions.mocks, undefined);
        test.done();
    },
};

/**
 * These tests ensure that all the expected HTTP codes get
 * returned at the right time
 */
var _goodMessage = {
        sender: 'someguy@example.com',
        performative: 'request',
        action: 'ls',
        content: {
            resource: 'files',
            fields: ['_id', 'name', 'lastModified'],
        },
        access_token: 'LetMeIn',
    };

var geboDb, agentDb;

exports.api = {

    setUp: function(callback) {
        _gebo = require('..')(true);

        // The gebo, by default, redirects all requests to
        // HTTPS. This removes the redirecting function from
        // the middleware stack, which the tests don't like.
        var index = utils.getIndexOfObject(_gebo.server._router.stack, 'name', 'requireHttps');
        if (index > -1) {
          _gebo.server._router.stack.splice(index, 1);
        }

        // Make a friendo
        agentDb = new _gebo.schemata.agent();
        var friendo = new agentDb.friendoModel({
                name: 'Some guy',
                email: 'someguy@example.com',
                gebo: 'https://somegebo.com',
            });

        friendo.permissions.push({ resource: 'files',
                                   read: true,
                                   write: false,
                                   execute: false,
                                 });

        // Set up permissions and a token for a friendo
        geboDb = new _gebo.schemata.gebo();
        var token = new geboDb.tokenModel({
            friendoId: friendo._id,
            string: 'LetMeIn',
          });

        friendo.save(function(err) {
            if (err) {
              console.log(err);
            }
            token.save(function(err) {
                if (err) {
                  console.log(err);
                }
                callback();
              });
          });
    },

    tearDown: function(callback) {
        geboDb.connection.db.dropDatabase(function(err) {
            if (err) {
              console.log(err)
            }
            agentDb.connection.db.dropDatabase(function(err) {
                if (err) {
                  console.log(err)
                }
                callback();
              });
          });
    },

    'Respond with 200 when a well-formed request has been received': function(test) {
        request(_gebo.server).
            post('/perform').
            send(_goodMessage).
            expect(200, test.done);
    },

/*
     ------ Testing a Typical Request -----
             HttpCode: 200
             Content-Type: application/json; charset=utf-8

              ------ Testing an Invalid API Key -----
              HttpCode: 401
              Content-Type: application/json; charset=utf-8

              {
                          "error": {
                                          "code": 123,
                                                  "message": "The token provided is invalid"
                                                              }
              }

     ------ Testing an Invalid Content Type Header -----
             HttpCode: 400
             Content-Type: application/json; charset=utf-8

             {
                         "error": {
                                         "code": 123,
                                                 "message": "The request could not be understood by the server."
                                                             }
             }

      ------ Testing an Invalid Sender -----
              HttpCode: 401
              Content-Type: application/json; charset=utf-8

              {
                          "error": {
                                          "code": 123,
                                                  "message": "The token provided is invalid"
                                                              }
              }

       ------ Testing an Invalid Performative -----
               HttpCode: 501
               Content-Type: application/json; charset=utf-8

               {
                           "error": {
                                           "code": 123,
                                                   "message": "The performative is not recognized"
                                                               }
               }

        ------ Testing an Invalid Action -----
                HttpCode: 501
                Content-Type: application/json; charset=utf-8

                {
                            "error": {
                                            "code": 123,
                                                    "message": "I don't know how to _______"
                                                                }
                }

         ------ Testing an Invalid Content -----
                 HttpCode: 501
                 Content-Type: application/json; charset=utf-8

                 {
                             "error": {
                                             "code": 123,
                                                     "message": "Content format is not available"
                                                                 }
                 }

*/

};
<|endoftext|>


<commit_before>'use strict';
var assert = require('assert');
var setCookie = require('../lib/set-cookie.js');

describe('set-cookie-parser', function () {

  it('should parse a simple set-cookie header', function () {
    var actual = setCookie.parse('foo=bar;');
    var expected = [{name: 'foo', value: 'bar'}];
    assert.deepEqual(actual, expected);
  });

  it('should parse a complex set-cookie header', function () {
    var cookieStr = 'foo=bar; Max-Age=1000; Domain=.example.com; Path=/; Expires=Tue, 01 Jul 2025 10:01:11 GMT; HttpOnly; Secure';
    var actual = setCookie.parse(cookieStr);
    var expected = [{name: 'foo', value: 'bar', path: '/', expires: new Date('Tue Jul 01 2025 06:01:11 GMT-0400 (EDT)'), maxAge: 1000, domain: '.example.com', secure: true, httpOnly: true}];
    assert.deepEqual(actual, expected);
  });

  it('should work on an array of headers', function () {
    var cookieStrs = ['bam=baz', 'foo=bar; Max-Age=1000; Domain=.example.com; Path=/; Expires=Tue, 01 Jul 2025 10:01:11 GMT; HttpOnly; Secure'];
    var actual = setCookie.parse(cookieStrs);
    var expected = [
      {name: 'bam', value: 'baz'},
      {name: 'foo', value: 'bar', path: '/', expires: new Date('Tue Jul 01 2025 06:01:11 GMT-0400 (EDT)'), maxAge: 1000, domain: '.example.com', secure: true, httpOnly: true}
    ];
    assert.deepEqual(actual, expected);
  });

  it('should work on request objects', function () {
    var mockRequest = {
      headers: {
        'set-cookie': ['bam=baz', 'foo=bar; Max-Age=1000; Domain=.example.com; Path=/; Expires=Tue, 01 Jul 2025 10:01:11 GMT; HttpOnly; Secure']
      }
    };
    var actual = setCookie.parse(mockRequest);
    var expected = [
      {name: 'bam', value: 'baz'},
      {name: 'foo', value: 'bar', path: '/', expires: new Date('Tue Jul 01 2025 06:01:11 GMT-0400 (EDT)'), maxAge: 1000, domain: '.example.com', secure: true, httpOnly: true}
    ];
    assert.deepEqual(actual, expected);
  });

  it('should work on request objects that don\'t have any set-cookie headers', function () {
    var mockRequest = {
      headers: {}
    };
    var actual = setCookie.parse(mockRequest);
    var expected = [];
    assert.deepEqual(actual, expected);
  });

});
<commit_msg>Add test, percent-encoding<commit_after>'use strict';
var assert = require('assert');
var setCookie = require('../lib/set-cookie.js');

describe('set-cookie-parser', function () {

  it('should parse a simple set-cookie header', function () {
    var actual = setCookie.parse('foo=bar;');
    var expected = [{name: 'foo', value: 'bar'}];
    assert.deepEqual(actual, expected);
  });

  it('should parse a complex set-cookie header', function () {
    var cookieStr = 'foo=bar; Max-Age=1000; Domain=.example.com; Path=/; Expires=Tue, 01 Jul 2025 10:01:11 GMT; HttpOnly; Secure';
    var actual = setCookie.parse(cookieStr);
    var expected = [{name: 'foo', value: 'bar', path: '/', expires: new Date('Tue Jul 01 2025 06:01:11 GMT-0400 (EDT)'), maxAge: 1000, domain: '.example.com', secure: true, httpOnly: true}];
    assert.deepEqual(actual, expected);
  });

  it('should parse a cookie with percent-encoding in the data', function () {
    var cookieStr = 'foo=asdf%3Basdf%3Dtrue%3Basdf%3Dasdf%3Basdf%3Dtrue%40asdf';
    var actual = setCookie.parse(cookieStr);
    var expected = [{name: 'foo', value: 'asdf%3Basdf%3Dtrue%3Basdf%3Dasdf%3Basdf%3Dtrue%40asdf'}];
    assert.deepEqual(actual, expected);
  });

  it('should work on an array of headers', function () {
    var cookieStrs = ['bam=baz', 'foo=bar; Max-Age=1000; Domain=.example.com; Path=/; Expires=Tue, 01 Jul 2025 10:01:11 GMT; HttpOnly; Secure'];
    var actual = setCookie.parse(cookieStrs);
    var expected = [
      {name: 'bam', value: 'baz'},
      {name: 'foo', value: 'bar', path: '/', expires: new Date('Tue Jul 01 2025 06:01:11 GMT-0400 (EDT)'), maxAge: 1000, domain: '.example.com', secure: true, httpOnly: true}
    ];
    assert.deepEqual(actual, expected);
  });

  it('should work on request objects', function () {
    var mockRequest = {
      headers: {
        'set-cookie': ['bam=baz', 'foo=bar; Max-Age=1000; Domain=.example.com; Path=/; Expires=Tue, 01 Jul 2025 10:01:11 GMT; HttpOnly; Secure']
      }
    };
    var actual = setCookie.parse(mockRequest);
    var expected = [
      {name: 'bam', value: 'baz'},
      {name: 'foo', value: 'bar', path: '/', expires: new Date('Tue Jul 01 2025 06:01:11 GMT-0400 (EDT)'), maxAge: 1000, domain: '.example.com', secure: true, httpOnly: true}
    ];
    assert.deepEqual(actual, expected);
  });

  it('should work on request objects that don\'t have any set-cookie headers', function () {
    var mockRequest = {
      headers: {}
    };
    var actual = setCookie.parse(mockRequest);
    var expected = [];
    assert.deepEqual(actual, expected);
  });

});
<|endoftext|>


<commit_before>'use strict';

var test = require('tape');
var csjs = require('../');

test('basic template string functionality', function t(assert) {
  var result = csjs`foo`;
  assert.equal(result.css, 'foo', 'basic template string works');
  assert.end();
});

test('basic template string functionality', function t(assert) {
  var result = csjs`

    .foo {}
    .bar extends .foo {}

  `;

  assert.ok(result, 'result exists');
  assert.ok(result.extensions, 'extensions exist');
  assert.ok(result.extensions.bar, 'bar has an extension');
  assert.equal(result.extensions.bar.className, 'bar foo', 'bar extends foo');
  assert.end();
});
<commit_msg>Added test for extending from external composition<commit_after>'use strict';

var test = require('tape');
var csjs = require('../');

test('basic template string functionality', function t(assert) {
  var result = csjs`foo`;
  assert.equal(result.css, 'foo', 'basic template string works');
  assert.end();
});

test('basic template string functionality', function t(assert) {
  var result = csjs`

    .foo {}
    .bar extends .foo {}

  `;

  assert.ok(result, 'result exists');
  assert.ok(result.extensions, 'extensions exist');
  assert.ok(result.extensions.bar, 'bar has an extension');
  assert.equal(result.extensions.bar.className, 'bar foo', 'bar extends foo');
  assert.end();
});

test('basic template string functionality', function t(assert) {
  var one = csjs`

    .foo {}
    .bar extends .foo {}

  `;

  var barFromOne = one.extensions.bar;

  var two = csjs`

    .baz extends ${barFromOne} {}

  `;

  assert.ok(two, 'result exists');
  assert.ok(two.extensions, 'extensions exist');
  assert.ok(two.extensions.baz, 'baz has an extension');
  assert.equal(two.extensions.baz.className, 'baz bar foo',
    'baz extends both bar and foo');
  assert.end();
});
<|endoftext|>