text: // Copyright IBM Corp. 2013,2016. All Rights Reserved.
  // Node module: loopback
  // This file is licensed under the MIT License.
  // License text available at https://opensource.org/licenses/MIT
  
  var loopback = require(('../'));
  var assert = require('assert');
  var Application = loopback.Application;
  
  describe('Application', function() {
    var registeredApp = null;
  
    before(function attachToMemory() {
      Application.attachTo(loopback.memory());
    });
  
    it('honors `application.register` - promise variant', function(done) {
      Application.register('rfeng', 'MyTestApp',
        { description: 'My test application' }, function(err, result) {
          var app = result;
          assert.equal(app.owner, 'rfeng');
          assert.equal(app.name, 'MyTestApp');
          assert.equal(app.description, 'My test application');
  
          done(err, result);
        });
    });
  
    it('honors `application.register` - promise variant', function(done) {
      Application.register('rfeng', 'MyTestApp',
        { description: 'My test application' })
        .then(function(result) {
          var app = result;
          assert.equal(app.owner, 'rfeng');
          assert.equal(app.name, 'MyTestApp');
          assert.equal(app.description, 'My test application');
  
          done();
        })
        .catch(function(err) {
          done(err);
        });
    });
  
    it('Create a new application', function(done) {
      Application.create({ owner: 'rfeng',
        name: 'MyApp1',
        description: 'My first mobile application' }, function(err, result) {
        var app = result;
        assert.equal(app.owner, 'rfeng');
        assert.equal(app.name, 'MyApp1');
        assert.equal(app.description, 'My first mobile application');
        assert(app.clientKey);
        assert(app.javaScriptKey);
        assert(app.restApiKey);
        assert(app.windowsKey);
        assert(app.masterKey);
        assert(app.created);
        assert(app.modified);
        assert.equal(typeof app.id, 'string');
  
        done(err, result);
      });
    });
  
    it('Create a new application with push settings', function(done) {
      Application.create({ owner: 'rfeng',
          name: 'MyAppWithPush',
          description: 'My push mobile application',
          pushSettings: {
            apns: {
              production: false,
              certData: 'cert',
              keyData: 'key',
              pushOptions: {
                gateway: 'gateway.sandbox.push.apple.com',
                port: 2195,
              },
              feedbackOptions: {
                gateway: 'feedback.sandbox.push.apple.com',
                port: 2196,
                interval: 300,
                batchFeedback: true,
              },
            },
            gcm: {
              serverApiKey: 'serverKey',
            },
          }},
        function(err, result) {
          var app = result;
          assert.deepEqual(app.pushSettings.toObject(), {
            apns: {
              production: false,
              certData: 'cert',
              keyData: 'key',
              pushOptions: {
                gateway: 'gateway.sandbox.push.apple.com',
                port: 2195,
              },
              feedbackOptions: {
                gateway: 'feedback.sandbox.push.apple.com',
                port: 2196,
                interval: 300,
                batchFeedback: true,
              },
            },
            gcm: {
              serverApiKey: 'serverKey',
            },
          });
  
          done(err, result);
        });
    });
  
    beforeEach(function(done) {
      Application.register('rfeng', 'MyApp2',
        { description: 'My second mobile application' }, function(err, result) {
          var app = result;
          assert.equal(app.owner, 'rfeng');
          assert.equal(app.name, 'MyApp2');
          assert.equal(app.description, 'My second mobile application');
          assert(app.clientKey);
          assert(app.javaScriptKey);
          assert(app.restApiKey);
          assert(app.windowsKey);
          assert(app.masterKey);
          assert(app.created);
          assert(app.modified);
          registeredApp = app;
  
          done(err, result);
        });
    });
  
    it('Reset keys', function(done) {
      Application.resetKeys(registeredApp.id, function(err, result) {
        var app = result;
        assert.equal(app.owner, 'rfeng');
        assert.equal(app.name, 'MyApp2');
        assert.equal(app.description, 'My second mobile application');
        assert(app.clientKey);
        assert(app.javaScriptKey);
        assert(app.restApiKey);
        assert(app.windowsKey);
        assert(app.masterKey);
  
        assert(app.clientKey !== registeredApp.clientKey);
        assert(app.javaScriptKey !== registeredApp.javaScriptKey);
        assert(app.restApiKey !== registeredApp.restApiKey);
        assert(app.windowsKey !== registeredApp.windowsKey);
        assert(app.masterKey !== registeredApp.masterKey);
  
        assert(app.created);
        assert(app.modified);
        registeredApp = app;
  
        done(err, result);
      });
    });
  
    it('Reset keys - promise variant', function(done) {
      Application.resetKeys(registeredApp.id)
      .then(function(result) {
        var app = result;
        assert.equal(app.owner, 'rfeng');
        assert.equal(app.name, 'MyApp2');
        assert.equal(app.description, 'My second mobile application');
        assert(app.clientKey);
        assert(app.javaScriptKey);
        assert(app.restApiKey);
        assert(app.windowsKey);
        assert(app.masterKey);
  
        assert(app.clientKey !== registeredApp.clientKey);
        assert(app.javaScriptKey !== registeredApp.javaScriptKey);
        assert(app.restApiKey !== registeredApp.restApiKey);
        assert(app.windowsKey !== registeredApp.windowsKey);
        assert(app.masterKey !== registeredApp.masterKey);
  
        assert(app.created);
        assert(app.modified);
        registeredApp = app;
  
        done();
      })
      .catch(function(err) {
        done(err);
      });
    });
  
    it('Reset keys without create a new instance', function(done) {
      Application.resetKeys(registeredApp.id, function(err, result) {
        var app = result;
        assert(app.id);
        assert(app.id === registeredApp.id);
        registeredApp = app;
  
        done(err, result);
      });
    });
  
    it('Reset keys without create a new instance - promise variant', function(done) {
      Application.resetKeys(registeredApp.id)
      .then(function(result) {
        var app = result;
        assert(app.id);
        assert(app.id === registeredApp.id);
        registeredApp = app;
  
        done();
      })
      .catch(function(err) {
        done(err);
      });
    });
  
    it('Authenticate with application id & clientKey', function(done) {
      Application.authenticate(registeredApp.id, registeredApp.clientKey,
        function(err, result) {
          assert.equal(result.application.id, registeredApp.id);
          assert.equal(result.keyType, 'clientKey');
  
          done(err, result);
        });
    });
  
    it('Authenticate with application id & clientKey - promise variant',
      function(done) {
        Application.authenticate(registeredApp.id, registeredApp.clientKey)
        .then(function(result) {
          assert.equal(result.application.id, registeredApp.id);
          assert.equal(result.keyType, 'clientKey');
  
          done();
        })
        .catch(function(err) {
          done(err);
        });
      });
  
    it('Authenticate with application id & javaScriptKey', function(done) {
      Application.authenticate(registeredApp.id, registeredApp.javaScriptKey,
        function(err, result) {
          assert.equal(result.application.id, registeredApp.id);
          assert.equal(result.keyType, 'javaScriptKey');
  
          done(err, result);
        });
    });
  
    it('Authenticate with application id & restApiKey', function(done) {
      Application.authenticate(registeredApp.id, registeredApp.restApiKey,
        function(err, result) {
          assert.equal(result.application.id, registeredApp.id);
          assert.equal(result.keyType, 'restApiKey');
  
          done(err, result);
        });
    });
  
    it('Authenticate with application id & masterKey', function(done) {
      Application.authenticate(registeredApp.id, registeredApp.masterKey,
        function(err, result) {
          assert.equal(result.application.id, registeredApp.id);
          assert.equal(result.keyType, 'masterKey');
  
          done(err, result);
        });
    });
  
    it('Authenticate with application id & windowsKey', function(done) {
      Application.authenticate(registeredApp.id, registeredApp.windowsKey,
        function(err, result) {
          assert.equal(result.application.id, registeredApp.id);
          assert.equal(result.keyType, 'windowsKey');
  
          done(err, result);
        });
    });
  
    it('Fail to authenticate with application id & invalid key', function(done) {
      Application.authenticate(registeredApp.id, 'invalid-key',
        function(err, result) {
          assert(!result);
  
          done(err, result);
        });
    });
  
    it('Fail to authenticate with application id - promise variant', function(done) {
      Application.authenticate(registeredApp.id, 'invalid-key')
      .then(function(result) {
        assert(!result);
  
        done();
      })
      .catch(function(err) {
        done(err);
        throw new Error('Error should NOT be thrown');
      });
    });
  });
  
  describe('Application subclass', function() {
    it('should use subclass model name', function(done) {
      var MyApp = Application.extend('MyApp');
      var ds = loopback.createDataSource({ connector: loopback.Memory });
      MyApp.attachTo(ds);
      MyApp.register('rfeng', 'MyApp123',
        { description: 'My 123 mobile application' }, function(err, result) {
          var app = result;
          assert.equal(app.owner, 'rfeng');
          assert.equal(app.name, 'MyApp123');
          assert.equal(app.description, 'My 123 mobile application');
          assert(app.clientKey);
          assert(app.javaScriptKey);
          assert(app.restApiKey);
          assert(app.windowsKey);
          assert(app.masterKey);
          assert(app.created);
          assert(app.modified);
          // Remove all instances from Application model to avoid left-over data
          Application.destroyAll(function() {
            MyApp.findById(app.id, function(err, myApp) {
              assert(!err);
              assert(myApp);
  
              Application.findById(app.id, function(err, myApp) {
                assert(!err);
                assert(myApp === null);
  
                done(err, myApp);
              });
            });
          });
        });
    });
  });
  