summaryrefslogtreecommitdiffstats
path: root/mod2/ui/src/app/comp-spec-validation
diff options
context:
space:
mode:
Diffstat (limited to 'mod2/ui/src/app/comp-spec-validation')
-rw-r--r--mod2/ui/src/app/comp-spec-validation/comp-spec-validation.component.css73
-rw-r--r--mod2/ui/src/app/comp-spec-validation/comp-spec-validation.component.html108
-rw-r--r--mod2/ui/src/app/comp-spec-validation/comp-spec-validation.component.spec.ts132
-rw-r--r--mod2/ui/src/app/comp-spec-validation/comp-spec-validation.component.ts145
4 files changed, 458 insertions, 0 deletions
diff --git a/mod2/ui/src/app/comp-spec-validation/comp-spec-validation.component.css b/mod2/ui/src/app/comp-spec-validation/comp-spec-validation.component.css
new file mode 100644
index 0000000..d76e0fa
--- /dev/null
+++ b/mod2/ui/src/app/comp-spec-validation/comp-spec-validation.component.css
@@ -0,0 +1,73 @@
+/*
+ * # ============LICENSE_START=======================================================
+ * # Copyright (c) 2020 AT&T Intellectual Property. All rights reserved.
+ * # ================================================================================
+ * # 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.
+ * # ============LICENSE_END=========================================================
+ */
+
+.validator-input-card{
+ width: 40%;
+ min-width: 430px;
+ min-height: 100%;
+ border: 2px solid slategray;
+ border-radius: 5px;
+ background-color: white;
+ padding: 1%;
+}
+.validator-output-card{
+ width: 58%;
+ border: 2px solid slategray;
+ margin-left: 2%;
+ min-height: 100%;
+ border-radius: 5px;
+ background-color: white;
+ padding: 1%;
+}
+
+.input-section-card{
+ font-size: 14px;
+ border: solid slategray;
+ border-style: double;
+ margin-top: 7px
+}
+
+.validateSpec{
+ margin-top: 10px;
+}
+.downloadSchema{
+ margin-top: 80px;
+}
+
+.type-selection{
+ position: absolute;
+ background-color: rgba(128, 128, 128, 0.15);
+ width: 190px;
+ height: 40px;
+ display: inline-flex;
+ align-items: center;
+ margin-left: 150px;
+}
+
+.greenOutput{
+ background-color: rgba(0, 255, 0, 0.205);
+ height: 40px;
+ padding: 3px;
+ border: 2px solid rgba(0, 66, 0, 0.747);
+}
+.redOutput{
+ background-color: rgba(255, 0, 0, 0.267);
+ height: 87%;
+ padding: 10px;
+ border: 2px solid rgba(65, 0, 0, 0.712);
+}
diff --git a/mod2/ui/src/app/comp-spec-validation/comp-spec-validation.component.html b/mod2/ui/src/app/comp-spec-validation/comp-spec-validation.component.html
new file mode 100644
index 0000000..9867364
--- /dev/null
+++ b/mod2/ui/src/app/comp-spec-validation/comp-spec-validation.component.html
@@ -0,0 +1,108 @@
+<!--
+ # ============LICENSE_START=======================================================
+ # Copyright (c) 2020 AT&T Intellectual Property. All rights reserved.
+ # ================================================================================
+ # 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.
+ # ============LICENSE_END=========================================================
+ -->
+
+<div style="margin-left: 2%; margin-right: 2%;">
+ <p style="font-size: 26px;">Component Specification Validation</p>
+ <div style="display: inline-flex; width: 100%; height: 100%; min-height: 450px;">
+ <div class="validator-input-card">
+ <div>
+ <mat-card class="input-section-card">
+ <span><b>Action</b></span><span style="color:red">*</span><br>
+ <div style="display: inline-flex;">
+ <div style="padding-right: 10%; width: 200px;">
+ <p-radioButton name="spec-validator-actions" value="validateSpec" [(ngModel)]="spec_validator_action" (click)="validateRadioButton()"></p-radioButton>&nbsp;&nbsp;Validate Spec File
+ </div>
+ <div>
+ <p-radioButton name="spec-validator-actions" value="downloadSchema" [(ngModel)]="spec_validator_action" (click)="downloadRadioButton()"></p-radioButton>&nbsp;&nbsp;Download Schema
+ </div>
+ </div>
+ </mat-card>
+
+ <mat-card class="input-section-card">
+ <span><b>Release</b></span><span style="color:red">*</span><br>
+ <div>
+ <div style="display: inline-flex; align-items: center;">
+ <p-radioButton name="spec-validator-release" value="2007" [(ngModel)]="release"></p-radioButton>&nbsp;&nbsp;2007+
+ </div>
+ </div>
+ </mat-card>
+
+ <mat-card class="input-section-card">
+ <span><b>Type</b></span><span style="color:red">*</span><br>
+ <div>
+ <div style="display: inline-flex; align-items: center;">
+ <p-radioButton name="spec-validator-type" value="k8s" [(ngModel)]="type"></p-radioButton>&nbsp;&nbsp;K8s
+ </div>
+ <br>
+ <div style="display: inline-flex; align-items: center;">
+ <p-radioButton name="spec-validator-type" value="docker" [(ngModel)]="type"></p-radioButton>&nbsp;&nbsp;Docker
+ </div>
+ </div>
+ </mat-card>
+
+ <mat-card *ngIf="spec_validator_action === 'validateSpec'" class="input-section-card">
+ <!-- * * * Comp Spec File Select * * * -->
+ <div>
+ <b>Component Spec File</b><span style="color:red">*</span><br>
+
+ <div style="display: inline-flex;">
+ <input #myFile type="file" style="color:blue; font-style: italic; width: fit-content"
+ (input)="onCompSpecUpload($event)" name="myfile" accept=".json">
+
+ <button pButton type="button" (click)="resetFile()"
+ style="background-color: transparent; border: none; height: 20px;"><i class="pi pi-times"
+ style="color: black;"></i></button>
+ </div>
+ </div>
+ </mat-card>
+
+ <div>
+ <div *ngIf="shouldValidate" style="background-color: rgba(128, 128, 128, 0.315); height: 2px; width: 100%; margin-top: 2%;"></div>
+ <div *ngIf="shouldDownload" style="background-color: rgba(128, 128, 128, 0.315); height: 2px; width: 100%; margin-top: 22%;"></div>
+
+ <div style="float: right; margin-top: 8px">
+ <div *ngIf="shouldValidate" matTooltip="Fill In Required Fields" [matTooltipDisabled]="!(release === '' || type === '' || compSpecContent === null)" matTooltipPosition="above">
+ <button [disabled]="release === '' || type === '' || compSpecContent === null" pButton label="Validate Spec" type="button" (click)="validateSpec()"></button>
+ </div>
+ <div *ngIf="shouldDownload" matTooltip="Fill In Required Fields" [matTooltipDisabled]="!(release === '' || type === '')" matTooltipPosition="above">
+ <button [disabled]="release === '' || type === ''" pButton label="Download Schema" type="button" (click)="downloadSchema()"></button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div *ngIf="shouldValidate" class="validator-output-card">
+ <span><b>Output:</b></span><br><br>
+ <div *ngIf="specValidated" style="width: 100%; padding: 1%; border-radius: 3px; overflow: hidden;" [ngClass]="{'greenOutput' : validCompSpec === true, 'redOutput' : validCompSpec === false}">
+ <div>
+ <span style="font-weight: 500;">{{specValidationOutputHeader}}</span>
+ <div *ngIf="specValidationOutputMessage !== ''" style="margin-top: 10px; width: 100%; height: 2px; background-color: rgba(128, 128, 128, 0.315); "></div>
+
+ <div *ngIf="specValidationOutputMessage !== ''" style="margin-top: 10px">
+ <p-scrollPanel [style]="{width: '100%', height: '50vh'}">
+ <pre style="white-space: pre-wrap;"><b>Summary:</b><br>{{specValidationOutputSummary}}</pre>
+ <pre style="white-space: pre-wrap;"><b>Message(s):</b><br>{{specValidationOutputMessage}}</pre>
+ </p-scrollPanel>
+ </div>
+
+ </div>
+ </div>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/mod2/ui/src/app/comp-spec-validation/comp-spec-validation.component.spec.ts b/mod2/ui/src/app/comp-spec-validation/comp-spec-validation.component.spec.ts
new file mode 100644
index 0000000..a9efe28
--- /dev/null
+++ b/mod2/ui/src/app/comp-spec-validation/comp-spec-validation.component.spec.ts
@@ -0,0 +1,132 @@
+/*
+ * # ============LICENSE_START=======================================================
+ * # Copyright (c) 2020 AT&T Intellectual Property. All rights reserved.
+ * # ================================================================================
+ * # 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.
+ * # ============LICENSE_END=========================================================
+ */
+
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { RadioButtonModule } from 'primeng/radiobutton';
+
+import { CompSpecValidationComponent } from './comp-spec-validation.component';
+import { FormsModule } from '@angular/forms';
+import { MatCardModule, MatTooltipModule } from '@angular/material';
+import { ScrollPanelModule } from 'primeng/scrollpanel';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { MessageService } from 'primeng/api';
+import { JwtHelperService, JWT_OPTIONS } from '@auth0/angular-jwt';
+import { Ng4LoadingSpinnerModule } from 'ng4-loading-spinner';
+
+describe('CompSpecValidationComponent', () => {
+ let component: CompSpecValidationComponent;
+ let fixture: ComponentFixture<CompSpecValidationComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ CompSpecValidationComponent ],
+ imports: [
+ RadioButtonModule,
+ FormsModule,
+ MatCardModule,
+ MatTooltipModule,
+ ScrollPanelModule,
+ HttpClientTestingModule,
+ Ng4LoadingSpinnerModule
+ ],
+ providers: [
+ MessageService,
+ { provide: JWT_OPTIONS, useValue: JWT_OPTIONS },
+ JwtHelperService
+ ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CompSpecValidationComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it(`should have as shouldValidate 'false'`, () => {
+ const fixture = TestBed.createComponent(CompSpecValidationComponent);
+ const app = fixture.debugElement.componentInstance;
+ expect(app.shouldValidate).toEqual(false);
+ });
+
+ it(`should change shouldValidate to 'true'`, async(() => {
+ const fixture = TestBed.createComponent(CompSpecValidationComponent);
+ const app = fixture.debugElement.componentInstance;
+ app.validateRadioButton()
+ fixture.detectChanges();
+ expect(app.shouldValidate).toEqual(true);
+ }));
+
+ it(`should have as shouldDownload 'false'`, () => {
+ const fixture = TestBed.createComponent(CompSpecValidationComponent);
+ const app = fixture.debugElement.componentInstance;
+ expect(app.shouldDownload).toEqual(false);
+ });
+
+ it(`should change shouldDownload to 'true'`, async(() => {
+ const fixture = TestBed.createComponent(CompSpecValidationComponent);
+ const app = fixture.debugElement.componentInstance;
+ app.downloadRadioButton()
+ fixture.detectChanges();
+ expect(app.shouldDownload).toEqual(true);
+ }));
+
+ it(`should set validation error message`, async(() => {
+ const fixture = TestBed.createComponent(CompSpecValidationComponent);
+ const app = fixture.debugElement.componentInstance;
+ let mockSuccess = {
+ status: 200
+ }
+ app.setSpecValidationMessage(mockSuccess)
+ fixture.detectChanges();
+ expect(app.validCompSpec).toEqual(true)
+ }));
+
+ it(`should set validation error message`, async(() => {
+ const fixture = TestBed.createComponent(CompSpecValidationComponent);
+ const app = fixture.debugElement.componentInstance;
+
+ let mockError = {
+ status: 400,
+ error: {
+ summary: 'Test',
+ errors: [
+ 'error1',
+ 'error2'
+ ]
+ }
+ }
+ app.setSpecValidationMessage(mockError)
+ fixture.detectChanges();
+ expect(app.validCompSpec).toEqual(false)
+ }));
+
+ it(`should invalidate JSON structure`, async(() => {
+ const fixture = TestBed.createComponent(CompSpecValidationComponent);
+ const app = fixture.debugElement.componentInstance;
+ let mockErrorJson = "test: 'test}"
+ app.compSpecContent = mockErrorJson
+ expect(() => app.validateJsonStructure()).toThrowError('JSON Structure error, quit!')
+ }));
+
+});
diff --git a/mod2/ui/src/app/comp-spec-validation/comp-spec-validation.component.ts b/mod2/ui/src/app/comp-spec-validation/comp-spec-validation.component.ts
new file mode 100644
index 0000000..2ce8fef
--- /dev/null
+++ b/mod2/ui/src/app/comp-spec-validation/comp-spec-validation.component.ts
@@ -0,0 +1,145 @@
+/*
+ * # ============LICENSE_START=======================================================
+ * # Copyright (c) 2020 AT&T Intellectual Property. All rights reserved.
+ * # ================================================================================
+ * # 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.
+ * # ============LICENSE_END=========================================================
+ */
+
+import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
+import { SpecValidationService } from '../services/spec-validation.service';
+import { DownloadService } from '../services/download.service';
+import { Ng4LoadingSpinnerService } from 'ng4-loading-spinner';
+
+@Component({
+ selector: 'app-comp-spec-validation',
+ templateUrl: './comp-spec-validation.component.html',
+ styleUrls: ['./comp-spec-validation.component.css']
+})
+export class CompSpecValidationComponent implements OnInit {
+
+ @ViewChild('myFile', {static: false})
+ myInputVariable: ElementRef;
+
+ spec_validator_action;
+ release = '';
+ type = '';
+ shouldValidate = false;
+ shouldDownload = false;
+ validCompSpec = false;
+ specValidated = false;
+ specValidationOutputSummary: any;
+
+ constructor(private specValidator: SpecValidationService, private downloadService: DownloadService, private spinnerService: Ng4LoadingSpinnerService ) { }
+
+ ngOnInit() {
+
+ }
+
+ compSpecSelected: any;
+ onCompSpecUpload(event){
+ this.compSpecSelected = event.target.files[0];
+ this.readCsFileContent(this.compSpecSelected);
+ }
+
+ compSpecContent: any = null;
+ readCsFileContent(file) {
+ if (file) {
+ let fileReader = new FileReader();
+ fileReader.onload = (e) => { this.compSpecContent = fileReader.result; };
+ fileReader.readAsText(file);
+ }
+ }
+
+ validateRadioButton(){
+ this.shouldValidate = true;
+ this.shouldDownload = false;
+ }
+
+ downloadRadioButton(){
+ this.shouldValidate = false;
+ this.shouldDownload = true;
+ this.compSpecContent = null;
+ this.specValidated = false
+ }
+
+ resetFile(){
+ this.myInputVariable.nativeElement.value = "";
+ this.compSpecContent = null
+ this.compSpecSelected = null
+ this.specValidated = false
+ }
+
+ specValidationOutputHeader = ''
+ specValidationOutputMessage = '';
+ validateSpec(){
+ this.specValidationOutputHeader = ""
+ this.specValidationOutputMessage = ""
+ this.specValidationOutputSummary = ""
+
+ this.spinnerService.show()
+ this.validateJsonStructure()
+ this.specValidator.sendSpecFile(this.compSpecContent, this.type, this.release).subscribe(
+ res => {}, err => {
+ this.setSpecValidationMessage(err)
+ }
+ )
+ }
+
+ setSpecValidationMessage(res){
+ if(res.status === 200){
+ this.specValidationOutputHeader = "Success: Valid Component Spec"
+ this.specValidationOutputMessage = ""
+ this.validCompSpec = true
+ } else {
+ this.specValidationOutputHeader = `${res.status} Error: Invalid Component Spec`
+ this.specValidationOutputSummary = res.error.summary
+
+ for(let item of res.error.errors){
+ this.specValidationOutputMessage += `- ${item}\n\n`
+ }
+
+ this.validCompSpec = false
+ }
+
+ this.specValidated = true;
+ this.spinnerService.hide()
+ }
+
+ validateJsonStructure() {
+ try {
+ JSON.parse(this.compSpecContent);
+ } catch (error) {
+ this.specValidationOutputHeader = "Error: Invalid Component Spec"
+ this.specValidationOutputSummary = "JSON Structure Error"
+ this.specValidationOutputMessage = error
+ this.validCompSpec = false
+ this.specValidated = true
+ this.spinnerService.hide()
+ throw new Error('JSON Structure error, quit!');
+ }
+ }
+
+ downloadSchema(){
+ this.spinnerService.show()
+ this.specValidator.getSchema(this.type).subscribe(
+ res => {
+ this.downloadService.downloadJSON(res, `${this.release}+_${this.type}_Schema`)
+ this.spinnerService.hide()
+ }, err => {
+ console.log(err)
+ this.spinnerService.hide()
+ }
+ )
+ }
+}