Fix app test

This commit is contained in:
Girish Ramakrishnan
2017-02-06 21:53:29 -08:00
parent 02bcff2223
commit 9d3cf990d1
4 changed files with 983 additions and 1255 deletions
+4
View File
@@ -122,6 +122,10 @@ CloudronError.SELF_UPGRADE_NOT_SUPPORTED = 'Self upgrade not supported';
function initialize(callback) { function initialize(callback) {
assert.strictEqual(typeof callback, 'function'); assert.strictEqual(typeof callback, 'function');
gConfigState = { dns: false, tls: false, configured: false };
gUpdatingDns = false;
gBoxAndUserDetails = null;
async.series([ async.series([
installAppBundle, installAppBundle,
checkConfigState, checkConfigState,
+1 -1
View File
@@ -64,7 +64,7 @@ function saveSync() {
fs.writeFileSync(cloudronConfigFileName, JSON.stringify(data, null, 4)); // functions are ignored by JSON.stringify fs.writeFileSync(cloudronConfigFileName, JSON.stringify(data, null, 4)); // functions are ignored by JSON.stringify
} }
function _reset (callback) { function _reset(callback) {
safe.fs.unlinkSync(cloudronConfigFileName); safe.fs.unlinkSync(cloudronConfigFileName);
initConfig(); initConfig();
+79 -355
View File
@@ -62,20 +62,7 @@ var USER_1_ID = null, USERNAME_1 = 'user', EMAIL_1 ='user@me.com';
var token = null; // authentication token var token = null; // authentication token
var token_1 = null; var token_1 = null;
var awsHostedZones = { var awsHostedZones;
HostedZones: [{
Id: '/hostedzone/ZONEID',
Name: 'localhost.',
CallerReference: '305AFD59-9D73-4502-B020-F4E6F889CB30',
ResourceRecordSetCount: 2,
ChangeInfo: {
Id: '/change/CKRTFJA0ANHXB',
Status: 'INSYNC'
}
}],
IsTruncated: false,
MaxItems: '100'
};
function startDockerProxy(interceptor, callback) { function startDockerProxy(interceptor, callback) {
assert.strictEqual(typeof interceptor, 'function'); assert.strictEqual(typeof interceptor, 'function');
@@ -148,21 +135,38 @@ function checkRedis(containerId, done) {
}); });
} }
describe('Apps', function () { var dockerProxy;
this.timeout(100000); var imageDeleted;
var imageCreated;
var dockerProxy; function startBox(done) {
var imageDeleted = false;
var imageCreated = false;
before(function (done) {
config._reset(); config._reset();
imageDeleted = false;
imageCreated = false;
process.env.TEST_CREATE_INFRA = 1; process.env.TEST_CREATE_INFRA = 1;
safe.fs.unlinkSync(paths.INFRA_VERSION_FILE); safe.fs.unlinkSync(paths.INFRA_VERSION_FILE);
child_process.execSync('docker ps -qa | xargs --no-run-if-empty docker rm -f'); child_process.execSync('docker ps -qa | xargs --no-run-if-empty docker rm -f');
config.set('fqdn', 'foobar.com');
awsHostedZones = {
HostedZones: [{
Id: '/hostedzone/ZONEID',
Name: config.zoneName() + '.',
CallerReference: '305AFD59-9D73-4502-B020-F4E6F889CB30',
ResourceRecordSetCount: 2,
ChangeInfo: {
Id: '/change/CKRTFJA0ANHXB',
Status: 'INSYNC'
}
}],
IsTruncated: false,
MaxItems: '100'
};
async.series([ async.series([
// first clear, then start server. otherwise, taskmanager spins up tasks for obsolete appIds // first clear, then start server. otherwise, taskmanager spins up tasks for obsolete appIds
database.initialize, database.initialize,
@@ -238,9 +242,9 @@ describe('Apps', function () {
console.log('This test can take ~40 seconds to start as it waits for infra to be ready'); console.log('This test can take ~40 seconds to start as it waits for infra to be ready');
setTimeout(done, 40000); setTimeout(done, 40000);
}); });
}); }
after(function (done) { function stopBox(done) {
delete process.env.TEST_CREATE_INFRA; delete process.env.TEST_CREATE_INFRA;
// child_process.execSync('docker ps -qa | xargs --no-run-if-empty docker rm -f'); // child_process.execSync('docker ps -qa | xargs --no-run-if-empty docker rm -f');
@@ -250,17 +254,19 @@ describe('Apps', function () {
async.series([ async.series([
taskmanager.stopPendingTasks, taskmanager.stopPendingTasks,
taskmanager.waitForPendingTasks, taskmanager.waitForPendingTasks,
appdb._clear,
server.stop, server.stop,
ldap.stop, ldap.stop,
simpleauth.stop, simpleauth.stop,
config._reset, config._reset
], done); ], done);
}); }
describe('App API', function () { describe('App API', function () {
after(function (done) { this.timeout(100000);
appdb._clear(done); // TODO: test proper uninstall (requires mock for aws)
}); before(startBox);
after(stopBox);
it('app install fails - missing manifest', function (done) { it('app install fails - missing manifest', function (done) {
superagent.post(SERVER_URL + '/api/v1/apps/install') superagent.post(SERVER_URL + '/api/v1/apps/install')
@@ -607,21 +613,27 @@ describe('Apps', function () {
done(); done();
}); });
}); });
}); });
describe('App installation', function () { describe('App installation', function () {
this.timeout(50000); this.timeout(100000);
var apiHockInstance = hock.createHock({ throwOnUnmatched: false }), apiHockServer; var apiHockInstance = hock.createHock({ throwOnUnmatched: false }), apiHockServer;
var awsHockInstance = hock.createHock({ throwOnUnmatched: false }), awsHockServer; var awsHockInstance = hock.createHock({ throwOnUnmatched: false }), awsHockServer;
// *.foobar.com
var validCert1, validKey1;
before(function (done) { before(function (done) {
child_process.execSync('openssl req -subj "/CN=*.foobar.com/O=My Company Name LTD./C=US" -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout /tmp/server.key -out /tmp/server.crt');
validKey1 = fs.readFileSync('/tmp/server.key', 'utf8');
validCert1 = fs.readFileSync('/tmp/server.crt', 'utf8');
APP_ID = uuid.v4(); APP_ID = uuid.v4();
imageDeleted = false;
imageCreated = false;
async.series([ async.series([
startBox,
function (callback) { function (callback) {
apiHockInstance apiHockInstance
.get('/api/v1/apps/' + APP_STORE_ID + '/versions/' + APP_MANIFEST.version + '/icon') .get('/api/v1/apps/' + APP_STORE_ID + '/versions/' + APP_MANIFEST.version + '/icon')
@@ -631,12 +643,17 @@ describe('Apps', function () {
apiHockServer = http.createServer(apiHockInstance.handler).listen(port, callback); apiHockServer = http.createServer(apiHockInstance.handler).listen(port, callback);
}, },
settings.setDnsConfig.bind(null, { provider: 'route53', accessKeyId: 'accessKeyId', secretAccessKey: 'secretAccessKey', endpoint: 'http://localhost:5353' }, config.fqdn()),
settings.setTlsConfig.bind(null, { provider: 'caas' }),
function (callback) { function (callback) {
awsHockInstance awsHockInstance
.get('/2013-04-01/hostedzone') .get('/2013-04-01/hostedzone')
.max(Infinity) .max(Infinity)
.reply(200, js2xml('ListHostedZonesResponse', awsHostedZones, { arrayMap: { HostedZones: 'HostedZone'} }), { 'Content-Type': 'application/xml' }) .reply(200, js2xml('ListHostedZonesResponse', awsHostedZones, { arrayMap: { HostedZones: 'HostedZone'} }), { 'Content-Type': 'application/xml' })
.get('/2013-04-01/hostedzone/ZONEID/rrset?maxitems=1&name=appslocation.localhost.&type=A') .filteringPathRegEx(/name=[^&]*/, 'name=location')
.get('/2013-04-01/hostedzone/ZONEID/rrset?maxitems=1&name=location&type=A')
.max(Infinity) .max(Infinity)
.reply(200, js2xml('ListResourceRecordSetsResponse', { ResourceRecordSets: [ ] }, { 'Content-Type': 'application/xml' })) .reply(200, js2xml('ListResourceRecordSetsResponse', { ResourceRecordSets: [ ] }, { 'Content-Type': 'application/xml' }))
.filteringRequestBody(function (unusedBody) { return ''; }) // strip out body .filteringRequestBody(function (unusedBody) { return ''; }) // strip out body
@@ -651,14 +668,14 @@ describe('Apps', function () {
after(function (done) { after(function (done) {
APP_ID = null; APP_ID = null;
async.series([ async.series([
apiHockServer.close.bind(apiHockServer), apiHockServer.close.bind(apiHockServer),
awsHockServer.close.bind(awsHockServer) awsHockServer.close.bind(awsHockServer),
stopBox
], done); ], done);
}); });
var appResult = null /* the json response */, appEntry = null /* entry from database */; var appResult = null, appEntry = null;
it('can install test app', function (done) { it('can install test app', function (done) {
var fake1 = nock(config.apiServerOrigin()).get('/api/v1/apps/' + APP_STORE_ID).reply(200, { manifest: APP_MANIFEST }); var fake1 = nock(config.apiServerOrigin()).get('/api/v1/apps/' + APP_STORE_ID).reply(200, { manifest: APP_MANIFEST });
@@ -680,11 +697,10 @@ describe('Apps', function () {
superagent.post(SERVER_URL + '/api/v1/apps/install') superagent.post(SERVER_URL + '/api/v1/apps/install')
.query({ access_token: token }) .query({ access_token: token })
.send({ appStoreId: APP_STORE_ID, password: PASSWORD, location: APP_LOCATION, portBindings: null, accessRestriction: null }) .send({ appStoreId: APP_STORE_ID, password: PASSWORD, location: APP_LOCATION, portBindings: { ECHO_SERVER_PORT: 7171 }, accessRestriction: null })
.end(function (err, res) { .end(function (err, res) {
expect(res.statusCode).to.equal(202); expect(res.statusCode).to.equal(202);
expect(fake1.isDone()).to.be.ok(); expect(fake1.isDone()).to.be.ok();
expect(res.body.id).to.be.a('string');
APP_ID = res.body.id; APP_ID = res.body.id;
checkInstallStatus(); checkInstallStatus();
}); });
@@ -706,6 +722,7 @@ describe('Apps', function () {
it('installation - container created', function (done) { it('installation - container created', function (done) {
expect(appResult.containerId).to.be(undefined); expect(appResult.containerId).to.be(undefined);
expect(appEntry.containerId).to.be.ok();
docker.getContainer(appEntry.containerId).inspect(function (error, data) { docker.getContainer(appEntry.containerId).inspect(function (error, data) {
expect(error).to.not.be.ok(); expect(error).to.not.be.ok();
expect(data.Config.ExposedPorts['7777/tcp']).to.eql({ }); expect(data.Config.ExposedPorts['7777/tcp']).to.eql({ });
@@ -716,6 +733,8 @@ describe('Apps', function () {
expect(data.Config.Env).to.contain('APP_DOMAIN=' + config.appFqdn(APP_LOCATION)); expect(data.Config.Env).to.contain('APP_DOMAIN=' + config.appFqdn(APP_LOCATION));
// Hostname must not be set of app fqdn or app location! // Hostname must not be set of app fqdn or app location!
expect(data.Config.Hostname).to.not.contain(APP_LOCATION); expect(data.Config.Hostname).to.not.contain(APP_LOCATION);
expect(data.Config.Env).to.contain('ECHO_SERVER_PORT=7171');
expect(data.HostConfig.PortBindings['7778/tcp'][0].HostPort).to.eql('7171');
done(); done();
}); });
}); });
@@ -735,16 +754,31 @@ describe('Apps', function () {
done(); done();
}); });
it('installation - is up and running', function (done) { it('installation - http is up and running', function (done) {
var tryCount = 20;
expect(appResult.httpPort).to.be(undefined); expect(appResult.httpPort).to.be(undefined);
setTimeout(function () { (function healthCheck() {
superagent.get('http://localhost:' + appEntry.httpPort + appResult.manifest.healthCheckPath) superagent.get('http://localhost:' + appEntry.httpPort + appResult.manifest.healthCheckPath)
.end(function (err, res) { .end(function (err, res) {
if (err || res.statusCode !== 200) {
if (--tryCount === 0) return done(new Error('Timedout'));
return setTimeout(healthCheck, 2000);
}
expect(!err).to.be.ok(); expect(!err).to.be.ok();
expect(res.statusCode).to.equal(200); expect(res.statusCode).to.equal(200);
done(); done();
}); });
}, 2000); // give some time for docker to settle })();
});
it('installation - tcp port mapping works', function (done) {
var client = net.connect(7171);
client.on('data', function (data) {
expect(data.toString()).to.eql('ECHO_SERVER_PORT=7171');
done();
});
client.on('error', done);
}); });
it('installation - running container has volume mounted', function (done) { it('installation - running container has volume mounted', function (done) {
@@ -800,7 +834,7 @@ describe('Apps', function () {
it('installation - app can check addons', function (done) { it('installation - app can check addons', function (done) {
this.timeout(120000); this.timeout(120000);
console.log('This test can take a while as it waits for scheduler addon to tick 1'); console.log('This test can take a while as it waits for scheduler addon to tick 3');
checkAddons(appEntry, done); checkAddons(appEntry, done);
}); });
@@ -933,276 +967,6 @@ describe('Apps', function () {
checkAddons(appEntry, done); checkAddons(appEntry, done);
}); });
it('can uninstall app', function (done) {
var fake1 = nock(config.apiServerOrigin()).post('/api/v1/exchangeBoxTokenWithUserToken?token=APPSTORE_TOKEN').reply(201, { userId: 'USER_ID', cloudronId: 'CLOUDRON_ID', token: 'ACCESS_TOKEN' });
var fake2 = nock(config.apiServerOrigin()).get(function (uri) { return uri.indexOf('/api/v1/users/USER_ID/cloudrons/CLOUDRON_ID/apps/') >= 0; }).reply(200, { });
var fake3 = nock(config.apiServerOrigin()).delete(function (uri) { return uri.indexOf('/api/v1/users/USER_ID/cloudrons/CLOUDRON_ID/apps/') >= 0; }).reply(204, { });
var count = 0;
function checkUninstallStatus() {
superagent.get(SERVER_URL + '/api/v1/apps/' + APP_ID)
.query({ access_token: token })
.end(function (err, res) {
if (res.statusCode === 404) return done(null);
if (++count > 50) return done(new Error('Timedout'));
setTimeout(checkUninstallStatus, 1000);
});
}
superagent.post(SERVER_URL + '/api/v1/apps/' + APP_ID + '/uninstall')
.send({ password: PASSWORD })
.query({ access_token: token })
.end(function (err, res) {
expect(res.statusCode).to.equal(202);
checkUninstallStatus();
});
});
it('uninstalled - container destroyed', function (done) {
docker.getContainer(appEntry.containerId).inspect(function (error, data) {
if (data) {
console.log('Container is still alive', data);
}
expect(error).to.be.ok();
done();
});
});
it('uninstalled - image destroyed', function (done) {
expect(imageDeleted).to.be.ok();
done();
});
it('uninstalled - volume destroyed', function (done) {
expect(!fs.existsSync(paths.DATA_DIR + '/' + APP_ID));
done();
});
it('uninstalled - unregistered subdomain', function (done) {
apiHockInstance.done(function (error) { // checks if all the apiHockServer APIs were called
expect(!error).to.be.ok();
awsHockInstance.done(function (error) {
expect(!error).to.be.ok();
done();
});
});
});
it('uninstalled - removed nginx', function (done) {
expect(!fs.existsSync(paths.NGINX_APPCONFIG_DIR + '/' + APP_LOCATION + '.conf'));
done();
});
it('uninstalled - removed redis addon', function (done) {
docker.getContainer('redis-' + APP_ID).inspect(function (error, data) {
expect(error).to.be.ok();
done();
});
});
});
describe('App installation - port bindings', function () {
this.timeout(50000);
var apiHockInstance = hock.createHock({ throwOnUnmatched: false }), apiHockServer;
var awsHockInstance = hock.createHock({ throwOnUnmatched: false }), awsHockServer;
// *.foobar.com
var validCert1, validKey1;
before(function (done) {
imageDeleted = false;
imageCreated = false;
child_process.execSync('openssl req -subj "/CN=*.foobar.com/O=My Company Name LTD./C=US" -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout /tmp/server.key -out /tmp/server.crt');
validKey1 = fs.readFileSync('/tmp/server.key', 'utf8');
validCert1 = fs.readFileSync('/tmp/server.crt', 'utf8');
APP_ID = uuid.v4();
async.series([
function (callback) {
config.set('fqdn', 'test.foobar.com');
callback();
},
function (callback) {
apiHockInstance
.get('/api/v1/apps/' + APP_STORE_ID + '/versions/' + APP_MANIFEST.version + '/icon')
.replyWithFile(200, path.resolve(__dirname, '../../../webadmin/src/img/appicon_fallback.png'));
var port = parseInt(url.parse(config.apiServerOrigin()).port, 10);
apiHockServer = http.createServer(apiHockInstance.handler).listen(port, callback);
},
settings.setDnsConfig.bind(null, { provider: 'route53', accessKeyId: 'accessKeyId', secretAccessKey: 'secretAccessKey', endpoint: 'http://localhost:5353' }, config.fqdn()),
settings.setTlsConfig.bind(null, { provider: 'caas' }),
function (callback) {
awsHockInstance
.get('/2013-04-01/hostedzone')
.max(Infinity)
.reply(200, js2xml('ListHostedZonesResponse', awsHostedZones, { arrayMap: { HostedZones: 'HostedZone'} }), { 'Content-Type': 'application/xml' })
.filteringPathRegEx(/name=[^&]*/, 'name=location')
.get('/2013-04-01/hostedzone/ZONEID/rrset?maxitems=1&name=location&type=A')
.max(Infinity)
.reply(200, js2xml('ListResourceRecordSetsResponse', { ResourceRecordSets: [ ] }, { 'Content-Type': 'application/xml' }))
.filteringRequestBody(function (unusedBody) { return ''; }) // strip out body
.post('/2013-04-01/hostedzone/ZONEID/rrset/')
.max(Infinity)
.reply(200, js2xml('ChangeResourceRecordSetsResponse', { ChangeInfo: { Id: 'dnsrecordid', Status: 'INSYNC' } }), { 'Content-Type': 'application/xml' });
awsHockServer = http.createServer(awsHockInstance.handler).listen(5353, callback);
}
], done);
});
after(function (done) {
APP_ID = null;
async.series([
apiHockServer.close.bind(apiHockServer),
awsHockServer.close.bind(awsHockServer)
], done);
});
var appResult = null, appEntry = null;
it('can install test app', function (done) {
var fake1 = nock(config.apiServerOrigin()).get('/api/v1/apps/' + APP_STORE_ID).reply(200, { manifest: APP_MANIFEST });
var fake2 = nock(config.apiServerOrigin()).post('/api/v1/exchangeBoxTokenWithUserToken?token=APPSTORE_TOKEN').reply(201, { userId: 'USER_ID', cloudronId: 'CLOUDRON_ID', token: 'ACCESS_TOKEN' });
var fake3 = nock(config.apiServerOrigin()).post(function (uri) { return uri.indexOf('/api/v1/users/USER_ID/cloudrons/CLOUDRON_ID/apps/') >= 0; }, { 'appstoreId': APP_STORE_ID }).reply(201, { });
var count = 0;
function checkInstallStatus() {
superagent.get(SERVER_URL + '/api/v1/apps/' + APP_ID)
.query({ access_token: token })
.end(function (err, res) {
expect(res.statusCode).to.equal(200);
if (res.body.installationState === appdb.ISTATE_INSTALLED) { appResult = res.body; return done(null); }
if (res.body.installationState === appdb.ISTATE_ERROR) return done(new Error('Install error'));
if (++count > 50) return done(new Error('Timedout'));
setTimeout(checkInstallStatus, 1000);
});
}
superagent.post(SERVER_URL + '/api/v1/apps/install')
.query({ access_token: token })
.send({ appStoreId: APP_STORE_ID, password: PASSWORD, location: APP_LOCATION, portBindings: { ECHO_SERVER_PORT: 7171 }, accessRestriction: null })
.end(function (err, res) {
expect(res.statusCode).to.equal(202);
expect(fake1.isDone()).to.be.ok();
APP_ID = res.body.id;
checkInstallStatus();
});
});
it('installation - image created', function (done) {
expect(imageCreated).to.be.ok();
done();
});
it('installation - can get app', function (done) {
apps.get(appResult.id, function (error, app) {
expect(!error).to.be.ok();
expect(app).to.be.an('object');
appEntry = app;
done();
});
});
it('installation - container created', function (done) {
expect(appResult.containerId).to.be(undefined);
expect(appEntry.containerId).to.be.ok();
docker.getContainer(appEntry.containerId).inspect(function (error, data) {
expect(error).to.not.be.ok();
expect(data.Config.ExposedPorts['7777/tcp']).to.eql({ });
expect(data.Config.Env).to.contain('ECHO_SERVER_PORT=7171');
expect(data.HostConfig.PortBindings['7778/tcp'][0].HostPort).to.eql('7171');
done();
});
});
it('installation - nginx config', function (done) {
expect(fs.existsSync(paths.NGINX_APPCONFIG_DIR + '/' + APP_LOCATION + '.conf'));
done();
});
it('installation - registered subdomain', function (done) {
// this is checked in unregister subdomain testcase
done();
});
it('installation - volume created', function (done) {
expect(fs.existsSync(paths.DATA_DIR + '/' + APP_ID));
done();
});
it('installation - http is up and running', function (done) {
var tryCount = 20;
expect(appResult.httpPort).to.be(undefined);
(function healthCheck() {
superagent.get('http://localhost:' + appEntry.httpPort + appResult.manifest.healthCheckPath)
.end(function (err, res) {
if (err || res.statusCode !== 200) {
if (--tryCount === 0) return done(new Error('Timedout'));
return setTimeout(healthCheck, 2000);
}
expect(!err).to.be.ok();
expect(res.statusCode).to.equal(200);
done();
});
})();
});
it('installation - tcp port mapping works', function (done) {
var client = net.connect(7171);
client.on('data', function (data) {
expect(data.toString()).to.eql('ECHO_SERVER_PORT=7171');
done();
});
client.on('error', done);
});
it('installation - running container has volume mounted', function (done) {
docker.getContainer(appEntry.containerId).inspect(function (error, data) {
expect(error).to.not.be.ok();
// support newer docker versions
if (data.Volumes) {
expect(data.Volumes['/app/data']).to.eql(paths.DATA_DIR + '/' + APP_ID + '/data');
} else {
expect(data.Mounts.filter(function (mount) { return mount.Destination === '/app/data'; })[0].Source).to.eql(paths.DATA_DIR + '/' + APP_ID + '/data');
}
done();
});
});
it('installation - app can populate addons', function (done) {
superagent.get('http://localhost:' + appEntry.httpPort + '/populate_addons').end(function (err, res) {
expect(!err).to.be.ok();
expect(res.statusCode).to.equal(200);
for (var key in res.body) {
expect(res.body[key]).to.be('OK');
}
done();
});
});
it('installation - app can check addons', function (done) {
this.timeout(120000);
console.log('This test can take a while as it waits for scheduler addon to tick 3');
checkAddons(appEntry, done);
});
it('installation - redis addon created', function (done) {
checkRedis('redis-' + APP_ID, done);
});
function checkConfigureStatus(count, done) { function checkConfigureStatus(count, done) {
assert.strictEqual(typeof count, 'number'); assert.strictEqual(typeof count, 'number');
assert.strictEqual(typeof done, 'function'); assert.strictEqual(typeof done, 'function');
@@ -1340,45 +1104,6 @@ describe('Apps', function () {
}); });
}); });
it('can stop app', function (done) {
superagent.post(SERVER_URL + '/api/v1/apps/' + APP_ID + '/stop')
.query({ access_token: token })
.end(function (err, res) {
expect(res.statusCode).to.equal(202);
done();
});
});
// osx: if this test is failing, it is probably because of a stray port binding in boot2docker
it('did stop the app', function (done) {
var timer1, timer2;
function finished() {
clearTimeout(timer1);
clearTimeout(timer2);
if (done) done();
// avoid double callbacks
done = null;
}
function waitForAppToDie() {
var client = net.connect(7171);
client.setTimeout(2000);
client.on('connect', function () {
timer1 = setTimeout(waitForAppToDie, 1000);
});
client.on('timeout', function () { finished(); });
client.on('error', function (error) { finished(); });
client.on('data', function (data) {
timer2 = setTimeout(waitForAppToDie, 1000);
});
}
waitForAppToDie();
});
it('can uninstall app', function (done) { it('can uninstall app', function (done) {
var fake1 = nock(config.apiServerOrigin()).post('/api/v1/exchangeBoxTokenWithUserToken?token=APPSTORE_TOKEN').reply(201, { userId: 'USER_ID', cloudronId: 'CLOUDRON_ID', token: 'ACCESS_TOKEN' }); var fake1 = nock(config.apiServerOrigin()).post('/api/v1/exchangeBoxTokenWithUserToken?token=APPSTORE_TOKEN').reply(201, { userId: 'USER_ID', cloudronId: 'CLOUDRON_ID', token: 'ACCESS_TOKEN' });
var fake2 = nock(config.apiServerOrigin()).get(function (uri) { return uri.indexOf('/api/v1/users/USER_ID/cloudrons/CLOUDRON_ID/apps/') >= 0; }).reply(200, { }); var fake2 = nock(config.apiServerOrigin()).get(function (uri) { return uri.indexOf('/api/v1/users/USER_ID/cloudrons/CLOUDRON_ID/apps/') >= 0; }).reply(200, { });
@@ -1444,5 +1169,4 @@ describe('Apps', function () {
done(); done();
}); });
}); });
});
}); });
+1 -1
View File
@@ -271,7 +271,7 @@ function getEmailDnsRecords(callback) {
function ignoreError(what, func) { function ignoreError(what, func) {
return function (callback) { return function (callback) {
func(function (error) { func(function (error) {
if (error && process.env.BOX_ENV !== 'test') console.error('Ignored error - ' + what + ':', error); if (error) debug('Ignored error - ' + what + ':', error);
callback(); callback();
}); });