Skip to content

Commit

Permalink
feat(engine): add scan modes, external sources, and ip filters list
Browse files Browse the repository at this point in the history
  • Loading branch information
burgerni10 authored and burgerni10 committed Jun 21, 2023
1 parent 0edecb3 commit 18fde83
Show file tree
Hide file tree
Showing 29 changed files with 1,515 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<div class="modal-header">
<h4 class="modal-title" [translate]="'engine.external-source.title-' + mode"></h4>
</div>
<div class="modal-body">
<form [formGroup]="form" (ngSubmit)="save()" id="form">
<!-- Reference -->
<div class="form-group">
<label class="form-label" for="reference" translate="engine.external-source.reference"></label>
<input formControlName="reference" id="reference" class="form-control" />
<val-errors controlName="reference"></val-errors>
</div>
<!-- Description -->
<div class="form-group">
<label class="form-label" for="description" translate="engine.external-source.description"></label>
<textarea formControlName="description" id="description" class="form-control"></textarea>
</div>
</form>
</div>
<div class="modal-footer">
<div class="btn-group">
<oib-save-button [state]="state"></oib-save-button>
<button type="button" class="btn btn-cancel" ngbAutofocus (click)="cancel()" translate="common.cancel" id="cancel-button"></button>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import { EditExternalSourceModalComponent } from './edit-external-source-modal.component';
import { ComponentTester, createMock } from 'ngx-speculoos';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { fakeAsync, TestBed } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { of } from 'rxjs';
import { MockI18nModule } from '../../../i18n/mock-i18n.spec';
import { DefaultValidationErrorsComponent } from '../../components/shared/default-validation-errors/default-validation-errors.component';
import { ExternalSourceService } from '../../services/external-source.service';
import { ExternalSourceCommandDTO, ExternalSourceDTO } from '../../model/external-sources.model';

class EditExternalSourceModalComponentTester extends ComponentTester<EditExternalSourceModalComponent> {
constructor() {
super(EditExternalSourceModalComponent);
}

get reference() {
return this.input('#reference')!;
}

get description() {
return this.textarea('#description')!;
}

get validationErrors() {
return this.elements('val-errors div');
}

get save() {
return this.button('#save-button')!;
}

get cancel() {
return this.button('#cancel-button')!;
}
}

describe('EditExternalSourceModalComponent', () => {
let tester: EditExternalSourceModalComponentTester;
let fakeActiveModal: NgbActiveModal;
let externalSourceService: jasmine.SpyObj<ExternalSourceService>;

beforeEach(() => {
fakeActiveModal = createMock(NgbActiveModal);
externalSourceService = createMock(ExternalSourceService);

TestBed.configureTestingModule({
imports: [
MockI18nModule,
ReactiveFormsModule,
HttpClientTestingModule,
EditExternalSourceModalComponent,
DefaultValidationErrorsComponent
],
providers: [
{ provide: NgbActiveModal, useValue: fakeActiveModal },
{ provide: ExternalSourceService, useValue: externalSourceService }
]
});

TestBed.createComponent(DefaultValidationErrorsComponent).detectChanges();

tester = new EditExternalSourceModalComponentTester();
});

describe('create mode', () => {
beforeEach(() => {
tester.componentInstance.prepareForCreation();
tester.detectChanges();
});

it('should have an empty form', () => {
expect(tester.reference).toHaveValue('');
expect(tester.description).toHaveValue('');
});

it('should not save if invalid', () => {
tester.save.click();

// reference
expect(tester.validationErrors.length).toBe(1);
expect(fakeActiveModal.close).not.toHaveBeenCalled();
});

it('should save if valid', fakeAsync(() => {
tester.reference.fillWith('ref');
tester.description.fillWith('desc');

tester.detectChanges();

const createdExternalSource = {
id: 'id1'
} as ExternalSourceDTO;
externalSourceService.createExternalSource.and.returnValue(of(createdExternalSource));

tester.save.click();

const expectedCommand: ExternalSourceCommandDTO = {
reference: 'ref',
description: 'desc'
};

expect(externalSourceService.createExternalSource).toHaveBeenCalledWith(expectedCommand);
expect(fakeActiveModal.close).toHaveBeenCalledWith(createdExternalSource);
}));

it('should cancel', () => {
tester.cancel.click();
expect(fakeActiveModal.dismiss).toHaveBeenCalled();
});
});

describe('edit mode', () => {
const externalSourceToUpdate: ExternalSourceDTO = {
id: 'id1',
reference: 'ref1',
description: 'My External source 1'
};

beforeEach(() => {
externalSourceService.getExternalSource.and.returnValue(of(externalSourceToUpdate));

tester.componentInstance.prepareForEdition(externalSourceToUpdate);
tester.detectChanges();
});

it('should have a populated form', () => {
expect(tester.reference).toHaveValue(externalSourceToUpdate.reference);
expect(tester.description).toHaveValue(externalSourceToUpdate.description);
});

it('should not save if invalid', () => {
tester.reference.fillWith('');
tester.save.click();

// reference
expect(tester.validationErrors.length).toBe(1);
expect(fakeActiveModal.close).not.toHaveBeenCalled();
});

it('should save if valid', fakeAsync(() => {
externalSourceService.updateExternalSource.and.returnValue(of(undefined));

tester.reference.fillWith('External source 1 (updated)');
tester.description.fillWith('A longer and updated description of my external source');

tester.save.click();

const expectedCommand: ExternalSourceCommandDTO = {
reference: 'External source 1 (updated)',
description: 'A longer and updated description of my external source'
};

expect(externalSourceService.updateExternalSource).toHaveBeenCalledWith('id1', expectedCommand);
expect(externalSourceService.getExternalSource).toHaveBeenCalledWith('id1');
expect(fakeActiveModal.close).toHaveBeenCalledWith(externalSourceToUpdate);
}));

it('should cancel', () => {
tester.cancel.click();
expect(fakeActiveModal.dismiss).toHaveBeenCalled();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { Component } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
import { Observable, switchMap } from 'rxjs';
import { ObservableState, SaveButtonComponent } from '../../components/shared/save-button/save-button.component';
import { ValidationErrorsComponent } from 'ngx-valdemort';
import { TranslateModule } from '@ngx-translate/core';
import { ExternalSourceCommandDTO, ExternalSourceDTO } from '../../model/external-sources.model';
import { ExternalSourceService } from '../../services/external-source.service';

@Component({
selector: 'oib-edit-external-source-modal',
templateUrl: './edit-external-source-modal.component.html',
styleUrls: ['./edit-external-source-modal.component.scss'],
imports: [ReactiveFormsModule, TranslateModule, ValidationErrorsComponent, SaveButtonComponent],
standalone: true
})
export class EditExternalSourceModalComponent {
mode: 'create' | 'edit' = 'create';
state = new ObservableState();
externalSource: ExternalSourceDTO | null = null;
form = this.fb.group({
reference: ['', Validators.required],
description: ''
});

constructor(private modal: NgbActiveModal, private fb: FormBuilder, private externalSourceService: ExternalSourceService) {}

/**
* Prepares the component for creation.
*/
prepareForCreation() {
this.mode = 'create';
}

/**
* Prepares the component for edition.
*/
prepareForEdition(externalSource: ExternalSourceDTO) {
this.mode = 'edit';
this.externalSource = externalSource;

this.form.patchValue({
reference: externalSource.reference,
description: externalSource.description
});
}

cancel() {
this.modal.dismiss();
}

save() {
if (!this.form.valid) {
return;
}

const formValue = this.form.value;

const command: ExternalSourceCommandDTO = {
reference: formValue.reference!,
description: formValue.description!
};

let obs: Observable<ExternalSourceDTO>;
if (this.mode === 'create') {
obs = this.externalSourceService.createExternalSource(command);
} else {
obs = this.externalSourceService
.updateExternalSource(this.externalSource!.id, command)
.pipe(switchMap(() => this.externalSourceService.getExternalSource(this.externalSource!.id)));
}
obs.pipe(this.state.pendingUntilFinalization()).subscribe(externalSource => {
this.modal.close(externalSource);
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<div class="modal-header">
<h4 class="modal-title" [translate]="'engine.ip-filter.title-' + mode"></h4>
</div>
<div class="modal-body">
<form [formGroup]="form" (ngSubmit)="save()" id="form">
<!-- Address -->
<div class="form-group">
<label class="form-label" for="address" translate="engine.ip-filter.address"></label>
<input formControlName="address" id="address" class="form-control" />
<val-errors controlName="address"></val-errors>
</div>
<!-- Description -->
<div class="form-group">
<label class="form-label" for="description" translate="engine.ip-filter.description"></label>
<textarea formControlName="description" id="description" class="form-control"></textarea>
</div>
</form>
</div>
<div class="modal-footer">
<div class="btn-group">
<oib-save-button [state]="state"></oib-save-button>
<button type="button" class="btn btn-cancel" ngbAutofocus (click)="cancel()" translate="common.cancel" id="cancel-button"></button>
</div>
</div>
Empty file.
Loading

0 comments on commit 18fde83

Please sign in to comment.