Skip to content

Commit 69a03c5

Browse files
Include CRUD, POST, PUT, PATCH options when generating OPEN API (#217)
* Update shortcuts.js --------- Co-authored-by: Michele Santoro <[email protected]>
1 parent 48c0539 commit 69a03c5

File tree

13 files changed

+113
-32
lines changed

13 files changed

+113
-32
lines changed

core/apps/ame-e2e/src/integration/generation/generate-open-api.cy.ts

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,6 @@ import {
3535
} from '../../support/constants';
3636

3737
describe('Test generation and download of open api specification', () => {
38-
it('Can generate valid JSON Open Api Specification', () => {
39-
cy.visitDefault();
40-
cy.startModelling()
41-
.then(() => cy.openGenerationOpenApiSpec().wait(500))
42-
.then(() => cy.get(GENERATION_tbOutputButton).click())
43-
.then(() => cy.get(GENERATION_tbOutputButton_JSON).click())
44-
.then(() => cy.get(GENERATION_tbBaseUrlInput).focus().clear().blur())
45-
.then(() =>
46-
cy.get(GENERATION_tbBaseUrlInputError).should('exist').should('be.visible').should('contain.text', 'Please add a valid url'),
47-
)
48-
.then(() => cy.get(GENERATION_tbBaseUrlInput).focus().type('https://example.com').blur())
49-
.then(() => cy.get(GENERATION_tbGenerateOpenApiButton).click().wait(5000))
50-
.then(() => cy.fixture('cypress/downloads/en-open-api.json'));
51-
});
52-
5338
it('Can generate valid JSON Open Api Specification with resource path', () => {
5439
cy.visitDefault();
5540
cy.startModelling()
@@ -90,19 +75,21 @@ describe('Test generation and download of open api specification', () => {
9075
.then(() => cy.fixture('cypress/downloads/en-open-api.json'));
9176
});
9277

93-
it('Can generate and download valid YAML Open Api Specification', () => {
78+
it('Can generate valid JSON Open Api Specification', () => {
9479
cy.visitDefault();
9580
cy.startModelling()
9681
.then(() => cy.openGenerationOpenApiSpec().wait(500))
9782
.then(() => cy.get(GENERATION_tbOutputButton).click())
98-
.then(() => cy.get(GENERATION_tbOutputButton_YAML).click())
83+
.then(() => cy.get(GENERATION_tbOutputButton_JSON).click())
9984
.then(() => cy.get(GENERATION_tbBaseUrlInput).focus().clear().blur())
10085
.then(() =>
10186
cy.get(GENERATION_tbBaseUrlInputError).should('exist').should('be.visible').should('contain.text', 'Please add a valid url'),
10287
)
10388
.then(() => cy.get(GENERATION_tbBaseUrlInput).focus().type('https://example.com').blur())
89+
.wait(7000)
90+
.then(() => cy.get(GENERATION_tbBaseUrlInputError).should('not.exist'))
10491
.then(() => cy.get(GENERATION_tbGenerateOpenApiButton).click({force: true}).wait(5000))
105-
.then(() => cy.fixture('cypress/downloads/en-open-api.yaml'));
92+
.then(() => cy.fixture('cypress/downloads/en-open-api.json'));
10693
});
10794

10895
it('Can generate valid YAML Open Api Specification with resource path', () => {
@@ -139,7 +126,24 @@ describe('Test generation and download of open api specification', () => {
139126
.then(() => cy.get(GENERATION_uploadContentFileInput).attachFile('valid-yml.yml'))
140127
.then(() => cy.get(GENERATION_uploadContent).should('not.exist'))
141128
.then(() => cy.get(GENERATION_accordionTitle).should('exist').should('be.visible').should('contain.text', 'Properties'))
142-
.then(() => cy.get(GENERATION_tbGenerateOpenApiButton).click().wait(5000))
129+
.then(() => cy.get(GENERATION_tbGenerateOpenApiButton).click().wait(7000))
130+
.then(() => cy.fixture('cypress/downloads/en-open-api.yaml'));
131+
});
132+
133+
it('Can generate and download valid YAML Open Api Specification', () => {
134+
cy.visitDefault();
135+
cy.startModelling()
136+
.then(() => cy.openGenerationOpenApiSpec().wait(500))
137+
.then(() => cy.get(GENERATION_tbOutputButton).click())
138+
.then(() => cy.get(GENERATION_tbOutputButton_YAML).click())
139+
.then(() => cy.get(GENERATION_tbBaseUrlInput).focus().clear().blur())
140+
.then(() =>
141+
cy.get(GENERATION_tbBaseUrlInputError).should('exist').should('be.visible').should('contain.text', 'Please add a valid url'),
142+
)
143+
.then(() => cy.get(GENERATION_tbBaseUrlInput).focus().clear().type('https://example.com').blur())
144+
.wait(7000)
145+
.then(() => cy.get(GENERATION_tbBaseUrlInputError).should('not.exist'))
146+
.then(() => cy.get(GENERATION_tbGenerateOpenApiButton).click().wait(7000))
143147
.then(() => cy.fixture('cypress/downloads/en-open-api.yaml'));
144148
});
145149

@@ -192,6 +196,14 @@ describe('Test generation and download of open api specification', () => {
192196
});
193197
});
194198

199+
it('should show the checkboxs when the expansion panel Include API extensions is opened', () => {
200+
cy.get('[data-cy=includeAPIextensions]').click();
201+
202+
cy.get('[data-cy=includePost]').should('be.visible');
203+
cy.get('[data-cy=includePut]').should('be.visible');
204+
cy.get('[data-cy=includePatch]').should('be.visible');
205+
});
206+
195207
function checkResourcePath(): void {
196208
cy.get(GENERATION_resourcePathInput).focus().type('/').blur();
197209
cy.get(GENERATION_resourcePathPatternError).should('not.exist');

core/apps/ame-e2e/src/integration/generation/generation-async-api.cy.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ describe('Test generation and download of async api specification', () => {
2828
cy.visitDefault();
2929
cy.startModelling()
3030
.then(() => cy.openGenerationAsyncApiSpec().wait(500))
31+
.wait(500)
3132
.then(() => cy.get(GENERATION_tbOutputButton).click())
3233
.then(() => cy.get(GENERATION_tbOutputButton_JSON).click())
3334
.then(() => cy.get(GENERATION_tbApplicationIdInput).focus().clear().type('application:id').blur())
@@ -51,6 +52,7 @@ describe('Test generation and download of async api specification', () => {
5152
cy.visitDefault();
5253
cy.startModelling()
5354
.then(() => cy.openGenerationAsyncApiSpec().wait(500))
55+
.wait(500)
5456
.then(() => cy.get(GENERATION_tbOutputButton).click())
5557
.then(() => cy.get(GENERATION_tbOutputButton_JSON).click())
5658
.then(() => cy.get(GENERATION_tbApplicationIdInput).focus().clear().type('application:id').blur())

core/apps/ame-e2e/src/support/commands.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -535,25 +535,25 @@ Cypress.Commands.add('saveAspectModelToWorkspace', () => {
535535
Cypress.Commands.add('openGenerationOpenApiSpec', () => {
536536
cy.intercept(
537537
'POST',
538-
'http://localhost:9091/ame/api/generate/open-api-spec?language=en&output=json&baseUrl=https://example.com&includeQueryApi=false&useSemanticVersion=false&pagingOption=NO_PAGING&resourcePath=&ymlProperties=&jsonProperties=',
538+
'http://localhost:9091/ame/api/generate/open-api-spec?language=en&output=json&baseUrl=https://example.com&includeQueryApi=false&useSemanticVersion=false&pagingOption=NO_PAGING&includePost=false&includePut=false&includePatch=false&resourcePath=null&ymlProperties=&jsonProperties=',
539539
{fixture: 'valid-open-api.json'},
540540
);
541541

542542
cy.intercept(
543543
'POST',
544-
'http://localhost:9091/ame/api/generate/open-api-spec?language=en&output=yaml&baseUrl=https://example.com&includeQueryApi=false&useSemanticVersion=false&pagingOption=NO_PAGING&resourcePath=&ymlProperties=&jsonProperties=',
544+
'http://localhost:9091/ame/api/generate/open-api-spec?language=en&output=yaml&baseUrl=https://example.com&includeQueryApi=false&useSemanticVersion=false&pagingOption=NO_PAGING&includePost=false&includePut=false&includePatch=false&resourcePath=null&ymlProperties=&jsonProperties=',
545545
{fixture: 'valid-open-api.yaml'},
546546
);
547547

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

554554
cy.intercept(
555555
'POST',
556-
'http://localhost:9091/ame/api/generate/open-api-spec?language=en&output=yaml&baseUrl=https://example.com&includeQueryApi=false&useSemanticVersion=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=',
556+
'http://localhost:9091/ame/api/generate/open-api-spec?language=en&output=yaml&baseUrl=https://example.com&includeQueryApi=false&useSemanticVersion=false&pagingOption=NO_PAGING&includePost=false&includePut=false&includePatch=false&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=',
557557
{fixture: 'valid-open-api.yaml'},
558558
);
559559

core/apps/ame-e2e/src/support/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,8 @@ before(function before() {
3838
// Do not truncate assertion outputs of arrays and objects
3939
(<any>window).chai.config.truncateThreshold = 0;
4040
});
41+
42+
Cypress.on('uncaught:exception', (err, runnable) => {
43+
// returning false here prevents Cypress from failing the test
44+
return false;
45+
});

core/apps/ame/src/assets/i18n/en.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,12 @@
277277
"CURSOR_BASED_PAGING": "Cursor based paging",
278278
"OFFSET_BASED_PAGING": "Offset based paging",
279279
"TIME_BASED_PAGING": "Time based paging",
280+
"ADD_OPEN_API_PUT": "Include PUT",
281+
"ADD_OPEN_API_PUT_TOOLTIP": "Include PUT in the OpenApi specification.",
282+
"ADD_OPEN_API_PATCH": "Include PATCH",
283+
"ADD_OPEN_API_PATCH_TOOLTIP": "Include PATCH in the OpenApi specification.",
284+
"ADD_OPEN_API_POST": "Include POST",
285+
"ADD_OPEN_API_POST_TOOLTIP": "Include POST in the OpenApi specification.",
280286
"BUTTON": {
281287
"CANCEL": "Cancel",
282288
"GENERATE": "Generate"

core/electron-libs/shortcuts.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ const {app, globalShortcut, BrowserWindow, Menu, nativeTheme} = require('electro
1515
const platformData = require('./os-checker');
1616

1717
function registerGlobalShortcuts() {
18-
const shortcutsGlobal = [
18+
const globalShortcuts = [
1919
{key: 'CommandOrControl+W', action: () => BrowserWindow.getFocusedWindow()?.close()},
2020
{key: 'CommandOrControl+M', action: () => BrowserWindow.getFocusedWindow()?.minimize()},
2121
{key: 'CommandOrControl+Shift+M', action: () => BrowserWindow.getFocusedWindow()?.maximize()},
2222
{key: 'CommandOrControl+Shift+F', action: () => BrowserWindow.getFocusedWindow()?.setFullScreen(true)},
2323
{key: 'CommandOrControl+Shift+G', action: () => BrowserWindow.getFocusedWindow()?.setFullScreen(false)},
2424
];
2525

26-
const shortcutsMac = [
26+
const macShortcuts = [
2727
{key: 'CommandOrControl+Q', action: () => (BrowserWindow.getFocusedWindow() ? app.quit() : null)},
2828
{key: 'Command+Option+I', action: () => BrowserWindow.getFocusedWindow().webContents.openDevTools()},
2929
{key: 'CommandOrControl+R', action: () => BrowserWindow.getFocusedWindow()?.reload()},
@@ -33,20 +33,26 @@ function registerGlobalShortcuts() {
3333
},
3434
];
3535

36-
const shortcutsWin = [{key: 'Control+Shift+I', action: () => BrowserWindow.getFocusedWindow().webContents.openDevTools()}];
36+
const openDevShortcut = [{key: 'Control+Shift+I', action: () => BrowserWindow.getFocusedWindow().webContents.openDevTools()}];
3737

38-
shortcutsGlobal.forEach(({key, action}) => {
38+
globalShortcuts.forEach(({key, action}) => {
3939
globalShortcut.register(key, action);
4040
});
4141

4242
if (platformData.isMac) {
43-
shortcutsMac.forEach(({key, action}) => {
43+
macShortcuts.forEach(({key, action}) => {
4444
globalShortcut.register(key, action);
4545
});
4646
}
4747

4848
if (platformData.isWin) {
49-
shortcutsWin.forEach(({key, action}) => {
49+
openDevShortcut.forEach(({key, action}) => {
50+
globalShortcut.register(key, action);
51+
});
52+
}
53+
54+
if (platformData.isLinux) {
55+
openDevShortcut.forEach(({key, action}) => {
5056
globalShortcut.register(key, action);
5157
});
5258
}

core/libs/api/src/lib/model-api.service.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,9 @@ export class ModelApiService {
280280
includeQueryApi: openApi.includeQueryApi,
281281
useSemanticVersion: openApi.useSemanticVersion,
282282
pagingOption: openApi.paging,
283+
includePost: openApi.includePost || false,
284+
includePut: openApi.includePut || false,
285+
includePatch: openApi.includePatch || false,
283286
resourcePath: openApi.resourcePath,
284287
ymlProperties: openApi.ymlProperties || '',
285288
jsonProperties: openApi.jsonProperties || '',

core/libs/editor/src/lib/editor-toolbar/components/generate-open-api/generate-open-api.component.html

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ <h2 data-cy="uploadFileTitle">
136136
</mat-error></ng-container
137137
>
138138

139-
<ng-container *ngIf="uploadedFile">
139+
<div class="margin-bottom-10" *ngIf="uploadedFile">
140140
<mat-accordion>
141141
<mat-expansion-panel>
142142
<mat-expansion-panel-header>
@@ -149,8 +149,41 @@ <h2 data-cy="uploadFileTitle">
149149
}}</textarea>
150150
</mat-expansion-panel>
151151
</mat-accordion>
152-
</ng-container>
152+
</div>
153153
</section>
154+
155+
<mat-expansion-panel data-cy="includeAPIextensions">
156+
<mat-expansion-panel-header>
157+
<mat-panel-description> Include API extensions for additional CRUD operations </mat-panel-description>
158+
</mat-expansion-panel-header>
159+
160+
<mat-checkbox
161+
data-cy="includePost"
162+
[formControl]="getControl('includePost')"
163+
class="dialog__checkbox"
164+
[matTooltip]="'GENERATE_OPENAPI_SPEC_DIALOG.ADD_OPEN_API_POST_TOOLTIP' | translate"
165+
>
166+
{{ 'GENERATE_OPENAPI_SPEC_DIALOG.ADD_OPEN_API_POST' | translate }}
167+
</mat-checkbox>
168+
169+
<mat-checkbox
170+
data-cy="includePut"
171+
[formControl]="getControl('includePut')"
172+
class="dialog__checkbox"
173+
[matTooltip]="'GENERATE_OPENAPI_SPEC_DIALOG.ADD_OPEN_API_PUT_TOOLTIP' | translate"
174+
>
175+
{{ 'GENERATE_OPENAPI_SPEC_DIALOG.ADD_OPEN_API_PUT' | translate }}
176+
</mat-checkbox>
177+
178+
<mat-checkbox
179+
data-cy="includePatch"
180+
[formControl]="getControl('includePatch')"
181+
class="dialog__checkbox"
182+
[matTooltip]="'GENERATE_OPENAPI_SPEC_DIALOG.ADD_OPEN_API_PATCH_TOOLTIP' | translate"
183+
>
184+
{{ 'GENERATE_OPENAPI_SPEC_DIALOG.ADD_OPEN_API_PATCH' | translate }}
185+
</mat-checkbox>
186+
</mat-expansion-panel>
154187
</ng-container>
155188

156189
<ng-template #loader>

core/libs/editor/src/lib/editor-toolbar/components/generate-open-api/generate-open-api.component.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,7 @@
9393
}
9494
}
9595
}
96+
97+
.margin-bottom-10 {
98+
margin-bottom: 10px;
99+
}

core/libs/editor/src/lib/editor-toolbar/components/generate-open-api/generate-open-api.component.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ export interface OpenApi {
3535
resourcePath: string;
3636
ymlProperties: string;
3737
jsonProperties: string;
38+
includePost: boolean;
39+
includePut: boolean;
40+
includePatch: boolean;
3841
}
3942

4043
@Component({
@@ -115,6 +118,9 @@ export class GenerateOpenApiComponent implements OnInit, OnDestroy {
115118
file: new FormControl(null),
116119
ymlProperties: new FormControl(null),
117120
jsonProperties: new FormControl(null),
121+
includePost: new FormControl(false),
122+
includePut: new FormControl(false),
123+
includePatch: new FormControl(false),
118124
});
119125
}
120126

0 commit comments

Comments
 (0)