import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { ComponentFixture, inject, TestBed, waitForAsync } from '@angular/core/testing'; import { of as observableOf } from 'rxjs'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { Store } from '@ngrx/store'; import { SubmissionServiceStub } from '../../../shared/testing/submission-service.stub'; import { mockSectionsData, mockSubmissionCollectionId, mockSubmissionId, mockSubmissionObject, mockUploadResponse1ParsedErrors, mockUploadResponse2Errors, mockUploadResponse2ParsedErrors } from '../../../shared/mocks/submission.mock'; import { SubmissionService } from '../../submission.service'; import { SectionsServiceStub } from '../../../shared/testing/sections-service.stub'; import { SectionsService } from '../../sections/sections.service'; import { SubmissionUploadFilesComponent } from './submission-upload-files.component'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub'; import { getMockTranslateService } from '../../../shared/mocks/translate.service.mock'; import { cold, hot } from 'jasmine-marbles'; import { SubmissionJsonPatchOperationsServiceStub } from '../../../shared/testing/submission-json-patch-operations-service.stub'; import { SubmissionJsonPatchOperationsService } from '../../../core/submission/submission-json-patch-operations.service'; import { SharedModule } from '../../../shared/shared.module'; import { createTestComponent } from '../../../shared/testing/utils.test'; import { UploaderOptions } from '../../../shared/uploader/uploader-options.model'; describe('SubmissionUploadFilesComponent Component', () => { let comp: SubmissionUploadFilesComponent; let compAsAny: any; let fixture: ComponentFixture<SubmissionUploadFilesComponent>; let submissionServiceStub: SubmissionServiceStub; let sectionsServiceStub: SectionsServiceStub; let notificationsServiceStub: NotificationsServiceStub; let translateService: any; const submissionJsonPatchOperationsServiceStub = new SubmissionJsonPatchOperationsServiceStub(); const submissionId = mockSubmissionId; const collectionId = mockSubmissionCollectionId; const uploadRestResponse: any = mockSubmissionObject; const store: any = jasmine.createSpyObj('store', { dispatch: jasmine.createSpy('dispatch'), select: jasmine.createSpy('select') }); beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [ SharedModule, TranslateModule.forRoot() ], declarations: [ SubmissionUploadFilesComponent, TestComponent ], providers: [ { provide: NotificationsService, useClass: NotificationsServiceStub }, { provide: SubmissionService, useClass: SubmissionServiceStub }, { provide: SectionsService, useClass: SectionsServiceStub }, { provide: TranslateService, useValue: getMockTranslateService() }, { provide: SubmissionJsonPatchOperationsService, useValue: submissionJsonPatchOperationsServiceStub }, { provide: Store, useValue: store }, ChangeDetectorRef, SubmissionUploadFilesComponent ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }).compileComponents(); })); describe('', () => { let testComp: TestComponent; let testFixture: ComponentFixture<TestComponent>; // synchronous beforeEach beforeEach(() => { const html = ` <ds-submission-upload-files [submissionId]="submissionId" [collectionId]="collectionId" [uploadFilesOptions]="uploadFilesOptions"></ds-submission-upload-files>`; testFixture = createTestComponent(html, TestComponent) as ComponentFixture<TestComponent>; testComp = testFixture.componentInstance; }); afterEach(() => { testFixture.destroy(); }); it('should create SubmissionUploadFilesComponent', inject([SubmissionUploadFilesComponent], (app: SubmissionUploadFilesComponent) => { expect(app).toBeDefined(); })); }); describe('', () => { beforeEach(() => { fixture = TestBed.createComponent(SubmissionUploadFilesComponent); comp = fixture.componentInstance; compAsAny = comp; submissionServiceStub = TestBed.inject(SubmissionService as any); sectionsServiceStub = TestBed.inject(SectionsService as any); sectionsServiceStub.isSectionTypeAvailable.and.returnValue(observableOf(true)); notificationsServiceStub = TestBed.inject(NotificationsService as any); translateService = TestBed.inject(TranslateService); comp.submissionId = submissionId; comp.collectionId = collectionId; comp.uploadFilesOptions = Object.assign(new UploaderOptions(),{ url: '', authToken: null, disableMultipart: false, itemAlias: null }); }); afterEach(() => { comp = null; compAsAny = null; fixture = null; submissionServiceStub = null; sectionsServiceStub = null; notificationsServiceStub = null; translateService = null; }); it('should init uploadEnabled properly', () => { sectionsServiceStub.isSectionTypeAvailable.and.returnValue(hot('-a-b', { a: false, b: true })); const expected = cold('-c-d', { c: false, d: true }); comp.ngOnChanges(); fixture.detectChanges(); expect(compAsAny.uploadEnabled).toBeObservable(expected); }); describe('on upload complete', () => { beforeEach(() => { sectionsServiceStub.isSectionType.and.callFake((_, sectionId, __) => observableOf(sectionId === 'upload')); compAsAny.uploadEnabled = observableOf(true); }); it('should show a success notification and call updateSectionData if successful', () => { const expectedErrors: any = mockUploadResponse1ParsedErrors; fixture.detectChanges(); comp.onCompleteItem(Object.assign({}, uploadRestResponse, { sections: mockSectionsData })); Object.keys(mockSectionsData).forEach((sectionId) => { expect(sectionsServiceStub.updateSectionData).toHaveBeenCalledWith( submissionId, sectionId, mockSectionsData[sectionId], expectedErrors[sectionId], expectedErrors[sectionId] ); }); expect(notificationsServiceStub.success).toHaveBeenCalled(); }); it('should show an error notification and call updateSectionData if unsuccessful', () => { const responseErrors = mockUploadResponse2Errors; const expectedErrors: any = mockUploadResponse2ParsedErrors; fixture.detectChanges(); comp.onCompleteItem(Object.assign({}, uploadRestResponse, { sections: mockSectionsData, errors: responseErrors.errors })); Object.keys(mockSectionsData).forEach((sectionId) => { expect(sectionsServiceStub.updateSectionData).toHaveBeenCalledWith( submissionId, sectionId, mockSectionsData[sectionId], expectedErrors[sectionId], expectedErrors[sectionId] ); }); expect(notificationsServiceStub.success).not.toHaveBeenCalled(); }); }); }); }); // declare a test component @Component({ selector: 'ds-test-cmp', template: `` }) class TestComponent { submissionId = mockSubmissionId; collectionId = mockSubmissionCollectionId; uploadFilesOptions = Object.assign(new UploaderOptions(), { url: '', authToken: null, disableMultipart: false, itemAlias: null }); }