From 12b3eb839ba63032d715bb4c25ac1a2ce00f492e Mon Sep 17 00:00:00 2001 From: Enea Jahollari Date: Wed, 7 Jun 2023 17:29:05 +0200 Subject: [PATCH] CST-9639: Added and fixed unit tests --- .../access-control-array-form.component.html | 4 +- ...ccess-control-array-form.component.spec.ts | 32 ++- .../access-control-array-form.component.ts | 6 +- ...s-control-form-container.component.spec.ts | 187 ++++++++++++++---- ...access-control-form-container.component.ts | 2 +- 5 files changed, 178 insertions(+), 53 deletions(-) diff --git a/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.html b/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.html index 963ae165e7..efe2259328 100644 --- a/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.html +++ b/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.html @@ -4,7 +4,7 @@ -
+
@@ -91,7 +91,7 @@
diff --git a/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.spec.ts b/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.spec.ts index 88d462ad79..964eb30de2 100644 --- a/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.spec.ts +++ b/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.spec.ts @@ -45,12 +45,14 @@ describe('AccessControlArrayFormComponent', () => { }); it('should remove access control item', () => { - component.removeAccessControlItem(0); - expect(component.form.accessControls.length).toEqual(0); + expect(component.form.accessControls.length).toEqual(1); component.addAccessControlItem(); - component.removeAccessControlItem(0); - expect(component.form.accessControls.length).toEqual(0); + expect(component.form.accessControls.length).toEqual(2); + + const id = component.form.accessControls[0].id; + component.removeAccessControlItem(id); + expect(component.form.accessControls.length).toEqual(1); }); it('should reset form value', () => { @@ -69,7 +71,12 @@ describe('AccessControlArrayFormComponent', () => { it('should display a select dropdown with options', () => { - const selectElement: DebugElement = fixture.debugElement.query(By.css('select#accesscontroloption-0')); + component.enable(); + fixture.detectChanges(); + + const id = component.form.accessControls[0].id; + + const selectElement: DebugElement = fixture.debugElement.query(By.css(`select#accesscontroloption-${id}`)); expect(selectElement).toBeTruthy(); const options = selectElement.nativeElement.querySelectorAll('option'); @@ -81,6 +88,9 @@ describe('AccessControlArrayFormComponent', () => { }); it('should add new access control items when clicking "Add more" button', () => { + component.enable(); + fixture.detectChanges(); + const addButton: DebugElement = fixture.debugElement.query(By.css(`button#add-btn-${component.type}`)); addButton.nativeElement.click(); fixture.detectChanges(); @@ -90,11 +100,17 @@ describe('AccessControlArrayFormComponent', () => { }); it('should remove access control items when clicking remove button', () => { - const removeButton: DebugElement = fixture.debugElement.query(By.css('button.btn-outline-danger')); - removeButton.nativeElement.click(); + component.enable(); + + component.addAccessControlItem('test'); + + fixture.detectChanges(); + + const removeButton: DebugElement[] = fixture.debugElement.queryAll(By.css('button.btn-outline-danger')); + removeButton[1].nativeElement.click(); fixture.detectChanges(); const accessControlItems = fixture.debugElement.queryAll(By.css('.access-control-item')); - expect(accessControlItems.length).toEqual(0); + expect(accessControlItems.length).toEqual(1); }); }); diff --git a/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.ts b/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.ts index f08534e8f9..227de596ff 100644 --- a/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.ts +++ b/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.ts @@ -1,5 +1,5 @@ import {Component, Input, OnInit, ViewChild} from '@angular/core'; -import {NgForm, NgModelGroup} from '@angular/forms'; +import {NgForm} from '@angular/forms'; import {AccessesConditionOption} from '../../../core/config/models/config-accesses-conditions-options.model'; import {dateToISOFormat} from '../../date.util'; @@ -52,9 +52,7 @@ export class AccessControlArrayFormComponent implements OnInit { * @param ngModelGroup * @param index */ - removeAccessControlItem(ngModelGroup: NgModelGroup, id: number) { - this.ngForm.removeFormGroup(ngModelGroup); - + removeAccessControlItem(id: number) { this.form.accessControls = this.form.accessControls.filter(item => item.id !== id); } diff --git a/src/app/shared/access-control-form-container/access-control-form-container.component.spec.ts b/src/app/shared/access-control-form-container/access-control-form-container.component.spec.ts index 66ef20444e..4d02f7a52d 100644 --- a/src/app/shared/access-control-form-container/access-control-form-container.component.spec.ts +++ b/src/app/shared/access-control-form-container/access-control-form-container.component.spec.ts @@ -1,38 +1,149 @@ -// -// describe('AccessControlFormContainerComponent', () => { -// let component: AccessControlFormContainerComponent; -// let fixture: ComponentFixture>; -// -// let bulkAccessConfigDataServiceMock: BulkAccessConfigDataService; -// -// beforeEach(async () => { -// -// bulkAccessConfigDataServiceMock = jasmine.createSpyObj('BulkAccessConfigDataService', { -// findByName: jasmine.createSpy('findByName'), -// }); -// -// -// await TestBed.configureTestingModule({ -// declarations: [ AccessControlFormContainerComponent ], -// imports: [ CommonModule, ReactiveFormsModule, SharedBrowseByModule, TranslateModule, NgbDatepickerModule ], -// providers: [ -// { provide: BulkAccessConfigDataService, useValue: bulkAccessConfigDataServiceMock }, -// // private bulkAccessControlService: BulkAccessControlService, -// // private selectableListService: SelectableListService, -// // protected modalService: NgbModal, -// // private cdr: ChangeDetectorRef -// ] -// }) -// .compileComponents(); -// }); -// -// beforeEach(() => { -// fixture = TestBed.createComponent(AccessControlFormContainerComponent); -// component = fixture.componentInstance; -// fixture.detectChanges(); -// }); -// -// it('should create', () => { -// expect(component).toBeTruthy(); -// }); -// }); +import {ComponentFixture, fakeAsync, TestBed} from '@angular/core/testing'; +import {NgbDatepickerModule, NgbModal, NgbModalRef} from '@ng-bootstrap/ng-bootstrap'; +import {Component} from '@angular/core'; +import {of} from 'rxjs'; +import {AccessControlFormContainerComponent} from './access-control-form-container.component'; +import {BulkAccessControlService} from './bulk-access-control.service'; +import {BulkAccessConfigDataService} from '../../core/config/bulk-access-config-data.service'; +import {Item} from '../../core/shared/item.model'; +import {SelectableListService} from '../object-list/selectable-list/selectable-list.service'; +import {createAccessControlInitialFormState} from './access-control-form-container-intial-state'; +import {CommonModule} from '@angular/common'; +import {SharedBrowseByModule} from '../browse-by/shared-browse-by.module'; +import {TranslateModule} from '@ngx-translate/core'; +import {FormsModule} from '@angular/forms'; +import {UiSwitchModule} from 'ngx-ui-switch'; +import { + ITEM_ACCESS_CONTROL_SELECT_BITSTREAMS_LIST_ID +} from './item-access-control-select-bitstreams-modal/item-access-control-select-bitstreams-modal.component'; +import {AccessControlFormModule} from './access-control-form.module'; + + +describe('AccessControlFormContainerComponent', () => { + let component: AccessControlFormContainerComponent; + let fixture: ComponentFixture>; + + +// Mock NgbModal + @Component({selector: 'ds-ngb-modal', template: ''}) + class MockNgbModalComponent { + } + +// Mock dependencies + const mockBulkAccessControlService = { + createPayloadFile: jasmine.createSpy('createPayloadFile').and.returnValue({file: 'mocked-file'}), + executeScript: jasmine.createSpy('executeScript').and.returnValue(of('success')), + }; + + const mockBulkAccessConfigDataService = { + findByName: jasmine.createSpy('findByName').and.returnValue(of({payload: {options: []}})), + }; + + const mockSelectableListService = { + getSelectableList: jasmine.createSpy('getSelectableList').and.returnValue(of({selection: []})), + deselectAll: jasmine.createSpy('deselectAll'), + }; + + const mockNgbModal = { + open: jasmine.createSpy('open').and.returnValue( + { componentInstance: {}, closed: of({})} as NgbModalRef + ) + }; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [AccessControlFormContainerComponent, MockNgbModalComponent], + imports: [ + CommonModule, + FormsModule, + SharedBrowseByModule, + AccessControlFormModule, + TranslateModule.forRoot(), + NgbDatepickerModule, + UiSwitchModule + ], + providers: [ + {provide: BulkAccessControlService, useValue: mockBulkAccessControlService}, + {provide: BulkAccessConfigDataService, useValue: mockBulkAccessConfigDataService}, + {provide: SelectableListService, useValue: mockSelectableListService}, + {provide: NgbModal, useValue: mockNgbModal}, + ], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(AccessControlFormContainerComponent); + component = fixture.componentInstance; + component.state = createAccessControlInitialFormState(); + fixture.detectChanges(); + }); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + it('should reset the form', fakeAsync(() => { + fixture.detectChanges(); + const resetSpy = spyOn(component.bitstreamAccessCmp, 'reset'); + spyOn(component.itemAccessCmp, 'reset'); + + component.reset(); + + expect(resetSpy).toHaveBeenCalled(); + expect(component.itemAccessCmp.reset).toHaveBeenCalled(); + expect(component.state).toEqual(createAccessControlInitialFormState()); + })); + + it('should submit the form', () => { + const bitstreamAccess = 'bitstreamAccess'; + const itemAccess = 'itemAccess'; + component.bitstreamAccessCmp.getValue = jasmine.createSpy('getValue').and.returnValue(bitstreamAccess); + component.itemAccessCmp.getValue = jasmine.createSpy('getValue').and.returnValue(itemAccess); + component.itemRD = {payload: {uuid: 'item-uuid'}} as any; + + component.submit(); + + expect(mockBulkAccessControlService.createPayloadFile).toHaveBeenCalledWith({ + bitstreamAccess, + itemAccess, + state: createAccessControlInitialFormState(), + }); + expect(mockBulkAccessControlService.executeScript).toHaveBeenCalledWith(['item-uuid'], 'mocked-file'); + }); + + it('should handle the status change for bitstream access', () => { + component.bitstreamAccessCmp.enable = jasmine.createSpy('enable'); + component.bitstreamAccessCmp.disable = jasmine.createSpy('disable'); + + component.handleStatusChange('bitstream', true); + expect(component.bitstreamAccessCmp.enable).toHaveBeenCalled(); + + component.handleStatusChange('bitstream', false); + expect(component.bitstreamAccessCmp.disable).toHaveBeenCalled(); + }); + + it('should handle the status change for item access', () => { + component.itemAccessCmp.enable = jasmine.createSpy('enable'); + component.itemAccessCmp.disable = jasmine.createSpy('disable'); + + component.handleStatusChange('item', true); + expect(component.itemAccessCmp.enable).toHaveBeenCalled(); + + component.handleStatusChange('item', false); + expect(component.itemAccessCmp.disable).toHaveBeenCalled(); + }); + + it('should open the select bitstreams modal', () => { + const modalService = TestBed.inject(NgbModal); + + component.openSelectBitstreamsModal(new Item()); + expect(modalService.open).toHaveBeenCalled(); + }); + + it('should unsubscribe and deselect all on component destroy', () => { + component.ngOnDestroy(); + expect(component.selectableListService.deselectAll).toHaveBeenCalledWith( + ITEM_ACCESS_CONTROL_SELECT_BITSTREAMS_LIST_ID + ); + }); +}); diff --git a/src/app/shared/access-control-form-container/access-control-form-container.component.ts b/src/app/shared/access-control-form-container/access-control-form-container.component.ts index a97859a599..b13943e07a 100644 --- a/src/app/shared/access-control-form-container/access-control-form-container.component.ts +++ b/src/app/shared/access-control-form-container/access-control-form-container.component.ts @@ -58,7 +58,7 @@ export class AccessControlFormContainerComponent impleme constructor( private bulkAccessConfigService: BulkAccessConfigDataService, private bulkAccessControlService: BulkAccessControlService, - private selectableListService: SelectableListService, + public selectableListService: SelectableListService, protected modalService: NgbModal, private cdr: ChangeDetectorRef ) {}