diff --git a/src/app/shared/resource-policies/form/resource-policy-form.component.spec.ts b/src/app/shared/resource-policies/form/resource-policy-form.component.spec.ts new file mode 100644 index 0000000000..46b80070b1 --- /dev/null +++ b/src/app/shared/resource-policies/form/resource-policy-form.component.spec.ts @@ -0,0 +1,426 @@ +import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing'; +import { ChangeDetectorRef, Component, NO_ERRORS_SCHEMA } from '@angular/core'; +import { BrowserModule, By } from '@angular/platform-browser'; +import { CommonModule } from '@angular/common'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; + +import { getTestScheduler } from 'jasmine-marbles'; +import { of as observableOf } from 'rxjs'; +import { TestScheduler } from 'rxjs/testing'; +import { delay } from 'rxjs/operators'; +import { TranslateModule } from '@ngx-translate/core'; + +import { createSuccessfulRemoteDataObject, createTestComponent } from '../../testing/utils'; +import { EPersonDataService } from '../../../core/eperson/eperson-data.service'; +import { GroupDataService } from '../../../core/eperson/group-data.service'; +import { RequestService } from '../../../core/data/request.service'; +import { getMockRequestService } from '../../mocks/mock-request.service'; +import { PolicyType } from '../../../core/resource-policy/models/policy-type.model'; +import { ActionType } from '../../../core/resource-policy/models/action-type.model'; +import { GroupMock } from '../../testing/group-mock'; +import { ResourcePolicyEvent, ResourcePolicyFormComponent } from './resource-policy-form.component'; +import { FormService } from '../../form/form.service'; +import { getMockFormService } from '../../mocks/mock-form-service'; +import { FormBuilderService } from '../../form/builder/form-builder.service'; +import { EpersonGroupListComponent } from './eperson-group-list/eperson-group-list.component'; +import { FormComponent } from '../../form/form.component'; +import { stringToNgbDateStruct } from '../../date.util'; +import { ResourcePolicy } from '../../../core/resource-policy/models/resource-policy.model'; +import { RESOURCE_POLICY } from '../../../core/resource-policy/models/resource-policy.resource-type'; +import { EPersonMock } from '../../testing/eperson-mock'; + +export const mockResourcePolicyFormData = { + name: [ + { + value: 'name', + language: null, + authority: null, + display: 'name', + confidence: -1, + place: 0, + otherInformation: null + } + ], + description: [ + { + value: 'description', + language: null, + authority: null, + display: 'description', + confidence: -1, + place: 0, + otherInformation: null + } + ], + policyType: [ + { + value: 'TYPE_WORKFLOW', + language: null, + authority: null, + display: 'TYPE_WORKFLOW', + confidence: -1, + place: 0, + otherInformation: null + } + ], + action: [ + { + value: 'WRITE', + language: null, + authority: null, + display: 'WRITE', + confidence: -1, + place: 0, + otherInformation: null + } + ], + date: { + start: [ + { + value: { year: '2019', month: '04', day: '14' }, + language: null, + authority: null, + display: '2019-04-14', + confidence: -1, + place: 0, + otherInformation: null + } + ], + end: [ + { + value: { year: '2020', month: '04', day: '14' }, + language: null, + authority: null, + display: '2020-04-14', + confidence: -1, + place: 0, + otherInformation: null + } + ], + } +}; + +export const submittedResourcePolicy = Object.assign(new ResourcePolicy(), { + name: 'name', + description: 'description', + policyType: PolicyType.TYPE_WORKFLOW, + action: ActionType.WRITE, + startDate: '2019-04-14T00:00:00Z', + endDate: '2020-04-14T00:00:00Z', + type: RESOURCE_POLICY +}); + +describe('ResourcePolicyFormComponent test suite', () => { + let comp: ResourcePolicyFormComponent; + let compAsAny: any; + let fixture: ComponentFixture; + let de; + let scheduler: TestScheduler; + + const resourcePolicy: any = { + id: '1', + name: null, + description: null, + policyType: PolicyType.TYPE_SUBMISSION, + action: ActionType.READ, + startDate: '2019-04-14', + endDate: '2020-04-14', + type: 'resourcepolicy', + uuid: 'resource-policy-1', + _links: { + eperson: { + href: 'https://rest.api/rest/api/eperson' + }, + group: { + href: 'https://rest.api/rest/api/group' + }, + self: { + href: 'https://rest.api/rest/api/resourcepolicies/1' + }, + }, + eperson: observableOf(createSuccessfulRemoteDataObject({})), + group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) + }; + + const epersonService = jasmine.createSpyObj('epersonService', { + findByHref: jasmine.createSpy('findByHref'), + findAll: jasmine.createSpy('findAll') + }); + + const groupService = jasmine.createSpyObj('groupService', { + findByHref: jasmine.createSpy('findByHref'), + findAll: jasmine.createSpy('findAll') + }); + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + BrowserModule, + CommonModule, + FormsModule, + ReactiveFormsModule, + TranslateModule.forRoot() + ], + declarations: [ + FormComponent, + EpersonGroupListComponent, + ResourcePolicyFormComponent, + TestComponent + ], + providers: [ + { provide: EPersonDataService, useValue: epersonService }, + { provide: FormService, useValue: getMockFormService() }, + { provide: GroupDataService, useValue: groupService }, + { provide: RequestService, useValue: getMockRequestService() }, + FormBuilderService, + ChangeDetectorRef, + ResourcePolicyFormComponent + ], + schemas: [ + NO_ERRORS_SCHEMA + ] + }).compileComponents(); + })); + + describe('', () => { + let testComp: TestComponent; + let testFixture: ComponentFixture; + + // synchronous beforeEach + beforeEach(() => { + const html = ` + `; + + testFixture = createTestComponent(html, TestComponent) as ComponentFixture; + testComp = testFixture.componentInstance; + }); + + afterEach(() => { + testFixture.destroy(); + }); + + it('should create ResourcePolicyFormComponent', inject([ResourcePolicyFormComponent], (app: ResourcePolicyFormComponent) => { + + expect(app).toBeDefined(); + + })); + }); + + describe('when resource policy is not provided', () => { + + beforeEach(() => { + // initTestScheduler(); + fixture = TestBed.createComponent(ResourcePolicyFormComponent); + comp = fixture.componentInstance; + compAsAny = fixture.componentInstance; + comp.isProcessing = observableOf(false); + }); + + afterEach(() => { + comp = null; + compAsAny = null; + de = null; + fixture.destroy(); + }); + + it('should init form model properly', () => { + spyOn(compAsAny, 'isFormValid').and.returnValue(observableOf(false)); + spyOn(compAsAny, 'initModelsValue').and.callThrough(); + spyOn(compAsAny, 'buildResourcePolicyForm').and.callThrough(); + fixture.detectChanges(); + + expect(compAsAny.buildResourcePolicyForm).toHaveBeenCalled(); + expect(compAsAny.initModelsValue).toHaveBeenCalled(); + expect(compAsAny.formModel.length).toBe(5); + expect(compAsAny.subs.length).toBe(0); + + }); + + it('should can set grant', () => { + expect(comp.canSetGrant()).toBeTruthy(); + }); + + it('should not have a target name', () => { + expect(comp.getResourcePolicyTargetName()).toBe(''); + }); + + it('should emit reset event', () => { + spyOn(compAsAny.reset, 'emit'); + comp.onReset(); + expect(compAsAny.reset.emit).toHaveBeenCalled(); + }); + + it('should update resource policy grant object properly', () => { + comp.updateObjectSelected(EPersonMock, true); + + expect(comp.resourcePolicyGrant).toEqual(EPersonMock); + expect(comp.resourcePolicyGrantType).toBe('eperson'); + + comp.updateObjectSelected(GroupMock, false); + + expect(comp.resourcePolicyGrant).toEqual(GroupMock); + expect(comp.resourcePolicyGrantType).toBe('group'); + }); + + }); + + describe('when resource policy is provided', () => { + + beforeEach(() => { + // initTestScheduler(); + fixture = TestBed.createComponent(ResourcePolicyFormComponent); + comp = fixture.componentInstance; + compAsAny = fixture.componentInstance; + comp.resourcePolicy = resourcePolicy; + comp.isProcessing = observableOf(false); + compAsAny.ePersonService.findByHref.and.returnValue( + observableOf(createSuccessfulRemoteDataObject({})).pipe(delay(100)) + ); + compAsAny.groupService.findByHref.and.returnValue(observableOf(createSuccessfulRemoteDataObject(GroupMock))); + }); + + afterEach(() => { + comp = null; + compAsAny = null; + de = null; + fixture.destroy(); + }); + + it('should init form model properly', () => { + spyOn(compAsAny, 'isFormValid').and.returnValue(observableOf(false)); + spyOn(compAsAny, 'initModelsValue').and.callThrough(); + spyOn(compAsAny, 'buildResourcePolicyForm').and.callThrough(); + fixture.detectChanges(); + + expect(compAsAny.buildResourcePolicyForm).toHaveBeenCalled(); + expect(compAsAny.initModelsValue).toHaveBeenCalled(); + expect(compAsAny.formModel.length).toBe(5); + expect(compAsAny.subs.length).toBe(1); + expect(compAsAny.formModel[2].value).toBe('TYPE_SUBMISSION'); + expect(compAsAny.formModel[3].value).toBe('READ'); + expect(compAsAny.formModel[4].get(0).value).toEqual(stringToNgbDateStruct('2019-04-14')); + expect(compAsAny.formModel[4].get(1).value).toEqual(stringToNgbDateStruct('2020-04-14')); + + }); + + it('should init resourcePolicyGrant properly', () => { + compAsAny.isActive = true; + + scheduler = getTestScheduler(); + scheduler.schedule(() => comp.ngOnInit()); + scheduler.flush(); + + expect(compAsAny.resourcePolicyGrant).toEqual(GroupMock); + }); + + it('should not can set grant', () => { + expect(comp.canSetGrant()).toBeFalsy(); + }); + + it('should have a target name', () => { + compAsAny.resourcePolicyGrant = GroupMock; + + expect(comp.getResourcePolicyTargetName()).toBe('testgroupname'); + }); + + }); + + describe('when form is valid', () => { + beforeEach(() => { + + fixture = TestBed.createComponent(ResourcePolicyFormComponent); + comp = fixture.componentInstance; + compAsAny = comp; + comp.resourcePolicy = resourcePolicy; + comp.isProcessing = observableOf(false); + compAsAny.ePersonService.findByHref.and.returnValue( + observableOf(createSuccessfulRemoteDataObject({})).pipe(delay(100)) + ); + compAsAny.groupService.findByHref.and.returnValue(observableOf(createSuccessfulRemoteDataObject(GroupMock))); + compAsAny.formService.isValid.and.returnValue(observableOf(true)); + compAsAny.isActive = true; + comp.resourcePolicyGrant = GroupMock; + comp.resourcePolicyGrantType = 'group'; + fixture.detectChanges(); + }); + + afterEach(() => { + comp = null; + compAsAny = null; + de = null; + fixture.destroy(); + }); + + it('should not have submit button disabled when submission is valid', () => { + + const depositBtn: any = fixture.debugElement.query(By.css('.btn-primary')); + + expect(depositBtn.nativeElement.disabled).toBeFalsy(); + }); + + it('should emit submit event', () => { + spyOn(compAsAny.submit, 'emit'); + spyOn(compAsAny, 'createResourcePolicyByFormData').and.callThrough(); + compAsAny.formService.getFormData.and.returnValue(observableOf(mockResourcePolicyFormData)); + const eventPayload: ResourcePolicyEvent = Object.create({}); + eventPayload.object = submittedResourcePolicy; + eventPayload.target = { + type: 'group', + uuid: GroupMock.id + }; + + scheduler = getTestScheduler(); + scheduler.schedule(() => comp.onSubmit()); + + scheduler.flush(); + + expect(compAsAny.submit.emit).toHaveBeenCalledWith(eventPayload); + expect(compAsAny.createResourcePolicyByFormData).toHaveBeenCalled(); + }); + + }); + + describe('when form is not valid', () => { + beforeEach(() => { + + fixture = TestBed.createComponent(ResourcePolicyFormComponent); + comp = fixture.componentInstance; + compAsAny = comp; + comp.resourcePolicy = resourcePolicy; + comp.isProcessing = observableOf(false); + compAsAny.ePersonService.findByHref.and.returnValue( + observableOf(createSuccessfulRemoteDataObject({})).pipe(delay(100)) + ); + compAsAny.groupService.findByHref.and.returnValue(observableOf(createSuccessfulRemoteDataObject(GroupMock))); + compAsAny.formService.isValid.and.returnValue(observableOf(false)); + compAsAny.isActive = true; + fixture.detectChanges(); + }); + + afterEach(() => { + comp = null; + compAsAny = null; + de = null; + fixture.destroy(); + }); + + it('should have submit button disabled when submission is valid', () => { + + const depositBtn: any = fixture.debugElement.query(By.css('.btn-primary')); + + expect(depositBtn.nativeElement.disabled).toBeTruthy(); + }); + + }); +}); + +// declare a test component +@Component({ + selector: 'ds-test-cmp', + template: `` +}) +class TestComponent { + + resourcePolicy = null; + isProcessing = observableOf(false); +}