apostrophe
Version:
The Apostrophe Content Management System.
156 lines (141 loc) • 4.36 kB
JavaScript
const { createId } = require('@paralleldrive/cuid2');
const mongodbConnect = require('../lib/mongodb-connect');
// Properly clean up an apostrophe instance and drop its
// database collections to create a sane environment for the next test.
// Drops the collections, not the entire database, to avoid problems
// when testing something like a mongodb hosting environment with
// credentials per database.
//
// If `apos` is null, no work is done.
async function destroy(apos) {
if (!apos) {
return;
}
await apos.destroy();
const { uri } = apos.modules['@apostrophecms/db'];
const dbName = apos.db && apos.db.databaseName;
// TODO at some point accommodate nonsense like testing remote databases
// that won't let us use dropDatabase, no shell available etc., but the
// important principle here is that we should not have to have an apos
// object to clean up the database, otherwise we have to get hold of one
// when initialization failed and that's really not apostrophe's concern
if (dbName && uri) {
const client = await mongodbConnect(`${uri}${dbName}`);
const db = client.db(dbName);
await db.dropDatabase();
await client.close();
}
};
async function create(options = {}) {
const config = {
shortName: options.shortName || `test-${createId()}`,
argv: {
_: [],
'ignore-orphan-modules': true
},
test: true,
autoBuild: false,
...options
};
// Automatically configure Express, but not if we're in a special
// environment where the default apostrophe modules don't initialize
// TODO: Remove __testDefaults references in 4.x major version or formalize
// intended usage with documentation.
if (!config.__testDefaults) {
config.modules = config.modules || {};
const express = config.modules['@apostrophecms/express'] || {};
express.options = express.options || {};
// Allow OS to choose open port if not explicitly set.
express.options.port = express.options.port || null;
express.options.address = express.options.address || 'localhost';
express.options.session = express.options.session || {};
express.options.session.secret = express.options.session.secret || 'test';
config.modules['@apostrophecms/express'] = express;
}
return require('../index.js')(config);
}
// Create an admin user. Invokes createUser with the `admin` role.
// Accepts the same options.
async function createAdmin(apos, {
username, password, title, email
} = {}) {
return createUser(apos, 'admin', {
username,
password,
title,
email
});
}
// Resolves to a user with the specified `role`. `username` defaults to
// `role`. `title` defaults to `username` or `role`.
// `password` defaults to `username` or `role`. `email` defaults to
// `${username}@test.io` where `username` can also be inferred from `role`.
async function createUser(apos, role, {
username, password, title, email
} = {}) {
title = title || username || role;
username = username || role;
password = password || username || role;
email = email || `${username}@test.io`;
return apos.user.insert(
apos.task.getReq(),
{
...apos.user.newInstance(),
title,
username,
password,
email,
role
}
);
}
// Log in with the specified password. Returns a
// cookie jar object for use with additional
// apos.http calls via the `jar` option.
// `password` defaults to `username`.
async function loginAs(apos, username, password) {
password = password || username;
const jar = apos.http.jar();
await apos.http.post('/api/v1/@apostrophecms/login/login', {
body: {
username,
password,
session: true
},
jar
});
return jar;
};
async function logout(apos, username, password, jar) {
await apos.http.post(
'/api/v1/@apostrophecms/login/logout',
{
body: {
username,
password,
session: true
},
jar
}
);
await apos.http.get(
'/',
{
jar
}
);
};
// Deprecated legacy wrapper for loginAs.
function getUserJar(apos, { username = 'admin', password } = {}) {
return loginAs(apos, username, password);
}
module.exports = {
destroy,
create,
createAdmin,
createUser,
loginAs,
logout,
getUserJar,
timeout: (process.env.TEST_TIMEOUT && parseInt(process.env.TEST_TIMEOUT)) || 20000
};