extracts out tests into separate files to establish a better testing pattern

This commit is contained in:
James
2020-04-16 15:03:16 -04:00
parent 5699bb6ecd
commit f4faefbd7e
24 changed files with 213 additions and 447 deletions

2
src/tests/credentials.js Normal file
View File

@@ -0,0 +1,2 @@
exports.email = 'test@test.com';
exports.password = 'test123';

26
src/tests/globalSetup.js Normal file
View File

@@ -0,0 +1,26 @@
const server = require('../../demo/server');
const config = require('../../demo/payload.config');
const { email, password } = require('./credentials');
const url = config.serverURL;
const usernameField = config.user.auth.useAsUsername;
const globalSetup = async () => {
global.PAYLOAD_SERVER = await server.start();
const response = await fetch(`${url}/api/first-register`, {
body: JSON.stringify({
[usernameField]: email,
password,
}),
headers: {
'Content-Type': 'application/json',
},
method: 'post',
});
const data = await response.json();
global.AUTH_TOKEN = data.token;
};
module.exports = globalSetup;

View File

@@ -0,0 +1,6 @@
const globalTeardown = async () => {
const serverClosePromise = new Promise(resolve => global.PAYLOAD_SERVER.close(resolve));
await serverClosePromise;
};
module.exports = globalTeardown;

View File

@@ -1,162 +0,0 @@
/**
* @jest-environment node
*/
const faker = require('faker');
const server = require('../../../demo/server');
describe('API', () => {
const url = 'http://localhost:3000';
let token = null;
const email = 'test@test.com';
const password = 'test123';
let localizedPostID;
const englishPostDesc = faker.lorem.lines(20);
const spanishPostDesc = faker.lorem.lines(20);
beforeAll((done) => {
server.start(done);
});
it('should register a first user', async () => {
const response = await fetch(`${url}/api/first-register`, {
body: JSON.stringify({
email,
password,
}),
headers: {
'Content-Type': 'application/json',
},
method: 'post',
});
const data = await response.json();
expect(response.status).toBe(201);
expect(data).toHaveProperty('email');
expect(data).toHaveProperty('role');
expect(data).toHaveProperty('createdAt');
});
it('should login a user successfully', async () => {
const response = await fetch(`${url}/api/login`, {
body: JSON.stringify({
email,
password,
}),
headers: {
'Content-Type': 'application/json',
},
method: 'post',
});
const data = await response.json();
expect(response.status).toBe(200);
expect(data.token).not.toBeNull();
({ token } = data);
});
it('should allow a user to be created', async () => {
const response = await fetch(`${url}/api/users/register`, {
body: JSON.stringify({
email: `${faker.name.firstName()}@test.com`,
password,
}),
headers: {
Authorization: `JWT ${token}`,
'Content-Type': 'application/json',
},
method: 'post',
});
const data = await response.json();
expect(response.status).toBe(201);
expect(data).toHaveProperty('email');
expect(data).toHaveProperty('role');
expect(data).toHaveProperty('createdAt');
});
it('should allow a post to be created in English', async () => {
const response = await fetch(`${url}/api/posts`, {
body: JSON.stringify({
title: faker.name.firstName(),
description: englishPostDesc,
priority: 1,
}),
headers: {
Authorization: `JWT ${token}`,
'Content-Type': 'application/json',
},
method: 'post',
});
const data = await response.json();
expect(response.status).toBe(201);
expect(data.doc.title).not.toBeNull();
expect(data.doc.id).not.toBeNull();
localizedPostID = data.doc.id;
});
it('should allow a Spanish locale to be added to an existing post', async () => {
const response = await fetch(`${url}/api/posts/${localizedPostID}?locale=es`, {
body: JSON.stringify({
title: `Spanish-${faker.name.firstName()}`,
description: spanishPostDesc,
priority: 1,
}),
headers: {
Authorization: `JWT ${token}`,
'Content-Type': 'application/json',
},
method: 'put',
});
const data = await response.json();
expect(response.status).toBe(200);
expect(data.doc.description).toBe(spanishPostDesc);
});
it('should allow a localized post to be retrieved in default locale of English', async () => {
const response = await fetch(`${url}/api/posts/${localizedPostID}`);
const data = await response.json();
expect(response.status).toBe(200);
expect(data.description).toBe(englishPostDesc);
});
it('should allow a localized post to be retrieved in default locale of English', async () => {
const response = await fetch(`${url}/api/posts/${localizedPostID}?locale=en`);
const data = await response.json();
expect(response.status).toBe(200);
expect(data.description).toBe(englishPostDesc);
});
it('should allow a localized post to be retrieved in Spanish', async () => {
const response = await fetch(`${url}/api/posts/${localizedPostID}?locale=es`);
const data = await response.json();
expect(response.status).toBe(200);
expect(data.description).toBe(spanishPostDesc);
});
it('should allow a localized post to be retrieved in all locales', async () => {
const response = await fetch(`${url}/api/posts/${localizedPostID}?locale=all`);
const data = await response.json();
expect(response.status).toBe(200);
expect(data.description.es).toBe(spanishPostDesc);
expect(data.description.en).toBe(englishPostDesc);
});
afterAll((done) => {
server.close(done);
});
});

View File

@@ -1,8 +0,0 @@
const defaults = require('./jest.config');
module.exports = {
...defaults,
roots: [
'./integration'
],
};

View File

@@ -1,11 +0,0 @@
module.exports = {
verbose: true,
testURL: 'http://localhost/',
roots: [
'./unit'
],
transform: {
'^.+\\.(j|t)s$': 'babel-jest'
},
testEnvironment: 'node',
};

View File

@@ -1,99 +0,0 @@
const mockExpress = require('jest-mock-express');
const localizationMiddleware = require('../../localization/middleware');
let res = null;
let next = null;
describe('Payload Middleware', () => {
beforeEach(() => {
res = mockExpress.response();
next = jest.fn();
});
describe('Payload Locale Middleware', () => {
let req, localization;
beforeEach(() => {
req = {
query: {},
headers: {},
body: {}
};
localization = {
locales: ['en', 'es'],
defaultLocale: 'en'
};
});
it('Supports query params', () => {
req.query.locale = 'es';
localizationMiddleware(localization)(req, res, next);
expect(next).toHaveBeenCalledTimes(1);
expect(req.locale).toEqual(req.query.locale);
});
it('Supports query param fallback to default', () => {
req.query.locale = 'pt';
localizationMiddleware(localization)(req, res, next);
expect(next).toHaveBeenCalledTimes(1);
expect(req.locale).toEqual(localization.defaultLocale);
});
it('Supports accept-language header', () => {
req.headers['accept-language'] = 'es,fr;';
localizationMiddleware(localization)(req, res, next);
expect(next).toHaveBeenCalledTimes(1);
expect(req.locale).toEqual('es');
});
it('Supports accept-language header fallback', () => {
req.query.locale = 'pt';
req.headers['accept-language'] = 'fr;';
localizationMiddleware(localization)(req, res, next);
expect(next).toHaveBeenCalledTimes(1);
expect(req.locale).toEqual(localization.defaultLocale);
});
it('Query param takes precedence over header', () => {
req.query.locale = 'es';
req.headers['accept-language'] = 'en;';
localizationMiddleware(localization)(req, res, next);
expect(next).toHaveBeenCalledTimes(1);
expect(req.locale).toEqual('es');
});
it('Supports default locale', () => {
localizationMiddleware(localization)(req, res, next);
expect(next).toHaveBeenCalledTimes(1);
expect(req.locale).toEqual(localization.defaultLocale);
});
it('Supports locale all', () => {
req.query.locale = '*';
localizationMiddleware(localization)(req, res, next);
expect(next).toHaveBeenCalledTimes(1);
expect(req.locale).toBeUndefined();
});
it('Supports locale in body on post', () => {
req.body = {locale: 'es'};
req.method = 'post';
localizationMiddleware(localization)(req, res, next);
expect(next).toHaveBeenCalledTimes(1);
expect(req.locale).toEqual('es');
});
});
});

View File

@@ -1,21 +0,0 @@
import mongoose from 'mongoose';
const Schema = mongoose.Schema;
import mongooseApiQuery from '../../mongoose/buildQuery.plugin';
const TestUserSchema = new Schema({
name: {type: String},
description: {type: String},
married: {type: Boolean},
age: {type: Number}
}
);
TestUserSchema.plugin(mongooseApiQuery);
const TestUser = mongoose.model('TestUser', TestUserSchema);
describe('mongooseApiQuery', () => {
it('Should not blow up', () => {
expect(mongooseApiQuery).not.toBeNull();
});
});

View File

@@ -1,26 +0,0 @@
import SchemaLoader from '../../mongoose/schema/schemaLoader';
import config from '../../../demo/payload.config';
let schemaLoader;
describe('schemaLoader', () => {
beforeAll(async () => {
schemaLoader = new SchemaLoader(config);
console.log('before done');
});
it('load collections', async () => {
expect(schemaLoader.collections).not.toBeNull();
});
it('load globals', async () => {
expect(schemaLoader.globalModel).not.toBeNull();
expect(schemaLoader.globals).not.toBeNull();
});
it('load blocks', async () => {
expect(schemaLoader.blockSchema).not.toBeNull();
expect(schemaLoader.contentBlocks).not.toBeNull();
});
});

View File

@@ -1,126 +0,0 @@
/* eslint-disable camelcase */
import mongoose from 'mongoose';
const Schema = mongoose.Schema;
import { intlModel } from './testModels/IntlModel';
import { paramParser } from '../../mongoose/buildQuery.plugin';
const AuthorSchema = new Schema({
name: String,
publish_count: Number
});
const PageSchema = new Schema({
title: { type: String, unique: true },
author: AuthorSchema,
content: { type: String },
metaTitle: String,
likes: { type: Number }
});
const Page = mongoose.model('Page', PageSchema);
describe('Param Parser', () => {
describe('Parameter Parsing', () => {
it('No params', () => {
let parsed = paramParser(Page, {});
expect(parsed.searchParams).toEqual({});
});
it('Property Equals - Object property', () => {
let parsed = paramParser(Page, { title: 'This is my title' });
expect(parsed.searchParams).toEqual({ title: 'This is my title' });
});
it('Property Equals - String property', () => {
let parsed = paramParser(Page, { metaTitle: 'This is my title' });
expect(parsed.searchParams).toEqual({ metaTitle: 'This is my title' });
});
it('Multiple params', () => {
let parsed = paramParser(Page, { title: 'This is my title', metaTitle: 'this-is-my-title' });
expect(parsed.searchParams).toEqual({ title: 'This is my title', metaTitle: 'this-is-my-title' });
});
it('Greater than or equal', () => {
let parsed = paramParser(Page, { likes: '{gte}50' });
expect(parsed.searchParams).toEqual({ likes: { '$gte': '50' } });
});
it('Greater than, less than', () => {
let parsed = paramParser(Page, { likes: '{gte}50{lt}100' });
expect(parsed.searchParams).toEqual({ likes: { '$gte': '50', '$lt': '100' } });
});
it('Like', () => {
let parsed = paramParser(Page, { title: '{like}This' });
expect(parsed.searchParams).toEqual({ title: { '$regex': 'This', '$options': '-i' } });
});
describe('SubSchemas', () => {
it('Parse subschema for String', () => {
let parsed = paramParser(Page, { 'author.name': 'Jane' });
expect(parsed.searchParams).toEqual({ 'author.name': 'Jane' })
});
it('Parse subschema for Number', () => {
let parsed = paramParser(Page, { 'author.publish_count': '7' });
expect(parsed.searchParams).toEqual({ 'author.publish_count': '7' })
})
});
describe('Locale handling', () => {
it('should handle intl string property', () => {
let parsed = paramParser(intlModel, { title: 'This is my title' }, 'en');
expect(parsed.searchParams).toEqual({ 'title.en': 'This is my title'});
});
it('should handle intl string property', () => {
let parsed = paramParser(intlModel, { title: 'This is my title' }, 'en');
expect(parsed.searchParams).toEqual({ 'title.en': 'This is my title'});
});
});
});
describe('Include', () => {
it('Include Single', () => {
let parsed = paramParser(Page, { include: 'SomeId' });
expect(parsed.searchParams).toEqual({ _id: 'SomeId' });
});
it('Include Multiple', () => {
let parsed = paramParser(Page, { include: 'SomeId,SomeSecondId' });
expect(parsed.searchParams)
.toEqual({ '$or': [{ _id: 'SomeId' }, { _id: 'SomeSecondId' }] });
});
});
describe('Exclude', () => {
it('Exclude Single', () => {
let parsed = paramParser(Page, { exclude: 'SomeId' });
expect(parsed.searchParams).toEqual({ _id: { '$ne': 'SomeId' } });
});
it('Exclude Multiple', () => {
let parsed = paramParser(Page, { exclude: 'SomeId,SomeSecondId' });
expect(parsed.searchParams)
.toEqual({ '$and': [{ _id: { '$ne': 'SomeId' } }, { _id: { '$ne': 'SomeSecondId' } }] });
});
});
describe('Ordering/Sorting', () => {
it('Order by ascending (default)', () => {
let parsed = paramParser(Page, { sort_by: 'title' });
expect(parsed).toEqual({ searchParams: {}, sort: { title: 1 } });
});
it('Order by ascending', () => {
let parsed = paramParser(Page, { sort_by: 'title,asc' });
expect(parsed).toEqual({ searchParams: {}, sort: { title: 1 } });
});
it('Order by descending', () => {
let parsed = paramParser(Page, { sort_by: 'title,desc' });
expect(parsed).toEqual({ searchParams: {}, sort: { title: 'desc' } });
})
});
});

View File

@@ -1,29 +0,0 @@
import mongoose from 'mongoose';
import { schemaBaseFields } from '../../../mongoose/schema/schemaBaseFields';
import paginate from '../../../mongoose/paginate.plugin';
import buildQueryPlugin from '../../../mongoose/buildQuery.plugin';
import localizationPlugin from '../../../localization/localization.plugin';
const IntlSchema = new mongoose.Schema({
...schemaBaseFields,
title: { type: String, localized: true, unique: true },
content: { type: String, localized: true },
metaTitle: String,
metaDesc: String
},
{ timestamps: true }
);
IntlSchema.plugin(paginate);
IntlSchema.plugin(buildQueryPlugin);
IntlSchema.plugin(localizationPlugin, {
locales: [
'en',
'es'
],
defaultLocale: 'en',
fallback: true
});
const intlModel = mongoose.model('IntlModel', IntlSchema);
export { intlModel };

View File

@@ -1,7 +0,0 @@
import express from 'express';
export function getConfiguredExpress() {
let expressApp = express();
expressApp.set('view engine', 'pug');
return expressApp;
}

View File

@@ -1,7 +0,0 @@
describe('troubleshooting', () => {
describe('plugins', () => {
it('should return all records', () => {
});
});
});