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 { ItemEditBitstreamBundleComponent } from './item-edit-bitstream-bundle.component';
|
||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { of as observableOf } from 'rxjs/internal/observable/of';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { VarDirective } from '../../../../shared/utils/var.directive';
|
import { NO_ERRORS_SCHEMA, ViewContainerRef } from '@angular/core';
|
||||||
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 { Item } from '../../../../core/shared/item.model';
|
import { Item } from '../../../../core/shared/item.model';
|
||||||
import { Bundle } from '../../../../core/shared/bundle.model';
|
import { Bundle } from '../../../../core/shared/bundle.model';
|
||||||
|
|
||||||
describe('ItemEditBitstreamBundleComponent', () => {
|
describe('ItemEditBitstreamBundleComponent', () => {
|
||||||
let comp: ItemEditBitstreamBundleComponent;
|
let comp: ItemEditBitstreamBundleComponent;
|
||||||
let fixture: ComponentFixture<ItemEditBitstreamBundleComponent>;
|
let fixture: ComponentFixture<ItemEditBitstreamBundleComponent>;
|
||||||
|
let viewContainerRef: ViewContainerRef;
|
||||||
let objectUpdatesService: ObjectUpdatesService;
|
|
||||||
let bundleService: BundleDataService;
|
|
||||||
|
|
||||||
const item = Object.assign(new Item(), {
|
const item = Object.assign(new Item(), {
|
||||||
id: 'item-1',
|
id: 'item-1',
|
||||||
@@ -30,75 +19,12 @@ describe('ItemEditBitstreamBundleComponent', () => {
|
|||||||
uuid: 'bundle-1',
|
uuid: 'bundle-1',
|
||||||
self: 'bundle-1-selflink'
|
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(() => {
|
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({
|
TestBed.configureTestingModule({
|
||||||
imports: [TranslateModule.forRoot()],
|
imports: [TranslateModule.forRoot()],
|
||||||
declarations: [ItemEditBitstreamBundleComponent, VarDirective, ObjectValuesPipe],
|
declarations: [ItemEditBitstreamBundleComponent],
|
||||||
providers: [
|
schemas: [
|
||||||
{ provide: ObjectUpdatesService, useValue: objectUpdatesService },
|
|
||||||
{ provide: BundleDataService, useValue: bundleService }
|
|
||||||
], schemas: [
|
|
||||||
NO_ERRORS_SCHEMA
|
NO_ERRORS_SCHEMA
|
||||||
]
|
]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
@@ -109,35 +35,12 @@ describe('ItemEditBitstreamBundleComponent', () => {
|
|||||||
comp = fixture.componentInstance;
|
comp = fixture.componentInstance;
|
||||||
comp.item = item;
|
comp.item = item;
|
||||||
comp.bundle = bundle;
|
comp.bundle = bundle;
|
||||||
comp.batchSize = batchSize;
|
viewContainerRef = (comp as any).viewContainerRef;
|
||||||
|
spyOn(viewContainerRef, 'createEmbeddedView');
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('A drag-and-drop event', () => {
|
it('should create an embedded view of the component', () => {
|
||||||
it('should send a move update to the objectUpdatesService', () => {
|
expect(viewContainerRef.createEmbeddedView).toHaveBeenCalled();
|
||||||
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);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -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 * as deepFreeze from 'deep-freeze';
|
||||||
import {
|
import {
|
||||||
AddFieldUpdateAction,
|
AddFieldUpdateAction, AddPageToCustomOrderAction,
|
||||||
DiscardObjectUpdatesAction,
|
DiscardObjectUpdatesAction,
|
||||||
FieldChangeType,
|
FieldChangeType,
|
||||||
InitializeFieldsAction, MoveFieldUpdateAction,
|
InitializeFieldsAction, MoveFieldUpdateAction,
|
||||||
@@ -81,8 +81,13 @@ describe('objectUpdatesReducer', () => {
|
|||||||
},
|
},
|
||||||
lastModified: modDate,
|
lastModified: modDate,
|
||||||
customOrder: {
|
customOrder: {
|
||||||
initialOrder: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid],
|
initialOrderPages: [
|
||||||
newOrder: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid],
|
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
||||||
|
],
|
||||||
|
newOrderPages: [
|
||||||
|
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
||||||
|
],
|
||||||
|
pageSize: 10,
|
||||||
changed: false
|
changed: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,8 +114,13 @@ describe('objectUpdatesReducer', () => {
|
|||||||
},
|
},
|
||||||
lastModified: modDate,
|
lastModified: modDate,
|
||||||
customOrder: {
|
customOrder: {
|
||||||
initialOrder: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid],
|
initialOrderPages: [
|
||||||
newOrder: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid],
|
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
||||||
|
],
|
||||||
|
newOrderPages: [
|
||||||
|
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
||||||
|
],
|
||||||
|
pageSize: 10,
|
||||||
changed: false
|
changed: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -145,8 +155,13 @@ describe('objectUpdatesReducer', () => {
|
|||||||
},
|
},
|
||||||
lastModified: modDate,
|
lastModified: modDate,
|
||||||
customOrder: {
|
customOrder: {
|
||||||
initialOrder: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid],
|
initialOrderPages: [
|
||||||
newOrder: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid],
|
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
||||||
|
],
|
||||||
|
newOrderPages: [
|
||||||
|
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
||||||
|
],
|
||||||
|
pageSize: 10,
|
||||||
changed: false
|
changed: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -211,7 +226,7 @@ describe('objectUpdatesReducer', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should initialize all fields when the INITIALIZE action is dispatched, based on the payload', () => {
|
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 = {
|
const expectedState = {
|
||||||
[url]: {
|
[url]: {
|
||||||
@@ -230,8 +245,13 @@ describe('objectUpdatesReducer', () => {
|
|||||||
fieldUpdates: {},
|
fieldUpdates: {},
|
||||||
lastModified: modDate,
|
lastModified: modDate,
|
||||||
customOrder: {
|
customOrder: {
|
||||||
initialOrder: [],
|
initialOrderPages: [
|
||||||
newOrder: [],
|
{ order: [identifiable1.uuid, identifiable3.uuid] }
|
||||||
|
],
|
||||||
|
newOrderPages: [
|
||||||
|
{ order: [identifiable1.uuid, identifiable3.uuid] }
|
||||||
|
],
|
||||||
|
pageSize: 10,
|
||||||
changed: false
|
changed: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -301,11 +321,28 @@ describe('objectUpdatesReducer', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should move the custom order from the state when the MOVE action is dispatched', () => {
|
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);
|
const newState = objectUpdatesReducer(testState, action);
|
||||||
expect(newState[url].customOrder.newOrder[0]).toEqual(testState[url].customOrder.newOrder[1]);
|
expect(newState[url].customOrder.newOrderPages[0].order[0]).toEqual(testState[url].customOrder.newOrderPages[0].order[1]);
|
||||||
expect(newState[url].customOrder.newOrder[1]).toEqual(testState[url].customOrder.newOrder[0]);
|
expect(newState[url].customOrder.newOrderPages[0].order[1]).toEqual(testState[url].customOrder.newOrderPages[0].order[0]);
|
||||||
expect(newState[url].customOrder.changed).toEqual(true);
|
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 { CoreState } from '../../core.reducers';
|
||||||
import { ObjectUpdatesService } from './object-updates.service';
|
import { ObjectUpdatesService } from './object-updates.service';
|
||||||
import {
|
import {
|
||||||
|
AddPageToCustomOrderAction,
|
||||||
DiscardObjectUpdatesAction,
|
DiscardObjectUpdatesAction,
|
||||||
FieldChangeType,
|
FieldChangeType,
|
||||||
InitializeFieldsAction, ReinstateObjectUpdatesAction, RemoveFieldUpdateAction,
|
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', () => {
|
describe('getFieldUpdates', () => {
|
||||||
it('should return the list of all fields, including their update if there is one', () => {
|
it('should return the list of all fields, including their update if there is one', () => {
|
||||||
const result$ = service.getFieldUpdates(url, identifiables);
|
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));
|
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 {
|
addPageToCustomOrder(url, fields: Identifiable[], page: number): void {
|
||||||
this.store.dispatch(new AddPageToCustomOrderAction(url, fields, fields.map((field) => field.uuid), page));
|
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 { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
||||||
import { ObjectUpdatesService } from '../../core/data/object-updates/object-updates.service';
|
import { ObjectUpdatesService } from '../../core/data/object-updates/object-updates.service';
|
||||||
import { switchMap, take, tap } from 'rxjs/operators';
|
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 { paginatedListToArray } from '../../core/shared/operators';
|
||||||
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||||
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
||||||
@@ -152,7 +152,7 @@ export abstract class AbstractPaginatedDragAndDropListComponent<T extends DSpace
|
|||||||
drop(event: CdkDragDrop<any>) {
|
drop(event: CdkDragDrop<any>) {
|
||||||
// Check if the user is hovering over any of the pagination's pages at the time of dropping the object
|
// 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');
|
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
|
// The user is hovering over a page, fetch the page's number from the element
|
||||||
const page = Number(droppedOnElement.textContent);
|
const page = Number(droppedOnElement.textContent);
|
||||||
if (hasValue(page) && !Number.isNaN(page)) {
|
if (hasValue(page) && !Number.isNaN(page)) {
|
||||||
|
Reference in New Issue
Block a user