mirror of https://gitee.com/bigwinds/arangodb
Merge pull request #939 from triAGENS/foxx-joiful-params
Foxx: use joi in queryParam and pathParam (fixes #936)
This commit is contained in:
commit
f5d35c053a
|
@ -14,6 +14,8 @@ migrations will also be detailed here.
|
||||||
* Foxx: The usage of `controller.collection` is no longer suggested, it will be deprecated in the next version. Please use `appContext.collection` instead.
|
* Foxx: The usage of `controller.collection` is no longer suggested, it will be deprecated in the next version. Please use `appContext.collection` instead.
|
||||||
* Foxx: The usage of `Model.extend({}, {attributes: {}})` is no longer suggested, it will be deprecated in the next version. Please use `Model.extend({schema: {}})` instead.
|
* Foxx: The usage of `Model.extend({}, {attributes: {}})` is no longer suggested, it will be deprecated in the next version. Please use `Model.extend({schema: {}})` instead.
|
||||||
* Foxx: The usage of `requestContext.bodyParam(paramName, description, Model)` is no longer suggested, it will be deprecated in the next version. Please use `requestContext.bodyParam(paramName, options)` instead.
|
* Foxx: The usage of `requestContext.bodyParam(paramName, description, Model)` is no longer suggested, it will be deprecated in the next version. Please use `requestContext.bodyParam(paramName, options)` instead.
|
||||||
|
* Foxx: The usage of `requestContext.queryParam({type: string})` is no longer suggested, it will be deprecated in the next version. Please use `requestContext.queryParam({type: joi})` instead.
|
||||||
|
* Foxx: The usage of `requestContext.pathParam({type: string})` is no longer suggested, it will be deprecated in the next version. Please use `requestContext.pathParam({type: joi})` instead.
|
||||||
* Foxx: The usage of `apps` in manifest files is no longer possible, please use `controllers` instead.
|
* Foxx: The usage of `apps` in manifest files is no longer possible, please use `controllers` instead.
|
||||||
* Graph: The usage of the modules `org/arangodb/graph` and `org/arangodb/graph-blueprint` is no longer suggested, it will be deprecated in the next version. Please use module `org/arangodb/general-graph` instead.
|
* Graph: The usage of the modules `org/arangodb/graph` and `org/arangodb/graph-blueprint` is no longer suggested, it will be deprecated in the next version. Please use module `org/arangodb/general-graph` instead.
|
||||||
* Graph: The module `org/arangodb/graph` will now load the module `org/arangodb/graph-blueprint`.
|
* Graph: The module `org/arangodb/graph` will now load the module `org/arangodb/graph-blueprint`.
|
||||||
|
@ -34,6 +36,8 @@ migrations will also be detailed here.
|
||||||
* Foxx: `controller.collection` is now deprecated, it will raise a warning if you use it. To suppress the warning, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `appContext.collection` instead.
|
* Foxx: `controller.collection` is now deprecated, it will raise a warning if you use it. To suppress the warning, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `appContext.collection` instead.
|
||||||
* Foxx: `Model.extend({}, {attributes: {}})` is now deprecated, it will raise a warning if you use it. To suppress the warning, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `Model.extend({schema: {}})` instead.
|
* Foxx: `Model.extend({}, {attributes: {}})` is now deprecated, it will raise a warning if you use it. To suppress the warning, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `Model.extend({schema: {}})` instead.
|
||||||
* Foxx: `requestContext.bodyParam(paramName, description, Model)` is now deprecated, it will raise a warning if you use it. To suppress the warning, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `requestContext.bodyParam(paramName, options)` instead.
|
* Foxx: `requestContext.bodyParam(paramName, description, Model)` is now deprecated, it will raise a warning if you use it. To suppress the warning, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `requestContext.bodyParam(paramName, options)` instead.
|
||||||
|
* Foxx: `requestContext.queryParam({type: string})` is now deprecated, it will raise a warning if you use it. To suppress the warning, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `requestContext.queryParam({type: joi})` instead.
|
||||||
|
* Foxx: `requestContext.pathParam({type: string})` is now deprecated, it will raise a warning if you use it. To suppress the warning, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `requestContext.pathParam({type: joi})` instead.
|
||||||
* Graph: The modules `org/arangodb/graph` and `org/arangodb/graph-blueprint` are now deprecated, it will raise a warning if you use it. To suppress the warning, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use module `org/arangodb/general-graph` instead.
|
* Graph: The modules `org/arangodb/graph` and `org/arangodb/graph-blueprint` are now deprecated, it will raise a warning if you use it. To suppress the warning, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use module `org/arangodb/general-graph` instead.
|
||||||
* AQL: The function `PATHS` is now deprecated, it will raise a warning if you use it. To suppress the warning, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `GRAPH_PATHS` instead.
|
* AQL: The function `PATHS` is now deprecated, it will raise a warning if you use it. To suppress the warning, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `GRAPH_PATHS` instead.
|
||||||
* AQL: The function `SHORTEST_PATH` is now deprecated, it will raise a warning if you use it. To suppress the warning, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `GRAPH_SHORTEST_PATH` instead.
|
* AQL: The function `SHORTEST_PATH` is now deprecated, it will raise a warning if you use it. To suppress the warning, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `GRAPH_SHORTEST_PATH` instead.
|
||||||
|
@ -51,6 +55,8 @@ migrations will also be detailed here.
|
||||||
* Foxx: `controller.collection` is no longer available by default. If you still want to use it, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `appContext.collection` instead.
|
* Foxx: `controller.collection` is no longer available by default. If you still want to use it, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `appContext.collection` instead.
|
||||||
* Foxx: `Model.extend({}, {attributes: {}})` is no longer available by default. If you still want to use it, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `Model.extend({schema: {}})` instead.
|
* Foxx: `Model.extend({}, {attributes: {}})` is no longer available by default. If you still want to use it, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `Model.extend({schema: {}})` instead.
|
||||||
* Foxx: `requestContext.bodyParam(paramName, description, Model)` is no longer available by default. If you still want to use it, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `requestContext.bodyParam(paramName, options)` instead.
|
* Foxx: `requestContext.bodyParam(paramName, description, Model)` is no longer available by default. If you still want to use it, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `requestContext.bodyParam(paramName, options)` instead.
|
||||||
|
* Foxx: `requestContext.queryParam({type: string})` is no longer available by default. If you still want to use it, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `requestContext.queryParam({type: joi})` instead.
|
||||||
|
* Foxx: `requestContext.pathParam({type: string})` is no longer available by default. If you still want to use it, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `requestContext.pathParam({type: joi})` instead.
|
||||||
* Graph: The modules `org/arangodb/graph` and `org/arangodb/graph-blueprint` are no longer available by default. If you still want to use them, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use module `org/arangodb/general-graph` instead.
|
* Graph: The modules `org/arangodb/graph` and `org/arangodb/graph-blueprint` are no longer available by default. If you still want to use them, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use module `org/arangodb/general-graph` instead.
|
||||||
* AQL: The function `PATHS` is no longer available by default. If you still want to use it, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `GRAPH_PATHS` instead.
|
* AQL: The function `PATHS` is no longer available by default. If you still want to use it, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `GRAPH_PATHS` instead.
|
||||||
* AQL: The function `SHORTEST_PATH` is no longer available by default. If you still want to use it, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `GRAPH_SHORTEST_PATH` instead.
|
* AQL: The function `SHORTEST_PATH` is no longer available by default. If you still want to use it, please start `arangod` with the option `--server.default-api-compatibility 20200`. Please use `GRAPH_SHORTEST_PATH` instead.
|
||||||
|
@ -68,6 +74,8 @@ migrations will also be detailed here.
|
||||||
* Foxx: `controller.collection` has been removed entirely. Please use `appContext.collection` instead.
|
* Foxx: `controller.collection` has been removed entirely. Please use `appContext.collection` instead.
|
||||||
* Foxx: `Model.extend({}, {attributes: {}})` has been removed entirely. Please use `Model.extend({schema: {}})` instead.
|
* Foxx: `Model.extend({}, {attributes: {}})` has been removed entirely. Please use `Model.extend({schema: {}})` instead.
|
||||||
* Foxx: `requestContext.bodyParam(paramName, description, Model)` has been removed entirely. Please use `requestContext.bodyParam(paramName, options)` instead.
|
* Foxx: `requestContext.bodyParam(paramName, description, Model)` has been removed entirely. Please use `requestContext.bodyParam(paramName, options)` instead.
|
||||||
|
* Foxx: `requestContext.queryParam({type: string})` has been removed entirely. Please use `requestContext.queryParam({type: joi})` instead.
|
||||||
|
* Foxx: `requestContext.pathParam({type: string})` has been removed entirely. Please use `requestContext.pathParam({type: joi})` instead.
|
||||||
* Graph: The modules `org/arangodb/graph` and `org/arangodb/graph-blueprint` have been removed entirely. Please use module `org/arangodb/general-graph` instead.
|
* Graph: The modules `org/arangodb/graph` and `org/arangodb/graph-blueprint` have been removed entirely. Please use module `org/arangodb/general-graph` instead.
|
||||||
* AQL: The function `PATHS` has been removed entirely. Please use `GRAPH_PATHS` instead.
|
* AQL: The function `PATHS` has been removed entirely. Please use `GRAPH_PATHS` instead.
|
||||||
* AQL: The function `SHORTEST_PATH` has been removed entirely. Please use `GRAPH_SHORTEST_PATH` instead.
|
* AQL: The function `SHORTEST_PATH` has been removed entirely. Please use `GRAPH_SHORTEST_PATH` instead.
|
||||||
|
|
|
@ -156,8 +156,9 @@ extend(Controller.prototype, {
|
||||||
|
|
||||||
handleRequest: function (method, route, callback) {
|
handleRequest: function (method, route, callback) {
|
||||||
'use strict';
|
'use strict';
|
||||||
var newRoute = internal.constructRoute(method, route, callback, this),
|
var constraints = {queryParams: {}, urlParams: {}},
|
||||||
requestContext = new RequestContext(this.allRoutes, this.models, newRoute, this.rootElement),
|
newRoute = internal.constructRoute(method, route, callback, this, constraints),
|
||||||
|
requestContext = new RequestContext(this.allRoutes, this.models, newRoute, this.rootElement, constraints),
|
||||||
summary,
|
summary,
|
||||||
undocumentedBody;
|
undocumentedBody;
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,9 @@
|
||||||
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
|
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var is = require("org/arangodb/is"),
|
var _ = require("underscore"),
|
||||||
|
is = require("org/arangodb/is"),
|
||||||
|
actions = require("org/arangodb/actions"),
|
||||||
constructUrlObject,
|
constructUrlObject,
|
||||||
constructNickname,
|
constructNickname,
|
||||||
constructRoute,
|
constructRoute,
|
||||||
|
@ -84,17 +86,37 @@ constructNickname = function (httpMethod, url) {
|
||||||
.toLowerCase();
|
.toLowerCase();
|
||||||
};
|
};
|
||||||
|
|
||||||
constructRoute = function (method, route, callback, controller) {
|
constructRoute = function (method, route, callback, controller, constraints) {
|
||||||
'use strict';
|
'use strict';
|
||||||
return {
|
return {
|
||||||
url: constructUrlObject(route, undefined, method),
|
url: constructUrlObject(route, undefined, method),
|
||||||
action: {
|
action: {
|
||||||
callback: function (req, res) {
|
callback: function (req, res) {
|
||||||
Object.keys(controller.injectors).forEach(function (key) {
|
if (constraints) {
|
||||||
if (Object.prototype.hasOwnProperty.call(controller.injected, key)) {
|
try {
|
||||||
|
_.each({
|
||||||
|
urlParameters: constraints.urlParams,
|
||||||
|
parameters: constraints.queryParams
|
||||||
|
}, function (paramConstraints, paramsPropertyName) {
|
||||||
|
var params = req[paramsPropertyName];
|
||||||
|
_.each(paramConstraints, function (constraint, paramName) {
|
||||||
|
var result = constraint.validate(params[paramName]);
|
||||||
|
params[paramName] = result.value;
|
||||||
|
if (result.error) {
|
||||||
|
result.error.message = 'Invalid value for "' + paramName + '": ' + result.error.message;
|
||||||
|
throw result.error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
actions.resultBad(req, res, actions.HTTP_BAD, err.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_.each(controller.injectors, function (injector, key) {
|
||||||
|
if (_.has(controller.injected, key)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var injector = controller.injectors[key];
|
|
||||||
if (typeof injector === 'function') {
|
if (typeof injector === 'function') {
|
||||||
controller.injected[key] = injector();
|
controller.injected[key] = injector();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -180,7 +180,7 @@ extend(SwaggerDocs.prototype, {
|
||||||
/// Used for documenting and constraining the routes.
|
/// Used for documenting and constraining the routes.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
RequestContext = function (executionBuffer, models, route, rootElement) {
|
RequestContext = function (executionBuffer, models, route, rootElement, constraints) {
|
||||||
'use strict';
|
'use strict';
|
||||||
this.route = route;
|
this.route = route;
|
||||||
this.typeToRegex = {
|
this.typeToRegex = {
|
||||||
|
@ -189,6 +189,7 @@ RequestContext = function (executionBuffer, models, route, rootElement) {
|
||||||
"string": "/[^/]+/"
|
"string": "/[^/]+/"
|
||||||
};
|
};
|
||||||
this.rootElement = rootElement;
|
this.rootElement = rootElement;
|
||||||
|
this.constraints = constraints;
|
||||||
|
|
||||||
this.docs = new SwaggerDocs(this.route.docs, models);
|
this.docs = new SwaggerDocs(this.route.docs, models);
|
||||||
this.docs.addNickname(route.docs.httpMethod, route.url.match);
|
this.docs.addNickname(route.docs.httpMethod, route.url.match);
|
||||||
|
@ -202,11 +203,9 @@ extend(RequestContext.prototype, {
|
||||||
/// @startDocuBlock JSF_foxx_RequestContext_pathParam
|
/// @startDocuBlock JSF_foxx_RequestContext_pathParam
|
||||||
///
|
///
|
||||||
/// If you defined a route "/foxx/:id", you can constrain which format a path
|
/// If you defined a route "/foxx/:id", you can constrain which format a path
|
||||||
/// parameter (*/foxx/12*) can have by giving it a type. We currently support
|
/// parameter (*/foxx/12*) can have by giving it a *joi* type.
|
||||||
/// the following types:
|
|
||||||
///
|
///
|
||||||
/// * int
|
/// For more information on *joi* see [the official Joi documentation](https://github.com/spumko/joi).
|
||||||
/// * string
|
|
||||||
///
|
///
|
||||||
/// You can also provide a description of this parameter.
|
/// You can also provide a description of this parameter.
|
||||||
///
|
///
|
||||||
|
@ -216,8 +215,7 @@ extend(RequestContext.prototype, {
|
||||||
/// app.get("/foxx/:id", function {
|
/// app.get("/foxx/:id", function {
|
||||||
/// // Do something
|
/// // Do something
|
||||||
/// }).pathParam("id", {
|
/// }).pathParam("id", {
|
||||||
/// description: "Id of the Foxx",
|
/// type: joi.number().integer().required().description("Id of the Foxx")
|
||||||
/// type: "int"
|
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
/// @endDocuBlock
|
/// @endDocuBlock
|
||||||
|
@ -226,14 +224,49 @@ extend(RequestContext.prototype, {
|
||||||
pathParam: function (paramName, attributes) {
|
pathParam: function (paramName, attributes) {
|
||||||
'use strict';
|
'use strict';
|
||||||
var url = this.route.url,
|
var url = this.route.url,
|
||||||
constraint = url.constraint || {};
|
urlConstraint = url.constraint || {},
|
||||||
|
type = attributes.type,
|
||||||
|
required = attributes.required,
|
||||||
|
description = attributes.description,
|
||||||
|
constraint = type,
|
||||||
|
regexType = type,
|
||||||
|
cfg;
|
||||||
|
|
||||||
constraint[paramName] = this.typeToRegex[attributes.type];
|
// deprecated: assume type.describe is always a function
|
||||||
if (!constraint[paramName]) {
|
if (type && typeof type.describe === 'function') {
|
||||||
throw new Error("Illegal attribute type: " + attributes.type);
|
if (typeof required === 'boolean') {
|
||||||
|
constraint = required ? constraint.required() : constraint.optional();
|
||||||
}
|
}
|
||||||
this.route.url = internal.constructUrlObject(url.match, constraint, url.methods[0]);
|
if (typeof description === 'string') {
|
||||||
this.docs.addPathParam(paramName, attributes.description, attributes.type);
|
constraint = constraint.description(description);
|
||||||
|
}
|
||||||
|
this.constraints.urlParams[paramName] = constraint;
|
||||||
|
cfg = constraint.describe();
|
||||||
|
required = Boolean(cfg.flags && cfg.flags.presense === 'required');
|
||||||
|
description = cfg.description;
|
||||||
|
type = cfg.type;
|
||||||
|
if (
|
||||||
|
type === 'number' &&
|
||||||
|
_.isArray(cfg.rules) &&
|
||||||
|
_.some(cfg.rules, function (rule) {
|
||||||
|
return rule.name === 'integer';
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
type = 'integer';
|
||||||
|
}
|
||||||
|
if (_.has(this.typeToRegex, type)) {
|
||||||
|
regexType = type;
|
||||||
|
} else {
|
||||||
|
regexType = 'string';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
urlConstraint[paramName] = this.typeToRegex[regexType];
|
||||||
|
if (!urlConstraint[paramName]) {
|
||||||
|
throw new Error("Illegal attribute type: " + regexType);
|
||||||
|
}
|
||||||
|
this.route.url = internal.constructUrlObject(url.match, urlConstraint, url.methods[0]);
|
||||||
|
this.docs.addPathParam(paramName, description, type);
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -245,14 +278,12 @@ extend(RequestContext.prototype, {
|
||||||
/// Describe a query parameter:
|
/// Describe a query parameter:
|
||||||
///
|
///
|
||||||
/// If you defined a route "/foxx", you can constrain which format a query
|
/// If you defined a route "/foxx", you can constrain which format a query
|
||||||
/// parameter (*/foxx?a=12*) can have by giving it a type. We currently support
|
/// parameter (*/foxx?a=12*) can have by giving it a *joi* type.
|
||||||
/// the following types:
|
|
||||||
///
|
///
|
||||||
/// * int
|
/// For more information on *joi* see [the official Joi documentation](https://github.com/spumko/joi).
|
||||||
/// * string
|
|
||||||
///
|
///
|
||||||
/// You can also provide a description of this parameter, if it is required and
|
/// You can also provide a description of this parameter and
|
||||||
/// if you can provide the parameter multiple times.
|
/// whether you can provide the parameter multiple times.
|
||||||
///
|
///
|
||||||
/// @EXAMPLES
|
/// @EXAMPLES
|
||||||
///
|
///
|
||||||
|
@ -260,9 +291,7 @@ extend(RequestContext.prototype, {
|
||||||
/// app.get("/foxx", function {
|
/// app.get("/foxx", function {
|
||||||
/// // Do something
|
/// // Do something
|
||||||
/// }).queryParam("id", {
|
/// }).queryParam("id", {
|
||||||
/// description: "Id of the Foxx",
|
/// type: joi.number().integer().required().description("Id of the Foxx"),
|
||||||
/// type: "int",
|
|
||||||
/// required: true,
|
|
||||||
/// allowMultiple: false
|
/// allowMultiple: false
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -271,11 +300,41 @@ extend(RequestContext.prototype, {
|
||||||
|
|
||||||
queryParam: function (paramName, attributes) {
|
queryParam: function (paramName, attributes) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
var type = attributes.type,
|
||||||
|
required = attributes.required,
|
||||||
|
description = attributes.description,
|
||||||
|
constraint = type,
|
||||||
|
cfg;
|
||||||
|
|
||||||
|
// deprecated: assume type.describe is always a function
|
||||||
|
if (type && typeof type.describe === 'function') {
|
||||||
|
if (typeof required === 'boolean') {
|
||||||
|
constraint = required ? constraint.required() : constraint.optional();
|
||||||
|
}
|
||||||
|
if (typeof description === 'string') {
|
||||||
|
constraint = constraint.description(description);
|
||||||
|
}
|
||||||
|
this.constraints.queryParams[paramName] = constraint;
|
||||||
|
cfg = constraint.describe();
|
||||||
|
required = Boolean(cfg.flags && cfg.flags.presense === 'required');
|
||||||
|
description = cfg.description;
|
||||||
|
type = cfg.type;
|
||||||
|
if (
|
||||||
|
type === 'number' &&
|
||||||
|
_.isArray(cfg.rules) &&
|
||||||
|
_.some(cfg.rules, function (rule) {
|
||||||
|
return rule.name === 'integer';
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
type = 'integer';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.docs.addQueryParam(
|
this.docs.addQueryParam(
|
||||||
paramName,
|
paramName,
|
||||||
attributes.description,
|
description,
|
||||||
attributes.type,
|
type,
|
||||||
attributes.required,
|
required,
|
||||||
attributes.allowMultiple
|
attributes.allowMultiple
|
||||||
);
|
);
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -6,6 +6,7 @@ var stub,
|
||||||
allow,
|
allow,
|
||||||
FunctionStub,
|
FunctionStub,
|
||||||
mockConstructor,
|
mockConstructor,
|
||||||
|
joi = require("joi"),
|
||||||
_ = require("underscore");
|
_ = require("underscore");
|
||||||
|
|
||||||
// Sorry for Yak Shaving. But I can't take it anymore.
|
// Sorry for Yak Shaving. But I can't take it anymore.
|
||||||
|
@ -464,11 +465,11 @@ function DocumentationAndConstraintsSpec () {
|
||||||
},
|
},
|
||||||
|
|
||||||
testDefinePathParam: function () {
|
testDefinePathParam: function () {
|
||||||
app.get('/foxx/:id', function () {
|
var constraint = joi.number().integer().description("Id of the Foxx"),
|
||||||
|
context = app.get('/foxx/:id', function () {
|
||||||
//nothing
|
//nothing
|
||||||
}).pathParam("id", {
|
}).pathParam("id", {
|
||||||
description: "Id of the Foxx",
|
type: constraint
|
||||||
type: "int"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assertEqual(routes.length, 1);
|
assertEqual(routes.length, 1);
|
||||||
|
@ -476,15 +477,16 @@ function DocumentationAndConstraintsSpec () {
|
||||||
assertEqual(routes[0].docs.parameters[0].paramType, "path");
|
assertEqual(routes[0].docs.parameters[0].paramType, "path");
|
||||||
assertEqual(routes[0].docs.parameters[0].name, "id");
|
assertEqual(routes[0].docs.parameters[0].name, "id");
|
||||||
assertEqual(routes[0].docs.parameters[0].description, "Id of the Foxx");
|
assertEqual(routes[0].docs.parameters[0].description, "Id of the Foxx");
|
||||||
assertEqual(routes[0].docs.parameters[0].dataType, "int");
|
assertEqual(routes[0].docs.parameters[0].dataType, "integer");
|
||||||
|
assertEqual(context.constraints.urlParams, {id: constraint});
|
||||||
},
|
},
|
||||||
|
|
||||||
testDefinePathCaseParam: function () {
|
testDefinePathCaseParam: function () {
|
||||||
app.get('/foxx/:idParam', function () {
|
var constraint = joi.number().integer().description("Id of the Foxx"),
|
||||||
|
context = app.get('/foxx/:idParam', function () {
|
||||||
//nothing
|
//nothing
|
||||||
}).pathParam("idParam", {
|
}).pathParam("idParam", {
|
||||||
description: "Id of the Foxx",
|
type: constraint
|
||||||
type: "int"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assertEqual(routes.length, 1);
|
assertEqual(routes.length, 1);
|
||||||
|
@ -492,18 +494,19 @@ function DocumentationAndConstraintsSpec () {
|
||||||
assertEqual(routes[0].docs.parameters[0].paramType, "path");
|
assertEqual(routes[0].docs.parameters[0].paramType, "path");
|
||||||
assertEqual(routes[0].docs.parameters[0].name, "idParam");
|
assertEqual(routes[0].docs.parameters[0].name, "idParam");
|
||||||
assertEqual(routes[0].docs.parameters[0].description, "Id of the Foxx");
|
assertEqual(routes[0].docs.parameters[0].description, "Id of the Foxx");
|
||||||
assertEqual(routes[0].docs.parameters[0].dataType, "int");
|
assertEqual(routes[0].docs.parameters[0].dataType, "integer");
|
||||||
|
assertEqual(context.constraints.urlParams, {idParam: constraint});
|
||||||
},
|
},
|
||||||
|
|
||||||
testDefineMultiplePathParams: function () {
|
testDefineMultiplePathParams: function () {
|
||||||
app.get('/:foxx/:id', function () {
|
var foxxConstraint = joi.string().description("Kind of Foxx"),
|
||||||
|
idConstraint = joi.number().integer().description("Id of the Foxx"),
|
||||||
|
context = app.get('/:foxx/:id', function () {
|
||||||
//nothing
|
//nothing
|
||||||
}).pathParam("foxx", {
|
}).pathParam("foxx", {
|
||||||
description: "Kind of Foxx",
|
type: foxxConstraint
|
||||||
type: "string"
|
|
||||||
}).pathParam("id", {
|
}).pathParam("id", {
|
||||||
description: "Id of the Foxx",
|
type: idConstraint
|
||||||
type: "int"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assertEqual(routes.length, 1);
|
assertEqual(routes.length, 1);
|
||||||
|
@ -518,18 +521,20 @@ function DocumentationAndConstraintsSpec () {
|
||||||
assertEqual(routes[0].docs.parameters[1].paramType, "path");
|
assertEqual(routes[0].docs.parameters[1].paramType, "path");
|
||||||
assertEqual(routes[0].docs.parameters[1].name, "id");
|
assertEqual(routes[0].docs.parameters[1].name, "id");
|
||||||
assertEqual(routes[0].docs.parameters[1].description, "Id of the Foxx");
|
assertEqual(routes[0].docs.parameters[1].description, "Id of the Foxx");
|
||||||
assertEqual(routes[0].docs.parameters[1].dataType, "int");
|
assertEqual(routes[0].docs.parameters[1].dataType, "integer");
|
||||||
|
|
||||||
|
assertEqual(context.constraints.urlParams, {foxx: foxxConstraint, id: idConstraint});
|
||||||
},
|
},
|
||||||
|
|
||||||
testDefineMultiplePathCaseParams: function () {
|
testDefineMultiplePathCaseParams: function () {
|
||||||
app.get('/:foxxParam/:idParam', function () {
|
var foxxConstraint = joi.string().description("Kind of Foxx"),
|
||||||
|
idConstraint = joi.number().integer().description("Id of the Foxx"),
|
||||||
|
context = app.get('/:foxxParam/:idParam', function () {
|
||||||
//nothing
|
//nothing
|
||||||
}).pathParam("foxxParam", {
|
}).pathParam("foxxParam", {
|
||||||
description: "Kind of Foxx",
|
type: foxxConstraint
|
||||||
type: "string"
|
|
||||||
}).pathParam("idParam", {
|
}).pathParam("idParam", {
|
||||||
description: "Id of the Foxx",
|
type: idConstraint
|
||||||
type: "int"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assertEqual(routes.length, 1);
|
assertEqual(routes.length, 1);
|
||||||
|
@ -544,16 +549,17 @@ function DocumentationAndConstraintsSpec () {
|
||||||
assertEqual(routes[0].docs.parameters[1].paramType, "path");
|
assertEqual(routes[0].docs.parameters[1].paramType, "path");
|
||||||
assertEqual(routes[0].docs.parameters[1].name, "idParam");
|
assertEqual(routes[0].docs.parameters[1].name, "idParam");
|
||||||
assertEqual(routes[0].docs.parameters[1].description, "Id of the Foxx");
|
assertEqual(routes[0].docs.parameters[1].description, "Id of the Foxx");
|
||||||
assertEqual(routes[0].docs.parameters[1].dataType, "int");
|
assertEqual(routes[0].docs.parameters[1].dataType, "integer");
|
||||||
|
|
||||||
|
assertEqual(context.constraints.urlParams, {foxxParam: foxxConstraint, idParam: idConstraint});
|
||||||
},
|
},
|
||||||
|
|
||||||
testDefineQueryParam: function () {
|
testDefineQueryParam: function () {
|
||||||
app.get('/foxx', function () {
|
var constraint = joi.number().integer().description("The value of an a"),
|
||||||
|
context = app.get('/foxx', function () {
|
||||||
//nothing
|
//nothing
|
||||||
}).queryParam("a", {
|
}).queryParam("a", {
|
||||||
description: "The value of an a",
|
type: constraint,
|
||||||
type: "int",
|
|
||||||
required: false,
|
|
||||||
allowMultiple: true
|
allowMultiple: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -561,9 +567,10 @@ function DocumentationAndConstraintsSpec () {
|
||||||
assertEqual(routes[0].docs.parameters[0].paramType, "query");
|
assertEqual(routes[0].docs.parameters[0].paramType, "query");
|
||||||
assertEqual(routes[0].docs.parameters[0].name, "a");
|
assertEqual(routes[0].docs.parameters[0].name, "a");
|
||||||
assertEqual(routes[0].docs.parameters[0].description, "The value of an a");
|
assertEqual(routes[0].docs.parameters[0].description, "The value of an a");
|
||||||
assertEqual(routes[0].docs.parameters[0].dataType, "int");
|
assertEqual(routes[0].docs.parameters[0].dataType, "integer");
|
||||||
assertEqual(routes[0].docs.parameters[0].required, false);
|
assertEqual(routes[0].docs.parameters[0].required, false);
|
||||||
assertEqual(routes[0].docs.parameters[0].allowMultiple, true);
|
assertEqual(routes[0].docs.parameters[0].allowMultiple, true);
|
||||||
|
assertEqual(context.constraints.queryParams, {a: constraint});
|
||||||
},
|
},
|
||||||
|
|
||||||
testAddBodyParam: function () {
|
testAddBodyParam: function () {
|
||||||
|
@ -912,6 +919,160 @@ function LegacyDocumentationAndConstraintsSpec () {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function LegacyDocumentationAndConstraintsSpec () {
|
||||||
|
var app, routes, models;
|
||||||
|
|
||||||
|
return {
|
||||||
|
setUp: function () {
|
||||||
|
app = new FoxxController(fakeContext);
|
||||||
|
routes = app.routingInfo.routes;
|
||||||
|
models = app.models;
|
||||||
|
},
|
||||||
|
|
||||||
|
testDefinePathParamOverride: function () {
|
||||||
|
var constraint = joi.number().integer().description("no text"),
|
||||||
|
context = app.get('/foxx/:id', function () {
|
||||||
|
//nothing
|
||||||
|
}).pathParam("id", {
|
||||||
|
type: constraint,
|
||||||
|
description: "Id of the Foxx"
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEqual(routes.length, 1);
|
||||||
|
assertEqual(routes[0].url.constraint.id, "/[0-9]+/");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].paramType, "path");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].name, "id");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].description, "Id of the Foxx");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].dataType, "integer");
|
||||||
|
assertEqual(context.constraints.urlParams, {id: constraint});
|
||||||
|
},
|
||||||
|
|
||||||
|
testDefinePathParam: function () {
|
||||||
|
app.get('/foxx/:id', function () {
|
||||||
|
//nothing
|
||||||
|
}).pathParam("id", {
|
||||||
|
description: "Id of the Foxx",
|
||||||
|
type: "int"
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEqual(routes.length, 1);
|
||||||
|
assertEqual(routes[0].url.constraint.id, "/[0-9]+/");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].paramType, "path");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].name, "id");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].description, "Id of the Foxx");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].dataType, "int");
|
||||||
|
},
|
||||||
|
|
||||||
|
testDefinePathCaseParam: function () {
|
||||||
|
app.get('/foxx/:idParam', function () {
|
||||||
|
//nothing
|
||||||
|
}).pathParam("idParam", {
|
||||||
|
description: "Id of the Foxx",
|
||||||
|
type: "int"
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEqual(routes.length, 1);
|
||||||
|
assertEqual(routes[0].url.constraint.idParam, "/[0-9]+/");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].paramType, "path");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].name, "idParam");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].description, "Id of the Foxx");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].dataType, "int");
|
||||||
|
},
|
||||||
|
|
||||||
|
testDefineMultiplePathParams: function () {
|
||||||
|
app.get('/:foxx/:id', function () {
|
||||||
|
//nothing
|
||||||
|
}).pathParam("foxx", {
|
||||||
|
description: "Kind of Foxx",
|
||||||
|
type: "string"
|
||||||
|
}).pathParam("id", {
|
||||||
|
description: "Id of the Foxx",
|
||||||
|
type: "int"
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEqual(routes.length, 1);
|
||||||
|
|
||||||
|
assertEqual(routes[0].url.constraint.foxx, "/[^/]+/");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].paramType, "path");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].name, "foxx");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].description, "Kind of Foxx");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].dataType, "string");
|
||||||
|
|
||||||
|
assertEqual(routes[0].url.constraint.id, "/[0-9]+/");
|
||||||
|
assertEqual(routes[0].docs.parameters[1].paramType, "path");
|
||||||
|
assertEqual(routes[0].docs.parameters[1].name, "id");
|
||||||
|
assertEqual(routes[0].docs.parameters[1].description, "Id of the Foxx");
|
||||||
|
assertEqual(routes[0].docs.parameters[1].dataType, "int");
|
||||||
|
},
|
||||||
|
|
||||||
|
testDefineMultiplePathCaseParams: function () {
|
||||||
|
app.get('/:foxxParam/:idParam', function () {
|
||||||
|
//nothing
|
||||||
|
}).pathParam("foxxParam", {
|
||||||
|
description: "Kind of Foxx",
|
||||||
|
type: "string"
|
||||||
|
}).pathParam("idParam", {
|
||||||
|
description: "Id of the Foxx",
|
||||||
|
type: "int"
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEqual(routes.length, 1);
|
||||||
|
|
||||||
|
assertEqual(routes[0].url.constraint.foxxParam, "/[^/]+/");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].paramType, "path");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].name, "foxxParam");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].description, "Kind of Foxx");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].dataType, "string");
|
||||||
|
|
||||||
|
assertEqual(routes[0].url.constraint.idParam, "/[0-9]+/");
|
||||||
|
assertEqual(routes[0].docs.parameters[1].paramType, "path");
|
||||||
|
assertEqual(routes[0].docs.parameters[1].name, "idParam");
|
||||||
|
assertEqual(routes[0].docs.parameters[1].description, "Id of the Foxx");
|
||||||
|
assertEqual(routes[0].docs.parameters[1].dataType, "int");
|
||||||
|
},
|
||||||
|
|
||||||
|
testDefineQueryParamOverride: function () {
|
||||||
|
var constraint = joi.number().integer().description("no text"),
|
||||||
|
context = app.get('/foxx', function () {
|
||||||
|
//nothing
|
||||||
|
}).queryParam("a", {
|
||||||
|
type: constraint,
|
||||||
|
required: true,
|
||||||
|
description: "The value of an a",
|
||||||
|
allowMultiple: true
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEqual(routes.length, 1);
|
||||||
|
assertEqual(routes[0].docs.parameters[0].paramType, "query");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].name, "a");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].description, "The value of an a");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].dataType, "integer");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].required, false);
|
||||||
|
assertEqual(routes[0].docs.parameters[0].allowMultiple, true);
|
||||||
|
assertEqual(context.constraints.queryParams, {a: constraint});
|
||||||
|
},
|
||||||
|
|
||||||
|
testDefineQueryParam: function () {
|
||||||
|
app.get('/foxx', function () {
|
||||||
|
//nothing
|
||||||
|
}).queryParam("a", {
|
||||||
|
description: "The value of an a",
|
||||||
|
type: "int",
|
||||||
|
required: false,
|
||||||
|
allowMultiple: true
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEqual(routes.length, 1);
|
||||||
|
assertEqual(routes[0].docs.parameters[0].paramType, "query");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].name, "a");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].description, "The value of an a");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].dataType, "int");
|
||||||
|
assertEqual(routes[0].docs.parameters[0].required, false);
|
||||||
|
assertEqual(routes[0].docs.parameters[0].allowMultiple, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function AddMiddlewareFoxxControllerSpec () {
|
function AddMiddlewareFoxxControllerSpec () {
|
||||||
var app;
|
var app;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue