Unique indexes (#1971)

* Add unique indexing

* Add unique indexing for username/email

* WIP

* Finish unique indexes

* Notes on how to upgrade to 2.3.0 safely

* index on unique-indexes: c454180 Revert "Log objects rather than JSON stringified objects (#1922)"

* reconfigure username/email tests

* Start dealing with test shittyness

* Remove tests for files that we are removing

* most tests passing

* fix failing test

* Make specific server config for tests async

* Fix more tests

* fix more tests

* Fix another test

* fix more tests

* Fix email validation

* move some stuff around

* Destroy server to ensure all connections are gone

* Fix broken cloud code

* Save callback to variable

* no need to delete non existant cloud

* undo

* Fix all tests where connections are left open after server closes.

* Fix issues caused by missing gridstore adapter

* Update guide for 2.3.0 and fix final tests

* use strict

* don't use features that won't work in node 4

* Fix syntax error

* Fix typos

* Add duplicate finding command

* Update 2.3.0.md
This commit is contained in:
Drew
2016-06-10 20:27:21 -07:00
committed by GitHub
parent 6415a35433
commit 7e868b2dcc
37 changed files with 1727 additions and 1517 deletions

View File

@@ -1,6 +1,7 @@
"use strict"
// Sets up a Parse API server for testing.
jasmine.DEFAULT_TIMEOUT_INTERVAL = 15000;
jasmine.DEFAULT_TIMEOUT_INTERVAL = process.env.PARSE_SERVER_TEST_TIMEOUT || 3000;
var cache = require('../src/cache').default;
var DatabaseAdapter = require('../src/DatabaseAdapter');
@@ -10,13 +11,23 @@ var ParseServer = require('../src/index').ParseServer;
var path = require('path');
var TestUtils = require('../src/index').TestUtils;
var MongoStorageAdapter = require('../src/Adapters/Storage/Mongo/MongoStorageAdapter');
const GridStoreAdapter = require('../src/Adapters/Files/GridStoreAdapter').GridStoreAdapter;
var databaseURI = 'mongodb://localhost:27017/parseServerMongoAdapterTestDatabase';
var port = 8378;
let mongoURI = 'mongodb://localhost:27017/parseServerMongoAdapterTestDatabase';
let mongoAdapter = new MongoStorageAdapter({
uri: mongoURI,
collectionPrefix: 'test_',
})
let gridStoreAdapter = new GridStoreAdapter(mongoURI);
// Default server configuration for tests.
var defaultConfiguration = {
databaseURI: databaseURI,
databaseAdapter: mongoAdapter,
filesAdapter: gridStoreAdapter,
serverURL: 'http://localhost:' + port + '/1',
appId: 'test',
javascriptKey: 'test',
@@ -25,14 +36,13 @@ var defaultConfiguration = {
restAPIKey: 'rest',
webhookKey: 'hook',
masterKey: 'test',
collectionPrefix: 'test_',
fileKey: 'test',
push: {
'ios': {
cert: 'prodCert.pem',
key: 'prodKey.pem',
production: true,
bundleId: 'bundleId'
bundleId: 'bundleId',
}
},
oauth: { // Override the facebook provider
@@ -43,33 +53,45 @@ var defaultConfiguration = {
},
};
let openConnections = {};
// Set up a default API server for testing with default configuration.
var api = new ParseServer(defaultConfiguration);
var app = express();
app.use('/1', api);
var server = app.listen(port);
server.on('connection', connection => {
let key = `${connection.remoteAddress}:${connection.remotePort}`;
openConnections[key] = connection;
connection.on('close', () => { delete openConnections[key] });
});
// Prevent reinitializing the server from clobbering Cloud Code
delete defaultConfiguration.cloud;
var currentConfiguration;
// Allows testing specific configurations of Parse Server
const setServerConfiguration = configuration => {
// the configuration hasn't changed
if (configuration === currentConfiguration) {
return;
}
DatabaseAdapter.clearDatabaseSettings();
currentConfiguration = configuration;
server.close();
cache.clear();
app = express();
api = new ParseServer(configuration);
app.use('/1', api);
server = app.listen(port);
};
const reconfigureServer = changedConfiguration => {
return new Promise((resolve, reject) => {
server.close(() => {
try {
let newConfiguration = Object.assign({}, defaultConfiguration, changedConfiguration, {
__indexBuildCompletionCallbackForTests: indexBuildPromise => indexBuildPromise.then(resolve, reject)
});
cache.clear();
app = express();
api = new ParseServer(newConfiguration);
app.use('/1', api);
var restoreServerConfiguration = () => setServerConfiguration(defaultConfiguration);
server = app.listen(port);
server.on('connection', connection => {
let key = `${connection.remoteAddress}:${connection.remotePort}`;
openConnections[key] = connection;
connection.on('close', () => { delete openConnections[key] });
});
} catch(error) {
reject(error);
}
});
});
}
// Set up a Parse client to talk to our test API server
var Parse = require('parse/node');
@@ -79,19 +101,35 @@ Parse.serverURL = 'http://localhost:' + port + '/1';
// TODO: update tests to work in an A+ way
Parse.Promise.disableAPlusCompliant();
beforeEach(function(done) {
restoreServerConfiguration();
Parse.initialize('test', 'test', 'test');
Parse.serverURL = 'http://localhost:' + port + '/1';
Parse.User.enableUnsafeCurrentUser();
return TestUtils.destroyAllDataPermanently().then(done, fail);
beforeEach(done => {
try {
Parse.User.enableUnsafeCurrentUser();
} catch (error) {
if (error !== 'You need to call Parse.initialize before using Parse.') {
throw error;
}
}
TestUtils.destroyAllDataPermanently()
.catch(error => {
// For tests that connect to their own mongo, there won't be any data to delete.
if (error.message === 'ns not found' || error.message.startsWith('connect ECONNREFUSED')) {
return;
} else {
fail(error);
return;
}
})
.then(reconfigureServer)
.then(() => {
Parse.initialize('test', 'test', 'test');
Parse.serverURL = 'http://localhost:' + port + '/1';
done();
}, error => {
fail(JSON.stringify(error));
done();
})
});
var mongoAdapter = new MongoStorageAdapter({
collectionPrefix: defaultConfiguration.collectionPrefix,
uri: databaseURI,
})
afterEach(function(done) {
Parse.Cloud._removeAllHooks();
mongoAdapter.getAllSchemas()
@@ -111,11 +149,13 @@ afterEach(function(done) {
})
.then(() => Parse.User.logOut())
.then(() => {
return TestUtils.destroyAllDataPermanently();
}).then(() => {
if (Object.keys(openConnections).length > 0) {
fail('There were open connections to the server left after the test finished');
}
done();
}, (error) => {
console.log('error in clearData', error);
})
.catch(error => {
fail(JSON.stringify(error));
done();
});
});
@@ -243,14 +283,16 @@ function mockFacebook() {
facebook.validateAuthData = function(authData) {
if (authData.id === '8675309' && authData.access_token === 'jenny') {
return Promise.resolve();
} else {
throw undefined;
}
return Promise.reject();
};
facebook.validateAppId = function(appId, authData) {
if (authData.access_token === 'jenny') {
return Promise.resolve();
} else {
throw undefined;
}
return Promise.reject();
};
return facebook;
}
@@ -272,7 +314,7 @@ global.expectError = expectError;
global.arrayContains = arrayContains;
global.jequal = jequal;
global.range = range;
global.setServerConfiguration = setServerConfiguration;
global.reconfigureServer = reconfigureServer;
global.defaultConfiguration = defaultConfiguration;
// LiveQuery test setting