Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update specs to OpenAPI 3.0.1 #1120

Merged
merged 1 commit into from
May 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,34 +35,35 @@
"homepage": "https://github.com/wikimedia/restbase",
"readme": "README.md",
"dependencies": {
"bluebird": "^3.5.3",
"bluebird": "^3.5.5",
"cassandra-uuid": "^0.1.0",
"content-type": "git+https://github.com/wikimedia/content-type#master",
"entities": "^1.1.2",
"extend": "^3.0.2",
"fast-json-stable-stringify": "^2.0.0",
"hyperswitch": "^0.11.0",
"hyperswitch": "^0.12.3",
"jsonwebtoken": "^8.5.1",
"mediawiki-title": "^0.6.5",
"restbase-mod-table-cassandra": "^1.1.3",
"restbase-mod-table-cassandra": "^1.1.4",
"semver": "latest",
"service-runner": "^2.6.17",
"extend": "^3.0.2"
"service-runner": "^2.7.0"
},
"devDependencies": {
"ajv": "^6.10.0",
"bunyan": "^1.8.12",
"coveralls": "^3.0.3",
"eslint-config-wikimedia": "^0.11.0",
"eslint-plugin-jsdoc": "^4.7.0",
"eslint-plugin-json": "^1.4.0",
"eslint": "^5.16.0",
"js-yaml": "^3.13.0",
"mocha": "^6.0.2",
"eslint-config-wikimedia": "^0.12.0",
"eslint-plugin-jsdoc": "^7.1.0",
"eslint-plugin-json": "^1.4.0",
"js-yaml": "^3.13.1",
"mocha": "^6.1.4",
"mocha-lcov-reporter": "^1.3.0",
"mocha.parallel": "^0.15.6",
"nock": "^10.0.6",
"nyc": "^13.3.0",
"preq": "^0.5.7",
"nyc": "^14.1.1",
"openapi-schema-validator": "^3.0.3",
"preq": "^0.5.8",
"restbase-mod-table-sqlite": "^1.1.2"
},
"engines": {
Expand Down
2 changes: 1 addition & 1 deletion projects/wmf_wiktionary.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
swagger: '2.0'
openapi: 3.0.1
paths:
/{api:v1}: &default_project_paths_v1
x-modules:
Expand Down
2 changes: 1 addition & 1 deletion sys/action.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ class ActionService {
}

_getBaseUri(req) {
return this.baseUriTemplate.expand({ request: req }).uri;
return this.baseUriTemplate.expand({ request: req }).uri.toString();
}

query(hyper, req) {
Expand Down
2 changes: 1 addition & 1 deletion sys/key_value.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
swagger: '2.0'
openapi: 3.0.1
info:
version: '1.0.0'
title: RESTBase key-value module
Expand Down
6 changes: 4 additions & 2 deletions sys/page_revisions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ paths:
- name: page
in: query
description: The next page token
type: string
schema:
type: string
required: false

/page/{title}: &page_title
Expand All @@ -23,7 +24,8 @@ paths:
- name: page
in: query
description: The next page token
type: string
schema:
type: string
required: false

/page/{title}/{revision}:
Expand Down
2 changes: 1 addition & 1 deletion sys/parsoid.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
swagger: 2.0
openapi: 3.0.1
info:
version: 0.1.0
title: Internal Parsoid content API
Expand Down
2 changes: 1 addition & 1 deletion sys/post_data.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
swagger: '2.0'
openapi: 3.0.1
info:
version: '1.0.0'
title: RESTBase post data storage module
Expand Down
2 changes: 1 addition & 1 deletion test/features/pagecontent/pagecontent.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ describe('item requests', function() {
.then((res) => {
assert.deepEqual(res.status, 200);
assert.contentType(res, 'application/json');
assert.deepEqual(res.body.swagger, '2.0');
assert.deepEqual(res.body.openapi, '3.0.1');
});
});

Expand Down
25 changes: 11 additions & 14 deletions test/features/schema_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const assert = require('../utils/assert.js');
const Server = require('../utils/server.js');
const preq = require('preq');
const Ajv = require('ajv');
const OpenAPISchemaValidator = require('openapi-schema-validator').default;
const validator = new OpenAPISchemaValidator({ version: 3 });

parallel('Responses should conform to the provided JSON schema of the response', () => {
const ajv = new Ajv({});
Expand All @@ -26,28 +28,23 @@ parallel('Responses should conform to the provided JSON schema of the response',
before(() => server.start()
.then(() => preq.get({uri: `${server.config.baseURL()}/?spec`}))
.then((res) => {
Object.keys(res.body.definitions).forEach((defName) => {
ajv.addSchema(res.body.definitions[defName], `#/definitions/${defName}`);
Object.keys(res.body.components.schemas).forEach((defName) => {
ajv.addSchema(res.body.components.schemas[defName], `#/components/schemas/${defName}`);
});
}));
after(() => server.stop());

it('should expose valid OpenAPI spec', () => {
return preq.get({ uri: `${server.config.baseURL()}/?spec` })
.then((res) => {
return preq.post({uri: `http://online.swagger.io/validator/debug`,
body: JSON.stringify(res.body)})
.then((res) => {
// if valid will return an empty object: {}
assert.deepEqual({}, res.body, 'Spec must have no validation errors');
})
assert.deepEqual({errors: []}, validator.validate(res.body), 'Spec must have no validation errors');
clarakosi marked this conversation as resolved.
Show resolved Hide resolved
});
});

it('/feed/featured should conform schema', () => {
return preq.get({ uri: `${server.config.baseURL()}/feed/featured/${getToday()}` })
.then((res) => {
if (!ajv.validate('#/definitions/feed', res.body)) {
if (!ajv.validate('#/components/schemas/feed', res.body)) {
throw new assert.AssertionError({
message: ajv.errorsText()
});
Expand All @@ -58,7 +55,7 @@ parallel('Responses should conform to the provided JSON schema of the response',
it('/feed/featured should conform schema, ruwiki', () => {
return preq.get({ uri: `${server.config.baseURL('ru.wikipedia.org')}/feed/featured/${getToday()}` })
.then((res) => {
if (!ajv.validate('#/definitions/feed', res.body)) {
if (!ajv.validate('#/components/schemas/feed', res.body)) {
throw new assert.AssertionError({
message: ajv.errorsText()
});
Expand All @@ -70,7 +67,7 @@ parallel('Responses should conform to the provided JSON schema of the response',
it('/page/summary/{title} should conform schema', () => {
return preq.get({ uri: `${server.config.baseURL()}/page/summary/Tank` })
.then((res) => {
if (!ajv.validate('#/definitions/summary', res.body)) {
if (!ajv.validate('#/components/schemas/summary', res.body)) {
throw new assert.AssertionError({
message: ajv.errorsText()
});
Expand All @@ -81,7 +78,7 @@ parallel('Responses should conform to the provided JSON schema of the response',
it('/feed/announcements should conform schema', () => {
return preq.get({ uri: `${server.config.baseURL()}/feed/announcements` })
.then((res) => {
if (!ajv.validate('#/definitions/announcementsResponse', res.body)) {
if (!ajv.validate('#/components/schemas/announcementsResponse', res.body)) {
throw new assert.AssertionError({
message: ajv.errorsText()
});
Expand All @@ -92,7 +89,7 @@ parallel('Responses should conform to the provided JSON schema of the response',
it('/feed/onthisday should conform schema', () => {
return preq.get({ uri: `${server.config.baseURL()}/feed/onthisday/all/01/03` })
.then((res) => {
if (!ajv.validate('#/definitions/onthisdayResponse', res.body)) {
if (!ajv.validate('#/components/schemas/onthisdayResponse', res.body)) {
throw new assert.AssertionError({
message: ajv.errorsText()
});
Expand All @@ -104,7 +101,7 @@ parallel('Responses should conform to the provided JSON schema of the response',
it('/page/related should conform schema', () => {
return preq.get({ uri: `${server.config.bucketURL()}/related/Tank` })
.then((res) => {
if (!ajv.validate('#/definitions/related', res.body)) {
if (!ajv.validate('#/components/schemas/related', res.body)) {
throw new assert.AssertionError({
message: ajv.errorsText()
});
Expand Down
2 changes: 1 addition & 1 deletion test/test_module.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Simple test spec

swagger: 2.0
openapi: 3.0.1
paths:
/{api:v1}:
x-modules:
Expand Down
149 changes: 74 additions & 75 deletions v1/announcements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ paths:
Gets announcements for display in the official Wikipedia iOS and Android apps.

Stability: [experimental](https://www.mediawiki.org/wiki/API_versioning#Experimental)
produces:
- application/json; charset=utf-8; profile="https://www.mediawiki.org/wiki/Specs/Announcements/0.2.0"
- application/problem+json
responses:
'200':
200:
description: Announcements for the given Wiki
schema:
$ref: '#/definitions/announcementsResponse'
content:
application/json; charset=utf-8; profile="https://www.mediawiki.org/wiki/Specs/Announcements/0.2.0":
schema:
$ref: '#/components/schemas/announcementsResponse'
x-request-handler:
- get_announcements_from_mcs:
request:
Expand All @@ -37,76 +36,76 @@ paths:
status: 200
headers:
content-type: application/json
components:
schemas:
action:
type: object
properties:
title:
type: string
description: The title to display on the button that performs the action
url:
type: string
description: The URL to navigate to when the button is pressed
required:
- title
- url

definitions:
action:
type: object
properties:
title:
type: string
description: The title to display on the button that performs the action
url:
type: string
description: The URL to navigate to when the button is pressed
required:
- title
- url

announcement:
type: object
properties:
id:
type: string
description: Unique ID of the announcement
type:
type: string
description: The type of announcement. Possible values are "survey" or "fundraising"
start_time:
type: string
description: The date to begin showing the announcement
end_time:
type: string
description: The date to stop showing the announcement
platforms:
type: array
items:
announcement:
type: object
properties:
id:
type: string
description: Unique ID of the announcement
type:
type: string
description: The type of announcement. Possible values are "survey" or "fundraising"
start_time:
type: string
description: The date to begin showing the announcement
end_time:
type: string
description: The date to stop showing the announcement
platforms:
type: array
items:
type: string
description: An array of platforms to display the announcement. Possible
values are "iOSApp" or "AndroidApp"
text:
type: string
description: The text of the announcement
image:
type: string
description: An array of platforms to display the announcement. Possible values are "iOSApp" or "AndroidApp"
text:
type: string
description: The text of the announcement
image:
type: string
description: The URL of the image for the announcement
action:
type: object
description: The action for the button of the announcement
$ref: '#/definitions/action'
caption_HTML:
type: string
description: HTML to display below the announcement. Usually a privacy statment and link to a policy
countries:
type: array
items:
description: The URL of the image for the announcement
action:
$ref: '#/components/schemas/action'
caption_HTML:
type: string
description: |
An array of country codes in which to display the announcement.
Clients should derive the country from 'GeoIP' portion of the Set-Cookie header
required:
- id
- type
- start_time
- end_time
- platforms
- text
- countries
description: HTML to display below the announcement. Usually a privacy statment
and link to a policy
countries:
type: array
items:
type: string
description: |
An array of country codes in which to display the announcement.
Clients should derive the country from 'GeoIP' portion of the Set-Cookie header
required:
- id
- type
- start_time
- end_time
- platforms
- text
- countries

announcementsResponse:
type: object
properties:
announce:
type: array
items:
$ref: '#/definitions/announcement'
required:
- announce
announcementsResponse:
type: object
properties:
announce:
type: array
items:
$ref: '#/components/schemas/announcement'
required:
- announce
Loading