Skip to content

Commit

Permalink
feat: handle the case when policy or SPG is not found
Browse files Browse the repository at this point in the history
  • Loading branch information
ThibaudAV committed Aug 13, 2024
1 parent 7d918c2 commit 429e7ae
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,19 @@

<span *ngIf="step.name" class="info__head__name">{{ step.name }}</span>

<span *ngIf="genericPolicy?.type === 'SHARED_POLICY_GROUP'" class="gio-badge-neutral" matTooltip="Shared Policy Group"
><mat-icon svgIcon="gio:users"></mat-icon
></span>
<span *ngIf="genericPolicy?.type === 'SHARED_POLICY_GROUP'" class="gio-badge-neutral" matTooltip="Shared Policy Group">
<mat-icon svgIcon="gio:users"></mat-icon>
</span>
<span
*ngIf="policyNotFound !== false"
class="gio-badge-error"
[matTooltip]="policyNotFound === 'SHARED_POLICY_GROUP' ? 'Shared Policy Group not found' : 'Policy not found'"
>
@if (policyNotFound === 'SHARED_POLICY_GROUP') {
<mat-icon svgIcon="gio:users"></mat-icon>&nbsp;
}
<mat-icon svgIcon="gio:alert-circle"></mat-icon>
</span>
</div>

<div *ngIf="step.description" class="info__description">{{ step.description }}</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
*/
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { GIO_DIALOG_WIDTH, GioIconsModule } from '@gravitee/ui-particles-angular';
import { GIO_DIALOG_WIDTH, GioConfirmDialogComponent, GioConfirmDialogData, GioIconsModule } from '@gravitee/ui-particles-angular';
import { MatButtonModule } from '@angular/material/button';
import { MatMenuModule } from '@angular/material/menu';
import { CommonModule } from '@angular/common';
import { get, isEmpty, isNil } from 'lodash';
import { get, isEmpty, isNil, has } from 'lodash';
import { MatTooltipModule } from '@angular/material/tooltip';

import {
Expand Down Expand Up @@ -58,7 +58,8 @@ export class GioPolicyStudioDetailsPhaseStepComponent implements OnChanges {
@Output()
public disabled = new EventEmitter<void>();

public genericPolicy?: GenericPolicy;
protected genericPolicy?: GenericPolicy;
protected policyNotFound: false | 'SHARED_POLICY_GROUP' | 'POLICY' = false;
protected policyIcon?: string;

constructor(private readonly matDialog: MatDialog) {}
Expand All @@ -76,12 +77,32 @@ export class GioPolicyStudioDetailsPhaseStepComponent implements OnChanges {
// Not expected
throw new Error('Unknown policy type');
});

// if this.genericPolicy is not found, it means that the policy has been deleted or the shared policy group no longer exists (or deployed)
if (!this.genericPolicy) {
this.policyNotFound = has(this.step.configuration, 'sharedPolicyGroupId') ? 'SHARED_POLICY_GROUP' : 'POLICY';
}
}
}

public onEditOrView() {
if (!this.genericPolicy) {
// TODO: Handle UseCase when policy is not found. (Like if the plugin is removed from the BackEnd)
if (!this.genericPolicy || this.policyNotFound != false) {
this.matDialog
.open<GioConfirmDialogComponent, GioConfirmDialogData, boolean>(GioConfirmDialogComponent, {
data: {
title: `${this.policyNotFound === 'SHARED_POLICY_GROUP' ? 'Shared Policy Group' : 'Policy'} not found`,
content: `This step is linked to a ${this.policyNotFound === 'SHARED_POLICY_GROUP' ? 'Shared Policy Group' : 'Policy'} that no longer exists.<br>
${this.policyNotFound === 'SHARED_POLICY_GROUP' ? 'Note: The Gateway will ignore this step.' : 'Note: The Gateway will throw an error on deployment.'}
`,
confirmButton: 'OK',
disableCancel: true,
},
role: 'alertdialog',
id: 'gioPolicyNotFoundDialog',
width: GIO_DIALOG_WIDTH.MEDIUM,
})
.afterClosed()
.subscribe();
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core';
import { ReactiveFormsModule, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { map, takeUntil } from 'rxjs/operators';
import { catchError, map, takeUntil } from 'rxjs/operators';
import { Observable, of, Subject } from 'rxjs';
import {
GioFormJsonSchemaComponent,
Expand Down Expand Up @@ -89,9 +89,10 @@ export class GioPolicyStudioStepFormComponent implements OnChanges, OnInit, OnDe
}),
);

this.policyDocumentation$ = this.policyStudioService
.getPolicyDocumentation(toPolicy(this.genericPolicy))
.pipe(map(doc => (isEmpty(doc) ? 'No documentation available.' : doc)));
this.policyDocumentation$ = this.policyStudioService.getPolicyDocumentation(toPolicy(this.genericPolicy)).pipe(
map(doc => (isEmpty(doc) ? 'No documentation available.' : doc)),
catchError(() => of('No documentation available.')),
);
}
if (isSharedPolicyGroupPolicy(this.genericPolicy)) {
this.policySchema$ = of({});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,15 @@ export const ProxyWithSharedPolicyGroup: StoryObj = {
name: 'Second plan',
flows: [
fakeHttpFlow({
request: [fakeSharedPolicyGroupPolicyStep()],
request: [
fakeSharedPolicyGroupPolicyStep(),
fakeSharedPolicyGroupPolicyStep({
name: 'SPG Not found',
configuration: {
sharedPolicyGroupId: 'undefined',
},
}),
],
}),
],
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { MatButtonHarness } from '@angular/material/button/testing';
import { of } from 'rxjs';
import { MatInputHarness } from '@angular/material/input/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { GioFormJsonSchemaModule } from '@gravitee/ui-particles-angular';
import { GioConfirmDialogHarness, GioFormJsonSchemaModule } from '@gravitee/ui-particles-angular';

import {
fakeAllPolicies,
Expand Down Expand Up @@ -59,6 +59,7 @@ import { GioPolicyStudioComponent } from './gio-policy-studio.component';

describe('GioPolicyStudioComponent', () => {
let loader: HarnessLoader;
let rootLoader: HarnessLoader;
let component: GioPolicyStudioComponent;
let fixture: ComponentFixture<GioPolicyStudioComponent>;
let policyStudioHarness: GioPolicyStudioHarness;
Expand All @@ -78,6 +79,7 @@ describe('GioPolicyStudioComponent', () => {
fixture = TestBed.createComponent(GioPolicyStudioComponent);
component = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
rootLoader = TestbedHarnessEnvironment.documentRootLoader(fixture);
policyStudioHarness = await TestbedHarnessEnvironment.harnessForFixture(fixture, GioPolicyStudioHarness);

component.policies = fakeAllPolicies();
Expand Down Expand Up @@ -1544,6 +1546,56 @@ describe('GioPolicyStudioComponent', () => {
fakeSharedPolicyGroupPolicyStep({ description: 'A', configuration: { sharedPolicyGroupId: '4d4c1b3b-3b1b-4b3b-8b3b-response' } }),
]);
});

it('should edit step with not found SPG into phase', async () => {
const commonFlows = [
fakeHttpFlow({
name: 'Alphabetical policy',
request: [fakeSharedPolicyGroupPolicyStep({ description: 'B', configuration: { sharedPolicyGroupId: 'notExist' } })],
}),
];
component.commonFlows = commonFlows;
component.ngOnChanges({
commonFlows: new SimpleChange(null, null, true),
});

// Edit step B into REQUEST phase
const requestPhase = await policyStudioHarness.getSelectedFlowPhase('REQUEST');

const step = await requestPhase?.getStep(0);
await step?.clickOnEdit();

const confirmDialog = await rootLoader.getHarness(GioConfirmDialogHarness);
expect(await (await confirmDialog.host()).text()).toContain(
'Shared Policy Group not foundThis step is linked to a Shared Policy Group that no longer exists.\n' +
'Note: The Gateway will ignore this step.',
);
});

it('should edit step with not found Policy into phase', async () => {
const commonFlows = [
fakeHttpFlow({
name: 'Alphabetical policy',
request: [fakeTestPolicyStep({ policy: 'notExist' })],
}),
];
component.commonFlows = commonFlows;
component.ngOnChanges({
commonFlows: new SimpleChange(null, null, true),
});

// Edit step B into REQUEST phase
const requestPhase = await policyStudioHarness.getSelectedFlowPhase('REQUEST');

const step = await requestPhase?.getStep(0);
await step?.clickOnEdit();

const confirmDialog = await rootLoader.getHarness(GioConfirmDialogHarness);
expect(await (await confirmDialog.host()).text()).toContain(
'Policy not foundThis step is linked to a Policy that no longer exists.\n' +
'Note: The Gateway will throw an error on deployment.',
);
});
});
});

Expand Down

0 comments on commit 429e7ae

Please sign in to comment.