mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
Merge branch 'master' into improve-i18n-files
This commit is contained in:
@@ -11,7 +11,7 @@ language: node_js
|
||||
|
||||
node_js:
|
||||
- "8"
|
||||
- "9"
|
||||
- "10"
|
||||
|
||||
cache:
|
||||
yarn: true
|
||||
|
@@ -14,7 +14,7 @@ If you're looking for the 2016 Angular 2 DSpace UI prototype, you can find it [h
|
||||
Quick start
|
||||
-----------
|
||||
|
||||
**Ensure you're running [Node](https://nodejs.org) >= `v8.0.x`, [npm](https://www.npmjs.com/) >= `v5.x` and [yarn](https://yarnpkg.com) >= `v1.x`**
|
||||
**Ensure you're running [Node](https://nodejs.org) `v8.0.x` or `v10.0.x`, [npm](https://www.npmjs.com/) >= `v5.x` and [yarn](https://yarnpkg.com) >= `v1.x`**
|
||||
|
||||
```bash
|
||||
# clone the repo
|
||||
@@ -65,7 +65,7 @@ Requirements
|
||||
------------
|
||||
|
||||
- [Node.js](https://nodejs.org), [npm](https://www.npmjs.com/), and [yarn](https://yarnpkg.com)
|
||||
- Ensure you're running node >= `v8.x`, npm >= `v5.x` and yarn >= `v1.x`
|
||||
- Ensure you're running node `v8.x` or `v10.x`, npm >= `v5.x` and yarn >= `v1.x`
|
||||
|
||||
If you have [`nvm`](https://github.com/creationix/nvm#install-script) or [`nvm-windows`](https://github.com/coreybutler/nvm-windows) installed, which is highly recommended, you can run `nvm install --lts && nvm use` to install and start using the latest Node LTS.
|
||||
|
||||
|
@@ -13,7 +13,7 @@ module.exports = {
|
||||
host: 'dspace7.4science.cloud',
|
||||
port: 443,
|
||||
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
|
||||
nameSpace: '/dspace-spring-rest/api'
|
||||
nameSpace: '/server/api'
|
||||
},
|
||||
// Caching settings
|
||||
cache: {
|
||||
|
18
package.json
18
package.json
@@ -8,7 +8,7 @@
|
||||
},
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
"node": "8.* || >= 10.*"
|
||||
},
|
||||
"scripts": {
|
||||
"global": "npm install -g @angular/cli marked node-gyp nodemon node-nightly npm-check-updates npm-run-all rimraf typescript ts-node typedoc webpack webpack-bundle-analyzer pm2 rollup",
|
||||
@@ -62,7 +62,9 @@
|
||||
"webdriver:update": "node node_modules/protractor/bin/webdriver-manager update --standalone --gecko false",
|
||||
"lint": "tslint \"src/**/*.ts\" && tslint \"e2e/**/*.ts\"",
|
||||
"docs": "typedoc --options typedoc.json ./src/",
|
||||
"coverage": "http-server -c-1 -o -p 9875 ./coverage"
|
||||
"coverage": "http-server -c-1 -o -p 9875 ./coverage",
|
||||
"postinstall": "yarn run patch-protractor",
|
||||
"patch-protractor": "ncp node_modules/webdriver-manager node_modules/protractor/node_modules/webdriver-manager"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/animations": "^6.1.4",
|
||||
@@ -121,7 +123,7 @@
|
||||
"ngx-moment": "^3.1.0",
|
||||
"ngx-pagination": "3.0.3",
|
||||
"nouislider": "^11.0.0",
|
||||
"pem": "1.12.3",
|
||||
"pem": "1.13.2",
|
||||
"reflect-metadata": "0.1.12",
|
||||
"rxjs": "6.2.2",
|
||||
"rxjs-spy": "^7.5.1",
|
||||
@@ -169,7 +171,7 @@
|
||||
"codelyzer": "^4.4.4",
|
||||
"compression-webpack-plugin": "^1.1.6",
|
||||
"copy-webpack-plugin": "^4.4.1",
|
||||
"copyfiles": "^2.1.0",
|
||||
"copyfiles": "^2.1.1",
|
||||
"coveralls": "3.0.0",
|
||||
"css-loader": "1.0.0",
|
||||
"cssnano": "^4.1.10",
|
||||
@@ -192,8 +194,9 @@
|
||||
"karma-remap-coverage": "^0.1.5",
|
||||
"karma-remap-istanbul": "0.6.0",
|
||||
"karma-sourcemap-loader": "0.3.7",
|
||||
"karma-webdriver-launcher": "1.0.5",
|
||||
"karma-webdriver-launcher": "^1.0.7",
|
||||
"karma-webpack": "3.0.0",
|
||||
"ncp": "^2.0.0",
|
||||
"ngrx-store-freeze": "^0.2.4",
|
||||
"node-sass": "^4.11.0",
|
||||
"nodemon": "^1.15.0",
|
||||
@@ -206,7 +209,7 @@
|
||||
"postcss-loader": "^3.0.0",
|
||||
"postcss-responsive-type": "1.0.0",
|
||||
"postcss-smart-import": "0.7.6",
|
||||
"protractor": "^5.3.0",
|
||||
"protractor": "^5.4.2",
|
||||
"protractor-istanbul-plugin": "2.0.0",
|
||||
"raw-loader": "0.5.1",
|
||||
"resolve-url-loader": "^2.3.0",
|
||||
@@ -227,10 +230,11 @@
|
||||
"tslint": "5.11.0",
|
||||
"typedoc": "^0.9.0",
|
||||
"typescript": "^2.9.1",
|
||||
"webdriver-manager": "^12.1.6",
|
||||
"webpack": "^4.17.1",
|
||||
"webpack-bundle-analyzer": "^3.3.2",
|
||||
"webpack-dev-middleware": "3.2.0",
|
||||
"webpack-dev-server": "^3.1.5",
|
||||
"webpack-dev-server": "^3.1.11",
|
||||
"webpack-import-glob-loader": "^1.6.3",
|
||||
"webpack-merge": "4.1.4",
|
||||
"webpack-node-externals": "1.7.2"
|
||||
|
@@ -5,7 +5,7 @@
|
||||
var SpecReporter = require('jasmine-spec-reporter').SpecReporter;
|
||||
|
||||
exports.config = {
|
||||
allScriptsTimeout: 11000,
|
||||
allScriptsTimeout: 600000,
|
||||
// -----------------------------------------------------------------
|
||||
// Uncomment to run tests using a remote Selenium server
|
||||
//seleniumAddress: 'http://selenium.address:4444/wd/hub',
|
||||
@@ -73,7 +73,7 @@ exports.config = {
|
||||
framework: 'jasmine',
|
||||
jasmineNodeOpts: {
|
||||
showColors: true,
|
||||
defaultTimeoutInterval: 30000,
|
||||
defaultTimeoutInterval: 600000,
|
||||
print: function () {}
|
||||
},
|
||||
useAllAngular2AppRoots: true,
|
||||
|
@@ -13,6 +13,7 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { EnumKeysPipe } from '../../../shared/utils/enum-keys-pipe';
|
||||
import { HostWindowService } from '../../../shared/host-window.service';
|
||||
import { HostWindowServiceStub } from '../../../shared/testing/host-window-service-stub';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils';
|
||||
|
||||
describe('BitstreamFormatsComponent', () => {
|
||||
let comp: BitstreamFormatsComponent;
|
||||
@@ -52,7 +53,7 @@ describe('BitstreamFormatsComponent', () => {
|
||||
extensions: null
|
||||
}
|
||||
];
|
||||
const mockFormats = observableOf(new RemoteData(false, false, true, undefined, new PaginatedList(null, mockFormatsList)));
|
||||
const mockFormats = createSuccessfulRemoteDataObject$(new PaginatedList(null, mockFormatsList));
|
||||
const registryServiceStub = {
|
||||
getBitstreamFormats: () => mockFormats
|
||||
};
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
import { type } from '../../../shared/ngrx/type';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadataschema.model';
|
||||
import { MetadataField } from '../../../core/metadata/metadatafield.model';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
||||
import { MetadataField } from '../../../core/metadata/metadata-field.model';
|
||||
|
||||
/**
|
||||
* For each action type in an action group, make a simple
|
||||
|
@@ -17,6 +17,7 @@ import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils';
|
||||
|
||||
describe('MetadataRegistryComponent', () => {
|
||||
let comp: MetadataRegistryComponent;
|
||||
@@ -36,7 +37,7 @@ describe('MetadataRegistryComponent', () => {
|
||||
namespace: 'http://dspace.org/mockschema'
|
||||
}
|
||||
];
|
||||
const mockSchemas = observableOf(new RemoteData(false, false, true, undefined, new PaginatedList(null, mockSchemasList)));
|
||||
const mockSchemas = createSuccessfulRemoteDataObject$(new PaginatedList(null, mockSchemasList));
|
||||
/* tslint:disable:no-empty */
|
||||
const registryServiceStub = {
|
||||
getMetadataSchemas: () => mockSchemas,
|
||||
|
@@ -3,7 +3,6 @@ import { RegistryService } from '../../../core/registry/registry.service';
|
||||
import { Observable, combineLatest as observableCombineLatest } from 'rxjs';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadataschema.model';
|
||||
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
||||
import { map, take } from 'rxjs/operators';
|
||||
import { hasValue } from '../../../shared/empty.util';
|
||||
@@ -12,6 +11,7 @@ import { zip } from 'rxjs/internal/observable/zip';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { Route, Router } from '@angular/router';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-metadata-registry',
|
||||
|
@@ -7,8 +7,8 @@ import {
|
||||
MetadataRegistrySelectSchemaAction
|
||||
} from './metadata-registry.actions';
|
||||
import { metadataRegistryReducer, MetadataRegistryState } from './metadata-registry.reducers';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadataschema.model';
|
||||
import { MetadataField } from '../../../core/metadata/metadatafield.model';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
||||
import { MetadataField } from '../../../core/metadata/metadata-field.model';
|
||||
|
||||
class NullAction extends MetadataRegistryEditSchemaAction {
|
||||
type = null;
|
||||
|
@@ -1,4 +1,3 @@
|
||||
import { MetadataSchema } from '../../../core/metadata/metadataschema.model';
|
||||
import {
|
||||
MetadataRegistryAction,
|
||||
MetadataRegistryActionTypes,
|
||||
@@ -9,7 +8,8 @@ import {
|
||||
MetadataRegistrySelectFieldAction,
|
||||
MetadataRegistrySelectSchemaAction
|
||||
} from './metadata-registry.actions';
|
||||
import { MetadataField } from '../../../core/metadata/metadatafield.model';
|
||||
import { MetadataField } from '../../../core/metadata/metadata-field.model';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
||||
|
||||
/**
|
||||
* The metadata registry state.
|
||||
|
@@ -10,7 +10,7 @@ import { EnumKeysPipe } from '../../../../shared/utils/enum-keys-pipe';
|
||||
import { RegistryService } from '../../../../core/registry/registry.service';
|
||||
import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service';
|
||||
import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||
import { MetadataSchema } from '../../../../core/metadata/metadataschema.model';
|
||||
import { MetadataSchema } from '../../../../core/metadata/metadata-schema.model';
|
||||
|
||||
describe('MetadataSchemaFormComponent', () => {
|
||||
let component: MetadataSchemaFormComponent;
|
||||
|
@@ -9,9 +9,9 @@ import { FormGroup } from '@angular/forms';
|
||||
import { RegistryService } from '../../../../core/registry/registry.service';
|
||||
import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { MetadataSchema } from '../../../../core/metadata/metadataschema.model';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { combineLatest } from 'rxjs/internal/observable/combineLatest';
|
||||
import { MetadataSchema } from '../../../../core/metadata/metadata-schema.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-metadata-schema-form',
|
||||
|
@@ -3,7 +3,6 @@ import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing'
|
||||
import { MetadataFieldFormComponent } from './metadata-field-form.component';
|
||||
import { RegistryService } from '../../../../core/registry/registry.service';
|
||||
import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||
import { MetadataField } from '../../../../core/metadata/metadatafield.model';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
@@ -11,7 +10,8 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { EnumKeysPipe } from '../../../../shared/utils/enum-keys-pipe';
|
||||
import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { MetadataSchema } from '../../../../core/metadata/metadataschema.model';
|
||||
import { MetadataField } from '../../../../core/metadata/metadata-field.model';
|
||||
import { MetadataSchema } from '../../../../core/metadata/metadata-schema.model';
|
||||
|
||||
describe('MetadataFieldFormComponent', () => {
|
||||
let component: MetadataFieldFormComponent;
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
|
||||
import { MetadataSchema } from '../../../../core/metadata/metadataschema.model';
|
||||
import {
|
||||
DynamicFormControlModel,
|
||||
DynamicFormLayout,
|
||||
@@ -8,10 +7,11 @@ import {
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { RegistryService } from '../../../../core/registry/registry.service';
|
||||
import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service';
|
||||
import { MetadataField } from '../../../../core/metadata/metadatafield.model';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { combineLatest } from 'rxjs/internal/observable/combineLatest';
|
||||
import { MetadataSchema } from '../../../../core/metadata/metadata-schema.model';
|
||||
import { MetadataField } from '../../../../core/metadata/metadata-field.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-metadata-field-form',
|
||||
|
@@ -3,7 +3,6 @@ import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing'
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadataschema.model';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
@@ -21,6 +20,8 @@ import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils';
|
||||
|
||||
describe('MetadataSchemaComponent', () => {
|
||||
let comp: MetadataSchemaComponent;
|
||||
@@ -74,12 +75,12 @@ describe('MetadataSchemaComponent', () => {
|
||||
schema: mockSchemasList[1]
|
||||
}
|
||||
];
|
||||
const mockSchemas = observableOf(new RemoteData(false, false, true, undefined, new PaginatedList(null, mockSchemasList)));
|
||||
const mockSchemas = createSuccessfulRemoteDataObject$(new PaginatedList(null, mockSchemasList));
|
||||
/* tslint:disable:no-empty */
|
||||
const registryServiceStub = {
|
||||
getMetadataSchemas: () => mockSchemas,
|
||||
getMetadataFieldsBySchema: (schema: MetadataSchema) => observableOf(new RemoteData(false, false, true, undefined, new PaginatedList(null, mockFieldsList.filter((value) => value.schema === schema)))),
|
||||
getMetadataSchemaByName: (schemaName: string) => observableOf(new RemoteData(false, false, true, undefined, mockSchemasList.filter((value) => value.prefix === schemaName)[0])),
|
||||
getMetadataFieldsBySchema: (schema: MetadataSchema) => createSuccessfulRemoteDataObject$(new PaginatedList(null, mockFieldsList.filter((value) => value.schema === schema))),
|
||||
getMetadataSchemaByName: (schemaName: string) => createSuccessfulRemoteDataObject$(mockSchemasList.filter((value) => value.prefix === schemaName)[0]),
|
||||
getActiveMetadataField: () => observableOf(undefined),
|
||||
getSelectedMetadataFields: () => observableOf([]),
|
||||
editMetadataField: (schema) => {},
|
||||
|
@@ -4,8 +4,6 @@ import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Observable, combineLatest as observableCombineLatest } from 'rxjs';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { MetadataField } from '../../../core/metadata/metadatafield.model';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadataschema.model';
|
||||
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
||||
import { map, take } from 'rxjs/operators';
|
||||
import { hasValue } from '../../../shared/empty.util';
|
||||
@@ -13,6 +11,8 @@ import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { zip } from 'rxjs/internal/observable/zip';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { MetadataField } from '../../../core/metadata/metadata-field.model';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-metadata-schema',
|
||||
|
@@ -18,6 +18,7 @@ import { Item } from '../../core/shared/item.model';
|
||||
import { ENV_CONFIG, GLOBAL_CONFIG } from '../../../config';
|
||||
import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-options.model';
|
||||
import { toRemoteData } from '../+browse-by-metadata-page/browse-by-metadata-page.component.spec';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
|
||||
|
||||
describe('BrowseByDatePageComponent', () => {
|
||||
let comp: BrowseByDatePageComponent;
|
||||
@@ -48,11 +49,11 @@ describe('BrowseByDatePageComponent', () => {
|
||||
const mockBrowseService = {
|
||||
getBrowseEntriesFor: (options: BrowseEntrySearchOptions) => toRemoteData([]),
|
||||
getBrowseItemsFor: (value: string, options: BrowseEntrySearchOptions) => toRemoteData([firstItem]),
|
||||
getFirstItemFor: () => observableOf(new RemoteData(false, false, true, undefined, firstItem))
|
||||
getFirstItemFor: () => createSuccessfulRemoteDataObject$(firstItem)
|
||||
};
|
||||
|
||||
const mockDsoService = {
|
||||
findById: () => observableOf(new RemoteData(false, false, true, null, mockCommunity))
|
||||
findById: () => createSuccessfulRemoteDataObject$(mockCommunity)
|
||||
};
|
||||
|
||||
const activatedRouteStub = Object.assign(new ActivatedRouteStub(), {
|
||||
|
@@ -20,6 +20,9 @@ import { Item } from '../../core/shared/item.model';
|
||||
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
|
||||
import { Community } from '../../core/shared/community.model';
|
||||
import { MockRouter } from '../../shared/mocks/mock-router';
|
||||
import { ResourceType } from '../../core/shared/resource-type';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
|
||||
import { BrowseEntry } from '../../core/shared/browse-entry.model';
|
||||
|
||||
describe('BrowseByMetadataPageComponent', () => {
|
||||
let comp: BrowseByMetadataPageComponent;
|
||||
@@ -39,21 +42,21 @@ describe('BrowseByMetadataPageComponent', () => {
|
||||
|
||||
const mockEntries = [
|
||||
{
|
||||
type: 'author',
|
||||
type: BrowseEntry.type,
|
||||
authority: null,
|
||||
value: 'John Doe',
|
||||
language: 'en',
|
||||
count: 1
|
||||
},
|
||||
{
|
||||
type: 'author',
|
||||
type: BrowseEntry.type,
|
||||
authority: null,
|
||||
value: 'James Doe',
|
||||
language: 'en',
|
||||
count: 3
|
||||
},
|
||||
{
|
||||
type: 'subject',
|
||||
type: BrowseEntry.type,
|
||||
authority: null,
|
||||
value: 'Fake subject',
|
||||
language: 'en',
|
||||
@@ -68,12 +71,12 @@ describe('BrowseByMetadataPageComponent', () => {
|
||||
];
|
||||
|
||||
const mockBrowseService = {
|
||||
getBrowseEntriesFor: (options: BrowseEntrySearchOptions) => toRemoteData(mockEntries.filter((entry) => entry.type === options.metadataDefinition)),
|
||||
getBrowseEntriesFor: (options: BrowseEntrySearchOptions) => toRemoteData(mockEntries),
|
||||
getBrowseItemsFor: (value: string, options: BrowseEntrySearchOptions) => toRemoteData(mockItems)
|
||||
};
|
||||
|
||||
const mockDsoService = {
|
||||
findById: () => observableOf(new RemoteData(false, false, true, null, mockCommunity))
|
||||
findById: () => createSuccessfulRemoteDataObject$(mockCommunity)
|
||||
};
|
||||
|
||||
const activatedRouteStub = Object.assign(new ActivatedRouteStub(), {
|
||||
@@ -105,12 +108,6 @@ describe('BrowseByMetadataPageComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should fetch the correct entries depending on the metadata definition', () => {
|
||||
comp.browseEntries$.subscribe((result) => {
|
||||
expect(result.payload.page).toEqual(mockEntries.filter((entry) => entry.type === 'author'));
|
||||
});
|
||||
});
|
||||
|
||||
it('should not fetch any items when no value is provided', () => {
|
||||
expect(comp.items$).toBeUndefined();
|
||||
});
|
||||
@@ -160,5 +157,5 @@ describe('BrowseByMetadataPageComponent', () => {
|
||||
});
|
||||
|
||||
export function toRemoteData(objects: any[]): Observable<RemoteData<PaginatedList<any>>> {
|
||||
return observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), objects)));
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), objects));
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@ import { RemoteData } from '../../core/data/remote-data';
|
||||
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
|
||||
import { BrowseService } from '../../core/browse/browse.service';
|
||||
import { MockRouter } from '../../shared/mocks/mock-router';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
|
||||
|
||||
describe('BrowseByTitlePageComponent', () => {
|
||||
let comp: BrowseByTitlePageComponent;
|
||||
@@ -52,7 +53,7 @@ describe('BrowseByTitlePageComponent', () => {
|
||||
};
|
||||
|
||||
const mockDsoService = {
|
||||
findById: () => observableOf(new RemoteData(false, false, true, null, mockCommunity))
|
||||
findById: () => createSuccessfulRemoteDataObject$(mockCommunity)
|
||||
};
|
||||
|
||||
const activatedRouteStub = Object.assign(new ActivatedRouteStub(), {
|
||||
|
@@ -1,12 +1,9 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import {
|
||||
DynamicInputModel,
|
||||
DynamicTextAreaModel
|
||||
} from '@ng-dynamic-forms/core';
|
||||
import { DynamicInputModel, DynamicTextAreaModel } from '@ng-dynamic-forms/core';
|
||||
import { DynamicFormControlModel } from '@ng-dynamic-forms/core/src/model/dynamic-form-control.model';
|
||||
import { ResourceType } from '../../core/shared/resource-type';
|
||||
import { Collection } from '../../core/shared/collection.model';
|
||||
import { ComColFormComponent } from '../../shared/comcol-forms/comcol-form/comcol-form.component';
|
||||
import { NormalizedCollection } from '../../core/cache/models/normalized-collection.model';
|
||||
|
||||
/**
|
||||
* Form used for creating and editing collections
|
||||
@@ -23,9 +20,9 @@ export class CollectionFormComponent extends ComColFormComponent<Collection> {
|
||||
@Input() dso: Collection = new Collection();
|
||||
|
||||
/**
|
||||
* @type {ResourceType.Collection} This is a collection-type form
|
||||
* @type {Collection.type} This is a collection-type form
|
||||
*/
|
||||
protected type = ResourceType.Collection;
|
||||
protected type = Collection.type;
|
||||
|
||||
/**
|
||||
* The dynamic form fields used for creating/editing a collection
|
||||
|
@@ -1,9 +1,11 @@
|
||||
import { CreateCollectionPageGuard } from './create-collection-page.guard';
|
||||
import { MockRouter } from '../../shared/mocks/mock-router';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Community } from '../../core/shared/community.model';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { first } from 'rxjs/operators';
|
||||
import {
|
||||
createFailedRemoteDataObject$,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../shared/testing/utils';
|
||||
|
||||
describe('CreateCollectionPageGuard', () => {
|
||||
describe('canActivate', () => {
|
||||
@@ -15,11 +17,11 @@ describe('CreateCollectionPageGuard', () => {
|
||||
communityDataServiceStub = {
|
||||
findById: (id: string) => {
|
||||
if (id === 'valid-id') {
|
||||
return observableOf(new RemoteData(false, false, true, null, new Community()));
|
||||
return createSuccessfulRemoteDataObject$(new Community());
|
||||
} else if (id === 'invalid-id') {
|
||||
return observableOf(new RemoteData(false, false, true, null, undefined));
|
||||
return createSuccessfulRemoteDataObject$(undefined);
|
||||
} else if (id === 'error-id') {
|
||||
return observableOf(new RemoteData(false, false, false, null, new Community()));
|
||||
return createFailedRemoteDataObject$(new Community());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -20,9 +20,9 @@ export class CommunityFormComponent extends ComColFormComponent<Community> {
|
||||
@Input() dso: Community = new Community();
|
||||
|
||||
/**
|
||||
* @type {ResourceType.Community} This is a community-type form
|
||||
* @type {Community.type} This is a community-type form
|
||||
*/
|
||||
protected type = ResourceType.Community;
|
||||
protected type = Community.type;
|
||||
|
||||
/**
|
||||
* The dynamic form fields used for creating/editing a community
|
||||
|
@@ -1,9 +1,11 @@
|
||||
import { CreateCommunityPageGuard } from './create-community-page.guard';
|
||||
import { MockRouter } from '../../shared/mocks/mock-router';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Community } from '../../core/shared/community.model';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { first } from 'rxjs/operators';
|
||||
import {
|
||||
createFailedRemoteDataObject$,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../shared/testing/utils';
|
||||
|
||||
describe('CreateCommunityPageGuard', () => {
|
||||
describe('canActivate', () => {
|
||||
@@ -15,11 +17,11 @@ describe('CreateCommunityPageGuard', () => {
|
||||
communityDataServiceStub = {
|
||||
findById: (id: string) => {
|
||||
if (id === 'valid-id') {
|
||||
return observableOf(new RemoteData(false, false, true, null, new Community()));
|
||||
return createSuccessfulRemoteDataObject$(new Community());
|
||||
} else if (id === 'invalid-id') {
|
||||
return observableOf(new RemoteData(false, false, true, null, undefined));
|
||||
return createSuccessfulRemoteDataObject$(undefined);
|
||||
} else if (id === 'error-id') {
|
||||
return observableOf(new RemoteData(false, false, false, null, new Community()));
|
||||
return createFailedRemoteDataObject$(new Community());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -11,6 +11,7 @@ import {RouterTestingModule} from '@angular/router/testing';
|
||||
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {By} from '@angular/platform-browser';
|
||||
import {of as observableOf, Observable } from 'rxjs';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
|
||||
|
||||
describe('SubCommunityList Component', () => {
|
||||
let comp: CommunityPageSubCommunityListComponent;
|
||||
@@ -40,8 +41,7 @@ describe('SubCommunityList Component', () => {
|
||||
{ language: 'en_US', value: 'Test title' }
|
||||
]
|
||||
},
|
||||
subcommunities: observableOf(new RemoteData(true, true, true,
|
||||
undefined, new PaginatedList(new PageInfo(), [])))
|
||||
subcommunities: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), []))
|
||||
});
|
||||
|
||||
const mockCommunity = Object.assign(new Community(), {
|
||||
@@ -50,8 +50,7 @@ describe('SubCommunityList Component', () => {
|
||||
{ language: 'en_US', value: 'Test title' }
|
||||
]
|
||||
},
|
||||
subcommunities: observableOf(new RemoteData(true, true, true,
|
||||
undefined, new PaginatedList(new PageInfo(), subcommunities)))
|
||||
subcommunities: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), subcommunities))
|
||||
})
|
||||
;
|
||||
|
||||
|
@@ -2,6 +2,10 @@ import {RemoteData} from '../../core/data/remote-data';
|
||||
import {hot} from 'jasmine-marbles';
|
||||
import {Item} from '../../core/shared/item.model';
|
||||
import {findSuccessfulAccordingTo} from './edit-item-operators';
|
||||
import {
|
||||
createFailedRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject
|
||||
} from '../../shared/testing/utils';
|
||||
|
||||
describe('findSuccessfulAccordingTo', () => {
|
||||
let mockItem1;
|
||||
@@ -19,11 +23,11 @@ describe('findSuccessfulAccordingTo', () => {
|
||||
});
|
||||
it('should return first successful RemoteData Observable that complies to predicate', () => {
|
||||
const testRD = {
|
||||
a: new RemoteData(false, false, true, null, undefined),
|
||||
b: new RemoteData(false, false, false, null, mockItem1),
|
||||
c: new RemoteData(false, false, true, null, mockItem2),
|
||||
d: new RemoteData(false, false, true, null, mockItem1),
|
||||
e: new RemoteData(false, false, true, null, mockItem2),
|
||||
a: createSuccessfulRemoteDataObject(undefined),
|
||||
b: createFailedRemoteDataObject(mockItem1),
|
||||
c: createSuccessfulRemoteDataObject(mockItem2),
|
||||
d: createSuccessfulRemoteDataObject(mockItem1),
|
||||
e: createSuccessfulRemoteDataObject(mockItem2),
|
||||
};
|
||||
|
||||
const source = hot('abcde', testRD);
|
||||
|
@@ -17,6 +17,7 @@ import { By } from '@angular/platform-browser';
|
||||
import { ItemDeleteComponent } from './item-delete.component';
|
||||
import { getItemEditPath } from '../../item-page-routing.module';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { createSuccessfulRemoteDataObject } from '../../../shared/testing/utils';
|
||||
|
||||
let comp: ItemDeleteComponent;
|
||||
let fixture: ComponentFixture<ItemDeleteComponent>;
|
||||
@@ -49,7 +50,7 @@ describe('ItemDeleteComponent', () => {
|
||||
|
||||
routeStub = {
|
||||
data: observableOf({
|
||||
item: new RemoteData(false, false, true, null, mockItem)
|
||||
item: createSuccessfulRemoteDataObject(mockItem)
|
||||
})
|
||||
};
|
||||
|
||||
|
@@ -6,17 +6,18 @@ import { ObjectUpdatesService } from '../../../../core/data/object-updates/objec
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { MetadataField } from '../../../../core/metadata/metadatafield.model';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { SharedModule } from '../../../../shared/shared.module';
|
||||
import { getTestScheduler } from 'jasmine-marbles';
|
||||
import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model';
|
||||
import { TestScheduler } from 'rxjs/testing';
|
||||
import { MetadataSchema } from '../../../../core/metadata/metadataschema.model';
|
||||
import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MetadatumViewModel } from '../../../../core/shared/metadata.models';
|
||||
import { MetadataSchema } from '../../../../core/metadata/metadata-schema.model';
|
||||
import { MetadataField } from '../../../../core/metadata/metadata-field.model';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
|
||||
|
||||
let comp: EditInPlaceFieldComponent;
|
||||
let fixture: ComponentFixture<EditInPlaceFieldComponent>;
|
||||
@@ -59,7 +60,7 @@ describe('EditInPlaceFieldComponent', () => {
|
||||
paginatedMetadataFields = new PaginatedList(undefined, [mdField1, mdField2, mdField3]);
|
||||
|
||||
metadataFieldService = jasmine.createSpyObj({
|
||||
queryMetadataFields: observableOf(new RemoteData(false, false, true, undefined, paginatedMetadataFields)),
|
||||
queryMetadataFields: createSuccessfulRemoteDataObject$(paginatedMetadataFields),
|
||||
});
|
||||
objectUpdatesService = jasmine.createSpyObj('objectUpdatesService',
|
||||
{
|
||||
|
@@ -4,13 +4,13 @@ import { RegistryService } from '../../../../core/registry/registry.service';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { BehaviorSubject, Observable, of as observableOf } from 'rxjs';
|
||||
import { map, take } from 'rxjs/operators';
|
||||
import { MetadataField } from '../../../../core/metadata/metadatafield.model';
|
||||
import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model';
|
||||
import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions';
|
||||
import { FieldUpdate } from '../../../../core/data/object-updates/object-updates.reducer';
|
||||
import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service';
|
||||
import { NgModel } from '@angular/forms';
|
||||
import { MetadatumViewModel } from '../../../../core/shared/metadata.models';
|
||||
import { MetadataField } from '../../../../core/metadata/metadata-field.model';
|
||||
|
||||
@Component({
|
||||
// tslint:disable-next-line:component-selector
|
||||
|
@@ -20,13 +20,16 @@ import { RouterStub } from '../../../shared/testing/router-stub';
|
||||
import { GLOBAL_CONFIG } from '../../../../config';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { FieldChangeType } from '../../../core/data/object-updates/object-updates.actions';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { MetadatumViewModel } from '../../../core/shared/metadata.models';
|
||||
import { RegistryService } from '../../../core/registry/registry.service';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadataschema.model';
|
||||
import { MetadataField } from '../../../core/metadata/metadatafield.model';
|
||||
import { Metadata } from '../../../core/shared/metadata.utils';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
||||
import { MetadataField } from '../../../core/metadata/metadata-field.model';
|
||||
import {
|
||||
createSuccessfulRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../../shared/testing/utils';
|
||||
|
||||
let comp: ItemMetadataComponent;
|
||||
let fixture: ComponentFixture<ItemMetadataComponent>;
|
||||
@@ -116,18 +119,18 @@ describe('ItemMetadataComponent', () => {
|
||||
)
|
||||
;
|
||||
itemService = jasmine.createSpyObj('itemService', {
|
||||
update: observableOf(new RemoteData(false, false, true, undefined, item)),
|
||||
update: createSuccessfulRemoteDataObject$(item),
|
||||
commitUpdates: {}
|
||||
});
|
||||
routeStub = {
|
||||
parent: {
|
||||
data: observableOf({ item: new RemoteData(false, false, true, null, item) })
|
||||
data: observableOf({ item: createSuccessfulRemoteDataObject(item) })
|
||||
}
|
||||
};
|
||||
paginatedMetadataFields = new PaginatedList(undefined, [mdField1, mdField2, mdField3]);
|
||||
|
||||
metadataFieldService = jasmine.createSpyObj({
|
||||
getAllMetadataFields: observableOf(new RemoteData(false, false, true, undefined, paginatedMetadataFields))
|
||||
getAllMetadataFields:createSuccessfulRemoteDataObject$(paginatedMetadataFields)
|
||||
});
|
||||
scheduler = getTestScheduler();
|
||||
objectUpdatesService = jasmine.createSpyObj('objectUpdatesService',
|
||||
|
@@ -17,9 +17,9 @@ import { NotificationsService } from '../../../shared/notifications/notification
|
||||
import { GLOBAL_CONFIG, GlobalConfig } from '../../../../config';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { RegistryService } from '../../../core/registry/registry.service';
|
||||
import { MetadataField } from '../../../core/metadata/metadatafield.model';
|
||||
import { MetadatumViewModel } from '../../../core/shared/metadata.models';
|
||||
import { Metadata } from '../../../core/shared/metadata.utils';
|
||||
import { MetadataField } from '../../../core/metadata/metadata-field.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-metadata',
|
||||
|
@@ -16,6 +16,7 @@ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { ItemPrivateComponent } from './item-private.component';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { createSuccessfulRemoteDataObject } from '../../../shared/testing/utils';
|
||||
|
||||
let comp: ItemPrivateComponent;
|
||||
let fixture: ComponentFixture<ItemPrivateComponent>;
|
||||
@@ -50,7 +51,7 @@ describe('ItemPrivateComponent', () => {
|
||||
|
||||
routeStub = {
|
||||
data: observableOf({
|
||||
item: new RemoteData(false, false, true, null, {
|
||||
item: createSuccessfulRemoteDataObject({
|
||||
id: 'fake-id'
|
||||
})
|
||||
})
|
||||
|
@@ -16,6 +16,7 @@ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { ItemPublicComponent } from './item-public.component';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { createSuccessfulRemoteDataObject } from '../../../shared/testing/utils';
|
||||
|
||||
let comp: ItemPublicComponent;
|
||||
let fixture: ComponentFixture<ItemPublicComponent>;
|
||||
@@ -50,7 +51,7 @@ describe('ItemPublicComponent', () => {
|
||||
|
||||
routeStub = {
|
||||
data: observableOf({
|
||||
item: new RemoteData(false, false, true, null, {
|
||||
item: createSuccessfulRemoteDataObject({
|
||||
id: 'fake-id'
|
||||
})
|
||||
})
|
||||
|
@@ -16,6 +16,7 @@ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { ItemReinstateComponent } from './item-reinstate.component';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { createSuccessfulRemoteDataObject } from '../../../shared/testing/utils';
|
||||
|
||||
let comp: ItemReinstateComponent;
|
||||
let fixture: ComponentFixture<ItemReinstateComponent>;
|
||||
@@ -50,7 +51,7 @@ describe('ItemReinstateComponent', () => {
|
||||
|
||||
routeStub = {
|
||||
data: observableOf({
|
||||
item: new RemoteData(false, false, true, null, {
|
||||
item: createSuccessfulRemoteDataObject({
|
||||
id: 'fake-id'
|
||||
})
|
||||
})
|
||||
|
@@ -12,7 +12,7 @@
|
||||
{{'item.edit.tabs.status.labels.itemPage' | translate}}:
|
||||
</div>
|
||||
<div class="col-9 float-left status-data" id="status-itemPage">
|
||||
<a href="{{getItemPage((itemRD$ | async)?.payload)}}">{{getItemPage((itemRD$ | async)?.payload)}}</a>
|
||||
<a [routerLink]="getItemPage((itemRD$ | async)?.payload)">{{getItemPage((itemRD$ | async)?.payload)}}</a>
|
||||
</div>
|
||||
|
||||
<div *ngFor="let operation of operations" class="w-100 pt-3">
|
||||
|
@@ -11,7 +11,7 @@ import { Item } from '../../../core/shared/item.model';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { createSuccessfulRemoteDataObject } from '../../../shared/testing/utils';
|
||||
|
||||
describe('ItemStatusComponent', () => {
|
||||
let comp: ItemStatusComponent;
|
||||
@@ -27,7 +27,7 @@ describe('ItemStatusComponent', () => {
|
||||
|
||||
const routeStub = {
|
||||
parent: {
|
||||
data: observableOf({ item: new RemoteData(false, false, true, null, mockItem) })
|
||||
data: observableOf({ item: createSuccessfulRemoteDataObject(mockItem) })
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -16,6 +16,7 @@ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { ItemWithdrawComponent } from './item-withdraw.component';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import { createSuccessfulRemoteDataObject } from '../../../shared/testing/utils';
|
||||
|
||||
let comp: ItemWithdrawComponent;
|
||||
let fixture: ComponentFixture<ItemWithdrawComponent>;
|
||||
@@ -50,7 +51,7 @@ describe('ItemWithdrawComponent', () => {
|
||||
|
||||
routeStub = {
|
||||
data: observableOf({
|
||||
item: new RemoteData(false, false, true, null, {
|
||||
item: createSuccessfulRemoteDataObject({
|
||||
id: 'fake-id'
|
||||
})
|
||||
})
|
||||
|
@@ -17,6 +17,10 @@ import { By } from '@angular/platform-browser';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { getItemEditPath } from '../../item-page-routing.module';
|
||||
import { RestResponse } from '../../../core/cache/response.models';
|
||||
import {
|
||||
createSuccessfulRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../../shared/testing/utils';
|
||||
|
||||
/**
|
||||
* Test component that implements the AbstractSimpleItemActionComponent used to test the
|
||||
@@ -65,12 +69,12 @@ describe('AbstractSimpleItemActionComponent', () => {
|
||||
});
|
||||
|
||||
mockItemDataService = jasmine.createSpyObj({
|
||||
findById: observableOf(new RemoteData(false, false, true, undefined, mockItem))
|
||||
findById: createSuccessfulRemoteDataObject$(mockItem)
|
||||
});
|
||||
|
||||
routeStub = {
|
||||
data: observableOf({
|
||||
item: new RemoteData(false, false, true, null, {
|
||||
item: createSuccessfulRemoteDataObject({
|
||||
id: 'fake-id'
|
||||
})
|
||||
})
|
||||
|
@@ -9,6 +9,10 @@ import { Item } from '../../../core/shared/item.model';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import {
|
||||
createFailedRemoteDataObject$,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../../shared/testing/utils';
|
||||
|
||||
let collectionsComponent: CollectionsComponent;
|
||||
let fixture: ComponentFixture<CollectionsComponent>;
|
||||
@@ -24,8 +28,8 @@ const mockCollection1: Collection = Object.assign(new Collection(), {
|
||||
}
|
||||
});
|
||||
|
||||
const succeededMockItem: Item = Object.assign(new Item(), {owningCollection: observableOf(new RemoteData(false, false, true, null, mockCollection1))});
|
||||
const failedMockItem: Item = Object.assign(new Item(), {owningCollection: observableOf(new RemoteData(false, false, false, null, mockCollection1))});
|
||||
const succeededMockItem: Item = Object.assign(new Item(), {owningCollection: createSuccessfulRemoteDataObject$(mockCollection1)});
|
||||
const failedMockItem: Item = Object.assign(new Item(), {owningCollection: createFailedRemoteDataObject$(mockCollection1)});
|
||||
|
||||
describe('CollectionsComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
|
@@ -17,9 +17,13 @@ import { RemoteData } from '../../core/data/remote-data';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import {
|
||||
createSuccessfulRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../shared/testing/utils';
|
||||
|
||||
const mockItem: Item = Object.assign(new Item(), {
|
||||
bitstreams: observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), []))),
|
||||
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
|
||||
metadata: {
|
||||
'dc.title': [
|
||||
{
|
||||
@@ -30,7 +34,7 @@ const mockItem: Item = Object.assign(new Item(), {
|
||||
}
|
||||
});
|
||||
const routeStub = Object.assign(new ActivatedRouteStub(), {
|
||||
data: observableOf({ item: new RemoteData(false, false, true, null, mockItem) })
|
||||
data: observableOf({ item: createSuccessfulRemoteDataObject(mockItem) })
|
||||
});
|
||||
const metadataServiceStub = {
|
||||
/* tslint:disable:no-empty */
|
||||
|
@@ -11,6 +11,7 @@ import { ItemPageFieldComponent } from './item-page-field.component';
|
||||
import { MetadataValuesComponent } from '../../../field-components/metadata-values/metadata-values.component';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { MetadataMap, MetadataValue } from '../../../../core/shared/metadata.models';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
|
||||
|
||||
let comp: ItemPageFieldComponent;
|
||||
let fixture: ComponentFixture<ItemPageFieldComponent>;
|
||||
@@ -52,7 +53,7 @@ describe('ItemPageFieldComponent', () => {
|
||||
|
||||
export function mockItemWithMetadataFieldAndValue(field: string, value: string): Item {
|
||||
const item = Object.assign(new Item(), {
|
||||
bitstreams: observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), []))),
|
||||
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
|
||||
metadata: new MetadataMap()
|
||||
});
|
||||
item.metadata[field] = [{
|
||||
|
@@ -16,9 +16,13 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { createRelationshipsObservable } from './item-types/shared/item.component.spec';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import {
|
||||
createFailedRemoteDataObject$, createPendingRemoteDataObject$, createSuccessfulRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject$
|
||||
} from '../../shared/testing/utils';
|
||||
|
||||
const mockItem: Item = Object.assign(new Item(), {
|
||||
bitstreams: observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), []))),
|
||||
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
|
||||
metadata: [],
|
||||
relationships: createRelationshipsObservable()
|
||||
});
|
||||
@@ -33,7 +37,7 @@ describe('ItemPageComponent', () => {
|
||||
/* tslint:enable:no-empty */
|
||||
};
|
||||
const mockRoute = Object.assign(new ActivatedRouteStub(), {
|
||||
data: observableOf({ item: new RemoteData(false, false, true, null, mockItem) })
|
||||
data: observableOf({ item: createSuccessfulRemoteDataObject(mockItem) })
|
||||
});
|
||||
|
||||
beforeEach(async(() => {
|
||||
@@ -66,7 +70,8 @@ describe('ItemPageComponent', () => {
|
||||
|
||||
describe('when the item is loading', () => {
|
||||
beforeEach(() => {
|
||||
comp.itemRD$ = observableOf(new RemoteData(true, true, true, null, undefined));
|
||||
comp.itemRD$ = createPendingRemoteDataObject$(undefined);
|
||||
// comp.itemRD$ = observableOf(new RemoteData(true, true, true, null, undefined));
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
@@ -78,7 +83,7 @@ describe('ItemPageComponent', () => {
|
||||
|
||||
describe('when the item failed loading', () => {
|
||||
beforeEach(() => {
|
||||
comp.itemRD$ = observableOf(new RemoteData(false, false, false, null, undefined));
|
||||
comp.itemRD$ = createFailedRemoteDataObject$(undefined);
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
|
@@ -17,9 +17,10 @@ import { createRelationshipsObservable } from '../shared/item.component.spec';
|
||||
import { PublicationComponent } from './publication.component';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { MetadataMap } from '../../../../core/shared/metadata.models';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
|
||||
|
||||
const mockItem: Item = Object.assign(new Item(), {
|
||||
bitstreams: observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), []))),
|
||||
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
|
||||
metadata: new MetadataMap(),
|
||||
relationships: createRelationshipsObservable()
|
||||
});
|
||||
|
@@ -26,6 +26,7 @@ import { MetadatumRepresentation } from '../../../../core/shared/metadata-repres
|
||||
import { ItemMetadataRepresentation } from '../../../../core/shared/metadata-representation/item/item-metadata-representation.model';
|
||||
import { MetadataMap, MetadataValue } from '../../../../core/shared/metadata.models';
|
||||
import { compareArraysUsing, compareArraysUsingIds } from './item-relationships-utils';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
|
||||
|
||||
/**
|
||||
* Create a generic test for an item-page-fields component using a mockItem and the type of component
|
||||
@@ -102,13 +103,13 @@ export function containsFieldInput(fields: DebugElement[], metadataKey: string):
|
||||
}
|
||||
|
||||
export function createRelationshipsObservable() {
|
||||
return observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), [
|
||||
return createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [
|
||||
Object.assign(new Relationship(), {
|
||||
relationshipType: observableOf(new RemoteData(false, false, true, null, new RelationshipType())),
|
||||
leftItem: observableOf(new RemoteData(false, false, true, null, new Item())),
|
||||
rightItem: observableOf(new RemoteData(false, false, true, null, new Item()))
|
||||
relationshipType: createSuccessfulRemoteDataObject$(new RelationshipType()),
|
||||
leftItem: createSuccessfulRemoteDataObject$(new Item()),
|
||||
rightItem: createSuccessfulRemoteDataObject$(new Item())
|
||||
})
|
||||
])));
|
||||
]));
|
||||
}
|
||||
describe('ItemComponent', () => {
|
||||
const arr1 = [
|
||||
@@ -337,15 +338,15 @@ describe('ItemComponent', () => {
|
||||
uuid: '1',
|
||||
metadata: new MetadataMap()
|
||||
});
|
||||
mockItem.relationships = observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), [
|
||||
mockItem.relationships = createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [
|
||||
Object.assign(new Relationship(), {
|
||||
uuid: '123',
|
||||
id: '123',
|
||||
leftItem: observableOf(new RemoteData(false, false, true, null, mockItem)),
|
||||
rightItem: observableOf(new RemoteData(false, false, true, null, relatedItem)),
|
||||
relationshipType: observableOf(new RemoteData(false, false, true, null, new RelationshipType()))
|
||||
leftItem: createSuccessfulRemoteDataObject$(mockItem),
|
||||
rightItem: createSuccessfulRemoteDataObject$(relatedItem),
|
||||
relationshipType: createSuccessfulRemoteDataObject$(new RelationshipType())
|
||||
})
|
||||
])));
|
||||
]));
|
||||
mockItem.metadata[metadataField] = [
|
||||
{
|
||||
value: 'Second value',
|
||||
@@ -369,7 +370,7 @@ describe('ItemComponent', () => {
|
||||
const mockItemDataService = Object.assign({
|
||||
findById: (id) => {
|
||||
if (id === relatedItem.id) {
|
||||
return observableOf(new RemoteData(false, false, true, null, relatedItem))
|
||||
return createSuccessfulRemoteDataObject$(relatedItem)
|
||||
}
|
||||
}
|
||||
}) as ItemDataService;
|
||||
|
@@ -8,14 +8,15 @@ import { PageInfo } from '../../../core/shared/page-info.model';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { createRelationshipsObservable } from '../item-types/shared/item.component.spec';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils';
|
||||
|
||||
const mockItem1: Item = Object.assign(new Item(), {
|
||||
bitstreams: observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), []))),
|
||||
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
|
||||
metadata: [],
|
||||
relationships: createRelationshipsObservable()
|
||||
});
|
||||
const mockItem2: Item = Object.assign(new Item(), {
|
||||
bitstreams: observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), []))),
|
||||
bitstreams: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), [])),
|
||||
metadata: [],
|
||||
relationships: createRelationshipsObservable()
|
||||
});
|
||||
|
@@ -29,6 +29,7 @@ import { RoleDirective } from '../shared/roles/role.directive';
|
||||
import { RoleService } from '../core/roles/role.service';
|
||||
import { MockRoleService } from '../shared/mocks/mock-role-service';
|
||||
import { SearchFixedFilterService } from '../+search-page/search-filters/search-filter/search-fixed-filter.service';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../shared/testing/utils';
|
||||
|
||||
describe('MyDSpacePageComponent', () => {
|
||||
let comp: MyDSpacePageComponent;
|
||||
@@ -46,7 +47,7 @@ describe('MyDSpacePageComponent', () => {
|
||||
pagination.currentPage = 1;
|
||||
pagination.pageSize = 10;
|
||||
const sort: SortOptions = new SortOptions('score', SortDirection.DESC);
|
||||
const mockResults = observableOf(new RemoteData(false, false, true, null, ['test', 'data']));
|
||||
const mockResults = createSuccessfulRemoteDataObject$(['test', 'data']);
|
||||
const searchServiceStub = jasmine.createSpyObj('SearchService', {
|
||||
search: mockResults,
|
||||
getSearchLink: '/mydspace',
|
||||
|
@@ -1,10 +1,12 @@
|
||||
import { autoserialize, autoserializeAs } from 'cerialize';
|
||||
import { autoserialize, inheritSerialization } from 'cerialize';
|
||||
import { MetadataMap } from '../core/shared/metadata.models';
|
||||
import { ListableObject } from '../shared/object-collection/shared/listable-object.model';
|
||||
import { NormalizedObject } from '../core/cache/models/normalized-object.model';
|
||||
|
||||
/**
|
||||
* Represents a normalized version of a search result object of a certain DSpaceObject
|
||||
*/
|
||||
@inheritSerialization(NormalizedObject)
|
||||
export class NormalizedSearchResult implements ListableObject {
|
||||
/**
|
||||
* The UUID of the DSpaceObject that was found
|
||||
|
@@ -20,6 +20,7 @@ import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-d
|
||||
import { SearchConfigurationServiceStub } from '../../../../shared/testing/search-configuration-service-stub';
|
||||
import { SEARCH_CONFIG_SERVICE } from '../../../../+my-dspace-page/my-dspace-page.component';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
|
||||
|
||||
describe('SearchFacetFilterComponent', () => {
|
||||
let comp: SearchFacetFilterComponent;
|
||||
@@ -61,7 +62,7 @@ describe('SearchFacetFilterComponent', () => {
|
||||
let router;
|
||||
const page = observableOf(0);
|
||||
|
||||
const mockValues = observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), values)));
|
||||
const mockValues = createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), values));
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot(), NoopAnimationsModule, FormsModule],
|
||||
|
@@ -20,6 +20,7 @@ import { RouteService } from '../../../../shared/services/route.service';
|
||||
import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service';
|
||||
import { SEARCH_CONFIG_SERVICE } from '../../../../+my-dspace-page/my-dspace-page.component';
|
||||
import { SearchConfigurationServiceStub } from '../../../../shared/testing/search-configuration-service-stub';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
|
||||
|
||||
describe('SearchRangeFilterComponent', () => {
|
||||
let comp: SearchRangeFilterComponent;
|
||||
@@ -66,7 +67,7 @@ describe('SearchRangeFilterComponent', () => {
|
||||
let router;
|
||||
const page = observableOf(0);
|
||||
|
||||
const mockValues = observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), values)));
|
||||
const mockValues = createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), values));
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot(), NoopAnimationsModule, FormsModule],
|
||||
|
@@ -25,6 +25,7 @@ import { RouteService } from '../shared/services/route.service';
|
||||
import { SearchConfigurationServiceStub } from '../shared/testing/search-configuration-service-stub';
|
||||
import { PaginatedSearchOptions } from './paginated-search-options.model';
|
||||
import { SearchFixedFilterService } from './search-filters/search-filter/search-fixed-filter.service';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../shared/testing/utils';
|
||||
|
||||
let comp: SearchPageComponent;
|
||||
let fixture: ComponentFixture<SearchPageComponent>;
|
||||
@@ -41,7 +42,7 @@ pagination.id = 'search-results-pagination';
|
||||
pagination.currentPage = 1;
|
||||
pagination.pageSize = 10;
|
||||
const sort: SortOptions = new SortOptions('score', SortDirection.DESC);
|
||||
const mockResults = observableOf(new RemoteData(false, false, true, null, ['test', 'data']));
|
||||
const mockResults = createSuccessfulRemoteDataObject$(['test', 'data']);
|
||||
const searchServiceStub = jasmine.createSpyObj('SearchService', {
|
||||
search: mockResults,
|
||||
getSearchLink: '/search',
|
||||
|
@@ -114,7 +114,7 @@ export const objects = [
|
||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/communities/7669c72a-3f2a-451f-a3b9-9210e7a4c02f',
|
||||
id: '7669c72a-3f2a-451f-a3b9-9210e7a4c02f',
|
||||
uuid: '7669c72a-3f2a-451f-a3b9-9210e7a4c02f',
|
||||
type: ResourceType.Community,
|
||||
type: Community.type,
|
||||
metadata: {
|
||||
'dc.description': [
|
||||
{
|
||||
@@ -168,7 +168,7 @@ export const objects = [
|
||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/communities/9076bd16-e69a-48d6-9e41-0238cb40d863',
|
||||
id: '9076bd16-e69a-48d6-9e41-0238cb40d863',
|
||||
uuid: '9076bd16-e69a-48d6-9e41-0238cb40d863',
|
||||
type: ResourceType.Community,
|
||||
type: Community.type,
|
||||
metadata: {
|
||||
'dc.description': [
|
||||
{
|
||||
|
@@ -21,6 +21,7 @@ import { getSucceededRemoteData } from '../../core/shared/operators';
|
||||
import { SearchFilter } from '../search-filter.model';
|
||||
import { DSpaceObjectType } from '../../core/shared/dspace-object-type.model';
|
||||
import { SearchFixedFilterService } from '../search-filters/search-filter/search-fixed-filter.service';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
|
||||
|
||||
/**
|
||||
* Service that performs all actions that have to do with the current search configuration
|
||||
@@ -269,7 +270,7 @@ export class SearchConfigurationService implements OnDestroy {
|
||||
scope: this.defaultScope,
|
||||
query: this.defaultQuery
|
||||
});
|
||||
this._defaults = observableOf(new RemoteData(false, false, true, null, options));
|
||||
this._defaults = createSuccessfulRemoteDataObject$(options);
|
||||
}
|
||||
return this._defaults;
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@ import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.serv
|
||||
import { map } from 'rxjs/operators';
|
||||
import { RouteService } from '../../shared/services/route.service';
|
||||
import { routeServiceStub } from '../../shared/testing/route-service-stub';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
|
||||
|
||||
@Component({ template: '' })
|
||||
class DummyComponent {
|
||||
@@ -91,7 +92,7 @@ describe('SearchService', () => {
|
||||
);
|
||||
},
|
||||
aggregate: (input: Array<Observable<RemoteData<any>>>): Observable<RemoteData<any[]>> => {
|
||||
return observableOf(new RemoteData(false, false, true, null, []));
|
||||
return createSuccessfulRemoteDataObject$([]);
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs';
|
||||
import { Injectable, OnDestroy } from '@angular/core';
|
||||
import { NavigationExtras, PRIMARY_OUTLET, Router, UrlSegmentGroup } from '@angular/router';
|
||||
import { NavigationExtras, Router } from '@angular/router';
|
||||
import { first, map, switchMap } from 'rxjs/operators';
|
||||
import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service';
|
||||
import {
|
||||
@@ -40,7 +40,6 @@ import { PaginatedSearchOptions } from '../paginated-search-options.model';
|
||||
import { Community } from '../../core/shared/community.model';
|
||||
import { CommunityDataService } from '../../core/data/community-data.service';
|
||||
import { ViewMode } from '../../core/shared/view-mode.model';
|
||||
import { ResourceType } from '../../core/shared/resource-type';
|
||||
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
|
||||
import { RouteService } from '../../shared/services/route.service';
|
||||
|
||||
@@ -296,7 +295,7 @@ export class SearchService implements OnDestroy {
|
||||
const scopeObject: Observable<RemoteData<DSpaceObject>> = this.dspaceObjectService.findById(scopeId).pipe(getSucceededRemoteData());
|
||||
const scopeList: Observable<DSpaceObject[]> = scopeObject.pipe(
|
||||
switchMap((dsoRD: RemoteData<DSpaceObject>) => {
|
||||
if (dsoRD.payload.type === ResourceType.Community) {
|
||||
if ((dsoRD.payload as any).type === Community.type.value) {
|
||||
const community: Community = dsoRD.payload as Community;
|
||||
return observableCombineLatest(community.subcommunities, community.collections).pipe(
|
||||
map(([subCommunities, collections]) => {
|
||||
|
@@ -20,4 +20,4 @@ import { SubmissionEditComponent } from '../submission/edit/submission-edit.comp
|
||||
/**
|
||||
* This module defines the default component to load when navigating to the workflowitems edit page path.
|
||||
*/
|
||||
export class WorkflowitemsEditPageRoutingModule { }
|
||||
export class WorkflowItemsEditPageRoutingModule { }
|
||||
|
@@ -1,12 +1,12 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { SharedModule } from '../shared/shared.module';
|
||||
import { WorkflowitemsEditPageRoutingModule } from './workflowitems-edit-page-routing.module';
|
||||
import { WorkflowItemsEditPageRoutingModule } from './workflowitems-edit-page-routing.module';
|
||||
import { SubmissionModule } from '../submission/submission.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
WorkflowitemsEditPageRoutingModule,
|
||||
WorkflowItemsEditPageRoutingModule,
|
||||
CommonModule,
|
||||
SharedModule,
|
||||
SubmissionModule,
|
||||
@@ -16,6 +16,6 @@ import { SubmissionModule } from '../submission/submission.module';
|
||||
/**
|
||||
* This module handles all modules that need to access the workflowitems edit page.
|
||||
*/
|
||||
export class WorkflowitemsEditPageModule {
|
||||
export class WorkflowItemsEditPageModule {
|
||||
|
||||
}
|
||||
|
@@ -32,7 +32,7 @@ export function getCommunityModulePath() {
|
||||
{ path: 'logout', loadChildren: './+logout-page/logout-page.module#LogoutPageModule' },
|
||||
{ path: 'submit', loadChildren: './+submit-page/submit-page.module#SubmitPageModule' },
|
||||
{ path: 'workspaceitems', loadChildren: './+workspaceitems-edit-page/workspaceitems-edit-page.module#WorkspaceitemsEditPageModule' },
|
||||
{ path: 'workflowitems', loadChildren: './+workflowitems-edit-page/workflowitems-edit-page.module#WorkflowitemsEditPageModule' },
|
||||
{ path: 'workflowitems', loadChildren: './+workflowitems-edit-page/workflowitems-edit-page.module#WorkflowItemsEditPageModule' },
|
||||
{ path: '**', pathMatch: 'full', component: PageNotFoundComponent },
|
||||
])
|
||||
],
|
||||
|
@@ -1,29 +0,0 @@
|
||||
import { AuthType } from './auth-type';
|
||||
import { GenericConstructor } from '../shared/generic-constructor';
|
||||
import { NormalizedAuthStatus } from './models/normalized-auth-status.model';
|
||||
import { NormalizedEPerson } from '../eperson/models/normalized-eperson.model';
|
||||
import { NormalizedObject } from '../cache/models/normalized-object.model';
|
||||
import { CacheableObject } from '../cache/object-cache.reducer';
|
||||
import { NormalizedGroup } from '../eperson/models/normalized-group.model';
|
||||
|
||||
export class AuthObjectFactory {
|
||||
public static getConstructor(type): GenericConstructor<NormalizedObject<CacheableObject>> {
|
||||
switch (type) {
|
||||
case AuthType.EPerson: {
|
||||
return NormalizedEPerson
|
||||
}
|
||||
|
||||
case AuthType.Group: {
|
||||
return NormalizedGroup
|
||||
}
|
||||
|
||||
case AuthType.Status: {
|
||||
return NormalizedAuthStatus
|
||||
}
|
||||
|
||||
default: {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -35,95 +35,103 @@ describe('AuthResponseParsingService', () => {
|
||||
});
|
||||
|
||||
describe('parse', () => {
|
||||
const validRequest = new AuthPostRequest(
|
||||
'69f375b5-19f4-4453-8c7a-7dc5c55aafbb',
|
||||
'https://rest.api/dspace-spring-rest/api/authn/login',
|
||||
'password=test&user=myself@testshib.org');
|
||||
let validRequest;
|
||||
let validRequest2;
|
||||
let validResponse;
|
||||
let validResponse1;
|
||||
let validResponse2;
|
||||
beforeEach(() => {
|
||||
|
||||
const validRequest2 = new AuthGetRequest(
|
||||
'69f375b5-19f4-4453-8c7a-7dc5c55aafbb',
|
||||
'https://rest.api/dspace-spring-rest/api/authn/status');
|
||||
validRequest = new AuthPostRequest(
|
||||
'69f375b5-19f4-4453-8c7a-7dc5c55aafbb',
|
||||
'https://rest.api/dspace-spring-rest/api/authn/login',
|
||||
'password=test&user=myself@testshib.org');
|
||||
|
||||
const validResponse = {
|
||||
payload: {
|
||||
authenticated: true,
|
||||
id: null,
|
||||
okay: true,
|
||||
token: {
|
||||
accessToken: 'eyJhbGciOiJIUzI1NiJ9.eyJlaWQiOiI0ZGM3MGFiNS1jZDczLTQ5MmYtYjAwNy0zMTc5ZDJkOTI5NmIiLCJzZyI6W10sImV4cCI6MTUyNjMxODMyMn0.ASmvcbJFBfzhN7D5ncloWnaVZr5dLtgTuOgHaCKiimc',
|
||||
expires: 1526318322000
|
||||
},
|
||||
} as AuthStatus,
|
||||
statusCode: 200,
|
||||
statusText: '200'
|
||||
};
|
||||
validRequest2 = new AuthGetRequest(
|
||||
'69f375b5-19f4-4453-8c7a-7dc5c55aafbb',
|
||||
'https://rest.api/dspace-spring-rest/api/authn/status');
|
||||
|
||||
const validResponse1 = {
|
||||
payload: {},
|
||||
statusCode: 404,
|
||||
statusText: '404'
|
||||
};
|
||||
validResponse = {
|
||||
payload: {
|
||||
authenticated: true,
|
||||
id: null,
|
||||
okay: true,
|
||||
token: {
|
||||
accessToken: 'eyJhbGciOiJIUzI1NiJ9.eyJlaWQiOiI0ZGM3MGFiNS1jZDczLTQ5MmYtYjAwNy0zMTc5ZDJkOTI5NmIiLCJzZyI6W10sImV4cCI6MTUyNjMxODMyMn0.ASmvcbJFBfzhN7D5ncloWnaVZr5dLtgTuOgHaCKiimc',
|
||||
expires: 1526318322000
|
||||
},
|
||||
} as AuthStatus,
|
||||
statusCode: 200,
|
||||
statusText: '200'
|
||||
};
|
||||
|
||||
const validResponse2 = {
|
||||
payload: {
|
||||
authenticated: true,
|
||||
id: null,
|
||||
okay: true,
|
||||
type: 'status',
|
||||
_embedded: {
|
||||
eperson: {
|
||||
canLogIn: true,
|
||||
email: 'myself@testshib.org',
|
||||
groups: [],
|
||||
handle: null,
|
||||
id: '4dc70ab5-cd73-492f-b007-3179d2d9296b',
|
||||
lastActive: '2018-05-14T17:03:31.277+0000',
|
||||
metadata: {
|
||||
'eperson.firstname': [
|
||||
{
|
||||
language: null,
|
||||
value: 'User'
|
||||
validResponse1 = {
|
||||
payload: {},
|
||||
statusCode: 404,
|
||||
statusText: '404'
|
||||
};
|
||||
|
||||
validResponse2 = {
|
||||
payload: {
|
||||
authenticated: true,
|
||||
id: null,
|
||||
okay: true,
|
||||
type: 'status',
|
||||
_embedded: {
|
||||
eperson: {
|
||||
canLogIn: true,
|
||||
email: 'myself@testshib.org',
|
||||
groups: [],
|
||||
handle: null,
|
||||
id: '4dc70ab5-cd73-492f-b007-3179d2d9296b',
|
||||
lastActive: '2018-05-14T17:03:31.277+0000',
|
||||
metadata: {
|
||||
'eperson.firstname': [
|
||||
{
|
||||
language: null,
|
||||
value: 'User'
|
||||
}
|
||||
],
|
||||
'eperson.lastname': [
|
||||
{
|
||||
language: null,
|
||||
value: 'Test'
|
||||
}
|
||||
],
|
||||
'eperson.language': [
|
||||
{
|
||||
language: null,
|
||||
value: 'en'
|
||||
}
|
||||
]
|
||||
},
|
||||
name: 'User Test',
|
||||
netid: 'myself@testshib.org',
|
||||
requireCertificate: false,
|
||||
selfRegistered: false,
|
||||
type: 'eperson',
|
||||
uuid: '4dc70ab5-cd73-492f-b007-3179d2d9296b',
|
||||
_links: {
|
||||
self: {
|
||||
href: 'https://hasselt-dspace.dev01.4science.it/dspace-spring-rest/api/eperson/epersons/4dc70ab5-cd73-492f-b007-3179d2d9296b'
|
||||
}
|
||||
],
|
||||
'eperson.lastname': [
|
||||
{
|
||||
language: null,
|
||||
value: 'Test'
|
||||
}
|
||||
],
|
||||
'eperson.language': [
|
||||
{
|
||||
language: null,
|
||||
value: 'en'
|
||||
}
|
||||
]
|
||||
},
|
||||
name: 'User Test',
|
||||
netid: 'myself@testshib.org',
|
||||
requireCertificate: false,
|
||||
selfRegistered: false,
|
||||
type: 'eperson',
|
||||
uuid: '4dc70ab5-cd73-492f-b007-3179d2d9296b',
|
||||
_links: {
|
||||
self: {
|
||||
href: 'https://hasselt-dspace.dev01.4science.it/dspace-spring-rest/api/eperson/epersons/4dc70ab5-cd73-492f-b007-3179d2d9296b'
|
||||
}
|
||||
}
|
||||
},
|
||||
_links: {
|
||||
eperson: {
|
||||
href: 'https://hasselt-dspace.dev01.4science.it/dspace-spring-rest/api/eperson/epersons/4dc70ab5-cd73-492f-b007-3179d2d9296b'
|
||||
},
|
||||
self: {
|
||||
href: 'https://hasselt-dspace.dev01.4science.it/dspace-spring-rest/api/authn/status'
|
||||
}
|
||||
}
|
||||
},
|
||||
_links: {
|
||||
eperson: {
|
||||
href: 'https://hasselt-dspace.dev01.4science.it/dspace-spring-rest/api/eperson/epersons/4dc70ab5-cd73-492f-b007-3179d2d9296b'
|
||||
},
|
||||
self: {
|
||||
href: 'https://hasselt-dspace.dev01.4science.it/dspace-spring-rest/api/authn/status'
|
||||
}
|
||||
}
|
||||
},
|
||||
statusCode: 200,
|
||||
statusText: '200'
|
||||
statusCode: 200,
|
||||
statusText: '200'
|
||||
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
it('should return a AuthStatusResponse if data contains a valid AuthStatus object as payload', () => {
|
||||
const response = service.parse(validRequest, validResponse);
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
|
||||
import { AuthObjectFactory } from './auth-object-factory';
|
||||
import { BaseResponseParsingService } from '../data/base-response-parsing.service';
|
||||
import { AuthStatusResponse, RestResponse } from '../cache/response.models';
|
||||
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
|
||||
@@ -10,7 +9,6 @@ import { isNotEmpty } from '../../shared/empty.util';
|
||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||
import { ResponseParsingService } from '../data/parsing.service';
|
||||
import { RestRequest } from '../data/request.models';
|
||||
import { AuthType } from './auth-type';
|
||||
import { AuthStatus } from './models/auth-status.model';
|
||||
import { NormalizedAuthStatus } from './models/normalized-auth-status.model';
|
||||
import { NormalizedObject } from '../cache/models/normalized-object.model';
|
||||
@@ -18,7 +16,6 @@ import { NormalizedObject } from '../cache/models/normalized-object.model';
|
||||
@Injectable()
|
||||
export class AuthResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {
|
||||
|
||||
protected objectFactory = AuthObjectFactory;
|
||||
protected toCache = true;
|
||||
|
||||
constructor(@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
|
||||
@@ -28,7 +25,7 @@ export class AuthResponseParsingService extends BaseResponseParsingService imple
|
||||
|
||||
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
||||
if (isNotEmpty(data.payload) && isNotEmpty(data.payload._links) && (data.statusCode === 200)) {
|
||||
const response = this.process<NormalizedObject<AuthStatus>, AuthType>(data.payload, request.uuid);
|
||||
const response = this.process<NormalizedObject<AuthStatus>>(data.payload, request.uuid);
|
||||
return new AuthStatusResponse(response, data.statusCode, data.statusText);
|
||||
} else {
|
||||
return new AuthStatusResponse(data.payload as NormalizedAuthStatus, data.statusCode, data.statusText);
|
||||
|
@@ -1,5 +0,0 @@
|
||||
export enum AuthType {
|
||||
EPerson = 'eperson',
|
||||
Status = 'status',
|
||||
Group = 'group'
|
||||
}
|
@@ -4,20 +4,51 @@ import { EPerson } from '../../eperson/models/eperson.model';
|
||||
import { RemoteData } from '../../data/remote-data';
|
||||
import { Observable } from 'rxjs';
|
||||
import { CacheableObject } from '../../cache/object-cache.reducer';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
|
||||
/**
|
||||
* Object that represents the authenticated status of a user
|
||||
*/
|
||||
export class AuthStatus implements CacheableObject {
|
||||
static type = new ResourceType('status');
|
||||
|
||||
/**
|
||||
* The unique identifier of this auth status
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* The unique uuid of this auth status
|
||||
*/
|
||||
uuid: string;
|
||||
|
||||
/**
|
||||
* True if REST API is up and running, should never return false
|
||||
*/
|
||||
okay: boolean;
|
||||
|
||||
/**
|
||||
* If the auth status represents an authenticated state
|
||||
*/
|
||||
authenticated: boolean;
|
||||
|
||||
/**
|
||||
* Authentication error if there was one for this status
|
||||
*/
|
||||
error?: AuthError;
|
||||
|
||||
/**
|
||||
* The eperson of this auth status
|
||||
*/
|
||||
eperson: Observable<RemoteData<EPerson>>;
|
||||
|
||||
/**
|
||||
* True if the token is valid, false if there was no token or the token wasn't valid
|
||||
*/
|
||||
token?: AuthTokenInfo;
|
||||
|
||||
/**
|
||||
* The self link of this auth status' REST object
|
||||
*/
|
||||
self: string;
|
||||
}
|
||||
|
@@ -1,16 +1,22 @@
|
||||
import { AuthStatus } from './auth-status.model';
|
||||
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize';
|
||||
import { mapsTo, relationship } from '../../cache/builders/build-decorators';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
import { NormalizedObject } from '../../cache/models/normalized-object.model';
|
||||
import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer';
|
||||
import { EPerson } from '../../eperson/models/eperson.model';
|
||||
|
||||
@mapsTo(AuthStatus)
|
||||
@inheritSerialization(NormalizedObject)
|
||||
export class NormalizedAuthStatus extends NormalizedObject<AuthStatus> {
|
||||
/**
|
||||
* The unique identifier of this auth status
|
||||
*/
|
||||
@autoserialize
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* The unique generated uuid of this auth status
|
||||
*/
|
||||
@autoserializeAs(new IDToUUIDSerializer('auth-status'), 'id')
|
||||
uuid: string;
|
||||
|
||||
@@ -26,7 +32,10 @@ export class NormalizedAuthStatus extends NormalizedObject<AuthStatus> {
|
||||
@autoserialize
|
||||
authenticated: boolean;
|
||||
|
||||
@relationship(ResourceType.EPerson, false)
|
||||
/**
|
||||
* The self link to the eperson of this auth status
|
||||
*/
|
||||
@relationship(EPerson, false)
|
||||
@autoserialize
|
||||
eperson: string;
|
||||
}
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { distinctUntilChanged, map, startWith, take } from 'rxjs/operators';
|
||||
import { distinctUntilChanged, map, startWith } from 'rxjs/operators';
|
||||
import {
|
||||
ensureArrayHasValue, hasValue,
|
||||
ensureArrayHasValue,
|
||||
hasValue,
|
||||
hasValueOperator,
|
||||
isEmpty,
|
||||
isNotEmpty,
|
||||
@@ -23,7 +24,9 @@ import { BrowseEntry } from '../shared/browse-entry.model';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
import {
|
||||
configureRequest,
|
||||
filterSuccessfulResponses, getBrowseDefinitionLinks, getFirstOccurrence,
|
||||
filterSuccessfulResponses,
|
||||
getBrowseDefinitionLinks,
|
||||
getFirstOccurrence,
|
||||
getRemoteDataPayload,
|
||||
getRequestFromRequestHref
|
||||
} from '../shared/operators';
|
||||
@@ -32,7 +35,6 @@ import { Item } from '../shared/item.model';
|
||||
import { DSpaceObject } from '../shared/dspace-object.model';
|
||||
import { BrowseEntrySearchOptions } from './browse-entry-search-options.model';
|
||||
import { GenericSuccessResponse } from '../cache/response.models';
|
||||
import { RequestEntry } from '../data/request.reducer';
|
||||
|
||||
/**
|
||||
* The service handling all browse requests
|
||||
|
50
src/app/core/cache/builders/build-decorators.ts
vendored
50
src/app/core/cache/builders/build-decorators.ts
vendored
@@ -1,23 +1,59 @@
|
||||
import 'reflect-metadata';
|
||||
|
||||
import { GenericConstructor } from '../../shared/generic-constructor';
|
||||
import { CacheableObject } from '../object-cache.reducer';
|
||||
import { CacheableObject, TypedObject } from '../object-cache.reducer';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
|
||||
const mapsToMetadataKey = Symbol('mapsTo');
|
||||
const relationshipKey = Symbol('relationship');
|
||||
|
||||
const relationshipMap = new Map();
|
||||
const typeMap = new Map();
|
||||
|
||||
export function mapsTo(value: GenericConstructor<CacheableObject>) {
|
||||
return Reflect.metadata(mapsToMetadataKey, value);
|
||||
/**
|
||||
* Decorator function to map a normalized class to it's not-normalized counter part class
|
||||
* It will also maps a type to the matching class
|
||||
* @param value The not-normalized class to map to
|
||||
*/
|
||||
export function mapsTo(value: GenericConstructor<TypedObject>) {
|
||||
return function decorator(objectConstructor: GenericConstructor<TypedObject>) {
|
||||
Reflect.defineMetadata(mapsToMetadataKey, value, objectConstructor);
|
||||
mapsToType((value as any).type, objectConstructor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a type to the matching class
|
||||
* @param value The resourse type
|
||||
* @param objectConstructor The class to map to
|
||||
*/
|
||||
function mapsToType(value: ResourceType, objectConstructor: GenericConstructor<TypedObject>) {
|
||||
if (!objectConstructor || !value) {
|
||||
return;
|
||||
}
|
||||
typeMap.set(value.value, objectConstructor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mapped class for the given normalized class
|
||||
* @param target The normalized class
|
||||
*/
|
||||
export function getMapsTo(target: any) {
|
||||
return Reflect.getOwnMetadata(mapsToMetadataKey, target);
|
||||
}
|
||||
|
||||
export function relationship(value: ResourceType, isList: boolean = false): any {
|
||||
/**
|
||||
* Returns the mapped class for the given type
|
||||
* @param type The resource type
|
||||
*/
|
||||
export function getMapsToType(type: string | ResourceType) {
|
||||
if (typeof(type) === 'object') {
|
||||
type = (type as ResourceType).value;
|
||||
}
|
||||
return typeMap.get(type);
|
||||
}
|
||||
|
||||
export function relationship<T extends CacheableObject>(value: GenericConstructor<T>, isList: boolean = false): any {
|
||||
return function r(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
||||
if (!target || !propertyKey) {
|
||||
return;
|
||||
@@ -28,8 +64,10 @@ export function relationship(value: ResourceType, isList: boolean = false): any
|
||||
metaDataList.push(propertyKey);
|
||||
}
|
||||
relationshipMap.set(target.constructor, metaDataList);
|
||||
|
||||
return Reflect.metadata(relationshipKey, { resourceType: value, isList }).apply(this, arguments);
|
||||
return Reflect.metadata(relationshipKey, {
|
||||
resourceType: (value as any).type.value,
|
||||
isList
|
||||
}).apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -1,9 +1,8 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { NormalizedObject } from '../models/normalized-object.model';
|
||||
import { CacheableObject } from '../object-cache.reducer';
|
||||
import { getRelationships } from './build-decorators';
|
||||
import { NormalizedObjectFactory } from '../models/normalized-object-factory';
|
||||
import { getMapsToType, getRelationships } from './build-decorators';
|
||||
import { hasValue, isNotEmpty } from '../../../shared/empty.util';
|
||||
import { TypedObject } from '../object-cache.reducer';
|
||||
|
||||
/**
|
||||
* Return true if halObj has a value for `_links.self`
|
||||
@@ -35,8 +34,8 @@ export class NormalizedObjectBuildService {
|
||||
*
|
||||
* @param {TDomain} domainModel a domain model
|
||||
*/
|
||||
normalize<T extends CacheableObject>(domainModel: T): NormalizedObject<T> {
|
||||
const normalizedConstructor = NormalizedObjectFactory.getConstructor(domainModel.type);
|
||||
normalize<T extends TypedObject>(domainModel: T): NormalizedObject<T> {
|
||||
const normalizedConstructor = getMapsToType((domainModel as any).type);
|
||||
const relationships = getRelationships(normalizedConstructor) || [];
|
||||
|
||||
const normalizedModel = Object.assign({}, domainModel) as any;
|
||||
|
@@ -4,6 +4,7 @@ import { PaginatedList } from '../../data/paginated-list';
|
||||
import { PageInfo } from '../../shared/page-info.model';
|
||||
import { RemoteData } from '../../data/remote-data';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { createSuccessfulRemoteDataObject } from '../../../shared/testing/utils';
|
||||
|
||||
const pageInfo = new PageInfo();
|
||||
const array = [
|
||||
@@ -29,8 +30,8 @@ const array = [
|
||||
})
|
||||
];
|
||||
const paginatedList = new PaginatedList(pageInfo, array);
|
||||
const arrayRD = new RemoteData(false, false, true, undefined, array);
|
||||
const paginatedListRD = new RemoteData(false, false, true, undefined, paginatedList);
|
||||
const arrayRD = createSuccessfulRemoteDataObject(array);
|
||||
const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList);
|
||||
|
||||
describe('RemoteDataBuildService', () => {
|
||||
let service: RemoteDataBuildService;
|
||||
|
@@ -21,7 +21,8 @@ import {
|
||||
getRequestFromRequestUUID,
|
||||
getResourceLinksFromResponse
|
||||
} from '../../shared/operators';
|
||||
import { CacheableObject } from '../object-cache.reducer';
|
||||
import { CacheableObject, TypedObject } from '../object-cache.reducer';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils';
|
||||
|
||||
@Injectable()
|
||||
export class RemoteDataBuildService {
|
||||
@@ -200,7 +201,7 @@ export class RemoteDataBuildService {
|
||||
aggregate<T>(input: Array<Observable<RemoteData<T>>>): Observable<RemoteData<T[]>> {
|
||||
|
||||
if (isEmpty(input)) {
|
||||
return observableOf(new RemoteData(false, false, true, null, []));
|
||||
return createSuccessfulRemoteDataObject$([]);
|
||||
}
|
||||
|
||||
return observableCombineLatest(...input).pipe(
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize';
|
||||
import { ItemType } from '../../../shared/item-relationships/item-type.model';
|
||||
import { ResourceType } from '../../../shared/resource-type';
|
||||
import { mapsTo } from '../../builders/build-decorators';
|
||||
import { NormalizedObject } from '../normalized-object.model';
|
||||
import { IDToUUIDSerializer } from '../../id-to-uuid-serializer';
|
||||
@@ -11,7 +10,6 @@ import { IDToUUIDSerializer } from '../../id-to-uuid-serializer';
|
||||
@mapsTo(ItemType)
|
||||
@inheritSerialization(NormalizedObject)
|
||||
export class NormalizedItemType extends NormalizedObject<ItemType> {
|
||||
|
||||
/**
|
||||
* The label that describes the ResourceType of the Item
|
||||
*/
|
||||
@@ -27,6 +25,6 @@ export class NormalizedItemType extends NormalizedObject<ItemType> {
|
||||
/**
|
||||
* The universally unique identifier of this ItemType
|
||||
*/
|
||||
@autoserializeAs(new IDToUUIDSerializer(ResourceType.ItemType), 'id')
|
||||
@autoserializeAs(new IDToUUIDSerializer(ItemType.type.value), 'id')
|
||||
uuid: string;
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@ import { mapsTo, relationship } from '../../builders/build-decorators';
|
||||
import { NormalizedDSpaceObject } from '../normalized-dspace-object.model';
|
||||
import { NormalizedObject } from '../normalized-object.model';
|
||||
import { IDToUUIDSerializer } from '../../id-to-uuid-serializer';
|
||||
import { ItemType } from '../../../shared/item-relationships/item-type.model';
|
||||
|
||||
/**
|
||||
* Normalized model class for a DSpace RelationshipType
|
||||
@@ -12,7 +13,6 @@ import { IDToUUIDSerializer } from '../../id-to-uuid-serializer';
|
||||
@mapsTo(RelationshipType)
|
||||
@inheritSerialization(NormalizedDSpaceObject)
|
||||
export class NormalizedRelationshipType extends NormalizedObject<RelationshipType> {
|
||||
|
||||
/**
|
||||
* The identifier of this RelationshipType
|
||||
*/
|
||||
@@ -59,19 +59,19 @@ export class NormalizedRelationshipType extends NormalizedObject<RelationshipTyp
|
||||
* The type of Item found to the left of this RelationshipType
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.ItemType, false)
|
||||
@relationship(ItemType, false)
|
||||
leftType: string;
|
||||
|
||||
/**
|
||||
* The type of Item found to the right of this RelationshipType
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.ItemType, false)
|
||||
@relationship(ItemType, false)
|
||||
rightType: string;
|
||||
|
||||
/**
|
||||
* The universally unique identifier of this RelationshipType
|
||||
*/
|
||||
@autoserializeAs(new IDToUUIDSerializer(ResourceType.RelationshipType), 'id')
|
||||
@autoserializeAs(new IDToUUIDSerializer(RelationshipType.type.value), 'id')
|
||||
uuid: string;
|
||||
}
|
||||
|
@@ -1,9 +1,10 @@
|
||||
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize';
|
||||
import { Relationship } from '../../../shared/item-relationships/relationship.model';
|
||||
import { ResourceType } from '../../../shared/resource-type';
|
||||
import { mapsTo, relationship } from '../../builders/build-decorators';
|
||||
import { NormalizedObject } from '../normalized-object.model';
|
||||
import { IDToUUIDSerializer } from '../../id-to-uuid-serializer';
|
||||
import { RelationshipType } from '../../../shared/item-relationships/relationship-type.model';
|
||||
import { Item } from '../../../shared/item.model';
|
||||
|
||||
/**
|
||||
* Normalized model class for a DSpace Relationship
|
||||
@@ -22,14 +23,14 @@ export class NormalizedRelationship extends NormalizedObject<Relationship> {
|
||||
* The item to the left of this relationship
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.Item, false)
|
||||
@relationship(Item, false)
|
||||
leftItem: string;
|
||||
|
||||
/**
|
||||
* The item to the right of this relationship
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.Item, false)
|
||||
@relationship(Item, false)
|
||||
rightItem: string;
|
||||
|
||||
/**
|
||||
@@ -48,12 +49,12 @@ export class NormalizedRelationship extends NormalizedObject<Relationship> {
|
||||
* The type of Relationship
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.RelationshipType, false)
|
||||
@relationship(RelationshipType, false)
|
||||
relationshipType: string;
|
||||
|
||||
/**
|
||||
* The universally unique identifier of this Relationship
|
||||
*/
|
||||
@autoserializeAs(new IDToUUIDSerializer(ResourceType.Relationship), 'id')
|
||||
@autoserializeAs(new IDToUUIDSerializer(Relationship.type.value), 'id')
|
||||
uuid: string;
|
||||
}
|
||||
|
@@ -12,7 +12,6 @@ import { SupportLevel } from './support-level.model';
|
||||
@mapsTo(BitstreamFormat)
|
||||
@inheritSerialization(NormalizedObject)
|
||||
export class NormalizedBitstreamFormat extends NormalizedObject<BitstreamFormat> {
|
||||
|
||||
/**
|
||||
* Short description of this Bitstream Format
|
||||
*/
|
||||
|
@@ -1,9 +1,10 @@
|
||||
import { inheritSerialization, autoserialize } from 'cerialize';
|
||||
import { autoserialize, inheritSerialization } from 'cerialize';
|
||||
|
||||
import { NormalizedDSpaceObject } from './normalized-dspace-object.model';
|
||||
import { Bitstream } from '../../shared/bitstream.model';
|
||||
import { mapsTo, relationship } from '../builders/build-decorators';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
import { Item } from '../../shared/item.model';
|
||||
import { BitstreamFormat } from '../../shared/bitstream-format.model';
|
||||
|
||||
/**
|
||||
* Normalized model class for a DSpace Bitstream
|
||||
@@ -11,7 +12,6 @@ import { ResourceType } from '../../shared/resource-type';
|
||||
@mapsTo(Bitstream)
|
||||
@inheritSerialization(NormalizedDSpaceObject)
|
||||
export class NormalizedBitstream extends NormalizedDSpaceObject<Bitstream> {
|
||||
|
||||
/**
|
||||
* The size of this bitstream in bytes
|
||||
*/
|
||||
@@ -28,7 +28,7 @@ export class NormalizedBitstream extends NormalizedDSpaceObject<Bitstream> {
|
||||
* The format of this Bitstream
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.BitstreamFormat, false)
|
||||
@relationship(BitstreamFormat, false)
|
||||
format: string;
|
||||
|
||||
/**
|
||||
@@ -41,14 +41,14 @@ export class NormalizedBitstream extends NormalizedDSpaceObject<Bitstream> {
|
||||
* An array of Bundles that are direct parents of this Bitstream
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.Item, true)
|
||||
@relationship(Item, true)
|
||||
parents: string[];
|
||||
|
||||
/**
|
||||
* The Bundle that owns this Bitstream
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.Item, false)
|
||||
@relationship(Item, false)
|
||||
owner: string;
|
||||
|
||||
/**
|
||||
|
@@ -3,7 +3,7 @@ import { autoserialize, inheritSerialization } from 'cerialize';
|
||||
import { NormalizedDSpaceObject } from './normalized-dspace-object.model';
|
||||
import { Bundle } from '../../shared/bundle.model';
|
||||
import { mapsTo, relationship } from '../builders/build-decorators';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
import { Bitstream } from '../../shared/bitstream.model';
|
||||
|
||||
/**
|
||||
* Normalized model class for a DSpace Bundle
|
||||
@@ -15,7 +15,7 @@ export class NormalizedBundle extends NormalizedDSpaceObject<Bundle> {
|
||||
* The primary bitstream of this Bundle
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.Bitstream, false)
|
||||
@relationship(Bitstream, false)
|
||||
primaryBitstream: string;
|
||||
|
||||
/**
|
||||
@@ -32,7 +32,7 @@ export class NormalizedBundle extends NormalizedDSpaceObject<Bundle> {
|
||||
* List of Bitstreams that are part of this Bundle
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.Bitstream, true)
|
||||
@relationship(Bitstream, true)
|
||||
bitstreams: string[];
|
||||
|
||||
}
|
||||
|
@@ -3,7 +3,15 @@ import { autoserialize, deserialize, inheritSerialization } from 'cerialize';
|
||||
import { NormalizedDSpaceObject } from './normalized-dspace-object.model';
|
||||
import { Collection } from '../../shared/collection.model';
|
||||
import { mapsTo, relationship } from '../builders/build-decorators';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
import { NormalizedResourcePolicy } from './normalized-resource-policy.model';
|
||||
import { NormalizedBitstream } from './normalized-bitstream.model';
|
||||
import { NormalizedCommunity } from './normalized-community.model';
|
||||
import { NormalizedItem } from './normalized-item.model';
|
||||
import { License } from '../../shared/license.model';
|
||||
import { ResourcePolicy } from '../../shared/resource-policy.model';
|
||||
import { Bitstream } from '../../shared/bitstream.model';
|
||||
import { Community } from '../../shared/community.model';
|
||||
import { Item } from '../../shared/item.model';
|
||||
|
||||
/**
|
||||
* Normalized model class for a DSpace Collection
|
||||
@@ -22,42 +30,42 @@ export class NormalizedCollection extends NormalizedDSpaceObject<Collection> {
|
||||
* The Bitstream that represents the license of this Collection
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.License, false)
|
||||
@relationship(License, false)
|
||||
license: string;
|
||||
|
||||
/**
|
||||
* The Bitstream that represents the default Access Conditions of this Collection
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.ResourcePolicy, false)
|
||||
@relationship(ResourcePolicy, false)
|
||||
defaultAccessConditions: string;
|
||||
|
||||
/**
|
||||
* The Bitstream that represents the logo of this Collection
|
||||
*/
|
||||
@deserialize
|
||||
@relationship(ResourceType.Bitstream, false)
|
||||
@relationship(Bitstream, false)
|
||||
logo: string;
|
||||
|
||||
/**
|
||||
* An array of Communities that are direct parents of this Collection
|
||||
*/
|
||||
@deserialize
|
||||
@relationship(ResourceType.Community, true)
|
||||
@relationship(Community, true)
|
||||
parents: string[];
|
||||
|
||||
/**
|
||||
* The Community that owns this Collection
|
||||
*/
|
||||
@deserialize
|
||||
@relationship(ResourceType.Community, false)
|
||||
@relationship(Community, false)
|
||||
owner: string;
|
||||
|
||||
/**
|
||||
* List of Items that are part of (not necessarily owned by) this Collection
|
||||
*/
|
||||
@deserialize
|
||||
@relationship(ResourceType.Item, true)
|
||||
@relationship(Item, true)
|
||||
items: string[];
|
||||
|
||||
}
|
||||
|
@@ -1,9 +1,13 @@
|
||||
import { autoserialize, deserialize, inheritSerialization, serialize } from 'cerialize';
|
||||
import { autoserialize, deserialize, inheritSerialization } from 'cerialize';
|
||||
|
||||
import { NormalizedDSpaceObject } from './normalized-dspace-object.model';
|
||||
import { Community } from '../../shared/community.model';
|
||||
import { mapsTo, relationship } from '../builders/build-decorators';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
import { NormalizedBitstream } from './normalized-bitstream.model';
|
||||
import { NormalizedCollection } from './normalized-collection.model';
|
||||
import { Bitstream } from '../../shared/bitstream.model';
|
||||
import { Collection } from '../../shared/collection.model';
|
||||
|
||||
/**
|
||||
* Normalized model class for a DSpace Community
|
||||
@@ -11,7 +15,6 @@ import { ResourceType } from '../../shared/resource-type';
|
||||
@mapsTo(Community)
|
||||
@inheritSerialization(NormalizedDSpaceObject)
|
||||
export class NormalizedCommunity extends NormalizedDSpaceObject<Community> {
|
||||
|
||||
/**
|
||||
* A string representing the unique handle of this Community
|
||||
*/
|
||||
@@ -22,32 +25,32 @@ export class NormalizedCommunity extends NormalizedDSpaceObject<Community> {
|
||||
* The Bitstream that represents the logo of this Community
|
||||
*/
|
||||
@deserialize
|
||||
@relationship(ResourceType.Bitstream, false)
|
||||
@relationship(Bitstream, false)
|
||||
logo: string;
|
||||
|
||||
/**
|
||||
* An array of Communities that are direct parents of this Community
|
||||
*/
|
||||
@deserialize
|
||||
@relationship(ResourceType.Community, true)
|
||||
@relationship(Community, true)
|
||||
parents: string[];
|
||||
|
||||
/**
|
||||
* The Community that owns this Community
|
||||
*/
|
||||
@deserialize
|
||||
@relationship(ResourceType.Community, false)
|
||||
@relationship(Community, false)
|
||||
owner: string;
|
||||
|
||||
/**
|
||||
* List of Collections that are owned by this Community
|
||||
*/
|
||||
@deserialize
|
||||
@relationship(ResourceType.Collection, true)
|
||||
@relationship(Collection, true)
|
||||
collections: string[];
|
||||
|
||||
@deserialize
|
||||
@relationship(ResourceType.Community, true)
|
||||
@relationship(Community, true)
|
||||
subcommunities: string[];
|
||||
|
||||
}
|
||||
|
@@ -1,15 +1,15 @@
|
||||
import { autoserializeAs, deserializeAs } from 'cerialize';
|
||||
import { autoserializeAs, deserializeAs, autoserialize } from 'cerialize';
|
||||
import { DSpaceObject } from '../../shared/dspace-object.model';
|
||||
import { MetadataMap, MetadataMapSerializer } from '../../shared/metadata.models';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
import { mapsTo } from '../builders/build-decorators';
|
||||
import { NormalizedObject } from './normalized-object.model';
|
||||
import { TypedObject } from '../object-cache.reducer';
|
||||
|
||||
/**
|
||||
* An model class for a DSpaceObject.
|
||||
*/
|
||||
@mapsTo(DSpaceObject)
|
||||
export class NormalizedDSpaceObject<T extends DSpaceObject> extends NormalizedObject<T> {
|
||||
export class NormalizedDSpaceObject<T extends DSpaceObject> extends NormalizedObject<T> implements TypedObject {
|
||||
|
||||
/**
|
||||
* The link to the rest endpoint where this object can be found
|
||||
@@ -38,8 +38,8 @@ export class NormalizedDSpaceObject<T extends DSpaceObject> extends NormalizedOb
|
||||
/**
|
||||
* A string representing the kind of DSpaceObject, e.g. community, item, …
|
||||
*/
|
||||
@autoserializeAs(String)
|
||||
type: ResourceType;
|
||||
@autoserialize
|
||||
type: string;
|
||||
|
||||
/**
|
||||
* All metadata of this DSpaceObject
|
||||
|
@@ -4,6 +4,12 @@ import { NormalizedDSpaceObject } from './normalized-dspace-object.model';
|
||||
import { Item } from '../../shared/item.model';
|
||||
import { mapsTo, relationship } from '../builders/build-decorators';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
import { NormalizedCollection } from './normalized-collection.model';
|
||||
import { NormalizedBitstream } from './normalized-bitstream.model';
|
||||
import { NormalizedRelationship } from './items/normalized-relationship.model';
|
||||
import { Collection } from '../../shared/collection.model';
|
||||
import { Bitstream } from '../../shared/bitstream.model';
|
||||
import { Relationship } from '../../shared/item-relationships/relationship.model';
|
||||
|
||||
/**
|
||||
* Normalized model class for a DSpace Item
|
||||
@@ -46,25 +52,25 @@ export class NormalizedItem extends NormalizedDSpaceObject<Item> {
|
||||
* An array of Collections that are direct parents of this Item
|
||||
*/
|
||||
@deserialize
|
||||
@relationship(ResourceType.Collection, true)
|
||||
@relationship(Collection, true)
|
||||
parents: string[];
|
||||
|
||||
/**
|
||||
* The Collection that owns this Item
|
||||
*/
|
||||
@deserialize
|
||||
@relationship(ResourceType.Collection, false)
|
||||
@relationship(Collection, false)
|
||||
owningCollection: string;
|
||||
|
||||
/**
|
||||
* List of Bitstreams that are owned by this Item
|
||||
*/
|
||||
@deserialize
|
||||
@relationship(ResourceType.Bitstream, true)
|
||||
@relationship(Bitstream, true)
|
||||
bitstreams: string[];
|
||||
|
||||
@autoserialize
|
||||
@relationship(ResourceType.Relationship, true)
|
||||
@relationship(Relationship, true)
|
||||
relationships: string[];
|
||||
|
||||
}
|
||||
|
@@ -1,104 +0,0 @@
|
||||
import { NormalizedItemType } from './items/normalized-item-type.model';
|
||||
import { NormalizedRelationshipType } from './items/normalized-relationship-type.model';
|
||||
import { NormalizedRelationship } from './items/normalized-relationship.model';
|
||||
import { NormalizedBitstream } from './normalized-bitstream.model';
|
||||
import { NormalizedBundle } from './normalized-bundle.model';
|
||||
import { NormalizedItem } from './normalized-item.model';
|
||||
import { NormalizedCollection } from './normalized-collection.model';
|
||||
import { GenericConstructor } from '../../shared/generic-constructor';
|
||||
import { NormalizedCommunity } from './normalized-community.model';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
import { NormalizedObject } from './normalized-object.model';
|
||||
import { NormalizedLicense } from './normalized-license.model';
|
||||
import { NormalizedResourcePolicy } from './normalized-resource-policy.model';
|
||||
import { NormalizedWorkspaceItem } from '../../submission/models/normalized-workspaceitem.model';
|
||||
import { NormalizedEPerson } from '../../eperson/models/normalized-eperson.model';
|
||||
import { NormalizedGroup } from '../../eperson/models/normalized-group.model';
|
||||
import { NormalizedWorkflowItem } from '../../submission/models/normalized-workflowitem.model';
|
||||
import { NormalizedClaimedTask } from '../../tasks/models/normalized-claimed-task-object.model';
|
||||
import { NormalizedPoolTask } from '../../tasks/models/normalized-pool-task-object.model';
|
||||
import { NormalizedBitstreamFormat } from './normalized-bitstream-format.model';
|
||||
import { NormalizedMetadataSchema } from '../../metadata/normalized-metadata-schema.model';
|
||||
import { CacheableObject } from '../object-cache.reducer';
|
||||
import { NormalizedSubmissionDefinitionsModel } from '../../config/models/normalized-config-submission-definitions.model';
|
||||
import { NormalizedSubmissionFormsModel } from '../../config/models/normalized-config-submission-forms.model';
|
||||
import { NormalizedSubmissionSectionModel } from '../../config/models/normalized-config-submission-section.model';
|
||||
|
||||
export class NormalizedObjectFactory {
|
||||
public static getConstructor(type: ResourceType): GenericConstructor<NormalizedObject<CacheableObject>> {
|
||||
switch (type) {
|
||||
case ResourceType.Bitstream: {
|
||||
return NormalizedBitstream
|
||||
}
|
||||
case ResourceType.Bundle: {
|
||||
return NormalizedBundle
|
||||
}
|
||||
case ResourceType.Item: {
|
||||
return NormalizedItem
|
||||
}
|
||||
case ResourceType.Collection: {
|
||||
return NormalizedCollection
|
||||
}
|
||||
case ResourceType.Community: {
|
||||
return NormalizedCommunity
|
||||
}
|
||||
case ResourceType.BitstreamFormat: {
|
||||
return NormalizedBitstreamFormat
|
||||
}
|
||||
case ResourceType.License: {
|
||||
return NormalizedLicense
|
||||
}
|
||||
case ResourceType.ResourcePolicy: {
|
||||
return NormalizedResourcePolicy
|
||||
}
|
||||
case ResourceType.Relationship: {
|
||||
return NormalizedRelationship
|
||||
}
|
||||
case ResourceType.RelationshipType: {
|
||||
return NormalizedRelationshipType
|
||||
}
|
||||
case ResourceType.ItemType: {
|
||||
return NormalizedItemType
|
||||
}
|
||||
case ResourceType.EPerson: {
|
||||
return NormalizedEPerson
|
||||
}
|
||||
case ResourceType.Group: {
|
||||
return NormalizedGroup
|
||||
}
|
||||
case ResourceType.MetadataSchema: {
|
||||
return NormalizedMetadataSchema
|
||||
}
|
||||
case ResourceType.MetadataField: {
|
||||
return NormalizedGroup
|
||||
}
|
||||
case ResourceType.Workspaceitem: {
|
||||
return NormalizedWorkspaceItem
|
||||
}
|
||||
case ResourceType.Workflowitem: {
|
||||
return NormalizedWorkflowItem
|
||||
}
|
||||
case ResourceType.ClaimedTask: {
|
||||
return NormalizedClaimedTask
|
||||
}
|
||||
case ResourceType.PoolTask: {
|
||||
return NormalizedPoolTask
|
||||
}
|
||||
case ResourceType.SubmissionDefinition:
|
||||
case ResourceType.SubmissionDefinitions: {
|
||||
return NormalizedSubmissionDefinitionsModel
|
||||
}
|
||||
case ResourceType.SubmissionForm:
|
||||
case ResourceType.SubmissionForms: {
|
||||
return NormalizedSubmissionFormsModel
|
||||
}
|
||||
case ResourceType.SubmissionSection:
|
||||
case ResourceType.SubmissionSections: {
|
||||
return NormalizedSubmissionSectionModel
|
||||
}
|
||||
default: {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,25 +1,24 @@
|
||||
import { CacheableObject } from '../object-cache.reducer';
|
||||
import { CacheableObject, TypedObject } from '../object-cache.reducer';
|
||||
import { autoserialize } from 'cerialize';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
/**
|
||||
* An abstract model class for a NormalizedObject.
|
||||
*/
|
||||
export abstract class NormalizedObject<T extends CacheableObject> implements CacheableObject {
|
||||
|
||||
export abstract class NormalizedObject<T extends TypedObject> implements CacheableObject {
|
||||
/**
|
||||
* The link to the rest endpoint where this object can be found
|
||||
*/
|
||||
@autoserialize
|
||||
self: string;
|
||||
|
||||
/**
|
||||
* A string representing the kind of DSpaceObject, e.g. community, item, …
|
||||
*/
|
||||
@autoserialize
|
||||
type: ResourceType;
|
||||
|
||||
@autoserialize
|
||||
_links: {
|
||||
[name: string]: string
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A string representing the kind of object
|
||||
*/
|
||||
@autoserialize
|
||||
type: string;
|
||||
}
|
||||
|
@@ -12,7 +12,6 @@ import { ActionType } from './action-type.model';
|
||||
@mapsTo(ResourcePolicy)
|
||||
@inheritSerialization(NormalizedObject)
|
||||
export class NormalizedResourcePolicy extends NormalizedObject<ResourcePolicy> {
|
||||
|
||||
/**
|
||||
* The action that is allowed by this Resource Policy
|
||||
*/
|
||||
|
@@ -8,7 +8,7 @@ export enum SupportLevel {
|
||||
Unknown = 0,
|
||||
|
||||
/**
|
||||
* Unknown for Bitstream Formats that are known to the system, but not fully supported
|
||||
* Known for Bitstream Formats that are known to the system, but not fully supported
|
||||
*/
|
||||
Known = 1,
|
||||
|
||||
|
14
src/app/core/cache/object-cache.reducer.spec.ts
vendored
14
src/app/core/cache/object-cache.reducer.spec.ts
vendored
@@ -9,6 +9,7 @@ import {
|
||||
ResetObjectCacheTimestampsAction
|
||||
} from './object-cache.actions';
|
||||
import { Operation } from 'fast-json-patch';
|
||||
import { Item } from '../shared/item.model';
|
||||
|
||||
class NullAction extends RemoveFromObjectCacheAction {
|
||||
type = null;
|
||||
@@ -28,6 +29,7 @@ describe('objectCacheReducer', () => {
|
||||
const testState = {
|
||||
[selfLink1]: {
|
||||
data: {
|
||||
type: Item.type,
|
||||
self: selfLink1,
|
||||
foo: 'bar'
|
||||
},
|
||||
@@ -39,6 +41,7 @@ describe('objectCacheReducer', () => {
|
||||
},
|
||||
[selfLink2]: {
|
||||
data: {
|
||||
type: Item.type,
|
||||
self: requestUUID2,
|
||||
foo: 'baz'
|
||||
},
|
||||
@@ -67,7 +70,7 @@ describe('objectCacheReducer', () => {
|
||||
|
||||
it('should add the payload to the cache in response to an ADD action', () => {
|
||||
const state = Object.create(null);
|
||||
const objectToCache = { self: selfLink1 };
|
||||
const objectToCache = { self: selfLink1, type: Item.type };
|
||||
const timeAdded = new Date().getTime();
|
||||
const msToLive = 900000;
|
||||
const requestUUID = requestUUID1;
|
||||
@@ -80,7 +83,12 @@ describe('objectCacheReducer', () => {
|
||||
});
|
||||
|
||||
it('should overwrite an object in the cache in response to an ADD action if it already exists', () => {
|
||||
const objectToCache = { self: selfLink1, foo: 'baz', somethingElse: true };
|
||||
const objectToCache = {
|
||||
self: selfLink1,
|
||||
foo: 'baz',
|
||||
somethingElse: true,
|
||||
type: Item.type
|
||||
};
|
||||
const timeAdded = new Date().getTime();
|
||||
const msToLive = 900000;
|
||||
const requestUUID = requestUUID1;
|
||||
@@ -95,7 +103,7 @@ describe('objectCacheReducer', () => {
|
||||
|
||||
it('should perform the ADD action without affecting the previous state', () => {
|
||||
const state = Object.create(null);
|
||||
const objectToCache = { self: selfLink1 };
|
||||
const objectToCache = { self: selfLink1, type: Item.type };
|
||||
const timeAdded = new Date().getTime();
|
||||
const msToLive = 900000;
|
||||
const requestUUID = requestUUID1;
|
||||
|
9
src/app/core/cache/object-cache.reducer.ts
vendored
9
src/app/core/cache/object-cache.reducer.ts
vendored
@@ -32,15 +32,19 @@ export interface Patch {
|
||||
operations: Operation[];
|
||||
}
|
||||
|
||||
export abstract class TypedObject {
|
||||
static type: ResourceType;
|
||||
}
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
/**
|
||||
* An interface to represent objects that can be cached
|
||||
*
|
||||
* A cacheable object should have a self link
|
||||
*/
|
||||
export interface CacheableObject {
|
||||
export class CacheableObject extends TypedObject {
|
||||
uuid?: string;
|
||||
self: string;
|
||||
type?: ResourceType;
|
||||
// isNew: boolean;
|
||||
// dirtyType: DirtyType;
|
||||
// hasDirtyAttributes: boolean;
|
||||
@@ -59,6 +63,7 @@ export class ObjectCacheEntry implements CacheEntry {
|
||||
patches: Patch[] = [];
|
||||
isDirty: boolean;
|
||||
}
|
||||
/* tslint:enable:max-classes-per-file */
|
||||
|
||||
/**
|
||||
* The ObjectCache State
|
||||
|
@@ -10,13 +10,13 @@ import {
|
||||
RemoveFromObjectCacheAction
|
||||
} from './object-cache.actions';
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { ResourceType } from '../shared/resource-type';
|
||||
import { NormalizedItem } from './models/normalized-item.model';
|
||||
import { first } from 'rxjs/operators';
|
||||
import { Operation } from 'fast-json-patch';
|
||||
import { RestRequestMethod } from '../data/rest-request-method';
|
||||
import { AddToSSBAction } from './server-sync-buffer.actions';
|
||||
import { Patch } from './object-cache.reducer';
|
||||
import { Item } from '../shared/item.model';
|
||||
|
||||
describe('ObjectCacheService', () => {
|
||||
let service: ObjectCacheService;
|
||||
@@ -28,7 +28,7 @@ describe('ObjectCacheService', () => {
|
||||
const msToLive = 900000;
|
||||
let objectToCache = {
|
||||
self: selfLink,
|
||||
type: ResourceType.Item
|
||||
type: Item.type
|
||||
};
|
||||
let cacheEntry;
|
||||
let invalidCacheEntry;
|
||||
@@ -37,7 +37,7 @@ describe('ObjectCacheService', () => {
|
||||
function init() {
|
||||
objectToCache = {
|
||||
self: selfLink,
|
||||
type: ResourceType.Item
|
||||
type: Item.type
|
||||
};
|
||||
cacheEntry = {
|
||||
data: objectToCache,
|
||||
|
4
src/app/core/cache/object-cache.service.ts
vendored
4
src/app/core/cache/object-cache.service.ts
vendored
@@ -10,7 +10,6 @@ import { coreSelector } from '../core.selectors';
|
||||
import { RestRequestMethod } from '../data/rest-request-method';
|
||||
import { selfLinkFromUuidSelector } from '../index/index.selectors';
|
||||
import { GenericConstructor } from '../shared/generic-constructor';
|
||||
import { NormalizedObjectFactory } from './models/normalized-object-factory';
|
||||
import { NormalizedObject } from './models/normalized-object.model';
|
||||
import {
|
||||
AddPatchObjectCacheAction,
|
||||
@@ -21,6 +20,7 @@ import {
|
||||
|
||||
import { CacheableObject, ObjectCacheEntry, ObjectCacheState } from './object-cache.reducer';
|
||||
import { AddToSSBAction } from './server-sync-buffer.actions';
|
||||
import { getMapsToType } from './builders/build-decorators';
|
||||
|
||||
/**
|
||||
* The base selector function to select the object cache in the store
|
||||
@@ -109,7 +109,7 @@ export class ObjectCacheService {
|
||||
}
|
||||
),
|
||||
map((entry: ObjectCacheEntry) => {
|
||||
const type: GenericConstructor<NormalizedObject<T>> = NormalizedObjectFactory.getConstructor(entry.data.type);
|
||||
const type: GenericConstructor<NormalizedObject<T>> = getMapsToType((entry.data as any).type);
|
||||
return Object.assign(new type(), entry.data) as NormalizedObject<T>
|
||||
})
|
||||
);
|
||||
|
4
src/app/core/cache/response.models.ts
vendored
4
src/app/core/cache/response.models.ts
vendored
@@ -8,12 +8,12 @@ import { IntegrationModel } from '../integration/models/integration.model';
|
||||
import { RegistryMetadataschemasResponse } from '../registry/registry-metadataschemas-response.model';
|
||||
import { RegistryMetadatafieldsResponse } from '../registry/registry-metadatafields-response.model';
|
||||
import { RegistryBitstreamformatsResponse } from '../registry/registry-bitstreamformats-response.model';
|
||||
import { MetadataSchema } from '../metadata/metadataschema.model';
|
||||
import { MetadataField } from '../metadata/metadatafield.model';
|
||||
import { PaginatedList } from '../data/paginated-list';
|
||||
import { SubmissionObject } from '../submission/models/submission-object.model';
|
||||
import { DSpaceObject } from '../shared/dspace-object.model';
|
||||
import { NormalizedAuthStatus } from '../auth/models/normalized-auth-status.model';
|
||||
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
||||
import { MetadataField } from '../metadata/metadata-field.model';
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
export class RestResponse {
|
||||
|
@@ -8,8 +8,8 @@ import { Store } from '@ngrx/store';
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { PaginatedList } from '../data/paginated-list';
|
||||
import { PageInfo } from '../shared/page-info.model';
|
||||
import { NormalizedSubmissionDefinitionsModel } from './models/normalized-config-submission-definitions.model';
|
||||
import { NormalizedSubmissionSectionModel } from './models/normalized-config-submission-section.model';
|
||||
import { NormalizedSubmissionDefinitionModel } from './models/normalized-config-submission-definition.model';
|
||||
|
||||
describe('ConfigResponseParsingService', () => {
|
||||
let service: ConfigResponseParsingService;
|
||||
@@ -173,7 +173,7 @@ describe('ConfigResponseParsingService', () => {
|
||||
self: 'https://rest.api/config/submissiondefinitions/traditional/sections'
|
||||
});
|
||||
const definitions =
|
||||
Object.assign(new NormalizedSubmissionDefinitionsModel(), {
|
||||
Object.assign(new NormalizedSubmissionDefinitionModel(), {
|
||||
isDefault: true,
|
||||
name: 'traditional',
|
||||
type: 'submissiondefinition',
|
||||
|
@@ -5,10 +5,8 @@ import { RestRequest } from '../data/request.models';
|
||||
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
|
||||
import { ConfigSuccessResponse, ErrorResponse, RestResponse } from '../cache/response.models';
|
||||
import { isNotEmpty } from '../../shared/empty.util';
|
||||
import { ConfigObjectFactory } from './models/config-object-factory';
|
||||
|
||||
import { ConfigObject } from './models/config.model';
|
||||
import { ConfigType } from './models/config-type';
|
||||
import { BaseResponseParsingService } from '../data/base-response-parsing.service';
|
||||
import { GLOBAL_CONFIG } from '../../../config';
|
||||
import { GlobalConfig } from '../../../config/global-config.interface';
|
||||
@@ -16,8 +14,6 @@ import { ObjectCacheService } from '../cache/object-cache.service';
|
||||
|
||||
@Injectable()
|
||||
export class ConfigResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {
|
||||
|
||||
protected objectFactory = ConfigObjectFactory;
|
||||
protected toCache = false;
|
||||
|
||||
constructor(
|
||||
@@ -28,7 +24,7 @@ export class ConfigResponseParsingService extends BaseResponseParsingService imp
|
||||
|
||||
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
||||
if (isNotEmpty(data.payload) && isNotEmpty(data.payload._links) && (data.statusCode === 201 || data.statusCode === 200)) {
|
||||
const configDefinition = this.process<ConfigObject,ConfigType>(data.payload, request.uuid);
|
||||
const configDefinition = this.process<ConfigObject>(data.payload, request.uuid);
|
||||
return new ConfigSuccessResponse(configDefinition, data.statusCode, data.statusText, this.processPageInfo(data.payload));
|
||||
} else {
|
||||
return new ErrorResponse(
|
||||
|
@@ -1,36 +0,0 @@
|
||||
import { GenericConstructor } from '../../shared/generic-constructor';
|
||||
import { ConfigType } from './config-type';
|
||||
import { ConfigObject } from './config.model';
|
||||
import { NormalizedSubmissionDefinitionsModel } from './normalized-config-submission-definitions.model';
|
||||
import { NormalizedSubmissionFormsModel } from './normalized-config-submission-forms.model';
|
||||
import { NormalizedSubmissionSectionModel } from './normalized-config-submission-section.model';
|
||||
import { NormalizedSubmissionUploadsModel } from './normalized-config-submission-uploads.model';
|
||||
|
||||
/**
|
||||
* Class to return normalized models for config objects
|
||||
*/
|
||||
export class ConfigObjectFactory {
|
||||
public static getConstructor(type): GenericConstructor<ConfigObject> {
|
||||
switch (type) {
|
||||
case ConfigType.SubmissionDefinition:
|
||||
case ConfigType.SubmissionDefinitions: {
|
||||
return NormalizedSubmissionDefinitionsModel
|
||||
}
|
||||
case ConfigType.SubmissionForm:
|
||||
case ConfigType.SubmissionForms: {
|
||||
return NormalizedSubmissionFormsModel
|
||||
}
|
||||
case ConfigType.SubmissionSection:
|
||||
case ConfigType.SubmissionSections: {
|
||||
return NormalizedSubmissionSectionModel
|
||||
}
|
||||
case ConfigType.SubmissionUpload:
|
||||
case ConfigType.SubmissionUploads: {
|
||||
return NormalizedSubmissionUploadsModel
|
||||
}
|
||||
default: {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
import { ConfigObject } from './config.model';
|
||||
import { SubmissionSectionModel } from './config-submission-section.model';
|
||||
import { PaginatedList } from '../../data/paginated-list';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
|
||||
/**
|
||||
* Class for the configuration describing the submission
|
||||
*/
|
||||
export class SubmissionDefinitionModel extends ConfigObject {
|
||||
static type = new ResourceType('submissiondefinition');
|
||||
|
||||
/**
|
||||
* A boolean representing if this submission definition is the default or not
|
||||
*/
|
||||
isDefault: boolean;
|
||||
|
||||
/**
|
||||
* A list of SubmissionSectionModel that are present in this submission definition
|
||||
*/
|
||||
sections: PaginatedList<SubmissionSectionModel>;
|
||||
|
||||
}
|
@@ -1,17 +1,7 @@
|
||||
import { ConfigObject } from './config.model';
|
||||
import { SubmissionSectionModel } from './config-submission-section.model';
|
||||
import { PaginatedList } from '../../data/paginated-list';
|
||||
import { SubmissionDefinitionModel } from './config-submission-definition.model';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
|
||||
export class SubmissionDefinitionsModel extends ConfigObject {
|
||||
|
||||
/**
|
||||
* A boolean representing if this submission definition is the default or not
|
||||
*/
|
||||
isDefault: boolean;
|
||||
|
||||
/**
|
||||
* A list of SubmissionSectionModel that are present in this submission definition
|
||||
*/
|
||||
sections: PaginatedList<SubmissionSectionModel>;
|
||||
export class SubmissionDefinitionsModel extends SubmissionDefinitionModel {
|
||||
static type = new ResourceType('submissiondefinitions');
|
||||
|
||||
}
|
||||
|
22
src/app/core/config/models/config-submission-form.model.ts
Normal file
22
src/app/core/config/models/config-submission-form.model.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { ConfigObject } from './config.model';
|
||||
import { FormFieldModel } from '../../../shared/form/builder/models/form-field.model';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
|
||||
/**
|
||||
* An interface that define a form row and its properties.
|
||||
*/
|
||||
export interface FormRowModel {
|
||||
fields: FormFieldModel[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A model class for a NormalizedObject.
|
||||
*/
|
||||
export class SubmissionFormModel extends ConfigObject {
|
||||
static type = new ResourceType('submissionform');
|
||||
|
||||
/**
|
||||
* An array of [FormRowModel] that are present in this form
|
||||
*/
|
||||
rows: FormRowModel[];
|
||||
}
|
@@ -1,20 +1,9 @@
|
||||
import { ConfigObject } from './config.model';
|
||||
import { FormFieldModel } from '../../../shared/form/builder/models/form-field.model';
|
||||
|
||||
/**
|
||||
* An interface that define a form row and its properties.
|
||||
*/
|
||||
export interface FormRowModel {
|
||||
fields: FormFieldModel[];
|
||||
}
|
||||
import { SubmissionFormModel } from './config-submission-form.model';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
|
||||
/**
|
||||
* A model class for a NormalizedObject.
|
||||
*/
|
||||
export class SubmissionFormsModel extends ConfigObject {
|
||||
|
||||
/**
|
||||
* An array of [FormRowModel] that are present in this form
|
||||
*/
|
||||
rows: FormRowModel[];
|
||||
export class SubmissionFormsModel extends SubmissionFormModel {
|
||||
static type = new ResourceType('submissionforms');
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { ConfigObject } from './config.model';
|
||||
import { SectionsType } from '../../../submission/sections/sections-type';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
|
||||
/**
|
||||
* An interface that define section visibility and its properties.
|
||||
@@ -10,6 +11,7 @@ export interface SubmissionSectionVisibility {
|
||||
}
|
||||
|
||||
export class SubmissionSectionModel extends ConfigObject {
|
||||
static type = new ResourceType('submissionsection');
|
||||
|
||||
/**
|
||||
* The header for this section
|
||||
|
@@ -0,0 +1,6 @@
|
||||
import { SubmissionSectionModel } from './config-submission-section.model';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
|
||||
export class SubmissionSectionsModel extends SubmissionSectionModel {
|
||||
static type = new ResourceType('submissionsections');
|
||||
}
|
@@ -1,9 +1,10 @@
|
||||
import { ConfigObject } from './config.model';
|
||||
import { AccessConditionOption } from './config-access-condition-option.model';
|
||||
import { SubmissionFormsModel } from './config-submission-forms.model';
|
||||
import { ResourceType } from '../../shared/resource-type';
|
||||
|
||||
export class SubmissionUploadsModel extends ConfigObject {
|
||||
|
||||
static type = new ResourceType('submissionupload');
|
||||
/**
|
||||
* A list of available bitstream access conditions
|
||||
*/
|
||||
|
@@ -8,11 +8,6 @@ export abstract class ConfigObject implements CacheableObject {
|
||||
*/
|
||||
public name: string;
|
||||
|
||||
/**
|
||||
* A string representing the kind of config object
|
||||
*/
|
||||
public type: ResourceType;
|
||||
|
||||
/**
|
||||
* The links to all related resources returned by the rest api.
|
||||
*/
|
||||
|
@@ -0,0 +1,28 @@
|
||||
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize';
|
||||
import { SubmissionSectionModel } from './config-submission-section.model';
|
||||
import { PaginatedList } from '../../data/paginated-list';
|
||||
import { NormalizedConfigObject } from './normalized-config.model';
|
||||
import { SubmissionDefinitionsModel } from './config-submission-definitions.model';
|
||||
import { mapsTo } from '../../cache/builders/build-decorators';
|
||||
import { SubmissionDefinitionModel } from './config-submission-definition.model';
|
||||
|
||||
/**
|
||||
* Normalized class for the configuration describing the submission
|
||||
*/
|
||||
@mapsTo(SubmissionDefinitionModel)
|
||||
@inheritSerialization(NormalizedConfigObject)
|
||||
export class NormalizedSubmissionDefinitionModel extends NormalizedConfigObject<SubmissionDefinitionModel> {
|
||||
|
||||
/**
|
||||
* A boolean representing if this submission definition is the default or not
|
||||
*/
|
||||
@autoserialize
|
||||
isDefault: boolean;
|
||||
|
||||
/**
|
||||
* A list of SubmissionSectionModel that are present in this submission definition
|
||||
*/
|
||||
@autoserializeAs(SubmissionSectionModel)
|
||||
sections: PaginatedList<SubmissionSectionModel>;
|
||||
|
||||
}
|
@@ -1,25 +1,13 @@
|
||||
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize';
|
||||
import { SubmissionSectionModel } from './config-submission-section.model';
|
||||
import { PaginatedList } from '../../data/paginated-list';
|
||||
import { inheritSerialization } from 'cerialize';
|
||||
import { NormalizedConfigObject } from './normalized-config.model';
|
||||
import { SubmissionDefinitionsModel } from './config-submission-definitions.model';
|
||||
import { mapsTo } from '../../cache/builders/build-decorators';
|
||||
import { NormalizedSubmissionDefinitionModel } from './normalized-config-submission-definition.model';
|
||||
|
||||
/**
|
||||
* Normalized class for the configuration describing the submission
|
||||
*/
|
||||
@mapsTo(SubmissionDefinitionsModel)
|
||||
@inheritSerialization(NormalizedConfigObject)
|
||||
export class NormalizedSubmissionDefinitionsModel extends NormalizedConfigObject<SubmissionDefinitionsModel> {
|
||||
|
||||
/**
|
||||
* A boolean representing if this submission definition is the default or not
|
||||
*/
|
||||
@autoserialize
|
||||
isDefault: boolean;
|
||||
|
||||
/**
|
||||
* A list of SubmissionSectionModel that are present in this submission definition
|
||||
*/
|
||||
@autoserializeAs(SubmissionSectionModel)
|
||||
sections: PaginatedList<SubmissionSectionModel>;
|
||||
|
||||
export class NormalizedSubmissionDefinitionsModel extends NormalizedSubmissionDefinitionModel {
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user