<commit_before>const should = require('should');
const config = require('../../../lib/config');
const services = require('../../../lib/services');
const schemas = require('../../../lib/schemas');
const credentialService = services.credential;
const userService = services.user;
const db = require('../../../lib/db');

describe('Credential tests', () => {
  const username = 'someUser';
  const credential = {
    secret: 'password'
  };

  function insertCredential(policy) {
    return credentialService.insertCredential(username, policy, credential);
  }

  beforeEach(() => db.flushdb());

  describe("'oauth2' specific cases", () => {
    const policy = 'oauth2';

    it('should not insert a credential that already exists', () => {
      return insertCredential(policy).then(newCredential => {
        return should(insertCredential(policy)).be.rejected();
      });
    });

    it('should insert a credential without password specified if autoGeneratePassword is set to true', () => {
      return credentialService
        .insertCredential(username, policy, {})
        .then(newCredential => {
          should.exist(newCredential);
          should.exist(newCredential.secret);
          should(newCredential.secret.length).greaterThanOrEqual(10);
        });
    });

    it('should insert a credential with id but different type that already exists', () => {
      return insertCredential(policy)
        .then(() => credentialService.insertCredential(username, 'basic-auth', credential))
        .then(newCredential => {
          should.exist(newCredential);
          newCredential.isActive.should.eql(true);
        });
    });
  });

  describe('support for multiple credentials', () => {
    ['key-auth', 'jwt'].forEach(policy => {
      it(policy, () => {
        return Promise.all([
          insertCredential(policy),
          insertCredential(policy)
        ])
          .then(() => credentialService.getCredentials(username))
          .then(results => {
            results.should.be.instanceOf(Array).and.have.length(2);
          });
      });
    });
  });

  const tests = [
    { policy: 'oauth2', passwordKey: 'secret' },
    { policy: 'basic-auth', passwordKey: 'password' },
    { policy: 'key-auth' },
    { policy: 'jwt' }
  ];

  tests.forEach(({ policy, passwordKey }) => {
    describe(`policy: '${policy}'`, () => {
      it('should insert a credential', () => {
        return insertCredential(policy);
      });

      it("should get a credential and strip 'passwordKey' props", () => {
        return insertCredential(policy)
          .then(credential => credentialService.getCredential(credential.id, policy))
          .then(credential => {
            should.exist(credential);
            if (passwordKey) {
              should.not.exist(credential.passwordKey);
              should.not.exist(credential[passwordKey]);
            };
            credential.isActive.should.eql(true);
          });
      });

      it('should deactivate a credential', () => {
        return insertCredential(policy)
          .then(credential => {
            return credentialService.deactivateCredential(credential.id, policy).then(res => {
              should.exist(res);
              return credentialService.getCredential(credential.id, policy);
            });
          })
          .then(credential => {
            should.exist(credential);
            credential.isActive.should.eql(false);
          });
      });

      it('should reactivate a credential', () => {
        return insertCredential(policy)
          .then(credential => {
            return credentialService.activateCredential(credential.id, policy).then(res => {
              should.exist(res);
              return credentialService.getCredential(credential.id, policy);
            });
          })
          .then(credential => {
            should.exist(credential);
            credential.isActive.should.eql(true);
          });
      });
    });
  });
});

describe('Credential service tests', () => {
  describe('Credential Cascade Delete tests', () => {
    let user;

    before(() => {
      user = {
        username: 'irfanbaqui',
        firstname: 'irfan',
        lastname: 'baqui',
        email: 'irfan@eg.com'
      };

      return db.flushdb()
        .then(() => userService.insert(user))
        .then((newUser) => {
          user = newUser;
          return Promise.all([
            credentialService.insertCredential(user.id, 'oauth2').then((oauthCred) => should.exist(oauthCred.secret)),
            credentialService.insertCredential(user.id, 'basic-auth').then((basicAuthCred) => should.exist(basicAuthCred.password))
          ]);
        });
    });

    it('should delete all credentials associated with a user when user is deleted', () => {
      return Promise.all([
        credentialService.getCredential(user.id, 'oauth2'),
        credentialService.getCredential(user.id, 'basic-auth')
      ])
        .then(([oauthRes, basicAuthRes]) => {
          should.exist(oauthRes); // Check to confirm the credentials exist
          should.exist(basicAuthRes);
          return userService.remove(user.id);
        })
        .then(res => {
          should.exist(res);
          return Promise.all([
            credentialService.getCredential(user.id, 'oauth2'),
            credentialService.getCredential(user.id, 'basic-auth')
          ]);
        })
        .then(([oauthResAfterDelete, basicAuthResAfterDelete]) => {
          should.not.exist(oauthResAfterDelete);
          should.not.exist(basicAuthResAfterDelete);
        });
    });

    it('should delete a credential', () => {
      return credentialService.insertCredential(user.id, 'oauth2').then(res => {
        should.exist(res);
        return credentialService.removeCredential(user.id, 'oauth2');
      }).then(deleted => {
        should(deleted).be.equal(1);
        return credentialService.getCredential(user.id, 'oauth2');
      }).then(resAfterDelete => should.not.exist(resAfterDelete));
    });
  });

  describe('Credential Property tests', () => {
    const originalModelConfig = JSON.parse(JSON.stringify(config.models.credentials));
    const username = 'someUser';
    const _credential = {
      secret: 'password',
      scopes: ['someScope'],
      someProperty: 'propVal'
    };

    before(() => {
      Object.assign(config.models.credentials.properties.oauth2.properties, {
        someProperty: { type: 'string' },
        otherProperty: { type: 'string', default: 'someDefaultValue' }
      });

      config.models.credentials.properties.oauth2.required.push('someProperty');
      schemas.register('credentials', 'credential', config.models.credentials);
      return db.flushdb();
    });

    after(() => {
      config.models.credentials = originalModelConfig;
      schemas.register('credentials', 'credential', config.models.credentials);
    });

    it('should not insert a credential with scopes if the scopes are not defined', () => {
      return should(credentialService.insertCredential(username, 'oauth2', _credential))
        .be.rejectedWith('One or more scopes don\'t exist');
    });

    it('should insert a credential with scopes if the scopes are defined', () => {
      return credentialService.insertScopes(['someScope'])
        .then(() => credentialService.insertCredential(username, 'oauth2', _credential))
        .then((newCredential) => {
          should.exist(newCredential);
          should.exist(newCredential.scopes);
          should.not.exist(newCredential.secret);

          should(newCredential.isActive).eql(true);
          should(newCredential.scopes).eql(['someScope']);
          should(newCredential.someProperty).eql('propVal');
        });
    });

    it('should add scopes to existing credential if the scopes are defined', () => {
      return credentialService.insertScopes(['someScope1', 'someScope2', 'someScope3', 'someOtherOne'])
        .then(() => credentialService.addScopesToCredential(username, 'oauth2', ['someScope1', 'someScope2', 'someScope3', 'someOtherOne']))
        .then((res) => {
          credentialService
            .getCredential(username, 'oauth2')
            .then((cred) => {
              should.exist(cred);
              should.exist(cred.scopes);
              cred.isActive.should.eql(true);
              cred.scopes.should.containEql(..._credential.scopes);
              cred.scopes.should.containEql('someScope1');
              cred.scopes.should.containEql('someScope2');
              cred.scopes.should.containEql('someScope3');
              cred.scopes.should.containEql('someOtherOne');
            });
        });
    });

    it('should remove scopes from existing credential', () => {
      return credentialService
        .removeScopesFromCredential(username, 'oauth2', ['someScope2', 'someScope3'])
        .then(() => credentialService.getCredential(username, 'oauth2'))
        .then((cred) => {
          should.exist(cred);
          should.exist(cred.scopes);
          cred.scopes.should.containEql(..._credential.scopes);
          cred.scopes.should.containEql('someScope1');
          cred.scopes.should.not.containEql('someScope2');
          cred.scopes.should.not.containEql('someScope3');
          cred.isActive.should.eql(true);
        });
    });

    it('should remove scopes from credential if the scope is deleted', () => {
      return credentialService.removeScopes(['someScope1', 'someScope'])
        .then(() => credentialService.getCredential(username, 'oauth2'))
        .then((cred) => {
          should.exist(cred);
          should.exist(cred.scopes);
          cred.scopes.should.containEql('someOtherOne');
          cred.scopes.should.not.containEql('someScope1');
          cred.scopes.should.not.containEql('someScope');
          cred.isActive.should.eql(true);
        });
    });

    it('should not add scopes to existing credential if the scopes are not defined', () => {
      return should(credentialService.addScopesToCredential(username, 'oauth2', ['undefinedScope']))
        .be.rejectedWith('One or more scopes don\'t exist');
    });

    it('should use default property if not defined', () => {
      const username2 = 'otherUser';
      const cred = {
        secret: 'password',
        scopes: ['someOtherOne'],
        someProperty: 'propVal'
      };

      return credentialService
        .insertCredential(username2, 'oauth2', cred)
        .then((newCredential) => {
          should.exist(newCredential);
          newCredential.isActive.should.eql(true);
          should.exist(newCredential.scopes);
          newCredential.scopes.should.eql(['someOtherOne']);
          newCredential.someProperty.should.eql('propVal');
          should.not.exist(newCredential.secret);
          newCredential.otherProperty.should.eql('someDefaultValue');
        });
    });

    it('should not create credential if a required property is not passed in', () => {
      const username3 = 'anotherUser';
      const cred = {
        secret: 'password',
        scopes: ['someScope']
      };

      return should(credentialService
        .insertCredential(username3, 'oauth2', cred))
        .be.rejectedWith('data should have required property \'someProperty\'')
        .then(() => credentialService.getCredential(username3, 'oauth2'))
        .then(credential => should.not.exist(credential));
    });

    it('should not update credential when no properties are specified', () => {
      return credentialService
        .updateCredential(username, 'oauth2', {})
        .then((newCredential) => {
          should.not.exist(newCredential);
          return credentialService.getCredential(username, 'oauth2');
        })
        .then(credential => {
          should.exist(credential);
        });
    });
  });
});
<commit_msg>better naming<commit_after>const should = require('should');
const config = require('../../../lib/config');
const services = require('../../../lib/services');
const schemas = require('../../../lib/schemas');
const credentialService = services.credential;
const userService = services.user;
const db = require('../../../lib/db');

describe('Credential tests', () => {
  const username = 'someUser';
  const credential = {
    secret: 'password'
  };

  function insertCredential(type) {
    return credentialService.insertCredential(username, policy, credential);
  }

  beforeEach(() => db.flushdb());

  describe("'oauth2' specific cases", () => {
    const policy = 'oauth2';

    it('should not insert a credential that already exists', () => {
      return insertCredential(policy).then(newCredential => {
        return should(insertCredential(policy)).be.rejected();
      });
    });

    it('should insert a credential without password specified if autoGeneratePassword is set to true', () => {
      return credentialService
        .insertCredential(username, policy, {})
        .then(newCredential => {
          should.exist(newCredential);
          should.exist(newCredential.secret);
          should(newCredential.secret.length).greaterThanOrEqual(10);
        });
    });

    it('should insert a credential with id but different type that already exists', () => {
      return insertCredential(policy)
        .then(() => credentialService.insertCredential(username, 'basic-auth', credential))
        .then(newCredential => {
          should.exist(newCredential);
          newCredential.isActive.should.eql(true);
        });
    });
  });

  describe('support for multiple credentials', () => {
    ['key-auth', 'jwt'].forEach(policy => {
      it(policy, () => {
        return Promise.all([
          insertCredential(policy),
          insertCredential(policy)
        ])
          .then(() => credentialService.getCredentials(username))
          .then(results => {
            results.should.be.instanceOf(Array).and.have.length(2);
          });
      });
    });
  });

  const tests = [
    { policy: 'oauth2', passwordKey: 'secret' },
    { policy: 'basic-auth', passwordKey: 'password' },
    { policy: 'key-auth' },
    { policy: 'jwt' }
  ];

  tests.forEach(({ policy, passwordKey }) => {
    describe(`policy: '${policy}'`, () => {
      it('should insert a credential', () => {
        return insertCredential(policy);
      });

      it("should get a credential and strip 'passwordKey' props", () => {
        return insertCredential(policy)
          .then(credential => credentialService.getCredential(credential.id, policy))
          .then(credential => {
            should.exist(credential);
            if (passwordKey) {
              should.not.exist(credential.passwordKey);
              should.not.exist(credential[passwordKey]);
            };
            credential.isActive.should.eql(true);
          });
      });

      it('should deactivate a credential', () => {
        return insertCredential(policy)
          .then(credential => {
            return credentialService.deactivateCredential(credential.id, policy).then(res => {
              should.exist(res);
              return credentialService.getCredential(credential.id, policy);
            });
          })
          .then(credential => {
            should.exist(credential);
            credential.isActive.should.eql(false);
          });
      });

      it('should reactivate a credential', () => {
        return insertCredential(policy)
          .then(credential => {
            return credentialService.activateCredential(credential.id, policy).then(res => {
              should.exist(res);
              return credentialService.getCredential(credential.id, policy);
            });
          })
          .then(credential => {
            should.exist(credential);
            credential.isActive.should.eql(true);
          });
      });
    });
  });
});

describe('Credential service tests', () => {
  describe('Credential Cascade Delete tests', () => {
    let user;

    before(() => {
      user = {
        username: 'irfanbaqui',
        firstname: 'irfan',
        lastname: 'baqui',
        email: 'irfan@eg.com'
      };

      return db.flushdb()
        .then(() => userService.insert(user))
        .then((newUser) => {
          user = newUser;
          return Promise.all([
            credentialService.insertCredential(user.id, 'oauth2').then((oauthCred) => should.exist(oauthCred.secret)),
            credentialService.insertCredential(user.id, 'basic-auth').then((basicAuthCred) => should.exist(basicAuthCred.password))
          ]);
        });
    });

    it('should delete all credentials associated with a user when user is deleted', () => {
      return Promise.all([
        credentialService.getCredential(user.id, 'oauth2'),
        credentialService.getCredential(user.id, 'basic-auth')
      ])
        .then(([oauthRes, basicAuthRes]) => {
          should.exist(oauthRes); // Check to confirm the credentials exist
          should.exist(basicAuthRes);
          return userService.remove(user.id);
        })
        .then(res => {
          should.exist(res);
          return Promise.all([
            credentialService.getCredential(user.id, 'oauth2'),
            credentialService.getCredential(user.id, 'basic-auth')
          ]);
        })
        .then(([oauthResAfterDelete, basicAuthResAfterDelete]) => {
          should.not.exist(oauthResAfterDelete);
          should.not.exist(basicAuthResAfterDelete);
        });
    });

    it('should delete a credential', () => {
      return credentialService.insertCredential(user.id, 'oauth2').then(res => {
        should.exist(res);
        return credentialService.removeCredential(user.id, 'oauth2');
      }).then(deleted => {
        should(deleted).be.equal(1);
        return credentialService.getCredential(user.id, 'oauth2');
      }).then(resAfterDelete => should.not.exist(resAfterDelete));
    });
  });

  describe('Credential Property tests', () => {
    const originalModelConfig = JSON.parse(JSON.stringify(config.models.credentials));
    const username = 'someUser';
    const _credential = {
      secret: 'password',
      scopes: ['someScope'],
      someProperty: 'propVal'
    };

    before(() => {
      Object.assign(config.models.credentials.properties.oauth2.properties, {
        someProperty: { type: 'string' },
        otherProperty: { type: 'string', default: 'someDefaultValue' }
      });

      config.models.credentials.properties.oauth2.required.push('someProperty');
      schemas.register('credentials', 'credential', config.models.credentials);
      return db.flushdb();
    });

    after(() => {
      config.models.credentials = originalModelConfig;
      schemas.register('credentials', 'credential', config.models.credentials);
    });

    it('should not insert a credential with scopes if the scopes are not defined', () => {
      return should(credentialService.insertCredential(username, 'oauth2', _credential))
        .be.rejectedWith('One or more scopes don\'t exist');
    });

    it('should insert a credential with scopes if the scopes are defined', () => {
      return credentialService.insertScopes(['someScope'])
        .then(() => credentialService.insertCredential(username, 'oauth2', _credential))
        .then((newCredential) => {
          should.exist(newCredential);
          should.exist(newCredential.scopes);
          should.not.exist(newCredential.secret);

          should(newCredential.isActive).eql(true);
          should(newCredential.scopes).eql(['someScope']);
          should(newCredential.someProperty).eql('propVal');
        });
    });

    it('should add scopes to existing credential if the scopes are defined', () => {
      return credentialService.insertScopes(['someScope1', 'someScope2', 'someScope3', 'someOtherOne'])
        .then(() => credentialService.addScopesToCredential(username, 'oauth2', ['someScope1', 'someScope2', 'someScope3', 'someOtherOne']))
        .then((res) => {
          credentialService
            .getCredential(username, 'oauth2')
            .then((cred) => {
              should.exist(cred);
              should.exist(cred.scopes);
              cred.isActive.should.eql(true);
              cred.scopes.should.containEql(..._credential.scopes);
              cred.scopes.should.containEql('someScope1');
              cred.scopes.should.containEql('someScope2');
              cred.scopes.should.containEql('someScope3');
              cred.scopes.should.containEql('someOtherOne');
            });
        });
    });

    it('should remove scopes from existing credential', () => {
      return credentialService
        .removeScopesFromCredential(username, 'oauth2', ['someScope2', 'someScope3'])
        .then(() => credentialService.getCredential(username, 'oauth2'))
        .then((cred) => {
          should.exist(cred);
          should.exist(cred.scopes);
          cred.scopes.should.containEql(..._credential.scopes);
          cred.scopes.should.containEql('someScope1');
          cred.scopes.should.not.containEql('someScope2');
          cred.scopes.should.not.containEql('someScope3');
          cred.isActive.should.eql(true);
        });
    });

    it('should remove scopes from credential if the scope is deleted', () => {
      return credentialService.removeScopes(['someScope1', 'someScope'])
        .then(() => credentialService.getCredential(username, 'oauth2'))
        .then((cred) => {
          should.exist(cred);
          should.exist(cred.scopes);
          cred.scopes.should.containEql('someOtherOne');
          cred.scopes.should.not.containEql('someScope1');
          cred.scopes.should.not.containEql('someScope');
          cred.isActive.should.eql(true);
        });
    });

    it('should not add scopes to existing credential if the scopes are not defined', () => {
      return should(credentialService.addScopesToCredential(username, 'oauth2', ['undefinedScope']))
        .be.rejectedWith('One or more scopes don\'t exist');
    });

    it('should use default property if not defined', () => {
      const username2 = 'otherUser';
      const cred = {
        secret: 'password',
        scopes: ['someOtherOne'],
        someProperty: 'propVal'
      };

      return credentialService
        .insertCredential(username2, 'oauth2', cred)
        .then((newCredential) => {
          should.exist(newCredential);
          newCredential.isActive.should.eql(true);
          should.exist(newCredential.scopes);
          newCredential.scopes.should.eql(['someOtherOne']);
          newCredential.someProperty.should.eql('propVal');
          should.not.exist(newCredential.secret);
          newCredential.otherProperty.should.eql('someDefaultValue');
        });
    });

    it('should not create credential if a required property is not passed in', () => {
      const username3 = 'anotherUser';
      const cred = {
        secret: 'password',
        scopes: ['someScope']
      };

      return should(credentialService
        .insertCredential(username3, 'oauth2', cred))
        .be.rejectedWith('data should have required property \'someProperty\'')
        .then(() => credentialService.getCredential(username3, 'oauth2'))
        .then(credential => should.not.exist(credential));
    });

    it('should not update credential when no properties are specified', () => {
      return credentialService
        .updateCredential(username, 'oauth2', {})
        .then((newCredential) => {
          should.not.exist(newCredential);
          return credentialService.getCredential(username, 'oauth2');
        })
        .then(credential => {
          should.exist(credential);
        });
    });
  });
});
<|endoftext|>


<commit_before>var express = require('express');
var proxy = require('express-http-proxy');
var webpackDevMiddleware = require('webpack-dev-middleware');
var webpack = require('webpack');

var compiler = webpack(require('../webpack.config.js'));
var handler = require('./handler');
var log = require('./log');
var routes = require('../src/routes.json').concat(require('../src/routes-dev.json'))
    .filter(route => !process.env.VIEW || process.env.VIEW === route.view);

// Create server
var app = express();
app.disable('x-powered-by');

// Server setup
app.use(log());

// Bind routes
routes.forEach(route => {
    app.get(route.pattern, handler(route));
});

app.use(webpackDevMiddleware(compiler,
    {
        watchOptions: {
            aggregateTimeout: 500,
            poll: 2500,
            ignored: ['node_modules','build']
        }
    }
));

var proxyHost = process.env.FALLBACK || '';
if (proxyHost !== '') {
    // Fall back to scratchr2 in development
    // This proxy middleware must come last
    app.use('/', proxy(proxyHost));
}

// Start listening
var port = process.env.PORT || 8333;
app.listen(port, function () {
    process.stdout.write('Server listening on port ' + port + '\n');
    if (proxyHost) {
        process.stdout.write('Proxy host: ' + proxyHost + '\n');
    }
});
<commit_msg>Move watchOptions into middlewareOptions<commit_after>var express = require('express');
var proxy = require('express-http-proxy');
var webpackDevMiddleware = require('webpack-dev-middleware');
var webpack = require('webpack');

var compiler = webpack(require('../webpack.config.js'));
var handler = require('./handler');
var log = require('./log');
var routes = require('../src/routes.json').concat(require('../src/routes-dev.json'))
    .filter(route => !process.env.VIEW || process.env.VIEW === route.view);

// Create server
var app = express();
app.disable('x-powered-by');

// Server setup
app.use(log());

// Bind routes
routes.forEach(route => {
    app.get(route.pattern, handler(route));
});

var middlewareOptions = {};
if (process.env.USE_DOCKER_WATCHOPTIONS) {
    middlewareOptions = {
        watchOptions: {
            aggregateTimeout: 500,
            poll: 2500,
            ignored: ['node_modules','build']
        }
    };
}

app.use(webpackDevMiddleware(compiler, middlewareOptions));

var proxyHost = process.env.FALLBACK || '';
if (proxyHost !== '') {
    // Fall back to scratchr2 in development
    // This proxy middleware must come last
    app.use('/', proxy(proxyHost));
}

// Start listening
var port = process.env.PORT || 8333;
app.listen(port, function () {
    process.stdout.write('Server listening on port ' + port + '\n');
    if (proxyHost) {
        process.stdout.write('Proxy host: ' + proxyHost + '\n');
    }
});
<|endoftext|>


<commit_before>// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

'use strict';

var path = require('path');
var fail = require('assert').fail;

var webdriver = require('..'),
    Browser = webdriver.Browser,
    By = webdriver.By,
    assert = require('../testing/assert'),
    test = require('../lib/test');

test.suite(function(env) {
  var driver;

  test.before(function() {
    driver = env.builder().build();
  });

  test.after(function() {
    driver.quit();
  });

  test.beforeEach(function() {
    driver.get(test.Pages.echoPage);
  });

  describe('executeScript;', function() {
    var shouldHaveFailed = new Error('Should have failed');

    test.it('fails if script throws', function() {
      execute('throw new Error("boom")')
          .then(function() { throw shouldHaveFailed; })
          .catch(function(e) {
            // The java WebDriver server adds a bunch of crap to error messages.
            // Error message will just be "JavaScript error" for IE.
            assert(e.message).matches(/.*(JavaScript error|boom).*/);
          });
    });

    test.it('fails if script does not parse', function() {
      execute('throw function\\*')
          .then(function() { throw shouldHaveFailed; })
          .catch(function(e) {
            assert(e).notEqualTo(shouldHaveFailed);
          });
    });

    describe('scripts;', function() {
      test.it('do not pollute the global scope', function() {
        execute('var x = 1;');
        assert(execute('return typeof x;')).equalTo('undefined');
      });

      test.it('can set global variables', function() {
        execute('window.x = 1234;');
        assert(execute('return x;')).equalTo(1234);
      });

      test.it('may be defined as a function expression', function() {
        assert(execute(function() {
          return 1234 + 'abc';
        })).equalTo('1234abc');
      });
    });

    describe('return values;', function() {

      test.it('returns undefined as null', function() {
        assert(execute('var x; return x;')).isNull();
      });

      test.it('can return null', function() {
        assert(execute('return null;')).isNull();
      });

      test.it('can return numbers', function() {
        assert(execute('return 1234')).equalTo(1234);
        assert(execute('return 3.1456')).equalTo(3.1456);
      });

      test.it('can return strings', function() {
        assert(execute('return "hello"')).equalTo('hello');
      });

      test.it('can return booleans', function() {
        assert(execute('return true')).equalTo(true);
        assert(execute('return false')).equalTo(false);
      });

      test.it('can return an array of primitives', function() {
        execute('var x; return [1, false, null, 3.14, x]')
            .then(verifyJson([1, false, null, 3.14, null]));
      });

      test.it('can return nested arrays', function() {
        execute('return [[1, 2, [3]]]')
            .then(verifyJson([[1, 2, [3]]]));
      });

      test.ignore(env.browsers(Browser.IE, Browser.SAFARI)).
      it('can return empty object literal', function() {
        execute('return {}').then(verifyJson({}));
      });

      test.it('can return object literals', function() {
        execute('return {a: 1, b: false, c: null}').then(function(result) {
          verifyJson(['a', 'b', 'c'])(Object.keys(result).sort());
          assert(result.a).equalTo(1);
          assert(result.b).equalTo(false);
          assert(result.c).isNull();
        });
      });

      test.it('can return complex object literals', function() {
        execute('return {a:{b: "hello"}}').then(verifyJson({a:{b: 'hello'}}));
      });

      test.it('can return dom elements as web elements', function() {
        execute('return document.querySelector(".header.host")')
            .then(function(result) {
              assert(result).instanceOf(webdriver.WebElement);
              assert(result.getText()).startsWith('host: ');
            });
      });

      test.it('can return array of dom elements', function() {
        execute('var nodes = document.querySelectorAll(".request,.host");' +
                'return [nodes[0], nodes[1]];')
            .then(function(result) {
              assert(result.length).equalTo(2);

              assert(result[0]).instanceOf(webdriver.WebElement);
              assert(result[0].getText()).startsWith('GET ');

              assert(result[1]).instanceOf(webdriver.WebElement);
              assert(result[1].getText()).startsWith('host: ');
            });
      });

      test.it('can return a NodeList as an array of web elements', function() {
        execute('return document.querySelectorAll(".request,.host");')
            .then(function(result) {
              assert(result.length).equalTo(2);

              assert(result[0]).instanceOf(webdriver.WebElement);
              assert(result[0].getText()).startsWith('GET ');

              assert(result[1]).instanceOf(webdriver.WebElement);
              assert(result[1].getText()).startsWith('host: ');
            });
      });

      test.it('can return object literal with element property', function() {
        execute('return {a: document.body}').then(function(result) {
          assert(result.a).instanceOf(webdriver.WebElement);
          assert(result.a.getTagName()).equalTo('body');
        });
      });
    });

    describe('parameters;', function() {
      test.it('can pass numeric arguments', function() {
        assert(execute('return arguments[0]', 12)).equalTo(12);
        assert(execute('return arguments[0]', 3.14)).equalTo(3.14);
      });

      test.it('can pass boolean arguments', function() {
        assert(execute('return arguments[0]', true)).equalTo(true);
        assert(execute('return arguments[0]', false)).equalTo(false);
      });

      test.it('can pass string arguments', function() {
        assert(execute('return arguments[0]', 'hi')).equalTo('hi');
      });

      test.it('can pass null arguments', function() {
        assert(execute('return arguments[0] === null', null)).equalTo(true);
        assert(execute('return arguments[0]', null)).equalTo(null);
      });

      test.it('passes undefined as a null argument', function() {
        var x;
        assert(execute('return arguments[0] === null', x)).equalTo(true);
        assert(execute('return arguments[0]', x)).equalTo(null);
      });

      test.it('can pass multiple arguments', function() {
        assert(execute('return arguments.length')).equalTo(0);
        assert(execute('return arguments.length', 1, 'a', false)).equalTo(3);
      });

      test.ignore(env.browsers(Browser.FIREFOX)).
      it('can return arguments object as array', function() {
        execute('return arguments', 1, 'a', false).then(function(val) {
          assert(val.length).equalTo(3);
          assert(val[0]).equalTo(1);
          assert(val[1]).equalTo('a');
          assert(val[2]).equalTo(false);
        });
      });

      test.it('can pass object literal', function() {
        execute(
            'return [typeof arguments[0], arguments[0].a]', {a: 'hello'})
            .then(function(result) {
              assert(result[0]).equalTo('object');
              assert(result[1]).equalTo('hello');
            });
      });

      test.it('WebElement arguments are passed as DOM elements', function() {
        var el = driver.findElement(By.tagName('div'));
        assert(execute('return arguments[0].tagName.toLowerCase();', el))
            .equalTo('div');
      });

      test.it('can pass array containing object literals', function() {
        execute('return arguments[0]', [{color: "red"}]).then(function(result) {
          assert(result.length).equalTo(1);
          assert(result[0].color).equalTo('red');
        });
      });

      test.it('does not modify object literal parameters', function() {
        var input = {color: 'red'};
        execute('return arguments[0];', input).then(verifyJson(input));
      });
    });

    // See https://code.google.com/p/selenium/issues/detail?id=8223.
    describe('issue 8223;', function() {
      describe('using for..in loops;', function() {
        test.it('can return array built from for-loop index', function() {
          execute(function() {
            var ret = [];
            for (var i = 0; i < 3; i++) {
              ret.push(i);
            }
            return ret;
          }).then(verifyJson[0, 1, 2]);
        });

        test.it('can copy input array contents', function() {
          execute(function(input) {
            var ret = [];
            for (var i in input) {
              ret.push(input[i]);
            }
            return ret;
          }, ['fa', 'fe', 'fi']).then(verifyJson(['fa', 'fe', 'fi']));
        });

        test.it('can iterate over input object keys', function() {
          execute(function(thing) {
            var ret = [];
            for (var w in thing.words) {
              ret.push(thing.words[w].word);
            }
            return ret;
          }, {words: [{word: 'fa'}, {word: 'fe'}, {word: 'fi'}]})
          .then(verifyJson(['fa', 'fe', 'fi']));
        });

        describe('recursive functions;', function() {
          test.it('can build array from input', function() {
            var input = ['fa', 'fe', 'fi'];
            execute(function(thearray) {
              var ret = [];
              function build_response(thearray, ret) {
                ret.push(thearray.shift());
                return (!thearray.length && ret
                    || build_response(thearray, ret));
              }
              return build_response(thearray, ret);
            }, input).then(verifyJson(input));
          });

          test.it('can build array from elements in object', function() {
            var input = {words: [{word: 'fa'}, {word: 'fe'}, {word: 'fi'}]};
            execute(function(thing) {
              var ret = [];
              function build_response(thing, ret) {
                var item = thing.words.shift();
                ret.push(item.word);
                return (!thing.words.length && ret
                    || build_response(thing, ret));
              }
              return build_response(thing, ret);
            }, input).then(verifyJson(['fa', 'fe', 'fi']));
          });
        });
      });
    });

    describe('async timeouts', function() {
      var TIMEOUT_IN_MS = 200;
      var ACCEPTABLE_WAIT = TIMEOUT_IN_MS / 10;
      var TOO_LONG_WAIT = TIMEOUT_IN_MS * 10;

      before(function() {
        return driver.manage().timeouts().setScriptTimeout(TIMEOUT_IN_MS)
      });

      test.it('does not fail if script execute in time', function() {
        return executeTimeOutScript(ACCEPTABLE_WAIT);
      });

      test.it('fails if script took too long', function() {
        return executeTimeOutScript(TOO_LONG_WAIT)
          .then(function() {
            fail('it should have timed out');
          }).catch(function(e) {
            assert(e.name).equalTo('ScriptTimeoutError');
          });
      });

      function executeTimeOutScript(sleepTime) {
        return driver.executeAsyncScript(function(sleepTime) {
          var callback = arguments[arguments.length - 1];
          setTimeout(callback, sleepTime)
        }, sleepTime);
      }
    })
  });

  function verifyJson(expected) {
    return function(actual) {
      assert(JSON.stringify(actual)).equalTo(JSON.stringify(expected));
    };
  }

  function execute() {
    return driver.executeScript.apply(driver, arguments);
  }
});
<commit_msg>test: skip execute timeout spec<commit_after>// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

'use strict';

var path = require('path');
var fail = require('assert').fail;

var webdriver = require('..'),
    Browser = webdriver.Browser,
    By = webdriver.By,
    assert = require('../testing/assert'),
    test = require('../lib/test');

test.suite(function(env) {
  var driver;

  test.before(function() {
    driver = env.builder().build();
  });

  test.after(function() {
    driver.quit();
  });

  test.beforeEach(function() {
    driver.get(test.Pages.echoPage);
  });

  describe('executeScript;', function() {
    var shouldHaveFailed = new Error('Should have failed');

    test.it('fails if script throws', function() {
      execute('throw new Error("boom")')
          .then(function() { throw shouldHaveFailed; })
          .catch(function(e) {
            // The java WebDriver server adds a bunch of crap to error messages.
            // Error message will just be "JavaScript error" for IE.
            assert(e.message).matches(/.*(JavaScript error|boom).*/);
          });
    });

    test.it('fails if script does not parse', function() {
      execute('throw function\\*')
          .then(function() { throw shouldHaveFailed; })
          .catch(function(e) {
            assert(e).notEqualTo(shouldHaveFailed);
          });
    });

    describe('scripts;', function() {
      test.it('do not pollute the global scope', function() {
        execute('var x = 1;');
        assert(execute('return typeof x;')).equalTo('undefined');
      });

      test.it('can set global variables', function() {
        execute('window.x = 1234;');
        assert(execute('return x;')).equalTo(1234);
      });

      test.it('may be defined as a function expression', function() {
        assert(execute(function() {
          return 1234 + 'abc';
        })).equalTo('1234abc');
      });
    });

    describe('return values;', function() {

      test.it('returns undefined as null', function() {
        assert(execute('var x; return x;')).isNull();
      });

      test.it('can return null', function() {
        assert(execute('return null;')).isNull();
      });

      test.it('can return numbers', function() {
        assert(execute('return 1234')).equalTo(1234);
        assert(execute('return 3.1456')).equalTo(3.1456);
      });

      test.it('can return strings', function() {
        assert(execute('return "hello"')).equalTo('hello');
      });

      test.it('can return booleans', function() {
        assert(execute('return true')).equalTo(true);
        assert(execute('return false')).equalTo(false);
      });

      test.it('can return an array of primitives', function() {
        execute('var x; return [1, false, null, 3.14, x]')
            .then(verifyJson([1, false, null, 3.14, null]));
      });

      test.it('can return nested arrays', function() {
        execute('return [[1, 2, [3]]]')
            .then(verifyJson([[1, 2, [3]]]));
      });

      test.ignore(env.browsers(Browser.IE, Browser.SAFARI)).
      it('can return empty object literal', function() {
        execute('return {}').then(verifyJson({}));
      });

      test.it('can return object literals', function() {
        execute('return {a: 1, b: false, c: null}').then(function(result) {
          verifyJson(['a', 'b', 'c'])(Object.keys(result).sort());
          assert(result.a).equalTo(1);
          assert(result.b).equalTo(false);
          assert(result.c).isNull();
        });
      });

      test.it('can return complex object literals', function() {
        execute('return {a:{b: "hello"}}').then(verifyJson({a:{b: 'hello'}}));
      });

      test.it('can return dom elements as web elements', function() {
        execute('return document.querySelector(".header.host")')
            .then(function(result) {
              assert(result).instanceOf(webdriver.WebElement);
              assert(result.getText()).startsWith('host: ');
            });
      });

      test.it('can return array of dom elements', function() {
        execute('var nodes = document.querySelectorAll(".request,.host");' +
                'return [nodes[0], nodes[1]];')
            .then(function(result) {
              assert(result.length).equalTo(2);

              assert(result[0]).instanceOf(webdriver.WebElement);
              assert(result[0].getText()).startsWith('GET ');

              assert(result[1]).instanceOf(webdriver.WebElement);
              assert(result[1].getText()).startsWith('host: ');
            });
      });

      test.it('can return a NodeList as an array of web elements', function() {
        execute('return document.querySelectorAll(".request,.host");')
            .then(function(result) {
              assert(result.length).equalTo(2);

              assert(result[0]).instanceOf(webdriver.WebElement);
              assert(result[0].getText()).startsWith('GET ');

              assert(result[1]).instanceOf(webdriver.WebElement);
              assert(result[1].getText()).startsWith('host: ');
            });
      });

      test.it('can return object literal with element property', function() {
        execute('return {a: document.body}').then(function(result) {
          assert(result.a).instanceOf(webdriver.WebElement);
          assert(result.a.getTagName()).equalTo('body');
        });
      });
    });

    describe('parameters;', function() {
      test.it('can pass numeric arguments', function() {
        assert(execute('return arguments[0]', 12)).equalTo(12);
        assert(execute('return arguments[0]', 3.14)).equalTo(3.14);
      });

      test.it('can pass boolean arguments', function() {
        assert(execute('return arguments[0]', true)).equalTo(true);
        assert(execute('return arguments[0]', false)).equalTo(false);
      });

      test.it('can pass string arguments', function() {
        assert(execute('return arguments[0]', 'hi')).equalTo('hi');
      });

      test.it('can pass null arguments', function() {
        assert(execute('return arguments[0] === null', null)).equalTo(true);
        assert(execute('return arguments[0]', null)).equalTo(null);
      });

      test.it('passes undefined as a null argument', function() {
        var x;
        assert(execute('return arguments[0] === null', x)).equalTo(true);
        assert(execute('return arguments[0]', x)).equalTo(null);
      });

      test.it('can pass multiple arguments', function() {
        assert(execute('return arguments.length')).equalTo(0);
        assert(execute('return arguments.length', 1, 'a', false)).equalTo(3);
      });

      test.ignore(env.browsers(Browser.FIREFOX)).
      it('can return arguments object as array', function() {
        execute('return arguments', 1, 'a', false).then(function(val) {
          assert(val.length).equalTo(3);
          assert(val[0]).equalTo(1);
          assert(val[1]).equalTo('a');
          assert(val[2]).equalTo(false);
        });
      });

      test.it('can pass object literal', function() {
        execute(
            'return [typeof arguments[0], arguments[0].a]', {a: 'hello'})
            .then(function(result) {
              assert(result[0]).equalTo('object');
              assert(result[1]).equalTo('hello');
            });
      });

      test.it('WebElement arguments are passed as DOM elements', function() {
        var el = driver.findElement(By.tagName('div'));
        assert(execute('return arguments[0].tagName.toLowerCase();', el))
            .equalTo('div');
      });

      test.it('can pass array containing object literals', function() {
        execute('return arguments[0]', [{color: "red"}]).then(function(result) {
          assert(result.length).equalTo(1);
          assert(result[0].color).equalTo('red');
        });
      });

      test.it('does not modify object literal parameters', function() {
        var input = {color: 'red'};
        execute('return arguments[0];', input).then(verifyJson(input));
      });
    });

    // See https://code.google.com/p/selenium/issues/detail?id=8223.
    describe('issue 8223;', function() {
      describe('using for..in loops;', function() {
        test.it('can return array built from for-loop index', function() {
          execute(function() {
            var ret = [];
            for (var i = 0; i < 3; i++) {
              ret.push(i);
            }
            return ret;
          }).then(verifyJson[0, 1, 2]);
        });

        test.it('can copy input array contents', function() {
          execute(function(input) {
            var ret = [];
            for (var i in input) {
              ret.push(input[i]);
            }
            return ret;
          }, ['fa', 'fe', 'fi']).then(verifyJson(['fa', 'fe', 'fi']));
        });

        test.it('can iterate over input object keys', function() {
          execute(function(thing) {
            var ret = [];
            for (var w in thing.words) {
              ret.push(thing.words[w].word);
            }
            return ret;
          }, {words: [{word: 'fa'}, {word: 'fe'}, {word: 'fi'}]})
          .then(verifyJson(['fa', 'fe', 'fi']));
        });

        describe('recursive functions;', function() {
          test.it('can build array from input', function() {
            var input = ['fa', 'fe', 'fi'];
            execute(function(thearray) {
              var ret = [];
              function build_response(thearray, ret) {
                ret.push(thearray.shift());
                return (!thearray.length && ret
                    || build_response(thearray, ret));
              }
              return build_response(thearray, ret);
            }, input).then(verifyJson(input));
          });

          test.it('can build array from elements in object', function() {
            var input = {words: [{word: 'fa'}, {word: 'fe'}, {word: 'fi'}]};
            execute(function(thing) {
              var ret = [];
              function build_response(thing, ret) {
                var item = thing.words.shift();
                ret.push(item.word);
                return (!thing.words.length && ret
                    || build_response(thing, ret));
              }
              return build_response(thing, ret);
            }, input).then(verifyJson(['fa', 'fe', 'fi']));
          });
        });
      });
    });

    describe('async timeouts', function() {
      var TIMEOUT_IN_MS = 200;
      var ACCEPTABLE_WAIT = TIMEOUT_IN_MS / 10;
      var TOO_LONG_WAIT = TIMEOUT_IN_MS * 10;

      before(function() {
        return driver.manage().timeouts().setScriptTimeout(TIMEOUT_IN_MS)
      });

      test.it('does not fail if script execute in time', function() {
        return executeTimeOutScript(ACCEPTABLE_WAIT);
      });

      test.it.skip('fails if script took too long', function() {
        return executeTimeOutScript(TOO_LONG_WAIT)
          .then(function() {
            fail('it should have timed out');
          }).catch(function(e) {
            assert(e.name).equalTo('ScriptTimeoutError');
          });
      });

      function executeTimeOutScript(sleepTime) {
        return driver.executeAsyncScript(function(sleepTime) {
          var callback = arguments[arguments.length - 1];
          setTimeout(callback, sleepTime)
        }, sleepTime);
      }
    })
  });

  function verifyJson(expected) {
    return function(actual) {
      assert(JSON.stringify(actual)).equalTo(JSON.stringify(expected));
    };
  }

  function execute() {
    return driver.executeScript.apply(driver, arguments);
  }
});
<|endoftext|>


<commit_before>'use strict';

// Issue #419
var ThaliMobile = require('thali/NextGeneration/thaliMobile');
var platform = require('thali/NextGeneration/utils/platform');
var nodeUuid = require('node-uuid');
var net = require('net');
var thaliMobileNativeTestUtils = require('../lib/thaliMobileNativeTestUtils');
var makeIntoCloseAllServer = require('thali/NextGeneration/makeIntoCloseAllServer');
var thaliMobileNativeWrapper =
  require('thali/NextGeneration/thaliMobileNativeWrapper');
var logger = require('../lib/testLogger')('testThaliMobileNativeiOS');
var Promise = require('lie');
if (global.NETWORK_TYPE === ThaliMobile.networkTypes.WIFI ||
    !platform.isIOS) {
  return;
}

var randomString = require('randomstring');
var tape = require('../lib/thaliTape');
var uuid = require('node-uuid');
var peerIdsToBeClosed = [];

// jshint -W064

// A variable that can be used to store a server
// that will get closed in teardown.
var serverToBeClosed = null;

var test = tape({
  setup: function (t) {
    thaliMobileNativeWrapper._registerToNative();
    serverToBeClosed = {
      closeAll: function (callback) {
        callback();
      }
    };
    t.end();
  },
  teardown: function (t) {
    thaliMobileNativeTestUtils.multiConnectEmitter.removeAllListeners();
    serverToBeClosed.closeAll(function () {
      Mobile('stopListeningForAdvertisements').callNative(function (err) {
        t.notOk(
          err,
          'Should be able to call stopListeningForAdvertisements in teardown'
        );
        Mobile('stopAdvertisingAndListening').callNative(function (err) {
          t.notOk(
            err,
            'Should be able to call stopAdvertisingAndListening in teardown'
          );
          Promise.resolve()
            .then(function () {
              if (!platform.isAndroid) {
                return thaliMobileNativeTestUtils.killAllMultiConnectConnections(peerIdsToBeClosed);
              }
            })
            .catch(function (err) {
              t.fail(err);
            })
            .then(function () {
              peerIdsToBeClosed = [];
              t.end();
            });
        });
      });
    });
  }
});

test('cannot call multiConnect when start listening for advertisements is ' +
  'not active', function (t) {
  var connectReturned = false;
  var originalSyncValue = randomString.generate();
  thaliMobileNativeTestUtils.multiConnectEmitter
    .on('multiConnectResolved', function (syncValue, error, listeningPort) {
      t.ok(connectReturned, 'Should only get called after multiConnect ' +
        'returned');
      t.equal(originalSyncValue, syncValue, 'SyncValue matches');
      t.equal(error, 'startListeningForAdvertisements is not active',
        'Got right error');
      t.equal(listeningPort, null, 'listeningPort is null');
      t.end();
    });
  var peerId = nodeUuid.v4();
  Mobile('multiConnect').callNative(peerId, originalSyncValue, function (err) {
    t.equal(err, null, 'Got null as expected');
    connectReturned = true;
  });
});

test('cannot call multiConnect with illegal peerID', function (t) {
  var connectReturned = false;
  var originalSyncValue = randomString.generate();
  thaliMobileNativeTestUtils.multiConnectEmitter
    .on('multiConnectResolved', function (syncValue, error, listeningPort) {
      t.ok(connectReturned, 'Should only get called after multiConnect ' +
        'returned');
      t.equal(originalSyncValue, syncValue, 'SyncValue matches');
      t.equal(error, 'Illegal peerID',
        'Got right error');
      t.notOk(listeningPort, 'listeningPort is null');
      t.end();
    });
  Mobile('startListeningForAdvertisements').callNative(function (err) {
    t.notOk(err, 'No error on starting');
    Mobile('multiConnect').callNative('foo', originalSyncValue, function (err) {
      t.notOk(err, 'Got null as expected');
      connectReturned = true;
    });
  });
});

test('multiConnect properly fails on legal but non-existent peerID',
  function (t) {
    var connectReturned = false;
    var originalSyncValue = randomString.generate();
    thaliMobileNativeTestUtils.multiConnectEmitter
      .on('multiConnectResolved', function (syncValue, error, listeningPort) {
        t.ok(connectReturned, 'Should only get called after multiConnect ' +
        'returned');
        t.equal(originalSyncValue, syncValue, 'SyncValue matches');
        t.equal(error, 'Connection could not be established',
          'Got right error');
        t.notOk(listeningPort, 'listeningPort is null');
        t.end();
      });
    Mobile('startListeningForAdvertisements').callNative(function (err) {
      t.notOk(err, 'No error on starting');
      var peerId = nodeUuid.v4();
      Mobile('multiConnect').callNative(peerId, originalSyncValue,
        function (err) {
          t.notOk(err, 'Got null as expected');
          connectReturned = true;
        });
    });
  });

test('cannot call multiConnect with invalid syncValue',
  function (t) {
    var invalidSyncValue = /I am not a string/;
    Mobile('startListeningForAdvertisements').callNative(function (err) {
      t.notOk(err, 'No error on starting');
      var peerId = nodeUuid.v4();
      Mobile('multiConnect').callNative(peerId, invalidSyncValue,
        function (error) {
          t.equal(error, 'Bad parameters', 'Got right error');
          t.end();
        });
    });
  });

test('cannot call disconnect with invalid peer id', function (t) {
  Mobile('disconnect').callNative('foo', function (error) {
      t.equal(error, 'Bad parameters', 'Got right error');
      t.end();
    });
});

test('disconnect doesn\'t fail on plausible but bogus peer ID', function (t) {
  var peerId = nodeUuid.v4();
  Mobile('disconnect').callNative(peerId, function(err) {
    t.notOk(err, 'No error');
    // Giving failure callback a chance to mess things up
    setImmediate(function () {
      t.end();
    });
  });
  thaliMobileNativeTestUtils.multiConnectEmitter
    .on('multiConnectConnectionFailure', function (peerIdentifier, error) {
    t.fail('We shouldn\'t get a failure callback - peerID: ' +
      peerIdentifier + ', error: ' + error);
    });
});

if (!tape.coordinated) {
  return;
}

function reConnect(t, peerIdentifier, originalListeningPort) {
  return new Promise(function (resolve) {
    var originalSyncValue = randomString.generate();

    thaliMobileNativeTestUtils.multiConnectEmitter.on('multiConnectResolved',
      function (syncValue, error, listeningPort) {
        if (syncValue === originalSyncValue) {
          t.notOk(error, 'No error');
          t.equal(listeningPort, originalListeningPort, 'Ports equal');
          resolve(null);
        }
      });

    Mobile('multiConnect').callNative(peerIdentifier, originalSyncValue,
      function (err) {
        t.notOk(err, 'Got null as expected');
      });
  });
}

test('Get same port when trying to connect multiple times on iOS',
  function (t) {
    var server = net.createServer(function (socket) {
      socket.pipe(socket);
    });
    server = makeIntoCloseAllServer(server);
    serverToBeClosed = server;

    thaliMobileNativeTestUtils.executeZombieProofTest(t, server,
      function (currentConnection, currentTestPeer) {
        peerIdsToBeClosed.push(currentTestPeer.peerIdentifier);
        var listeningPort = currentConnection.listeningPort;
        var connection = net.connect(listeningPort,
          function () {
            // We aren't allowed to have multiple simultaneous outstanding
            // calls to the same peerID on iOS for multiConnect (or
            // disconnect) so we have to serialize.
            reConnect(t, currentTestPeer.peerIdentifier, listeningPort)
              .then(function () {
                return reConnect(t, currentTestPeer.peerIdentifier,
                  listeningPort);
              })
              .then(function () {
                t.end();
              });
          });
        connection.on('error', function (err) {
          t.fail('lost connection because of ' + err);
          t.end();
        });
      }
    );
  });
<commit_msg>Fix testThaliMobileNativeiOS test<commit_after>'use strict';

// Issue #419
var ThaliMobile = require('thali/NextGeneration/thaliMobile');
var platform = require('thali/NextGeneration/utils/platform');
var nodeUuid = require('node-uuid');
var net = require('net');
var thaliMobileNativeTestUtils = require('../lib/thaliMobileNativeTestUtils');
var makeIntoCloseAllServer = require('thali/NextGeneration/makeIntoCloseAllServer');
var thaliMobileNativeWrapper =
  require('thali/NextGeneration/thaliMobileNativeWrapper');
var logger = require('../lib/testLogger')('testThaliMobileNativeiOS');
var Promise = require('lie');
if (global.NETWORK_TYPE === ThaliMobile.networkTypes.WIFI ||
    !platform.isIOS) {
  return;
}

var randomString = require('randomstring');
var tape = require('../lib/thaliTape');
var uuid = require('node-uuid');
var peerIdsToBeClosed = [];

// jshint -W064

// A variable that can be used to store a server
// that will get closed in teardown.
var serverToBeClosed = null;

var test = tape({
  setup: function (t) {
    thaliMobileNativeWrapper._registerToNative();
    serverToBeClosed = {
      closeAll: function (callback) {
        callback();
      }
    };
    t.end();
  },
  teardown: function (t) {
    thaliMobileNativeTestUtils.multiConnectEmitter.removeAllListeners();
    serverToBeClosed.closeAll(function () {
      Mobile('stopListeningForAdvertisements').callNative(function (err) {
        t.notOk(
          err,
          'Should be able to call stopListeningForAdvertisements in teardown'
        );
        Mobile('stopAdvertisingAndListening').callNative(function (err) {
          t.notOk(
            err,
            'Should be able to call stopAdvertisingAndListening in teardown'
          );
          Promise.resolve()
            .then(function () {
              if (!platform.isAndroid) {
                return thaliMobileNativeTestUtils.killAllMultiConnectConnections(peerIdsToBeClosed);
              }
            })
            .catch(function (err) {
              t.fail(err);
            })
            .then(function () {
              peerIdsToBeClosed = [];
              t.end();
            });
        });
      });
    });
  }
});

test('cannot call multiConnect when start listening for advertisements is ' +
  'not active', function (t) {
  var connectReturned = false;
  var originalSyncValue = randomString.generate();
  thaliMobileNativeTestUtils.multiConnectEmitter
    .on('multiConnectResolved', function (syncValue, error, listeningPort) {
      t.ok(connectReturned, 'Should only get called after multiConnect ' +
        'returned');
      t.equal(originalSyncValue, syncValue, 'SyncValue matches');
      t.equal(error, 'startListeningForAdvertisements is not active',
        'Got right error');
      t.equal(listeningPort, null, 'listeningPort is null');
      t.end();
    });
  var peerId = nodeUuid.v4();
  Mobile('multiConnect').callNative(peerId, originalSyncValue, function (err) {
    t.equal(err, null, 'Got null as expected');
    connectReturned = true;
  });
});

test('cannot call multiConnect with illegal peerID', function (t) {
  var connectReturned = false;
  var originalSyncValue = randomString.generate();
  thaliMobileNativeTestUtils.multiConnectEmitter
    .on('multiConnectResolved', function (syncValue, error, listeningPort) {
      t.ok(connectReturned, 'Should only get called after multiConnect ' +
        'returned');
      t.equal(originalSyncValue, syncValue, 'SyncValue matches');
      t.equal(error, 'Illegal peerID',
        'Got right error');
      t.notOk(listeningPort, 'listeningPort is null');
      t.end();
    });
  Mobile('startListeningForAdvertisements').callNative(function (err) {
    t.notOk(err, 'No error on starting');
    Mobile('multiConnect').callNative('foo', originalSyncValue, function (err) {
      t.notOk(err, 'Got null as expected');
      connectReturned = true;
    });
  });
});

test('multiConnect properly fails on legal but non-existent peerID',
  function (t) {
    var connectReturned = false;
    var originalSyncValue = randomString.generate();
    thaliMobileNativeTestUtils.multiConnectEmitter
      .on('multiConnectResolved', function (syncValue, error, listeningPort) {
        t.ok(connectReturned, 'Should only get called after multiConnect ' +
        'returned');
        t.equal(originalSyncValue, syncValue, 'SyncValue matches');
        t.equal(error, 'Connection could not be established',
          'Got right error');
        t.notOk(listeningPort, 'listeningPort is null');
        t.end();
      });
    Mobile('startListeningForAdvertisements').callNative(function (err) {
      t.notOk(err, 'No error on starting');
      var peerId = nodeUuid.v4();
      Mobile('multiConnect').callNative(peerId, originalSyncValue,
        function (err) {
          t.notOk(err, 'Got null as expected');
          connectReturned = true;
        });
    });
  });

test('cannot call multiConnect with invalid syncValue',
  function (t) {
    var invalidSyncValue = /I am not a string/;
    Mobile('startListeningForAdvertisements').callNative(function (err) {
      t.notOk(err, 'No error on starting');
      var peerId = nodeUuid.v4();
      Mobile('multiConnect').callNative(peerId, invalidSyncValue,
        function (error) {
          t.equal(error, 'Bad parameters', 'Got right error');
          t.end();
        });
    });
  });

test('cannot call disconnect with invalid peer id', function (t) {
  Mobile('disconnect').callNative('foo', function (error) {
      t.equal(error, 'Bad parameters', 'Got right error');
      t.end();
    });
});

test('disconnect doesn\'t fail on plausible but bogus peer ID', function (t) {
  var peerId = nodeUuid.v4();
  Mobile('disconnect').callNative(peerId, function(err) {
    t.notOk(err, 'No error');
    // Giving failure callback a chance to mess things up
    setImmediate(function () {
      t.end();
    });
  });
  thaliMobileNativeTestUtils.multiConnectEmitter
    .on('multiConnectConnectionFailure', function (peerIdentifier, error) {
    t.fail('We shouldn\'t get a failure callback - peerID: ' +
      peerIdentifier + ', error: ' + error);
    });
});

if (!tape.coordinated) {
  return;
}

function reConnect(t, peerIdentifier, originalListeningPort) {
  return new Promise(function (resolve) {
    var originalSyncValue = randomString.generate();

    thaliMobileNativeTestUtils.multiConnectEmitter.on('multiConnectResolved',
      function (syncValue, error, listeningPort) {
        if (syncValue === originalSyncValue) {
          t.notOk(error, 'No error');
          t.equal(listeningPort, originalListeningPort, 'Ports equal');
          resolve(null);
        }
      });

    Mobile('multiConnect').callNative(peerIdentifier, originalSyncValue,
      function (err) {
        t.notOk(err, 'Got null as expected');
      });
  });
}

test('Get same port when trying to connect multiple times on iOS',
  function (t) {
    var server = net.createServer(function (socket) {
      socket.pipe(socket);
    });
    server = makeIntoCloseAllServer(server);
    serverToBeClosed = server;

    thaliMobileNativeTestUtils.executeZombieProofTest(t, server,
      function (currentConnection, currentTestPeer) {
        return new Promise(function (resolve, reject) {
          peerIdsToBeClosed.push(currentTestPeer.peerIdentifier);
          var listeningPort = currentConnection.listeningPort;
          var connection = net.connect(listeningPort,
            function () {
              // We aren't allowed to have multiple simultaneous outstanding
              // calls to the same peerID on iOS for multiConnect (or
              // disconnect) so we have to serialize.
              reConnect(t, currentTestPeer.peerIdentifier, listeningPort)
                .then(function () {
                  return reConnect(t, currentTestPeer.peerIdentifier,
                    listeningPort);
                })
                .then(function () {
                  resolve();
                });
            });
          connection.on('error', function (err) {
            t.fail('lost connection because of ' + err);
            reject();
          });
        });
      }
    );
  });

<|endoftext|>


<commit_before>/*
 eslint-disable prefer-arrow-callback,
 func-names,
 space-before-function-paren,
 no-unused-expressions
*/
import { expect } from 'chai';
import handlePolling from '../handlePolling';
import fetchMock from 'fetch-mock';
import pluginApp from '../reducers';
import { createStore } from 'redux';
import {
  setPollingInterval,
  startPolling,
  stopPolling,
  updateWorkerState,
} from '../actions';

describe('handlePolling', function() {
  const pollUrl = 'http://example.com/work_available';

  describe('when polling is on', function() {
    const storeWithPolling = () => {
      const store = createStore(pluginApp);
      store.dispatch(setPollingInterval(1));
      store.dispatch(startPolling({ url: pollUrl }));
      store.dispatch(updateWorkerState('ready'));

      return store;
    };

    it('pings periodically', function(done) {
      const store = storeWithPolling();
      store.dispatch(setPollingInterval(1));

      let poller = null;

      let pingCounts = 0;
      fetchMock.get(pollUrl, url => {
        expect(url).to.equal(pollUrl);
        pingCounts++;
        if (pingCounts === 3) {
          poller.stop();
          fetchMock.restore();
          done();
        }
        return { work_available: false };
      });

      poller = handlePolling(store);
    });

    it("doesn't ping when the worker isn't ready", function(done) {
      const store = storeWithPolling();
      store.dispatch(updateWorkerState('inactive'));

      let poller = null;
      let fail = false;
      fetchMock.get(pollUrl, () => {
        poller.stop();
        fetchMock.restore();
        fail = true;
        done(new Error("Shouldn't have polled because worker wasn't ready!"));
      });

      poller = handlePolling(store);

      setTimeout(() => {
        if (!fail) {
          poller.stop();
          fetchMock.restore();
          done();
        }
      }, 10);
    });

    it('checks for CAPTCHAs', function(done) {
      const store = storeWithPolling();
      let poller = null;
      fetchMock.get(pollUrl, {
        status: 503,
        body: 'CAPTCHA nonsense!',
        headers: {
          'Content-Type': 'text/html',
        },
      });

      let success = false;
      store.subscribe(() => {
        const state = store.getState();
        if (state.polling.get('captchaRequired')) {
          success = true;
          fetchMock.restore();
          poller.stop();
          done();
        }
      });

      poller = handlePolling(store);

      setTimeout(() => {
        if (!success) {
          fetchMock.restore();
          poller.stop();
          done(new Error("CAPTCHA wasn't detected"));
        }
      }, 50);
    });

    it('assigns work when work is available', function(done) {
      const workUrl = 'http://work.com';
      const store = storeWithPolling();
      fetchMock.get(pollUrl, { work_available: true, url: workUrl });

      let poller = null;
      store.subscribe(() => {
        const { worker, polling } = store.getState();
        if (worker.get('state') === 'working') {
          expect(worker.get('workUrl')).to.equal(workUrl);
          expect(polling.get('polling')).to.be.false;
          poller.stop();
          fetchMock.restore();
          done();
        }
      });

      poller = handlePolling(store);
    });

    it("doesn't assign work if the worker isn't ready", function(done) {
      const workUrl = 'http://work.com';
      const store = storeWithPolling();
      fetchMock.get(pollUrl, () => {
        store.dispatch(updateWorkerState('inactive'));
        return { work_available: true, url: workUrl };
      });

      let err = false;
      store.subscribe(() => {
        const { worker } = store.getState();
        if (worker.get('error')) {
          err = true;
          done(worker.get('error'));
        }
      });

      handlePolling(store);

      setTimeout(() => {
        if (!err) {
          done();
        }
      }, 50);
    });
  });

  describe('when polling is off', function() {
    it("doesn't poll", function(done) {
      const store = createStore(pluginApp);
      store.dispatch(setPollingInterval(1));
      store.dispatch(updateWorkerState('ready'));
      store.dispatch(stopPolling());
      let fail = false;
      let poller = null;

      fetchMock.get(pollUrl, () => {
        poller.stop();
        fetchMock.restore();
        fail = true;

        done(new Error("Shouldn't have polled because polling is off!"));
      });

      poller = handlePolling(store);
      setTimeout(() => {
        if (!fail) {
          fetchMock.restore();
          poller.stop();
          done();
        }
      }, 10);
    });
  });
});
<commit_msg>update handling rate limit exceeded error<commit_after>/*
 eslint-disable prefer-arrow-callback,
 func-names,
 space-before-function-paren,
 no-unused-expressions
*/
import { expect } from 'chai';
import handlePolling from '../handlePolling';
import fetchMock from 'fetch-mock';
import pluginApp from '../reducers';
import { createStore } from 'redux';
import {
  setPollingInterval,
  startPolling,
  stopPolling,
  updateWorkerState,
} from '../actions';

describe('handlePolling', function() {
  const pollUrl = 'http://example.com/work_available';

  describe('when polling is on', function() {
    const storeWithPolling = () => {
      const store = createStore(pluginApp);
      store.dispatch(setPollingInterval(1));
      store.dispatch(startPolling({ url: pollUrl }));
      store.dispatch(updateWorkerState('ready'));

      return store;
    };

    it('pings periodically', function(done) {
      const store = storeWithPolling();
      store.dispatch(setPollingInterval(1));

      let poller = null;

      let pingCounts = 0;
      fetchMock.get(pollUrl, url => {
        expect(url).to.equal(pollUrl);
        pingCounts++;
        if (pingCounts === 3) {
          poller.stop();
          fetchMock.restore();
          done();
        }
        return { work_available: false };
      });

      poller = handlePolling(store);
    });

    it("doesn't ping when the worker isn't ready", function(done) {
      const store = storeWithPolling();
      store.dispatch(updateWorkerState('inactive'));

      let poller = null;
      let fail = false;
      fetchMock.get(pollUrl, () => {
        poller.stop();
        fetchMock.restore();
        fail = true;
        done(new Error("Shouldn't have polled because worker wasn't ready!"));
      });

      poller = handlePolling(store);

      setTimeout(() => {
        if (!fail) {
          poller.stop();
          fetchMock.restore();
          done();
        }
      }, 10);
    });

    it('checks for RATE_LIMIT_EXCEEDED', function(done) {
      const store = storeWithPolling();
      let poller = null;
      fetchMock.get(pollUrl, {
        status: 400,
        body: '{"error":"Too many requests"}',
        headers: {
          'Content-Type': 'application/json',
        },
      });

      let state = store.getState();
      const interval = state.polling.get('interval');

      let success = false;
      store.subscribe(() => {
        state = store.getState();
        if (state.polling.get('interval') > interval) {
          success = true;
          fetchMock.restore();
          poller.stop();
          done();
        }
      });

      poller = handlePolling(store);

      setTimeout(() => {
        if (!success) {
          fetchMock.restore();
          poller.stop();
          done(new Error("RATE_LIMIT_EXCEEDED wasn't detected"));
        }
      }, 50);
    });

    it('checks for CAPTCHAs', function(done) {
      const store = storeWithPolling();
      let poller = null;
      fetchMock.get(pollUrl, {
        status: 503,
        body: 'CAPTCHA nonsense!',
        headers: {
          'Content-Type': 'text/html',
        },
      });

      let success = false;
      store.subscribe(() => {
        const state = store.getState();
        if (state.polling.get('captchaRequired')) {
          success = true;
          fetchMock.restore();
          poller.stop();
          done();
        }
      });

      poller = handlePolling(store);

      setTimeout(() => {
        if (!success) {
          fetchMock.restore();
          poller.stop();
          done(new Error("CAPTCHA wasn't detected"));
        }
      }, 50);
    });

    it('assigns work when work is available', function(done) {
      const workUrl = 'http://work.com';
      const store = storeWithPolling();
      fetchMock.get(pollUrl, { work_available: true, url: workUrl });

      let poller = null;
      store.subscribe(() => {
        const { worker, polling } = store.getState();
        if (worker.get('state') === 'working') {
          expect(worker.get('workUrl')).to.equal(workUrl);
          expect(polling.get('polling')).to.be.false;
          poller.stop();
          fetchMock.restore();
          done();
        }
      });

      poller = handlePolling(store);
    });

    it("doesn't assign work if the worker isn't ready", function(done) {
      const workUrl = 'http://work.com';
      const store = storeWithPolling();
      fetchMock.get(pollUrl, () => {
        store.dispatch(updateWorkerState('inactive'));
        return { work_available: true, url: workUrl };
      });

      let err = false;
      store.subscribe(() => {
        const { worker } = store.getState();
        if (worker.get('error')) {
          err = true;
          done(worker.get('error'));
        }
      });

      handlePolling(store);

      setTimeout(() => {
        if (!err) {
          done();
        }
      }, 50);
    });
  });

  describe('when polling is off', function() {
    it("doesn't poll", function(done) {
      const store = createStore(pluginApp);
      store.dispatch(setPollingInterval(1));
      store.dispatch(updateWorkerState('ready'));
      store.dispatch(stopPolling());
      let fail = false;
      let poller = null;

      fetchMock.get(pollUrl, () => {
        poller.stop();
        fetchMock.restore();
        fail = true;

        done(new Error("Shouldn't have polled because polling is off!"));
      });

      poller = handlePolling(store);
      setTimeout(() => {
        if (!fail) {
          fetchMock.restore();
          poller.stop();
          done();
        }
      }, 10);
    });
  });
});
<|endoftext|>


<commit_before>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @author       samme <samme.npm@gmail.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Wrap = require('../math/Wrap');

/**
 * Wrap each item's coordinates within a rectangle's area.
 *
 * @function Phaser.Actions.WrapInRectangle
 * @since 3.0.0
 * @see Phaser.Math.Wrap
 *
 * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return]
 *
 * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action.
 * @param {Phaser.Geom.Rectangle} rect - The rectangle.
 * @param {number} [padding=0] - An amount added to each side of the rectangle during the operation.
 *
 * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action.
 */
var WrapInRectangle = function (items, rect, padding)
{
    if (padding === undefined)
    {
        padding = 0;
    }

    for (var i = 0; i < items.length; i++)
    {
        var item = items[i];

        item.x = Wrap(item.x, rect.left - padding, rect.right + padding);
        item.y = Wrap(item.y, rect.top - padding, rect.bottom + padding);
    }

    return items;
};

module.exports = WrapInRectangle;
<commit_msg>Updated docs<commit_after>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @author       samme <samme.npm@gmail.com>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Wrap = require('../math/Wrap');

/**
 * Iterates through the given array and makes sure that each objects x and y
 * properties are wrapped to keep them contained within the given Rectangles
 * area.
 *
 * @function Phaser.Actions.WrapInRectangle
 * @since 3.0.0
 * @see Phaser.Math.Wrap
 *
 * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return]
 *
 * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action.
 * @param {Phaser.Geom.Rectangle} rect - The rectangle which the objects will be wrapped to remain within.
 * @param {number} [padding=0] - An amount added to each side of the rectangle during the operation.
 *
 * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action.
 */
var WrapInRectangle = function (items, rect, padding)
{
    if (padding === undefined)
    {
        padding = 0;
    }

    for (var i = 0; i < items.length; i++)
    {
        var item = items[i];

        item.x = Wrap(item.x, rect.left - padding, rect.right + padding);
        item.y = Wrap(item.y, rect.top - padding, rect.bottom + padding);
    }

    return items;
};

module.exports = WrapInRectangle;
<|endoftext|>


<commit_before>'use strict';
if (!process.env.LEVEL_ADAPTER &&
    !process.env.LEVEL_PREFIX &&
    !process.env.AUTO_COMPACTION &&
    !process.env.ADAPTER) {
  // these tests don't make sense for anything other than default leveldown
  var path = require('path');
  var mkdirp = require('mkdirp');
  var rimraf = require('rimraf');

  describe('defaults', function () {

    beforeEach(function () {
      return new PouchDB('mydb').destroy().then(function () {
        return new PouchDB('mydb', {db: require('memdown')}).destroy();
      });
    });

    afterEach(function (done) {
      rimraf.sync('./tmp/_pouch_.');
      rimraf.sync('./tmp/path');
      done();
    });

    it('should allow prefixes', function () {
      var prefix = './tmp/path/to/db/1/';
      var dir = path.join(prefix, '/tmp/');
      var dir2 = path.join('./tmp/_pouch_./', prefix);
      var dir3 = path.join(dir2, './tmp/_pouch_mydb');
      mkdirp.sync(dir);
      mkdirp.sync(dir2);
      mkdirp.sync(dir3);

      return new PouchDB('mydb', {
        prefix: prefix
      }).then(function (db) {
        return db.info().then(function (info1) {
          info1.db_name.should.equal('mydb');
          return db.destroy();
        });
      });
    });

    it('Defaults leaks eventEmitters', function () {
      PouchDB.defaults({db: require('memdown') });
      PouchDB.defaults({db: require('memdown') });
      PouchDB.defaults({db: require('memdown') });
      PouchDB.defaults({db: require('memdown') });
    });

    it('should allow us to set a prefix by default', function () {
      var prefix = './tmp/path/to/db/2/';
      var dir = path.join(prefix, '/tmp/');
      var dir2 = path.join('./tmp/_pouch_./', prefix);
      var dir3 = path.join(dir2, './tmp/_pouch_mydb');
      mkdirp.sync(dir);
      mkdirp.sync(dir2);
      mkdirp.sync(dir3);

      var CustomPouch = PouchDB.defaults({
        prefix: prefix
      });
      /* jshint newcap:false */
      var db = CustomPouch({name: 'mydb'});
      return db.info().then(function (info1) {
        info1.db_name.should.equal('mydb');
        return db.destroy();
      });
    });

    it('should allow us to use memdown', function () {
      var opts = { name: 'mydb', db: require('memdown') };
      return new PouchDB(opts).then(function (db) {
        return db.put({_id: 'foo'}).then(function () {
          return new PouchDB('mydb').then(function (otherDB) {
            return db.info().then(function (info1) {
              return otherDB.info().then(function (info2) {
                info1.doc_count.should.not.equal(info2.doc_count);
                return otherDB.destroy();
              }).then(function () {
                return db.destroy();
              });
            });
          });
        });
      });
    });

    it('should allow us to destroy memdown', function () {
      var opts = {db: require('memdown') };
      return new PouchDB('mydb', opts).then(function (db) {
        return db.put({_id: 'foo'}).then(function () {
          return new PouchDB('mydb', opts).then(function (otherDB) {
            return db.info().then(function (info1) {
              return otherDB.info().then(function (info2) {
                info1.doc_count.should.equal(info2.doc_count);
                return otherDB.destroy();
              }).then(function () {
                return new PouchDB('mydb', opts).then(function (db3) {
                  return db3.info().then(function (info) {
                    info.doc_count.should.equal(0);
                    return db3.destroy();
                  });
                });
              });
            });
          });
        });
      });
    });

    it('should allow us to use memdown by default', function () {
      var CustomPouch = PouchDB.defaults({db: require('memdown')});
      return new CustomPouch('mydb').then(function (db) {
        return db.put({_id: 'foo'}).then(function () {
          return new PouchDB('mydb').then(function (otherDB) {
            return db.info().then(function (info1) {
              return otherDB.info().then(function (info2) {
                info1.doc_count.should.not.equal(info2.doc_count);
                return otherDB.destroy();
              }).then(function () {
                return db.destroy();
              });
            });
          });
        });
      });
    });

    it('should inform us when using memdown', function () {
      var opts = { name: 'mydb', db: require('memdown') };
      return new PouchDB(opts).then(function (db) {
        return db.info().then(function (info) {
          info.backend_adapter.should.equal('MemDOWN');
        });
      });
    });

    it('constructor emits destroyed when using defaults', function () {
      var CustomPouch = PouchDB.defaults({db: require('memdown')});

      return new CustomPouch('mydb').then(function (db) {
        return new testUtils.Promise(function (resolve) {
          CustomPouch.once('destroyed', function (name) {
            name.should.equal('mydb');
            resolve();
          });
          db.destroy();
        });
      });
    });

    it('db emits destroyed when using defaults', function () {
      var CustomPouch = PouchDB.defaults({db: require('memdown')});

      return new CustomPouch('mydb').then(function (db) {
        return new testUtils.Promise(function (resolve) {
          db.once('destroyed', resolve);
          db.destroy();
        });
      });
    });

    it('constructor emits creation event', function (done) {
      var CustomPouch = PouchDB.defaults({db: require('memdown')});

      CustomPouch.once('created', function (name) {
        name.should.equal('mydb', 'should be same thing');
        done();
      });
      new PouchDB('mydb');
    });

    // somewhat odd behavior (CustomPouch constructor always mirrors PouchDB),
    // but better to test it explicitly
    it('PouchDB emits destroyed when using defaults', function () {
      var CustomPouch = PouchDB.defaults({db: require('memdown')});

      return new CustomPouch('mydb').then(function (db) {
        return new testUtils.Promise(function (resolve) {
          PouchDB.once('destroyed', function (name) {
            name.should.equal('mydb');
            resolve();
          });
          db.destroy();
        });
      });
    });

    // somewhat odd behavior (CustomPouch constructor always mirrors PouchDB),
    // but better to test it explicitly
    it('PouchDB emits created when using defaults', function (done) {
      var CustomPouch = PouchDB.defaults({db: require('memdown')});

      PouchDB.once('created', function (name) {
        name.should.equal('mydb', 'should be same thing');
        done();
      });
      new CustomPouch('mydb');
    });

  });
}
<commit_msg>test: workaround "Adapter is missing" error<commit_after>'use strict';
if (!process.env.LEVEL_ADAPTER &&
    !process.env.LEVEL_PREFIX &&
    !process.env.AUTO_COMPACTION &&
    !process.env.ADAPTER) {
  // these tests don't make sense for anything other than default leveldown
  var path = require('path');
  var mkdirp = require('mkdirp');
  var rimraf = require('rimraf');

  describe('defaults', function () {

    beforeEach(function () {
      return new PouchDB('mydb').destroy().then(function () {
        return new PouchDB('mydb', {db: require('memdown'), adapter: 'fs'}).destroy();
      });
    });

    afterEach(function (done) {
      rimraf.sync('./tmp/_pouch_.');
      rimraf.sync('./tmp/path');
      done();
    });

    it('should allow prefixes', function () {
      var prefix = './tmp/path/to/db/1/';
      var dir = path.join(prefix, '/tmp/');
      var dir2 = path.join('./tmp/_pouch_./', prefix);
      var dir3 = path.join(dir2, './tmp/_pouch_mydb');
      mkdirp.sync(dir);
      mkdirp.sync(dir2);
      mkdirp.sync(dir3);

      return new PouchDB('mydb', {
        prefix: prefix
      }).then(function (db) {
        return db.info().then(function (info1) {
          info1.db_name.should.equal('mydb');
          return db.destroy();
        });
      });
    });

    it('Defaults leaks eventEmitters', function () {
      PouchDB.defaults({db: require('memdown'), adapter: 'fs' });
      PouchDB.defaults({db: require('memdown'), adapter: 'fs' });
      PouchDB.defaults({db: require('memdown'), adapter: 'fs' });
      PouchDB.defaults({db: require('memdown'), adapter: 'fs' });
    });

    it('should allow us to set a prefix by default', function () {
      var prefix = './tmp/path/to/db/2/';
      var dir = path.join(prefix, '/tmp/');
      var dir2 = path.join('./tmp/_pouch_./', prefix);
      var dir3 = path.join(dir2, './tmp/_pouch_mydb');
      mkdirp.sync(dir);
      mkdirp.sync(dir2);
      mkdirp.sync(dir3);

      var CustomPouch = PouchDB.defaults({
        prefix: prefix
      });
      /* jshint newcap:false */
      var db = CustomPouch({name: 'mydb'});
      return db.info().then(function (info1) {
        info1.db_name.should.equal('mydb');
        return db.destroy();
      });
    });

    it('should allow us to use memdown', function () {
      var opts = { name: 'mydb', db: require('memdown'), adapter: 'fs' };
      return new PouchDB(opts).then(function (db) {
        return db.put({_id: 'foo'}).then(function () {
          return new PouchDB('mydb').then(function (otherDB) {
            return db.info().then(function (info1) {
              return otherDB.info().then(function (info2) {
                info1.doc_count.should.not.equal(info2.doc_count);
                return otherDB.destroy();
              }).then(function () {
                return db.destroy();
              });
            });
          });
        });
      });
    });

    it('should allow us to destroy memdown', function () {
      var opts = {db: require('memdown'), adapter: 'fs' };
      return new PouchDB('mydb', opts).then(function (db) {
        return db.put({_id: 'foo'}).then(function () {
          return new PouchDB('mydb', opts).then(function (otherDB) {
            return db.info().then(function (info1) {
              return otherDB.info().then(function (info2) {
                info1.doc_count.should.equal(info2.doc_count);
                return otherDB.destroy();
              }).then(function () {
                return new PouchDB('mydb', opts).then(function (db3) {
                  return db3.info().then(function (info) {
                    info.doc_count.should.equal(0);
                    return db3.destroy();
                  });
                });
              });
            });
          });
        });
      });
    });

    it('should allow us to use memdown by default', function () {
      var CustomPouch = PouchDB.defaults({db: require('memdown'), adapter: 'fs'});
      return new CustomPouch('mydb').then(function (db) {
        return db.put({_id: 'foo'}).then(function () {
          return new PouchDB('mydb').then(function (otherDB) {
            return db.info().then(function (info1) {
              return otherDB.info().then(function (info2) {
                info1.doc_count.should.not.equal(info2.doc_count);
                return otherDB.destroy();
              }).then(function () {
                return db.destroy();
              });
            });
          });
        });
      });
    });

    it('should inform us when using memdown', function () {
      var opts = { name: 'mydb', db: require('memdown'), adapter: 'fs' };
      return new PouchDB(opts).then(function (db) {
        return db.info().then(function (info) {
          info.backend_adapter.should.equal('MemDOWN');
        });
      });
    });

    it('constructor emits destroyed when using defaults', function () {
      var CustomPouch = PouchDB.defaults({db: require('memdown'), adapter: 'fs'});

      return new CustomPouch('mydb').then(function (db) {
        return new testUtils.Promise(function (resolve) {
          CustomPouch.once('destroyed', function (name) {
            name.should.equal('mydb');
            resolve();
          });
          db.destroy();
        });
      });
    });

    it('db emits destroyed when using defaults', function () {
      var CustomPouch = PouchDB.defaults({db: require('memdown'), adapter: 'fs'});

      return new CustomPouch('mydb').then(function (db) {
        return new testUtils.Promise(function (resolve) {
          db.once('destroyed', resolve);
          db.destroy();
        });
      });
    });

    it('constructor emits creation event', function (done) {
      var CustomPouch = PouchDB.defaults({db: require('memdown'), adapter: 'fs'});

      CustomPouch.once('created', function (name) {
        name.should.equal('mydb', 'should be same thing');
        done();
      });
      new PouchDB('mydb');
    });

    // somewhat odd behavior (CustomPouch constructor always mirrors PouchDB),
    // but better to test it explicitly
    it('PouchDB emits destroyed when using defaults', function () {
      var CustomPouch = PouchDB.defaults({db: require('memdown'), adapter: 'fs'});

      return new CustomPouch('mydb').then(function (db) {
        return new testUtils.Promise(function (resolve) {
          PouchDB.once('destroyed', function (name) {
            name.should.equal('mydb');
            resolve();
          });
          db.destroy();
        });
      });
    });

    // somewhat odd behavior (CustomPouch constructor always mirrors PouchDB),
    // but better to test it explicitly
    it('PouchDB emits created when using defaults', function (done) {
      var CustomPouch = PouchDB.defaults({db: require('memdown'), adapter: 'fs'});

      PouchDB.once('created', function (name) {
        name.should.equal('mydb', 'should be same thing');
        done();
      });
      new CustomPouch('mydb');
    });

  });
}
<|endoftext|>