mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-08 02:24:11 +00:00
Refactored Resource Policy service
This commit is contained in:
@@ -84,7 +84,7 @@ import { RegistryMetadatafieldsResponseParsingService } from './data/registry-me
|
|||||||
import { RegistryMetadataschemasResponseParsingService } from './data/registry-metadataschemas-response-parsing.service';
|
import { RegistryMetadataschemasResponseParsingService } from './data/registry-metadataschemas-response-parsing.service';
|
||||||
import { RelationshipTypeService } from './data/relationship-type.service';
|
import { RelationshipTypeService } from './data/relationship-type.service';
|
||||||
import { RelationshipService } from './data/relationship.service';
|
import { RelationshipService } from './data/relationship.service';
|
||||||
import { ResourcePolicyService } from './data/resource-policy.service';
|
import { ResourcePolicyService } from './resource-policy/resource-policy.service';
|
||||||
import { SearchResponseParsingService } from './data/search-response-parsing.service';
|
import { SearchResponseParsingService } from './data/search-response-parsing.service';
|
||||||
import { SiteDataService } from './data/site-data.service';
|
import { SiteDataService } from './data/site-data.service';
|
||||||
import { DSpaceRESTv2Service } from './dspace-rest-v2/dspace-rest-v2.service';
|
import { DSpaceRESTv2Service } from './dspace-rest-v2/dspace-rest-v2.service';
|
||||||
@@ -123,7 +123,7 @@ import { RelationshipType } from './shared/item-relationships/relationship-type.
|
|||||||
import { Relationship } from './shared/item-relationships/relationship.model';
|
import { Relationship } from './shared/item-relationships/relationship.model';
|
||||||
import { Item } from './shared/item.model';
|
import { Item } from './shared/item.model';
|
||||||
import { License } from './shared/license.model';
|
import { License } from './shared/license.model';
|
||||||
import { ResourcePolicy } from './shared/resource-policy.model';
|
import { ResourcePolicy } from './resource-policy/models/resource-policy.model';
|
||||||
import { SearchConfigurationService } from './shared/search/search-configuration.service';
|
import { SearchConfigurationService } from './shared/search/search-configuration.service';
|
||||||
import { SearchFilterService } from './shared/search/search-filter.service';
|
import { SearchFilterService } from './shared/search/search-filter.service';
|
||||||
import { SearchService } from './shared/search/search.service';
|
import { SearchService } from './shared/search/search.service';
|
||||||
|
@@ -1,75 +0,0 @@
|
|||||||
import { HttpClient } from '@angular/common/http';
|
|
||||||
import { cold, getTestScheduler } from 'jasmine-marbles';
|
|
||||||
import { TestScheduler } from 'rxjs/testing';
|
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
|
||||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
|
||||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
|
||||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
|
||||||
import { ResourcePolicy } from '../shared/resource-policy.model';
|
|
||||||
import { RequestService } from './request.service';
|
|
||||||
import { ResourcePolicyService } from './resource-policy.service';
|
|
||||||
|
|
||||||
describe('ResourcePolicyService', () => {
|
|
||||||
let scheduler: TestScheduler;
|
|
||||||
let service: ResourcePolicyService;
|
|
||||||
let requestService: RequestService;
|
|
||||||
let rdbService: RemoteDataBuildService;
|
|
||||||
let objectCache: ObjectCacheService;
|
|
||||||
const testObject = {
|
|
||||||
uuid: '664184ee-b254-45e8-970d-220e5ccc060b'
|
|
||||||
} as ResourcePolicy;
|
|
||||||
const requestURL = `https://rest.api/rest/api/resourcepolicies/${testObject.uuid}`;
|
|
||||||
const requestUUID = '8b3c613a-5a4b-438b-9686-be1d5b4a1c5a';
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
scheduler = getTestScheduler();
|
|
||||||
|
|
||||||
requestService = jasmine.createSpyObj('requestService', {
|
|
||||||
generateRequestId: requestUUID,
|
|
||||||
configure: true
|
|
||||||
});
|
|
||||||
rdbService = jasmine.createSpyObj('rdbService', {
|
|
||||||
buildSingle: cold('a', {
|
|
||||||
a: {
|
|
||||||
payload: testObject
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
objectCache = {} as ObjectCacheService;
|
|
||||||
const halService = {} as HALEndpointService;
|
|
||||||
const notificationsService = {} as NotificationsService;
|
|
||||||
const http = {} as HttpClient;
|
|
||||||
const comparator = {} as any;
|
|
||||||
|
|
||||||
service = new ResourcePolicyService(
|
|
||||||
requestService,
|
|
||||||
rdbService,
|
|
||||||
objectCache,
|
|
||||||
halService,
|
|
||||||
notificationsService,
|
|
||||||
http,
|
|
||||||
comparator
|
|
||||||
);
|
|
||||||
|
|
||||||
spyOn((service as any).dataService, 'findByHref').and.callThrough();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('findByHref', () => {
|
|
||||||
it('should proxy the call to dataservice.findByHref', () => {
|
|
||||||
scheduler.schedule(() => service.findByHref(requestURL));
|
|
||||||
scheduler.flush();
|
|
||||||
|
|
||||||
expect((service as any).dataService.findByHref).toHaveBeenCalledWith(requestURL);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return a RemoteData<ResourcePolicy> for the object with the given URL', () => {
|
|
||||||
const result = service.findByHref(requestURL);
|
|
||||||
const expected = cold('a', {
|
|
||||||
a: {
|
|
||||||
payload: testObject
|
|
||||||
}
|
|
||||||
});
|
|
||||||
expect(result).toBeObservable(expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@@ -5,27 +5,27 @@ export enum ActionType {
|
|||||||
/**
|
/**
|
||||||
* Action of reading, viewing or downloading something
|
* Action of reading, viewing or downloading something
|
||||||
*/
|
*/
|
||||||
READ = 0,
|
READ = 'READ',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action of modifying something
|
* Action of modifying something
|
||||||
*/
|
*/
|
||||||
WRITE = 1,
|
WRITE = 'WRITE',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action of deleting something
|
* Action of deleting something
|
||||||
*/
|
*/
|
||||||
DELETE = 2,
|
DELETE = 'DELETE',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action of adding something to a container
|
* Action of adding something to a container
|
||||||
*/
|
*/
|
||||||
ADD = 3,
|
ADD = 'ADD',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action of removing something from a container
|
* Action of removing something from a container
|
||||||
*/
|
*/
|
||||||
REMOVE = 4,
|
REMOVE = 'REMOVE',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action of performing workflow step 1
|
* Action of performing workflow step 1
|
||||||
@@ -50,15 +50,20 @@ export enum ActionType {
|
|||||||
/**
|
/**
|
||||||
* Default Read policies for Bitstreams submitted to container
|
* Default Read policies for Bitstreams submitted to container
|
||||||
*/
|
*/
|
||||||
DEFAULT_BITSTREAM_READ = 9,
|
DEFAULT_BITSTREAM_READ = 'DEFAULT_BITSTREAM_READ',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Read policies for Items submitted to container
|
* Default Read policies for Items submitted to container
|
||||||
*/
|
*/
|
||||||
DEFAULT_ITEM_READ = 10,
|
DEFAULT_ITEM_READ = 'DEFAULT_ITEM_READ',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Administrative actions
|
* Administrative actions
|
||||||
*/
|
*/
|
||||||
ADMIN = 11,
|
ADMIN = 'ADMIN',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action of withdrawn reading
|
||||||
|
*/
|
||||||
|
WITHDRAWN_READ = 'WITHDRAWN_READ'
|
||||||
}
|
}
|
25
src/app/core/resource-policy/models/policy-type.model.ts
Normal file
25
src/app/core/resource-policy/models/policy-type.model.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Enum representing the Policy Type of a Resource Policy
|
||||||
|
*/
|
||||||
|
export enum PolicyType {
|
||||||
|
/**
|
||||||
|
* A policy in place during the submission
|
||||||
|
*/
|
||||||
|
TYPE_SUBMISSION = 'TYPE_SUBMISSION',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A policy in place during the approval workflow
|
||||||
|
*/
|
||||||
|
TYPE_WORKFLOW = 'TYPE_WORKFLOW',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A policy that has been inherited from a container (the collection)
|
||||||
|
*/
|
||||||
|
TYPE_INHERITED = 'TYPE_INHERITED',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A policy defined by the user during the submission or workflow phase
|
||||||
|
*/
|
||||||
|
TYPE_CUSTOM = 'TYPE_CUSTOM',
|
||||||
|
|
||||||
|
}
|
85
src/app/core/resource-policy/models/resource-policy.model.ts
Normal file
85
src/app/core/resource-policy/models/resource-policy.model.ts
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
import { autoserialize, deserialize, deserializeAs } from 'cerialize';
|
||||||
|
import { typedObject } from '../../cache/builders/build-decorators';
|
||||||
|
import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer';
|
||||||
|
import { ActionType } from './action-type.model';
|
||||||
|
import { CacheableObject } from '../../cache/object-cache.reducer';
|
||||||
|
import { HALLink } from '../../shared/hal-link.model';
|
||||||
|
import { RESOURCE_POLICY } from './resource-policy.resource-type';
|
||||||
|
import { excludeFromEquals } from '../../utilities/equals.decorators';
|
||||||
|
import { ResourceType } from '../../shared/resource-type';
|
||||||
|
import { PolicyType } from './policy-type.model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model class for a Resource Policy
|
||||||
|
*/
|
||||||
|
@typedObject
|
||||||
|
export class ResourcePolicy implements CacheableObject {
|
||||||
|
static type = RESOURCE_POLICY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The identifier for this Resource Policy
|
||||||
|
*/
|
||||||
|
@autoserialize
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name for this Resource Policy
|
||||||
|
*/
|
||||||
|
@autoserialize
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The description for this Resource Policy
|
||||||
|
*/
|
||||||
|
@autoserialize
|
||||||
|
description: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The classification or this Resource Policy
|
||||||
|
*/
|
||||||
|
@autoserialize
|
||||||
|
policyType: PolicyType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The action that is allowed by this Resource Policy
|
||||||
|
*/
|
||||||
|
@autoserialize
|
||||||
|
action: ActionType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The first day of validity of the policy (format YYYY-MM-DD)
|
||||||
|
*/
|
||||||
|
@autoserialize
|
||||||
|
startDate: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last day of validity of the policy (format YYYY-MM-DD)
|
||||||
|
*/
|
||||||
|
@autoserialize
|
||||||
|
endDate: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The object type
|
||||||
|
*/
|
||||||
|
@excludeFromEquals
|
||||||
|
@autoserialize
|
||||||
|
type: ResourceType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The universally unique identifier for this Resource Policy
|
||||||
|
* This UUID is generated client-side and isn't used by the backend.
|
||||||
|
* It is based on the ID, so it will be the same for each refresh.
|
||||||
|
*/
|
||||||
|
@deserializeAs(new IDToUUIDSerializer('resource-policy'), 'id')
|
||||||
|
uuid: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link HALLink}s for this ResourcePolicy
|
||||||
|
*/
|
||||||
|
@deserialize
|
||||||
|
_links: {
|
||||||
|
eperson: HALLink,
|
||||||
|
group: HALLink,
|
||||||
|
self: HALLink,
|
||||||
|
}
|
||||||
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
import { ResourceType } from './resource-type';
|
import { ResourceType } from '../../shared/resource-type';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The resource type for ResourcePolicy
|
* The resource type for ResourcePolicy
|
||||||
@@ -6,4 +6,4 @@ import { ResourceType } from './resource-type';
|
|||||||
* Needs to be in a separate file to prevent circular
|
* Needs to be in a separate file to prevent circular
|
||||||
* dependencies in webpack.
|
* dependencies in webpack.
|
||||||
*/
|
*/
|
||||||
export const RESOURCE_POLICY = new ResourceType('resourcePolicy');
|
export const RESOURCE_POLICY = new ResourceType('resourcepolicy');
|
263
src/app/core/resource-policy/resource-policy.service.spec.ts
Normal file
263
src/app/core/resource-policy/resource-policy.service.spec.ts
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
|
||||||
|
import { cold, getTestScheduler, hot } from 'jasmine-marbles';
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
import { TestScheduler } from 'rxjs/testing';
|
||||||
|
|
||||||
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||||
|
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||||
|
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||||
|
import { RequestService } from '../data/request.service';
|
||||||
|
import { ResourcePolicyService } from './resource-policy.service';
|
||||||
|
import { PolicyType } from './models/policy-type.model';
|
||||||
|
import { ActionType } from './models/action-type.model';
|
||||||
|
import { FindListOptions } from '../data/request.models';
|
||||||
|
import { SearchParam } from '../cache/models/search-param.model';
|
||||||
|
import { PageInfo } from '../shared/page-info.model';
|
||||||
|
import { PaginatedList } from '../data/paginated-list';
|
||||||
|
import { createSuccessfulRemoteDataObject } from '../../shared/testing/utils';
|
||||||
|
import { RequestEntry } from '../data/request.reducer';
|
||||||
|
import { RestResponse } from '../cache/response.models';
|
||||||
|
|
||||||
|
describe('ResourcePolicyService', () => {
|
||||||
|
let scheduler: TestScheduler;
|
||||||
|
let service: ResourcePolicyService;
|
||||||
|
let requestService: RequestService;
|
||||||
|
let rdbService: RemoteDataBuildService;
|
||||||
|
let objectCache: ObjectCacheService;
|
||||||
|
let halService: HALEndpointService;
|
||||||
|
|
||||||
|
const resourcePolicy = {
|
||||||
|
id: '1',
|
||||||
|
name: null,
|
||||||
|
description: null,
|
||||||
|
policyType: PolicyType.TYPE_SUBMISSION,
|
||||||
|
action: ActionType.READ,
|
||||||
|
startDate : null,
|
||||||
|
endDate : null,
|
||||||
|
type: 'resourcepolicy',
|
||||||
|
uuid: 'resource-policy-1',
|
||||||
|
_links: {
|
||||||
|
eperson: {
|
||||||
|
href: 'https://rest.api/rest/api/eperson'
|
||||||
|
},
|
||||||
|
group: {
|
||||||
|
href: 'https://rest.api/rest/api/group'
|
||||||
|
},
|
||||||
|
self: {
|
||||||
|
href: 'https://rest.api/rest/api/resourcepolicies/1'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const anotherResourcePolicy = {
|
||||||
|
id: '2',
|
||||||
|
name: null,
|
||||||
|
description: null,
|
||||||
|
policyType: PolicyType.TYPE_SUBMISSION,
|
||||||
|
action: ActionType.WRITE,
|
||||||
|
startDate : null,
|
||||||
|
endDate : null,
|
||||||
|
type: 'resourcepolicy',
|
||||||
|
uuid: 'resource-policy-2',
|
||||||
|
_links: {
|
||||||
|
eperson: {
|
||||||
|
href: 'https://rest.api/rest/api/eperson'
|
||||||
|
},
|
||||||
|
group: {
|
||||||
|
href: 'https://rest.api/rest/api/group'
|
||||||
|
},
|
||||||
|
self: {
|
||||||
|
href: 'https://rest.api/rest/api/resourcepolicies/1'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const endpointURL = `https://rest.api/rest/api/resourcepolicies`;
|
||||||
|
const requestURL = `https://rest.api/rest/api/resourcepolicies/${resourcePolicy.id}`;
|
||||||
|
const requestUUID = '8b3c613a-5a4b-438b-9686-be1d5b4a1c5a';
|
||||||
|
const resourcePolicyId = '1';
|
||||||
|
const epersonUUID = '8b39g7ya-5a4b-438b-9686-be1d5b4a1c5a';
|
||||||
|
const groupUUID = '8b39g7ya-5a4b-36987-9686-be1d5b4a1c5a';
|
||||||
|
const resourceUUID = '8b39g7ya-5a4b-438b-851f-be1d5b4a1c5a';
|
||||||
|
|
||||||
|
const pageInfo = new PageInfo();
|
||||||
|
const array = [resourcePolicy, anotherResourcePolicy ];
|
||||||
|
const paginatedList = new PaginatedList(pageInfo, array);
|
||||||
|
const resourcePolicyRD = createSuccessfulRemoteDataObject(resourcePolicy);
|
||||||
|
const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList);
|
||||||
|
const responseCacheEntry = new RequestEntry();
|
||||||
|
responseCacheEntry.response = new RestResponse(true, 200, 'Success');
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
scheduler = getTestScheduler();
|
||||||
|
|
||||||
|
halService = jasmine.createSpyObj('halService', {
|
||||||
|
getEndpoint: cold('a', { a: endpointURL })
|
||||||
|
});
|
||||||
|
|
||||||
|
requestService = jasmine.createSpyObj('requestService', {
|
||||||
|
generateRequestId: requestUUID,
|
||||||
|
configure: true,
|
||||||
|
removeByHrefSubstring: {},
|
||||||
|
getByHref: observableOf(responseCacheEntry),
|
||||||
|
});
|
||||||
|
rdbService = jasmine.createSpyObj('rdbService', {
|
||||||
|
buildSingle: hot('a|', {
|
||||||
|
a: resourcePolicyRD
|
||||||
|
}),
|
||||||
|
buildList: hot('a|', {
|
||||||
|
a: paginatedListRD
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
objectCache = {} as ObjectCacheService;
|
||||||
|
const notificationsService = {} as NotificationsService;
|
||||||
|
const http = {} as HttpClient;
|
||||||
|
const comparator = {} as any;
|
||||||
|
|
||||||
|
service = new ResourcePolicyService(
|
||||||
|
requestService,
|
||||||
|
rdbService,
|
||||||
|
objectCache,
|
||||||
|
halService,
|
||||||
|
notificationsService,
|
||||||
|
http,
|
||||||
|
comparator
|
||||||
|
);
|
||||||
|
|
||||||
|
spyOn((service as any).dataService, 'findById').and.callThrough();
|
||||||
|
spyOn((service as any).dataService, 'findByHref').and.callThrough();
|
||||||
|
spyOn((service as any).dataService, 'searchBy').and.callThrough();
|
||||||
|
spyOn((service as any).dataService, 'getSearchByHref').and.returnValue(observableOf(requestURL));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('findById', () => {
|
||||||
|
it('should proxy the call to dataservice.findById', () => {
|
||||||
|
scheduler.schedule(() => service.findById(resourcePolicyId));
|
||||||
|
scheduler.flush();
|
||||||
|
|
||||||
|
expect((service as any).dataService.findById).toHaveBeenCalledWith(resourcePolicyId);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a RemoteData<ResourcePolicy> for the object with the given id', () => {
|
||||||
|
const result = service.findById(resourcePolicyId);
|
||||||
|
const expected = cold('a|', {
|
||||||
|
a: resourcePolicyRD
|
||||||
|
});
|
||||||
|
expect(result).toBeObservable(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('findByHref', () => {
|
||||||
|
it('should proxy the call to dataservice.findByHref', () => {
|
||||||
|
scheduler.schedule(() => service.findByHref(requestURL));
|
||||||
|
scheduler.flush();
|
||||||
|
|
||||||
|
expect((service as any).dataService.findByHref).toHaveBeenCalledWith(requestURL);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a RemoteData<ResourcePolicy> for the object with the given URL', () => {
|
||||||
|
const result = service.findByHref(requestURL);
|
||||||
|
const expected = cold('a|', {
|
||||||
|
a: resourcePolicyRD
|
||||||
|
});
|
||||||
|
expect(result).toBeObservable(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('searchByEPerson', () => {
|
||||||
|
it('should proxy the call to dataservice.searchBy', () => {
|
||||||
|
const options = new FindListOptions();
|
||||||
|
options.searchParams = [new SearchParam('uuid', epersonUUID)];
|
||||||
|
scheduler.schedule(() => service.searchByEPerson(epersonUUID));
|
||||||
|
scheduler.flush();
|
||||||
|
|
||||||
|
expect((service as any).dataService.searchBy).toHaveBeenCalledWith((service as any).searchByEPersonMethod, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should proxy the call to dataservice.searchBy with additional search param', () => {
|
||||||
|
const options = new FindListOptions();
|
||||||
|
options.searchParams = [
|
||||||
|
new SearchParam('uuid', epersonUUID),
|
||||||
|
new SearchParam('resource', resourceUUID),
|
||||||
|
];
|
||||||
|
scheduler.schedule(() => service.searchByEPerson(epersonUUID, resourceUUID));
|
||||||
|
scheduler.flush();
|
||||||
|
|
||||||
|
expect((service as any).dataService.searchBy).toHaveBeenCalledWith((service as any).searchByEPersonMethod, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a RemoteData<PaginatedList<ResourcePolicy>) for the search', () => {
|
||||||
|
const result = service.searchByEPerson(epersonUUID, resourceUUID);
|
||||||
|
const expected = cold('a|', {
|
||||||
|
a: paginatedListRD
|
||||||
|
});
|
||||||
|
expect(result).toBeObservable(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('searchByGroup', () => {
|
||||||
|
it('should proxy the call to dataservice.searchBy', () => {
|
||||||
|
const options = new FindListOptions();
|
||||||
|
options.searchParams = [new SearchParam('uuid', groupUUID)];
|
||||||
|
scheduler.schedule(() => service.searchByGroup(groupUUID));
|
||||||
|
scheduler.flush();
|
||||||
|
|
||||||
|
expect((service as any).dataService.searchBy).toHaveBeenCalledWith((service as any).searchByGroupMethod, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should proxy the call to dataservice.searchBy with additional search param', () => {
|
||||||
|
const options = new FindListOptions();
|
||||||
|
options.searchParams = [
|
||||||
|
new SearchParam('uuid', groupUUID),
|
||||||
|
new SearchParam('resource', resourceUUID),
|
||||||
|
];
|
||||||
|
scheduler.schedule(() => service.searchByGroup(groupUUID, resourceUUID));
|
||||||
|
scheduler.flush();
|
||||||
|
|
||||||
|
expect((service as any).dataService.searchBy).toHaveBeenCalledWith((service as any).searchByGroupMethod, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a RemoteData<PaginatedList<ResourcePolicy>) for the search', () => {
|
||||||
|
const result = service.searchByGroup(groupUUID);
|
||||||
|
const expected = cold('a|', {
|
||||||
|
a: paginatedListRD
|
||||||
|
});
|
||||||
|
expect(result).toBeObservable(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('searchByResource', () => {
|
||||||
|
it('should proxy the call to dataservice.searchBy', () => {
|
||||||
|
const options = new FindListOptions();
|
||||||
|
options.searchParams = [new SearchParam('uuid', resourceUUID)];
|
||||||
|
scheduler.schedule(() => service.searchByResource(resourceUUID));
|
||||||
|
scheduler.flush();
|
||||||
|
|
||||||
|
expect((service as any).dataService.searchBy).toHaveBeenCalledWith((service as any).searchByResourceMethod, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should proxy the call to dataservice.searchBy with additional search param', () => {
|
||||||
|
const action = ActionType.READ;
|
||||||
|
const options = new FindListOptions();
|
||||||
|
options.searchParams = [
|
||||||
|
new SearchParam('uuid', resourceUUID),
|
||||||
|
new SearchParam('action', action),
|
||||||
|
];
|
||||||
|
scheduler.schedule(() => service.searchByResource(resourceUUID, action));
|
||||||
|
scheduler.flush();
|
||||||
|
|
||||||
|
expect((service as any).dataService.searchBy).toHaveBeenCalledWith((service as any).searchByResourceMethod, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a RemoteData<PaginatedList<ResourcePolicy>) for the search', () => {
|
||||||
|
const result = service.searchByResource(resourceUUID);
|
||||||
|
const expected = cold('a|', {
|
||||||
|
a: paginatedListRD
|
||||||
|
});
|
||||||
|
expect(result).toBeObservable(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@@ -11,16 +11,19 @@ import { RequestService } from '../data/request.service';
|
|||||||
import { FindListOptions } from '../data/request.models';
|
import { FindListOptions } from '../data/request.models';
|
||||||
import { Collection } from '../shared/collection.model';
|
import { Collection } from '../shared/collection.model';
|
||||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||||
import { ResourcePolicy } from '../shared/resource-policy.model';
|
import { ResourcePolicy } from './models/resource-policy.model';
|
||||||
import { RemoteData } from '../data/remote-data';
|
import { RemoteData } from '../data/remote-data';
|
||||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||||
import { CoreState } from '../core.reducers';
|
import { CoreState } from '../core.reducers';
|
||||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { RESOURCE_POLICY } from '../shared/resource-policy.resource-type';
|
import { RESOURCE_POLICY } from './models/resource-policy.resource-type';
|
||||||
import { ChangeAnalyzer } from './change-analyzer';
|
import { ChangeAnalyzer } from '../data/change-analyzer';
|
||||||
import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service';
|
import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service';
|
||||||
import { PaginatedList } from './paginated-list';
|
import { PaginatedList } from '../data/paginated-list';
|
||||||
|
import { ActionType } from './models/action-type.model';
|
||||||
|
import { SearchParam } from '../cache/models/search-param.model';
|
||||||
|
import { isNotEmpty } from '../../shared/empty.util';
|
||||||
|
|
||||||
/* tslint:disable:max-classes-per-file */
|
/* tslint:disable:max-classes-per-file */
|
||||||
|
|
||||||
@@ -51,6 +54,9 @@ class DataServiceImpl extends DataService<ResourcePolicy> {
|
|||||||
@dataService(RESOURCE_POLICY)
|
@dataService(RESOURCE_POLICY)
|
||||||
export class ResourcePolicyService {
|
export class ResourcePolicyService {
|
||||||
private dataService: DataServiceImpl;
|
private dataService: DataServiceImpl;
|
||||||
|
protected searchByEPersonMethod = 'eperson';
|
||||||
|
protected searchByGroupMethod = 'group';
|
||||||
|
protected searchByResourceMethod = 'resource';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected requestService: RequestService,
|
protected requestService: RequestService,
|
||||||
@@ -74,13 +80,13 @@ export class ResourcePolicyService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of observables of {@link RemoteData} of {@link ResourcePolicy}s, based on an href, with a list of {@link FollowLinkConfig},
|
* Returns an observable of {@link RemoteData} of a {@link ResourcePolicy}, based on its ID, with a list of {@link FollowLinkConfig},
|
||||||
* to automatically resolve {@link HALLink}s of the {@link ResourcePolicy}
|
* to automatically resolve {@link HALLink}s of the object
|
||||||
* @param href The url of the {@link ResourcePolicy} we want to retrieve
|
* @param id ID of {@link ResourcePolicy} we want to retrieve
|
||||||
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
||||||
*/
|
*/
|
||||||
findAllByHref(href: string, findListOptions: FindListOptions = {}, ...linksToFollow: Array<FollowLinkConfig<ResourcePolicy>>): Observable<RemoteData<PaginatedList<ResourcePolicy>>> {
|
findById(id: string, ...linksToFollow: Array<FollowLinkConfig<ResourcePolicy>>): Observable<RemoteData<ResourcePolicy>> {
|
||||||
return this.dataService.findAllByHref(href, findListOptions, ...linksToFollow);
|
return this.dataService.findById(id, ...linksToFollow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -92,4 +98,53 @@ export class ResourcePolicyService {
|
|||||||
getDefaultAccessConditionsFor(collection: Collection, findListOptions?: FindListOptions): Observable<RemoteData<PaginatedList<ResourcePolicy>>> {
|
getDefaultAccessConditionsFor(collection: Collection, findListOptions?: FindListOptions): Observable<RemoteData<PaginatedList<ResourcePolicy>>> {
|
||||||
return this.dataService.findAllByHref(collection._links.defaultAccessConditions.href, findListOptions);
|
return this.dataService.findAllByHref(collection._links.defaultAccessConditions.href, findListOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the {@link ResourcePolicy} list for a {@link EPerson}
|
||||||
|
*
|
||||||
|
* @param UUID UUID of a given {@link EPerson}
|
||||||
|
* @param resourceUUID Limit the returned policies to the specified DSO
|
||||||
|
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
||||||
|
*/
|
||||||
|
searchByEPerson(UUID: string, resourceUUID?: string, ...linksToFollow: Array<FollowLinkConfig<ResourcePolicy>>) {
|
||||||
|
const options = new FindListOptions();
|
||||||
|
options.searchParams = [new SearchParam('uuid', UUID)];
|
||||||
|
if (isNotEmpty(resourceUUID)) {
|
||||||
|
options.searchParams.push(new SearchParam('resource', resourceUUID))
|
||||||
|
}
|
||||||
|
return this.dataService.searchBy(this.searchByEPersonMethod, options, ...linksToFollow)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the {@link ResourcePolicy} list for a {@link Group}
|
||||||
|
*
|
||||||
|
* @param UUID UUID of a given {@link Group}
|
||||||
|
* @param resourceUUID Limit the returned policies to the specified DSO
|
||||||
|
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
||||||
|
*/
|
||||||
|
searchByGroup(UUID: string, resourceUUID?: string, ...linksToFollow: Array<FollowLinkConfig<ResourcePolicy>>) {
|
||||||
|
const options = new FindListOptions();
|
||||||
|
options.searchParams = [new SearchParam('uuid', UUID)];
|
||||||
|
if (isNotEmpty(resourceUUID)) {
|
||||||
|
options.searchParams.push(new SearchParam('resource', resourceUUID))
|
||||||
|
}
|
||||||
|
return this.dataService.searchBy(this.searchByGroupMethod, options, ...linksToFollow)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the {@link ResourcePolicy} list for a given DSO
|
||||||
|
*
|
||||||
|
* @param UUID UUID of a given DSO
|
||||||
|
* @param action Limit the returned policies to the specified {@link ActionType}
|
||||||
|
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
||||||
|
*/
|
||||||
|
searchByResource(UUID: string, action?: ActionType, ...linksToFollow: Array<FollowLinkConfig<ResourcePolicy>>) {
|
||||||
|
const options = new FindListOptions();
|
||||||
|
options.searchParams = [new SearchParam('uuid', UUID)];
|
||||||
|
if (isNotEmpty(action)) {
|
||||||
|
options.searchParams.push(new SearchParam('action', action))
|
||||||
|
}
|
||||||
|
return this.dataService.searchBy(this.searchByResourceMethod, options, ...linksToFollow)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@@ -10,8 +10,8 @@ import { DSpaceObject } from './dspace-object.model';
|
|||||||
import { HALLink } from './hal-link.model';
|
import { HALLink } from './hal-link.model';
|
||||||
import { License } from './license.model';
|
import { License } from './license.model';
|
||||||
import { LICENSE } from './license.resource-type';
|
import { LICENSE } from './license.resource-type';
|
||||||
import { ResourcePolicy } from './resource-policy.model';
|
import { ResourcePolicy } from '../resource-policy/models/resource-policy.model';
|
||||||
import { RESOURCE_POLICY } from './resource-policy.resource-type';
|
import { RESOURCE_POLICY } from '../resource-policy/models/resource-policy.resource-type';
|
||||||
import { COMMUNITY } from './community.resource-type';
|
import { COMMUNITY } from './community.resource-type';
|
||||||
import { Community } from './community.model';
|
import { Community } from './community.model';
|
||||||
import { ChildHALResource } from './child-hal-resource.model';
|
import { ChildHALResource } from './child-hal-resource.model';
|
||||||
|
@@ -1,58 +0,0 @@
|
|||||||
import { autoserialize, deserialize, deserializeAs } from 'cerialize';
|
|
||||||
import { typedObject } from '../cache/builders/build-decorators';
|
|
||||||
import { IDToUUIDSerializer } from '../cache/id-to-uuid-serializer';
|
|
||||||
import { ActionType } from '../cache/models/action-type.model';
|
|
||||||
import { CacheableObject } from '../cache/object-cache.reducer';
|
|
||||||
import { excludeFromEquals } from '../utilities/equals.decorators';
|
|
||||||
import { HALLink } from './hal-link.model';
|
|
||||||
import { RESOURCE_POLICY } from './resource-policy.resource-type';
|
|
||||||
import { ResourceType } from './resource-type';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Model class for a Resource Policy
|
|
||||||
*/
|
|
||||||
@typedObject
|
|
||||||
export class ResourcePolicy implements CacheableObject {
|
|
||||||
static type = RESOURCE_POLICY;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The object type
|
|
||||||
*/
|
|
||||||
@excludeFromEquals
|
|
||||||
@autoserialize
|
|
||||||
type: ResourceType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The action that is allowed by this Resource Policy
|
|
||||||
*/
|
|
||||||
@autoserialize
|
|
||||||
action: ActionType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name for this Resource Policy
|
|
||||||
*/
|
|
||||||
@autoserialize
|
|
||||||
name: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The uuid of the Group this Resource Policy applies to
|
|
||||||
*/
|
|
||||||
@autoserialize
|
|
||||||
groupUUID: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The universally unique identifier for this Resource Policy
|
|
||||||
* This UUID is generated client-side and isn't used by the backend.
|
|
||||||
* It is based on the ID, so it will be the same for each refresh.
|
|
||||||
*/
|
|
||||||
@deserializeAs(new IDToUUIDSerializer('resource-policy'), 'id')
|
|
||||||
uuid: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link HALLink}s for this ResourcePolicy
|
|
||||||
*/
|
|
||||||
@deserialize
|
|
||||||
_links: {
|
|
||||||
self: HALLink,
|
|
||||||
}
|
|
||||||
}
|
|
@@ -3,7 +3,7 @@ import { Component, Input, OnInit } from '@angular/core';
|
|||||||
import { find } from 'rxjs/operators';
|
import { find } from 'rxjs/operators';
|
||||||
|
|
||||||
import { GroupDataService } from '../../../../core/eperson/group-data.service';
|
import { GroupDataService } from '../../../../core/eperson/group-data.service';
|
||||||
import { ResourcePolicy } from '../../../../core/shared/resource-policy.model';
|
import { ResourcePolicy } from '../../../../core/resource-policy/models/resource-policy.model';
|
||||||
import { isEmpty } from '../../../../shared/empty.util';
|
import { isEmpty } from '../../../../shared/empty.util';
|
||||||
import { Group } from '../../../../core/eperson/models/group.model';
|
import { Group } from '../../../../core/eperson/models/group.model';
|
||||||
import { RemoteData } from '../../../../core/data/remote-data';
|
import { RemoteData } from '../../../../core/data/remote-data';
|
||||||
|
@@ -19,7 +19,8 @@ import {
|
|||||||
mockSubmissionId,
|
mockSubmissionId,
|
||||||
mockSubmissionState,
|
mockSubmissionState,
|
||||||
mockUploadConfigResponse,
|
mockUploadConfigResponse,
|
||||||
mockUploadConfigResponseNotRequired, mockUploadFiles,
|
mockUploadConfigResponseNotRequired,
|
||||||
|
mockUploadFiles,
|
||||||
} from '../../../shared/mocks/mock-submission';
|
} from '../../../shared/mocks/mock-submission';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
@@ -28,10 +29,10 @@ import { SectionUploadService } from './section-upload.service';
|
|||||||
import { SubmissionSectionUploadComponent } from './section-upload.component';
|
import { SubmissionSectionUploadComponent } from './section-upload.component';
|
||||||
import { CollectionDataService } from '../../../core/data/collection-data.service';
|
import { CollectionDataService } from '../../../core/data/collection-data.service';
|
||||||
import { GroupDataService } from '../../../core/eperson/group-data.service';
|
import { GroupDataService } from '../../../core/eperson/group-data.service';
|
||||||
import { cold, hot } from 'jasmine-marbles';
|
import { cold } from 'jasmine-marbles';
|
||||||
import { Collection } from '../../../core/shared/collection.model';
|
import { Collection } from '../../../core/shared/collection.model';
|
||||||
import { ResourcePolicy } from '../../../core/shared/resource-policy.model';
|
import { ResourcePolicy } from '../../../core/resource-policy/models/resource-policy.model';
|
||||||
import { ResourcePolicyService } from '../../../core/data/resource-policy.service';
|
import { ResourcePolicyService } from '../../../core/resource-policy/resource-policy.service';
|
||||||
import { ConfigData } from '../../../core/config/config-data';
|
import { ConfigData } from '../../../core/config/config-data';
|
||||||
import { PageInfo } from '../../../core/shared/page-info.model';
|
import { PageInfo } from '../../../core/shared/page-info.model';
|
||||||
import { Group } from '../../../core/eperson/models/group.model';
|
import { Group } from '../../../core/eperson/models/group.model';
|
||||||
|
@@ -1,15 +1,14 @@
|
|||||||
import { ChangeDetectorRef, Component, Inject } from '@angular/core';
|
import { ChangeDetectorRef, Component, Inject } from '@angular/core';
|
||||||
|
|
||||||
import { BehaviorSubject, combineLatest as observableCombineLatest, Observable, Subscription} from 'rxjs';
|
import { BehaviorSubject, combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs';
|
||||||
import { distinctUntilChanged, filter, find, flatMap, map, reduce, take, tap } from 'rxjs/operators';
|
import { distinctUntilChanged, filter, find, flatMap, map, reduce, take, tap } from 'rxjs/operators';
|
||||||
import { followLink } from '../../../shared/utils/follow-link-config.model';
|
|
||||||
|
|
||||||
import { SectionModelComponent } from '../models/section.model';
|
import { SectionModelComponent } from '../models/section.model';
|
||||||
import { hasValue, isNotEmpty, isNotUndefined, isUndefined } from '../../../shared/empty.util';
|
import { hasValue, isNotEmpty, isNotUndefined, isUndefined } from '../../../shared/empty.util';
|
||||||
import { SectionUploadService } from './section-upload.service';
|
import { SectionUploadService } from './section-upload.service';
|
||||||
import { CollectionDataService } from '../../../core/data/collection-data.service';
|
import { CollectionDataService } from '../../../core/data/collection-data.service';
|
||||||
import { GroupDataService } from '../../../core/eperson/group-data.service';
|
import { GroupDataService } from '../../../core/eperson/group-data.service';
|
||||||
import { ResourcePolicyService } from '../../../core/data/resource-policy.service';
|
import { ResourcePolicyService } from '../../../core/resource-policy/resource-policy.service';
|
||||||
import { SubmissionUploadsConfigService } from '../../../core/config/submission-uploads-config.service';
|
import { SubmissionUploadsConfigService } from '../../../core/config/submission-uploads-config.service';
|
||||||
import { SubmissionUploadsModel } from '../../../core/config/models/config-submission-uploads.model';
|
import { SubmissionUploadsModel } from '../../../core/config/models/config-submission-uploads.model';
|
||||||
import { SubmissionFormsModel } from '../../../core/config/models/config-submission-forms.model';
|
import { SubmissionFormsModel } from '../../../core/config/models/config-submission-forms.model';
|
||||||
@@ -23,7 +22,6 @@ import { Group } from '../../../core/eperson/models/group.model';
|
|||||||
import { SectionsService } from '../sections.service';
|
import { SectionsService } from '../sections.service';
|
||||||
import { SubmissionService } from '../../submission.service';
|
import { SubmissionService } from '../../submission.service';
|
||||||
import { Collection } from '../../../core/shared/collection.model';
|
import { Collection } from '../../../core/shared/collection.model';
|
||||||
import { ResourcePolicy } from '../../../core/shared/resource-policy.model';
|
|
||||||
import { AccessConditionOption } from '../../../core/config/models/config-access-condition-option.model';
|
import { AccessConditionOption } from '../../../core/config/models/config-access-condition-option.model';
|
||||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user