Skip to content

Commit

Permalink
Test transactions (parse-community#6022)
Browse files Browse the repository at this point in the history
* Test transactions

* test: Separate transaction tests for SDK
  • Loading branch information
davimacedo authored Sep 5, 2019
1 parent e7539ad commit b66d9cc
Showing 1 changed file with 228 additions and 0 deletions.
228 changes: 228 additions & 0 deletions spec/MongoStorageAdapter.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ const MongoStorageAdapter = require('../lib/Adapters/Storage/Mongo/MongoStorageA
const { MongoClient } = require('mongodb');
const databaseURI =
'mongodb://localhost:27017/parseServerMongoAdapterTestDatabase';
const request = require('../lib/request');
const Config = require('../lib/Config');
const TestUtils = require('../lib/TestUtils');

const fakeClient = {
s: { options: { dbName: null } },
Expand Down Expand Up @@ -316,4 +319,229 @@ describe_only_db('mongo')('MongoStorageAdapter', () => {
undefined
);
});

if (
process.env.MONGODB_VERSION === '4.0.4' &&
process.env.MONGODB_TOPOLOGY === 'replicaset' &&
process.env.MONGODB_STORAGE_ENGINE === 'wiredTiger'
) {
describe('transactions', () => {
const headers = {
'Content-Type': 'application/json',
'X-Parse-Application-Id': 'test',
'X-Parse-REST-API-Key': 'rest',
};

beforeAll(async () => {
await reconfigureServer({
databaseAdapter: undefined,
databaseURI:
'mongodb://localhost:27017/parseServerMongoAdapterTestDatabase?replicaSet=replicaset',
});
});

beforeEach(async () => {
await TestUtils.destroyAllDataPermanently(true);
});

it('should use transaction in a batch with transaction = true', async () => {
const myObject = new Parse.Object('MyObject');
await myObject.save();

const databaseAdapter = Config.get(Parse.applicationId).database
.adapter;
spyOn(
databaseAdapter.database.serverConfig,
'command'
).and.callThrough();

await request({
method: 'POST',
headers: headers,
url: 'http://localhost:8378/1/batch',
body: JSON.stringify({
requests: [
{
method: 'PUT',
path: '/1/classes/MyObject/' + myObject.id,
body: { myAttribute: 'myValue' },
},
],
transaction: true,
}),
});

let found = false;
databaseAdapter.database.serverConfig.command.calls
.all()
.forEach(call => {
found = true;
expect(call.args[2].session.transaction.state).not.toBe(
'NO_TRANSACTION'
);
});
expect(found).toBe(true);
});

it('should not use transaction in a batch with transaction = false', async () => {
const myObject = new Parse.Object('MyObject');
await myObject.save();

const databaseAdapter = Config.get(Parse.applicationId).database
.adapter;
spyOn(
databaseAdapter.database.serverConfig,
'command'
).and.callThrough();

await request({
method: 'POST',
headers: headers,
url: 'http://localhost:8378/1/batch',
body: JSON.stringify({
requests: [
{
method: 'PUT',
path: '/1/classes/MyObject/' + myObject.id,
body: { myAttribute: 'myValue' },
},
],
transaction: false,
}),
});

let found = false;
databaseAdapter.database.serverConfig.command.calls
.all()
.forEach(call => {
found = true;
expect(call.args[2].session).toBe(undefined);
});
expect(found).toBe(true);
});

it('should not use transaction in a batch with no transaction option sent', async () => {
const myObject = new Parse.Object('MyObject');
await myObject.save();

const databaseAdapter = Config.get(Parse.applicationId).database
.adapter;
spyOn(
databaseAdapter.database.serverConfig,
'command'
).and.callThrough();

await request({
method: 'POST',
headers: headers,
url: 'http://localhost:8378/1/batch',
body: JSON.stringify({
requests: [
{
method: 'PUT',
path: '/1/classes/MyObject/' + myObject.id,
body: { myAttribute: 'myValue' },
},
],
}),
});

let found = false;
databaseAdapter.database.serverConfig.command.calls
.all()
.forEach(call => {
found = true;
expect(call.args[2].session).toBe(undefined);
});
expect(found).toBe(true);
});

it('should not use transaction in a put request', async () => {
const myObject = new Parse.Object('MyObject');
await myObject.save();

const databaseAdapter = Config.get(Parse.applicationId).database
.adapter;
spyOn(
databaseAdapter.database.serverConfig,
'command'
).and.callThrough();

await request({
method: 'PUT',
headers: headers,
url: 'http://localhost:8378/1/classes/MyObject/' + myObject.id,
body: { myAttribute: 'myValue' },
});

let found = false;
databaseAdapter.database.serverConfig.command.calls
.all()
.forEach(call => {
found = true;
expect(call.args[2].session).toBe(undefined);
});
expect(found).toBe(true);
});

it('should not use transactions when using SDK insert', async () => {
const databaseAdapter = Config.get(Parse.applicationId).database
.adapter;
spyOn(
databaseAdapter.database.serverConfig,
'insert'
).and.callThrough();

const myObject = new Parse.Object('MyObject');
await myObject.save();

const calls = databaseAdapter.database.serverConfig.insert.calls.all();
expect(calls.length).toBeGreaterThan(0);
calls.forEach(call => {
expect(call.args[2].session.transaction.state).toBe('NO_TRANSACTION');
});
});

it('should not use transactions when using SDK update', async () => {
const databaseAdapter = Config.get(Parse.applicationId).database
.adapter;
spyOn(
databaseAdapter.database.serverConfig,
'update'
).and.callThrough();

const myObject = new Parse.Object('MyObject');
await myObject.save();

myObject.set('myAttribute', 'myValue');
await myObject.save();

const calls = databaseAdapter.database.serverConfig.update.calls.all();
expect(calls.length).toBeGreaterThan(0);
calls.forEach(call => {
expect(call.args[2].session.transaction.state).toBe('NO_TRANSACTION');
});
});

it('should not use transactions when using SDK delete', async () => {
const databaseAdapter = Config.get(Parse.applicationId).database
.adapter;
spyOn(
databaseAdapter.database.serverConfig,
'remove'
).and.callThrough();

const myObject = new Parse.Object('MyObject');
await myObject.save();

await myObject.destroy();

const calls = databaseAdapter.database.serverConfig.remove.calls.all();
expect(calls.length).toBeGreaterThan(0);
calls.forEach(call => {
expect(call.args[2].session.transaction.state).toBe('NO_TRANSACTION');
});
});
});
}
});

0 comments on commit b66d9cc

Please sign in to comment.