Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(integrations): create integration
- Loading branch information
1 parent
b22c571
commit 7058b7e
Showing
19 changed files
with
1,180 additions
and
0 deletions.
There are no files selected for viewing
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
gravitee-apim-console-webui/src/entities/integrations/integration.fixture.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* Copyright (C) 2015 The Gravitee team (http://gravitee.io) | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import { Integration } from '../../management/integrations/integrations.model'; | ||
|
||
export function fakeIntegration(attribute?: Partial<Integration>) { | ||
const base: Integration = { | ||
id: 'test_id', | ||
name: 'test_name', | ||
description: 'test_description', | ||
provider: 'test_provider', | ||
owner: 'test_owner', | ||
status: 'test_status', | ||
agent: 'test_agent', | ||
}; | ||
|
||
return { | ||
...base, | ||
...attribute, | ||
}; | ||
} |
105 changes: 105 additions & 0 deletions
105
...le-webui/src/management/integrations/create-integration/create-integration.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
<!-- | ||
Copyright (C) 2015 The Gravitee team (http://gravitee.io) | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
--> | ||
|
||
<div> | ||
<div class="page-header"> | ||
<h1 class="page-header__page-title">Integrations</h1> | ||
<span class="page-header__description" | ||
>Connect to third-party API gateways and event brokers to create a unified control plane and API portal with Gravitee</span | ||
> | ||
</div> | ||
|
||
<mat-card> | ||
<mat-card-content> | ||
<div class="card-header"> | ||
<div class="card-header__title"> | ||
<h3>Create Integration</h3> | ||
</div> | ||
|
||
<div class="card-header__actions"> | ||
<button mat-raised-button [disabled]="false" data-testid="exit-create-integration-button" routerLink=".."> | ||
<mat-icon svgIcon="gio:cancel"></mat-icon> | ||
Exit without saving | ||
</button> | ||
</div> | ||
</div> | ||
|
||
<form [formGroup]="informationForm" class="form" (ngSubmit)="onSubmit()"> | ||
<div class="form__body"> | ||
<mat-card class="form-card"> | ||
<mat-card-content> | ||
<div> | ||
<h5>General Information</h5> | ||
<p class="info">Enter the general information for this new integration.</p> | ||
</div> | ||
<div> | ||
<mat-form-field appearance="outline" class="form-field"> | ||
<input | ||
id="name" | ||
type="text" | ||
matInput | ||
formControlName="name" | ||
required="true" | ||
data-testid="create-integration-name-input" | ||
/> | ||
<mat-label>Name</mat-label> | ||
<mat-error *ngIf="informationForm.get('name').hasError('required')">Integration name is required.</mat-error> | ||
<mat-error *ngIf="informationForm.get('name').hasError('maxlength')" | ||
>Integration name has to be less than 50 characters long.</mat-error | ||
> | ||
<mat-error *ngIf="informationForm.get('name').hasError('minlength')" | ||
>Integration name has to be more than 1 characters long.</mat-error | ||
> | ||
</mat-form-field> | ||
</div> | ||
<div> | ||
<mat-form-field appearance="outline" class="form-field"> | ||
<textarea | ||
id="description" | ||
matInput | ||
#input | ||
formControlName="description" | ||
maxlength="250" | ||
rows="2" | ||
data-testid="create-integration-description" | ||
></textarea> | ||
<mat-label>Description</mat-label> | ||
<mat-hint align="start" class="hint">{{ input.value.length }}/250</mat-hint> | ||
</mat-form-field> | ||
</div> | ||
</mat-card-content> | ||
</mat-card> | ||
</div> | ||
|
||
<div class="form__actions"> | ||
<button mat-flat-button [disabled]="true" data-testid="create-integration-back-button" routerLink="..">Back</button> | ||
|
||
<button | ||
type="submit" | ||
mat-raised-button | ||
color="primary" | ||
data-testid="create-integration-submit-button" | ||
[disabled]="!informationForm.valid" | ||
> | ||
Create Integration | ||
</button> | ||
</div> | ||
</form> | ||
</mat-card-content> | ||
</mat-card> | ||
</div> |
89 changes: 89 additions & 0 deletions
89
...le-webui/src/management/integrations/create-integration/create-integration.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* Copyright (C) 2015 The Gravitee team (http://gravitee.io) | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
@use 'sass:map'; | ||
@use '@angular/material' as mat; | ||
@use '@gravitee/ui-particles-angular' as gio; | ||
@use '../../../scss/gio-layout' as gio-layout; | ||
|
||
$typography: map.get(gio.$mat-theme, typography); | ||
|
||
:host { | ||
@include gio-layout.gio-responsive-content-container; | ||
} | ||
|
||
.page-header { | ||
margin-bottom: 24px; | ||
|
||
&__page-title { | ||
@include mat.typography-level($typography, headline-6); | ||
} | ||
|
||
&__description { | ||
color: mat.get-color-from-palette(gio.$mat-space-palette, 'lighter40'); | ||
@include mat.typography-level($typography, body-2); | ||
} | ||
} | ||
|
||
.card-header { | ||
display: flex; | ||
justify-content: space-between; | ||
padding-bottom: 24px; | ||
|
||
&__title { | ||
@include mat.typography-level($typography, subtitle-1); | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: center; | ||
|
||
h3 { | ||
margin: 0; | ||
} | ||
} | ||
} | ||
|
||
.form { | ||
&__body { | ||
display: flex; | ||
justify-content: center; | ||
padding: 24px 0; | ||
|
||
.mat-mdc-card { | ||
width: 600px; | ||
border: 1px solid mat.get-color-from-palette(gio.$mat-dove-palette, 'darker10'); | ||
box-shadow: 0 2px 4px 0 mat.get-color-from-palette(gio.$mat-dove-palette, 'darker20'); | ||
} | ||
} | ||
|
||
&__actions { | ||
display: flex; | ||
justify-content: space-between; | ||
padding-top: 24px; | ||
} | ||
|
||
.form-field { | ||
width: 100%; | ||
} | ||
} | ||
|
||
textarea { | ||
resize: none; | ||
} | ||
|
||
.info, | ||
.hint { | ||
color: mat.get-color-from-palette(gio.$mat-space-palette, 'lighter40'); | ||
} |
125 changes: 125 additions & 0 deletions
125
...webui/src/management/integrations/create-integration/create-integration.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
/* | ||
* Copyright (C) 2015 The Gravitee team (http://gravitee.io) | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations'; | ||
import { HttpTestingController } from '@angular/common/http/testing'; | ||
import { InteractivityChecker } from '@angular/cdk/a11y'; | ||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; | ||
|
||
import { CreateIntegrationComponent } from './create-integration.component'; | ||
import { CreateIntegrationHarness } from './create-integration.harness'; | ||
|
||
import { IntegrationsModule } from '../integrations.module'; | ||
import { CONSTANTS_TESTING, GioTestingModule } from '../../../shared/testing'; | ||
import { SnackBarService } from '../../../services-ngx/snack-bar.service'; | ||
import { CreateIntegrationPayload } from '../integrations.model'; | ||
|
||
describe('CreateIntegrationComponent', () => { | ||
let fixture: ComponentFixture<CreateIntegrationComponent>; | ||
let componentHarness: CreateIntegrationHarness; | ||
let httpTestingController: HttpTestingController; | ||
|
||
const fakeSnackBarService = { | ||
error: jest.fn(), | ||
}; | ||
|
||
beforeEach(async () => { | ||
await TestBed.configureTestingModule({ | ||
declarations: [CreateIntegrationComponent], | ||
imports: [GioTestingModule, IntegrationsModule, BrowserAnimationsModule, NoopAnimationsModule], | ||
providers: [ | ||
{ | ||
provide: SnackBarService, | ||
useValue: fakeSnackBarService, | ||
}, | ||
], | ||
}) | ||
.overrideProvider(InteractivityChecker, { | ||
useValue: { | ||
isFocusable: () => true, // This traps focus checks and so avoid warnings when dealing with | ||
isTabbable: () => true, // This traps focus checks and so avoid warnings when dealing with | ||
}, | ||
}) | ||
.compileComponents(); | ||
}); | ||
|
||
beforeEach(async () => { | ||
fixture = TestBed.createComponent(CreateIntegrationComponent); | ||
httpTestingController = TestBed.inject(HttpTestingController); | ||
componentHarness = await TestbedHarnessEnvironment.harnessForFixture(fixture, CreateIntegrationHarness); | ||
fixture.detectChanges(); | ||
}); | ||
|
||
afterEach(() => { | ||
httpTestingController.verify(); | ||
}); | ||
|
||
describe('form', () => { | ||
it('should not submit empty form', async () => { | ||
await componentHarness.clickOnSubmit(); | ||
httpTestingController.expectNone(`${CONSTANTS_TESTING.env.v2BaseURL}/integrations`); | ||
}); | ||
|
||
it('should create integration with valid form', async () => { | ||
const expectedPayload: CreateIntegrationPayload = { | ||
name: 'TEST123', | ||
description: '', | ||
provider: 'AWS', | ||
}; | ||
await componentHarness.setName('TEST123'); | ||
await componentHarness.clickOnSubmit(); | ||
expectIntegrationPostRequest(expectedPayload); | ||
}); | ||
|
||
it('should create integration with description', async () => { | ||
const expectedPayload: CreateIntegrationPayload = { | ||
name: 'TEST123', | ||
description: 'Test Description', | ||
provider: 'AWS', | ||
}; | ||
await componentHarness.setName('TEST123'); | ||
await componentHarness.setDescription('Test Description'); | ||
await componentHarness.clickOnSubmit(); | ||
|
||
expectIntegrationPostRequest(expectedPayload); | ||
}); | ||
|
||
it('should handle error with message', async () => { | ||
await componentHarness.setName('TEST123'); | ||
await componentHarness.clickOnSubmit(); | ||
|
||
expectIntegrationWithError(); | ||
|
||
fixture.detectChanges(); | ||
|
||
expect(fakeSnackBarService.error).toHaveBeenCalledWith('An error occurred. Integration not created'); | ||
}); | ||
}); | ||
|
||
function expectIntegrationPostRequest(payload: CreateIntegrationPayload): void { | ||
const req = httpTestingController.expectOne(`${CONSTANTS_TESTING.env.v2BaseURL}/integrations`); | ||
req.flush([]); | ||
expect(req.request.method).toEqual('POST'); | ||
expect(req.request.body).toEqual(payload); | ||
} | ||
|
||
function expectIntegrationWithError(): void { | ||
const req = httpTestingController.expectOne(`${CONSTANTS_TESTING.env.v2BaseURL}/integrations`); | ||
expect(req.request.method).toEqual('POST'); | ||
req.flush({}, { status: 400, statusText: 'Bad Request' }); | ||
} | ||
}); |
Oops, something went wrong.