import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { TranslateModule } from '@ngx-translate/core'; import { RouterTestingModule } from '@angular/router/testing'; import { ActivatedRoute, Router } from '@angular/router'; import { of as observableOf } from 'rxjs'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { CollectionSourceComponent } from './collection-source.component'; import { ContentSource, ContentSourceHarvestType } from '../../../core/shared/content-source.model'; import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service'; import { INotification, Notification } from '../../../shared/notifications/models/notification.model'; import { NotificationType } from '../../../shared/notifications/models/notification-type'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { DynamicFormControlModel, DynamicFormService } from '@ng-dynamic-forms/core'; import { hasValue } from '../../../shared/empty.util'; import { UntypedFormControl, UntypedFormGroup } from '@angular/forms'; import { RouterStub } from '../../../shared/testing/router.stub'; import { By } from '@angular/platform-browser'; import { Collection } from '../../../core/shared/collection.model'; import { CollectionDataService } from '../../../core/data/collection-data.service'; import { RequestService } from '../../../core/data/request.service'; import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { FieldUpdate } from '../../../core/data/object-updates/field-update.model'; const infoNotification: INotification = new Notification('id', NotificationType.Info, 'info'); const warningNotification: INotification = new Notification('id', NotificationType.Warning, 'warning'); const successNotification: INotification = new Notification('id', NotificationType.Success, 'success'); const uuid = '29481ed7-ae6b-409a-8c51-34dd347a0ce4'; let date: Date; let contentSource: ContentSource; let fieldUpdate: FieldUpdate; let objectUpdatesService: ObjectUpdatesService; let notificationsService: NotificationsService; let location: Location; let formService: DynamicFormService; let router: any; let collection: Collection; let collectionService: CollectionDataService; let requestService: RequestService; describe('CollectionSourceComponent', () => { let comp: CollectionSourceComponent; let fixture: ComponentFixture; beforeEach(waitForAsync(() => { date = new Date(); contentSource = Object.assign(new ContentSource(), { uuid: uuid, metadataConfigs: [ { id: 'dc', label: 'Simple Dublin Core', nameSpace: 'http://www.openarchives.org/OAI/2.0/oai_dc/' }, { id: 'qdc', label: 'Qualified Dublin Core', nameSpace: 'http://purl.org/dc/terms/' }, { id: 'dim', label: 'DSpace Intermediate Metadata', nameSpace: 'http://www.dspace.org/xmlns/dspace/dim' } ], _links: { self: { href: 'contentsource-selflink' } } }); fieldUpdate = { field: contentSource, changeType: undefined }; objectUpdatesService = jasmine.createSpyObj('objectUpdatesService', { getFieldUpdates: observableOf({ [contentSource.uuid]: fieldUpdate }), saveAddFieldUpdate: {}, discardFieldUpdates: {}, reinstateFieldUpdates: observableOf(true), initialize: {}, getUpdatedFields: observableOf([contentSource]), getLastModified: observableOf(date), hasUpdates: observableOf(true), isReinstatable: observableOf(false), isValidPage: observableOf(true) } ); notificationsService = jasmine.createSpyObj('notificationsService', { info: infoNotification, warning: warningNotification, success: successNotification } ); location = jasmine.createSpyObj('location', ['back']); formService = Object.assign({ createFormGroup: (fModel: DynamicFormControlModel[]) => { const controls = {}; if (hasValue(fModel)) { fModel.forEach((controlModel) => { controls[controlModel.id] = new UntypedFormControl((controlModel as any).value); }); return new UntypedFormGroup(controls); } return undefined; } }); router = Object.assign(new RouterStub(), { url: 'http://test-url.com/test-url' }); collection = Object.assign(new Collection(), { uuid: 'fake-collection-id' }); collectionService = jasmine.createSpyObj('collectionService', { getContentSource: createSuccessfulRemoteDataObject$(contentSource), updateContentSource: observableOf(contentSource), getHarvesterEndpoint: observableOf('harvester-endpoint') }); requestService = jasmine.createSpyObj('requestService', ['removeByHrefSubstring', 'setStaleByHrefSubstring']); TestBed.configureTestingModule({ imports: [TranslateModule.forRoot(), RouterTestingModule], declarations: [CollectionSourceComponent], providers: [ { provide: ObjectUpdatesService, useValue: objectUpdatesService }, { provide: NotificationsService, useValue: notificationsService }, { provide: Location, useValue: location }, { provide: DynamicFormService, useValue: formService }, { provide: ActivatedRoute, useValue: { parent: { data: observableOf({ dso: createSuccessfulRemoteDataObject(collection) }) } } }, { provide: Router, useValue: router }, { provide: CollectionDataService, useValue: collectionService }, { provide: RequestService, useValue: requestService } ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(CollectionSourceComponent); comp = fixture.componentInstance; fixture.detectChanges(); }); describe('on startup', () => { let form; beforeEach(() => { form = fixture.debugElement.query(By.css('ds-form')); }); it('ContentSource should be disabled', () => { expect(comp.contentSource.harvestType).toEqual(ContentSourceHarvestType.None); }); it('the input-form should be hidden', () => { expect(form).toBeNull(); }); }); describe('when selecting the checkbox', () => { let input; let form; beforeEach(() => { input = fixture.debugElement.query(By.css('#externalSourceCheck')).nativeElement; input.click(); fixture.detectChanges(); form = fixture.debugElement.query(By.css('ds-form')); }); it('should enable ContentSource', () => { expect(comp.contentSource.harvestType).not.toEqual(ContentSourceHarvestType.None); }); it('should send a field update', () => { expect(objectUpdatesService.saveAddFieldUpdate).toHaveBeenCalledWith(router.url, comp.contentSource); }); it('should display the form', () => { expect(form).not.toBeNull(); }); }); describe('isValid', () => { it('should return true when ContentSource is disabled but the form invalid', () => { spyOnProperty(comp.formGroup, 'valid').and.returnValue(false); comp.contentSource.harvestType = ContentSourceHarvestType.None; expect(comp.isValid()).toBe(true); }); it('should return false when ContentSource is enabled but the form is invalid', () => { spyOnProperty(comp.formGroup, 'valid').and.returnValue(false); comp.contentSource.harvestType = ContentSourceHarvestType.Metadata; expect(comp.isValid()).toBe(false); }); it('should return true when ContentSource is enabled and the form is valid', () => { spyOnProperty(comp.formGroup, 'valid').and.returnValue(true); comp.contentSource.harvestType = ContentSourceHarvestType.Metadata; expect(comp.isValid()).toBe(true); }); }); describe('onSubmit', () => { beforeEach(() => { comp.onSubmit(); }); it('should re-initialize the field updates', () => { expect(objectUpdatesService.initialize).toHaveBeenCalled(); }); it('should display a success notification', () => { expect(notificationsService.success).toHaveBeenCalled(); }); it('should call updateContentSource on the collectionService', () => { expect(collectionService.updateContentSource).toHaveBeenCalled(); }); }); });