mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-05-15 15:02:49 +00:00
Unit tests for confirmation dialog component added
This commit is contained in:
parent
cc401a584d
commit
606b7fa01c
@ -1,9 +1,7 @@
|
|||||||
<span>
|
<span>{{confirmationMessage}}</span>
|
||||||
{{confirmationMessage}}
|
|
||||||
</span>
|
|
||||||
<div class="buttons-bar" *ngIf="!isOpen">
|
<div class="buttons-bar" *ngIf="!isOpen">
|
||||||
<button mat-button (click)="onNoClick()" color="accent">No</button>
|
<button mat-button class="cancelButton" (click)="onNoClick()" color="accent">No</button>
|
||||||
<button mat-button (click)="onYesClick()" tabindex="2" mat-raised-button color="primary">Yes</button>
|
<button mat-button class="confirmButton" (click)="onYesClick()" tabindex="2" mat-raised-button color="primary">Yes</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons-bar" *ngIf="isOpen">
|
<div class="buttons-bar" *ngIf="isOpen">
|
||||||
<button mat-button (click)="onNoClick()" color="accent">Ok</button>
|
<button mat-button (click)="onNoClick()" color="accent">Ok</button>
|
||||||
|
@ -0,0 +1,131 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { MatDialogModule, MatDialog } from "@angular/material";
|
||||||
|
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
||||||
|
import { Component, NgModule } from '@angular/core';
|
||||||
|
import { Project } from '../../../../models/project';
|
||||||
|
import { ImportProjectConfirmationDialogComponent } from './import-project-confirmation-dialog.component';
|
||||||
|
import { OverlayContainer } from '@angular/cdk/overlay';
|
||||||
|
|
||||||
|
describe('ImportProjectConfirmationDialogComponent', () => {
|
||||||
|
let dialog: MatDialog;
|
||||||
|
let overlayContainerElement: HTMLElement;
|
||||||
|
|
||||||
|
let noop: ComponentFixture<NoopComponent>;
|
||||||
|
let existingProject: Project = {
|
||||||
|
auto_close: false,
|
||||||
|
auto_open: false,
|
||||||
|
auto_start: false,
|
||||||
|
filename: "blank",
|
||||||
|
name: "blank",
|
||||||
|
path: "",
|
||||||
|
project_id: "",
|
||||||
|
scene_height: 100,
|
||||||
|
scene_width: 100,
|
||||||
|
status: "",
|
||||||
|
readonly: false,
|
||||||
|
show_interface_labels: false,
|
||||||
|
show_layers: false,
|
||||||
|
show_grid: false,
|
||||||
|
snap_to_grid: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [ DialogTestModule ],
|
||||||
|
providers: [
|
||||||
|
{ provide: OverlayContainer, useFactory: () => {
|
||||||
|
overlayContainerElement = document.createElement('div');
|
||||||
|
return { getContainerElement: () => overlayContainerElement };
|
||||||
|
}}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog = TestBed.get(MatDialog);
|
||||||
|
|
||||||
|
noop = TestBed.createComponent(NoopComponent);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show correct message if project is open', () => {
|
||||||
|
existingProject.status = "opened";
|
||||||
|
const config = {
|
||||||
|
data: {
|
||||||
|
'existingProject' : existingProject
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.open(ImportProjectConfirmationDialogComponent, config);
|
||||||
|
noop.detectChanges();
|
||||||
|
|
||||||
|
const message = overlayContainerElement.querySelector('span');
|
||||||
|
expect(message.textContent).toBe("Project blank is open. You can not overwrite it.");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show correct message if project is closed', () => {
|
||||||
|
existingProject.status = "closed";
|
||||||
|
const config = {
|
||||||
|
data: {
|
||||||
|
'existingProject' : existingProject
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.open(ImportProjectConfirmationDialogComponent, config);
|
||||||
|
noop.detectChanges();
|
||||||
|
|
||||||
|
const message = overlayContainerElement.querySelector('span');
|
||||||
|
expect(message.textContent).toBe("Project blank already exist, overwrite it?");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false after closing when project is open', () => {
|
||||||
|
existingProject.status = "opened";
|
||||||
|
const config = {
|
||||||
|
data: {
|
||||||
|
'existingProject' : existingProject
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let dialogRef = dialog.open(ImportProjectConfirmationDialogComponent, config);
|
||||||
|
noop.detectChanges();
|
||||||
|
const button = overlayContainerElement.querySelector('button');
|
||||||
|
spyOn(dialogRef.componentInstance.dialogRef, 'close');
|
||||||
|
button.click();
|
||||||
|
|
||||||
|
expect(dialogRef.componentInstance.dialogRef.close).toHaveBeenCalledWith(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true after choosing overriding', () => {
|
||||||
|
existingProject.status = "closed";
|
||||||
|
const config = {
|
||||||
|
data: {
|
||||||
|
'existingProject' : existingProject
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let dialogRef = dialog.open(ImportProjectConfirmationDialogComponent, config);
|
||||||
|
noop.detectChanges();
|
||||||
|
const button: HTMLButtonElement = overlayContainerElement.querySelector('.confirmButton');
|
||||||
|
spyOn(dialogRef.componentInstance.dialogRef, 'close');
|
||||||
|
button.click();
|
||||||
|
|
||||||
|
expect(dialogRef.componentInstance.dialogRef.close).toHaveBeenCalledWith(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
template: ''
|
||||||
|
})
|
||||||
|
class NoopComponent {}
|
||||||
|
|
||||||
|
const TEST_DIRECTIVES = [
|
||||||
|
ImportProjectConfirmationDialogComponent,
|
||||||
|
NoopComponent
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [MatDialogModule, NoopAnimationsModule],
|
||||||
|
exports: TEST_DIRECTIVES,
|
||||||
|
declarations: TEST_DIRECTIVES,
|
||||||
|
entryComponents: [
|
||||||
|
ImportProjectConfirmationDialogComponent
|
||||||
|
],
|
||||||
|
})
|
||||||
|
class DialogTestModule { }
|
@ -4,10 +4,37 @@ import { Server } from "../../../models/server";
|
|||||||
import { MatInputModule, MatIconModule, MatSortModule, MatTableModule, MatTooltipModule, MatDialogModule, MatStepperModule, MatFormFieldModule, MatDialogRef, MatDialog, MAT_DIALOG_DATA } from "@angular/material";
|
import { MatInputModule, MatIconModule, MatSortModule, MatTableModule, MatTooltipModule, MatDialogModule, MatStepperModule, MatFormFieldModule, MatDialogRef, MatDialog, MAT_DIALOG_DATA } from "@angular/material";
|
||||||
import { RouterTestingModule } from "@angular/router/testing";
|
import { RouterTestingModule } from "@angular/router/testing";
|
||||||
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
import { NoopAnimationsModule } from "@angular/platform-browser/animations";
|
||||||
import { FileUploadModule, FileSelectDirective, FileItem, FileUploader } from "ng2-file-upload";
|
import { FileUploadModule, FileSelectDirective, FileItem, FileUploader, ParsedResponseHeaders } from "ng2-file-upload";
|
||||||
import { FormsModule, ReactiveFormsModule, FormBuilder, FormControl, Validators } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule, FormBuilder, FormControl, Validators } from '@angular/forms';
|
||||||
import { DebugElement } from '@angular/core';
|
import { DebugElement } from '@angular/core';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { ProjectService } from '../../../services/project.service';
|
||||||
|
import { of } from 'rxjs/internal/observable/of';
|
||||||
|
import { Project } from '../../../models/project';
|
||||||
|
|
||||||
|
export class MockedProjectService {
|
||||||
|
public projects: Project[] = [{
|
||||||
|
auto_close: false,
|
||||||
|
auto_open: false,
|
||||||
|
auto_start: false,
|
||||||
|
filename: "blank",
|
||||||
|
name: "blank",
|
||||||
|
path: "",
|
||||||
|
project_id: "",
|
||||||
|
scene_height: 100,
|
||||||
|
scene_width: 100,
|
||||||
|
status: "opened",
|
||||||
|
readonly: false,
|
||||||
|
show_interface_labels: false,
|
||||||
|
show_layers: false,
|
||||||
|
show_grid: false,
|
||||||
|
snap_to_grid: false,
|
||||||
|
}];
|
||||||
|
|
||||||
|
list(server: Server) {
|
||||||
|
return of(this.projects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
describe('ImportProjectDialogComponent', () => {
|
describe('ImportProjectDialogComponent', () => {
|
||||||
let component: ImportProjectDialogComponent;
|
let component: ImportProjectDialogComponent;
|
||||||
@ -36,7 +63,8 @@ describe('ImportProjectDialogComponent', () => {
|
|||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: MatDialogRef },
|
{ provide: MatDialogRef },
|
||||||
{ provide: MAT_DIALOG_DATA }
|
{ provide: MAT_DIALOG_DATA },
|
||||||
|
{ provide: ProjectService, useClass: MockedProjectService}
|
||||||
],
|
],
|
||||||
declarations : [ImportProjectDialogComponent]
|
declarations : [ImportProjectDialogComponent]
|
||||||
})
|
})
|
||||||
@ -61,6 +89,7 @@ describe('ImportProjectDialogComponent', () => {
|
|||||||
|
|
||||||
debugElement = fixture.debugElement.query(By.directive(FileSelectDirective));
|
debugElement = fixture.debugElement.query(By.directive(FileSelectDirective));
|
||||||
fileSelectDirective = debugElement.injector.get(FileSelectDirective) as FileSelectDirective;
|
fileSelectDirective = debugElement.injector.get(FileSelectDirective) as FileSelectDirective;
|
||||||
|
component.uploader.onErrorItem = (item: FileItem, response: string, status: number, headers: ParsedResponseHeaders) => {};
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be created', () => {
|
it('should be created', () => {
|
||||||
@ -134,6 +163,7 @@ describe('ImportProjectDialogComponent', () => {
|
|||||||
it('should navigate to next step after clicking import', () => {
|
it('should navigate to next step after clicking import', () => {
|
||||||
let fileItem = new FileItem(fileSelectDirective.uploader, new File([],"fileName"),{});
|
let fileItem = new FileItem(fileSelectDirective.uploader, new File([],"fileName"),{});
|
||||||
fileSelectDirective.uploader.queue.push(fileItem);
|
fileSelectDirective.uploader.queue.push(fileItem);
|
||||||
|
|
||||||
spyOn(component.stepper, "next");
|
spyOn(component.stepper, "next");
|
||||||
|
|
||||||
component.onImportClick();
|
component.onImportClick();
|
||||||
@ -166,4 +196,13 @@ describe('ImportProjectDialogComponent', () => {
|
|||||||
expect(fileSelectDirective.uploader.uploadItem).not.toHaveBeenCalled();
|
expect(fileSelectDirective.uploader.uploadItem).not.toHaveBeenCalled();
|
||||||
expect(component.projectNameForm.valid).toBeFalsy();
|
expect(component.projectNameForm.valid).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should open confirmation dialog if project with the same exists', () => {
|
||||||
|
component.projectNameForm.controls['projectName'].setValue("blank");
|
||||||
|
spyOn(component, "openConfirmationDialog");
|
||||||
|
|
||||||
|
component.onImportClick();
|
||||||
|
|
||||||
|
expect(component.openConfirmationDialog).toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
import { Component, OnInit, Inject, ViewChild } from '@angular/core';
|
import { Component, OnInit, Inject, ViewChild } from '@angular/core';
|
||||||
import { MatStepper, MatDialogRef, MAT_DIALOG_DATA } from "@angular/material";
|
import { MatStepper, MatDialogRef, MAT_DIALOG_DATA, MatDialog } from "@angular/material";
|
||||||
import { FileUploader, ParsedResponseHeaders, FileItem } from 'ng2-file-upload';
|
import { FileUploader, ParsedResponseHeaders, FileItem } from 'ng2-file-upload';
|
||||||
import { Server } from '../../../models/server';
|
import { Server } from '../../../models/server';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
|
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
|
||||||
|
import { ProjectService } from '../../../services/project.service';
|
||||||
|
import { Project } from '../../../models/project';
|
||||||
|
import { ImportProjectConfirmationDialogComponent } from './import-project-confirmation-dialog/import-project-confirmation-dialog.component';
|
||||||
|
import { ServerResponse } from '../../../models/serverResponse';
|
||||||
|
|
||||||
export class Validator {
|
export class Validator {
|
||||||
static projectNameValidator(projectName) {
|
static projectNameValidator(projectName) {
|
||||||
@ -34,9 +38,11 @@ export class ImportProjectDialogComponent implements OnInit {
|
|||||||
@ViewChild('stepper') stepper: MatStepper;
|
@ViewChild('stepper') stepper: MatStepper;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private dialog: MatDialog,
|
||||||
public dialogRef: MatDialogRef<ImportProjectDialogComponent>,
|
public dialogRef: MatDialogRef<ImportProjectDialogComponent>,
|
||||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
private formBuilder: FormBuilder){
|
private formBuilder: FormBuilder,
|
||||||
|
private projectService: ProjectService){
|
||||||
this.projectNameForm = this.formBuilder.group({
|
this.projectNameForm = this.formBuilder.group({
|
||||||
projectName: new FormControl(null, [Validators.required, Validator.projectNameValidator])
|
projectName: new FormControl(null, [Validators.required, Validator.projectNameValidator])
|
||||||
});
|
});
|
||||||
@ -45,6 +51,17 @@ export class ImportProjectDialogComponent implements OnInit {
|
|||||||
ngOnInit(){
|
ngOnInit(){
|
||||||
this.uploader = new FileUploader({});
|
this.uploader = new FileUploader({});
|
||||||
this.uploader.onAfterAddingFile = (file) => { file.withCredentials = false; };
|
this.uploader.onAfterAddingFile = (file) => { file.withCredentials = false; };
|
||||||
|
|
||||||
|
this.uploader.onErrorItem = (item: FileItem, response: string, status: number, headers: ParsedResponseHeaders) => {
|
||||||
|
let serverResponse : ServerResponse = JSON.parse(response);
|
||||||
|
this.resultMessage = "An error occured: " + serverResponse.message;
|
||||||
|
this.isFinishEnabled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.uploader.onCompleteItem = (item: FileItem, response: string, status: number, headers: ParsedResponseHeaders) => {
|
||||||
|
this.resultMessage = "Project was imported succesfully!";
|
||||||
|
this.isFinishEnabled = true;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
get form() {
|
get form() {
|
||||||
@ -60,6 +77,22 @@ export class ImportProjectDialogComponent implements OnInit {
|
|||||||
if (this.projectNameForm.invalid){
|
if (this.projectNameForm.invalid){
|
||||||
this.submitted = true;
|
this.submitted = true;
|
||||||
} else {
|
} else {
|
||||||
|
this.projectService
|
||||||
|
.list(this.server)
|
||||||
|
.subscribe((projects: Project[]) => {
|
||||||
|
const projectName = this.projectNameForm.controls['projectName'].value;
|
||||||
|
let existingProject = projects.find(project => project.name === projectName);
|
||||||
|
|
||||||
|
if (existingProject){
|
||||||
|
this.openConfirmationDialog(existingProject);
|
||||||
|
} else {
|
||||||
|
this.importProject();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
importProject(){
|
||||||
const url = this.prepareUploadPath();
|
const url = this.prepareUploadPath();
|
||||||
this.uploader.queue.forEach(elem => elem.url = url);
|
this.uploader.queue.forEach(elem => elem.url = url);
|
||||||
|
|
||||||
@ -68,17 +101,26 @@ export class ImportProjectDialogComponent implements OnInit {
|
|||||||
|
|
||||||
const itemToUpload = this.uploader.queue[0];
|
const itemToUpload = this.uploader.queue[0];
|
||||||
this.uploader.uploadItem(itemToUpload);
|
this.uploader.uploadItem(itemToUpload);
|
||||||
|
|
||||||
this.uploader.onErrorItem = (item: FileItem, response: string, status: number, headers: ParsedResponseHeaders) => {
|
|
||||||
this.resultMessage = response;
|
|
||||||
this.isFinishEnabled = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.uploader.onSuccessItem = (item: FileItem, response: string, status: number, headers: ParsedResponseHeaders) => {
|
|
||||||
this.resultMessage = "Project was imported succesfully!";
|
|
||||||
this.isFinishEnabled = true;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openConfirmationDialog(existingProject: Project) {
|
||||||
|
const dialogRef = this.dialog.open(ImportProjectConfirmationDialogComponent, {
|
||||||
|
width: '300px',
|
||||||
|
height: '150px',
|
||||||
|
data: {
|
||||||
|
'existingProject': existingProject
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dialogRef.afterClosed().subscribe((answer: boolean) => {
|
||||||
|
if (answer) {
|
||||||
|
this.projectService.close(this.server, existingProject.project_id).subscribe(() => {
|
||||||
|
this.projectService.delete(this.server, existingProject.project_id).subscribe(() => {
|
||||||
|
this.importProject();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onNoClick() : void{
|
onNoClick() : void{
|
||||||
@ -101,3 +143,4 @@ export class ImportProjectDialogComponent implements OnInit {
|
|||||||
return `http://${this.server.ip}:${this.server.port}/v2/projects/${uuid()}/import?name=${projectName}`;
|
return `http://${this.server.ip}:${this.server.port}/v2/projects/${uuid()}/import?name=${projectName}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user