[WIP] Enable test suite to be randomized (#7265)
* initial run * Update ParseGraphQLServer.spec.js * temporarily enable reporter * Bump retry limit * fix undefined database * try to catch error * Handle LiveQueryServers * Update Config.js * fast-fail false * Remove usage of AppCache * oops * Update contributing guide * enable debugger, try network retry attempt 1 * Fix ldap unbinding * move non specs to support * add missing mock adapter * fix Parse.Push * RestController should match batch.spec.js * Remove request attempt limit * handle index.spec.js * Update CHANGELOG.md * Handle error: tuple concurrently updated * test transactions * Clear RedisCache after every test * LoggerController.spec.js * Update schemas.spec.js * finally fix transactions * fix geopoint deadlock * transaction with clean database * batch.spec.js
This commit is contained in:
5
spec/support/MockAdapter.js
Normal file
5
spec/support/MockAdapter.js
Normal file
@@ -0,0 +1,5 @@
|
||||
module.exports = function (options) {
|
||||
return {
|
||||
options: options,
|
||||
};
|
||||
};
|
||||
5
spec/support/MockEmailAdapter.js
Normal file
5
spec/support/MockEmailAdapter.js
Normal file
@@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
sendVerificationEmail: () => Promise.resolve(),
|
||||
sendPasswordResetEmail: () => Promise.resolve(),
|
||||
sendMail: () => Promise.resolve(),
|
||||
};
|
||||
21
spec/support/MockEmailAdapterWithOptions.js
Normal file
21
spec/support/MockEmailAdapterWithOptions.js
Normal file
@@ -0,0 +1,21 @@
|
||||
module.exports = options => {
|
||||
if (!options) {
|
||||
throw 'Options were not provided';
|
||||
}
|
||||
const adapter = {
|
||||
sendVerificationEmail: () => Promise.resolve(),
|
||||
sendPasswordResetEmail: () => Promise.resolve(),
|
||||
sendMail: () => Promise.resolve(),
|
||||
};
|
||||
if (options.sendMail) {
|
||||
adapter.sendMail = options.sendMail;
|
||||
}
|
||||
if (options.sendPasswordResetEmail) {
|
||||
adapter.sendPasswordResetEmail = options.sendPasswordResetEmail;
|
||||
}
|
||||
if (options.sendVerificationEmail) {
|
||||
adapter.sendVerificationEmail = options.sendVerificationEmail;
|
||||
}
|
||||
|
||||
return adapter;
|
||||
};
|
||||
54
spec/support/MockLdapServer.js
Normal file
54
spec/support/MockLdapServer.js
Normal file
@@ -0,0 +1,54 @@
|
||||
const ldapjs = require('ldapjs');
|
||||
const fs = require('fs');
|
||||
|
||||
const tlsOptions = {
|
||||
key: fs.readFileSync(__dirname + '/cert/key.pem'),
|
||||
certificate: fs.readFileSync(__dirname + '/cert/cert.pem'),
|
||||
};
|
||||
|
||||
function newServer(port, dn, provokeSearchError = false, ssl = false) {
|
||||
const server = ssl ? ldapjs.createServer(tlsOptions) : ldapjs.createServer();
|
||||
|
||||
server.bind('o=example', function (req, res, next) {
|
||||
if (req.dn.toString() !== dn || req.credentials !== 'secret')
|
||||
return next(new ldapjs.InvalidCredentialsError());
|
||||
res.end();
|
||||
return next();
|
||||
});
|
||||
|
||||
server.search('o=example', function (req, res, next) {
|
||||
if (provokeSearchError) {
|
||||
res.end(ldapjs.LDAP_SIZE_LIMIT_EXCEEDED);
|
||||
return next();
|
||||
}
|
||||
const obj = {
|
||||
dn: req.dn.toString(),
|
||||
attributes: {
|
||||
objectclass: ['organization', 'top'],
|
||||
o: 'example',
|
||||
},
|
||||
};
|
||||
|
||||
const group = {
|
||||
dn: req.dn.toString(),
|
||||
attributes: {
|
||||
objectClass: ['groupOfUniqueNames', 'top'],
|
||||
uniqueMember: ['uid=testuser, o=example'],
|
||||
cn: 'powerusers',
|
||||
ou: 'powerusers',
|
||||
},
|
||||
};
|
||||
|
||||
if (req.filter.matches(obj.attributes)) {
|
||||
res.send(obj);
|
||||
}
|
||||
|
||||
if (req.filter.matches(group.attributes)) {
|
||||
res.send(group);
|
||||
}
|
||||
res.end();
|
||||
});
|
||||
return new Promise(resolve => server.listen(port, () => resolve(server)));
|
||||
}
|
||||
|
||||
module.exports = newServer;
|
||||
9
spec/support/MockPushAdapter.js
Normal file
9
spec/support/MockPushAdapter.js
Normal file
@@ -0,0 +1,9 @@
|
||||
module.exports = function (options) {
|
||||
return {
|
||||
options: options,
|
||||
send: function () {},
|
||||
getValidPushTypes: function () {
|
||||
return Object.keys(options.options);
|
||||
},
|
||||
};
|
||||
};
|
||||
95
spec/support/dev.js
Normal file
95
spec/support/dev.js
Normal file
@@ -0,0 +1,95 @@
|
||||
const Config = require('../../lib/Config');
|
||||
const Parse = require('parse/node');
|
||||
|
||||
const className = 'AnObject';
|
||||
const defaultRoleName = 'tester';
|
||||
|
||||
let schemaCache;
|
||||
|
||||
module.exports = {
|
||||
/* AnObject */
|
||||
className,
|
||||
schemaCache,
|
||||
|
||||
/**
|
||||
* Creates and returns new user.
|
||||
*
|
||||
* This method helps to avoid 'User already exists' when re-running/debugging a single test.
|
||||
* @param {string} username - username base, will be postfixed with current time in millis;
|
||||
* @param {string} [password='password'] - optional, defaults to "password" if not set;
|
||||
*/
|
||||
createUser: async (username, password = 'password') => {
|
||||
const user = new Parse.User({
|
||||
username: username + Date.now(),
|
||||
password,
|
||||
});
|
||||
await user.save();
|
||||
return user;
|
||||
},
|
||||
|
||||
/**
|
||||
* Logs the user in.
|
||||
*
|
||||
* If password not provided, default 'password' is used.
|
||||
* @param {string} username - username base, will be postfixed with current time in millis;
|
||||
* @param {string} [password='password'] - optional, defaults to "password" if not set;
|
||||
*/
|
||||
logIn: async (userObject, password) => {
|
||||
return await Parse.User.logIn(userObject.getUsername(), password || 'password');
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets up Class-Level Permissions for 'AnObject' class.
|
||||
* @param clp {ClassLevelPermissions}
|
||||
*/
|
||||
updateCLP: async (clp, targetClass = className) => {
|
||||
const config = Config.get(Parse.applicationId);
|
||||
const schemaController = await config.database.loadSchema();
|
||||
|
||||
await schemaController.updateClass(targetClass, {}, clp);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates and returns role. Adds user(s) if provided.
|
||||
*
|
||||
* This method helps to avoid errors when re-running/debugging a single test.
|
||||
*
|
||||
* @param {Parse.User|Parse.User[]} [users] - user or array of users to be related with this role;
|
||||
* @param {string?} [roleName] - uses this name for role if provided. Generates from datetime if not set;
|
||||
* @param {string?} [exactName] - sets exact name (no generated part added);
|
||||
* @param {Parse.Role[]} [roles] - uses this name for role if provided. Generates from datetime if not set;
|
||||
* @param {boolean} [read] - value for role's acl public read. Defaults to true;
|
||||
* @param {boolean} [write] - value for role's acl public write. Defaults to true;
|
||||
*/
|
||||
createRole: async ({
|
||||
users = null,
|
||||
exactName = defaultRoleName + Date.now(),
|
||||
roleName = null,
|
||||
roles = null,
|
||||
read = true,
|
||||
write = true,
|
||||
}) => {
|
||||
const acl = new Parse.ACL();
|
||||
acl.setPublicReadAccess(read);
|
||||
acl.setPublicWriteAccess(write);
|
||||
|
||||
const role = new Parse.Object('_Role');
|
||||
role.setACL(acl);
|
||||
|
||||
// generate name based on roleName or use exactName (if botth not provided name is generated)
|
||||
const name = roleName ? roleName + Date.now() : exactName;
|
||||
role.set('name', name);
|
||||
|
||||
if (roles) {
|
||||
role.relation('roles').add(roles);
|
||||
}
|
||||
|
||||
if (users) {
|
||||
role.relation('users').add(users);
|
||||
}
|
||||
|
||||
await role.save({ useMasterKey: true });
|
||||
|
||||
return role;
|
||||
},
|
||||
};
|
||||
@@ -2,5 +2,5 @@
|
||||
"spec_dir": "spec",
|
||||
"spec_files": ["*spec.js"],
|
||||
"helpers": ["helper.js"],
|
||||
"random": false
|
||||
"random": true
|
||||
}
|
||||
|
||||
17
spec/support/myoauth.js
Normal file
17
spec/support/myoauth.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// Custom oauth provider by module
|
||||
|
||||
// Returns a promise that fulfills iff this user id is valid.
|
||||
function validateAuthData(authData) {
|
||||
if (authData.id == '12345' && authData.access_token == '12345') {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject();
|
||||
}
|
||||
function validateAppId() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
validateAppId: validateAppId,
|
||||
validateAuthData: validateAuthData,
|
||||
};
|
||||
Reference in New Issue
Block a user