mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-02-28 01:21:13 +01:00
refactor: schema backreference test to use map instead of reduce, properly check write-api routes
This commit is contained in:
@@ -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,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
43
test/api.js
43
test/api.js
@@ -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));
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user