From 162646a6a5c1393d6b146b7badba67ad8a0b375c Mon Sep 17 00:00:00 2001 From: elinuxhenrik Date: Tue, 16 Mar 2021 13:55:28 +0100 Subject: [PATCH] Fix PolicyInstanceDialogComponent Also change the syubs to provide policy without type. Change-Id: I33d4088533e2c5087a20dd868bf88d6487297a71 Signed-off-by: elinuxhenrik Issue-ID: NONRTRIC-463 --- webapp-frontend/src/app/interceptor.mock.ts | 32 +++-- webapp-frontend/src/app/mock/no-type-policies.json | 5 + .../src/app/mock/policy-instance-notype.json | 33 +++-- .../no-type-policy-editor.component.spec.ts | 91 ++++++------ .../policy-instance-dialog.component.html | 8 +- .../policy-instance-dialog.component.spec.ts | 159 +++++++++++++-------- .../policy-instance-dialog.component.ts | 4 +- .../typed-policy-editor.component.spec.ts | 148 +++++++++++-------- .../typed-policy-editor.component.ts | 149 ++++++++++--------- 9 files changed, 359 insertions(+), 270 deletions(-) create mode 100644 webapp-frontend/src/app/mock/no-type-policies.json diff --git a/webapp-frontend/src/app/interceptor.mock.ts b/webapp-frontend/src/app/interceptor.mock.ts index 29bcf6a..749d762 100644 --- a/webapp-frontend/src/app/interceptor.mock.ts +++ b/webapp-frontend/src/app/interceptor.mock.ts @@ -21,11 +21,13 @@ import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http'; import { Injectable, Injector } from '@angular/core'; import { Observable, of } from 'rxjs'; -import * as policyinstances1 from './mock/policy-instance-1.json'; -import * as policies from './mock/policies.json'; -import * as policyinstances2 from './mock/policy-instance-2.json'; -import * as policyinstances1Status from './mock/policy-instance-1-status.json'; -import * as policyinstances2Status from './mock/policy-instance-2-status.json'; +import * as policyinstance1 from './mock/policy-instance-1.json'; +import * as noTypePolicies from './mock/no-type-policies.json'; +import * as typedPolicies from './mock/policies.json'; +import * as policyinstance2 from './mock/policy-instance-2.json'; +import * as noTypePolicyinstance from './mock/policy-instance-notype.json'; +import * as policyinstance1Status from './mock/policy-instance-1-status.json'; +import * as policyinstance2Status from './mock/policy-instance-2-status.json'; import * as eijobsProd1 from './mock/ei-jobs-producer1.json'; import * as eijobsProd2 from './mock/ei-jobs-producer2.json'; import * as eiProducerIds from './mock/ei-producerids.json'; @@ -54,27 +56,35 @@ const urls = [ }, { url: '/a1-policy/v2/policies?policytype_id=', - json: policies + json: noTypePolicies }, { url: '/a1-policy/v2/policies?policytype_id=1', - json: policies + json: typedPolicies + }, + { + url: '/a1-policy/v2/policies/2001', + json: noTypePolicyinstance }, { url: '/a1-policy/v2/policies/2000', - json: policyinstances1 + json: policyinstance1 }, { url: '/a1-policy/v2/policies/2100', - json: policyinstances2 + json: policyinstance2 + }, + { + url: '/a1-policy/v2/policies/2001/status', + json: policyinstance1Status }, { url: '/a1-policy/v2/policies/2000/status', - json: policyinstances1Status + json: policyinstance1Status }, { url: '/a1-policy/v2/policies/2100/status', - json: policyinstances2Status + json: policyinstance2Status }, { url: '/a1-policy/v2/policies/2000?type=', diff --git a/webapp-frontend/src/app/mock/no-type-policies.json b/webapp-frontend/src/app/mock/no-type-policies.json new file mode 100644 index 0000000..6f00441 --- /dev/null +++ b/webapp-frontend/src/app/mock/no-type-policies.json @@ -0,0 +1,5 @@ +{ + "policy_ids": [ + "2001" + ] +} \ No newline at end of file diff --git a/webapp-frontend/src/app/mock/policy-instance-notype.json b/webapp-frontend/src/app/mock/policy-instance-notype.json index 7c91060..a3d95e7 100644 --- a/webapp-frontend/src/app/mock/policy-instance-notype.json +++ b/webapp-frontend/src/app/mock/policy-instance-notype.json @@ -1,18 +1,17 @@ -[ - { - "id": "2001", - "type": "", - "ric": "ric1", - "json": { - "scope": { - "ueId": "ue3100", - "qosId": "qos3100" - }, - "qosObjectives": { - "priorityLevel": 3100 - } - }, - "service": "service1", - "lastModified": "2020-12-08T21:12:43.719084Z" +{ + "policy_id": "2001", + "policytype_id": "", + "ric_id": "ric1", + "policy_data": { + "scope": { + "ueId": "ue3200", + "qosId": "qos3200" + }, + "qosObjectives": { + "priorityLevel": 3100 } - ] \ No newline at end of file + }, + "service_id": "service1", + "transient": false, + "status_notification_uri": "" +} \ No newline at end of file diff --git a/webapp-frontend/src/app/policy/no-type-policy-editor/no-type-policy-editor.component.spec.ts b/webapp-frontend/src/app/policy/no-type-policy-editor/no-type-policy-editor.component.spec.ts index 529caee..fb3a6a6 100644 --- a/webapp-frontend/src/app/policy/no-type-policy-editor/no-type-policy-editor.component.spec.ts +++ b/webapp-frontend/src/app/policy/no-type-policy-editor/no-type-policy-editor.component.spec.ts @@ -18,22 +18,22 @@ // ========================LICENSE_END=================================== // -import { HarnessLoader } from '@angular/cdk/testing'; -import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; -import { Component, ViewChild, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormBuilder, FormGroup } from '@angular/forms'; -import { MatButtonModule } from '@angular/material/button'; -import { MatButtonHarness } from '@angular/material/button/testing'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatInputHarness } from '@angular/material/input/testing'; -import { BrowserModule } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { HarnessLoader } from "@angular/cdk/testing"; +import { TestbedHarnessEnvironment } from "@angular/cdk/testing/testbed"; +import { Component, ViewChild, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { FormBuilder, FormGroup } from "@angular/forms"; +import { MatButtonModule } from "@angular/material/button"; +import { MatButtonHarness } from "@angular/material/button/testing"; +import { MatFormFieldModule } from "@angular/material/form-field"; +import { MatInputModule } from "@angular/material/input"; +import { MatInputHarness } from "@angular/material/input/testing"; +import { BrowserModule } from "@angular/platform-browser"; +import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; -import { NoTypePolicyEditorComponent } from './no-type-policy-editor.component'; +import { NoTypePolicyEditorComponent } from "./no-type-policy-editor.component"; -describe('NoTypePolicyEditorComponent', () => { +describe("NoTypePolicyEditorComponent", () => { let formGroup: FormGroup = new FormGroup({}); let component: TestNoTypePolicyEditorComponentHostComponent; @@ -47,65 +47,74 @@ describe('NoTypePolicyEditorComponent', () => { BrowserAnimationsModule, MatButtonModule, MatFormFieldModule, - MatInputModule - ], - schemas: [ - CUSTOM_ELEMENTS_SCHEMA + MatInputModule, ], + schemas: [CUSTOM_ELEMENTS_SCHEMA], declarations: [ NoTypePolicyEditorComponent, - TestNoTypePolicyEditorComponentHostComponent + TestNoTypePolicyEditorComponentHostComponent, ], - providers: [ - FormBuilder - ] - }) - .compileComponents(); + providers: [FormBuilder], + }).compileComponents(); - fixture = TestBed.createComponent(TestNoTypePolicyEditorComponentHostComponent); + fixture = TestBed.createComponent( + TestNoTypePolicyEditorComponentHostComponent + ); component = fixture.componentInstance; fixture.detectChanges(); loader = TestbedHarnessEnvironment.loader(fixture); }); - it('should create', () => { + it("should create", () => { expect(component).toBeTruthy(); }); - it('should be added to form group with required validator', async () => { - let textArea: MatInputHarness = await loader.getHarness(MatInputHarness.with({ selector: '#policyJsonTextArea' })); + it("should be added to form group with required validator", async () => { + let textArea: MatInputHarness = await loader.getHarness( + MatInputHarness.with({ selector: "#policyJsonTextArea" }) + ); - expect(formGroup.get('policyJsonTextArea')).toBeTruthy(); + expect(formGroup.get("policyJsonTextArea")).toBeTruthy(); expect(await textArea.isRequired()).toBeTruthy(); }); - it('should contain provided policy json and enabled Format button', async () => { - let textArea: MatInputHarness = await loader.getHarness(MatInputHarness.with({ selector: '#policyJsonTextArea' })); + it("should contain provided policy json and enabled Format button", async () => { + let textArea: MatInputHarness = await loader.getHarness( + MatInputHarness.with({ selector: "#policyJsonTextArea" }) + ); expect(await textArea.getValue()).toEqual('{"A":"A"}'); - console.log('Validity:',formGroup.valid); - let formatButton: MatButtonHarness = await loader.getHarness(MatButtonHarness.with({ selector: '#formatButton' })); + let formatButton: MatButtonHarness = await loader.getHarness( + MatButtonHarness.with({ selector: "#formatButton" }) + ); expect(await formatButton.isDisabled()).toBeFalsy(); }); - it('Format button should be disabled when json not valid', async () => { - const ele = formGroup.get('policyJsonTextArea'); - ele.setValue('{'); + it("Format button should be disabled when json not valid", async () => { + const ele = formGroup.get("policyJsonTextArea"); + ele.setValue("{"); - let formatButton: MatButtonHarness = await loader.getHarness(MatButtonHarness.with({ selector: '#formatButton' })); + let formatButton: MatButtonHarness = await loader.getHarness( + MatButtonHarness.with({ selector: "#formatButton" }) + ); expect(await formatButton.isDisabled()).toBeTruthy(); }); - it('should format unformatted json', async () => { - const textArea = formGroup.get('policyJsonTextArea'); + it("should format unformatted json", async () => { + const textArea = formGroup.get("policyJsonTextArea"); textArea.setValue('{"A":"A"}'); component.noTypePolicyEditorComponent.formatJsonInput(); - expect(component.noTypePolicyEditorComponent.policyJson).toEqual('{\n "A": "A"\n}'); + expect(component.noTypePolicyEditorComponent.policyJson).toEqual( + '{\n "A": "A"\n}' + ); }); @Component({ selector: `no-type-policy-editor-host-component`, - template: `` + template: ``, }) class TestNoTypePolicyEditorComponentHostComponent { @ViewChild(NoTypePolicyEditorComponent) diff --git a/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.html b/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.html index df4c1cf..6e79e78 100644 --- a/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.html +++ b/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.html @@ -27,7 +27,9 @@ - Create new policy instance of type {{policyTypeName}} + Create new policy instance of type + {{policyTypeName}} + < No Type > @@ -39,11 +41,11 @@ fxLayoutAlign.lt-sm="flex-start center"> - +

Properties

- +
diff --git a/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.spec.ts b/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.spec.ts index e8038ed..b4c2732 100644 --- a/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.spec.ts +++ b/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.spec.ts @@ -30,7 +30,13 @@ import { } from "@angular/material/dialog"; import { MatSelectModule } from "@angular/material/select"; import { MatInputModule } from "@angular/material/input"; -import { AbstractControl, ReactiveFormsModule } from "@angular/forms"; +import { + AbstractControl, + FormControl, + FormGroup, + ReactiveFormsModule, + Validators, +} from "@angular/forms"; import { TestbedHarnessEnvironment } from "@angular/cdk/testing/testbed"; import { ToastrModule } from "ngx-toastr"; @@ -42,26 +48,17 @@ import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA, + Input, } from "@angular/core"; import { TypedPolicyEditorComponent } from "../typed-policy-editor/typed-policy-editor.component"; import { RicSelectorComponent } from "../ric-selector/ric-selector.component"; import { NoTypePolicyEditorComponent } from "../no-type-policy-editor/no-type-policy-editor.component"; -import { PolicyTypeSchema } from "../../interfaces/policy.types"; +import { By } from "@angular/platform-browser"; describe("PolicyInstanceDialogComponent", () => { const untypedSchema = "{}"; - const untypedSchemaObject = { - id: "", - name: "", - schemaObject: untypedSchema, - } as PolicyTypeSchema; const typedSchema = - '{ "description": "Type 1 policy type", "title": "1", "type": "object", "properties": { "priorityLevel": "number" }, "required": [ "priorityLevel" ]}'; - const typedSchemaObject = { - id: "Type 1", - name: "Type 1", - schemaObject: typedSchema, - } as PolicyTypeSchema; + '{ "description": "Type 1 policy type", "title": "1", "type": "object", "properties": { "priorityLevel": "number" }}'; let component: PolicyInstanceDialogComponent; let fixture: ComponentFixture; @@ -106,7 +103,7 @@ describe("PolicyInstanceDialogComponent", () => { describe("content when creating policy without type", () => { beforeEach(async () => { const policyData = { - createSchema: untypedSchemaObject, + createSchema: untypedSchema, }; TestBed.overrideProvider(MAT_DIALOG_DATA, { useValue: policyData }); // Should be provided with a policy ({ fixture, component, loader } = compileAndGetComponents( @@ -129,22 +126,29 @@ describe("PolicyInstanceDialogComponent", () => { expect(ele).toBeFalsy(); }); - it("should contain ric select", async () => { - const ele = fixture.debugElement.nativeElement.querySelector( - "nrcp-ric-selector" - ); - expect(ele).toBeTruthy(); + it("should contain ric select with instance form and no policy type", async () => { + const ricSelector: RicSelectorComponent = fixture.debugElement.query(By.directive(RicSelectorComponent)).componentInstance; + expect(ricSelector).toBeTruthy(); + expect(ricSelector.instanceForm).toBeTruthy(); + expect(ricSelector.policyTypeName).toBeFalsy(); }); - it("should contain json editor", async () => { - const ele = fixture.debugElement.nativeElement.querySelector( - "nrcp-no-type-policy-editor" - ); - expect(ele).toBeTruthy(); + it("should contain json editor with instance form and empty JSON", async () => { + const noTypePolicyEditor: NoTypePolicyEditorComponent = fixture.debugElement.query(By.directive(NoTypePolicyEditorComponent)).componentInstance; + expect(noTypePolicyEditor).toBeTruthy(); + expect(noTypePolicyEditor.instanceForm).toBeTruthy(); + expect(noTypePolicyEditor.policyJson).toEqual("{}"); }); it("should contain enabled Close button and disabled Submit button", async () => { component.ngOnInit(); + // Add an empty value with required validator to set the dialog's instance form to be invalid. + const value: any = null; + component.instanceForm.addControl( + "dummy", + new FormControl(value, [Validators.required]) + ); + expect(component.instanceForm.valid).toBeFalsy(); let closeButton: MatButtonHarness = await loader.getHarness( MatButtonHarness.with({ selector: "#closeButton" }) @@ -155,7 +159,7 @@ describe("PolicyInstanceDialogComponent", () => { let submitButton: MatButtonHarness = await loader.getHarness( MatButtonHarness.with({ selector: "#submitButton" }) ); - // expect(await submitButton.isDisabled()).toBeTruthy(); + expect(await submitButton.isDisabled()).toBeTruthy(); expect(await submitButton.getText()).toEqual("Submit"); }); }); @@ -164,7 +168,7 @@ describe("PolicyInstanceDialogComponent", () => { beforeEach(async () => { const policyData = { name: "Type 1", - createSchema: typedSchemaObject, + createSchema: typedSchema, }; TestBed.overrideProvider(MAT_DIALOG_DATA, { useValue: policyData }); // Should be provided with a policy ({ fixture, component, loader } = compileAndGetComponents( @@ -187,22 +191,30 @@ describe("PolicyInstanceDialogComponent", () => { expect(ele).toBeFalsy(); }); - it("should contain ric select", async () => { - const ele = fixture.debugElement.nativeElement.querySelector( - "nrcp-ric-selector" - ); - expect(ele).toBeTruthy(); + it("should contain ric select with instance form and provided policy type", async () => { + const ricSelector: RicSelectorComponent = fixture.debugElement.query(By.directive(RicSelectorComponent)).componentInstance; + expect(ricSelector).toBeTruthy(); + expect(ricSelector.instanceForm).toBeTruthy(); + expect(ricSelector.policyTypeName).toEqual("Type 1"); }); - it("should contain typed json editor", async () => { - const ele = fixture.debugElement.nativeElement.querySelector( - "nrcp-typed-policy-editor" - ); - expect(ele).toBeTruthy(); + it("should contain typed json editor with empty JSON, schema and dark mode true", async () => { + const typedPolicyEditor: TypedPolicyEditorComponent = fixture.debugElement.query(By.directive(TypedPolicyEditorComponent)).componentInstance; + expect(typedPolicyEditor).toBeTruthy(); + expect(typedPolicyEditor.jsonObject).toBeFalsy(); + expect(typedPolicyEditor.jsonSchemaObject).toEqual(typedSchema); + expect(typedPolicyEditor.darkMode).toBeTruthy(); }); it("should contain enabled Close button and disabled Submit button", async () => { component.ngOnInit(); + // Add an empty value with required validator to set the dialog's instance form to be invalid. + const value: any = null; + component.instanceForm.addControl( + "dummy", + new FormControl(value, [Validators.required]) + ); + expect(component.instanceForm.valid).toBeFalsy(); let closeButton: MatButtonHarness = await loader.getHarness( MatButtonHarness.with({ selector: "#closeButton" }) @@ -213,17 +225,18 @@ describe("PolicyInstanceDialogComponent", () => { let submitButton: MatButtonHarness = await loader.getHarness( MatButtonHarness.with({ selector: "#submitButton" }) ); - // expect(await submitButton.isDisabled()).toBeTruthy(); + expect(await submitButton.isDisabled()).toBeTruthy(); expect(await submitButton.getText()).toEqual("Submit"); }); }); describe("content when editing policy without type", () => { + const instanceJson = '{"qosObjectives": {"priorityLevel": 3100}}'; beforeEach(async () => { const policyData = { - createSchema: untypedSchemaObject, + createSchema: untypedSchema, instanceId: "instanceId", - instanceJson: '{"qosObjectives": {"priorityLevel": 3100}}', + instanceJson: instanceJson, name: "Type 1", ric: "ric1", }; @@ -248,20 +261,20 @@ describe("PolicyInstanceDialogComponent", () => { }); it("should not contain ric select", async () => { - const ele = fixture.debugElement.nativeElement.querySelector( - "nrcp-ric-selector" - ); - expect(ele).toBeFalsy(); + const ricSelector = fixture.debugElement.query(By.directive(RicSelectorComponent)); + expect(ricSelector).toBeFalsy(); }); - it("should contain json editor", async () => { - const ele = fixture.debugElement.nativeElement.querySelector( - "nrcp-no-type-policy-editor" - ); - expect(ele).toBeTruthy(); + it("should contain json editor with form and json data", async () => { + const noTypePolicyEditor: NoTypePolicyEditorComponent = fixture.debugElement.query(By.directive(NoTypePolicyEditorComponent)).componentInstance; + expect(noTypePolicyEditor).toBeTruthy(); + expect(noTypePolicyEditor.instanceForm).toBeTruthy(); + expect(unescapeQuotes(noTypePolicyEditor.policyJson)).toEqual('"' + instanceJson + '"'); }); - it("should contain enabled Close and Submit buttons", async () => { + it("should contain enabled Close and Submit buttons when all inputs are valid", async () => { + expect(component.instanceForm.valid).toBeTruthy(); + let closeButton: MatButtonHarness = await loader.getHarness( MatButtonHarness.with({ selector: "#closeButton" }) ); @@ -277,11 +290,12 @@ describe("PolicyInstanceDialogComponent", () => { }); describe("content when editing policy with type", () => { + const instanceJson = '{"qosObjectives": {"priorityLevel": 3100}}'; beforeEach(async () => { const policyData = { - createSchema: typedSchemaObject, + createSchema: typedSchema, instanceId: "instanceId", - instanceJson: '{"qosObjectives": {"priorityLevel": 3100}}', + instanceJson: instanceJson, name: "name", ric: "ric1", }; @@ -306,20 +320,21 @@ describe("PolicyInstanceDialogComponent", () => { }); it("should not contain ric select", async () => { - const ele = fixture.debugElement.nativeElement.querySelector( - "nrcp-ric-selector" - ); - expect(ele).toBeFalsy(); + const ricSelector = fixture.debugElement.query(By.directive(RicSelectorComponent)); + expect(ricSelector).toBeFalsy(); }); - it("should contain typed json editor", async () => { - const ele = fixture.debugElement.nativeElement.querySelector( - "nrcp-typed-policy-editor" - ); - expect(ele).toBeTruthy(); + it("should contain typed json editor with instance JSON, schema and dark mode true", async () => { + const typedPolicyEditor: TypedPolicyEditorComponent = fixture.debugElement.query(By.directive(TypedPolicyEditorComponent)).componentInstance; + expect(typedPolicyEditor).toBeTruthy(); + expect(unescapeQuotes(typedPolicyEditor.jsonObject)).toEqual(instanceJson); + expect(typedPolicyEditor.jsonSchemaObject).toEqual(typedSchema); + expect(typedPolicyEditor.darkMode).toBeTruthy(); }); - it("should contain enabled Close and Submit buttons", async () => { + it("should contain enabled Close and Submit buttons when all inputs are valid", async () => { + expect(component.instanceForm.valid).toBeTruthy(); + let closeButton: MatButtonHarness = await loader.getHarness( MatButtonHarness.with({ selector: "#closeButton" }) ); @@ -349,14 +364,24 @@ function compileAndGetComponents( return { fixture, component, loader }; } +function unescapeQuotes(string: string): string { + return string.replace(/\\"/g, '"'); +} + @Component({ - selector: "nrcp-ric-selecor", + selector: "nrcp-ric-selector", template: "", providers: [ - { provide: RicSelectorComponent, useClass: RicSelectorStubComponent }, + { + provide: RicSelectorComponent, + useClass: RicSelectorStubComponent, + }, ], }) class RicSelectorStubComponent { + @Input() instanceForm: FormGroup; + @Input() policyTypeName: string = ""; + get selectedRic(): string { return "ric1"; } @@ -373,6 +398,9 @@ class RicSelectorStubComponent { ], }) class NoTypePolicyEditorStubComponent { + @Input() instanceForm: FormGroup; + @Input() policyJson: string; + get policyJsonTextArea(): AbstractControl { const textArea = { value: "{}" } as AbstractControl; return textArea; @@ -390,6 +418,11 @@ class NoTypePolicyEditorStubComponent { ], }) class TypedPolicyEditorStubComponent { + @Input() jsonSchemaObject: any = {}; + @Input() jsonObject: any = {}; + @Input() darkMode: boolean; + + prettyLiveFormData = '"A": "string"'; get formIsValid(): boolean { return true; } diff --git a/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.ts b/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.ts index 3ec5522..096346e 100644 --- a/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.ts +++ b/webapp-frontend/src/app/policy/policy-instance-dialog/policy-instance-dialog.component.ts @@ -80,7 +80,7 @@ export class PolicyInstanceDialogComponent implements OnInit, AfterViewInit { private ui: UiService ) { this.policyInstanceId = data.instanceId; - this.policyTypeName = data.name ? data.name : "< No Type >"; + this.policyTypeName = data.name; this.policyJson = data.instanceJson; this.jsonSchemaObject = data.createSchema; this.ric = data.ric; @@ -138,7 +138,7 @@ export class PolicyInstanceDialogComponent implements OnInit, AfterViewInit { } typeHasSchema(): boolean { - return this.jsonSchemaObject.schemaObject !== "{}"; + return this.jsonSchemaObject !== "{}"; } isFormValid(): boolean { diff --git a/webapp-frontend/src/app/policy/typed-policy-editor/typed-policy-editor.component.spec.ts b/webapp-frontend/src/app/policy/typed-policy-editor/typed-policy-editor.component.spec.ts index 6c745e3..fc4a166 100644 --- a/webapp-frontend/src/app/policy/typed-policy-editor/typed-policy-editor.component.spec.ts +++ b/webapp-frontend/src/app/policy/typed-policy-editor/typed-policy-editor.component.spec.ts @@ -18,125 +18,157 @@ // ========================LICENSE_END=================================== // -import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/compiler'; -import { Component } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MatIconModule } from '@angular/material/icon'; -import { BrowserModule } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/compiler"; +import { Component } from "@angular/core"; +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { MatIconModule } from "@angular/material/icon"; +import { BrowserModule } from "@angular/platform-browser"; +import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; -import { TypedPolicyEditorComponent } from './typed-policy-editor.component'; +import { TypedPolicyEditorComponent } from "./typed-policy-editor.component"; -describe('TypedPolicyEditorComponent', () => { +describe("TypedPolicyEditorComponent", () => { let component: TestTypedPolicyEditorComponentHostComponent; let fixture: ComponentFixture; beforeEach(async () => { TestBed.configureTestingModule({ - imports: [ - BrowserModule, - BrowserAnimationsModule, - MatIconModule - ], + imports: [BrowserModule, BrowserAnimationsModule, MatIconModule], declarations: [ TypedPolicyEditorComponent, - TestTypedPolicyEditorComponentHostComponent + TestTypedPolicyEditorComponentHostComponent, ], - schemas: [ - CUSTOM_ELEMENTS_SCHEMA - ] - }) - .compileComponents(); + schemas: [CUSTOM_ELEMENTS_SCHEMA], + }).compileComponents(); }); beforeEach(() => { - fixture = TestBed.createComponent(TestTypedPolicyEditorComponentHostComponent); + fixture = TestBed.createComponent( + TestTypedPolicyEditorComponentHostComponent + ); component = fixture.componentInstance; fixture.detectChanges(); }); - it('should create', () => { + it("should create", () => { expect(component).toBeTruthy(); }); - it('should have JSON form visible and JSON and JSON Schema not visible', () => { - let propertiesHeading = fixture.debugElement.nativeElement.querySelector('#propertiesHeading'); + it("should have JSON form visible and JSON and JSON Schema not visible", () => { + let propertiesHeading = fixture.debugElement.nativeElement.querySelector( + "#propertiesHeading" + ); expect(propertiesHeading).toBeTruthy(); - expect(propertiesHeading.innerText).toContain('Properties'); - let propertiesIcon = fixture.debugElement.nativeElement.querySelector('#propertiesIcon'); + expect(propertiesHeading.innerText).toContain("Properties"); + let propertiesIcon = fixture.debugElement.nativeElement.querySelector( + "#propertiesIcon" + ); expect(propertiesIcon).toBeTruthy(); - expect(propertiesIcon.innerText).toEqual('expand_less'); - let jsonForm = fixture.debugElement.nativeElement.querySelector('json-schema-form'); + expect(propertiesIcon.innerText).toEqual("expand_less"); + let jsonForm = fixture.debugElement.nativeElement.querySelector( + "json-schema-form" + ); expect(jsonForm).toBeTruthy(); - let jsonHeading = fixture.debugElement.nativeElement.querySelector('#jsonHeading'); + let jsonHeading = fixture.debugElement.nativeElement.querySelector( + "#jsonHeading" + ); expect(jsonHeading).toBeTruthy(); - expect(jsonHeading.innerText).toContain('JSON') - let jsonIcon = fixture.debugElement.nativeElement.querySelector('#jsonIcon'); + expect(jsonHeading.innerText).toContain("JSON"); + let jsonIcon = fixture.debugElement.nativeElement.querySelector( + "#jsonIcon" + ); expect(jsonIcon).toBeTruthy(); - expect(jsonIcon.innerText).toEqual('expand_more'); - let jsonDiv = fixture.debugElement.nativeElement.querySelector('#jsonDiv'); + expect(jsonIcon.innerText).toEqual("expand_more"); + let jsonDiv = fixture.debugElement.nativeElement.querySelector("#jsonDiv"); expect(jsonDiv).toBeFalsy(); - let schemaHeading = fixture.debugElement.nativeElement.querySelector('#schemaHeading'); + let schemaHeading = fixture.debugElement.nativeElement.querySelector( + "#schemaHeading" + ); expect(schemaHeading).toBeTruthy(); - expect(schemaHeading.innerText).toContain('JSON Schema'); - let schemaIcon = fixture.debugElement.nativeElement.querySelector('#schemaIcon'); + expect(schemaHeading.innerText).toContain("JSON Schema"); + let schemaIcon = fixture.debugElement.nativeElement.querySelector( + "#schemaIcon" + ); expect(schemaIcon).toBeTruthy(); - expect(schemaIcon.innerText).toEqual('expand_more'); - let schemaDiv = fixture.debugElement.nativeElement.querySelector('#schemaDiv'); + expect(schemaIcon.innerText).toEqual("expand_more"); + let schemaDiv = fixture.debugElement.nativeElement.querySelector( + "#schemaDiv" + ); expect(schemaDiv).toBeFalsy(); }); - it('should hide JSON form', () => { - let propertiesHeading = fixture.debugElement.nativeElement.querySelector('#propertiesHeading'); + it("should hide JSON form", () => { + let propertiesHeading = fixture.debugElement.nativeElement.querySelector( + "#propertiesHeading" + ); expect(propertiesHeading).toBeTruthy(); propertiesHeading.click(); fixture.detectChanges(); - let propertiesIcon = fixture.debugElement.nativeElement.querySelector('#propertiesIcon'); + let propertiesIcon = fixture.debugElement.nativeElement.querySelector( + "#propertiesIcon" + ); expect(propertiesIcon).toBeTruthy(); - expect(propertiesIcon.innerText).toEqual('expand_more'); - let propertiesDiv = fixture.debugElement.nativeElement.querySelector('propertiesDiv'); + expect(propertiesIcon.innerText).toEqual("expand_more"); + let propertiesDiv = fixture.debugElement.nativeElement.querySelector( + "propertiesDiv" + ); expect(propertiesDiv).toBeFalsy(); }); - it('should show JSON with text for dark mode', () => { - let jsonHeading = fixture.debugElement.nativeElement.querySelector('#jsonHeading'); + it("should show JSON with text for dark mode", () => { + let jsonHeading = fixture.debugElement.nativeElement.querySelector( + "#jsonHeading" + ); expect(jsonHeading).toBeTruthy(); jsonHeading.click(); fixture.detectChanges(); - let jsonIcon = fixture.debugElement.nativeElement.querySelector('#jsonIcon'); + let jsonIcon = fixture.debugElement.nativeElement.querySelector( + "#jsonIcon" + ); expect(jsonIcon).toBeTruthy(); - expect(jsonIcon.innerText).toEqual('expand_less'); - let jsonDiv = fixture.debugElement.nativeElement.querySelector('#jsonDiv'); + expect(jsonIcon.innerText).toEqual("expand_less"); + let jsonDiv = fixture.debugElement.nativeElement.querySelector("#jsonDiv"); expect(jsonDiv).toBeTruthy(); - let jsonText = jsonDiv.querySelector('pre'); - expect(jsonText.classList).toContain('text__dark'); + let jsonText = jsonDiv.querySelector("pre"); + expect(jsonText.classList).toContain("text__dark"); }); - it('should show JSON Schema with text for dark mode', () => { - let schemaHeading = fixture.debugElement.nativeElement.querySelector('#schemaHeading'); + it("should show JSON Schema with text for dark mode", () => { + let schemaHeading = fixture.debugElement.nativeElement.querySelector( + "#schemaHeading" + ); expect(schemaHeading).toBeTruthy(); schemaHeading.click(); fixture.detectChanges(); - let schemaIcon = fixture.debugElement.nativeElement.querySelector('#schemaIcon'); + let schemaIcon = fixture.debugElement.nativeElement.querySelector( + "#schemaIcon" + ); expect(schemaIcon).toBeTruthy(); - expect(schemaIcon.innerText).toEqual('expand_less'); - let schemaDiv = fixture.debugElement.nativeElement.querySelector('#schemaDiv'); + expect(schemaIcon.innerText).toEqual("expand_less"); + let schemaDiv = fixture.debugElement.nativeElement.querySelector( + "#schemaDiv" + ); expect(schemaDiv).toBeTruthy(); - let jsonSchemaText = schemaDiv.querySelector('pre'); - expect(jsonSchemaText.classList).toContain('text__dark'); + let jsonSchemaText = schemaDiv.querySelector("pre"); + expect(jsonSchemaText.classList).toContain("text__dark"); }); @Component({ selector: `typed-policy-editor-host-component`, - template: `` + template: ``, }) class TestTypedPolicyEditorComponentHostComponent { policyJson: string = '{"A":"A"}'; - jsonSchemaObject: string = 'policy_schema": { "$schema": "http://json-schema.org/draft-07/schema#", "description": "Type 1 policy type", "additionalProperties": false, "title": "1", "type": "object", "properties": { "A": "string" }, "required": [ "A" ]}'; + jsonSchemaObject: string = + 'policy_schema": { "description": "Type 1 policy type", "title": "1", "type": "object", "properties": { "A": "string" }, "required": [ "A" ]}'; } }); diff --git a/webapp-frontend/src/app/policy/typed-policy-editor/typed-policy-editor.component.ts b/webapp-frontend/src/app/policy/typed-policy-editor/typed-policy-editor.component.ts index 46b51bf..f9651a4 100644 --- a/webapp-frontend/src/app/policy/typed-policy-editor/typed-policy-editor.component.ts +++ b/webapp-frontend/src/app/policy/typed-policy-editor/typed-policy-editor.component.ts @@ -23,95 +23,94 @@ import { Component, Input, OnInit } from '@angular/core'; import { JsonPointer } from 'angular6-json-schema-form'; @Component({ - selector: 'nrcp-typed-policy-editor', - templateUrl: './typed-policy-editor.component.html', - styleUrls: ['./typed-policy-editor.component.scss'], - animations: [ - trigger('expandSection', [ - state('in', style({ height: '*' })), - transition(':enter', [ - style({ height: 0 }), animate(100), - ]), - transition(':leave', [ - style({ height: '*' }), - animate(100, style({ height: 0 })), - ]), - ]), - ], - + selector: "nrcp-typed-policy-editor", + templateUrl: "./typed-policy-editor.component.html", + styleUrls: ["./typed-policy-editor.component.scss"], + animations: [ + trigger("expandSection", [ + state("in", style({ height: "*" })), + transition(":enter", [style({ height: 0 }), animate(100)]), + transition(":leave", [ + style({ height: "*" }), + animate(100, style({ height: 0 })), + ]), + ]), + ], }) export class TypedPolicyEditorComponent implements OnInit { - jsonFormOptions: any = { - addSubmit: false, // Add a submit button if layout does not have one - debug: false, // Don't show inline debugging information - loadExternalAssets: false, // Load external css and JavaScript for frameworks - returnEmptyFields: false, // Don't return values for empty input fields - setSchemaDefaults: true, // Always use schema defaults for empty fields - defautWidgetOptions: { feedback: true }, // Show inline feedback icons - }; + jsonFormOptions: any = { + addSubmit: false, // Add a submit button if layout does not have one + debug: false, // Don't show inline debugging information + loadExternalAssets: false, // Load external css and JavaScript for frameworks + returnEmptyFields: false, // Don't return values for empty input fields + setSchemaDefaults: true, // Always use schema defaults for empty fields + defautWidgetOptions: { feedback: true }, // Show inline feedback icons + }; - @Input() jsonSchemaObject: any = {}; - @Input() jsonObject: any = {}; - @Input() darkMode: boolean; + @Input() jsonSchemaObject: any = {}; + @Input() jsonObject: any = {}; + @Input() darkMode: boolean; - isVisible = { - form: true, - json: false, - schema: false - }; - liveFormData: any = {}; - formIsValid: boolean = false; - formValidationErrors: any; + isVisible = { + form: true, + json: false, + schema: false, + }; + liveFormData: any = {}; + formIsValid: boolean = false; + formValidationErrors: any; - constructor() {} + constructor() {} - ngOnInit(): void {} + ngOnInit(): void {} - public onChanges(formData: any) { - this.liveFormData = formData; - } + public onChanges(formData: any) { + this.liveFormData = formData; + } - get prettyLiveFormData(): string { - return JSON.stringify(this.liveFormData, null, 2); - } + get prettyLiveFormData(): string { + return JSON.stringify(this.liveFormData, null, 2); + } - get schemaAsString(): string { - return JSON.stringify(this.jsonSchemaObject, null, 2); - } + get schemaAsString(): string { + return JSON.stringify(this.jsonSchemaObject, null, 2); + } - get jsonAsString(): string { - return JSON.stringify(this.jsonObject, null, 2); - } + get jsonAsString(): string { + return JSON.stringify(this.jsonObject, null, 2); + } - isValid(isValid: boolean): void { - this.formIsValid = isValid; - } + isValid(isValid: boolean): void { + this.formIsValid = isValid; + } - validationErrors(validationErrors: any): void { - this.formValidationErrors = validationErrors; - } + validationErrors(validationErrors: any): void { + this.formValidationErrors = validationErrors; + } - get prettyValidationErrors() { - if (!this.formValidationErrors) { return null; } - const errorArray = []; - for (const error of this.formValidationErrors) { - const message = error.message; - const dataPathArray = JsonPointer.parse(error.dataPath); - if (dataPathArray.length) { - let field = dataPathArray[0]; - for (let i = 1; i < dataPathArray.length; i++) { - const key = dataPathArray[i]; - field += /^\d+$/.test(key) ? `[${key}]` : `.${key}`; - } - errorArray.push(`${field}: ${message}`); - } else { - errorArray.push(message); - } + get prettyValidationErrors() { + if (!this.formValidationErrors) { + return null; + } + const errorArray = []; + for (const error of this.formValidationErrors) { + const message = error.message; + const dataPathArray = JsonPointer.parse(error.dataPath); + if (dataPathArray.length) { + let field = dataPathArray[0]; + for (let i = 1; i < dataPathArray.length; i++) { + const key = dataPathArray[i]; + field += /^\d+$/.test(key) ? `[${key}]` : `.${key}`; } - return errorArray.join('
'); + errorArray.push(`${field}: ${message}`); + } else { + errorArray.push(message); + } } + return errorArray.join("
"); + } - public toggleVisible(item: string) { - this.isVisible[item] = !this.isVisible[item]; - } + public toggleVisible(item: string) { + this.isVisible[item] = !this.isVisible[item]; + } } -- 2.16.6