Browse Source

added interpolation service to schema

refactored similar service tests to iterate list of services instead of duplicating many tests for each service
pull/936/head
Stephen Hess 8 years ago
parent
commit
3c8bfa196e
  1. 5
      schema.js
  2. 526
      test/unit/schema.js

5
schema.js

@ -41,6 +41,11 @@ module.exports = Joi.object().keys({
url: Joi.string().uri({ scheme: /https?/ }),
timeout: Joi.number().integer().optional().default(250).min(0),
retries: Joi.number().integer().optional().default(3).min(0),
}).unknown(false).requiredKeys('url'),
interpolation: Joi.object().keys({
url: Joi.string().uri({ scheme: /https?/ }),
timeout: Joi.number().integer().optional().default(250).min(0),
retries: Joi.number().integer().optional().default(3).min(0),
}).unknown(false).requiredKeys('url')
}).unknown(false).default({}), // default api.services to an empty object
defaultParameters: Joi.object().keys({

526
test/unit/schema.js

@ -2,6 +2,7 @@
const Joi = require('joi');
const schema = require('../../schema');
const _ = require('lodash');
module.exports.tests = {};
@ -540,72 +541,30 @@ module.exports.tests.api_services_validation = (test, common) => {
};
module.exports.tests.placeholder_service_validation = (test, common) => {
module.exports.tests.service_validation = (test, common) => {
// these tests apply for all the individual service definitions
const services = ['pip', 'placeholder', 'language', 'interpolation'];
test('timeout and retries not specified should default to 250 and 3', (t) => {
services.forEach(service => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
placeholder: {
url: 'http://localhost'
}
}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.value.api.services.placeholder.timeout, 250);
t.equals(result.value.api.services.placeholder.retries, 3);
t.end();
});
test('when api.services.placeholder is defined, url is required', (t) => {
var config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
placeholder: {
}
}
services: {}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"url" is required');
t.end();
});
test('non-string api.services.placeholder.url should throw error', (t) => {
[null, 17, {}, [], true].forEach((value) => {
var config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
placeholder: {
url: value
}
}
},
esclient: {}
config.api.services[service] = {
url: 'http://localhost'
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"url" must be a string');
t.equals(result.value.api.services[service].timeout, 250);
t.equals(result.value.api.services[service].retries, 3);
});
@ -613,119 +572,45 @@ module.exports.tests.placeholder_service_validation = (test, common) => {
});
test('non-http/https api.services.placeholder.url should throw error', (t) => {
['ftp', 'git', 'unknown'].forEach((scheme) => {
var config = {
test('when api.services.service is defined, url is required', (t) => {
services.forEach(service => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
placeholder: {
url: `${scheme}://localhost`
}
}
services: {}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"url" must be a valid uri with a scheme matching the https\? pattern');
});
t.end();
});
test('non-url children of api.services.placeholder should be disallowed', (t) => {
var config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
placeholder: {
url: 'http://localhost',
unknown_property: 'value'
}
}
},
esclient: {}
};
config.api.services[service] = {};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"unknown_property" is not allowed');
t.end();
t.equals(result.error.details[0].message, '"url" is required');
});
};
module.exports.tests.pip_service_validation = (test, common) => {
test('timeout and retries not specified should default to 250 and 3', (t) => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
pip: {
url: 'http://localhost'
}
}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.value.api.services.pip.timeout, 250);
t.equals(result.value.api.services.pip.retries, 3);
t.end();
});
test('when api.services.pip is defined, url is required', (t) => {
var config = {
test('non-string api.services.pip.url should throw error', (t) => {
services.forEach(service => {
[null, 17, {}, [], true].forEach(value => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
pip: {
}
}
services: {}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"url" is required');
t.end();
});
test('non-string api.services.pip.url should throw error', (t) => {
[null, 17, {}, [], true].forEach((value) => {
var config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
pip: {
config.api.services[service] = {
url: value
}
}
},
esclient: {}
};
const result = Joi.validate(config, schema);
@ -735,26 +620,29 @@ module.exports.tests.pip_service_validation = (test, common) => {
});
});
t.end();
});
test('non-http/https api.services.pip.url should throw error', (t) => {
services.forEach(service => {
['ftp', 'git', 'unknown'].forEach((scheme) => {
var config = {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
pip: {
url: `${scheme}://localhost`
}
}
services: {}
},
esclient: {}
};
config.api.services[service] = {
url: `${scheme}://localhost`
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
@ -762,55 +650,33 @@ module.exports.tests.pip_service_validation = (test, common) => {
});
});
t.end();
});
test('non-url children of api.services.pip should be disallowed', (t) => {
var config = {
services.forEach(service => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
pip: {
url: 'http://localhost',
unknown_property: 'value'
}
}
services: {}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"unknown_property" is not allowed');
t.end();
});
test('non-number timeout should throw error', (t) => {
[null, 'string', {}, [], false].forEach((value) => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
pip: {
config.api.services[service] = {
url: 'http://localhost',
timeout: value
}
}
},
esclient: {}
unknown_property: 'value'
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"timeout" must be a number');
t.equals(result.error.details[0].message, '"unknown_property" is not allowed');
});
@ -818,198 +684,86 @@ module.exports.tests.pip_service_validation = (test, common) => {
});
test('non-integer timeout should throw error', (t) => {
test('non-number timeout should throw error', (t) => {
services.forEach(service => {
[null, 'string', {}, [], false].forEach((value) => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
pip: {
url: 'http://localhost',
timeout: 17.3
}
}
services: {}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"timeout" must be an integer');
t.end();
});
test('negative timeout should throw error', (t) => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
pip: {
config.api.services[service] = {
url: 'http://localhost',
timeout: -1
}
}
},
esclient: {}
timeout: value
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"timeout" must be larger than or equal to 0');
t.end();
t.equals(result.error.details[0].message, '"timeout" must be a number');
});
test('non-number retries should throw error', (t) => {
[null, 'string', {}, [], false].forEach((value) => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
pip: {
url: 'http://localhost',
retries: value
}
}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"retries" must be a number');
});
t.end();
});
test('non-integer retries should throw error', (t) => {
test('non-integer timeout should throw error', (t) => {
services.forEach(service => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
pip: {
url: 'http://localhost',
retries: 17.3
}
}
services: {}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"retries" must be an integer');
t.end();
});
test('negative retries should throw error', (t) => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
pip: {
config.api.services[service] = {
url: 'http://localhost',
retries: -1
}
}
},
esclient: {}
timeout: 17.3
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"retries" must be larger than or equal to 0');
t.end();
t.equals(result.error.details[0].message, '"timeout" must be an integer');
});
};
module.exports.tests.language_service_validation = (test, common) => {
test('timeout and retries not specified should default to 250 and 3', (t) => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
language: {
url: 'http://localhost'
}
}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.value.api.services.language.timeout, 250);
t.equals(result.value.api.services.language.retries, 3);
t.end();
});
test('when api.services.language is defined, url is required', (t) => {
var config = {
test('negative timeout should throw error', (t) => {
services.forEach(service => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
language: {
}
}
services: {}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"url" is required');
t.end();
});
test('non-string api.services.language.url should throw error', (t) => {
[null, 17, {}, [], true].forEach((value) => {
var config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
language: {
url: value
}
}
},
esclient: {}
config.api.services[service] = {
url: 'http://localhost',
timeout: -1
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"url" must be a string');
t.equals(result.error.details[0].message, '"timeout" must be larger than or equal to 0');
});
@ -1017,154 +771,58 @@ module.exports.tests.language_service_validation = (test, common) => {
});
test('non-http/https api.services.language.url should throw error', (t) => {
['ftp', 'git', 'unknown'].forEach((scheme) => {
var config = {
test('non-number retries should throw error', (t) => {
services.forEach(service => {
[null, 'string', {}, [], false].forEach((value) => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
language: {
url: `${scheme}://localhost`
}
}
services: {}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"url" must be a valid uri with a scheme matching the https\? pattern');
});
t.end();
});
test('non-url children of api.services.language should be disallowed', (t) => {
var config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
language: {
config.api.services[service] = {
url: 'http://localhost',
unknown_property: 'value'
}
}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"unknown_property" is not allowed');
t.end();
});
test('non-number timeout should throw error', (t) => {
[null, 'string', {}, [], false].forEach((value) => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
language: {
url: 'http://localhost',
timeout: value
}
}
},
esclient: {}
retries: value
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"timeout" must be a number');
t.equals(result.error.details[0].message, '"retries" must be a number');
});
t.end();
});
test('non-integer timeout should throw error', (t) => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
language: {
url: 'http://localhost',
timeout: 17.3
}
}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"timeout" must be an integer');
t.end();
});
test('negative timeout should throw error', (t) => {
test('non-integer retries should throw error', (t) => {
services.forEach(service => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
language: {
url: 'http://localhost',
timeout: -1
}
}
services: {}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"timeout" must be larger than or equal to 0');
t.end();
});
test('non-number retries should throw error', (t) => {
[null, 'string', {}, [], false].forEach((value) => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
language: {
config.api.services[service] = {
url: 'http://localhost',
retries: value
}
}
},
esclient: {}
retries: 17.3
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"retries" must be a number');
t.equals(result.error.details[0].message, '"retries" must be an integer');
});
@ -1172,50 +830,30 @@ module.exports.tests.language_service_validation = (test, common) => {
});
test('non-integer retries should throw error', (t) => {
test('negative retries should throw error', (t) => {
services.forEach(service => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
language: {
url: 'http://localhost',
retries: 17.3
}
}
services: {}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"retries" must be an integer');
t.end();
});
test('negative retries should throw error', (t) => {
const config = {
api: {
version: 'version value',
indexName: 'index name value',
host: 'host value',
services: {
language: {
config.api.services[service] = {
url: 'http://localhost',
retries: -1
}
}
},
esclient: {}
};
const result = Joi.validate(config, schema);
t.equals(result.error.details.length, 1);
t.equals(result.error.details[0].message, '"retries" must be larger than or equal to 0');
});
t.end();
});

Loading…
Cancel
Save