2016-09-06 18:25:03 +00:00
|
|
|
import test from 'ava';
|
|
|
|
import joi from 'joi';
|
|
|
|
import
|
|
|
|
getConfigForMethod, {
|
|
|
|
whereMethods,
|
|
|
|
includeMethods,
|
|
|
|
payloadMethods,
|
2016-09-08 01:09:48 +00:00
|
|
|
scopeParamsMethods,
|
|
|
|
idParamsMethods,
|
2016-09-06 18:25:03 +00:00
|
|
|
sequelizeOperators,
|
|
|
|
} from './get-config-for-method.js';
|
|
|
|
|
|
|
|
test.beforeEach((t) => {
|
2016-09-08 01:09:48 +00:00
|
|
|
t.context.models = ['MyModel'];
|
|
|
|
|
|
|
|
t.context.scopes = ['aScope'];
|
|
|
|
|
2016-09-06 18:25:03 +00:00
|
|
|
t.context.attributeValidation = {
|
|
|
|
myKey: joi.any(),
|
|
|
|
};
|
|
|
|
|
|
|
|
t.context.associationValidation = {
|
2016-09-08 01:09:48 +00:00
|
|
|
include: joi.array().items(joi.string().valid(t.context.models)),
|
2016-09-06 18:25:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
t.context.config = {
|
|
|
|
cors: {},
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
2016-09-08 01:09:48 +00:00
|
|
|
test('validate.query seqeulizeOperators', (t) => {
|
2016-09-06 18:25:03 +00:00
|
|
|
whereMethods.forEach((method) => {
|
|
|
|
const configForMethod = getConfigForMethod({ method });
|
|
|
|
const { query } = configForMethod.validate;
|
|
|
|
|
|
|
|
t.truthy(
|
|
|
|
query,
|
|
|
|
`applies query validation for ${method}`
|
|
|
|
);
|
|
|
|
|
|
|
|
Object.keys(sequelizeOperators).forEach((operator) => {
|
2016-09-08 01:09:48 +00:00
|
|
|
t.ifError(
|
|
|
|
query.validate({ [operator]: true }).error
|
|
|
|
, `applies sequelize operator "${operator}" in validate.where for ${method}`
|
2016-09-06 18:25:03 +00:00
|
|
|
);
|
|
|
|
});
|
2016-09-08 01:09:48 +00:00
|
|
|
|
|
|
|
t.truthy(
|
|
|
|
query.validate({ notAThing: true }).error
|
|
|
|
, 'errors on a non-valid key'
|
|
|
|
);
|
2016-09-06 18:25:03 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-09-08 01:09:48 +00:00
|
|
|
test('validate.query attributeValidation', (t) => {
|
2016-09-06 18:25:03 +00:00
|
|
|
const { attributeValidation } = t.context;
|
|
|
|
|
|
|
|
whereMethods.forEach((method) => {
|
|
|
|
const configForMethod = getConfigForMethod({ method, attributeValidation });
|
|
|
|
const { query } = configForMethod.validate;
|
|
|
|
|
|
|
|
Object.keys(attributeValidation).forEach((key) => {
|
2016-09-08 01:09:48 +00:00
|
|
|
t.ifError(
|
|
|
|
query.validate({ [key]: true }).error
|
2016-09-06 18:25:03 +00:00
|
|
|
, `applies attributeValidation (${key}) to validate.query`
|
|
|
|
);
|
|
|
|
});
|
2016-09-08 01:09:48 +00:00
|
|
|
|
|
|
|
t.truthy(
|
|
|
|
query.validate({ notAThing: true }).error
|
|
|
|
, 'errors on a non-valid key'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('query attributeValidation w/ config as plain object', (t) => {
|
|
|
|
const { attributeValidation } = t.context;
|
|
|
|
const config = {
|
|
|
|
validate: {
|
|
|
|
query: {
|
|
|
|
aKey: joi.boolean(),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
whereMethods.forEach((method) => {
|
|
|
|
const configForMethod = getConfigForMethod({
|
|
|
|
method,
|
|
|
|
attributeValidation,
|
|
|
|
config,
|
|
|
|
});
|
|
|
|
const { query } = configForMethod.validate;
|
|
|
|
|
|
|
|
const keys = [
|
|
|
|
...Object.keys(attributeValidation),
|
|
|
|
...Object.keys(config.validate.query),
|
|
|
|
];
|
|
|
|
|
|
|
|
keys.forEach((key) => {
|
|
|
|
t.ifError(
|
|
|
|
query.validate({ [key]: true }).error
|
|
|
|
, `applies ${key} to validate.query`
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
t.truthy(
|
|
|
|
query.validate({ notAThing: true }).error
|
|
|
|
, 'errors on a non-valid key'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('query attributeValidation w/ config as joi object', (t) => {
|
|
|
|
const { attributeValidation } = t.context;
|
|
|
|
const queryKeys = {
|
|
|
|
aKey: joi.boolean(),
|
|
|
|
};
|
|
|
|
const config = {
|
|
|
|
validate: {
|
|
|
|
query: joi.object().keys(queryKeys),
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
whereMethods.forEach((method) => {
|
|
|
|
const configForMethod = getConfigForMethod({
|
|
|
|
method,
|
|
|
|
attributeValidation,
|
|
|
|
config,
|
|
|
|
});
|
|
|
|
const { query } = configForMethod.validate;
|
|
|
|
|
|
|
|
const keys = [
|
|
|
|
...Object.keys(attributeValidation),
|
|
|
|
...Object.keys(queryKeys),
|
|
|
|
];
|
|
|
|
|
|
|
|
keys.forEach((key) => {
|
|
|
|
t.ifError(
|
|
|
|
query.validate({ [key]: true }).error
|
|
|
|
, `applies ${key} to validate.query`
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
t.truthy(
|
|
|
|
query.validate({ notAThing: true }).error
|
|
|
|
, 'errors on a non-valid key'
|
|
|
|
);
|
2016-09-06 18:25:03 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-09-08 01:09:48 +00:00
|
|
|
test('validate.query associationValidation', (t) => {
|
|
|
|
const { attributeValidation, associationValidation, models } = t.context;
|
2016-09-06 18:25:03 +00:00
|
|
|
|
|
|
|
includeMethods.forEach((method) => {
|
|
|
|
const configForMethod = getConfigForMethod({
|
|
|
|
method,
|
|
|
|
attributeValidation,
|
|
|
|
associationValidation,
|
|
|
|
});
|
|
|
|
const { query } = configForMethod.validate;
|
|
|
|
|
|
|
|
Object.keys(attributeValidation).forEach((key) => {
|
2016-09-08 01:09:48 +00:00
|
|
|
t.ifError(
|
|
|
|
query.validate({ [key]: true }).error
|
2016-09-06 18:25:03 +00:00
|
|
|
, `applies attributeValidation (${key}) to validate.query when include should be applied`
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
Object.keys(associationValidation).forEach((key) => {
|
2016-09-08 01:09:48 +00:00
|
|
|
t.ifError(
|
|
|
|
query.validate({ [key]: models }).error
|
2016-09-06 18:25:03 +00:00
|
|
|
, `applies associationValidation (${key}) to validate.query when include should be applied`
|
|
|
|
);
|
|
|
|
});
|
2016-09-08 01:09:48 +00:00
|
|
|
|
|
|
|
t.truthy(
|
|
|
|
query.validate({ notAThing: true }).error
|
|
|
|
, 'errors on a non-valid key'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('query associationValidation w/ config as plain object', (t) => {
|
|
|
|
const { associationValidation, models } = t.context;
|
|
|
|
const config = {
|
|
|
|
validate: {
|
|
|
|
query: {
|
|
|
|
aKey: joi.boolean(),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
includeMethods.forEach((method) => {
|
|
|
|
const configForMethod = getConfigForMethod({
|
|
|
|
method,
|
|
|
|
associationValidation,
|
|
|
|
config,
|
|
|
|
});
|
|
|
|
const { query } = configForMethod.validate;
|
|
|
|
|
|
|
|
Object.keys(associationValidation).forEach((key) => {
|
|
|
|
t.ifError(
|
|
|
|
query.validate({ [key]: models }).error
|
|
|
|
, `applies ${key} to validate.query`
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
Object.keys(config.validate.query).forEach((key) => {
|
|
|
|
t.ifError(
|
|
|
|
query.validate({ [key]: true }).error
|
|
|
|
, `applies ${key} to validate.query`
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
t.truthy(
|
|
|
|
query.validate({ notAThing: true }).error
|
|
|
|
, 'errors on a non-valid key'
|
|
|
|
);
|
2016-09-06 18:25:03 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-09-08 01:09:48 +00:00
|
|
|
test('query associationValidation w/ config as joi object', (t) => {
|
|
|
|
const { associationValidation, models } = t.context;
|
|
|
|
const queryKeys = {
|
|
|
|
aKey: joi.boolean(),
|
|
|
|
};
|
|
|
|
const config = {
|
|
|
|
validate: {
|
|
|
|
query: joi.object().keys(queryKeys),
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
includeMethods.forEach((method) => {
|
|
|
|
const configForMethod = getConfigForMethod({
|
|
|
|
method,
|
|
|
|
associationValidation,
|
|
|
|
config,
|
|
|
|
});
|
|
|
|
const { query } = configForMethod.validate;
|
|
|
|
|
|
|
|
Object.keys(associationValidation).forEach((key) => {
|
|
|
|
t.ifError(
|
|
|
|
query.validate({ [key]: models }).error
|
|
|
|
, `applies ${key} to validate.query`
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
Object.keys(queryKeys).forEach((key) => {
|
|
|
|
t.ifError(
|
|
|
|
query.validate({ [key]: true }).error
|
|
|
|
, `applies ${key} to validate.query`
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
t.truthy(
|
|
|
|
query.validate({ notAThing: true }).error
|
|
|
|
, 'errors on a non-valid key'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('validate.payload associationValidation', (t) => {
|
2016-09-06 18:25:03 +00:00
|
|
|
const { attributeValidation } = t.context;
|
|
|
|
|
|
|
|
payloadMethods.forEach((method) => {
|
|
|
|
const configForMethod = getConfigForMethod({ method, attributeValidation });
|
|
|
|
const { payload } = configForMethod.validate;
|
|
|
|
|
|
|
|
Object.keys(attributeValidation).forEach((key) => {
|
2016-09-08 01:09:48 +00:00
|
|
|
t.ifError(
|
|
|
|
payload.validate({ [key]: true }).error
|
2016-09-06 18:25:03 +00:00
|
|
|
, `applies attributeValidation (${key}) to validate.payload`
|
|
|
|
);
|
|
|
|
});
|
2016-09-08 01:09:48 +00:00
|
|
|
|
|
|
|
t.truthy(
|
|
|
|
payload.validate({ notAThing: true }).error
|
|
|
|
, 'errors on a non-valid key'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('payload attributeValidation w/ config as plain object', (t) => {
|
|
|
|
const { attributeValidation } = t.context;
|
|
|
|
const config = {
|
|
|
|
validate: {
|
|
|
|
payload: {
|
|
|
|
aKey: joi.boolean(),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
payloadMethods.forEach((method) => {
|
|
|
|
const configForMethod = getConfigForMethod({
|
|
|
|
method,
|
|
|
|
attributeValidation,
|
|
|
|
config,
|
|
|
|
});
|
|
|
|
const { payload } = configForMethod.validate;
|
|
|
|
|
|
|
|
const keys = [
|
|
|
|
...Object.keys(attributeValidation),
|
|
|
|
...Object.keys(config.validate.payload),
|
|
|
|
];
|
|
|
|
|
|
|
|
keys.forEach((key) => {
|
|
|
|
t.ifError(
|
|
|
|
payload.validate({ [key]: true }).error
|
|
|
|
, `applies ${key} to validate.payload`
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
t.truthy(
|
|
|
|
payload.validate({ notAThing: true }).error
|
|
|
|
, 'errors on a non-valid key'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('payload attributeValidation w/ config as joi object', (t) => {
|
|
|
|
const { attributeValidation } = t.context;
|
|
|
|
const payloadKeys = {
|
|
|
|
aKey: joi.boolean(),
|
|
|
|
};
|
|
|
|
const config = {
|
|
|
|
validate: {
|
|
|
|
payload: joi.object().keys(payloadKeys),
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
payloadMethods.forEach((method) => {
|
|
|
|
const configForMethod = getConfigForMethod({
|
|
|
|
method,
|
|
|
|
attributeValidation,
|
|
|
|
config,
|
|
|
|
});
|
|
|
|
const { payload } = configForMethod.validate;
|
|
|
|
|
|
|
|
const keys = [
|
|
|
|
...Object.keys(attributeValidation),
|
|
|
|
...Object.keys(payloadKeys),
|
|
|
|
];
|
|
|
|
|
|
|
|
keys.forEach((key) => {
|
|
|
|
t.ifError(
|
|
|
|
payload.validate({ [key]: true }).error
|
|
|
|
, `applies ${key} to validate.payload`
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
t.truthy(
|
|
|
|
payload.validate({ notAThing: true }).error
|
|
|
|
, 'errors on a non-valid key'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('validate.params scopeParamsMethods', (t) => {
|
|
|
|
const { scopes } = t.context;
|
|
|
|
|
|
|
|
scopeParamsMethods.forEach((method) => {
|
|
|
|
const configForMethod = getConfigForMethod({ method, scopes });
|
|
|
|
const { params } = configForMethod.validate;
|
|
|
|
|
|
|
|
scopes.forEach((key) => {
|
|
|
|
t.ifError(
|
|
|
|
params.validate({ scope: key }).error
|
|
|
|
, `applies "scope: ${key}" to validate.params`
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
t.truthy(
|
|
|
|
params.validate({ scope: 'notAthing' }).error
|
|
|
|
, 'errors on a non-valid key'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('params scopeParamsMethods w/ config as plain object', (t) => {
|
|
|
|
const { scopes } = t.context;
|
|
|
|
const config = {
|
|
|
|
validate: {
|
|
|
|
params: {
|
|
|
|
aKey: joi.boolean(),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
scopeParamsMethods.forEach((method) => {
|
|
|
|
const configForMethod = getConfigForMethod({
|
|
|
|
method,
|
|
|
|
scopes,
|
|
|
|
config,
|
|
|
|
});
|
|
|
|
const { params } = configForMethod.validate;
|
|
|
|
|
|
|
|
scopes.forEach((key) => {
|
|
|
|
t.ifError(
|
|
|
|
params.validate({ scope: key }).error
|
|
|
|
, `applies "scope: ${key}" to validate.params`
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
Object.keys(config.validate.params).forEach((key) => {
|
|
|
|
t.ifError(
|
|
|
|
params.validate({ [key]: true }).error
|
|
|
|
, `applies ${key} to validate.params`
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
t.truthy(
|
|
|
|
params.validate({ notAThing: true }).error
|
|
|
|
, 'errors on a non-valid key'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('params scopeParamsMethods w/ config as joi object', (t) => {
|
|
|
|
const { scopes } = t.context;
|
|
|
|
const paramsKeys = {
|
|
|
|
aKey: joi.boolean(),
|
|
|
|
};
|
|
|
|
const config = {
|
|
|
|
validate: {
|
|
|
|
params: joi.object().keys(paramsKeys),
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
scopeParamsMethods.forEach((method) => {
|
|
|
|
const configForMethod = getConfigForMethod({
|
|
|
|
method,
|
|
|
|
scopes,
|
|
|
|
config,
|
|
|
|
});
|
|
|
|
const { params } = configForMethod.validate;
|
|
|
|
|
|
|
|
scopes.forEach((key) => {
|
|
|
|
t.ifError(
|
|
|
|
params.validate({ scope: key }).error
|
|
|
|
, `applies "scope: ${key}" to validate.params`
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
Object.keys(paramsKeys).forEach((key) => {
|
|
|
|
t.ifError(
|
|
|
|
params.validate({ [key]: true }).error
|
|
|
|
, `applies ${key} to validate.params`
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
t.truthy(
|
|
|
|
params.validate({ notAThing: true }).error
|
|
|
|
, 'errors on a non-valid key'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test('validate.payload idParamsMethods', (t) => {
|
|
|
|
idParamsMethods.forEach((method) => {
|
|
|
|
const configForMethod = getConfigForMethod({ method });
|
|
|
|
const { params } = configForMethod.validate;
|
|
|
|
|
|
|
|
t.ifError(
|
|
|
|
params.validate({ id: 'aThing' }).error
|
|
|
|
, 'applies id to validate.params'
|
|
|
|
);
|
2016-09-06 18:25:03 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-09-08 01:09:48 +00:00
|
|
|
test('does not modify initial config on multiple passes', (t) => {
|
2016-09-06 18:25:03 +00:00
|
|
|
const { config } = t.context;
|
|
|
|
const originalConfig = { ...config };
|
|
|
|
|
|
|
|
whereMethods.forEach((method) => {
|
2016-09-08 01:09:48 +00:00
|
|
|
getConfigForMethod({ method, ...t.context });
|
2016-09-06 18:25:03 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
t.deepEqual(
|
|
|
|
config
|
|
|
|
, originalConfig
|
|
|
|
, 'does not modify the original config object'
|
|
|
|
);
|
|
|
|
});
|