test: improve transaction tests to use async/await (#7759)
This commit is contained in:
@@ -15,35 +15,18 @@ describe('ParseServerRESTController', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle a get request', done => {
|
||||
RESTController.request('GET', '/classes/MyObject').then(
|
||||
res => {
|
||||
expect(res.results.length).toBe(0);
|
||||
done();
|
||||
},
|
||||
err => {
|
||||
console.log(err);
|
||||
jfail(err);
|
||||
done();
|
||||
}
|
||||
);
|
||||
it('should handle a get request', async () => {
|
||||
const res = await RESTController.request('GET', '/classes/MyObject');
|
||||
expect(res.results.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should handle a get request with full serverURL mount path', done => {
|
||||
RESTController.request('GET', '/1/classes/MyObject').then(
|
||||
res => {
|
||||
expect(res.results.length).toBe(0);
|
||||
done();
|
||||
},
|
||||
err => {
|
||||
jfail(err);
|
||||
done();
|
||||
}
|
||||
);
|
||||
it('should handle a get request with full serverURL mount path', async () => {
|
||||
const res = await RESTController.request('GET', '/1/classes/MyObject');
|
||||
expect(res.results.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should handle a POST batch without transaction', done => {
|
||||
RESTController.request('POST', 'batch', {
|
||||
it('should handle a POST batch without transaction', async () => {
|
||||
const res = await RESTController.request('POST', 'batch', {
|
||||
requests: [
|
||||
{
|
||||
method: 'GET',
|
||||
@@ -59,20 +42,12 @@ describe('ParseServerRESTController', () => {
|
||||
path: '/classes/MyObject',
|
||||
},
|
||||
],
|
||||
}).then(
|
||||
res => {
|
||||
expect(res.length).toBe(3);
|
||||
done();
|
||||
},
|
||||
err => {
|
||||
jfail(err);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
expect(res.length).toBe(3);
|
||||
});
|
||||
|
||||
it('should handle a POST batch with transaction=false', done => {
|
||||
RESTController.request('POST', 'batch', {
|
||||
it('should handle a POST batch with transaction=false', async () => {
|
||||
const res = await RESTController.request('POST', 'batch', {
|
||||
requests: [
|
||||
{
|
||||
method: 'GET',
|
||||
@@ -89,16 +64,8 @@ describe('ParseServerRESTController', () => {
|
||||
},
|
||||
],
|
||||
transaction: false,
|
||||
}).then(
|
||||
res => {
|
||||
expect(res.length).toBe(3);
|
||||
done();
|
||||
},
|
||||
err => {
|
||||
jfail(err);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
expect(res.length).toBe(3);
|
||||
});
|
||||
|
||||
it('should handle response status', async () => {
|
||||
@@ -186,54 +153,43 @@ describe('ParseServerRESTController', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should handle a batch request with transaction = true', async done => {
|
||||
await reconfigureServer();
|
||||
it('should handle a batch request with transaction = true', async () => {
|
||||
const myObject = new Parse.Object('MyObject'); // This is important because transaction only works on pre-existing collections
|
||||
myObject
|
||||
.save()
|
||||
.then(() => {
|
||||
return myObject.destroy();
|
||||
})
|
||||
.then(() => {
|
||||
spyOn(databaseAdapter, 'createObject').and.callThrough();
|
||||
|
||||
return RESTController.request('POST', 'batch', {
|
||||
requests: [
|
||||
{
|
||||
method: 'POST',
|
||||
path: '/1/classes/MyObject',
|
||||
body: { key: 'value1' },
|
||||
},
|
||||
{
|
||||
method: 'POST',
|
||||
path: '/1/classes/MyObject',
|
||||
body: { key: 'value2' },
|
||||
},
|
||||
],
|
||||
transaction: true,
|
||||
}).then(response => {
|
||||
expect(response.length).toEqual(2);
|
||||
expect(response[0].success.objectId).toBeDefined();
|
||||
expect(response[0].success.createdAt).toBeDefined();
|
||||
expect(response[1].success.objectId).toBeDefined();
|
||||
expect(response[1].success.createdAt).toBeDefined();
|
||||
const query = new Parse.Query('MyObject');
|
||||
return query.find().then(results => {
|
||||
expect(databaseAdapter.createObject.calls.count() % 2).toBe(0);
|
||||
for (let i = 0; i + 1 < databaseAdapter.createObject.calls.length; i = i + 2) {
|
||||
expect(databaseAdapter.createObject.calls.argsFor(i)[3]).toBe(
|
||||
databaseAdapter.createObject.calls.argsFor(i + 1)[3]
|
||||
);
|
||||
}
|
||||
expect(results.map(result => result.get('key')).sort()).toEqual([
|
||||
'value1',
|
||||
'value2',
|
||||
]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(done.fail);
|
||||
await myObject.save();
|
||||
await myObject.destroy();
|
||||
spyOn(databaseAdapter, 'createObject').and.callThrough();
|
||||
const response = await RESTController.request('POST', 'batch', {
|
||||
requests: [
|
||||
{
|
||||
method: 'POST',
|
||||
path: '/1/classes/MyObject',
|
||||
body: { key: 'value1' },
|
||||
},
|
||||
{
|
||||
method: 'POST',
|
||||
path: '/1/classes/MyObject',
|
||||
body: { key: 'value2' },
|
||||
},
|
||||
],
|
||||
transaction: true,
|
||||
});
|
||||
expect(response.length).toEqual(2);
|
||||
expect(response[0].success.objectId).toBeDefined();
|
||||
expect(response[0].success.createdAt).toBeDefined();
|
||||
expect(response[1].success.objectId).toBeDefined();
|
||||
expect(response[1].success.createdAt).toBeDefined();
|
||||
const query = new Parse.Query('MyObject');
|
||||
const results = await query.find();
|
||||
expect(databaseAdapter.createObject.calls.count() % 2).toBe(0);
|
||||
for (let i = 0; i + 1 < databaseAdapter.createObject.calls.length; i = i + 2) {
|
||||
expect(databaseAdapter.createObject.calls.argsFor(i)[3]).toBe(
|
||||
databaseAdapter.createObject.calls.argsFor(i + 1)[3]
|
||||
);
|
||||
}
|
||||
expect(results.map(result => result.get('key')).sort()).toEqual([
|
||||
'value1',
|
||||
'value2',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not save anything when one operation fails in a transaction', async () => {
|
||||
@@ -560,21 +516,11 @@ describe('ParseServerRESTController', () => {
|
||||
});
|
||||
}
|
||||
|
||||
it('should handle a POST request', done => {
|
||||
RESTController.request('POST', '/classes/MyObject', { key: 'value' })
|
||||
.then(() => {
|
||||
return RESTController.request('GET', '/classes/MyObject');
|
||||
})
|
||||
.then(res => {
|
||||
expect(res.results.length).toBe(1);
|
||||
expect(res.results[0].key).toEqual('value');
|
||||
done();
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
jfail(err);
|
||||
done();
|
||||
});
|
||||
it('should handle a POST request', async () => {
|
||||
await RESTController.request('POST', '/classes/MyObject', { key: 'value' });
|
||||
const res = await RESTController.request('GET', '/classes/MyObject');
|
||||
expect(res.results.length).toBe(1);
|
||||
expect(res.results[0].key).toEqual('value');
|
||||
});
|
||||
|
||||
it('should handle a POST request with context', async () => {
|
||||
@@ -593,125 +539,76 @@ describe('ParseServerRESTController', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('ensures sessionTokens are properly handled', done => {
|
||||
let userId;
|
||||
Parse.User.signUp('user', 'pass')
|
||||
.then(user => {
|
||||
userId = user.id;
|
||||
const sessionToken = user.getSessionToken();
|
||||
return RESTController.request('GET', '/users/me', undefined, {
|
||||
sessionToken,
|
||||
});
|
||||
})
|
||||
.then(res => {
|
||||
// Result is in JSON format
|
||||
expect(res.objectId).toEqual(userId);
|
||||
done();
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
jfail(err);
|
||||
done();
|
||||
it('ensures sessionTokens are properly handled', async () => {
|
||||
const user = await Parse.User.signUp('user', 'pass');
|
||||
const sessionToken = user.getSessionToken();
|
||||
const res = await RESTController.request('GET', '/users/me', undefined, {
|
||||
sessionToken,
|
||||
});
|
||||
// Result is in JSON format
|
||||
expect(res.objectId).toEqual(user.id);
|
||||
});
|
||||
|
||||
it('ensures masterKey is properly handled', async () => {
|
||||
const user = await Parse.User.signUp('user', 'pass');
|
||||
const userId = user.id;
|
||||
await Parse.User.logOut();
|
||||
const res = await RESTController.request('GET', '/classes/_User', undefined, {
|
||||
useMasterKey: true,
|
||||
});
|
||||
expect(res.results.length).toBe(1);
|
||||
expect(res.results[0].objectId).toEqual(userId);
|
||||
});
|
||||
|
||||
it('ensures no user is created when passing an empty username', async () => {
|
||||
try {
|
||||
await RESTController.request('POST', '/classes/_User', {
|
||||
username: '',
|
||||
password: 'world',
|
||||
});
|
||||
fail('Success callback should not be called when passing an empty username.');
|
||||
} catch (err) {
|
||||
expect(err.code).toBe(Parse.Error.USERNAME_MISSING);
|
||||
expect(err.message).toBe('bad or missing username');
|
||||
}
|
||||
});
|
||||
|
||||
it('ensures masterKey is properly handled', done => {
|
||||
let userId;
|
||||
Parse.User.signUp('user', 'pass')
|
||||
.then(user => {
|
||||
userId = user.id;
|
||||
return Parse.User.logOut().then(() => {
|
||||
return RESTController.request('GET', '/classes/_User', undefined, {
|
||||
useMasterKey: true,
|
||||
});
|
||||
});
|
||||
})
|
||||
.then(
|
||||
res => {
|
||||
expect(res.results.length).toBe(1);
|
||||
expect(res.results[0].objectId).toEqual(userId);
|
||||
done();
|
||||
},
|
||||
err => {
|
||||
jfail(err);
|
||||
done();
|
||||
}
|
||||
);
|
||||
it('ensures no user is created when passing an empty password', async () => {
|
||||
try {
|
||||
await RESTController.request('POST', '/classes/_User', {
|
||||
username: 'hello',
|
||||
password: '',
|
||||
});
|
||||
fail('Success callback should not be called when passing an empty password.');
|
||||
} catch (err) {
|
||||
expect(err.code).toBe(Parse.Error.PASSWORD_MISSING);
|
||||
expect(err.message).toBe('password is required');
|
||||
}
|
||||
});
|
||||
|
||||
it('ensures no user is created when passing an empty username', done => {
|
||||
RESTController.request('POST', '/classes/_User', {
|
||||
username: '',
|
||||
password: 'world',
|
||||
}).then(
|
||||
() => {
|
||||
jfail(new Error('Success callback should not be called when passing an empty username.'));
|
||||
done();
|
||||
},
|
||||
err => {
|
||||
expect(err.code).toBe(Parse.Error.USERNAME_MISSING);
|
||||
expect(err.message).toBe('bad or missing username');
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('ensures no user is created when passing an empty password', done => {
|
||||
RESTController.request('POST', '/classes/_User', {
|
||||
username: 'hello',
|
||||
password: '',
|
||||
}).then(
|
||||
() => {
|
||||
jfail(new Error('Success callback should not be called when passing an empty password.'));
|
||||
done();
|
||||
},
|
||||
err => {
|
||||
expect(err.code).toBe(Parse.Error.PASSWORD_MISSING);
|
||||
expect(err.message).toBe('password is required');
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('ensures no session token is created on creating users', done => {
|
||||
RESTController.request('POST', '/classes/_User', {
|
||||
it('ensures no session token is created on creating users', async () => {
|
||||
const user = await RESTController.request('POST', '/classes/_User', {
|
||||
username: 'hello',
|
||||
password: 'world',
|
||||
})
|
||||
.then(user => {
|
||||
expect(user.sessionToken).toBeUndefined();
|
||||
const query = new Parse.Query('_Session');
|
||||
return query.find({ useMasterKey: true });
|
||||
})
|
||||
.then(sessions => {
|
||||
expect(sessions.length).toBe(0);
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
expect(user.sessionToken).toBeUndefined();
|
||||
const query = new Parse.Query('_Session');
|
||||
const sessions = await query.find({ useMasterKey: true });
|
||||
expect(sessions.length).toBe(0);
|
||||
});
|
||||
|
||||
it('ensures a session token is created when passing installationId != cloud', done => {
|
||||
RESTController.request(
|
||||
it('ensures a session token is created when passing installationId != cloud', async () => {
|
||||
const user = await RESTController.request(
|
||||
'POST',
|
||||
'/classes/_User',
|
||||
{ username: 'hello', password: 'world' },
|
||||
{ installationId: 'my-installation' }
|
||||
)
|
||||
.then(user => {
|
||||
expect(user.sessionToken).not.toBeUndefined();
|
||||
const query = new Parse.Query('_Session');
|
||||
return query.find({ useMasterKey: true });
|
||||
})
|
||||
.then(
|
||||
sessions => {
|
||||
expect(sessions.length).toBe(1);
|
||||
expect(sessions[0].get('installationId')).toBe('my-installation');
|
||||
done();
|
||||
},
|
||||
err => {
|
||||
jfail(err);
|
||||
done();
|
||||
}
|
||||
);
|
||||
);
|
||||
expect(user.sessionToken).not.toBeUndefined();
|
||||
const query = new Parse.Query('_Session');
|
||||
const sessions = await query.find({ useMasterKey: true });
|
||||
expect(sessions.length).toBe(1);
|
||||
expect(sessions[0].get('installationId')).toBe('my-installation');
|
||||
});
|
||||
|
||||
it('ensures logIn is saved with installationId', async () => {
|
||||
|
||||
@@ -89,10 +89,32 @@ describe('batch', () => {
|
||||
expect(internalURL).toEqual('/classes/Object');
|
||||
});
|
||||
|
||||
it('should handle a batch request without transaction', async done => {
|
||||
it('should return the proper url with no url provided', () => {
|
||||
const originalURL = '/parse/batch';
|
||||
const internalURL = batch.makeBatchRoutingPathFunction(
|
||||
originalURL,
|
||||
undefined,
|
||||
publicServerURL
|
||||
)('/parse/classes/Object');
|
||||
|
||||
expect(internalURL).toEqual('/classes/Object');
|
||||
});
|
||||
|
||||
it('should return the proper url with no public url provided', () => {
|
||||
const originalURL = '/parse/batch';
|
||||
const internalURL = batch.makeBatchRoutingPathFunction(
|
||||
originalURL,
|
||||
serverURLNaked,
|
||||
undefined
|
||||
)('/parse/classes/Object');
|
||||
|
||||
expect(internalURL).toEqual('/classes/Object');
|
||||
});
|
||||
|
||||
it('should handle a batch request without transaction', async () => {
|
||||
spyOn(databaseAdapter, 'createObject').and.callThrough();
|
||||
|
||||
request({
|
||||
const response = await request({
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
url: 'http://localhost:8378/1/batch',
|
||||
@@ -110,28 +132,25 @@ describe('batch', () => {
|
||||
},
|
||||
],
|
||||
}),
|
||||
}).then(response => {
|
||||
expect(response.data.length).toEqual(2);
|
||||
expect(response.data[0].success.objectId).toBeDefined();
|
||||
expect(response.data[0].success.createdAt).toBeDefined();
|
||||
expect(response.data[1].success.objectId).toBeDefined();
|
||||
expect(response.data[1].success.createdAt).toBeDefined();
|
||||
const query = new Parse.Query('MyObject');
|
||||
query.find().then(results => {
|
||||
expect(databaseAdapter.createObject.calls.count()).toBe(2);
|
||||
expect(databaseAdapter.createObject.calls.argsFor(0)[3]).toEqual(null);
|
||||
expect(databaseAdapter.createObject.calls.argsFor(1)[3]).toEqual(null);
|
||||
expect(results.map(result => result.get('key')).sort()).toEqual(['value1', 'value2']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
expect(response.data.length).toEqual(2);
|
||||
expect(response.data[0].success.objectId).toBeDefined();
|
||||
expect(response.data[0].success.createdAt).toBeDefined();
|
||||
expect(response.data[1].success.objectId).toBeDefined();
|
||||
expect(response.data[1].success.createdAt).toBeDefined();
|
||||
const query = new Parse.Query('MyObject');
|
||||
const results = await query.find();
|
||||
expect(databaseAdapter.createObject.calls.count()).toBe(2);
|
||||
expect(databaseAdapter.createObject.calls.argsFor(0)[3]).toEqual(null);
|
||||
expect(databaseAdapter.createObject.calls.argsFor(1)[3]).toEqual(null);
|
||||
expect(results.map(result => result.get('key')).sort()).toEqual(['value1', 'value2']);
|
||||
});
|
||||
|
||||
it('should handle a batch request with transaction = false', async done => {
|
||||
await reconfigureServer();
|
||||
it('should handle a batch request with transaction = false', async () => {
|
||||
spyOn(databaseAdapter, 'createObject').and.callThrough();
|
||||
|
||||
request({
|
||||
const response = await request({
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
url: 'http://localhost:8378/1/batch',
|
||||
@@ -150,21 +169,18 @@ describe('batch', () => {
|
||||
],
|
||||
transaction: false,
|
||||
}),
|
||||
}).then(response => {
|
||||
expect(response.data.length).toEqual(2);
|
||||
expect(response.data[0].success.objectId).toBeDefined();
|
||||
expect(response.data[0].success.createdAt).toBeDefined();
|
||||
expect(response.data[1].success.objectId).toBeDefined();
|
||||
expect(response.data[1].success.createdAt).toBeDefined();
|
||||
const query = new Parse.Query('MyObject');
|
||||
query.find().then(results => {
|
||||
expect(databaseAdapter.createObject.calls.count()).toBe(2);
|
||||
expect(databaseAdapter.createObject.calls.argsFor(0)[3]).toEqual(null);
|
||||
expect(databaseAdapter.createObject.calls.argsFor(1)[3]).toEqual(null);
|
||||
expect(results.map(result => result.get('key')).sort()).toEqual(['value1', 'value2']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
expect(response.data.length).toEqual(2);
|
||||
expect(response.data[0].success.objectId).toBeDefined();
|
||||
expect(response.data[0].success.createdAt).toBeDefined();
|
||||
expect(response.data[1].success.objectId).toBeDefined();
|
||||
expect(response.data[1].success.createdAt).toBeDefined();
|
||||
const query = new Parse.Query('MyObject');
|
||||
const results = await query.find();
|
||||
expect(databaseAdapter.createObject.calls.count()).toBe(2);
|
||||
expect(databaseAdapter.createObject.calls.argsFor(0)[3]).toEqual(null);
|
||||
expect(databaseAdapter.createObject.calls.argsFor(1)[3]).toEqual(null);
|
||||
expect(results.map(result => result.get('key')).sort()).toEqual(['value1', 'value2']);
|
||||
});
|
||||
|
||||
if (
|
||||
@@ -191,58 +207,48 @@ describe('batch', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should handle a batch request with transaction = true', async done => {
|
||||
await reconfigureServer();
|
||||
it('should handle a batch request with transaction = true', async () => {
|
||||
const myObject = new Parse.Object('MyObject'); // This is important because transaction only works on pre-existing collections
|
||||
myObject
|
||||
.save()
|
||||
.then(() => {
|
||||
return myObject.destroy();
|
||||
})
|
||||
.then(() => {
|
||||
spyOn(databaseAdapter, 'createObject').and.callThrough();
|
||||
|
||||
request({
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
url: 'http://localhost:8378/1/batch',
|
||||
body: JSON.stringify({
|
||||
requests: [
|
||||
{
|
||||
method: 'POST',
|
||||
path: '/1/classes/MyObject',
|
||||
body: { key: 'value1' },
|
||||
},
|
||||
{
|
||||
method: 'POST',
|
||||
path: '/1/classes/MyObject',
|
||||
body: { key: 'value2' },
|
||||
},
|
||||
],
|
||||
transaction: true,
|
||||
}),
|
||||
}).then(response => {
|
||||
expect(response.data.length).toEqual(2);
|
||||
expect(response.data[0].success.objectId).toBeDefined();
|
||||
expect(response.data[0].success.createdAt).toBeDefined();
|
||||
expect(response.data[1].success.objectId).toBeDefined();
|
||||
expect(response.data[1].success.createdAt).toBeDefined();
|
||||
const query = new Parse.Query('MyObject');
|
||||
query.find().then(results => {
|
||||
expect(databaseAdapter.createObject.calls.count() % 2).toBe(0);
|
||||
for (let i = 0; i + 1 < databaseAdapter.createObject.calls.length; i = i + 2) {
|
||||
expect(databaseAdapter.createObject.calls.argsFor(i)[3]).toBe(
|
||||
databaseAdapter.createObject.calls.argsFor(i + 1)[3]
|
||||
);
|
||||
}
|
||||
expect(results.map(result => result.get('key')).sort()).toEqual([
|
||||
'value1',
|
||||
'value2',
|
||||
]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
await myObject.save();
|
||||
await myObject.destroy();
|
||||
spyOn(databaseAdapter, 'createObject').and.callThrough();
|
||||
const response = await request({
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
url: 'http://localhost:8378/1/batch',
|
||||
body: JSON.stringify({
|
||||
requests: [
|
||||
{
|
||||
method: 'POST',
|
||||
path: '/1/classes/MyObject',
|
||||
body: { key: 'value1' },
|
||||
},
|
||||
{
|
||||
method: 'POST',
|
||||
path: '/1/classes/MyObject',
|
||||
body: { key: 'value2' },
|
||||
},
|
||||
],
|
||||
transaction: true,
|
||||
}),
|
||||
});
|
||||
expect(response.data.length).toEqual(2);
|
||||
expect(response.data[0].success.objectId).toBeDefined();
|
||||
expect(response.data[0].success.createdAt).toBeDefined();
|
||||
expect(response.data[1].success.objectId).toBeDefined();
|
||||
expect(response.data[1].success.createdAt).toBeDefined();
|
||||
const query = new Parse.Query('MyObject');
|
||||
const results = await query.find();
|
||||
expect(databaseAdapter.createObject.calls.count() % 2).toBe(0);
|
||||
for (let i = 0; i + 1 < databaseAdapter.createObject.calls.length; i = i + 2) {
|
||||
expect(databaseAdapter.createObject.calls.argsFor(i)[3]).toBe(
|
||||
databaseAdapter.createObject.calls.argsFor(i + 1)[3]
|
||||
);
|
||||
}
|
||||
expect(results.map(result => result.get('key')).sort()).toEqual([
|
||||
'value1',
|
||||
'value2',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not save anything when one operation fails in a transaction', async () => {
|
||||
@@ -350,6 +356,7 @@ describe('batch', () => {
|
||||
transaction: true,
|
||||
}),
|
||||
});
|
||||
fail();
|
||||
} catch (error) {
|
||||
expect(error).toBeDefined();
|
||||
const query = new Parse.Query('MyObject');
|
||||
|
||||
Reference in New Issue
Block a user