Skip to content
This repository was archived by the owner on Nov 28, 2022. It is now read-only.

Start testing server responses against OpenAPI doc via Chai plugin #203

Merged
merged 1 commit into from
Aug 16, 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
10 changes: 7 additions & 3 deletions docs/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,6 @@ paths:
content:
application/json:
schema:
type: object
$ref: '#/components/schemas/Project'
404:
description: The project was not found
Expand Down Expand Up @@ -1336,14 +1335,19 @@ components:
- projectType
properties:
label:
type: string
example: "python hello world"
description:
type: string
example: "python microservice"
language:
type: string
example: "python"
url:
type: string
example: "https://github.com/microclimate-dev2ops/SVTPythonTemplate"
projectType:
type: string
example: "docker"
TemplateRepo:
type: object
Expand Down Expand Up @@ -1560,8 +1564,8 @@ components:
type: string
example: "Codewind extension for knapp support"
commands:
type: array
$ref: '#/components/schemas/ExtensionCommand'
items:
$ref: '#/components/schemas/ExtensionCommand'
detection:
type: string
example: "knap_config.yaml"
Expand Down
1 change: 1 addition & 0 deletions test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"chai": "^4.1.2",
"chai-files": "^1.4.0",
"chai-http": "^4.0.0",
"chai-openapi-response-validator": "^0.2.3",
"child-process-promise": "^2.2.1",
"dateformat": "^3.0.3",
"dockerode": "^2.5.2",
Expand Down
63 changes: 20 additions & 43 deletions test/src/templates.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
******************************************************************************/

const chai = require('chai');
const chaiResValidator = require('chai-openapi-response-validator');

const {
defaultTemplates,
Expand All @@ -21,8 +22,10 @@ const {
resetTemplateReposTo,
getTemplateStyles,
} = require('../modules/template.service');
const { pathToApiSpec } = require('../config');

chai.should();
chai.use(chaiResValidator(pathToApiSpec));
const expectedLanguages = ['java', 'swift', 'nodejs', 'go', 'python'];

describe('Template API tests', function() {
Expand All @@ -31,8 +34,7 @@ describe('Template API tests', function() {
describe('empty', function() {
it('should return a list of all available templates', async function() {
const res = await getTemplates();
res.should.have.status(200);
res.body.should.be.an('array');
res.should.have.status(200).and.satisfyApiSpec;
res.body.should.deep.equal(defaultTemplates);
// check that we have a template for each supported language
res.body.map((template) => template.language).should.include.members(expectedLanguages);
Expand All @@ -42,11 +44,7 @@ describe('Template API tests', function() {
describe(projectStyle, function() {
it(`should return only ${projectStyle} templates`, async function() {
const res = await getTemplates({ projectStyle });
res.should.have.status(200);
res.body.should.be.an('array');
res.body.forEach((template) => {
template.should.be.an('object').with.all.keys('label', 'description', 'url', 'language', 'projectType');
});
res.should.have.status(200).and.satisfyApiSpec;
// check that we have a template for each supported language
res.body.map((template) => template.language).should.include.members(expectedLanguages);
});
Expand All @@ -63,14 +61,14 @@ describe('Template API tests', function() {
describe('false', function() {
it('should return all templates (from enabled and disabled repos)', async function() {
const res = await getTemplates({ showEnabledOnly: false });
res.should.have.status(200);
res.should.have.status(200).and.satisfyApiSpec;
res.body.should.deep.equal(defaultTemplates);
});
});
describe('true', function() {
it('should return only templates from enabled repos', async function() {
const res = await getTemplates({ showEnabledOnly: true });
res.should.have.status(200);
res.should.have.status(200).and.satisfyApiSpec;
res.body.should.deep.equal(defaultTemplates);
});
});
Expand All @@ -90,11 +88,8 @@ describe('Template API tests', function() {
});
it('GET should return a list of available templates repositories', async function() {
const res = await getTemplateRepos();
res.should.have.status(200);
res.should.have.status(200).and.satisfyApiSpec;
res.body.should.be.an('array').with.length(1);
res.body.forEach((repository) => {
repository.should.be.an('object').with.keys('description', 'url');
});
});
it('POST should fail to add template repository with a bad url', async function() {
const res = await addTemplateRepo({
Expand All @@ -112,9 +107,8 @@ describe('Template API tests', function() {
});
it('DELETE should remove a template repository', async function() {
const res = await deleteTemplateRepo(expectedUrl);
res.should.have.status(200);
res.body.should.be.an('array');
res.body.should.have.length(0);
res.should.have.status(200).and.satisfyApiSpec;
res.body.should.be.an('array').with.length(0);
});
it('GET /api/v1/templates should return an empty list of templates', async function() {
const res = await getTemplates();
Expand All @@ -125,56 +119,39 @@ describe('Template API tests', function() {
url: expectedUrl,
description: 'Default codewind templates.',
});
res.should.have.status(200);
res.should.have.status(200).and.satisfyApiSpec;
res.body.should.be.an('array').with.length(1);
res.body.forEach((repository) => {
repository.should.be.an('object').with.all.keys('description', 'url');
});
});
let firstLength;
it('should return a list of available templates', async function() {
const res = await getTemplates();
res.should.have.status(200);
res.should.have.status(200).and.satisfyApiSpec;
res.body.should.be.an('array');
res.body.forEach((repository) => {
repository.should.be.an('object').with.all.keys('label', 'description', 'url', 'language', 'projectType');
});
firstLength = res.body.length;
});
it('POST should add a second template repository', async function() {
const res = await addTemplateRepo({
url: testUrl,
description: 'Copy of default codewind templates.',
});
res.should.have.status(200);
res.should.have.status(200).and.satisfyApiSpec;
res.body.should.be.an('array').with.length(2);
res.body.forEach((repository) => {
repository.should.be.an('object').with.all.keys('description', 'url');
});
});
it('should return longer list of available templates', async function() {
const res = await getTemplates();
res.should.have.status(200);
res.body.should.be.an('array');
res.body.forEach((repository) => {
repository.should.be.an('object').with.all.keys('label', 'description', 'url', 'language', 'projectType');
});
res.should.have.status(200).and.satisfyApiSpec;
// There are 6 templates listed in the revision referenced by testUrl
res.body.should.have.length(firstLength + 7);
res.body.should.be.an('array').with.length(firstLength + 7);
});
it('DELETE should remove second repository', async function() {
const res = await deleteTemplateRepo(testUrl);
res.should.have.status(200);
res.should.have.status(200).and.satisfyApiSpec;
res.body.should.be.an('array').with.length(1);
});
it('should return initial list of available templates', async function() {
const res = await getTemplates();
res.should.have.status(200);
res.body.should.be.an('array');
res.body.forEach((repository) => {
repository.should.be.an('object').with.all.keys('label', 'description', 'url', 'language', 'projectType');
});
res.body.should.have.length(firstLength);
res.should.have.status(200).and.satisfyApiSpec;
res.body.should.be.an('array').with.length(firstLength);
});
});
describe('PATCH /api/v1/batch/templates/repositories', function() {
Expand Down Expand Up @@ -255,7 +232,7 @@ describe('Template API tests', function() {
describe(`to ${testName}`, function() {
it(`should return 207 and the expected operations info`, async function() {
const res = await batchPatchTemplateRepos(test.input);
res.should.have.status(207);
res.should.have.status(207).and.satisfyApiSpec;
res.body.should.deep.equal(test.output);
});
});
Expand All @@ -264,7 +241,7 @@ describe('Template API tests', function() {
describe('GET /api/v1/templates/styles', function() {
it('should return a list of available template styles', async function() {
const res = await getTemplateStyles();
res.should.have.status(200);
res.should.have.status(200).and.satisfyApiSpec;
res.body.should.deep.equal(['Codewind']); // TODO: add 'Appsody' when we ship Appsody templates by default
});
});
Expand Down