1296 lines
39 KiB
JavaScript
1296 lines
39 KiB
JavaScript
'use strict';
|
|
// These tests check the Installations functionality of the REST API.
|
|
// Ported from installation_collection_test.go
|
|
|
|
const auth = require('../lib/Auth');
|
|
const Config = require('../lib/Config');
|
|
const Parse = require('parse/node').Parse;
|
|
const rest = require('../lib/rest');
|
|
const request = require('../lib/request');
|
|
|
|
let config;
|
|
let database;
|
|
const defaultColumns = require('../lib/Controllers/SchemaController').defaultColumns;
|
|
|
|
const delay = function delay(delay) {
|
|
return new Promise(resolve => setTimeout(resolve, delay));
|
|
};
|
|
|
|
const installationSchema = {
|
|
fields: Object.assign({}, defaultColumns._Default, defaultColumns._Installation),
|
|
};
|
|
|
|
describe('Installations', () => {
|
|
beforeEach(() => {
|
|
config = Config.get('test');
|
|
database = config.database;
|
|
});
|
|
|
|
it('creates an android installation with ids', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const device = 'android';
|
|
const input = {
|
|
installationId: installId,
|
|
deviceType: device,
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
const obj = results[0];
|
|
expect(obj.installationId).toEqual(installId);
|
|
expect(obj.deviceType).toEqual(device);
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
console.log(error);
|
|
jfail(error);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('creates an ios installation with ids', done => {
|
|
const t = '11433856eed2f1285fb3aa11136718c1198ed5647875096952c66bf8cb976306';
|
|
const device = 'ios';
|
|
const input = {
|
|
deviceToken: t,
|
|
deviceType: device,
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
const obj = results[0];
|
|
expect(obj.deviceToken).toEqual(t);
|
|
expect(obj.deviceType).toEqual(device);
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
console.log(error);
|
|
jfail(error);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('creates an embedded installation with ids', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const device = 'embedded';
|
|
const input = {
|
|
installationId: installId,
|
|
deviceType: device,
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
const obj = results[0];
|
|
expect(obj.installationId).toEqual(installId);
|
|
expect(obj.deviceType).toEqual(device);
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
console.log(error);
|
|
jfail(error);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('creates an android installation with all fields', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const device = 'android';
|
|
const input = {
|
|
installationId: installId,
|
|
deviceType: device,
|
|
channels: ['foo', 'bar'],
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
const obj = results[0];
|
|
expect(obj.installationId).toEqual(installId);
|
|
expect(obj.deviceType).toEqual(device);
|
|
expect(typeof obj.channels).toEqual('object');
|
|
expect(obj.channels.length).toEqual(2);
|
|
expect(obj.channels[0]).toEqual('foo');
|
|
expect(obj.channels[1]).toEqual('bar');
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
console.log(error);
|
|
jfail(error);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('creates an ios installation with all fields', done => {
|
|
const t = '11433856eed2f1285fb3aa11136718c1198ed5647875096952c66bf8cb976306';
|
|
const device = 'ios';
|
|
const input = {
|
|
deviceToken: t,
|
|
deviceType: device,
|
|
channels: ['foo', 'bar'],
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
const obj = results[0];
|
|
expect(obj.deviceToken).toEqual(t);
|
|
expect(obj.deviceType).toEqual(device);
|
|
expect(typeof obj.channels).toEqual('object');
|
|
expect(obj.channels.length).toEqual(2);
|
|
expect(obj.channels[0]).toEqual('foo');
|
|
expect(obj.channels[1]).toEqual('bar');
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
console.log(error);
|
|
jfail(error);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should properly fail queying installations', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const device = 'android';
|
|
const input = {
|
|
installationId: installId,
|
|
deviceType: device,
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => {
|
|
const query = new Parse.Query(Parse.Installation);
|
|
return query.find();
|
|
})
|
|
.then(() => {
|
|
fail('Should not succeed!');
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
expect(error.code).toBe(119);
|
|
expect(error.message).toBe(
|
|
"Clients aren't allowed to perform the find operation on the installation collection."
|
|
);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should properly queying installations with masterKey', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const device = 'android';
|
|
const input = {
|
|
installationId: installId,
|
|
deviceType: device,
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => {
|
|
const query = new Parse.Query(Parse.Installation);
|
|
return query.find({ useMasterKey: true });
|
|
})
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
const obj = results[0].toJSON();
|
|
expect(obj.installationId).toEqual(installId);
|
|
expect(obj.deviceType).toEqual(device);
|
|
done();
|
|
})
|
|
.catch(() => {
|
|
fail('Should not fail');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('fails with missing ids', done => {
|
|
const input = {
|
|
deviceType: 'android',
|
|
channels: ['foo', 'bar'],
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => {
|
|
fail('Should not have been able to create an Installation.');
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
expect(error.code).toEqual(135);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('fails for android with missing type', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const input = {
|
|
installationId: installId,
|
|
channels: ['foo', 'bar'],
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => {
|
|
fail('Should not have been able to create an Installation.');
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
expect(error.code).toEqual(135);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('creates an object with custom fields', done => {
|
|
const t = '11433856eed2f1285fb3aa11136718c1198ed5647875096952c66bf8cb976306';
|
|
const input = {
|
|
deviceToken: t,
|
|
deviceType: 'ios',
|
|
channels: ['foo', 'bar'],
|
|
custom: 'allowed',
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
const obj = results[0];
|
|
expect(obj.custom).toEqual('allowed');
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
console.log(error);
|
|
});
|
|
});
|
|
|
|
// Note: did not port test 'TestObjectIDForIdentifiers'
|
|
|
|
it('merging when installationId already exists', done => {
|
|
const installId1 = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const t = '11433856eed2f1285fb3aa11136718c1198ed5647875096952c66bf8cb976306';
|
|
const input = {
|
|
deviceToken: t,
|
|
deviceType: 'ios',
|
|
installationId: installId1,
|
|
channels: ['foo', 'bar'],
|
|
};
|
|
let firstObject;
|
|
let secondObject;
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
firstObject = results[0];
|
|
delete input.deviceToken;
|
|
delete input.channels;
|
|
input['foo'] = 'bar';
|
|
return rest.create(config, auth.nobody(config), '_Installation', input);
|
|
})
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
secondObject = results[0];
|
|
expect(firstObject._id).toEqual(secondObject._id);
|
|
expect(secondObject.channels.length).toEqual(2);
|
|
expect(secondObject.foo).toEqual('bar');
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
console.log(error);
|
|
});
|
|
});
|
|
|
|
it('merging when two objects both only have one id', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const t = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
|
|
const input1 = {
|
|
installationId: installId,
|
|
deviceType: 'ios',
|
|
};
|
|
const input2 = {
|
|
deviceToken: t,
|
|
deviceType: 'ios',
|
|
};
|
|
const input3 = {
|
|
deviceToken: t,
|
|
installationId: installId,
|
|
deviceType: 'ios',
|
|
};
|
|
let firstObject;
|
|
let secondObject;
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input1)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
firstObject = results[0];
|
|
return rest.create(config, auth.nobody(config), '_Installation', input2);
|
|
})
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(2);
|
|
if (results[0]['_id'] == firstObject._id) {
|
|
secondObject = results[1];
|
|
} else {
|
|
secondObject = results[0];
|
|
}
|
|
return rest.create(config, auth.nobody(config), '_Installation', input3);
|
|
})
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
expect(results[0]['_id']).toEqual(secondObject._id);
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
jfail(error);
|
|
done();
|
|
});
|
|
});
|
|
|
|
xit('creating multiple devices with same device token works', done => {
|
|
const installId1 = '11111111-abcd-abcd-abcd-123456789abc';
|
|
const installId2 = '22222222-abcd-abcd-abcd-123456789abc';
|
|
const installId3 = '33333333-abcd-abcd-abcd-123456789abc';
|
|
const t = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
|
|
const input = {
|
|
installationId: installId1,
|
|
deviceType: 'ios',
|
|
deviceToken: t,
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => {
|
|
input.installationId = installId2;
|
|
return rest.create(config, auth.nobody(config), '_Installation', input);
|
|
})
|
|
.then(() => {
|
|
input.installationId = installId3;
|
|
return rest.create(config, auth.nobody(config), '_Installation', input);
|
|
})
|
|
.then(() =>
|
|
database.adapter.find(
|
|
'_Installation',
|
|
{ installationId: installId1 },
|
|
installationSchema,
|
|
{}
|
|
)
|
|
)
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
return database.adapter.find(
|
|
'_Installation',
|
|
{ installationId: installId2 },
|
|
installationSchema,
|
|
{}
|
|
);
|
|
})
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
return database.adapter.find(
|
|
'_Installation',
|
|
{ installationId: installId3 },
|
|
installationSchema,
|
|
{}
|
|
);
|
|
})
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
console.log(error);
|
|
});
|
|
});
|
|
|
|
it_id('95955e90-04bc-4437-920e-b84bc30dba01')(it)('updating with new channels', done => {
|
|
const input = {
|
|
installationId: '12345678-abcd-abcd-abcd-123456789abc',
|
|
deviceType: 'android',
|
|
channels: ['foo', 'bar'],
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
const objectId = results[0].objectId;
|
|
const update = {
|
|
channels: ['baz'],
|
|
};
|
|
return rest.update(config, auth.nobody(config), '_Installation', { objectId }, update);
|
|
})
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
expect(results[0].channels.length).toEqual(1);
|
|
expect(results[0].channels[0]).toEqual('baz');
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
jfail(error);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('update android fails with new installation id', done => {
|
|
const installId1 = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const installId2 = '87654321-abcd-abcd-abcd-123456789abc';
|
|
let input = {
|
|
installationId: installId1,
|
|
deviceType: 'android',
|
|
channels: ['foo', 'bar'],
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
input = { installationId: installId2 };
|
|
return rest.update(
|
|
config,
|
|
auth.nobody(config),
|
|
'_Installation',
|
|
{ objectId: results[0].objectId },
|
|
input
|
|
);
|
|
})
|
|
.then(() => {
|
|
fail('Updating the installation should have failed.');
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
expect(error.code).toEqual(136);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('update ios fails with new deviceToken and no installationId', done => {
|
|
const a = '11433856eed2f1285fb3aa11136718c1198ed5647875096952c66bf8cb976306';
|
|
const b = '91433856eed2f1285fb3aa11136718c1198ed5647875096952c66bf8cb976306';
|
|
let input = {
|
|
deviceToken: a,
|
|
deviceType: 'ios',
|
|
channels: ['foo', 'bar'],
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
input = { deviceToken: b };
|
|
return rest.update(
|
|
config,
|
|
auth.nobody(config),
|
|
'_Installation',
|
|
{ objectId: results[0].objectId },
|
|
input
|
|
);
|
|
})
|
|
.then(() => {
|
|
fail('Updating the installation should have failed.');
|
|
})
|
|
.catch(error => {
|
|
expect(error.code).toEqual(136);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('update ios updates device token', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const t = '11433856eed2f1285fb3aa11136718c1198ed5647875096952c66bf8cb976306';
|
|
const u = '91433856eed2f1285fb3aa11136718c1198ed5647875096952c66bf8cb976306';
|
|
let input = {
|
|
installationId: installId,
|
|
deviceType: 'ios',
|
|
deviceToken: t,
|
|
channels: ['foo', 'bar'],
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
input = {
|
|
installationId: installId,
|
|
deviceToken: u,
|
|
deviceType: 'ios',
|
|
};
|
|
return rest.update(
|
|
config,
|
|
auth.nobody(config),
|
|
'_Installation',
|
|
{ objectId: results[0].objectId },
|
|
input
|
|
);
|
|
})
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
expect(results[0].deviceToken).toEqual(u);
|
|
done();
|
|
})
|
|
.catch(err => {
|
|
jfail(err);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('update fails to change deviceType', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
let input = {
|
|
installationId: installId,
|
|
deviceType: 'android',
|
|
channels: ['foo', 'bar'],
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
input = {
|
|
deviceType: 'ios',
|
|
};
|
|
return rest.update(
|
|
config,
|
|
auth.nobody(config),
|
|
'_Installation',
|
|
{ objectId: results[0].objectId },
|
|
input
|
|
);
|
|
})
|
|
.then(() => {
|
|
fail('Should not have been able to update Installation.');
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
expect(error.code).toEqual(136);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('update android with custom field', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
let input = {
|
|
installationId: installId,
|
|
deviceType: 'android',
|
|
channels: ['foo', 'bar'],
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
input = {
|
|
custom: 'allowed',
|
|
};
|
|
return rest.update(
|
|
config,
|
|
auth.nobody(config),
|
|
'_Installation',
|
|
{ objectId: results[0].objectId },
|
|
input
|
|
);
|
|
})
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
expect(results[0]['custom']).toEqual('allowed');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('update android device token with duplicate device token', async () => {
|
|
const installId1 = '11111111-abcd-abcd-abcd-123456789abc';
|
|
const installId2 = '22222222-abcd-abcd-abcd-123456789abc';
|
|
const t = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
|
|
|
|
let input = {
|
|
installationId: installId1,
|
|
deviceToken: t,
|
|
deviceType: 'android',
|
|
};
|
|
await rest.create(config, auth.nobody(config), '_Installation', input);
|
|
|
|
input = {
|
|
installationId: installId2,
|
|
deviceType: 'android',
|
|
};
|
|
await rest.create(config, auth.nobody(config), '_Installation', input);
|
|
await delay(100);
|
|
|
|
let results = await database.adapter.find(
|
|
'_Installation',
|
|
installationSchema,
|
|
{ installationId: installId1 },
|
|
{}
|
|
);
|
|
expect(results.length).toEqual(1);
|
|
const firstObject = results[0];
|
|
|
|
results = await database.adapter.find(
|
|
'_Installation',
|
|
installationSchema,
|
|
{ installationId: installId2 },
|
|
{}
|
|
);
|
|
expect(results.length).toEqual(1);
|
|
const secondObject = results[0];
|
|
|
|
// Update second installation to conflict with first installation
|
|
input = {
|
|
objectId: secondObject.objectId,
|
|
deviceToken: t,
|
|
};
|
|
await rest.update(
|
|
config,
|
|
auth.nobody(config),
|
|
'_Installation',
|
|
{ objectId: secondObject.objectId },
|
|
input
|
|
);
|
|
await delay(100);
|
|
results = await database.adapter.find(
|
|
'_Installation',
|
|
installationSchema,
|
|
{ objectId: firstObject.objectId },
|
|
{}
|
|
);
|
|
expect(results.length).toEqual(0);
|
|
});
|
|
|
|
it('update ios device token with duplicate device token', done => {
|
|
const installId1 = '11111111-abcd-abcd-abcd-123456789abc';
|
|
const installId2 = '22222222-abcd-abcd-abcd-123456789abc';
|
|
const t = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
|
|
let input = {
|
|
installationId: installId1,
|
|
deviceToken: t,
|
|
deviceType: 'ios',
|
|
};
|
|
let firstObject;
|
|
let secondObject;
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => {
|
|
input = {
|
|
installationId: installId2,
|
|
deviceType: 'ios',
|
|
};
|
|
return rest.create(config, auth.nobody(config), '_Installation', input);
|
|
})
|
|
.then(() => delay(100))
|
|
.then(() =>
|
|
database.adapter.find(
|
|
'_Installation',
|
|
installationSchema,
|
|
{ installationId: installId1 },
|
|
{}
|
|
)
|
|
)
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
firstObject = results[0];
|
|
})
|
|
.then(() => delay(100))
|
|
.then(() =>
|
|
database.adapter.find(
|
|
'_Installation',
|
|
installationSchema,
|
|
{ installationId: installId2 },
|
|
{}
|
|
)
|
|
)
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
secondObject = results[0];
|
|
// Update second installation to conflict with first installation id
|
|
input = {
|
|
installationId: installId2,
|
|
deviceToken: t,
|
|
};
|
|
return rest.update(
|
|
config,
|
|
auth.nobody(config),
|
|
'_Installation',
|
|
{ objectId: secondObject.objectId },
|
|
input
|
|
);
|
|
})
|
|
.then(() => delay(100))
|
|
.then(() =>
|
|
database.adapter.find(
|
|
'_Installation',
|
|
installationSchema,
|
|
{ objectId: firstObject.objectId },
|
|
{}
|
|
)
|
|
)
|
|
.then(results => {
|
|
// The first object should have been deleted
|
|
expect(results.length).toEqual(0);
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
jfail(error);
|
|
done();
|
|
});
|
|
});
|
|
|
|
xit('update ios device token with duplicate token different app', done => {
|
|
const installId1 = '11111111-abcd-abcd-abcd-123456789abc';
|
|
const installId2 = '22222222-abcd-abcd-abcd-123456789abc';
|
|
const t = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
|
|
const input = {
|
|
installationId: installId1,
|
|
deviceToken: t,
|
|
deviceType: 'ios',
|
|
appIdentifier: 'foo',
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => {
|
|
input.installationId = installId2;
|
|
input.appIdentifier = 'bar';
|
|
return rest.create(config, auth.nobody(config), '_Installation', input);
|
|
})
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
// The first object should have been deleted during merge
|
|
expect(results.length).toEqual(1);
|
|
expect(results[0].installationId).toEqual(installId2);
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
jfail(error);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('update ios token and channels', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const t = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
|
|
let input = {
|
|
installationId: installId,
|
|
deviceType: 'ios',
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
input = {
|
|
deviceToken: t,
|
|
channels: [],
|
|
};
|
|
return rest.update(
|
|
config,
|
|
auth.nobody(config),
|
|
'_Installation',
|
|
{ objectId: results[0].objectId },
|
|
input
|
|
);
|
|
})
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
expect(results[0].installationId).toEqual(installId);
|
|
expect(results[0].deviceToken).toEqual(t);
|
|
expect(results[0].channels.length).toEqual(0);
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
jfail(error);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('update ios linking two existing objects', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const t = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
|
|
let input = {
|
|
installationId: installId,
|
|
deviceType: 'ios',
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => {
|
|
input = {
|
|
deviceToken: t,
|
|
deviceType: 'ios',
|
|
};
|
|
return rest.create(config, auth.nobody(config), '_Installation', input);
|
|
})
|
|
.then(() =>
|
|
database.adapter.find('_Installation', installationSchema, { deviceToken: t }, {})
|
|
)
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
input = {
|
|
deviceToken: t,
|
|
installationId: installId,
|
|
deviceType: 'ios',
|
|
};
|
|
return rest.update(
|
|
config,
|
|
auth.nobody(config),
|
|
'_Installation',
|
|
{ objectId: results[0].objectId },
|
|
input
|
|
);
|
|
})
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
expect(results[0].installationId).toEqual(installId);
|
|
expect(results[0].deviceToken).toEqual(t);
|
|
expect(results[0].deviceType).toEqual('ios');
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
jfail(error);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it_id('22311bc7-3f4f-42c1-a958-57083929e80d')(it)('update is linking two existing objects w/ increment', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const t = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
|
|
let input = {
|
|
installationId: installId,
|
|
deviceType: 'ios',
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => {
|
|
input = {
|
|
deviceToken: t,
|
|
deviceType: 'ios',
|
|
};
|
|
return rest.create(config, auth.nobody(config), '_Installation', input);
|
|
})
|
|
.then(() =>
|
|
database.adapter.find('_Installation', installationSchema, { deviceToken: t }, {})
|
|
)
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
input = {
|
|
deviceToken: t,
|
|
installationId: installId,
|
|
deviceType: 'ios',
|
|
score: {
|
|
__op: 'Increment',
|
|
amount: 1,
|
|
},
|
|
};
|
|
return rest.update(
|
|
config,
|
|
auth.nobody(config),
|
|
'_Installation',
|
|
{ objectId: results[0].objectId },
|
|
input
|
|
);
|
|
})
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
expect(results[0].installationId).toEqual(installId);
|
|
expect(results[0].deviceToken).toEqual(t);
|
|
expect(results[0].deviceType).toEqual('ios');
|
|
expect(results[0].score).toEqual(1);
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
jfail(error);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('update is linking two existing with installation id', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const t = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
|
|
let input = {
|
|
installationId: installId,
|
|
deviceType: 'ios',
|
|
};
|
|
let installObj;
|
|
let tokenObj;
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
installObj = results[0];
|
|
input = {
|
|
deviceToken: t,
|
|
deviceType: 'ios',
|
|
};
|
|
return rest.create(config, auth.nobody(config), '_Installation', input);
|
|
})
|
|
.then(() =>
|
|
database.adapter.find('_Installation', installationSchema, { deviceToken: t }, {})
|
|
)
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
tokenObj = results[0];
|
|
input = {
|
|
installationId: installId,
|
|
deviceToken: t,
|
|
deviceType: 'ios',
|
|
};
|
|
return rest.update(
|
|
config,
|
|
auth.nobody(config),
|
|
'_Installation',
|
|
{ objectId: installObj.objectId },
|
|
input
|
|
);
|
|
})
|
|
.then(() =>
|
|
database.adapter.find(
|
|
'_Installation',
|
|
installationSchema,
|
|
{ objectId: tokenObj.objectId },
|
|
{}
|
|
)
|
|
)
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
expect(results[0].installationId).toEqual(installId);
|
|
expect(results[0].deviceToken).toEqual(t);
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
jfail(error);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it_id('f2975078-eab7-4287-a932-288842e3cfb9')(it)('update is linking two existing with installation id w/ op', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const t = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
|
|
let input = {
|
|
installationId: installId,
|
|
deviceType: 'ios',
|
|
};
|
|
let installObj;
|
|
let tokenObj;
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
installObj = results[0];
|
|
input = {
|
|
deviceToken: t,
|
|
deviceType: 'ios',
|
|
};
|
|
return rest.create(config, auth.nobody(config), '_Installation', input);
|
|
})
|
|
.then(() =>
|
|
database.adapter.find('_Installation', installationSchema, { deviceToken: t }, {})
|
|
)
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
tokenObj = results[0];
|
|
input = {
|
|
installationId: installId,
|
|
deviceToken: t,
|
|
deviceType: 'ios',
|
|
score: {
|
|
__op: 'Increment',
|
|
amount: 1,
|
|
},
|
|
};
|
|
return rest.update(
|
|
config,
|
|
auth.nobody(config),
|
|
'_Installation',
|
|
{ objectId: installObj.objectId },
|
|
input
|
|
);
|
|
})
|
|
.then(() =>
|
|
database.adapter.find(
|
|
'_Installation',
|
|
installationSchema,
|
|
{ objectId: tokenObj.objectId },
|
|
{}
|
|
)
|
|
)
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
expect(results[0].installationId).toEqual(installId);
|
|
expect(results[0].deviceToken).toEqual(t);
|
|
expect(results[0].score).toEqual(1);
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
jfail(error);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('ios merge existing same token no installation id', done => {
|
|
// Test creating installation when there is an existing object with the
|
|
// same device token but no installation ID. This is possible when
|
|
// developers import device tokens from another push provider; the import
|
|
// process does not generate installation IDs. When they later integrate
|
|
// the Parse SDK, their app is going to save the installation. This save
|
|
// op will have a client-generated installation ID as well as a device
|
|
// token. At this point, if the device token matches the originally-
|
|
// imported installation, then we should reuse the existing installation
|
|
// object in case the developer already added additional fields via Data
|
|
// Browser or REST API (e.g. channel targeting info).
|
|
const t = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
let input = {
|
|
deviceToken: t,
|
|
deviceType: 'ios',
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
input = {
|
|
installationId: installId,
|
|
deviceToken: t,
|
|
deviceType: 'ios',
|
|
};
|
|
return rest.create(config, auth.nobody(config), '_Installation', input);
|
|
})
|
|
.then(() => database.adapter.find('_Installation', installationSchema, {}, {}))
|
|
.then(results => {
|
|
expect(results.length).toEqual(1);
|
|
expect(results[0].deviceToken).toEqual(t);
|
|
expect(results[0].installationId).toEqual(installId);
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
console.log(error);
|
|
fail();
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('allows you to get your own installation (regression test for #1718)', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const device = 'android';
|
|
const input = {
|
|
installationId: installId,
|
|
deviceType: device,
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(createResult => {
|
|
const headers = {
|
|
'X-Parse-Application-Id': 'test',
|
|
'X-Parse-REST-API-Key': 'rest',
|
|
};
|
|
return request({
|
|
headers: headers,
|
|
url: 'http://localhost:8378/1/installations/' + createResult.response.objectId,
|
|
}).then(response => {
|
|
const body = response.data;
|
|
expect(body.objectId).toEqual(createResult.response.objectId);
|
|
done();
|
|
});
|
|
})
|
|
.catch(error => {
|
|
console.log(error);
|
|
fail('failed');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('allows you to update installation from header (#2090)', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const device = 'android';
|
|
const input = {
|
|
installationId: installId,
|
|
deviceType: device,
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(() => {
|
|
const headers = {
|
|
'X-Parse-Application-Id': 'test',
|
|
'X-Parse-REST-API-Key': 'rest',
|
|
'X-Parse-Installation-Id': installId,
|
|
};
|
|
request({
|
|
method: 'POST',
|
|
headers: headers,
|
|
url: 'http://localhost:8378/1/classes/_Installation',
|
|
json: true,
|
|
body: {
|
|
date: new Date(),
|
|
},
|
|
}).then(response => {
|
|
const body = response.data;
|
|
expect(response.status).toBe(200);
|
|
expect(body.updatedAt).not.toBeUndefined();
|
|
done();
|
|
});
|
|
})
|
|
.catch(error => {
|
|
console.log(error);
|
|
fail('failed');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('allows you to update installation with masterKey', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const device = 'android';
|
|
const input = {
|
|
installationId: installId,
|
|
deviceType: device,
|
|
};
|
|
rest
|
|
.create(config, auth.nobody(config), '_Installation', input)
|
|
.then(createResult => {
|
|
const installationObj = Parse.Installation.createWithoutData(
|
|
createResult.response.objectId
|
|
);
|
|
installationObj.set('customField', 'custom value');
|
|
return installationObj.save(null, { useMasterKey: true });
|
|
})
|
|
.then(updateResult => {
|
|
expect(updateResult).not.toBeUndefined();
|
|
expect(updateResult.get('customField')).toEqual('custom value');
|
|
done();
|
|
})
|
|
.catch(error => {
|
|
console.log(error);
|
|
fail('failed');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should properly handle installation save #2780', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const device = 'android';
|
|
const input = {
|
|
installationId: installId,
|
|
deviceType: device,
|
|
};
|
|
rest.create(config, auth.nobody(config), '_Installation', input).then(() => {
|
|
const query = new Parse.Query(Parse.Installation);
|
|
query.equalTo('installationId', installId);
|
|
query
|
|
.first({ useMasterKey: true })
|
|
.then(installation => {
|
|
return installation.save(
|
|
{
|
|
key: 'value',
|
|
},
|
|
{ useMasterKey: true }
|
|
);
|
|
})
|
|
.then(
|
|
() => {
|
|
done();
|
|
},
|
|
err => {
|
|
jfail(err);
|
|
done();
|
|
}
|
|
);
|
|
});
|
|
});
|
|
|
|
it('should properly reject updating installationId', done => {
|
|
const installId = '12345678-abcd-abcd-abcd-123456789abc';
|
|
const device = 'android';
|
|
const input = {
|
|
installationId: installId,
|
|
deviceType: device,
|
|
};
|
|
rest.create(config, auth.nobody(config), '_Installation', input).then(() => {
|
|
const query = new Parse.Query(Parse.Installation);
|
|
query.equalTo('installationId', installId);
|
|
query
|
|
.first({ useMasterKey: true })
|
|
.then(installation => {
|
|
return installation.save(
|
|
{
|
|
key: 'value',
|
|
installationId: '22222222-abcd-abcd-abcd-123456789abc',
|
|
},
|
|
{ useMasterKey: true }
|
|
);
|
|
})
|
|
.then(
|
|
() => {
|
|
fail('should not succeed');
|
|
done();
|
|
},
|
|
err => {
|
|
expect(err.code).toBe(136);
|
|
expect(err.message).toBe('installationId may not be changed in this operation');
|
|
done();
|
|
}
|
|
);
|
|
});
|
|
});
|
|
|
|
it_id('e581faea-c1b4-4c64-af8c-52287ce6cd06')(it)('can use push with beforeSave', async () => {
|
|
const input = {
|
|
deviceToken: '11433856eed2f1285fb3aa11136718c1198ed5647875096952c66bf8cb976306',
|
|
deviceType: 'ios',
|
|
};
|
|
await rest.create(config, auth.nobody(config), '_Installation', input);
|
|
const functions = {
|
|
beforeSave() {},
|
|
afterSave() {},
|
|
};
|
|
spyOn(functions, 'beforeSave').and.callThrough();
|
|
spyOn(functions, 'afterSave').and.callThrough();
|
|
Parse.Cloud.beforeSave(Parse.Installation, functions.beforeSave);
|
|
Parse.Cloud.afterSave(Parse.Installation, functions.afterSave);
|
|
await Parse.Push.send({
|
|
where: {
|
|
deviceType: 'ios',
|
|
},
|
|
data: {
|
|
badge: 'increment',
|
|
alert: 'Hello world!',
|
|
},
|
|
});
|
|
|
|
await Parse.Push.send({
|
|
where: {
|
|
deviceType: 'ios',
|
|
},
|
|
data: {
|
|
badge: 'increment',
|
|
alert: 'Hello world!',
|
|
},
|
|
});
|
|
|
|
await Parse.Push.send({
|
|
where: {
|
|
deviceType: 'ios',
|
|
},
|
|
data: {
|
|
badge: 'increment',
|
|
alert: 'Hello world!',
|
|
},
|
|
});
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
const installation = await new Parse.Query(Parse.Installation).first({ useMasterKey: true });
|
|
expect(installation.get('badge')).toEqual(3);
|
|
expect(functions.beforeSave).not.toHaveBeenCalled();
|
|
expect(functions.afterSave).not.toHaveBeenCalled();
|
|
});
|
|
|
|
// TODO: Look at additional tests from installation_collection_test.go:882
|
|
// TODO: Do we need to support _tombstone disabling of installations?
|
|
// TODO: Test deletion, badge increments
|
|
});
|