Skip to content

Commit

Permalink
test: added tests for Swagger/OpenAPI import via file and URL
Browse files Browse the repository at this point in the history
  • Loading branch information
ctschacher authored and gaetanmaisse committed Mar 25, 2022
1 parent 882715f commit 2fe6304
Show file tree
Hide file tree
Showing 9 changed files with 308 additions and 299 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { Api, ApiLifecycleState, ApiMember, UpdateApiEntity } from '@model/apis'
import { ApiImport, ImportSwaggerDescriptorEntity } from '@model/api-imports';
import { BasicAuthentication } from '@model/users';
import { ProcessSubscriptionEntity } from '@model/api-subscriptions';
import { coerce } from 'semver';

export function createApi(auth: BasicAuthentication, body: Api, failOnStatusCode = false) {
return cy.request({
Expand Down Expand Up @@ -96,11 +95,10 @@ export function importCreateApi(auth: BasicAuthentication, body: ApiImport) {
}

export function importSwaggerApi(auth: BasicAuthentication, swaggerImport: string, attributes?: Partial<ImportSwaggerDescriptorEntity>) {
const swaggerVersion = coerce(JSON.parse(swaggerImport).swagger).toString();
return cy.request({
method: 'POST',
url: `${Cypress.config().baseUrl}${Cypress.env('managementApi')}/apis/import/swagger`,
qs: { definitionVersion: swaggerVersion },
qs: { definitionVersion: '2.0.0' },
body: {
payload: swaggerImport,
...attributes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
},
"host": "petstore:8080",
"host": "petstore.swagger.io",
"basePath": "/v2",
"tags": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,8 @@

import { PlanSecurityType, PlanStatus, PlanType, PlanValidation } from '@model/plan';
import { ApiImportFakers } from '@fakers/api-imports';
import { ADMIN_USER, API_PUBLISHER_USER, LOW_PERMISSION_USER } from '@fakers/users/users';
import {
deleteApi,
deployApi,
getApiById,
getApiMembers,
getApiMetadata,
importCreateApi,
importSwaggerApi,
} from '@commands/management/api-management-commands';
import { ADMIN_USER, LOW_PERMISSION_USER } from '@fakers/users/users';
import { deleteApi, getApiById, getApiMembers, getApiMetadata, importCreateApi } from '@commands/management/api-management-commands';
import { deletePage, getPage, getPages } from '@commands/management/api-pages-management-commands';
import { getPlan } from '@commands/management/api-plans-management-commands';
import { ApiMetadataFormat, ApiPageType, ApiPrimaryOwnerType } from '@model/apis';
Expand All @@ -34,7 +26,6 @@ import { createGroup, deleteGroup, getGroup } from '@commands/management/environ
import { createUser, deleteUser, getCurrentUser } from '@commands/management/user-management-commands';
import { createRole, deleteRole } from '@commands/management/organization-configuration-management-commands';
import { ApiImport } from '@model/api-imports';
import { requestGateway } from 'support/common/http.commands';

context('API - Imports', () => {
describe('Create API from import', () => {
Expand Down Expand Up @@ -812,244 +803,4 @@ context('API - Imports', () => {
});
});
});

describe('API import via Swagger definition', () => {
let swaggerImport: any;
let apiId: string;

beforeEach(() => {
cy.fixture('json/petstore_swaggerv2.json').then((fileContent) => {
swaggerImport = JSON.stringify(fileContent);
});
});

afterEach(() => {
deleteApi(ADMIN_USER, apiId).noContent();
});

it('should import API without creating a documentation', () => {
importSwaggerApi(API_PUBLISHER_USER, swaggerImport)
.created()
.its('body')
.then((api) => {
apiId = api.id;
expect(api.id).to.be.a('string').and.not.to.be.empty;
expect(api.visibility).to.equal('PRIVATE');
expect(api.state).to.equal('STOPPED');
getPages(API_PUBLISHER_USER, apiId).ok().its('body').should('have.length', 1).should('not.have.a.property', 'SWAGGER');
});
});

it('should import API and create a swagger documentation', () => {
importSwaggerApi(API_PUBLISHER_USER, swaggerImport, { with_documentation: true })
.created()
.its('body')
.then((api) => {
apiId = api.id;
expect(api.id).to.be.a('string').and.not.to.be.empty;
expect(api.visibility).to.equal('PRIVATE');
expect(api.state).to.equal('STOPPED');
getPages(API_PUBLISHER_USER, apiId)
.ok()
.its('body')
.should('have.length', 2)
.its(1)
.should((swaggerEntry) => {
expect(swaggerEntry).to.have.property('id').and.not.to.be.empty;
expect(swaggerEntry).to.have.property('type', 'SWAGGER');
expect(swaggerEntry).to.have.property('content').and.contain(api.name);
});
});
});

it('should fail to import the same Swagger API again', () => {
importSwaggerApi(API_PUBLISHER_USER, swaggerImport)
.created()
.its('body')
.then((api) => {
apiId = api.id;
importSwaggerApi(API_PUBLISHER_USER, swaggerImport)
.badRequest()
.its('body.message')
.should('equal', `The path [${api.context_path}/] is already covered by an other API.`);
});
});

it('should import API and create a path (to add policies) for every declared Swagger path', () => {
importSwaggerApi(API_PUBLISHER_USER, swaggerImport, { with_policy_paths: true })
.created()
.its('body')
.then((api) => {
apiId = api.id;
deployApi(API_PUBLISHER_USER, apiId).its('body.flows').should('have.length', 20);
});
});
});

describe('Test API endpoints on Swagger import', () => {
let mockPolicyApi: ApiImport;
let jsonValidationPolicyApi: ApiImport;
let noExtrasApi: ApiImport;
let xmlValidationPolicyApi: ApiImport;

before(() => {
{
cy.log('----- Import a swagger API without any extra options selected -----');
cy.fixture('json/petstore_swaggerv2.json')
.then((swaggerFile) => cy.createAndStartApiFromSwagger(swaggerFile))
.then((api) => (noExtrasApi = api));
}

{
cy.log('----- Import a swagger API with mock policies -----');
const swaggerImportAttributes = {
with_policy_paths: true,
with_policies: ['mock'],
};
cy.fixture('json/petstore_swaggerv2.json')
.then((swaggerFile) => cy.createAndStartApiFromSwagger(swaggerFile, swaggerImportAttributes))
.then((api) => (mockPolicyApi = api));
}

{
cy.log('----- Import a swagger API with JSON-Validation policies -----');
const swaggerImportAttributes = {
with_policy_paths: true,
with_policies: ['json-validation'],
};
cy.fixture('json/petstore_swaggerv2.json')
.then((swaggerFile) => cy.createAndStartApiFromSwagger(swaggerFile, swaggerImportAttributes))
.then((api) => (jsonValidationPolicyApi = api));
}

{
cy.log('----- Import a swagger API with XML-Validation policies -----');
const swaggerImportAttributes = {
with_policy_paths: true,
with_policies: ['xml-validation'],
};
cy.fixture('json/petstore_swaggerv2.json')
.then((swaggerFile) => cy.createAndStartApiFromSwagger(swaggerFile, swaggerImportAttributes))
.then((api) => (xmlValidationPolicyApi = api));
}
});

describe('Test without any extra options selected', () => {
after(() => cy.teardownApi(noExtrasApi));

it('should successfully connect to API endpoint', () => {
requestGateway({ url: `${Cypress.env('gatewayServer')}${noExtrasApi.context_path}/pet/findByStatus?status=available` })
.its('body')
.should('have.length', 7)
.its('0.name')
.should('equal', 'Cat 1');
});
});

describe('Tests mock path policy', () => {
after(() => cy.teardownApi(mockPolicyApi));

it('should get a mocked response when trying to reach API endpoint', () => {
requestGateway({ url: `${Cypress.env('gatewayServer')}${mockPolicyApi.context_path}/pet/findByStatus?status=available` })
.its('body.category.name')
.should('equal', 'Mocked string');
});
});

describe('Tests JSON-Validation path policy', () => {
after(() => cy.teardownApi(jsonValidationPolicyApi));

it('should fail with BAD REQUEST (400) when sending data using an invalid JSON schema', () => {
requestGateway(
{
url: `${Cypress.env('gatewayServer')}${jsonValidationPolicyApi.context_path}/pet`,
method: 'PUT',
body: {
invalidProperty: 'invalid value',
},
},
{
validWhen: (response) => response.status === 400,
},
).should((response) => {
expect(response.body.message).to.equal('Bad Request');
});
});

it('should successfully connect to API endpoint if JSON schema is valid', () => {
const body = {
id: 2,
category: {
id: 0,
name: 'string',
},
name: 'doggie',
photoUrls: ['string'],
tags: [
{
id: 0,
name: 'string',
},
],
status: 'available',
};
requestGateway(
{
url: `${Cypress.env('gatewayServer')}${jsonValidationPolicyApi.context_path}/pet`,
method: 'PUT',
body,
},
{
validWhen: (response) => response.status === 200,
},
).should((response) => {
expect(response.body.name).to.equal('doggie');
});
});
});

describe('Tests XML-Validation path policy', () => {
after(() => cy.teardownApi(xmlValidationPolicyApi));

it('should fail with BAD REQUEST (400) when sending data using an invalid XML schema', () => {
requestGateway(
{
url: `${Cypress.env('gatewayServer')}${xmlValidationPolicyApi.context_path}/pet`,
method: 'PUT',
headers: {
'Content-Type': 'application/xml',
},
body: {
invalidProperty: 'invalid value',
},
},
{
validWhen: (response) => response.status === 400,
},
).should((response) => {
expect(response.body.message).to.equal('Bad Request');
});
});

// test not working yet, needs investigation to figure out if there's an issue with the gateway
it.skip('should successfully connect to API endpoint if XML schema is valid', () => {
const body = `<?xml version="1.0" encoding="UTF-8"?><Pet><id>2</id><Category><id>0</id><name>string</name></Category><name>Cat 9</name><photoUrls><photoUrl>string</photoUrl></photoUrls><tags><Tag><id>0</id><name>string</name></Tag></tags><status>available</status></Pet>`;
requestGateway(
{
url: `${Cypress.env('gatewayServer')}${xmlValidationPolicyApi.context_path}/pet`,
method: 'PUT',
headers: {
'Content-Type': 'application/xml',
},
body,
},
{
validWhen: (response) => response.status === 200,
},
).should((response) => {
expect(response.body.name).to.equal('Cat 9');
});
});
});
});
});
Loading

0 comments on commit 2fe6304

Please sign in to comment.