refactor: schema backreference test to use map instead of reduce, properly check write-api routes

v1.18.x
Julian Lam 4 years ago
parent df8d62ba06
commit 878ee06715

@ -23,11 +23,25 @@ info:
servers: servers:
- url: /api/v3 - url: /api/v3
tags: tags:
- name: utilities
description: Utility calls to test Write API functionality
- name: users - name: users
description: 'Account related calls (create, modify, delete, etc.)' description: Account related calls (create, modify, delete, etc.)
- name: groups
description: Calls related to user groups
- name: categories - name: categories
description: Administrative calls to manage categories description: Administrative calls to manage categories
- name: topics
description: Topic-based calls (create, modify, delete, etc.)
- name: posts
description: Individual post-related calls (create, modify, delete, etc.)
- name: admin
description: Administrative calls
- name: files
description: File upload routes
paths: paths:
/ping:
$ref: 'write/ping.yaml'
/users/: /users/:
$ref: 'write/users.yaml' $ref: 'write/users.yaml'
/users/{uid}: /users/{uid}:

@ -48,6 +48,7 @@ Write.reload = async (params) => {
router.post('/api/v3/ping', middleware.authenticate, function (req, res) { router.post('/api/v3/ping', middleware.authenticate, function (req, res) {
helpers.formatApiResponse(200, res, { helpers.formatApiResponse(200, res, {
uid: req.user.uid, uid: req.user.uid,
received: req.body,
}); });
}); });

@ -172,31 +172,46 @@ describe('API', async () => {
it('should grab all mounted routes and ensure a schema exists', async () => { it('should grab all mounted routes and ensure a schema exists', async () => {
const webserver = require('../src/webserver'); const webserver = require('../src/webserver');
const buildPaths = function (stack, prefix) { const buildPaths = function (stack, prefix) {
const paths = stack.reduce((memo, cur) => { const paths = stack.map((dispatch) => {
if (cur.route && cur.route.path && typeof cur.route.path === 'string' && cur.route.path.startsWith('/api/')) { if (dispatch.route && dispatch.route.path && typeof dispatch.route.path === 'string') {
memo.push({ if (!prefix && !dispatch.route.path.startsWith('/api/')) {
method: Object.keys(cur.route.methods)[0], return null;
path: (prefix || '') + cur.route.path, }
}); return {
} else if (cur.name === 'router') { method: Object.keys(dispatch.route.methods)[0],
const prefix = cur.regexp.toString().replace('/^', '').replace('\\/?(?=\\/|$)/i', '').replace(/\\\//g, '/'); path: (prefix || '') + dispatch.route.path,
memo = memo.concat(buildPaths(cur.handle.stack, prefix)); };
} else if (dispatch.name === 'router') {
const prefix = dispatch.regexp.toString().replace('/^', '').replace('\\/?(?=\\/|$)/i', '').replace(/\\\//g, '/');
return buildPaths(dispatch.handle.stack, prefix);
} }
return memo;
}, []);
return paths; // Drop any that aren't actual routes (middlewares, error handlers, etc.)
return null;
});
return paths.flat();
}; };
const paths = buildPaths(webserver.app._router.stack).map(function normalize(pathObj) {
let paths = buildPaths(webserver.app._router.stack).filter(Boolean).map(function normalize(pathObj) {
pathObj.path = pathObj.path.replace(/\/:([^\\/]+)/g, '/{$1}'); pathObj.path = pathObj.path.replace(/\/:([^\\/]+)/g, '/{$1}');
return pathObj; return pathObj;
}); });
const exclusionPrefixes = ['/api/admin/plugins'];
paths = paths.filter(function filterExclusions(path) {
return !exclusionPrefixes.some(prefix => path.path.startsWith(prefix));
});
// For each express path, query for existence in read and write api schemas // For each express path, query for existence in read and write api schemas
paths.forEach((pathObj) => { paths.forEach((pathObj) => {
describe(`${pathObj.method.toUpperCase()} ${pathObj.path}`, () => { describe(`${pathObj.method.toUpperCase()} ${pathObj.path}`, () => {
it('should be defined in schema docs', () => { it('should be defined in schema docs', () => {
const schema = pathObj.path.startsWith('/api/v3') ? writeApi : readApi; let schema = readApi;
if (pathObj.path.startsWith('/api/v3')) {
schema = writeApi;
pathObj.path = pathObj.path.replace('/api/v3', '');
}
const normalizedPath = pathObj.path.replace(/\/:([^\\/]+)/g, '/{$1}').replace(/\?/g, ''); const normalizedPath = pathObj.path.replace(/\/:([^\\/]+)/g, '/{$1}').replace(/\?/g, '');
assert(schema.paths.hasOwnProperty(normalizedPath)); assert(schema.paths.hasOwnProperty(normalizedPath));
}); });

Loading…
Cancel
Save