mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
68346: Tests and JSDocs
This commit is contained in:
@@ -1,25 +1,14 @@
|
||||
import { ItemEditBitstreamBundleComponent } from './item-edit-bitstream-bundle.component';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { VarDirective } from '../../../../shared/utils/var.directive';
|
||||
import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { Bitstream } from '../../../../core/shared/bitstream.model';
|
||||
import { createMockRDObs } from '../item-bitstreams.component.spec';
|
||||
import { BitstreamFormat } from '../../../../core/shared/bitstream-format.model';
|
||||
import { BundleDataService } from '../../../../core/data/bundle-data.service';
|
||||
import { createPaginatedList, createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
|
||||
import { ObjectValuesPipe } from '../../../../shared/utils/object-values-pipe';
|
||||
import { NO_ERRORS_SCHEMA, ViewContainerRef } from '@angular/core';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
import { Bundle } from '../../../../core/shared/bundle.model';
|
||||
|
||||
describe('ItemEditBitstreamBundleComponent', () => {
|
||||
let comp: ItemEditBitstreamBundleComponent;
|
||||
let fixture: ComponentFixture<ItemEditBitstreamBundleComponent>;
|
||||
|
||||
let objectUpdatesService: ObjectUpdatesService;
|
||||
let bundleService: BundleDataService;
|
||||
let viewContainerRef: ViewContainerRef;
|
||||
|
||||
const item = Object.assign(new Item(), {
|
||||
id: 'item-1',
|
||||
@@ -30,75 +19,12 @@ describe('ItemEditBitstreamBundleComponent', () => {
|
||||
uuid: 'bundle-1',
|
||||
self: 'bundle-1-selflink'
|
||||
});
|
||||
const date = new Date();
|
||||
const format = Object.assign(new BitstreamFormat(), {
|
||||
shortDescription: 'PDF'
|
||||
});
|
||||
const bitstream1 = Object.assign(new Bitstream(), {
|
||||
uuid: 'bitstreamUUID1',
|
||||
name: 'Fake Bitstream 1',
|
||||
bundleName: 'ORIGINAL',
|
||||
description: 'Description',
|
||||
format: createMockRDObs(format)
|
||||
});
|
||||
const fieldUpdate1 = {
|
||||
field: bitstream1,
|
||||
changeType: undefined
|
||||
};
|
||||
const bitstream2 = Object.assign(new Bitstream(), {
|
||||
uuid: 'bitstreamUUID2',
|
||||
name: 'Fake Bitstream 2',
|
||||
bundleName: 'ORIGINAL',
|
||||
description: 'Description',
|
||||
format: createMockRDObs(format)
|
||||
});
|
||||
const fieldUpdate2 = {
|
||||
field: bitstream2,
|
||||
changeType: undefined
|
||||
};
|
||||
const batchSize = 10;
|
||||
|
||||
beforeEach(async(() => {
|
||||
objectUpdatesService = jasmine.createSpyObj('objectUpdatesService',
|
||||
{
|
||||
getFieldUpdates: observableOf({
|
||||
[bitstream1.uuid]: fieldUpdate1,
|
||||
[bitstream2.uuid]: fieldUpdate2,
|
||||
}),
|
||||
getFieldUpdatesExclusive: observableOf({
|
||||
[bitstream1.uuid]: fieldUpdate1,
|
||||
[bitstream2.uuid]: fieldUpdate2,
|
||||
}),
|
||||
getFieldUpdatesByCustomOrder: observableOf({
|
||||
[bitstream1.uuid]: fieldUpdate1,
|
||||
[bitstream2.uuid]: fieldUpdate2,
|
||||
}),
|
||||
saveMoveFieldUpdate: {},
|
||||
saveRemoveFieldUpdate: {},
|
||||
removeSingleFieldUpdate: {},
|
||||
saveAddFieldUpdate: {},
|
||||
discardFieldUpdates: {},
|
||||
reinstateFieldUpdates: observableOf(true),
|
||||
initialize: {},
|
||||
getUpdatedFields: observableOf([bitstream1, bitstream2]),
|
||||
getLastModified: observableOf(date),
|
||||
hasUpdates: observableOf(true),
|
||||
isReinstatable: observableOf(false),
|
||||
isValidPage: observableOf(true)
|
||||
}
|
||||
);
|
||||
|
||||
bundleService = jasmine.createSpyObj('bundleService', {
|
||||
getBitstreams: createSuccessfulRemoteDataObject$(createPaginatedList([bitstream1, bitstream2]))
|
||||
});
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot()],
|
||||
declarations: [ItemEditBitstreamBundleComponent, VarDirective, ObjectValuesPipe],
|
||||
providers: [
|
||||
{ provide: ObjectUpdatesService, useValue: objectUpdatesService },
|
||||
{ provide: BundleDataService, useValue: bundleService }
|
||||
], schemas: [
|
||||
declarations: [ItemEditBitstreamBundleComponent],
|
||||
schemas: [
|
||||
NO_ERRORS_SCHEMA
|
||||
]
|
||||
}).compileComponents();
|
||||
@@ -109,35 +35,12 @@ describe('ItemEditBitstreamBundleComponent', () => {
|
||||
comp = fixture.componentInstance;
|
||||
comp.item = item;
|
||||
comp.bundle = bundle;
|
||||
comp.batchSize = batchSize;
|
||||
viewContainerRef = (comp as any).viewContainerRef;
|
||||
spyOn(viewContainerRef, 'createEmbeddedView');
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
describe('A drag-and-drop event', () => {
|
||||
it('should send a move update to the objectUpdatesService', () => {
|
||||
const event = {
|
||||
previousIndex: 0,
|
||||
currentIndex: 1
|
||||
};
|
||||
comp.drop(event as any);
|
||||
expect(objectUpdatesService.saveMoveFieldUpdate).toHaveBeenCalledWith(bundle.self, event.previousIndex, event.currentIndex);
|
||||
});
|
||||
});
|
||||
|
||||
describe('loadMore', () => {
|
||||
it('should increase the current size by ' + batchSize, () => {
|
||||
const initialSize = comp.currentSize$.value;
|
||||
comp.loadMore();
|
||||
const newSize = comp.currentSize$.value;
|
||||
expect(initialSize + batchSize).toEqual(newSize);
|
||||
});
|
||||
});
|
||||
|
||||
describe('loadAll', () => {
|
||||
it('should increase the current size by a lot', () => {
|
||||
comp.loadAll();
|
||||
const newSize = comp.currentSize$.value;
|
||||
expect(newSize).toBeGreaterThanOrEqual(999);
|
||||
});
|
||||
it('should create an embedded view of the component', () => {
|
||||
expect(viewContainerRef.createEmbeddedView).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@@ -0,0 +1,120 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { Bundle } from '../../../../../core/shared/bundle.model';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { PaginatedDragAndDropBitstreamListComponent } from './paginated-drag-and-drop-bitstream-list.component';
|
||||
import { VarDirective } from '../../../../../shared/utils/var.directive';
|
||||
import { ObjectValuesPipe } from '../../../../../shared/utils/object-values-pipe';
|
||||
import { ObjectUpdatesService } from '../../../../../core/data/object-updates/object-updates.service';
|
||||
import { BundleDataService } from '../../../../../core/data/bundle-data.service';
|
||||
import { createMockRDObs } from '../../item-bitstreams.component.spec';
|
||||
import { Bitstream } from '../../../../../core/shared/bitstream.model';
|
||||
import { BitstreamFormat } from '../../../../../core/shared/bitstream-format.model';
|
||||
import { createPaginatedList, createSuccessfulRemoteDataObject$ } from '../../../../../shared/testing/utils';
|
||||
import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||
import { take } from 'rxjs/operators';
|
||||
|
||||
describe('PaginatedDragAndDropBitstreamListComponent', () => {
|
||||
let comp: PaginatedDragAndDropBitstreamListComponent;
|
||||
let fixture: ComponentFixture<PaginatedDragAndDropBitstreamListComponent>;
|
||||
let objectUpdatesService: ObjectUpdatesService;
|
||||
let bundleService: BundleDataService;
|
||||
|
||||
const bundle = Object.assign(new Bundle(), {
|
||||
id: 'bundle-1',
|
||||
uuid: 'bundle-1',
|
||||
self: 'bundle-1-selflink'
|
||||
});
|
||||
const date = new Date();
|
||||
const format = Object.assign(new BitstreamFormat(), {
|
||||
shortDescription: 'PDF'
|
||||
});
|
||||
const bitstream1 = Object.assign(new Bitstream(), {
|
||||
uuid: 'bitstreamUUID1',
|
||||
name: 'Fake Bitstream 1',
|
||||
bundleName: 'ORIGINAL',
|
||||
description: 'Description',
|
||||
format: createMockRDObs(format)
|
||||
});
|
||||
const fieldUpdate1 = {
|
||||
field: bitstream1,
|
||||
changeType: undefined
|
||||
};
|
||||
const bitstream2 = Object.assign(new Bitstream(), {
|
||||
uuid: 'bitstreamUUID2',
|
||||
name: 'Fake Bitstream 2',
|
||||
bundleName: 'ORIGINAL',
|
||||
description: 'Description',
|
||||
format: createMockRDObs(format)
|
||||
});
|
||||
const fieldUpdate2 = {
|
||||
field: bitstream2,
|
||||
changeType: undefined
|
||||
};
|
||||
|
||||
beforeEach(async(() => {
|
||||
objectUpdatesService = jasmine.createSpyObj('objectUpdatesService',
|
||||
{
|
||||
getFieldUpdates: observableOf({
|
||||
[bitstream1.uuid]: fieldUpdate1,
|
||||
[bitstream2.uuid]: fieldUpdate2,
|
||||
}),
|
||||
getFieldUpdatesExclusive: observableOf({
|
||||
[bitstream1.uuid]: fieldUpdate1,
|
||||
[bitstream2.uuid]: fieldUpdate2,
|
||||
}),
|
||||
getFieldUpdatesByCustomOrder: observableOf({
|
||||
[bitstream1.uuid]: fieldUpdate1,
|
||||
[bitstream2.uuid]: fieldUpdate2,
|
||||
}),
|
||||
saveMoveFieldUpdate: {},
|
||||
saveRemoveFieldUpdate: {},
|
||||
removeSingleFieldUpdate: {},
|
||||
saveAddFieldUpdate: {},
|
||||
discardFieldUpdates: {},
|
||||
reinstateFieldUpdates: observableOf(true),
|
||||
initialize: {},
|
||||
getUpdatedFields: observableOf([bitstream1, bitstream2]),
|
||||
getLastModified: observableOf(date),
|
||||
hasUpdates: observableOf(true),
|
||||
isReinstatable: observableOf(false),
|
||||
isValidPage: observableOf(true),
|
||||
initializeWithCustomOrder: {},
|
||||
addPageToCustomOrder: {}
|
||||
}
|
||||
);
|
||||
|
||||
bundleService = jasmine.createSpyObj('bundleService', {
|
||||
getBitstreams: createSuccessfulRemoteDataObject$(createPaginatedList([bitstream1, bitstream2]))
|
||||
});
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot()],
|
||||
declarations: [PaginatedDragAndDropBitstreamListComponent, VarDirective, ObjectValuesPipe],
|
||||
providers: [
|
||||
{ provide: ObjectUpdatesService, useValue: objectUpdatesService },
|
||||
{ provide: BundleDataService, useValue: bundleService }
|
||||
], schemas: [
|
||||
NO_ERRORS_SCHEMA
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(PaginatedDragAndDropBitstreamListComponent);
|
||||
comp = fixture.componentInstance;
|
||||
comp.bundle = bundle;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should initialize the objectsRD$', (done) => {
|
||||
comp.objectsRD$.pipe(take(1)).subscribe((objects) => {
|
||||
expect(objects.payload.page).toEqual([bitstream1, bitstream2]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should initialize the URL', () => {
|
||||
expect(comp.url).toEqual(bundle.self);
|
||||
});
|
||||
});
|
@@ -1,6 +1,6 @@
|
||||
import * as deepFreeze from 'deep-freeze';
|
||||
import {
|
||||
AddFieldUpdateAction,
|
||||
AddFieldUpdateAction, AddPageToCustomOrderAction,
|
||||
DiscardObjectUpdatesAction,
|
||||
FieldChangeType,
|
||||
InitializeFieldsAction, MoveFieldUpdateAction,
|
||||
@@ -81,8 +81,13 @@ describe('objectUpdatesReducer', () => {
|
||||
},
|
||||
lastModified: modDate,
|
||||
customOrder: {
|
||||
initialOrder: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid],
|
||||
newOrder: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid],
|
||||
initialOrderPages: [
|
||||
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
||||
],
|
||||
newOrderPages: [
|
||||
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
||||
],
|
||||
pageSize: 10,
|
||||
changed: false
|
||||
}
|
||||
}
|
||||
@@ -109,8 +114,13 @@ describe('objectUpdatesReducer', () => {
|
||||
},
|
||||
lastModified: modDate,
|
||||
customOrder: {
|
||||
initialOrder: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid],
|
||||
newOrder: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid],
|
||||
initialOrderPages: [
|
||||
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
||||
],
|
||||
newOrderPages: [
|
||||
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
||||
],
|
||||
pageSize: 10,
|
||||
changed: false
|
||||
}
|
||||
},
|
||||
@@ -145,8 +155,13 @@ describe('objectUpdatesReducer', () => {
|
||||
},
|
||||
lastModified: modDate,
|
||||
customOrder: {
|
||||
initialOrder: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid],
|
||||
newOrder: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid],
|
||||
initialOrderPages: [
|
||||
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
||||
],
|
||||
newOrderPages: [
|
||||
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
||||
],
|
||||
pageSize: 10,
|
||||
changed: false
|
||||
}
|
||||
}
|
||||
@@ -211,7 +226,7 @@ describe('objectUpdatesReducer', () => {
|
||||
});
|
||||
|
||||
it('should initialize all fields when the INITIALIZE action is dispatched, based on the payload', () => {
|
||||
const action = new InitializeFieldsAction(url, [identifiable1, identifiable3], modDate);
|
||||
const action = new InitializeFieldsAction(url, [identifiable1, identifiable3], modDate, [identifiable1.uuid, identifiable3.uuid], 10, 0);
|
||||
|
||||
const expectedState = {
|
||||
[url]: {
|
||||
@@ -230,8 +245,13 @@ describe('objectUpdatesReducer', () => {
|
||||
fieldUpdates: {},
|
||||
lastModified: modDate,
|
||||
customOrder: {
|
||||
initialOrder: [],
|
||||
newOrder: [],
|
||||
initialOrderPages: [
|
||||
{ order: [identifiable1.uuid, identifiable3.uuid] }
|
||||
],
|
||||
newOrderPages: [
|
||||
{ order: [identifiable1.uuid, identifiable3.uuid] }
|
||||
],
|
||||
pageSize: 10,
|
||||
changed: false
|
||||
}
|
||||
}
|
||||
@@ -301,11 +321,28 @@ describe('objectUpdatesReducer', () => {
|
||||
});
|
||||
|
||||
it('should move the custom order from the state when the MOVE action is dispatched', () => {
|
||||
const action = new MoveFieldUpdateAction(url, 0, 1);
|
||||
const action = new MoveFieldUpdateAction(url, 0, 1, 0, 0);
|
||||
|
||||
const newState = objectUpdatesReducer(testState, action);
|
||||
expect(newState[url].customOrder.newOrder[0]).toEqual(testState[url].customOrder.newOrder[1]);
|
||||
expect(newState[url].customOrder.newOrder[1]).toEqual(testState[url].customOrder.newOrder[0]);
|
||||
expect(newState[url].customOrder.newOrderPages[0].order[0]).toEqual(testState[url].customOrder.newOrderPages[0].order[1]);
|
||||
expect(newState[url].customOrder.newOrderPages[0].order[1]).toEqual(testState[url].customOrder.newOrderPages[0].order[0]);
|
||||
expect(newState[url].customOrder.changed).toEqual(true);
|
||||
});
|
||||
|
||||
it('should add a new page to the custom order and add empty pages in between when the ADD_PAGE_TO_CUSTOM_ORDER action is dispatched', () => {
|
||||
const identifiable4 = {
|
||||
uuid: 'a23eae5a-7857-4ef9-8e52-989436ad2955',
|
||||
key: 'dc.description.abstract',
|
||||
language: null,
|
||||
value: 'Extra value'
|
||||
};
|
||||
const action = new AddPageToCustomOrderAction(url, [identifiable4], [identifiable4.uuid], 2);
|
||||
|
||||
const newState = objectUpdatesReducer(testState, action);
|
||||
// Confirm the page in between the two pages (index 1) has been filled with 10 (page size) undefined values
|
||||
expect(newState[url].customOrder.newOrderPages[1].order.length).toEqual(10);
|
||||
expect(newState[url].customOrder.newOrderPages[1].order[0]).toBeUndefined();
|
||||
// Verify the new page is correct
|
||||
expect(newState[url].customOrder.newOrderPages[2].order[0]).toEqual(identifiable4.uuid);
|
||||
});
|
||||
});
|
||||
|
@@ -2,6 +2,7 @@ import { Store } from '@ngrx/store';
|
||||
import { CoreState } from '../../core.reducers';
|
||||
import { ObjectUpdatesService } from './object-updates.service';
|
||||
import {
|
||||
AddPageToCustomOrderAction,
|
||||
DiscardObjectUpdatesAction,
|
||||
FieldChangeType,
|
||||
InitializeFieldsAction, ReinstateObjectUpdatesAction, RemoveFieldUpdateAction,
|
||||
@@ -58,6 +59,25 @@ describe('ObjectUpdatesService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('initializeWithCustomOrder', () => {
|
||||
const pageSize = 20;
|
||||
const page = 0;
|
||||
|
||||
it('should dispatch an INITIALIZE action with the correct URL, initial identifiables, last modified , custom order, page size and page', () => {
|
||||
service.initializeWithCustomOrder(url, identifiables, modDate, pageSize, page);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new InitializeFieldsAction(url, identifiables, modDate, identifiables.map((identifiable) => identifiable.uuid), pageSize, page));
|
||||
});
|
||||
});
|
||||
|
||||
describe('addPageToCustomOrder', () => {
|
||||
const page = 2;
|
||||
|
||||
it('should dispatch an ADD_PAGE_TO_CUSTOM_ORDER action with the correct URL, identifiables, custom order and page number to add', () => {
|
||||
service.addPageToCustomOrder(url, identifiables, page);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new AddPageToCustomOrderAction(url, identifiables, identifiables.map((identifiable) => identifiable.uuid), page));
|
||||
});
|
||||
});
|
||||
|
||||
describe('getFieldUpdates', () => {
|
||||
it('should return the list of all fields, including their update if there is one', () => {
|
||||
const result$ = service.getFieldUpdates(url, identifiables);
|
||||
|
@@ -73,6 +73,12 @@ export class ObjectUpdatesService {
|
||||
this.store.dispatch(new InitializeFieldsAction(url, fields, lastModified, fields.map((field) => field.uuid), pageSize, page));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to dispatch an AddPageToCustomOrderAction, adding a new page to an already existing custom order tracking
|
||||
* @param url The URL for which the changes are being mapped
|
||||
* @param fields The fields to add a new page for
|
||||
* @param page The page number (starting from index 0)
|
||||
*/
|
||||
addPageToCustomOrder(url, fields: Identifiable[], page: number): void {
|
||||
this.store.dispatch(new AddPageToCustomOrderAction(url, fields, fields.map((field) => field.uuid), page));
|
||||
}
|
||||
|
@@ -0,0 +1,178 @@
|
||||
import { AbstractPaginatedDragAndDropListComponent } from './abstract-paginated-drag-and-drop-list.component';
|
||||
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||
import { ObjectUpdatesService } from '../../core/data/object-updates/object-updates.service';
|
||||
import { ElementRef } from '@angular/core';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
||||
import { createPaginatedList, createSuccessfulRemoteDataObject } from '../testing/utils';
|
||||
import { FieldUpdates } from '../../core/data/object-updates/object-updates.reducer';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { PaginationComponent } from '../pagination/pagination.component';
|
||||
|
||||
class MockAbstractPaginatedDragAndDropListComponent extends AbstractPaginatedDragAndDropListComponent<DSpaceObject> {
|
||||
|
||||
constructor(protected objectUpdatesService: ObjectUpdatesService,
|
||||
protected elRef: ElementRef,
|
||||
protected mockUrl: string,
|
||||
protected mockObjectsRD$: Observable<RemoteData<PaginatedList<DSpaceObject>>>) {
|
||||
super(objectUpdatesService, elRef);
|
||||
}
|
||||
|
||||
initializeObjectsRD(): void {
|
||||
this.objectsRD$ = this.mockObjectsRD$;
|
||||
}
|
||||
|
||||
initializeURL(): void {
|
||||
this.url = this.mockUrl;
|
||||
}
|
||||
}
|
||||
|
||||
describe('AbstractPaginatedDragAndDropListComponent', () => {
|
||||
let component: MockAbstractPaginatedDragAndDropListComponent;
|
||||
let objectUpdatesService: ObjectUpdatesService;
|
||||
let elRef: ElementRef;
|
||||
|
||||
const url = 'mock-abstract-paginated-drag-and-drop-list-component';
|
||||
|
||||
const object1 = Object.assign(new DSpaceObject(), { uuid: 'object-1' });
|
||||
const object2 = Object.assign(new DSpaceObject(), { uuid: 'object-2' });
|
||||
const objectsRD = createSuccessfulRemoteDataObject(createPaginatedList([object1, object2]));
|
||||
let objectsRD$: BehaviorSubject<RemoteData<PaginatedList<DSpaceObject>>>;
|
||||
|
||||
const updates = {
|
||||
[object1.uuid]: { field: object1, changeType: undefined },
|
||||
[object2.uuid]: { field: object2, changeType: undefined }
|
||||
} as FieldUpdates;
|
||||
|
||||
let paginationComponent: PaginationComponent;
|
||||
|
||||
beforeEach(() => {
|
||||
objectUpdatesService = jasmine.createSpyObj('objectUpdatesService', {
|
||||
initializeWithCustomOrder: {},
|
||||
addPageToCustomOrder: {},
|
||||
getFieldUpdatesByCustomOrder: observableOf(updates),
|
||||
saveMoveFieldUpdate: {}
|
||||
});
|
||||
elRef = {
|
||||
nativeElement: jasmine.createSpyObj('nativeElement', {
|
||||
querySelector: {}
|
||||
})
|
||||
};
|
||||
paginationComponent = jasmine.createSpyObj('paginationComponent', {
|
||||
doPageChange: {}
|
||||
});
|
||||
objectsRD$ = new BehaviorSubject(objectsRD);
|
||||
component = new MockAbstractPaginatedDragAndDropListComponent(objectUpdatesService, elRef, url, objectsRD$);
|
||||
component.paginationComponent = paginationComponent;
|
||||
component.ngOnInit();
|
||||
});
|
||||
|
||||
it('should call initializeWithCustomOrder to initialize the first page and add it to initializedPages', (done) => {
|
||||
expect(component.initializedPages.indexOf(0)).toBeLessThan(0);
|
||||
component.updates$.pipe(take(1)).subscribe(() => {
|
||||
expect(objectUpdatesService.initializeWithCustomOrder).toHaveBeenCalled();
|
||||
expect(component.initializedPages.indexOf(0)).toBeGreaterThanOrEqual(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should initialize the updates correctly', (done) => {
|
||||
component.updates$.pipe(take(1)).subscribe((fieldUpdates) => {
|
||||
expect(fieldUpdates).toEqual(updates);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when a new page is loaded', () => {
|
||||
const page = 5;
|
||||
|
||||
beforeEach((done) => {
|
||||
component.updates$.pipe(take(1)).subscribe(() => {
|
||||
component.currentPage$.next(page);
|
||||
objectsRD$.next(objectsRD);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should call addPageToCustomOrder to initialize the new page and add it to initializedPages', (done) => {
|
||||
component.updates$.pipe(take(1)).subscribe(() => {
|
||||
expect(objectUpdatesService.addPageToCustomOrder).toHaveBeenCalled();
|
||||
expect(component.initializedPages.indexOf(page - 1)).toBeGreaterThanOrEqual(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('twice', () => {
|
||||
beforeEach((done) => {
|
||||
component.updates$.pipe(take(1)).subscribe(() => {
|
||||
component.currentPage$.next(page);
|
||||
objectsRD$.next(objectsRD);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('shouldn\'t call addPageToCustomOrder again, as the page has already been initialized', (done) => {
|
||||
component.updates$.pipe(take(1)).subscribe(() => {
|
||||
expect(objectUpdatesService.addPageToCustomOrder).toHaveBeenCalledTimes(1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('switchPage', () => {
|
||||
const page = 3;
|
||||
|
||||
beforeEach(() => {
|
||||
component.switchPage(page);
|
||||
});
|
||||
|
||||
it('should set currentPage$ to the new page', () => {
|
||||
expect(component.currentPage$.value).toEqual(page);
|
||||
});
|
||||
});
|
||||
|
||||
describe('drop', () => {
|
||||
const event = {
|
||||
previousIndex: 0,
|
||||
currentIndex: 1,
|
||||
item: { element: { nativeElement: { id: object1.uuid } } }
|
||||
} as any;
|
||||
|
||||
describe('when the user is hovering over a new page', () => {
|
||||
const hoverPage = 3;
|
||||
const hoverElement = { textContent: '' + hoverPage };
|
||||
|
||||
beforeEach(() => {
|
||||
elRef.nativeElement.querySelector.and.returnValue(hoverElement);
|
||||
component.initializedPages.push(hoverPage - 1);
|
||||
component.drop(event);
|
||||
});
|
||||
|
||||
it('should detect the page and set currentPage$ to its value', () => {
|
||||
expect(component.currentPage$.value).toEqual(hoverPage);
|
||||
});
|
||||
|
||||
it('should detect the page and update the pagination component with its value', () => {
|
||||
expect(paginationComponent.doPageChange).toHaveBeenCalledWith(hoverPage);
|
||||
});
|
||||
|
||||
it('should send out a saveMoveFieldUpdate with the correct values', () => {
|
||||
expect(objectUpdatesService.saveMoveFieldUpdate).toHaveBeenCalledWith(url, event.previousIndex, 0, 0, hoverPage - 1, object1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the user is not hovering over a new page', () => {
|
||||
beforeEach(() => {
|
||||
component.drop(event);
|
||||
});
|
||||
|
||||
it('should send out a saveMoveFieldUpdate with the correct values', () => {
|
||||
expect(objectUpdatesService.saveMoveFieldUpdate).toHaveBeenCalledWith(url, event.previousIndex, event.currentIndex, 0, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@@ -6,7 +6,7 @@ import { PaginationComponentOptions } from '../pagination/pagination-component-o
|
||||
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
||||
import { ObjectUpdatesService } from '../../core/data/object-updates/object-updates.service';
|
||||
import { switchMap, take, tap } from 'rxjs/operators';
|
||||
import { hasValue, isEmpty } from '../empty.util';
|
||||
import { hasValue, isEmpty, isNotEmpty } from '../empty.util';
|
||||
import { paginatedListToArray } from '../../core/shared/operators';
|
||||
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
||||
@@ -152,7 +152,7 @@ export abstract class AbstractPaginatedDragAndDropListComponent<T extends DSpace
|
||||
drop(event: CdkDragDrop<any>) {
|
||||
// Check if the user is hovering over any of the pagination's pages at the time of dropping the object
|
||||
const droppedOnElement = this.elRef.nativeElement.querySelector('.page-item:hover');
|
||||
if (hasValue(droppedOnElement)) {
|
||||
if (isNotEmpty(droppedOnElement)) {
|
||||
// The user is hovering over a page, fetch the page's number from the element
|
||||
const page = Number(droppedOnElement.textContent);
|
||||
if (hasValue(page) && !Number.isNaN(page)) {
|
||||
|
Reference in New Issue
Block a user