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

Feature/improve open api generation #196

Merged
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
7 changes: 7 additions & 0 deletions core/apps/ame-e2e/src/fixtures/valid-yml.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
resourceId:
name: resourceId
in: path
description: An example resource Id.
required: true
schema:
type: string
68 changes: 0 additions & 68 deletions core/apps/ame-e2e/src/integration/editor/generation.cy.ts

This file was deleted.

213 changes: 213 additions & 0 deletions core/apps/ame-e2e/src/integration/generation/generate-open-api.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
/* eslint-disable cypress/no-unnecessary-waiting */
/*
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
*
* See the AUTHORS file(s) distributed with this work for
* additional information regarding authorship.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

/// <reference types="Cypress" />

import {
GENERATION_accordionTitle,
GENERATION_activateResourcePathCheckbox,
GENERATION_removeUploadFile,
GENERATION_resourcePathInput,
GENERATION_resourcePathPatternError,
GENERATION_resourcePathRequiredError,
GENERATION_resourcePathTitle,
GENERATION_tbBaseUrlInput,
GENERATION_tbBaseUrlInputError,
GENERATION_tbGenerateOpenApiButton,
GENERATION_tbOutputButton,
GENERATION_tbOutputButton_JSON,
GENERATION_tbOutputButton_YAML,
GENERATION_uploadContent,
GENERATION_uploadContentFileInput,
GENERATION_uploadFileRequireError,
GENERATION_uploadTitle,
} from '../../support/constants';

describe('Test generation and download of open api specification', () => {
it('Can generate valid JSON Open Api Specification', () => {
cy.visitDefault();
cy.startModelling()
.then(() => cy.openGenerationOpenApiSpec().wait(500))
.then(() => cy.get(GENERATION_tbOutputButton).click())
.then(() => cy.get(GENERATION_tbOutputButton_JSON).click())
.then(() => cy.get(GENERATION_tbBaseUrlInput).focus().clear().blur())
.then(() =>
cy.get(GENERATION_tbBaseUrlInputError).should('exist').should('be.visible').should('contain.text', 'Please add a valid url'),
)
.then(() => cy.get(GENERATION_tbBaseUrlInput).focus().type('https://example.com').blur())
.then(() => cy.get(GENERATION_tbGenerateOpenApiButton).click().wait(5000))
.then(() => cy.fixture('cypress/downloads/en-open-api.json'));
});

it('Can generate valid JSON Open Api Specification with resource path', () => {
cy.visitDefault();
cy.startModelling()
.then(() => cy.openGenerationOpenApiSpec().wait(500))
.then(() => cy.get(GENERATION_tbOutputButton).click())
.then(() => cy.get(GENERATION_tbOutputButton_JSON).click())
.then(() => cy.get(GENERATION_resourcePathTitle).should('not.exist'))
.then(() => cy.get(GENERATION_activateResourcePathCheckbox).click())
.then(() =>
cy
.get(GENERATION_resourcePathTitle)
.should('exist')
.should('be.visible')
.should('contain.text', 'Resource Path - The resource path for the Aspect API endpoints'),
)
.then(() => cy.get(GENERATION_resourcePathInput).should('exist').should('be.visible').focus().clear().blur())
.then(() =>
cy
.get(GENERATION_resourcePathRequiredError)
.should('exist')
.should('be.visible')
.should('contain.text', 'Resource path is required'),
)
.then(() => checkResourcePath())
.then(() => cy.get(GENERATION_uploadTitle).should('exist').should('be.visible').should('contain.text', 'Upload JSON File'))
.then(() => cy.get(GENERATION_uploadContent).should('exist').should('be.visible'))
.then(() =>
cy
.get(GENERATION_uploadFileRequireError)
.should('exist')
.should('be.visible')
.should('contain.text', 'JSON file is required - a variable has been defined in the resource path.'),
)
.then(() => cy.get(GENERATION_uploadContentFileInput).attachFile('valid-json.json'))
.then(() => cy.get(GENERATION_uploadContent).should('not.exist'))
.then(() => cy.get(GENERATION_accordionTitle).should('exist').should('be.visible').should('contain.text', 'Properties'))
.then(() => cy.get(GENERATION_tbGenerateOpenApiButton).click().wait(5000))
.then(() => cy.fixture('cypress/downloads/en-open-api.json'));
});

it('Can generate and download valid YAML Open Api Specification', () => {
cy.visitDefault();
cy.startModelling()
.then(() => cy.openGenerationOpenApiSpec().wait(500))
.then(() => cy.get(GENERATION_tbOutputButton).click())
.then(() => cy.get(GENERATION_tbOutputButton_YAML).click())
.then(() => cy.get(GENERATION_tbBaseUrlInput).focus().clear().blur())
.then(() =>
cy.get(GENERATION_tbBaseUrlInputError).should('exist').should('be.visible').should('contain.text', 'Please add a valid url'),
)
.then(() => cy.get(GENERATION_tbBaseUrlInput).focus().type('https://example.com').blur())
.then(() => cy.get(GENERATION_tbGenerateOpenApiButton).click({force: true}).wait(5000))
.then(() => cy.fixture('cypress/downloads/en-open-api.yaml'));
});

it('Can generate valid YAML Open Api Specification with resource path', () => {
cy.visitDefault();
cy.startModelling()
.then(() => cy.openGenerationOpenApiSpec().wait(500))
.then(() => cy.get(GENERATION_resourcePathTitle).should('not.exist'))
.then(() => cy.get(GENERATION_activateResourcePathCheckbox).click())
.then(() =>
cy
.get(GENERATION_resourcePathTitle)
.should('exist')
.should('be.visible')
.should('contain.text', 'Resource Path - The resource path for the Aspect API endpoints'),
)
.then(() => cy.get(GENERATION_resourcePathInput).should('exist').should('be.visible').focus().clear().blur())
.then(() =>
cy
.get(GENERATION_resourcePathRequiredError)
.should('exist')
.should('be.visible')
.should('contain.text', 'Resource path is required'),
)
.then(() => checkResourcePath())
.then(() => cy.get(GENERATION_uploadTitle).should('exist').should('be.visible').should('contain.text', 'Upload YAML File'))
.then(() => cy.get(GENERATION_uploadContent).should('exist').should('be.visible'))
.then(() =>
cy
.get(GENERATION_uploadFileRequireError)
.should('exist')
.should('be.visible')
.should('contain.text', 'YAML file is required - a variable has been defined in the resource path.'),
)
.then(() => cy.get(GENERATION_uploadContentFileInput).attachFile('valid-yml.yml'))
.then(() => cy.get(GENERATION_uploadContent).should('not.exist'))
.then(() => cy.get(GENERATION_accordionTitle).should('exist').should('be.visible').should('contain.text', 'Properties'))
.then(() => cy.get(GENERATION_tbGenerateOpenApiButton).click().wait(5000))
.then(() => cy.fixture('cypress/downloads/en-open-api.yaml'));
});

it('Test some generate variations', () => {
cy.visitDefault();
cy.startModelling()
.then(() => cy.openGenerationOpenApiSpec().wait(500))
.then(() => cy.get(GENERATION_resourcePathTitle).should('not.exist'))
.then(() => {
cy.get(GENERATION_activateResourcePathCheckbox).click();
cy.get(GENERATION_resourcePathTitle)
.should('exist')
.should('be.visible')
.should('contain.text', 'Resource Path - The resource path for the Aspect API endpoints');
cy.get(GENERATION_resourcePathInput).should('exist').should('be.visible').scrollIntoView();
cy.get(GENERATION_uploadTitle).should('exist').should('be.visible').should('contain.text', 'Upload YAML File');
cy.get(GENERATION_uploadContent).should('exist').should('be.visible');
cy.get(GENERATION_uploadFileRequireError)
.should('exist')
.should('be.visible')
.should('contain.text', 'YAML file is required - a variable has been defined in the resource path.');
cy.get(GENERATION_uploadContentFileInput).attachFile('valid-yml.yml');
cy.get(GENERATION_uploadContent).should('not.exist');
cy.get(GENERATION_accordionTitle).should('exist').should('be.visible').should('contain.text', 'Properties');
cy.get(GENERATION_tbGenerateOpenApiButton).should('be.enabled');
})
.then(() => {
cy.get(GENERATION_removeUploadFile).click({force: true});
cy.get(GENERATION_uploadContent).should('exist').should('be.visible');
cy.get(GENERATION_accordionTitle).should('not.exist');
})
.then(() => {
cy.get(GENERATION_uploadContentFileInput).attachFile('valid-yml.yml');
cy.get(GENERATION_tbOutputButton).click();
cy.get(GENERATION_tbOutputButton_JSON).click();
cy.get(GENERATION_uploadContent).should('exist').should('be.visible');
cy.get(GENERATION_accordionTitle).should('not.exist');
})
.then(() => {
cy.get(GENERATION_uploadContentFileInput).attachFile('valid-json.json');
cy.get(GENERATION_uploadContent).should('not.exist');
cy.get(GENERATION_accordionTitle).should('exist').should('be.visible');
cy.get(GENERATION_tbGenerateOpenApiButton).should('be.enabled');
})
.then(() => {
cy.get(GENERATION_activateResourcePathCheckbox).click();
cy.get(GENERATION_uploadContent).should('not.exist');
cy.get(GENERATION_accordionTitle).should('not.exist');
cy.get(GENERATION_tbGenerateOpenApiButton).should('be.enabled');
});
});

function checkResourcePath(): void {
cy.get(GENERATION_resourcePathInput).focus().type('/').blur();
cy.get(GENERATION_resourcePathPatternError).should('not.exist');
cy.get(GENERATION_resourcePathInput).focus().clear().type('//').blur();
cy.get(GENERATION_resourcePathPatternError).should('exist').should('be.visible').should('contain.text', 'Pattern is not matching');
cy.get(GENERATION_resourcePathInput).focus().clear().type('resource').blur();
cy.get(GENERATION_resourcePathPatternError).should('exist').should('be.visible').should('contain.text', 'Pattern is not matching');
cy.get(GENERATION_resourcePathInput).focus().clear().type('/resource').blur();
cy.get(GENERATION_resourcePathPatternError).should('not.exist');
cy.get(GENERATION_resourcePathInput).focus().clear().type('/resource/{{').blur();
cy.get(GENERATION_resourcePathPatternError).should('exist').should('be.visible').should('contain.text', 'Pattern is not matching');
cy.get(GENERATION_resourcePathInput).focus().clear().type('/resource/}}').blur();
cy.get(GENERATION_resourcePathPatternError).should('exist').should('be.visible').should('contain.text', 'Pattern is not matching');
cy.get(GENERATION_resourcePathInput).focus().clear().type('/resource/{}').blur();
cy.get(GENERATION_resourcePathPatternError).should('not.exist');
cy.get(GENERATION_resourcePathInput).focus().clear().type('/resource/{resourceId}', {parseSpecialCharSequences: false}).blur();
cy.get(GENERATION_resourcePathPatternError).should('not.exist');
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* eslint-disable cypress/no-unnecessary-waiting */
/*
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
*
* See the AUTHORS file(s) distributed with this work for
* additional information regarding authorship.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

/// <reference types="Cypress" />

import {GENERATION_tbDownloadDoc} from '../../support/constants';

describe('Test generation and download of Aspect Model documentation', () => {
it('Can generate and download valid Aspect Model documentation', () => {
cy.visitDefault();
cy.startModelling()
.then(() => cy.openGenerationDocumentation().wait(500))
.then(() => cy.get(GENERATION_tbDownloadDoc).click({force: true}).wait(5000))
.then(() => cy.fixture('cypress/downloads/AspectDefault-documentation.html'));
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* eslint-disable cypress/no-unnecessary-waiting */
/*
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
*
* See the AUTHORS file(s) distributed with this work for
* additional information regarding authorship.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

/// <reference types="Cypress" />

import {GENERATION_downloadFileButton} from '../../support/constants';

describe('Test generation and download of Json payload/schema', () => {
it('Can generate and download valid Json payload', () => {
cy.visitDefault();
cy.startModelling()
.then(() => cy.openGenerationJsonSample().wait(500))
.then(() => cy.get(GENERATION_downloadFileButton).click({force: true}).wait(5000))
.then(() => cy.fixture('cypress/downloads/AspectDefault-sample.json'));
});

it('Can generate and download valid Json schema', () => {
cy.visitDefault();
cy.startModelling()
.then(() => cy.openGenerationJsonSchema().wait(500))
.then(() => cy.get(GENERATION_downloadFileButton).click({force: true}).wait(5000))
.then(() => cy.fixture('cypress/downloads/AspectDefault-schema.json'));
});
});
17 changes: 15 additions & 2 deletions core/apps/ame-e2e/src/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {FileHandlingService, GenerateHandlingService} from '@ame/editor';
import {SearchesStateService} from '@ame/utils';
import {NamespacesManagerService} from '@ame/namespace-manager';
import {Aspect} from '@ame/meta-model';
import 'cypress-file-upload';

const {mxEventObject, mxEvent} = mxgraphFactory({});

Expand Down Expand Up @@ -528,13 +529,25 @@ Cypress.Commands.add('saveAspectModelToWorkspace', () => {
Cypress.Commands.add('openGenerationOpenApiSpec', () => {
cy.intercept(
'POST',
'http://localhost:9091/ame/api/generate/open-api-spec?language=en&output=json&baseUrl=https://example.com&includeQueryApi=false&pagingOption=NO_PAGING',
'http://localhost:9091/ame/api/generate/open-api-spec?language=en&output=json&baseUrl=https://example.com&includeQueryApi=false&pagingOption=NO_PAGING&resourcePath=null&ymlProperties=&jsonProperties=',
{fixture: 'valid-open-api.json'},
);

cy.intercept(
'POST',
'http://localhost:9091/ame/api/generate/open-api-spec?language=en&output=yaml&baseUrl=https://example.com&includeQueryApi=false&pagingOption=NO_PAGING',
'http://localhost:9091/ame/api/generate/open-api-spec?language=en&output=yaml&baseUrl=https://example.com&includeQueryApi=false&pagingOption=NO_PAGING&resourcePath=null&ymlProperties=&jsonProperties=',
{fixture: 'valid-open-api.yaml'},
);

cy.intercept(
'POST',
'http://localhost:9091/ame/api/generate/open-api-spec?language=en&output=json&baseUrl=https://example.com&includeQueryApi=false&pagingOption=NO_PAGING&resourcePath=/resource/%7BresourceId%7D&ymlProperties=&jsonProperties=%7B%0A%20%20%22key%22:%20%22value%22%0A%7D',
{fixture: 'valid-open-api.json'},
);

cy.intercept(
'POST',
'http://localhost:9091/ame/api/generate/open-api-spec?language=en&output=yaml&baseUrl=https://example.com&includeQueryApi=false&pagingOption=NO_PAGING&resourcePath=/resource/%7BresourceId%7D&ymlProperties=resourceId:%0A%20%20name:%20resourceId%0A%20%20in:%20path%0A%20%20description:%20An%20example%20resource%20Id.%0A%20%20required:%20true%0A%20%20schema:%0A%20%20%20%20type:%20string%0A&jsonProperties=',
{fixture: 'valid-open-api.yaml'},
);

Expand Down
Loading
Loading