mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-13 13:03:04 +00:00

Conflicts: src/app/+item-page/edit-item-page/edit-item-page.module.ts src/app/+item-page/edit-item-page/item-relationships/item-relationships.component.ts src/app/core/core.module.ts src/app/core/data/data.service.ts src/app/core/data/object-updates/object-updates.actions.ts src/app/core/data/object-updates/object-updates.reducer.spec.ts src/app/core/data/object-updates/object-updates.reducer.ts src/app/core/data/object-updates/object-updates.service.spec.ts src/app/core/data/object-updates/object-updates.service.ts
367 lines
13 KiB
TypeScript
367 lines
13 KiB
TypeScript
import * as deepFreeze from 'deep-freeze';
|
|
import {
|
|
AddFieldUpdateAction, AddPageToCustomOrderAction,
|
|
DiscardObjectUpdatesAction,
|
|
FieldChangeType,
|
|
InitializeFieldsAction, MoveFieldUpdateAction,
|
|
ReinstateObjectUpdatesAction, RemoveAllObjectUpdatesAction,
|
|
RemoveFieldUpdateAction, RemoveObjectUpdatesAction, SelectVirtualMetadataAction,
|
|
SetEditableFieldUpdateAction, SetValidFieldUpdateAction
|
|
} from './object-updates.actions';
|
|
import { OBJECT_UPDATES_TRASH_PATH, objectUpdatesReducer } from './object-updates.reducer';
|
|
import {Relationship} from '../../shared/item-relationships/relationship.model';
|
|
|
|
class NullAction extends RemoveFieldUpdateAction {
|
|
type = null;
|
|
payload = null;
|
|
|
|
constructor() {
|
|
super(null, null);
|
|
}
|
|
}
|
|
|
|
const identifiable1 = {
|
|
uuid: '8222b07e-330d-417b-8d7f-3b82aeaf2320',
|
|
key: 'dc.contributor.author',
|
|
language: null,
|
|
value: 'Smith, John'
|
|
};
|
|
|
|
const identifiable1update = {
|
|
uuid: '8222b07e-330d-417b-8d7f-3b82aeaf2320',
|
|
key: 'dc.contributor.author',
|
|
language: null,
|
|
value: 'Smith, James'
|
|
};
|
|
const identifiable2 = {
|
|
uuid: '26cbb5ce-5786-4e57-a394-b9fcf8eaf241',
|
|
key: 'dc.title',
|
|
language: null,
|
|
value: 'New title'
|
|
};
|
|
const identifiable3 = {
|
|
uuid: 'c5d2c2f7-d757-48bf-84cc-8c9229c8407e',
|
|
key: 'dc.description.abstract',
|
|
language: null,
|
|
value: 'Unchanged value'
|
|
};
|
|
const relationship: Relationship = Object.assign(new Relationship(), {uuid: 'test relationship uuid'});
|
|
|
|
const modDate = new Date(2010, 2, 11);
|
|
const uuid = identifiable1.uuid;
|
|
const url = 'test-object.url/edit';
|
|
describe('objectUpdatesReducer', () => {
|
|
const testState = {
|
|
[url]: {
|
|
fieldStates: {
|
|
[identifiable1.uuid]: {
|
|
editable: true,
|
|
isNew: false,
|
|
isValid: true
|
|
},
|
|
[identifiable2.uuid]: {
|
|
editable: false,
|
|
isNew: true,
|
|
isValid: true
|
|
},
|
|
[identifiable3.uuid]: {
|
|
editable: false,
|
|
isNew: false,
|
|
isValid: false
|
|
},
|
|
},
|
|
fieldUpdates: {
|
|
[identifiable2.uuid]: {
|
|
field: {
|
|
uuid: identifiable2.uuid,
|
|
key: 'dc.titl',
|
|
language: null,
|
|
value: 'New title'
|
|
},
|
|
changeType: FieldChangeType.ADD
|
|
}
|
|
},
|
|
lastModified: modDate,
|
|
virtualMetadataSources: {
|
|
[relationship.uuid]: {[identifiable1.uuid]: true}
|
|
},
|
|
customOrder: {
|
|
initialOrderPages: [
|
|
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
|
],
|
|
newOrderPages: [
|
|
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
|
],
|
|
pageSize: 10,
|
|
changed: false
|
|
}
|
|
}
|
|
};
|
|
|
|
const discardedTestState = {
|
|
[url]: {
|
|
fieldStates: {
|
|
[identifiable1.uuid]: {
|
|
editable: true,
|
|
isNew: false,
|
|
isValid: true
|
|
},
|
|
[identifiable2.uuid]: {
|
|
editable: false,
|
|
isNew: true,
|
|
isValid: true
|
|
},
|
|
[identifiable3.uuid]: {
|
|
editable: false,
|
|
isNew: false,
|
|
isValid: true
|
|
},
|
|
},
|
|
lastModified: modDate,
|
|
virtualMetadataSources: {
|
|
[relationship.uuid]: {[identifiable1.uuid]: true}
|
|
},
|
|
customOrder: {
|
|
initialOrderPages: [
|
|
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
|
],
|
|
newOrderPages: [
|
|
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
|
],
|
|
pageSize: 10,
|
|
changed: false
|
|
}
|
|
},
|
|
[url + OBJECT_UPDATES_TRASH_PATH]: {
|
|
fieldStates: {
|
|
[identifiable1.uuid]: {
|
|
editable: true,
|
|
isNew: false,
|
|
isValid: true
|
|
},
|
|
[identifiable2.uuid]: {
|
|
editable: false,
|
|
isNew: true,
|
|
isValid: true
|
|
},
|
|
[identifiable3.uuid]: {
|
|
editable: false,
|
|
isNew: false,
|
|
isValid: false
|
|
},
|
|
},
|
|
fieldUpdates: {
|
|
[identifiable2.uuid]: {
|
|
field: {
|
|
uuid: identifiable2.uuid,
|
|
key: 'dc.titl',
|
|
language: null,
|
|
value: 'New title'
|
|
},
|
|
changeType: FieldChangeType.ADD
|
|
}
|
|
},
|
|
lastModified: modDate,
|
|
virtualMetadataSources: {
|
|
[relationship.uuid]: {[identifiable1.uuid]: true}
|
|
},
|
|
customOrder: {
|
|
initialOrderPages: [
|
|
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
|
],
|
|
newOrderPages: [
|
|
{ order: [identifiable1.uuid, identifiable2.uuid, identifiable3.uuid] }
|
|
],
|
|
pageSize: 10,
|
|
changed: false
|
|
}
|
|
}
|
|
};
|
|
|
|
deepFreeze(testState);
|
|
|
|
it('should return the current state when no valid actions have been made', () => {
|
|
const action = new NullAction();
|
|
const newState = objectUpdatesReducer(testState, action);
|
|
|
|
expect(newState).toEqual(testState);
|
|
});
|
|
|
|
it('should start with an empty object', () => {
|
|
const action = new NullAction();
|
|
const initialState = objectUpdatesReducer(undefined, action);
|
|
|
|
expect(initialState).toEqual({});
|
|
});
|
|
|
|
it('should perform the INITIALIZE_FIELDS action without affecting the previous state', () => {
|
|
const action = new InitializeFieldsAction(url, [identifiable1, identifiable2], modDate);
|
|
// testState has already been frozen above
|
|
objectUpdatesReducer(testState, action);
|
|
});
|
|
|
|
it('should perform the SET_EDITABLE_FIELD action without affecting the previous state', () => {
|
|
const action = new SetEditableFieldUpdateAction(url, uuid, false);
|
|
// testState has already been frozen above
|
|
objectUpdatesReducer(testState, action);
|
|
});
|
|
|
|
it('should perform the ADD_FIELD action without affecting the previous state', () => {
|
|
const action = new AddFieldUpdateAction(url, identifiable1update, FieldChangeType.UPDATE);
|
|
// testState has already been frozen above
|
|
objectUpdatesReducer(testState, action);
|
|
});
|
|
|
|
it('should perform the DISCARD action without affecting the previous state', () => {
|
|
const action = new DiscardObjectUpdatesAction(url, null);
|
|
// testState has already been frozen above
|
|
objectUpdatesReducer(testState, action);
|
|
});
|
|
|
|
it('should perform the REINSTATE action without affecting the previous state', () => {
|
|
const action = new ReinstateObjectUpdatesAction(url);
|
|
// testState has already been frozen above
|
|
objectUpdatesReducer(testState, action);
|
|
});
|
|
|
|
it('should perform the REMOVE action without affecting the previous state', () => {
|
|
const action = new RemoveFieldUpdateAction(url, uuid);
|
|
// testState has already been frozen above
|
|
objectUpdatesReducer(testState, action);
|
|
});
|
|
|
|
it('should perform the REMOVE_FIELD action without affecting the previous state', () => {
|
|
const action = new RemoveFieldUpdateAction(url, uuid);
|
|
// testState has already been frozen above
|
|
objectUpdatesReducer(testState, action);
|
|
});
|
|
|
|
it('should perform the SELECT_VIRTUAL_METADATA action without affecting the previous state', () => {
|
|
const action = new SelectVirtualMetadataAction(url, relationship.uuid, identifiable1.uuid, true);
|
|
// testState has already been frozen above
|
|
objectUpdatesReducer(testState, action);
|
|
});
|
|
|
|
it('should initialize all fields when the INITIALIZE action is dispatched, based on the payload', () => {
|
|
const action = new InitializeFieldsAction(url, [identifiable1, identifiable3], modDate, [identifiable1.uuid, identifiable3.uuid], 10, 0);
|
|
|
|
const expectedState = {
|
|
[url]: {
|
|
fieldStates: {
|
|
[identifiable1.uuid]: {
|
|
editable: false,
|
|
isNew: false,
|
|
isValid: true
|
|
},
|
|
[identifiable3.uuid]: {
|
|
editable: false,
|
|
isNew: false,
|
|
isValid: true
|
|
},
|
|
},
|
|
fieldUpdates: {},
|
|
virtualMetadataSources: {},
|
|
lastModified: modDate,
|
|
customOrder: {
|
|
initialOrderPages: [
|
|
{ order: [identifiable1.uuid, identifiable3.uuid] }
|
|
],
|
|
newOrderPages: [
|
|
{ order: [identifiable1.uuid, identifiable3.uuid] }
|
|
],
|
|
pageSize: 10,
|
|
changed: false
|
|
}
|
|
}
|
|
};
|
|
const newState = objectUpdatesReducer(testState, action);
|
|
expect(newState).toEqual(expectedState);
|
|
});
|
|
|
|
it('should set the given field\'s fieldStates when the SET_EDITABLE_FIELD action is dispatched, based on the payload', () => {
|
|
const action = new SetEditableFieldUpdateAction(url, identifiable3.uuid, true);
|
|
|
|
const newState = objectUpdatesReducer(testState, action);
|
|
expect(newState[url].fieldStates[identifiable3.uuid].editable).toBeTruthy();
|
|
});
|
|
|
|
it('should set the given field\'s fieldStates when the SET_VALID_FIELD action is dispatched, based on the payload', () => {
|
|
const action = new SetValidFieldUpdateAction(url, identifiable3.uuid, false);
|
|
|
|
const newState = objectUpdatesReducer(testState, action);
|
|
expect(newState[url].fieldStates[identifiable3.uuid].isValid).toBeFalsy();
|
|
});
|
|
|
|
it('should add a given field\'s update to the state when the ADD_FIELD action is dispatched, based on the payload', () => {
|
|
const action = new AddFieldUpdateAction(url, identifiable1update, FieldChangeType.UPDATE);
|
|
|
|
const newState = objectUpdatesReducer(testState, action);
|
|
expect(newState[url].fieldUpdates[identifiable1.uuid].field).toEqual(identifiable1update);
|
|
expect(newState[url].fieldUpdates[identifiable1.uuid].changeType).toEqual(FieldChangeType.UPDATE);
|
|
});
|
|
|
|
it('should discard a given url\'s updates from the state when the DISCARD action is dispatched, based on the payload', () => {
|
|
const action = new DiscardObjectUpdatesAction(url, null);
|
|
|
|
const newState = objectUpdatesReducer(testState, action);
|
|
expect(newState[url].fieldUpdates).toEqual({});
|
|
expect(newState[url + OBJECT_UPDATES_TRASH_PATH]).toEqual(testState[url]);
|
|
});
|
|
|
|
it('should reinstate a given url\'s updates from the state when the REINSTATE action is dispatched, based on the payload', () => {
|
|
const action = new ReinstateObjectUpdatesAction(url);
|
|
|
|
const newState = objectUpdatesReducer(discardedTestState, action);
|
|
expect(newState).toEqual(testState);
|
|
});
|
|
|
|
it('should remove a given url\'s updates from the state when the REMOVE action is dispatched, based on the payload', () => {
|
|
const action = new RemoveObjectUpdatesAction(url);
|
|
|
|
const newState = objectUpdatesReducer(discardedTestState, action);
|
|
expect(newState[url].fieldUpdates).toBeUndefined();
|
|
expect(newState[url + OBJECT_UPDATES_TRASH_PATH]).toBeUndefined();
|
|
});
|
|
|
|
it('should remove all updates from the state when the REMOVE_ALL action is dispatched', () => {
|
|
const action = new RemoveAllObjectUpdatesAction();
|
|
|
|
const newState = objectUpdatesReducer(discardedTestState, action as any);
|
|
expect(newState[url].fieldUpdates).toBeUndefined();
|
|
expect(newState[url + OBJECT_UPDATES_TRASH_PATH]).toBeUndefined();
|
|
});
|
|
|
|
it('should remove a given field\'s update from the state when the REMOVE_FIELD action is dispatched, based on the payload', () => {
|
|
const action = new RemoveFieldUpdateAction(url, uuid);
|
|
|
|
const newState = objectUpdatesReducer(testState, action);
|
|
expect(newState[url].fieldUpdates[uuid]).toBeUndefined();
|
|
});
|
|
|
|
it('should move the custom order from the state when the MOVE action is dispatched', () => {
|
|
const action = new MoveFieldUpdateAction(url, 0, 1, 0, 0);
|
|
|
|
const newState = objectUpdatesReducer(testState, action);
|
|
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);
|
|
});
|
|
});
|