From 49aee1898bcae93b2ee5f5f5c17e135ddbc45b0c Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Tue, 2 Apr 2019 16:25:50 +0200 Subject: [PATCH] Added tests and comments --- ...-dspace-result-detail-element.component.ts | 14 +- .../object-detail.component.spec.ts | 181 ++++++++++++++++++ .../object-detail/object-detail.component.ts | 52 ++++- .../wrapper-detail-element.component.spec.ts | 24 ++- .../wrapper-detail-element.component.ts | 22 +++ ...my-dspace-result-list-element.component.ts | 15 +- .../object-list/object-list.component.spec.ts | 2 +- .../shared/pagination/pagination.component.ts | 2 +- 8 files changed, 290 insertions(+), 22 deletions(-) diff --git a/src/app/shared/object-detail/my-dspace-result-detail-element/my-dspace-result-detail-element.component.ts b/src/app/shared/object-detail/my-dspace-result-detail-element/my-dspace-result-detail-element.component.ts index 3efb668c5a..4017026396 100644 --- a/src/app/shared/object-detail/my-dspace-result-detail-element/my-dspace-result-detail-element.component.ts +++ b/src/app/shared/object-detail/my-dspace-result-detail-element/my-dspace-result-detail-element.component.ts @@ -10,12 +10,20 @@ import { Metadata } from '../../../core/shared/metadata.utils'; selector: 'ds-my-dspace-result-detail-element', template: `` }) - export class MyDSpaceResultDetailElementComponent, K extends DSpaceObject> extends AbstractListableElementComponent { + + /** + * The result element object + */ dso: K; - public constructor(@Inject('objectElementProvider') public gridable: ListableObject) { - super(gridable); + /** + * Initialize instance variables + * + * @param {ListableObject} detailable + */ + public constructor(@Inject('objectElementProvider') public detailable: ListableObject) { + super(detailable); this.dso = this.object.dspaceObject; } diff --git a/src/app/shared/object-detail/object-detail.component.spec.ts b/src/app/shared/object-detail/object-detail.component.spec.ts index e69de29bb2..9b81f1019f 100644 --- a/src/app/shared/object-detail/object-detail.component.spec.ts +++ b/src/app/shared/object-detail/object-detail.component.spec.ts @@ -0,0 +1,181 @@ +import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; +import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; +import { By } from '@angular/platform-browser'; +import { ObjectDetailComponent } from './object-detail.component'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { MockTranslateLoader } from '../mocks/mock-translate-loader'; +import { RemoteData } from '../../core/data/remote-data'; +import { PaginatedList } from '../../core/data/paginated-list'; +import { PageInfo } from '../../core/shared/page-info.model'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; + +describe('ObjectDetailComponent', () => { + let comp: ObjectDetailComponent; + let fixture: ComponentFixture; + const testEvent = {test: 'test'}; + + const testObjects = [ + { one: 1 }, + { two: 2 }, + { three: 3 }, + { four: 4 }, + { five: 5 }, + { six: 6 }, + { seven: 7 }, + { eight: 8 }, + { nine: 9 }, + { ten: 10 } + ]; + const pageInfo = Object.assign(new PageInfo(), {elementsPerPage: 1, totalElements: 10, totalPages: 10, currentPage: 1}) + const mockRD = new RemoteData(false, false, true, null, new PaginatedList(pageInfo, testObjects)); + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + NoopAnimationsModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: MockTranslateLoader + } + }) + ], + declarations: [ObjectDetailComponent], + schemas: [NO_ERRORS_SCHEMA] + }).overrideComponent(ObjectDetailComponent, { + set: { changeDetection: ChangeDetectionStrategy.Default } + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ObjectDetailComponent); + comp = fixture.componentInstance; // SearchPageComponent test instance + comp.objects = mockRD; + fixture.detectChanges(); + }); + + describe('when the pageChange output on the pagination is triggered', () => { + beforeEach(() => { + spyOn(comp, 'onPageChange'); + const paginationEl = fixture.debugElement.query(By.css('ds-pagination')); + paginationEl.triggerEventHandler('pageChange', testEvent); + }); + + it('should call onPageChange on the component', () => { + expect(comp.onPageChange).toHaveBeenCalledWith(testEvent); + }); + }); + + describe('when the pageSizeChange output on the pagination is triggered', () => { + beforeEach(() => { + spyOn(comp, 'onPageSizeChange'); + const paginationEl = fixture.debugElement.query(By.css('ds-pagination')); + paginationEl.triggerEventHandler('pageSizeChange', testEvent); + }); + + it('should call onPageSizeChange on the component', () => { + expect(comp.onPageSizeChange).toHaveBeenCalledWith(testEvent); + }); + }); + + describe('when the sortDirectionChange output on the pagination is triggered', () => { + beforeEach(() => { + spyOn(comp, 'onSortDirectionChange'); + const paginationEl = fixture.debugElement.query(By.css('ds-pagination')); + paginationEl.triggerEventHandler('sortDirectionChange', testEvent); + }); + + it('should call onSortDirectionChange on the component', () => { + expect(comp.onSortDirectionChange).toHaveBeenCalledWith(testEvent); + }); + }); + + describe('when the sortFieldChange output on the pagination is triggered', () => { + beforeEach(() => { + spyOn(comp, 'onSortFieldChange'); + const paginationEl = fixture.debugElement.query(By.css('ds-pagination')); + paginationEl.triggerEventHandler('sortFieldChange', testEvent); + }); + + it('should call onSortFieldChange on the component', () => { + expect(comp.onSortFieldChange).toHaveBeenCalledWith(testEvent); + }); + }); + + describe('when the paginationChange output on the pagination is triggered', () => { + beforeEach(() => { + spyOn(comp, 'onPaginationChange'); + const paginationEl = fixture.debugElement.query(By.css('ds-pagination')); + paginationEl.triggerEventHandler('paginationChange', testEvent); + }); + + it('should call onPaginationChange on the component', () => { + expect(comp.onPaginationChange).toHaveBeenCalledWith(testEvent); + }); + }); + + describe('when onPageChange is triggered with an event', () => { + beforeEach(() => { + spyOn(comp.pageChange, 'emit'); + comp.onPageChange(testEvent); + }); + + it('should emit the value from the pageChange EventEmitter', fakeAsync(() => { + tick(1); + expect(comp.pageChange.emit).toHaveBeenCalled(); + expect(comp.pageChange.emit).toHaveBeenCalledWith(testEvent); + })); + }); + + describe('when onPageSizeChange is triggered with an event', () => { + beforeEach(() => { + spyOn(comp.pageSizeChange, 'emit'); + comp.onPageSizeChange(testEvent); + }); + + it('should emit the value from the pageSizeChange EventEmitter', fakeAsync(() => { + tick(1); + expect(comp.pageSizeChange.emit).toHaveBeenCalled(); + expect(comp.pageSizeChange.emit).toHaveBeenCalledWith(testEvent); + })); + }); + + describe('when onSortDirectionChange is triggered with an event', () => { + beforeEach(() => { + spyOn(comp.sortDirectionChange, 'emit'); + comp.onSortDirectionChange(testEvent); + }); + + it('should emit the value from the sortDirectionChange EventEmitter', fakeAsync(() => { + tick(1); + expect(comp.sortDirectionChange.emit).toHaveBeenCalled(); + expect(comp.sortDirectionChange.emit).toHaveBeenCalledWith(testEvent); + })); + }); + + describe('when onSortFieldChange is triggered with an event', () => { + beforeEach(() => { + spyOn(comp.sortFieldChange, 'emit'); + comp.onSortFieldChange(testEvent); + }); + + it('should emit the value from the sortFieldChange EventEmitter', fakeAsync(() => { + tick(1); + expect(comp.sortFieldChange.emit).toHaveBeenCalled(); + expect(comp.sortFieldChange.emit).toHaveBeenCalledWith(testEvent); + })); + }); + + describe('when onPaginationChange is triggered with an event', () => { + beforeEach(() => { + spyOn(comp.paginationChange, 'emit'); + comp.onPaginationChange(testEvent); + }); + + it('should emit the value from the paginationChange EventEmitter', fakeAsync(() => { + tick(1); + expect(comp.paginationChange.emit).toHaveBeenCalled(); + expect(comp.paginationChange.emit).toHaveBeenCalledWith(testEvent); + })); + }); +}); diff --git a/src/app/shared/object-detail/object-detail.component.ts b/src/app/shared/object-detail/object-detail.component.ts index bdbb360be6..dad5951e46 100644 --- a/src/app/shared/object-detail/object-detail.component.ts +++ b/src/app/shared/object-detail/object-detail.component.ts @@ -24,17 +24,44 @@ import { PaginationComponentOptions } from '../pagination/pagination-component-o templateUrl: './object-detail.component.html', animations: [fadeIn] }) - export class ObjectDetailComponent { + /** + * Pagination options object + */ @Input() config: PaginationComponentOptions; + + /** + * Sort options object + */ @Input() sortConfig: SortOptions; - @Input() hideGear = false; + + /** + * A boolean representing if to hide gear pagination icon + */ + @Input() hideGear = true; + + /** + * A boolean representing if to hide pagination when there is only a page + */ @Input() hidePagerWhenSinglePage = true; + + /** + * The list of objects to paginate + */ private _objects: RemoteData>; + + /** + * Setter for _objects property + * @param objects + */ @Input() set objects(objects: RemoteData>) { this._objects = objects; } + + /** + * Getter for _objects property + */ get objects() { return this._objects; } @@ -69,6 +96,10 @@ export class ObjectDetailComponent { */ @Output() sortDirectionChange: EventEmitter = new EventEmitter(); + /** + * An event fired when the pagination is changed. + * Event's payload equals to the newly selected sort direction. + */ @Output() paginationChange: EventEmitter = new EventEmitter(); /** @@ -76,23 +107,38 @@ export class ObjectDetailComponent { * Event's payload equals to the newly selected sort field. */ @Output() sortFieldChange: EventEmitter = new EventEmitter(); - data: any = {}; + + /** + * Emit pageChange event + */ onPageChange(event) { this.pageChange.emit(event); } + /** + * Emit pageSizeChange event + */ onPageSizeChange(event) { this.pageSizeChange.emit(event); } + /** + * Emit sortDirectionChange event + */ onSortDirectionChange(event) { this.sortDirectionChange.emit(event); } + /** + * Emit sortFieldChange event + */ onSortFieldChange(event) { this.sortFieldChange.emit(event); } + /** + * Emit paginationChange event + */ onPaginationChange(event) { this.paginationChange.emit(event); } diff --git a/src/app/shared/object-detail/wrapper-detail-element/wrapper-detail-element.component.spec.ts b/src/app/shared/object-detail/wrapper-detail-element/wrapper-detail-element.component.spec.ts index 3f28d5e76b..e54ae58398 100644 --- a/src/app/shared/object-detail/wrapper-detail-element/wrapper-detail-element.component.spec.ts +++ b/src/app/shared/object-detail/wrapper-detail-element/wrapper-detail-element.component.spec.ts @@ -1,16 +1,15 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; +import { ActivatedRoute, Router } from '@angular/router'; import { of as observableOf } from 'rxjs'; -import { ActivatedRoute, Router } from '@angular/router'; import { RouterStub } from '../../testing/router-stub'; +import { WrapperDetailElementComponent } from './wrapper-detail-element.component'; -import { WrapperGridElementComponent } from '../../object-grid/wrapper-grid-element/wrapper-grid-element.component'; - -let wrapperGridElementComponent: WrapperGridElementComponent; -let fixture: ComponentFixture; +let wrapperDetailElementComponent: WrapperDetailElementComponent; +let fixture: ComponentFixture; const queryParam = 'test query'; const scopeParam = '7669c72a-3f2a-451f-a3b9-9210e7a4c02f'; const activatedRouteStub = { @@ -20,14 +19,14 @@ const activatedRouteStub = { }) }; -describe('WrapperGridElementComponent', () => { +describe('WrapperDetailElementComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ WrapperGridElementComponent ], + declarations: [ WrapperDetailElementComponent ], providers: [ { provide: ActivatedRoute, useValue: activatedRouteStub }, { provide: Router, useClass: RouterStub }, - { provide: 'objectElementProvider', useFactory: (wrapperGridElementComponent)} + { provide: 'objectElementProvider', useFactory: (WrapperDetailElementComponent)} ], schemas: [ NO_ERRORS_SCHEMA ] @@ -35,12 +34,11 @@ describe('WrapperGridElementComponent', () => { })); beforeEach(async(() => { - fixture = TestBed.createComponent(WrapperGridElementComponent); - wrapperGridElementComponent = fixture.componentInstance; - + fixture = TestBed.createComponent(WrapperDetailElementComponent); + wrapperDetailElementComponent = fixture.componentInstance; })); - it('should show the wrapper element containing the cards',() => { - expect(fixture.debugElement.query(By.css('ds-collection-grid-element'))).toBeDefined(); + it('should show the wrapper element containing the detail object',() => { + expect(fixture.debugElement.query(By.css('ds-workspaceitem-my-dspace-result-detail-element'))).toBeDefined(); }) }); diff --git a/src/app/shared/object-detail/wrapper-detail-element/wrapper-detail-element.component.ts b/src/app/shared/object-detail/wrapper-detail-element/wrapper-detail-element.component.ts index 0d3bfef3fe..b959505eea 100644 --- a/src/app/shared/object-detail/wrapper-detail-element/wrapper-detail-element.component.ts +++ b/src/app/shared/object-detail/wrapper-detail-element/wrapper-detail-element.component.ts @@ -5,18 +5,37 @@ import { GenericConstructor } from '../../../core/shared/generic-constructor'; import { rendersDSOType } from '../../object-collection/shared/dso-element-decorator'; import { ListableObject } from '../../object-collection/shared/listable-object.model'; +/** + * This component renders a wrapper for an object in the detail view. + */ @Component({ selector: 'ds-wrapper-detail-element', styleUrls: ['./wrapper-detail-element.component.scss'], templateUrl: './wrapper-detail-element.component.html' }) export class WrapperDetailElementComponent implements OnInit { + + /** + * The listable object. + */ @Input() object: ListableObject; + + /** + * The instance of the injector. + */ objectInjector: Injector; + /** + * Initialize instance variables + * + * @param {Injector} injector + */ constructor(private injector: Injector) { } + /** + * Initialize injector + */ ngOnInit(): void { this.objectInjector = Injector.create({ providers: [{ provide: 'objectElementProvider', useFactory: () => (this.object), deps:[] }], @@ -25,6 +44,9 @@ export class WrapperDetailElementComponent implements OnInit { } + /** + * Return class name for the object to inject + */ getDetailElement(): string { const f: GenericConstructor = this.object.constructor as GenericConstructor; return rendersDSOType(f, ViewMode.Detail); diff --git a/src/app/shared/object-list/my-dspace-result-list-element/my-dspace-result-list-element.component.ts b/src/app/shared/object-list/my-dspace-result-list-element/my-dspace-result-list-element.component.ts index bddf40d8c2..4fd40e7318 100644 --- a/src/app/shared/object-list/my-dspace-result-list-element/my-dspace-result-list-element.component.ts +++ b/src/app/shared/object-list/my-dspace-result-list-element/my-dspace-result-list-element.component.ts @@ -10,11 +10,24 @@ import { Metadata } from '../../../core/shared/metadata.utils'; selector: 'ds-my-dspace-result-list-element', template: `` }) - export class MyDSpaceResultListElementComponent, K extends DSpaceObject> extends AbstractListableElementComponent { + + /** + * The result element object + */ dso: K; + + /** + * The array index of the result element + */ dsoIndex: number; + /** + * Initialize instance variables + * + * @param {ListableObject} listable + * @param {number} index + */ public constructor(@Inject('objectElementProvider') public listable: ListableObject, @Inject('indexElementProvider') public index: number) { super(listable); diff --git a/src/app/shared/object-list/object-list.component.spec.ts b/src/app/shared/object-list/object-list.component.spec.ts index 7e0b704a19..12ad032e98 100644 --- a/src/app/shared/object-list/object-list.component.spec.ts +++ b/src/app/shared/object-list/object-list.component.spec.ts @@ -6,7 +6,7 @@ import { By } from '@angular/platform-browser'; describe('ObjectListComponent', () => { let comp: ObjectListComponent; let fixture: ComponentFixture; - const testEvent = {test: 'test'} + const testEvent = {test: 'test'}; beforeEach(async(() => { TestBed.configureTestingModule({ diff --git a/src/app/shared/pagination/pagination.component.ts b/src/app/shared/pagination/pagination.component.ts index 825365c8c1..573c6a94f7 100644 --- a/src/app/shared/pagination/pagination.component.ts +++ b/src/app/shared/pagination/pagination.component.ts @@ -79,7 +79,7 @@ export class PaginationComponent implements OnDestroy, OnInit { @Output() sortFieldChange: EventEmitter = new EventEmitter(); /** - * An event fired when the sort field is changed. + * An event fired when the pagination is changed. * Event's payload equals to the newly selected sort field. */ @Output() paginationChange: EventEmitter = new EventEmitter();