[MediaWiki-commits] [Gerrit] mediawiki...mobileapps[master]: Add response schema validation
jenkins-bot has submitted this change and it was merged. Change subject: Add response schema validation .. Add response schema validation Checks responses systematically against the updated schema definitions. Provides for schema validation checks beyond checking checking the public x-amples. Made a couple updates to featured-image since a failure scenario we want to test is testable now. Bug: T145075 Change-Id: I0d3f20cd40f18661a135b6999dff47b0888e0cea --- M package.json M test/features/app/spec.js M test/utils/assert.js 3 files changed, 113 insertions(+), 3 deletions(-) Approvals: BearND: Looks good to me, approved jenkins-bot: Verified diff --git a/package.json b/package.json index 2cfbb34..6acc25d 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "underscore": "^1.8.3" }, "devDependencies": { +"ajv": "^4.7.7", "csv-parse": "^1.1.7", "extend": "^3.0.0", "grunt": "^1.0.1", diff --git a/test/features/app/spec.js b/test/features/app/spec.js index 570fb40..a530fb7 100644 --- a/test/features/app/spec.js +++ b/test/features/app/spec.js @@ -2,11 +2,18 @@ var preq = require('preq'); -var assert = require('../../utils/assert.js'); -var server = require('../../utils/server.js'); +var assert = require('../../utils/assert'); +var server = require('../../utils/server'); +var dateUtil = require('../../../lib/dateUtil'); var URI= require('swagger-router').URI; var yaml = require('js-yaml'); var fs = require('fs'); +var Ajv= require('ajv'); + +var date = new Date(); +var yesterday = new Date(Date.now() - dateUtil.ONE_DAY); +var dateString = date.getUTCFullYear() + '/' + dateUtil.pad(date.getUTCMonth() + 1) + '/' + dateUtil.pad(date.getUTCDate()); +var yesterdayString = yesterday.getUTCFullYear() + '/' + dateUtil.pad(yesterday.getUTCMonth() + 1) + '/' + dateUtil.pad(yesterday.getUTCDate()); function staticSpecLoad() { @@ -266,7 +273,108 @@ }); }); -describe('routes', function() { +describe('validate responses against schema', function() { +var ajv = new Ajv({}); + +var assertValidSchema = function(uri, schemaPath) { +return preq.get({ uri: uri }) +.then(function(res) { +if (!ajv.validate(schemaPath, res.body)) { +throw new assert.AssertionError({ message: ajv.errorsText() }); +} +}); +}; + +var assertValidSchemaAggregated = function(uri) { +return preq.get({ uri: uri, query: { aggregated: true } }) +.then(function(res) { +if (!!res.body) { +throw new assert.AssertionError({ message: 'Response should be empty!' }); +} +}); +}; + +var assertBadRequest = function(uri) { +return preq.get({ uri: uri }) +.then(function(res) { +assert.fail("This request should fail!"); +}) +.catch(function(err) { +if (!ajv.validate('#/definitions/problem', err.body)) { +throw new assert.AssertionError({ message: ajv.errorsText() }); +} +}); +}; + +Object.keys(spec.definitions).forEach(function(defName) { +ajv.addSchema(spec.definitions[defName], '#/definitions/' + defName); +}); + +//Valid non-aggregated requests + +it('featured article response should conform to schema', function() { +var uri = server.config.uri + 'en.wikipedia.org/v1/page/featured/' + dateString; +return assertValidSchema(uri, '#/definitions/article_title'); +}); + +it('featured image response should conform to schema', function() { +var uri = server.config.uri + 'en.wikipedia.org/v1/media/image/featured/' + dateString; +return assertValidSchema(uri, '#/definitions/image'); +}); + +it('most-read response should conform to schema', function() { +var uri = server.config.uri + 'en.wikipedia.org/v1/page/most-read/' + yesterdayString; +return assertValidSchema(uri, '#/definitions/mostread'); +}); + +it('news response should conform to schema', function() { +var uri = server.config.uri + 'en.wikipedia.org/v1/page/news'; +return assertValidSchema(uri, '#/definitions/news'); +}); + +it('random response should conform to schema', function() { +var uri = server.config.uri + 'en.wikipedia.org/v1/page/random/title'; +return assertValidSchema(uri, '#/definitions/random'); +}); + +//Bad requests return empty response for aggregated=true + +it('featured article response should conform to schema (invalid language, aggregated=true)', function() { +return assertValidSchemaAggregated(server.con
[MediaWiki-commits] [Gerrit] mediawiki...mobileapps[master]: Add response schema validation
Mholloway has uploaded a new change for review. https://gerrit.wikimedia.org/r/315996 Change subject: Add response schema validation .. Add response schema validation Checks responses systematically against the updated schema definitions. Provides for schema validation checks beyond checking checking the public x-amples. Made a couple updates to featured-image since a failure scenario we want to test is testable now. Bug: T145075 Change-Id: I0d3f20cd40f18661a135b6999dff47b0888e0cea --- M lib/feed/featured-image.js M package.json M spec.yaml M test/features/app/spec.js M test/features/featured-image/pagecontent.js M test/utils/assert.js 6 files changed, 234 insertions(+), 10 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/services/mobileapps refs/changes/96/315996/1 diff --git a/lib/feed/featured-image.js b/lib/feed/featured-image.js index f6bc226..0c04409 100644 --- a/lib/feed/featured-image.js +++ b/lib/feed/featured-image.js @@ -107,7 +107,7 @@ if (!dateUtil.validate(dateUtil.hyphenDelimitedDateString(req))) { if (aggregated) { -return BBPromise.resolve({}); +return BBPromise.resolve({ empty: true }); } dateUtil.throwDateError(); } diff --git a/package.json b/package.json index 00ea2eb..8dc74dc 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,8 @@ "underscore": "^1.8.3" }, "devDependencies": { -"csv-parse": "1.1.7", +"ajv": "^4.7.7", +"csv-parse": "^1.1.7", "extend": "^3.0.0", "grunt": "^1.0.1", "grunt-jscs": "^3.0.1", diff --git a/spec.yaml b/spec.yaml index aa9ef92..da9148b 100644 --- a/spec.yaml +++ b/spec.yaml @@ -98,6 +98,12 @@ $ref: '#/definitions/article_title' '204': description: Empty response (for feed content aggregation requests from RESTBase) + schema: +$ref: '#/definitions/empty' +'501': + description: Unsupported language + schema: +$ref: '#/definitions/problem' default: description: Error schema: @@ -513,13 +519,17 @@ required: - type properties: + status: +type: integer type: type: string title: type: string detail: type: string - instance: + method: +type: string + uri: type: string article_title: @@ -632,9 +642,20 @@ description: Full-size image $ref: '#/definitions/thumbnail' description: -descrtiption: Description of an image +description: Description of an image $ref: '#/definitions/image_description' required: - title - thumbnail - image + + empty: +type: object +properties: + type: +type: string +description: description of original content type (buffer) + data: +type: array +description: Buffer contents +additionalProperties: false diff --git a/test/features/app/spec.js b/test/features/app/spec.js index 570fb40..635f588 100644 --- a/test/features/app/spec.js +++ b/test/features/app/spec.js @@ -2,11 +2,17 @@ var preq = require('preq'); -var assert = require('../../utils/assert.js'); -var server = require('../../utils/server.js'); +var assert = require('../../utils/assert'); +var server = require('../../utils/server'); +var dateUtil = require('../../../lib/dateUtil'); var URI= require('swagger-router').URI; var yaml = require('js-yaml'); var fs = require('fs'); +var Ajv = require('ajv'); +var date = new Date(); +var yesterday = new Date(Date.now() - dateUtil.ONE_DAY); +var dateString = date.getUTCFullYear() + '/' + dateUtil.pad(date.getUTCMonth() + 1) + '/' + dateUtil.pad(date.getUTCDate()); +var yesterdayString = yesterday.getUTCFullYear() + '/' + dateUtil.pad(yesterday.getUTCMonth() + 1) + '/' + dateUtil.pad(yesterday.getUTCDate()); function staticSpecLoad() { @@ -266,7 +272,202 @@ }); }); -describe('routes', function() { +describe('validate responses against schema', function() { +var ajv = new Ajv({}); + +Object.keys(spec.definitions).forEach(function(defName) { +ajv.addSchema(spec.definitions[defName], '#/definitions/' + defName); +}); + +it('featured article response should conform to schema', function() { +return preq.get({ uri: server.config.uri + 'en.wikipedia.org/v1/page/featured/' + dateString }) +.then(function(res) { +if (!ajv.validate('#/definitions/article_title', res.body)) { +throw new assert.AssertionError({ +message: ajv.errorsText() +}); +} +}); +}); + +it('featured article request should fail for invalid language when not in aggregated request', func