Merge branch 'master' into improve-i18n-files

This commit is contained in:
Art Lowel
2019-08-08 13:50:10 +02:00
251 changed files with 2509 additions and 1792 deletions

View File

@@ -11,7 +11,7 @@ language: node_js
node_js: node_js:
- "8" - "8"
- "9" - "10"
cache: cache:
yarn: true yarn: true

View File

@@ -14,7 +14,7 @@ If you're looking for the 2016 Angular 2 DSpace UI prototype, you can find it [h
Quick start 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 ```bash
# clone the repo # clone the repo
@@ -65,7 +65,7 @@ Requirements
------------ ------------
- [Node.js](https://nodejs.org), [npm](https://www.npmjs.com/), and [yarn](https://yarnpkg.com) - [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. 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.

View File

@@ -13,7 +13,7 @@ module.exports = {
host: 'dspace7.4science.cloud', host: 'dspace7.4science.cloud',
port: 443, port: 443,
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript // NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
nameSpace: '/dspace-spring-rest/api' nameSpace: '/server/api'
}, },
// Caching settings // Caching settings
cache: { cache: {

View File

@@ -8,7 +8,7 @@
}, },
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"engines": { "engines": {
"node": ">=8.0.0" "node": "8.* || >= 10.*"
}, },
"scripts": { "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", "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", "webdriver:update": "node node_modules/protractor/bin/webdriver-manager update --standalone --gecko false",
"lint": "tslint \"src/**/*.ts\" && tslint \"e2e/**/*.ts\"", "lint": "tslint \"src/**/*.ts\" && tslint \"e2e/**/*.ts\"",
"docs": "typedoc --options typedoc.json ./src/", "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": { "dependencies": {
"@angular/animations": "^6.1.4", "@angular/animations": "^6.1.4",
@@ -121,7 +123,7 @@
"ngx-moment": "^3.1.0", "ngx-moment": "^3.1.0",
"ngx-pagination": "3.0.3", "ngx-pagination": "3.0.3",
"nouislider": "^11.0.0", "nouislider": "^11.0.0",
"pem": "1.12.3", "pem": "1.13.2",
"reflect-metadata": "0.1.12", "reflect-metadata": "0.1.12",
"rxjs": "6.2.2", "rxjs": "6.2.2",
"rxjs-spy": "^7.5.1", "rxjs-spy": "^7.5.1",
@@ -169,7 +171,7 @@
"codelyzer": "^4.4.4", "codelyzer": "^4.4.4",
"compression-webpack-plugin": "^1.1.6", "compression-webpack-plugin": "^1.1.6",
"copy-webpack-plugin": "^4.4.1", "copy-webpack-plugin": "^4.4.1",
"copyfiles": "^2.1.0", "copyfiles": "^2.1.1",
"coveralls": "3.0.0", "coveralls": "3.0.0",
"css-loader": "1.0.0", "css-loader": "1.0.0",
"cssnano": "^4.1.10", "cssnano": "^4.1.10",
@@ -192,8 +194,9 @@
"karma-remap-coverage": "^0.1.5", "karma-remap-coverage": "^0.1.5",
"karma-remap-istanbul": "0.6.0", "karma-remap-istanbul": "0.6.0",
"karma-sourcemap-loader": "0.3.7", "karma-sourcemap-loader": "0.3.7",
"karma-webdriver-launcher": "1.0.5", "karma-webdriver-launcher": "^1.0.7",
"karma-webpack": "3.0.0", "karma-webpack": "3.0.0",
"ncp": "^2.0.0",
"ngrx-store-freeze": "^0.2.4", "ngrx-store-freeze": "^0.2.4",
"node-sass": "^4.11.0", "node-sass": "^4.11.0",
"nodemon": "^1.15.0", "nodemon": "^1.15.0",
@@ -206,7 +209,7 @@
"postcss-loader": "^3.0.0", "postcss-loader": "^3.0.0",
"postcss-responsive-type": "1.0.0", "postcss-responsive-type": "1.0.0",
"postcss-smart-import": "0.7.6", "postcss-smart-import": "0.7.6",
"protractor": "^5.3.0", "protractor": "^5.4.2",
"protractor-istanbul-plugin": "2.0.0", "protractor-istanbul-plugin": "2.0.0",
"raw-loader": "0.5.1", "raw-loader": "0.5.1",
"resolve-url-loader": "^2.3.0", "resolve-url-loader": "^2.3.0",
@@ -227,10 +230,11 @@
"tslint": "5.11.0", "tslint": "5.11.0",
"typedoc": "^0.9.0", "typedoc": "^0.9.0",
"typescript": "^2.9.1", "typescript": "^2.9.1",
"webdriver-manager": "^12.1.6",
"webpack": "^4.17.1", "webpack": "^4.17.1",
"webpack-bundle-analyzer": "^3.3.2", "webpack-bundle-analyzer": "^3.3.2",
"webpack-dev-middleware": "3.2.0", "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-import-glob-loader": "^1.6.3",
"webpack-merge": "4.1.4", "webpack-merge": "4.1.4",
"webpack-node-externals": "1.7.2" "webpack-node-externals": "1.7.2"

View File

@@ -5,7 +5,7 @@
var SpecReporter = require('jasmine-spec-reporter').SpecReporter; var SpecReporter = require('jasmine-spec-reporter').SpecReporter;
exports.config = { exports.config = {
allScriptsTimeout: 11000, allScriptsTimeout: 600000,
// ----------------------------------------------------------------- // -----------------------------------------------------------------
// Uncomment to run tests using a remote Selenium server // Uncomment to run tests using a remote Selenium server
//seleniumAddress: 'http://selenium.address:4444/wd/hub', //seleniumAddress: 'http://selenium.address:4444/wd/hub',
@@ -73,7 +73,7 @@ exports.config = {
framework: 'jasmine', framework: 'jasmine',
jasmineNodeOpts: { jasmineNodeOpts: {
showColors: true, showColors: true,
defaultTimeoutInterval: 30000, defaultTimeoutInterval: 600000,
print: function () {} print: function () {}
}, },
useAllAngular2AppRoots: true, useAllAngular2AppRoots: true,

View File

@@ -13,6 +13,7 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { EnumKeysPipe } from '../../../shared/utils/enum-keys-pipe'; import { EnumKeysPipe } from '../../../shared/utils/enum-keys-pipe';
import { HostWindowService } from '../../../shared/host-window.service'; import { HostWindowService } from '../../../shared/host-window.service';
import { HostWindowServiceStub } from '../../../shared/testing/host-window-service-stub'; import { HostWindowServiceStub } from '../../../shared/testing/host-window-service-stub';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils';
describe('BitstreamFormatsComponent', () => { describe('BitstreamFormatsComponent', () => {
let comp: BitstreamFormatsComponent; let comp: BitstreamFormatsComponent;
@@ -52,7 +53,7 @@ describe('BitstreamFormatsComponent', () => {
extensions: null extensions: null
} }
]; ];
const mockFormats = observableOf(new RemoteData(false, false, true, undefined, new PaginatedList(null, mockFormatsList))); const mockFormats = createSuccessfulRemoteDataObject$(new PaginatedList(null, mockFormatsList));
const registryServiceStub = { const registryServiceStub = {
getBitstreamFormats: () => mockFormats getBitstreamFormats: () => mockFormats
}; };

View File

@@ -1,7 +1,7 @@
import { Action } from '@ngrx/store'; import { Action } from '@ngrx/store';
import { type } from '../../../shared/ngrx/type'; import { type } from '../../../shared/ngrx/type';
import { MetadataSchema } from '../../../core/metadata/metadataschema.model'; import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
import { MetadataField } from '../../../core/metadata/metadatafield.model'; import { MetadataField } from '../../../core/metadata/metadata-field.model';
/** /**
* For each action type in an action group, make a simple * For each action type in an action group, make a simple

View File

@@ -17,6 +17,7 @@ import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub'; import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub';
import { RestResponse } from '../../../core/cache/response.models'; import { RestResponse } from '../../../core/cache/response.models';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils';
describe('MetadataRegistryComponent', () => { describe('MetadataRegistryComponent', () => {
let comp: MetadataRegistryComponent; let comp: MetadataRegistryComponent;
@@ -36,7 +37,7 @@ describe('MetadataRegistryComponent', () => {
namespace: 'http://dspace.org/mockschema' 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 */ /* tslint:disable:no-empty */
const registryServiceStub = { const registryServiceStub = {
getMetadataSchemas: () => mockSchemas, getMetadataSchemas: () => mockSchemas,

View File

@@ -3,7 +3,6 @@ import { RegistryService } from '../../../core/registry/registry.service';
import { Observable, combineLatest as observableCombineLatest } from 'rxjs'; import { Observable, combineLatest as observableCombineLatest } from 'rxjs';
import { RemoteData } from '../../../core/data/remote-data'; import { RemoteData } from '../../../core/data/remote-data';
import { PaginatedList } from '../../../core/data/paginated-list'; import { PaginatedList } from '../../../core/data/paginated-list';
import { MetadataSchema } from '../../../core/metadata/metadataschema.model';
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
import { map, take } from 'rxjs/operators'; import { map, take } from 'rxjs/operators';
import { hasValue } from '../../../shared/empty.util'; 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 { NotificationsService } from '../../../shared/notifications/notifications.service';
import { Route, Router } from '@angular/router'; import { Route, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
@Component({ @Component({
selector: 'ds-metadata-registry', selector: 'ds-metadata-registry',

View File

@@ -7,8 +7,8 @@ import {
MetadataRegistrySelectSchemaAction MetadataRegistrySelectSchemaAction
} from './metadata-registry.actions'; } from './metadata-registry.actions';
import { metadataRegistryReducer, MetadataRegistryState } from './metadata-registry.reducers'; import { metadataRegistryReducer, MetadataRegistryState } from './metadata-registry.reducers';
import { MetadataSchema } from '../../../core/metadata/metadataschema.model'; import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
import { MetadataField } from '../../../core/metadata/metadatafield.model'; import { MetadataField } from '../../../core/metadata/metadata-field.model';
class NullAction extends MetadataRegistryEditSchemaAction { class NullAction extends MetadataRegistryEditSchemaAction {
type = null; type = null;

View File

@@ -1,4 +1,3 @@
import { MetadataSchema } from '../../../core/metadata/metadataschema.model';
import { import {
MetadataRegistryAction, MetadataRegistryAction,
MetadataRegistryActionTypes, MetadataRegistryActionTypes,
@@ -9,7 +8,8 @@ import {
MetadataRegistrySelectFieldAction, MetadataRegistrySelectFieldAction,
MetadataRegistrySelectSchemaAction MetadataRegistrySelectSchemaAction
} from './metadata-registry.actions'; } 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. * The metadata registry state.

View File

@@ -10,7 +10,7 @@ import { EnumKeysPipe } from '../../../../shared/utils/enum-keys-pipe';
import { RegistryService } from '../../../../core/registry/registry.service'; import { RegistryService } from '../../../../core/registry/registry.service';
import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service'; import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service';
import { of as observableOf } from 'rxjs/internal/observable/of'; 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', () => { describe('MetadataSchemaFormComponent', () => {
let component: MetadataSchemaFormComponent; let component: MetadataSchemaFormComponent;

View File

@@ -9,9 +9,9 @@ import { FormGroup } from '@angular/forms';
import { RegistryService } from '../../../../core/registry/registry.service'; import { RegistryService } from '../../../../core/registry/registry.service';
import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service'; import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service';
import { take } from 'rxjs/operators'; import { take } from 'rxjs/operators';
import { MetadataSchema } from '../../../../core/metadata/metadataschema.model';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { combineLatest } from 'rxjs/internal/observable/combineLatest'; import { combineLatest } from 'rxjs/internal/observable/combineLatest';
import { MetadataSchema } from '../../../../core/metadata/metadata-schema.model';
@Component({ @Component({
selector: 'ds-metadata-schema-form', selector: 'ds-metadata-schema-form',

View File

@@ -3,7 +3,6 @@ import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing'
import { MetadataFieldFormComponent } from './metadata-field-form.component'; import { MetadataFieldFormComponent } from './metadata-field-form.component';
import { RegistryService } from '../../../../core/registry/registry.service'; import { RegistryService } from '../../../../core/registry/registry.service';
import { of as observableOf } from 'rxjs/internal/observable/of'; import { of as observableOf } from 'rxjs/internal/observable/of';
import { MetadataField } from '../../../../core/metadata/metadatafield.model';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { TranslateModule } from '@ngx-translate/core'; 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 { EnumKeysPipe } from '../../../../shared/utils/enum-keys-pipe';
import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service'; import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service';
import { NO_ERRORS_SCHEMA } from '@angular/core'; 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', () => { describe('MetadataFieldFormComponent', () => {
let component: MetadataFieldFormComponent; let component: MetadataFieldFormComponent;

View File

@@ -1,5 +1,4 @@
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { MetadataSchema } from '../../../../core/metadata/metadataschema.model';
import { import {
DynamicFormControlModel, DynamicFormControlModel,
DynamicFormLayout, DynamicFormLayout,
@@ -8,10 +7,11 @@ import {
import { FormGroup } from '@angular/forms'; import { FormGroup } from '@angular/forms';
import { RegistryService } from '../../../../core/registry/registry.service'; import { RegistryService } from '../../../../core/registry/registry.service';
import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service'; import { FormBuilderService } from '../../../../shared/form/builder/form-builder.service';
import { MetadataField } from '../../../../core/metadata/metadatafield.model';
import { take } from 'rxjs/operators'; import { take } from 'rxjs/operators';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { combineLatest } from 'rxjs/internal/observable/combineLatest'; import { combineLatest } from 'rxjs/internal/observable/combineLatest';
import { MetadataSchema } from '../../../../core/metadata/metadata-schema.model';
import { MetadataField } from '../../../../core/metadata/metadata-field.model';
@Component({ @Component({
selector: 'ds-metadata-field-form', selector: 'ds-metadata-field-form',

View File

@@ -3,7 +3,6 @@ import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing'
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { RemoteData } from '../../../core/data/remote-data'; import { RemoteData } from '../../../core/data/remote-data';
import { PaginatedList } from '../../../core/data/paginated-list'; import { PaginatedList } from '../../../core/data/paginated-list';
import { MetadataSchema } from '../../../core/metadata/metadataschema.model';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { ActivatedRoute, Router } from '@angular/router'; 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 { NotificationsService } from '../../../shared/notifications/notifications.service';
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub'; import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub';
import { RestResponse } from '../../../core/cache/response.models'; import { RestResponse } from '../../../core/cache/response.models';
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils';
describe('MetadataSchemaComponent', () => { describe('MetadataSchemaComponent', () => {
let comp: MetadataSchemaComponent; let comp: MetadataSchemaComponent;
@@ -74,12 +75,12 @@ describe('MetadataSchemaComponent', () => {
schema: mockSchemasList[1] 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 */ /* tslint:disable:no-empty */
const registryServiceStub = { const registryServiceStub = {
getMetadataSchemas: () => mockSchemas, getMetadataSchemas: () => mockSchemas,
getMetadataFieldsBySchema: (schema: MetadataSchema) => observableOf(new RemoteData(false, false, true, undefined, new PaginatedList(null, mockFieldsList.filter((value) => value.schema === schema)))), getMetadataFieldsBySchema: (schema: MetadataSchema) => createSuccessfulRemoteDataObject$(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])), getMetadataSchemaByName: (schemaName: string) => createSuccessfulRemoteDataObject$(mockSchemasList.filter((value) => value.prefix === schemaName)[0]),
getActiveMetadataField: () => observableOf(undefined), getActiveMetadataField: () => observableOf(undefined),
getSelectedMetadataFields: () => observableOf([]), getSelectedMetadataFields: () => observableOf([]),
editMetadataField: (schema) => {}, editMetadataField: (schema) => {},

View File

@@ -4,8 +4,6 @@ import { ActivatedRoute, Router } from '@angular/router';
import { Observable, combineLatest as observableCombineLatest } from 'rxjs'; import { Observable, combineLatest as observableCombineLatest } from 'rxjs';
import { RemoteData } from '../../../core/data/remote-data'; import { RemoteData } from '../../../core/data/remote-data';
import { PaginatedList } from '../../../core/data/paginated-list'; 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 { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
import { map, take } from 'rxjs/operators'; import { map, take } from 'rxjs/operators';
import { hasValue } from '../../../shared/empty.util'; 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 { zip } from 'rxjs/internal/observable/zip';
import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { MetadataField } from '../../../core/metadata/metadata-field.model';
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
@Component({ @Component({
selector: 'ds-metadata-schema', selector: 'ds-metadata-schema',

View File

@@ -18,6 +18,7 @@ import { Item } from '../../core/shared/item.model';
import { ENV_CONFIG, GLOBAL_CONFIG } from '../../../config'; import { ENV_CONFIG, GLOBAL_CONFIG } from '../../../config';
import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-options.model'; import { BrowseEntrySearchOptions } from '../../core/browse/browse-entry-search-options.model';
import { toRemoteData } from '../+browse-by-metadata-page/browse-by-metadata-page.component.spec'; import { toRemoteData } from '../+browse-by-metadata-page/browse-by-metadata-page.component.spec';
import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
describe('BrowseByDatePageComponent', () => { describe('BrowseByDatePageComponent', () => {
let comp: BrowseByDatePageComponent; let comp: BrowseByDatePageComponent;
@@ -48,11 +49,11 @@ describe('BrowseByDatePageComponent', () => {
const mockBrowseService = { const mockBrowseService = {
getBrowseEntriesFor: (options: BrowseEntrySearchOptions) => toRemoteData([]), getBrowseEntriesFor: (options: BrowseEntrySearchOptions) => toRemoteData([]),
getBrowseItemsFor: (value: string, options: BrowseEntrySearchOptions) => toRemoteData([firstItem]), getBrowseItemsFor: (value: string, options: BrowseEntrySearchOptions) => toRemoteData([firstItem]),
getFirstItemFor: () => observableOf(new RemoteData(false, false, true, undefined, firstItem)) getFirstItemFor: () => createSuccessfulRemoteDataObject$(firstItem)
}; };
const mockDsoService = { const mockDsoService = {
findById: () => observableOf(new RemoteData(false, false, true, null, mockCommunity)) findById: () => createSuccessfulRemoteDataObject$(mockCommunity)
}; };
const activatedRouteStub = Object.assign(new ActivatedRouteStub(), { const activatedRouteStub = Object.assign(new ActivatedRouteStub(), {

View File

@@ -20,6 +20,9 @@ import { Item } from '../../core/shared/item.model';
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service'; import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
import { Community } from '../../core/shared/community.model'; import { Community } from '../../core/shared/community.model';
import { MockRouter } from '../../shared/mocks/mock-router'; 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', () => { describe('BrowseByMetadataPageComponent', () => {
let comp: BrowseByMetadataPageComponent; let comp: BrowseByMetadataPageComponent;
@@ -39,21 +42,21 @@ describe('BrowseByMetadataPageComponent', () => {
const mockEntries = [ const mockEntries = [
{ {
type: 'author', type: BrowseEntry.type,
authority: null, authority: null,
value: 'John Doe', value: 'John Doe',
language: 'en', language: 'en',
count: 1 count: 1
}, },
{ {
type: 'author', type: BrowseEntry.type,
authority: null, authority: null,
value: 'James Doe', value: 'James Doe',
language: 'en', language: 'en',
count: 3 count: 3
}, },
{ {
type: 'subject', type: BrowseEntry.type,
authority: null, authority: null,
value: 'Fake subject', value: 'Fake subject',
language: 'en', language: 'en',
@@ -68,12 +71,12 @@ describe('BrowseByMetadataPageComponent', () => {
]; ];
const mockBrowseService = { 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) getBrowseItemsFor: (value: string, options: BrowseEntrySearchOptions) => toRemoteData(mockItems)
}; };
const mockDsoService = { const mockDsoService = {
findById: () => observableOf(new RemoteData(false, false, true, null, mockCommunity)) findById: () => createSuccessfulRemoteDataObject$(mockCommunity)
}; };
const activatedRouteStub = Object.assign(new ActivatedRouteStub(), { const activatedRouteStub = Object.assign(new ActivatedRouteStub(), {
@@ -105,12 +108,6 @@ describe('BrowseByMetadataPageComponent', () => {
fixture.detectChanges(); 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', () => { it('should not fetch any items when no value is provided', () => {
expect(comp.items$).toBeUndefined(); expect(comp.items$).toBeUndefined();
}); });
@@ -160,5 +157,5 @@ describe('BrowseByMetadataPageComponent', () => {
}); });
export function toRemoteData(objects: any[]): Observable<RemoteData<PaginatedList<any>>> { 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));
} }

View File

@@ -17,6 +17,7 @@ import { RemoteData } from '../../core/data/remote-data';
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service'; import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
import { BrowseService } from '../../core/browse/browse.service'; import { BrowseService } from '../../core/browse/browse.service';
import { MockRouter } from '../../shared/mocks/mock-router'; import { MockRouter } from '../../shared/mocks/mock-router';
import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
describe('BrowseByTitlePageComponent', () => { describe('BrowseByTitlePageComponent', () => {
let comp: BrowseByTitlePageComponent; let comp: BrowseByTitlePageComponent;
@@ -52,7 +53,7 @@ describe('BrowseByTitlePageComponent', () => {
}; };
const mockDsoService = { const mockDsoService = {
findById: () => observableOf(new RemoteData(false, false, true, null, mockCommunity)) findById: () => createSuccessfulRemoteDataObject$(mockCommunity)
}; };
const activatedRouteStub = Object.assign(new ActivatedRouteStub(), { const activatedRouteStub = Object.assign(new ActivatedRouteStub(), {

View File

@@ -1,12 +1,9 @@
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { import { DynamicInputModel, DynamicTextAreaModel } from '@ng-dynamic-forms/core';
DynamicInputModel,
DynamicTextAreaModel
} from '@ng-dynamic-forms/core';
import { DynamicFormControlModel } from '@ng-dynamic-forms/core/src/model/dynamic-form-control.model'; 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 { Collection } from '../../core/shared/collection.model';
import { ComColFormComponent } from '../../shared/comcol-forms/comcol-form/comcol-form.component'; 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 * Form used for creating and editing collections
@@ -23,9 +20,9 @@ export class CollectionFormComponent extends ComColFormComponent<Collection> {
@Input() dso: Collection = new 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 * The dynamic form fields used for creating/editing a collection

View File

@@ -1,9 +1,11 @@
import { CreateCollectionPageGuard } from './create-collection-page.guard'; import { CreateCollectionPageGuard } from './create-collection-page.guard';
import { MockRouter } from '../../shared/mocks/mock-router'; import { MockRouter } from '../../shared/mocks/mock-router';
import { RemoteData } from '../../core/data/remote-data';
import { Community } from '../../core/shared/community.model'; import { Community } from '../../core/shared/community.model';
import { of as observableOf } from 'rxjs';
import { first } from 'rxjs/operators'; import { first } from 'rxjs/operators';
import {
createFailedRemoteDataObject$,
createSuccessfulRemoteDataObject$
} from '../../shared/testing/utils';
describe('CreateCollectionPageGuard', () => { describe('CreateCollectionPageGuard', () => {
describe('canActivate', () => { describe('canActivate', () => {
@@ -15,11 +17,11 @@ describe('CreateCollectionPageGuard', () => {
communityDataServiceStub = { communityDataServiceStub = {
findById: (id: string) => { findById: (id: string) => {
if (id === 'valid-id') { if (id === 'valid-id') {
return observableOf(new RemoteData(false, false, true, null, new Community())); return createSuccessfulRemoteDataObject$(new Community());
} else if (id === 'invalid-id') { } else if (id === 'invalid-id') {
return observableOf(new RemoteData(false, false, true, null, undefined)); return createSuccessfulRemoteDataObject$(undefined);
} else if (id === 'error-id') { } else if (id === 'error-id') {
return observableOf(new RemoteData(false, false, false, null, new Community())); return createFailedRemoteDataObject$(new Community());
} }
} }
}; };

View File

@@ -20,9 +20,9 @@ export class CommunityFormComponent extends ComColFormComponent<Community> {
@Input() dso: Community = new 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 * The dynamic form fields used for creating/editing a community

View File

@@ -1,9 +1,11 @@
import { CreateCommunityPageGuard } from './create-community-page.guard'; import { CreateCommunityPageGuard } from './create-community-page.guard';
import { MockRouter } from '../../shared/mocks/mock-router'; import { MockRouter } from '../../shared/mocks/mock-router';
import { RemoteData } from '../../core/data/remote-data';
import { Community } from '../../core/shared/community.model'; import { Community } from '../../core/shared/community.model';
import { of as observableOf } from 'rxjs';
import { first } from 'rxjs/operators'; import { first } from 'rxjs/operators';
import {
createFailedRemoteDataObject$,
createSuccessfulRemoteDataObject$
} from '../../shared/testing/utils';
describe('CreateCommunityPageGuard', () => { describe('CreateCommunityPageGuard', () => {
describe('canActivate', () => { describe('canActivate', () => {
@@ -15,11 +17,11 @@ describe('CreateCommunityPageGuard', () => {
communityDataServiceStub = { communityDataServiceStub = {
findById: (id: string) => { findById: (id: string) => {
if (id === 'valid-id') { if (id === 'valid-id') {
return observableOf(new RemoteData(false, false, true, null, new Community())); return createSuccessfulRemoteDataObject$(new Community());
} else if (id === 'invalid-id') { } else if (id === 'invalid-id') {
return observableOf(new RemoteData(false, false, true, null, undefined)); return createSuccessfulRemoteDataObject$(undefined);
} else if (id === 'error-id') { } else if (id === 'error-id') {
return observableOf(new RemoteData(false, false, false, null, new Community())); return createFailedRemoteDataObject$(new Community());
} }
} }
}; };

View File

@@ -11,6 +11,7 @@ import {RouterTestingModule} from '@angular/router/testing';
import {NoopAnimationsModule} from '@angular/platform-browser/animations'; import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {By} from '@angular/platform-browser'; import {By} from '@angular/platform-browser';
import {of as observableOf, Observable } from 'rxjs'; import {of as observableOf, Observable } from 'rxjs';
import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
describe('SubCommunityList Component', () => { describe('SubCommunityList Component', () => {
let comp: CommunityPageSubCommunityListComponent; let comp: CommunityPageSubCommunityListComponent;
@@ -40,8 +41,7 @@ describe('SubCommunityList Component', () => {
{ language: 'en_US', value: 'Test title' } { language: 'en_US', value: 'Test title' }
] ]
}, },
subcommunities: observableOf(new RemoteData(true, true, true, subcommunities: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), []))
undefined, new PaginatedList(new PageInfo(), [])))
}); });
const mockCommunity = Object.assign(new Community(), { const mockCommunity = Object.assign(new Community(), {
@@ -50,8 +50,7 @@ describe('SubCommunityList Component', () => {
{ language: 'en_US', value: 'Test title' } { language: 'en_US', value: 'Test title' }
] ]
}, },
subcommunities: observableOf(new RemoteData(true, true, true, subcommunities: createSuccessfulRemoteDataObject$(new PaginatedList(new PageInfo(), subcommunities))
undefined, new PaginatedList(new PageInfo(), subcommunities)))
}) })
; ;

View File

@@ -2,6 +2,10 @@ import {RemoteData} from '../../core/data/remote-data';
import {hot} from 'jasmine-marbles'; import {hot} from 'jasmine-marbles';
import {Item} from '../../core/shared/item.model'; import {Item} from '../../core/shared/item.model';
import {findSuccessfulAccordingTo} from './edit-item-operators'; import {findSuccessfulAccordingTo} from './edit-item-operators';
import {
createFailedRemoteDataObject,
createSuccessfulRemoteDataObject
} from '../../shared/testing/utils';
describe('findSuccessfulAccordingTo', () => { describe('findSuccessfulAccordingTo', () => {
let mockItem1; let mockItem1;
@@ -19,11 +23,11 @@ describe('findSuccessfulAccordingTo', () => {
}); });
it('should return first successful RemoteData Observable that complies to predicate', () => { it('should return first successful RemoteData Observable that complies to predicate', () => {
const testRD = { const testRD = {
a: new RemoteData(false, false, true, null, undefined), a: createSuccessfulRemoteDataObject(undefined),
b: new RemoteData(false, false, false, null, mockItem1), b: createFailedRemoteDataObject(mockItem1),
c: new RemoteData(false, false, true, null, mockItem2), c: createSuccessfulRemoteDataObject(mockItem2),
d: new RemoteData(false, false, true, null, mockItem1), d: createSuccessfulRemoteDataObject(mockItem1),
e: new RemoteData(false, false, true, null, mockItem2), e: createSuccessfulRemoteDataObject(mockItem2),
}; };
const source = hot('abcde', testRD); const source = hot('abcde', testRD);

View File

@@ -17,6 +17,7 @@ import { By } from '@angular/platform-browser';
import { ItemDeleteComponent } from './item-delete.component'; import { ItemDeleteComponent } from './item-delete.component';
import { getItemEditPath } from '../../item-page-routing.module'; import { getItemEditPath } from '../../item-page-routing.module';
import { RestResponse } from '../../../core/cache/response.models'; import { RestResponse } from '../../../core/cache/response.models';
import { createSuccessfulRemoteDataObject } from '../../../shared/testing/utils';
let comp: ItemDeleteComponent; let comp: ItemDeleteComponent;
let fixture: ComponentFixture<ItemDeleteComponent>; let fixture: ComponentFixture<ItemDeleteComponent>;
@@ -49,7 +50,7 @@ describe('ItemDeleteComponent', () => {
routeStub = { routeStub = {
data: observableOf({ data: observableOf({
item: new RemoteData(false, false, true, null, mockItem) item: createSuccessfulRemoteDataObject(mockItem)
}) })
}; };

View File

@@ -6,17 +6,18 @@ import { ObjectUpdatesService } from '../../../../core/data/object-updates/objec
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { RemoteData } from '../../../../core/data/remote-data'; import { RemoteData } from '../../../../core/data/remote-data';
import { PaginatedList } from '../../../../core/data/paginated-list'; import { PaginatedList } from '../../../../core/data/paginated-list';
import { MetadataField } from '../../../../core/metadata/metadatafield.model';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { SharedModule } from '../../../../shared/shared.module'; import { SharedModule } from '../../../../shared/shared.module';
import { getTestScheduler } from 'jasmine-marbles'; import { getTestScheduler } from 'jasmine-marbles';
import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model'; import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model';
import { TestScheduler } from 'rxjs/testing'; import { TestScheduler } from 'rxjs/testing';
import { MetadataSchema } from '../../../../core/metadata/metadataschema.model';
import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions'; import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { MetadatumViewModel } from '../../../../core/shared/metadata.models'; 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 comp: EditInPlaceFieldComponent;
let fixture: ComponentFixture<EditInPlaceFieldComponent>; let fixture: ComponentFixture<EditInPlaceFieldComponent>;
@@ -59,7 +60,7 @@ describe('EditInPlaceFieldComponent', () => {
paginatedMetadataFields = new PaginatedList(undefined, [mdField1, mdField2, mdField3]); paginatedMetadataFields = new PaginatedList(undefined, [mdField1, mdField2, mdField3]);
metadataFieldService = jasmine.createSpyObj({ metadataFieldService = jasmine.createSpyObj({
queryMetadataFields: observableOf(new RemoteData(false, false, true, undefined, paginatedMetadataFields)), queryMetadataFields: createSuccessfulRemoteDataObject$(paginatedMetadataFields),
}); });
objectUpdatesService = jasmine.createSpyObj('objectUpdatesService', objectUpdatesService = jasmine.createSpyObj('objectUpdatesService',
{ {

View File

@@ -4,13 +4,13 @@ import { RegistryService } from '../../../../core/registry/registry.service';
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'; import { BehaviorSubject, Observable, of as observableOf } from 'rxjs';
import { map, take } from 'rxjs/operators'; import { map, take } from 'rxjs/operators';
import { MetadataField } from '../../../../core/metadata/metadatafield.model';
import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model'; import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model';
import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions'; import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions';
import { FieldUpdate } from '../../../../core/data/object-updates/object-updates.reducer'; import { FieldUpdate } from '../../../../core/data/object-updates/object-updates.reducer';
import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service';
import { NgModel } from '@angular/forms'; import { NgModel } from '@angular/forms';
import { MetadatumViewModel } from '../../../../core/shared/metadata.models'; import { MetadatumViewModel } from '../../../../core/shared/metadata.models';
import { MetadataField } from '../../../../core/metadata/metadata-field.model';
@Component({ @Component({
// tslint:disable-next-line:component-selector // tslint:disable-next-line:component-selector

View File

@@ -20,13 +20,16 @@ import { RouterStub } from '../../../shared/testing/router-stub';
import { GLOBAL_CONFIG } from '../../../../config'; import { GLOBAL_CONFIG } from '../../../../config';
import { Item } from '../../../core/shared/item.model'; import { Item } from '../../../core/shared/item.model';
import { FieldChangeType } from '../../../core/data/object-updates/object-updates.actions'; 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 { MetadatumViewModel } from '../../../core/shared/metadata.models';
import { RegistryService } from '../../../core/registry/registry.service'; import { RegistryService } from '../../../core/registry/registry.service';
import { PaginatedList } from '../../../core/data/paginated-list'; 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 { 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 comp: ItemMetadataComponent;
let fixture: ComponentFixture<ItemMetadataComponent>; let fixture: ComponentFixture<ItemMetadataComponent>;
@@ -116,18 +119,18 @@ describe('ItemMetadataComponent', () => {
) )
; ;
itemService = jasmine.createSpyObj('itemService', { itemService = jasmine.createSpyObj('itemService', {
update: observableOf(new RemoteData(false, false, true, undefined, item)), update: createSuccessfulRemoteDataObject$(item),
commitUpdates: {} commitUpdates: {}
}); });
routeStub = { routeStub = {
parent: { parent: {
data: observableOf({ item: new RemoteData(false, false, true, null, item) }) data: observableOf({ item: createSuccessfulRemoteDataObject(item) })
} }
}; };
paginatedMetadataFields = new PaginatedList(undefined, [mdField1, mdField2, mdField3]); paginatedMetadataFields = new PaginatedList(undefined, [mdField1, mdField2, mdField3]);
metadataFieldService = jasmine.createSpyObj({ metadataFieldService = jasmine.createSpyObj({
getAllMetadataFields: observableOf(new RemoteData(false, false, true, undefined, paginatedMetadataFields)) getAllMetadataFields:createSuccessfulRemoteDataObject$(paginatedMetadataFields)
}); });
scheduler = getTestScheduler(); scheduler = getTestScheduler();
objectUpdatesService = jasmine.createSpyObj('objectUpdatesService', objectUpdatesService = jasmine.createSpyObj('objectUpdatesService',

View File

@@ -17,9 +17,9 @@ import { NotificationsService } from '../../../shared/notifications/notification
import { GLOBAL_CONFIG, GlobalConfig } from '../../../../config'; import { GLOBAL_CONFIG, GlobalConfig } from '../../../../config';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { RegistryService } from '../../../core/registry/registry.service'; import { RegistryService } from '../../../core/registry/registry.service';
import { MetadataField } from '../../../core/metadata/metadatafield.model';
import { MetadatumViewModel } from '../../../core/shared/metadata.models'; import { MetadatumViewModel } from '../../../core/shared/metadata.models';
import { Metadata } from '../../../core/shared/metadata.utils'; import { Metadata } from '../../../core/shared/metadata.utils';
import { MetadataField } from '../../../core/metadata/metadata-field.model';
@Component({ @Component({
selector: 'ds-item-metadata', selector: 'ds-item-metadata',

View File

@@ -16,6 +16,7 @@ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { ItemPrivateComponent } from './item-private.component'; import { ItemPrivateComponent } from './item-private.component';
import { RestResponse } from '../../../core/cache/response.models'; import { RestResponse } from '../../../core/cache/response.models';
import { createSuccessfulRemoteDataObject } from '../../../shared/testing/utils';
let comp: ItemPrivateComponent; let comp: ItemPrivateComponent;
let fixture: ComponentFixture<ItemPrivateComponent>; let fixture: ComponentFixture<ItemPrivateComponent>;
@@ -50,7 +51,7 @@ describe('ItemPrivateComponent', () => {
routeStub = { routeStub = {
data: observableOf({ data: observableOf({
item: new RemoteData(false, false, true, null, { item: createSuccessfulRemoteDataObject({
id: 'fake-id' id: 'fake-id'
}) })
}) })

View File

@@ -16,6 +16,7 @@ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { ItemPublicComponent } from './item-public.component'; import { ItemPublicComponent } from './item-public.component';
import { RestResponse } from '../../../core/cache/response.models'; import { RestResponse } from '../../../core/cache/response.models';
import { createSuccessfulRemoteDataObject } from '../../../shared/testing/utils';
let comp: ItemPublicComponent; let comp: ItemPublicComponent;
let fixture: ComponentFixture<ItemPublicComponent>; let fixture: ComponentFixture<ItemPublicComponent>;
@@ -50,7 +51,7 @@ describe('ItemPublicComponent', () => {
routeStub = { routeStub = {
data: observableOf({ data: observableOf({
item: new RemoteData(false, false, true, null, { item: createSuccessfulRemoteDataObject({
id: 'fake-id' id: 'fake-id'
}) })
}) })

View File

@@ -16,6 +16,7 @@ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { ItemReinstateComponent } from './item-reinstate.component'; import { ItemReinstateComponent } from './item-reinstate.component';
import { RestResponse } from '../../../core/cache/response.models'; import { RestResponse } from '../../../core/cache/response.models';
import { createSuccessfulRemoteDataObject } from '../../../shared/testing/utils';
let comp: ItemReinstateComponent; let comp: ItemReinstateComponent;
let fixture: ComponentFixture<ItemReinstateComponent>; let fixture: ComponentFixture<ItemReinstateComponent>;
@@ -50,7 +51,7 @@ describe('ItemReinstateComponent', () => {
routeStub = { routeStub = {
data: observableOf({ data: observableOf({
item: new RemoteData(false, false, true, null, { item: createSuccessfulRemoteDataObject({
id: 'fake-id' id: 'fake-id'
}) })
}) })

View File

@@ -12,7 +12,7 @@
{{'item.edit.tabs.status.labels.itemPage' | translate}}: {{'item.edit.tabs.status.labels.itemPage' | translate}}:
</div> </div>
<div class="col-9 float-left status-data" id="status-itemPage"> <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>
<div *ngFor="let operation of operations" class="w-100 pt-3"> <div *ngFor="let operation of operations" class="w-100 pt-3">

View File

@@ -11,7 +11,7 @@ import { Item } from '../../../core/shared/item.model';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { RemoteData } from '../../../core/data/remote-data'; import { createSuccessfulRemoteDataObject } from '../../../shared/testing/utils';
describe('ItemStatusComponent', () => { describe('ItemStatusComponent', () => {
let comp: ItemStatusComponent; let comp: ItemStatusComponent;
@@ -27,7 +27,7 @@ describe('ItemStatusComponent', () => {
const routeStub = { const routeStub = {
parent: { parent: {
data: observableOf({ item: new RemoteData(false, false, true, null, mockItem) }) data: observableOf({ item: createSuccessfulRemoteDataObject(mockItem) })
} }
}; };

View File

@@ -16,6 +16,7 @@ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ItemWithdrawComponent } from './item-withdraw.component'; import { ItemWithdrawComponent } from './item-withdraw.component';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { RestResponse } from '../../../core/cache/response.models'; import { RestResponse } from '../../../core/cache/response.models';
import { createSuccessfulRemoteDataObject } from '../../../shared/testing/utils';
let comp: ItemWithdrawComponent; let comp: ItemWithdrawComponent;
let fixture: ComponentFixture<ItemWithdrawComponent>; let fixture: ComponentFixture<ItemWithdrawComponent>;
@@ -50,7 +51,7 @@ describe('ItemWithdrawComponent', () => {
routeStub = { routeStub = {
data: observableOf({ data: observableOf({
item: new RemoteData(false, false, true, null, { item: createSuccessfulRemoteDataObject({
id: 'fake-id' id: 'fake-id'
}) })
}) })

View File

@@ -17,6 +17,10 @@ import { By } from '@angular/platform-browser';
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { getItemEditPath } from '../../item-page-routing.module'; import { getItemEditPath } from '../../item-page-routing.module';
import { RestResponse } from '../../../core/cache/response.models'; import { RestResponse } from '../../../core/cache/response.models';
import {
createSuccessfulRemoteDataObject,
createSuccessfulRemoteDataObject$
} from '../../../shared/testing/utils';
/** /**
* Test component that implements the AbstractSimpleItemActionComponent used to test the * Test component that implements the AbstractSimpleItemActionComponent used to test the
@@ -65,12 +69,12 @@ describe('AbstractSimpleItemActionComponent', () => {
}); });
mockItemDataService = jasmine.createSpyObj({ mockItemDataService = jasmine.createSpyObj({
findById: observableOf(new RemoteData(false, false, true, undefined, mockItem)) findById: createSuccessfulRemoteDataObject$(mockItem)
}); });
routeStub = { routeStub = {
data: observableOf({ data: observableOf({
item: new RemoteData(false, false, true, null, { item: createSuccessfulRemoteDataObject({
id: 'fake-id' id: 'fake-id'
}) })
}) })

View File

@@ -9,6 +9,10 @@ import { Item } from '../../../core/shared/item.model';
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { RemoteData } from '../../../core/data/remote-data'; import { RemoteData } from '../../../core/data/remote-data';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import {
createFailedRemoteDataObject$,
createSuccessfulRemoteDataObject$
} from '../../../shared/testing/utils';
let collectionsComponent: CollectionsComponent; let collectionsComponent: CollectionsComponent;
let fixture: ComponentFixture<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 succeededMockItem: Item = Object.assign(new Item(), {owningCollection: createSuccessfulRemoteDataObject$(mockCollection1)});
const failedMockItem: Item = Object.assign(new Item(), {owningCollection: observableOf(new RemoteData(false, false, false, null, mockCollection1))}); const failedMockItem: Item = Object.assign(new Item(), {owningCollection: createFailedRemoteDataObject$(mockCollection1)});
describe('CollectionsComponent', () => { describe('CollectionsComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {

View File

@@ -17,9 +17,13 @@ import { RemoteData } from '../../core/data/remote-data';
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import {
createSuccessfulRemoteDataObject,
createSuccessfulRemoteDataObject$
} from '../../shared/testing/utils';
const mockItem: Item = Object.assign(new Item(), { 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: { metadata: {
'dc.title': [ 'dc.title': [
{ {
@@ -30,7 +34,7 @@ const mockItem: Item = Object.assign(new Item(), {
} }
}); });
const routeStub = Object.assign(new ActivatedRouteStub(), { const routeStub = Object.assign(new ActivatedRouteStub(), {
data: observableOf({ item: new RemoteData(false, false, true, null, mockItem) }) data: observableOf({ item: createSuccessfulRemoteDataObject(mockItem) })
}); });
const metadataServiceStub = { const metadataServiceStub = {
/* tslint:disable:no-empty */ /* tslint:disable:no-empty */

View File

@@ -11,6 +11,7 @@ import { ItemPageFieldComponent } from './item-page-field.component';
import { MetadataValuesComponent } from '../../../field-components/metadata-values/metadata-values.component'; import { MetadataValuesComponent } from '../../../field-components/metadata-values/metadata-values.component';
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { MetadataMap, MetadataValue } from '../../../../core/shared/metadata.models'; import { MetadataMap, MetadataValue } from '../../../../core/shared/metadata.models';
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
let comp: ItemPageFieldComponent; let comp: ItemPageFieldComponent;
let fixture: ComponentFixture<ItemPageFieldComponent>; let fixture: ComponentFixture<ItemPageFieldComponent>;
@@ -52,7 +53,7 @@ describe('ItemPageFieldComponent', () => {
export function mockItemWithMetadataFieldAndValue(field: string, value: string): Item { export function mockItemWithMetadataFieldAndValue(field: string, value: string): Item {
const item = Object.assign(new 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() metadata: new MetadataMap()
}); });
item.metadata[field] = [{ item.metadata[field] = [{

View File

@@ -16,9 +16,13 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { createRelationshipsObservable } from './item-types/shared/item.component.spec'; import { createRelationshipsObservable } from './item-types/shared/item.component.spec';
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import {
createFailedRemoteDataObject$, createPendingRemoteDataObject$, createSuccessfulRemoteDataObject,
createSuccessfulRemoteDataObject$
} from '../../shared/testing/utils';
const mockItem: Item = Object.assign(new Item(), { 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: [], metadata: [],
relationships: createRelationshipsObservable() relationships: createRelationshipsObservable()
}); });
@@ -33,7 +37,7 @@ describe('ItemPageComponent', () => {
/* tslint:enable:no-empty */ /* tslint:enable:no-empty */
}; };
const mockRoute = Object.assign(new ActivatedRouteStub(), { const mockRoute = Object.assign(new ActivatedRouteStub(), {
data: observableOf({ item: new RemoteData(false, false, true, null, mockItem) }) data: observableOf({ item: createSuccessfulRemoteDataObject(mockItem) })
}); });
beforeEach(async(() => { beforeEach(async(() => {
@@ -66,7 +70,8 @@ describe('ItemPageComponent', () => {
describe('when the item is loading', () => { describe('when the item is loading', () => {
beforeEach(() => { 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(); fixture.detectChanges();
}); });
@@ -78,7 +83,7 @@ describe('ItemPageComponent', () => {
describe('when the item failed loading', () => { describe('when the item failed loading', () => {
beforeEach(() => { beforeEach(() => {
comp.itemRD$ = observableOf(new RemoteData(false, false, false, null, undefined)); comp.itemRD$ = createFailedRemoteDataObject$(undefined);
fixture.detectChanges(); fixture.detectChanges();
}); });

View File

@@ -17,9 +17,10 @@ import { createRelationshipsObservable } from '../shared/item.component.spec';
import { PublicationComponent } from './publication.component'; import { PublicationComponent } from './publication.component';
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { MetadataMap } from '../../../../core/shared/metadata.models'; import { MetadataMap } from '../../../../core/shared/metadata.models';
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
const mockItem: Item = Object.assign(new Item(), { 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(), metadata: new MetadataMap(),
relationships: createRelationshipsObservable() relationships: createRelationshipsObservable()
}); });

View File

@@ -26,6 +26,7 @@ import { MetadatumRepresentation } from '../../../../core/shared/metadata-repres
import { ItemMetadataRepresentation } from '../../../../core/shared/metadata-representation/item/item-metadata-representation.model'; import { ItemMetadataRepresentation } from '../../../../core/shared/metadata-representation/item/item-metadata-representation.model';
import { MetadataMap, MetadataValue } from '../../../../core/shared/metadata.models'; import { MetadataMap, MetadataValue } from '../../../../core/shared/metadata.models';
import { compareArraysUsing, compareArraysUsingIds } from './item-relationships-utils'; 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 * 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() { 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(), { Object.assign(new Relationship(), {
relationshipType: observableOf(new RemoteData(false, false, true, null, new RelationshipType())), relationshipType: createSuccessfulRemoteDataObject$(new RelationshipType()),
leftItem: observableOf(new RemoteData(false, false, true, null, new Item())), leftItem: createSuccessfulRemoteDataObject$(new Item()),
rightItem: observableOf(new RemoteData(false, false, true, null, new Item())) rightItem: createSuccessfulRemoteDataObject$(new Item())
}) })
]))); ]));
} }
describe('ItemComponent', () => { describe('ItemComponent', () => {
const arr1 = [ const arr1 = [
@@ -337,15 +338,15 @@ describe('ItemComponent', () => {
uuid: '1', uuid: '1',
metadata: new MetadataMap() 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(), { Object.assign(new Relationship(), {
uuid: '123', uuid: '123',
id: '123', id: '123',
leftItem: observableOf(new RemoteData(false, false, true, null, mockItem)), leftItem: createSuccessfulRemoteDataObject$(mockItem),
rightItem: observableOf(new RemoteData(false, false, true, null, relatedItem)), rightItem: createSuccessfulRemoteDataObject$(relatedItem),
relationshipType: observableOf(new RemoteData(false, false, true, null, new RelationshipType())) relationshipType: createSuccessfulRemoteDataObject$(new RelationshipType())
}) })
]))); ]));
mockItem.metadata[metadataField] = [ mockItem.metadata[metadataField] = [
{ {
value: 'Second value', value: 'Second value',
@@ -369,7 +370,7 @@ describe('ItemComponent', () => {
const mockItemDataService = Object.assign({ const mockItemDataService = Object.assign({
findById: (id) => { findById: (id) => {
if (id === relatedItem.id) { if (id === relatedItem.id) {
return observableOf(new RemoteData(false, false, true, null, relatedItem)) return createSuccessfulRemoteDataObject$(relatedItem)
} }
} }
}) as ItemDataService; }) as ItemDataService;

View File

@@ -8,14 +8,15 @@ import { PageInfo } from '../../../core/shared/page-info.model';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { createRelationshipsObservable } from '../item-types/shared/item.component.spec'; import { createRelationshipsObservable } from '../item-types/shared/item.component.spec';
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils';
const mockItem1: Item = Object.assign(new Item(), { 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: [], metadata: [],
relationships: createRelationshipsObservable() relationships: createRelationshipsObservable()
}); });
const mockItem2: Item = Object.assign(new Item(), { 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: [], metadata: [],
relationships: createRelationshipsObservable() relationships: createRelationshipsObservable()
}); });

View File

@@ -29,6 +29,7 @@ import { RoleDirective } from '../shared/roles/role.directive';
import { RoleService } from '../core/roles/role.service'; import { RoleService } from '../core/roles/role.service';
import { MockRoleService } from '../shared/mocks/mock-role-service'; import { MockRoleService } from '../shared/mocks/mock-role-service';
import { SearchFixedFilterService } from '../+search-page/search-filters/search-filter/search-fixed-filter.service'; import { SearchFixedFilterService } from '../+search-page/search-filters/search-filter/search-fixed-filter.service';
import { createSuccessfulRemoteDataObject$ } from '../shared/testing/utils';
describe('MyDSpacePageComponent', () => { describe('MyDSpacePageComponent', () => {
let comp: MyDSpacePageComponent; let comp: MyDSpacePageComponent;
@@ -46,7 +47,7 @@ describe('MyDSpacePageComponent', () => {
pagination.currentPage = 1; pagination.currentPage = 1;
pagination.pageSize = 10; pagination.pageSize = 10;
const sort: SortOptions = new SortOptions('score', SortDirection.DESC); 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', { const searchServiceStub = jasmine.createSpyObj('SearchService', {
search: mockResults, search: mockResults,
getSearchLink: '/mydspace', getSearchLink: '/mydspace',

View File

@@ -1,10 +1,12 @@
import { autoserialize, autoserializeAs } from 'cerialize'; import { autoserialize, inheritSerialization } from 'cerialize';
import { MetadataMap } from '../core/shared/metadata.models'; import { MetadataMap } from '../core/shared/metadata.models';
import { ListableObject } from '../shared/object-collection/shared/listable-object.model'; 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 * Represents a normalized version of a search result object of a certain DSpaceObject
*/ */
@inheritSerialization(NormalizedObject)
export class NormalizedSearchResult implements ListableObject { export class NormalizedSearchResult implements ListableObject {
/** /**
* The UUID of the DSpaceObject that was found * The UUID of the DSpaceObject that was found

View File

@@ -20,6 +20,7 @@ import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-d
import { SearchConfigurationServiceStub } from '../../../../shared/testing/search-configuration-service-stub'; import { SearchConfigurationServiceStub } from '../../../../shared/testing/search-configuration-service-stub';
import { SEARCH_CONFIG_SERVICE } from '../../../../+my-dspace-page/my-dspace-page.component'; import { SEARCH_CONFIG_SERVICE } from '../../../../+my-dspace-page/my-dspace-page.component';
import { tap } from 'rxjs/operators'; import { tap } from 'rxjs/operators';
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
describe('SearchFacetFilterComponent', () => { describe('SearchFacetFilterComponent', () => {
let comp: SearchFacetFilterComponent; let comp: SearchFacetFilterComponent;
@@ -61,7 +62,7 @@ describe('SearchFacetFilterComponent', () => {
let router; let router;
const page = observableOf(0); 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(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), NoopAnimationsModule, FormsModule], imports: [TranslateModule.forRoot(), NoopAnimationsModule, FormsModule],

View File

@@ -20,6 +20,7 @@ import { RouteService } from '../../../../shared/services/route.service';
import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service';
import { SEARCH_CONFIG_SERVICE } from '../../../../+my-dspace-page/my-dspace-page.component'; import { SEARCH_CONFIG_SERVICE } from '../../../../+my-dspace-page/my-dspace-page.component';
import { SearchConfigurationServiceStub } from '../../../../shared/testing/search-configuration-service-stub'; import { SearchConfigurationServiceStub } from '../../../../shared/testing/search-configuration-service-stub';
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/testing/utils';
describe('SearchRangeFilterComponent', () => { describe('SearchRangeFilterComponent', () => {
let comp: SearchRangeFilterComponent; let comp: SearchRangeFilterComponent;
@@ -66,7 +67,7 @@ describe('SearchRangeFilterComponent', () => {
let router; let router;
const page = observableOf(0); 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(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), NoopAnimationsModule, FormsModule], imports: [TranslateModule.forRoot(), NoopAnimationsModule, FormsModule],

View File

@@ -25,6 +25,7 @@ import { RouteService } from '../shared/services/route.service';
import { SearchConfigurationServiceStub } from '../shared/testing/search-configuration-service-stub'; import { SearchConfigurationServiceStub } from '../shared/testing/search-configuration-service-stub';
import { PaginatedSearchOptions } from './paginated-search-options.model'; import { PaginatedSearchOptions } from './paginated-search-options.model';
import { SearchFixedFilterService } from './search-filters/search-filter/search-fixed-filter.service'; import { SearchFixedFilterService } from './search-filters/search-filter/search-fixed-filter.service';
import { createSuccessfulRemoteDataObject$ } from '../shared/testing/utils';
let comp: SearchPageComponent; let comp: SearchPageComponent;
let fixture: ComponentFixture<SearchPageComponent>; let fixture: ComponentFixture<SearchPageComponent>;
@@ -41,7 +42,7 @@ pagination.id = 'search-results-pagination';
pagination.currentPage = 1; pagination.currentPage = 1;
pagination.pageSize = 10; pagination.pageSize = 10;
const sort: SortOptions = new SortOptions('score', SortDirection.DESC); 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', { const searchServiceStub = jasmine.createSpyObj('SearchService', {
search: mockResults, search: mockResults,
getSearchLink: '/search', getSearchLink: '/search',

View File

@@ -114,7 +114,7 @@ export const objects = [
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/communities/7669c72a-3f2a-451f-a3b9-9210e7a4c02f', self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/communities/7669c72a-3f2a-451f-a3b9-9210e7a4c02f',
id: '7669c72a-3f2a-451f-a3b9-9210e7a4c02f', id: '7669c72a-3f2a-451f-a3b9-9210e7a4c02f',
uuid: '7669c72a-3f2a-451f-a3b9-9210e7a4c02f', uuid: '7669c72a-3f2a-451f-a3b9-9210e7a4c02f',
type: ResourceType.Community, type: Community.type,
metadata: { metadata: {
'dc.description': [ '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', self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/communities/9076bd16-e69a-48d6-9e41-0238cb40d863',
id: '9076bd16-e69a-48d6-9e41-0238cb40d863', id: '9076bd16-e69a-48d6-9e41-0238cb40d863',
uuid: '9076bd16-e69a-48d6-9e41-0238cb40d863', uuid: '9076bd16-e69a-48d6-9e41-0238cb40d863',
type: ResourceType.Community, type: Community.type,
metadata: { metadata: {
'dc.description': [ 'dc.description': [
{ {

View File

@@ -21,6 +21,7 @@ import { getSucceededRemoteData } from '../../core/shared/operators';
import { SearchFilter } from '../search-filter.model'; import { SearchFilter } from '../search-filter.model';
import { DSpaceObjectType } from '../../core/shared/dspace-object-type.model'; import { DSpaceObjectType } from '../../core/shared/dspace-object-type.model';
import { SearchFixedFilterService } from '../search-filters/search-filter/search-fixed-filter.service'; 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 * 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, scope: this.defaultScope,
query: this.defaultQuery query: this.defaultQuery
}); });
this._defaults = observableOf(new RemoteData(false, false, true, null, options)); this._defaults = createSuccessfulRemoteDataObject$(options);
} }
return this._defaults; return this._defaults;
} }

View File

@@ -28,6 +28,7 @@ import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.serv
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { RouteService } from '../../shared/services/route.service'; import { RouteService } from '../../shared/services/route.service';
import { routeServiceStub } from '../../shared/testing/route-service-stub'; import { routeServiceStub } from '../../shared/testing/route-service-stub';
import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
@Component({ template: '' }) @Component({ template: '' })
class DummyComponent { class DummyComponent {
@@ -91,7 +92,7 @@ describe('SearchService', () => {
); );
}, },
aggregate: (input: Array<Observable<RemoteData<any>>>): Observable<RemoteData<any[]>> => { aggregate: (input: Array<Observable<RemoteData<any>>>): Observable<RemoteData<any[]>> => {
return observableOf(new RemoteData(false, false, true, null, [])); return createSuccessfulRemoteDataObject$([]);
} }
}; };

View File

@@ -1,6 +1,6 @@
import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs';
import { Injectable, OnDestroy } from '@angular/core'; 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 { first, map, switchMap } from 'rxjs/operators';
import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service';
import { import {
@@ -40,7 +40,6 @@ import { PaginatedSearchOptions } from '../paginated-search-options.model';
import { Community } from '../../core/shared/community.model'; import { Community } from '../../core/shared/community.model';
import { CommunityDataService } from '../../core/data/community-data.service'; import { CommunityDataService } from '../../core/data/community-data.service';
import { ViewMode } from '../../core/shared/view-mode.model'; 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 { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
import { RouteService } from '../../shared/services/route.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 scopeObject: Observable<RemoteData<DSpaceObject>> = this.dspaceObjectService.findById(scopeId).pipe(getSucceededRemoteData());
const scopeList: Observable<DSpaceObject[]> = scopeObject.pipe( const scopeList: Observable<DSpaceObject[]> = scopeObject.pipe(
switchMap((dsoRD: RemoteData<DSpaceObject>) => { 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; const community: Community = dsoRD.payload as Community;
return observableCombineLatest(community.subcommunities, community.collections).pipe( return observableCombineLatest(community.subcommunities, community.collections).pipe(
map(([subCommunities, collections]) => { map(([subCommunities, collections]) => {

View File

@@ -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. * This module defines the default component to load when navigating to the workflowitems edit page path.
*/ */
export class WorkflowitemsEditPageRoutingModule { } export class WorkflowItemsEditPageRoutingModule { }

View File

@@ -1,12 +1,12 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { SharedModule } from '../shared/shared.module'; 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'; import { SubmissionModule } from '../submission/submission.module';
@NgModule({ @NgModule({
imports: [ imports: [
WorkflowitemsEditPageRoutingModule, WorkflowItemsEditPageRoutingModule,
CommonModule, CommonModule,
SharedModule, SharedModule,
SubmissionModule, SubmissionModule,
@@ -16,6 +16,6 @@ import { SubmissionModule } from '../submission/submission.module';
/** /**
* This module handles all modules that need to access the workflowitems edit page. * This module handles all modules that need to access the workflowitems edit page.
*/ */
export class WorkflowitemsEditPageModule { export class WorkflowItemsEditPageModule {
} }

View File

@@ -32,7 +32,7 @@ export function getCommunityModulePath() {
{ path: 'logout', loadChildren: './+logout-page/logout-page.module#LogoutPageModule' }, { path: 'logout', loadChildren: './+logout-page/logout-page.module#LogoutPageModule' },
{ path: 'submit', loadChildren: './+submit-page/submit-page.module#SubmitPageModule' }, { path: 'submit', loadChildren: './+submit-page/submit-page.module#SubmitPageModule' },
{ path: 'workspaceitems', loadChildren: './+workspaceitems-edit-page/workspaceitems-edit-page.module#WorkspaceitemsEditPageModule' }, { 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 }, { path: '**', pathMatch: 'full', component: PageNotFoundComponent },
]) ])
], ],

View File

@@ -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;
}
}
}
}

View File

@@ -35,95 +35,103 @@ describe('AuthResponseParsingService', () => {
}); });
describe('parse', () => { describe('parse', () => {
const validRequest = new AuthPostRequest( let validRequest;
'69f375b5-19f4-4453-8c7a-7dc5c55aafbb', let validRequest2;
'https://rest.api/dspace-spring-rest/api/authn/login', let validResponse;
'password=test&user=myself@testshib.org'); let validResponse1;
let validResponse2;
beforeEach(() => {
const validRequest2 = new AuthGetRequest( validRequest = new AuthPostRequest(
'69f375b5-19f4-4453-8c7a-7dc5c55aafbb', '69f375b5-19f4-4453-8c7a-7dc5c55aafbb',
'https://rest.api/dspace-spring-rest/api/authn/status'); 'https://rest.api/dspace-spring-rest/api/authn/login',
'password=test&user=myself@testshib.org');
const validResponse = { validRequest2 = new AuthGetRequest(
payload: { '69f375b5-19f4-4453-8c7a-7dc5c55aafbb',
authenticated: true, 'https://rest.api/dspace-spring-rest/api/authn/status');
id: null,
okay: true,
token: {
accessToken: 'eyJhbGciOiJIUzI1NiJ9.eyJlaWQiOiI0ZGM3MGFiNS1jZDczLTQ5MmYtYjAwNy0zMTc5ZDJkOTI5NmIiLCJzZyI6W10sImV4cCI6MTUyNjMxODMyMn0.ASmvcbJFBfzhN7D5ncloWnaVZr5dLtgTuOgHaCKiimc',
expires: 1526318322000
},
} as AuthStatus,
statusCode: 200,
statusText: '200'
};
const validResponse1 = { validResponse = {
payload: {}, payload: {
statusCode: 404, authenticated: true,
statusText: '404' id: null,
}; okay: true,
token: {
accessToken: 'eyJhbGciOiJIUzI1NiJ9.eyJlaWQiOiI0ZGM3MGFiNS1jZDczLTQ5MmYtYjAwNy0zMTc5ZDJkOTI5NmIiLCJzZyI6W10sImV4cCI6MTUyNjMxODMyMn0.ASmvcbJFBfzhN7D5ncloWnaVZr5dLtgTuOgHaCKiimc',
expires: 1526318322000
},
} as AuthStatus,
statusCode: 200,
statusText: '200'
};
const validResponse2 = { validResponse1 = {
payload: { payload: {},
authenticated: true, statusCode: 404,
id: null, statusText: '404'
okay: true, };
type: 'status',
_embedded: { validResponse2 = {
eperson: { payload: {
canLogIn: true, authenticated: true,
email: 'myself@testshib.org', id: null,
groups: [], okay: true,
handle: null, type: 'status',
id: '4dc70ab5-cd73-492f-b007-3179d2d9296b', _embedded: {
lastActive: '2018-05-14T17:03:31.277+0000', eperson: {
metadata: { canLogIn: true,
'eperson.firstname': [ email: 'myself@testshib.org',
{ groups: [],
language: null, handle: null,
value: 'User' 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: { statusCode: 200,
eperson: { statusText: '200'
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'
}; };
});
it('should return a AuthStatusResponse if data contains a valid AuthStatus object as payload', () => { it('should return a AuthStatusResponse if data contains a valid AuthStatus object as payload', () => {
const response = service.parse(validRequest, validResponse); const response = service.parse(validRequest, validResponse);

View File

@@ -1,6 +1,5 @@
import { Inject, Injectable } from '@angular/core'; import { Inject, Injectable } from '@angular/core';
import { AuthObjectFactory } from './auth-object-factory';
import { BaseResponseParsingService } from '../data/base-response-parsing.service'; import { BaseResponseParsingService } from '../data/base-response-parsing.service';
import { AuthStatusResponse, RestResponse } from '../cache/response.models'; import { AuthStatusResponse, RestResponse } from '../cache/response.models';
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model'; 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 { ObjectCacheService } from '../cache/object-cache.service';
import { ResponseParsingService } from '../data/parsing.service'; import { ResponseParsingService } from '../data/parsing.service';
import { RestRequest } from '../data/request.models'; import { RestRequest } from '../data/request.models';
import { AuthType } from './auth-type';
import { AuthStatus } from './models/auth-status.model'; import { AuthStatus } from './models/auth-status.model';
import { NormalizedAuthStatus } from './models/normalized-auth-status.model'; import { NormalizedAuthStatus } from './models/normalized-auth-status.model';
import { NormalizedObject } from '../cache/models/normalized-object.model'; import { NormalizedObject } from '../cache/models/normalized-object.model';
@@ -18,7 +16,6 @@ import { NormalizedObject } from '../cache/models/normalized-object.model';
@Injectable() @Injectable()
export class AuthResponseParsingService extends BaseResponseParsingService implements ResponseParsingService { export class AuthResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {
protected objectFactory = AuthObjectFactory;
protected toCache = true; protected toCache = true;
constructor(@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig, constructor(@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
@@ -28,7 +25,7 @@ export class AuthResponseParsingService extends BaseResponseParsingService imple
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse { parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
if (isNotEmpty(data.payload) && isNotEmpty(data.payload._links) && (data.statusCode === 200)) { 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); return new AuthStatusResponse(response, data.statusCode, data.statusText);
} else { } else {
return new AuthStatusResponse(data.payload as NormalizedAuthStatus, data.statusCode, data.statusText); return new AuthStatusResponse(data.payload as NormalizedAuthStatus, data.statusCode, data.statusText);

View File

@@ -1,5 +0,0 @@
export enum AuthType {
EPerson = 'eperson',
Status = 'status',
Group = 'group'
}

View File

@@ -4,20 +4,51 @@ import { EPerson } from '../../eperson/models/eperson.model';
import { RemoteData } from '../../data/remote-data'; import { RemoteData } from '../../data/remote-data';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { CacheableObject } from '../../cache/object-cache.reducer'; 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 { export class AuthStatus implements CacheableObject {
static type = new ResourceType('status');
/**
* The unique identifier of this auth status
*/
id: string; 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; okay: boolean;
/**
* If the auth status represents an authenticated state
*/
authenticated: boolean; authenticated: boolean;
/**
* Authentication error if there was one for this status
*/
error?: AuthError; error?: AuthError;
/**
* The eperson of this auth status
*/
eperson: Observable<RemoteData<EPerson>>; eperson: Observable<RemoteData<EPerson>>;
/**
* True if the token is valid, false if there was no token or the token wasn't valid
*/
token?: AuthTokenInfo; token?: AuthTokenInfo;
/**
* The self link of this auth status' REST object
*/
self: string; self: string;
} }

View File

@@ -1,16 +1,22 @@
import { AuthStatus } from './auth-status.model'; import { AuthStatus } from './auth-status.model';
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize'; import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize';
import { mapsTo, relationship } from '../../cache/builders/build-decorators'; import { mapsTo, relationship } from '../../cache/builders/build-decorators';
import { ResourceType } from '../../shared/resource-type';
import { NormalizedObject } from '../../cache/models/normalized-object.model'; import { NormalizedObject } from '../../cache/models/normalized-object.model';
import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer'; import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer';
import { EPerson } from '../../eperson/models/eperson.model';
@mapsTo(AuthStatus) @mapsTo(AuthStatus)
@inheritSerialization(NormalizedObject) @inheritSerialization(NormalizedObject)
export class NormalizedAuthStatus extends NormalizedObject<AuthStatus> { export class NormalizedAuthStatus extends NormalizedObject<AuthStatus> {
/**
* The unique identifier of this auth status
*/
@autoserialize @autoserialize
id: string; id: string;
/**
* The unique generated uuid of this auth status
*/
@autoserializeAs(new IDToUUIDSerializer('auth-status'), 'id') @autoserializeAs(new IDToUUIDSerializer('auth-status'), 'id')
uuid: string; uuid: string;
@@ -26,7 +32,10 @@ export class NormalizedAuthStatus extends NormalizedObject<AuthStatus> {
@autoserialize @autoserialize
authenticated: boolean; authenticated: boolean;
@relationship(ResourceType.EPerson, false) /**
* The self link to the eperson of this auth status
*/
@relationship(EPerson, false)
@autoserialize @autoserialize
eperson: string; eperson: string;
} }

View File

@@ -1,8 +1,9 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, of as observableOf } from 'rxjs'; import { Observable, of as observableOf } from 'rxjs';
import { distinctUntilChanged, map, startWith, take } from 'rxjs/operators'; import { distinctUntilChanged, map, startWith } from 'rxjs/operators';
import { import {
ensureArrayHasValue, hasValue, ensureArrayHasValue,
hasValue,
hasValueOperator, hasValueOperator,
isEmpty, isEmpty,
isNotEmpty, isNotEmpty,
@@ -23,7 +24,9 @@ import { BrowseEntry } from '../shared/browse-entry.model';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { import {
configureRequest, configureRequest,
filterSuccessfulResponses, getBrowseDefinitionLinks, getFirstOccurrence, filterSuccessfulResponses,
getBrowseDefinitionLinks,
getFirstOccurrence,
getRemoteDataPayload, getRemoteDataPayload,
getRequestFromRequestHref getRequestFromRequestHref
} from '../shared/operators'; } from '../shared/operators';
@@ -32,7 +35,6 @@ import { Item } from '../shared/item.model';
import { DSpaceObject } from '../shared/dspace-object.model'; import { DSpaceObject } from '../shared/dspace-object.model';
import { BrowseEntrySearchOptions } from './browse-entry-search-options.model'; import { BrowseEntrySearchOptions } from './browse-entry-search-options.model';
import { GenericSuccessResponse } from '../cache/response.models'; import { GenericSuccessResponse } from '../cache/response.models';
import { RequestEntry } from '../data/request.reducer';
/** /**
* The service handling all browse requests * The service handling all browse requests

View File

@@ -1,23 +1,59 @@
import 'reflect-metadata'; import 'reflect-metadata';
import { GenericConstructor } from '../../shared/generic-constructor'; 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'; import { ResourceType } from '../../shared/resource-type';
const mapsToMetadataKey = Symbol('mapsTo'); const mapsToMetadataKey = Symbol('mapsTo');
const relationshipKey = Symbol('relationship'); const relationshipKey = Symbol('relationship');
const relationshipMap = new Map(); 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) { export function getMapsTo(target: any) {
return Reflect.getOwnMetadata(mapsToMetadataKey, target); 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) { return function r(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
if (!target || !propertyKey) { if (!target || !propertyKey) {
return; return;
@@ -28,8 +64,10 @@ export function relationship(value: ResourceType, isList: boolean = false): any
metaDataList.push(propertyKey); metaDataList.push(propertyKey);
} }
relationshipMap.set(target.constructor, metaDataList); relationshipMap.set(target.constructor, metaDataList);
return Reflect.metadata(relationshipKey, {
return Reflect.metadata(relationshipKey, { resourceType: value, isList }).apply(this, arguments); resourceType: (value as any).type.value,
isList
}).apply(this, arguments);
}; };
} }

View File

@@ -1,9 +1,8 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { NormalizedObject } from '../models/normalized-object.model'; import { NormalizedObject } from '../models/normalized-object.model';
import { CacheableObject } from '../object-cache.reducer'; import { getMapsToType, getRelationships } from './build-decorators';
import { getRelationships } from './build-decorators';
import { NormalizedObjectFactory } from '../models/normalized-object-factory';
import { hasValue, isNotEmpty } from '../../../shared/empty.util'; import { hasValue, isNotEmpty } from '../../../shared/empty.util';
import { TypedObject } from '../object-cache.reducer';
/** /**
* Return true if halObj has a value for `_links.self` * Return true if halObj has a value for `_links.self`
@@ -35,8 +34,8 @@ export class NormalizedObjectBuildService {
* *
* @param {TDomain} domainModel a domain model * @param {TDomain} domainModel a domain model
*/ */
normalize<T extends CacheableObject>(domainModel: T): NormalizedObject<T> { normalize<T extends TypedObject>(domainModel: T): NormalizedObject<T> {
const normalizedConstructor = NormalizedObjectFactory.getConstructor(domainModel.type); const normalizedConstructor = getMapsToType((domainModel as any).type);
const relationships = getRelationships(normalizedConstructor) || []; const relationships = getRelationships(normalizedConstructor) || [];
const normalizedModel = Object.assign({}, domainModel) as any; const normalizedModel = Object.assign({}, domainModel) as any;

View File

@@ -4,6 +4,7 @@ import { PaginatedList } from '../../data/paginated-list';
import { PageInfo } from '../../shared/page-info.model'; import { PageInfo } from '../../shared/page-info.model';
import { RemoteData } from '../../data/remote-data'; import { RemoteData } from '../../data/remote-data';
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { createSuccessfulRemoteDataObject } from '../../../shared/testing/utils';
const pageInfo = new PageInfo(); const pageInfo = new PageInfo();
const array = [ const array = [
@@ -29,8 +30,8 @@ const array = [
}) })
]; ];
const paginatedList = new PaginatedList(pageInfo, array); const paginatedList = new PaginatedList(pageInfo, array);
const arrayRD = new RemoteData(false, false, true, undefined, array); const arrayRD = createSuccessfulRemoteDataObject(array);
const paginatedListRD = new RemoteData(false, false, true, undefined, paginatedList); const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList);
describe('RemoteDataBuildService', () => { describe('RemoteDataBuildService', () => {
let service: RemoteDataBuildService; let service: RemoteDataBuildService;

View File

@@ -21,7 +21,8 @@ import {
getRequestFromRequestUUID, getRequestFromRequestUUID,
getResourceLinksFromResponse getResourceLinksFromResponse
} from '../../shared/operators'; } from '../../shared/operators';
import { CacheableObject } from '../object-cache.reducer'; import { CacheableObject, TypedObject } from '../object-cache.reducer';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/testing/utils';
@Injectable() @Injectable()
export class RemoteDataBuildService { export class RemoteDataBuildService {
@@ -200,7 +201,7 @@ export class RemoteDataBuildService {
aggregate<T>(input: Array<Observable<RemoteData<T>>>): Observable<RemoteData<T[]>> { aggregate<T>(input: Array<Observable<RemoteData<T>>>): Observable<RemoteData<T[]>> {
if (isEmpty(input)) { if (isEmpty(input)) {
return observableOf(new RemoteData(false, false, true, null, [])); return createSuccessfulRemoteDataObject$([]);
} }
return observableCombineLatest(...input).pipe( return observableCombineLatest(...input).pipe(

View File

@@ -1,6 +1,5 @@
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize'; import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize';
import { ItemType } from '../../../shared/item-relationships/item-type.model'; import { ItemType } from '../../../shared/item-relationships/item-type.model';
import { ResourceType } from '../../../shared/resource-type';
import { mapsTo } from '../../builders/build-decorators'; import { mapsTo } from '../../builders/build-decorators';
import { NormalizedObject } from '../normalized-object.model'; import { NormalizedObject } from '../normalized-object.model';
import { IDToUUIDSerializer } from '../../id-to-uuid-serializer'; import { IDToUUIDSerializer } from '../../id-to-uuid-serializer';
@@ -11,7 +10,6 @@ import { IDToUUIDSerializer } from '../../id-to-uuid-serializer';
@mapsTo(ItemType) @mapsTo(ItemType)
@inheritSerialization(NormalizedObject) @inheritSerialization(NormalizedObject)
export class NormalizedItemType extends NormalizedObject<ItemType> { export class NormalizedItemType extends NormalizedObject<ItemType> {
/** /**
* The label that describes the ResourceType of the Item * 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 * The universally unique identifier of this ItemType
*/ */
@autoserializeAs(new IDToUUIDSerializer(ResourceType.ItemType), 'id') @autoserializeAs(new IDToUUIDSerializer(ItemType.type.value), 'id')
uuid: string; uuid: string;
} }

View File

@@ -5,6 +5,7 @@ import { mapsTo, relationship } from '../../builders/build-decorators';
import { NormalizedDSpaceObject } from '../normalized-dspace-object.model'; import { NormalizedDSpaceObject } from '../normalized-dspace-object.model';
import { NormalizedObject } from '../normalized-object.model'; import { NormalizedObject } from '../normalized-object.model';
import { IDToUUIDSerializer } from '../../id-to-uuid-serializer'; import { IDToUUIDSerializer } from '../../id-to-uuid-serializer';
import { ItemType } from '../../../shared/item-relationships/item-type.model';
/** /**
* Normalized model class for a DSpace RelationshipType * Normalized model class for a DSpace RelationshipType
@@ -12,7 +13,6 @@ import { IDToUUIDSerializer } from '../../id-to-uuid-serializer';
@mapsTo(RelationshipType) @mapsTo(RelationshipType)
@inheritSerialization(NormalizedDSpaceObject) @inheritSerialization(NormalizedDSpaceObject)
export class NormalizedRelationshipType extends NormalizedObject<RelationshipType> { export class NormalizedRelationshipType extends NormalizedObject<RelationshipType> {
/** /**
* The identifier of this 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 * The type of Item found to the left of this RelationshipType
*/ */
@autoserialize @autoserialize
@relationship(ResourceType.ItemType, false) @relationship(ItemType, false)
leftType: string; leftType: string;
/** /**
* The type of Item found to the right of this RelationshipType * The type of Item found to the right of this RelationshipType
*/ */
@autoserialize @autoserialize
@relationship(ResourceType.ItemType, false) @relationship(ItemType, false)
rightType: string; rightType: string;
/** /**
* The universally unique identifier of this RelationshipType * The universally unique identifier of this RelationshipType
*/ */
@autoserializeAs(new IDToUUIDSerializer(ResourceType.RelationshipType), 'id') @autoserializeAs(new IDToUUIDSerializer(RelationshipType.type.value), 'id')
uuid: string; uuid: string;
} }

View File

@@ -1,9 +1,10 @@
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize'; import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize';
import { Relationship } from '../../../shared/item-relationships/relationship.model'; import { Relationship } from '../../../shared/item-relationships/relationship.model';
import { ResourceType } from '../../../shared/resource-type';
import { mapsTo, relationship } from '../../builders/build-decorators'; import { mapsTo, relationship } from '../../builders/build-decorators';
import { NormalizedObject } from '../normalized-object.model'; import { NormalizedObject } from '../normalized-object.model';
import { IDToUUIDSerializer } from '../../id-to-uuid-serializer'; 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 * 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 * The item to the left of this relationship
*/ */
@autoserialize @autoserialize
@relationship(ResourceType.Item, false) @relationship(Item, false)
leftItem: string; leftItem: string;
/** /**
* The item to the right of this relationship * The item to the right of this relationship
*/ */
@autoserialize @autoserialize
@relationship(ResourceType.Item, false) @relationship(Item, false)
rightItem: string; rightItem: string;
/** /**
@@ -48,12 +49,12 @@ export class NormalizedRelationship extends NormalizedObject<Relationship> {
* The type of Relationship * The type of Relationship
*/ */
@autoserialize @autoserialize
@relationship(ResourceType.RelationshipType, false) @relationship(RelationshipType, false)
relationshipType: string; relationshipType: string;
/** /**
* The universally unique identifier of this Relationship * The universally unique identifier of this Relationship
*/ */
@autoserializeAs(new IDToUUIDSerializer(ResourceType.Relationship), 'id') @autoserializeAs(new IDToUUIDSerializer(Relationship.type.value), 'id')
uuid: string; uuid: string;
} }

View File

@@ -12,7 +12,6 @@ import { SupportLevel } from './support-level.model';
@mapsTo(BitstreamFormat) @mapsTo(BitstreamFormat)
@inheritSerialization(NormalizedObject) @inheritSerialization(NormalizedObject)
export class NormalizedBitstreamFormat extends NormalizedObject<BitstreamFormat> { export class NormalizedBitstreamFormat extends NormalizedObject<BitstreamFormat> {
/** /**
* Short description of this Bitstream Format * Short description of this Bitstream Format
*/ */

View File

@@ -1,9 +1,10 @@
import { inheritSerialization, autoserialize } from 'cerialize'; import { autoserialize, inheritSerialization } from 'cerialize';
import { NormalizedDSpaceObject } from './normalized-dspace-object.model'; import { NormalizedDSpaceObject } from './normalized-dspace-object.model';
import { Bitstream } from '../../shared/bitstream.model'; import { Bitstream } from '../../shared/bitstream.model';
import { mapsTo, relationship } from '../builders/build-decorators'; 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 * Normalized model class for a DSpace Bitstream
@@ -11,7 +12,6 @@ import { ResourceType } from '../../shared/resource-type';
@mapsTo(Bitstream) @mapsTo(Bitstream)
@inheritSerialization(NormalizedDSpaceObject) @inheritSerialization(NormalizedDSpaceObject)
export class NormalizedBitstream extends NormalizedDSpaceObject<Bitstream> { export class NormalizedBitstream extends NormalizedDSpaceObject<Bitstream> {
/** /**
* The size of this bitstream in bytes * The size of this bitstream in bytes
*/ */
@@ -28,7 +28,7 @@ export class NormalizedBitstream extends NormalizedDSpaceObject<Bitstream> {
* The format of this Bitstream * The format of this Bitstream
*/ */
@autoserialize @autoserialize
@relationship(ResourceType.BitstreamFormat, false) @relationship(BitstreamFormat, false)
format: string; format: string;
/** /**
@@ -41,14 +41,14 @@ export class NormalizedBitstream extends NormalizedDSpaceObject<Bitstream> {
* An array of Bundles that are direct parents of this Bitstream * An array of Bundles that are direct parents of this Bitstream
*/ */
@autoserialize @autoserialize
@relationship(ResourceType.Item, true) @relationship(Item, true)
parents: string[]; parents: string[];
/** /**
* The Bundle that owns this Bitstream * The Bundle that owns this Bitstream
*/ */
@autoserialize @autoserialize
@relationship(ResourceType.Item, false) @relationship(Item, false)
owner: string; owner: string;
/** /**

View File

@@ -3,7 +3,7 @@ import { autoserialize, inheritSerialization } from 'cerialize';
import { NormalizedDSpaceObject } from './normalized-dspace-object.model'; import { NormalizedDSpaceObject } from './normalized-dspace-object.model';
import { Bundle } from '../../shared/bundle.model'; import { Bundle } from '../../shared/bundle.model';
import { mapsTo, relationship } from '../builders/build-decorators'; 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 * Normalized model class for a DSpace Bundle
@@ -15,7 +15,7 @@ export class NormalizedBundle extends NormalizedDSpaceObject<Bundle> {
* The primary bitstream of this Bundle * The primary bitstream of this Bundle
*/ */
@autoserialize @autoserialize
@relationship(ResourceType.Bitstream, false) @relationship(Bitstream, false)
primaryBitstream: string; primaryBitstream: string;
/** /**
@@ -32,7 +32,7 @@ export class NormalizedBundle extends NormalizedDSpaceObject<Bundle> {
* List of Bitstreams that are part of this Bundle * List of Bitstreams that are part of this Bundle
*/ */
@autoserialize @autoserialize
@relationship(ResourceType.Bitstream, true) @relationship(Bitstream, true)
bitstreams: string[]; bitstreams: string[];
} }

View File

@@ -3,7 +3,15 @@ import { autoserialize, deserialize, inheritSerialization } from 'cerialize';
import { NormalizedDSpaceObject } from './normalized-dspace-object.model'; import { NormalizedDSpaceObject } from './normalized-dspace-object.model';
import { Collection } from '../../shared/collection.model'; import { Collection } from '../../shared/collection.model';
import { mapsTo, relationship } from '../builders/build-decorators'; 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 * 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 * The Bitstream that represents the license of this Collection
*/ */
@autoserialize @autoserialize
@relationship(ResourceType.License, false) @relationship(License, false)
license: string; license: string;
/** /**
* The Bitstream that represents the default Access Conditions of this Collection * The Bitstream that represents the default Access Conditions of this Collection
*/ */
@autoserialize @autoserialize
@relationship(ResourceType.ResourcePolicy, false) @relationship(ResourcePolicy, false)
defaultAccessConditions: string; defaultAccessConditions: string;
/** /**
* The Bitstream that represents the logo of this Collection * The Bitstream that represents the logo of this Collection
*/ */
@deserialize @deserialize
@relationship(ResourceType.Bitstream, false) @relationship(Bitstream, false)
logo: string; logo: string;
/** /**
* An array of Communities that are direct parents of this Collection * An array of Communities that are direct parents of this Collection
*/ */
@deserialize @deserialize
@relationship(ResourceType.Community, true) @relationship(Community, true)
parents: string[]; parents: string[];
/** /**
* The Community that owns this Collection * The Community that owns this Collection
*/ */
@deserialize @deserialize
@relationship(ResourceType.Community, false) @relationship(Community, false)
owner: string; owner: string;
/** /**
* List of Items that are part of (not necessarily owned by) this Collection * List of Items that are part of (not necessarily owned by) this Collection
*/ */
@deserialize @deserialize
@relationship(ResourceType.Item, true) @relationship(Item, true)
items: string[]; items: string[];
} }

View File

@@ -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 { NormalizedDSpaceObject } from './normalized-dspace-object.model';
import { Community } from '../../shared/community.model'; import { Community } from '../../shared/community.model';
import { mapsTo, relationship } from '../builders/build-decorators'; import { mapsTo, relationship } from '../builders/build-decorators';
import { ResourceType } from '../../shared/resource-type'; 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 * Normalized model class for a DSpace Community
@@ -11,7 +15,6 @@ import { ResourceType } from '../../shared/resource-type';
@mapsTo(Community) @mapsTo(Community)
@inheritSerialization(NormalizedDSpaceObject) @inheritSerialization(NormalizedDSpaceObject)
export class NormalizedCommunity extends NormalizedDSpaceObject<Community> { export class NormalizedCommunity extends NormalizedDSpaceObject<Community> {
/** /**
* A string representing the unique handle of this 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 * The Bitstream that represents the logo of this Community
*/ */
@deserialize @deserialize
@relationship(ResourceType.Bitstream, false) @relationship(Bitstream, false)
logo: string; logo: string;
/** /**
* An array of Communities that are direct parents of this Community * An array of Communities that are direct parents of this Community
*/ */
@deserialize @deserialize
@relationship(ResourceType.Community, true) @relationship(Community, true)
parents: string[]; parents: string[];
/** /**
* The Community that owns this Community * The Community that owns this Community
*/ */
@deserialize @deserialize
@relationship(ResourceType.Community, false) @relationship(Community, false)
owner: string; owner: string;
/** /**
* List of Collections that are owned by this Community * List of Collections that are owned by this Community
*/ */
@deserialize @deserialize
@relationship(ResourceType.Collection, true) @relationship(Collection, true)
collections: string[]; collections: string[];
@deserialize @deserialize
@relationship(ResourceType.Community, true) @relationship(Community, true)
subcommunities: string[]; subcommunities: string[];
} }

View File

@@ -1,15 +1,15 @@
import { autoserializeAs, deserializeAs } from 'cerialize'; import { autoserializeAs, deserializeAs, autoserialize } from 'cerialize';
import { DSpaceObject } from '../../shared/dspace-object.model'; import { DSpaceObject } from '../../shared/dspace-object.model';
import { MetadataMap, MetadataMapSerializer } from '../../shared/metadata.models'; import { MetadataMap, MetadataMapSerializer } from '../../shared/metadata.models';
import { ResourceType } from '../../shared/resource-type';
import { mapsTo } from '../builders/build-decorators'; import { mapsTo } from '../builders/build-decorators';
import { NormalizedObject } from './normalized-object.model'; import { NormalizedObject } from './normalized-object.model';
import { TypedObject } from '../object-cache.reducer';
/** /**
* An model class for a DSpaceObject. * An model class for a DSpaceObject.
*/ */
@mapsTo(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 * 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, … * A string representing the kind of DSpaceObject, e.g. community, item, …
*/ */
@autoserializeAs(String) @autoserialize
type: ResourceType; type: string;
/** /**
* All metadata of this DSpaceObject * All metadata of this DSpaceObject

View File

@@ -4,6 +4,12 @@ import { NormalizedDSpaceObject } from './normalized-dspace-object.model';
import { Item } from '../../shared/item.model'; import { Item } from '../../shared/item.model';
import { mapsTo, relationship } from '../builders/build-decorators'; import { mapsTo, relationship } from '../builders/build-decorators';
import { ResourceType } from '../../shared/resource-type'; 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 * 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 * An array of Collections that are direct parents of this Item
*/ */
@deserialize @deserialize
@relationship(ResourceType.Collection, true) @relationship(Collection, true)
parents: string[]; parents: string[];
/** /**
* The Collection that owns this Item * The Collection that owns this Item
*/ */
@deserialize @deserialize
@relationship(ResourceType.Collection, false) @relationship(Collection, false)
owningCollection: string; owningCollection: string;
/** /**
* List of Bitstreams that are owned by this Item * List of Bitstreams that are owned by this Item
*/ */
@deserialize @deserialize
@relationship(ResourceType.Bitstream, true) @relationship(Bitstream, true)
bitstreams: string[]; bitstreams: string[];
@autoserialize @autoserialize
@relationship(ResourceType.Relationship, true) @relationship(Relationship, true)
relationships: string[]; relationships: string[];
} }

View File

@@ -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;
}
}
}
}

View File

@@ -1,25 +1,24 @@
import { CacheableObject } from '../object-cache.reducer'; import { CacheableObject, TypedObject } from '../object-cache.reducer';
import { autoserialize } from 'cerialize'; import { autoserialize } from 'cerialize';
import { ResourceType } from '../../shared/resource-type'; import { ResourceType } from '../../shared/resource-type';
/** /**
* An abstract model class for a NormalizedObject. * 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 * The link to the rest endpoint where this object can be found
*/ */
@autoserialize @autoserialize
self: string; self: string;
/**
* A string representing the kind of DSpaceObject, e.g. community, item, …
*/
@autoserialize
type: ResourceType;
@autoserialize @autoserialize
_links: { _links: {
[name: string]: string [name: string]: string
} };
/**
* A string representing the kind of object
*/
@autoserialize
type: string;
} }

View File

@@ -12,7 +12,6 @@ import { ActionType } from './action-type.model';
@mapsTo(ResourcePolicy) @mapsTo(ResourcePolicy)
@inheritSerialization(NormalizedObject) @inheritSerialization(NormalizedObject)
export class NormalizedResourcePolicy extends NormalizedObject<ResourcePolicy> { export class NormalizedResourcePolicy extends NormalizedObject<ResourcePolicy> {
/** /**
* The action that is allowed by this Resource Policy * The action that is allowed by this Resource Policy
*/ */

View File

@@ -8,7 +8,7 @@ export enum SupportLevel {
Unknown = 0, 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, Known = 1,

View File

@@ -9,6 +9,7 @@ import {
ResetObjectCacheTimestampsAction ResetObjectCacheTimestampsAction
} from './object-cache.actions'; } from './object-cache.actions';
import { Operation } from 'fast-json-patch'; import { Operation } from 'fast-json-patch';
import { Item } from '../shared/item.model';
class NullAction extends RemoveFromObjectCacheAction { class NullAction extends RemoveFromObjectCacheAction {
type = null; type = null;
@@ -28,6 +29,7 @@ describe('objectCacheReducer', () => {
const testState = { const testState = {
[selfLink1]: { [selfLink1]: {
data: { data: {
type: Item.type,
self: selfLink1, self: selfLink1,
foo: 'bar' foo: 'bar'
}, },
@@ -39,6 +41,7 @@ describe('objectCacheReducer', () => {
}, },
[selfLink2]: { [selfLink2]: {
data: { data: {
type: Item.type,
self: requestUUID2, self: requestUUID2,
foo: 'baz' foo: 'baz'
}, },
@@ -67,7 +70,7 @@ describe('objectCacheReducer', () => {
it('should add the payload to the cache in response to an ADD action', () => { it('should add the payload to the cache in response to an ADD action', () => {
const state = Object.create(null); const state = Object.create(null);
const objectToCache = { self: selfLink1 }; const objectToCache = { self: selfLink1, type: Item.type };
const timeAdded = new Date().getTime(); const timeAdded = new Date().getTime();
const msToLive = 900000; const msToLive = 900000;
const requestUUID = requestUUID1; 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', () => { 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 timeAdded = new Date().getTime();
const msToLive = 900000; const msToLive = 900000;
const requestUUID = requestUUID1; const requestUUID = requestUUID1;
@@ -95,7 +103,7 @@ describe('objectCacheReducer', () => {
it('should perform the ADD action without affecting the previous state', () => { it('should perform the ADD action without affecting the previous state', () => {
const state = Object.create(null); const state = Object.create(null);
const objectToCache = { self: selfLink1 }; const objectToCache = { self: selfLink1, type: Item.type };
const timeAdded = new Date().getTime(); const timeAdded = new Date().getTime();
const msToLive = 900000; const msToLive = 900000;
const requestUUID = requestUUID1; const requestUUID = requestUUID1;

View File

@@ -32,15 +32,19 @@ export interface Patch {
operations: Operation[]; operations: Operation[];
} }
export abstract class TypedObject {
static type: ResourceType;
}
/* tslint:disable:max-classes-per-file */
/** /**
* An interface to represent objects that can be cached * An interface to represent objects that can be cached
* *
* A cacheable object should have a self link * A cacheable object should have a self link
*/ */
export interface CacheableObject { export class CacheableObject extends TypedObject {
uuid?: string; uuid?: string;
self: string; self: string;
type?: ResourceType;
// isNew: boolean; // isNew: boolean;
// dirtyType: DirtyType; // dirtyType: DirtyType;
// hasDirtyAttributes: boolean; // hasDirtyAttributes: boolean;
@@ -59,6 +63,7 @@ export class ObjectCacheEntry implements CacheEntry {
patches: Patch[] = []; patches: Patch[] = [];
isDirty: boolean; isDirty: boolean;
} }
/* tslint:enable:max-classes-per-file */
/** /**
* The ObjectCache State * The ObjectCache State

View File

@@ -10,13 +10,13 @@ import {
RemoveFromObjectCacheAction RemoveFromObjectCacheAction
} from './object-cache.actions'; } from './object-cache.actions';
import { CoreState } from '../core.reducers'; import { CoreState } from '../core.reducers';
import { ResourceType } from '../shared/resource-type';
import { NormalizedItem } from './models/normalized-item.model'; import { NormalizedItem } from './models/normalized-item.model';
import { first } from 'rxjs/operators'; import { first } from 'rxjs/operators';
import { Operation } from 'fast-json-patch'; import { Operation } from 'fast-json-patch';
import { RestRequestMethod } from '../data/rest-request-method'; import { RestRequestMethod } from '../data/rest-request-method';
import { AddToSSBAction } from './server-sync-buffer.actions'; import { AddToSSBAction } from './server-sync-buffer.actions';
import { Patch } from './object-cache.reducer'; import { Patch } from './object-cache.reducer';
import { Item } from '../shared/item.model';
describe('ObjectCacheService', () => { describe('ObjectCacheService', () => {
let service: ObjectCacheService; let service: ObjectCacheService;
@@ -28,7 +28,7 @@ describe('ObjectCacheService', () => {
const msToLive = 900000; const msToLive = 900000;
let objectToCache = { let objectToCache = {
self: selfLink, self: selfLink,
type: ResourceType.Item type: Item.type
}; };
let cacheEntry; let cacheEntry;
let invalidCacheEntry; let invalidCacheEntry;
@@ -37,7 +37,7 @@ describe('ObjectCacheService', () => {
function init() { function init() {
objectToCache = { objectToCache = {
self: selfLink, self: selfLink,
type: ResourceType.Item type: Item.type
}; };
cacheEntry = { cacheEntry = {
data: objectToCache, data: objectToCache,

View File

@@ -10,7 +10,6 @@ import { coreSelector } from '../core.selectors';
import { RestRequestMethod } from '../data/rest-request-method'; import { RestRequestMethod } from '../data/rest-request-method';
import { selfLinkFromUuidSelector } from '../index/index.selectors'; import { selfLinkFromUuidSelector } from '../index/index.selectors';
import { GenericConstructor } from '../shared/generic-constructor'; import { GenericConstructor } from '../shared/generic-constructor';
import { NormalizedObjectFactory } from './models/normalized-object-factory';
import { NormalizedObject } from './models/normalized-object.model'; import { NormalizedObject } from './models/normalized-object.model';
import { import {
AddPatchObjectCacheAction, AddPatchObjectCacheAction,
@@ -21,6 +20,7 @@ import {
import { CacheableObject, ObjectCacheEntry, ObjectCacheState } from './object-cache.reducer'; import { CacheableObject, ObjectCacheEntry, ObjectCacheState } from './object-cache.reducer';
import { AddToSSBAction } from './server-sync-buffer.actions'; 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 * The base selector function to select the object cache in the store
@@ -109,7 +109,7 @@ export class ObjectCacheService {
} }
), ),
map((entry: ObjectCacheEntry) => { 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> return Object.assign(new type(), entry.data) as NormalizedObject<T>
}) })
); );

View File

@@ -8,12 +8,12 @@ import { IntegrationModel } from '../integration/models/integration.model';
import { RegistryMetadataschemasResponse } from '../registry/registry-metadataschemas-response.model'; import { RegistryMetadataschemasResponse } from '../registry/registry-metadataschemas-response.model';
import { RegistryMetadatafieldsResponse } from '../registry/registry-metadatafields-response.model'; import { RegistryMetadatafieldsResponse } from '../registry/registry-metadatafields-response.model';
import { RegistryBitstreamformatsResponse } from '../registry/registry-bitstreamformats-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 { PaginatedList } from '../data/paginated-list';
import { SubmissionObject } from '../submission/models/submission-object.model'; import { SubmissionObject } from '../submission/models/submission-object.model';
import { DSpaceObject } from '../shared/dspace-object.model'; import { DSpaceObject } from '../shared/dspace-object.model';
import { NormalizedAuthStatus } from '../auth/models/normalized-auth-status.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 */ /* tslint:disable:max-classes-per-file */
export class RestResponse { export class RestResponse {

View File

@@ -8,8 +8,8 @@ import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers'; import { CoreState } from '../core.reducers';
import { PaginatedList } from '../data/paginated-list'; import { PaginatedList } from '../data/paginated-list';
import { PageInfo } from '../shared/page-info.model'; 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 { NormalizedSubmissionSectionModel } from './models/normalized-config-submission-section.model';
import { NormalizedSubmissionDefinitionModel } from './models/normalized-config-submission-definition.model';
describe('ConfigResponseParsingService', () => { describe('ConfigResponseParsingService', () => {
let service: ConfigResponseParsingService; let service: ConfigResponseParsingService;
@@ -173,7 +173,7 @@ describe('ConfigResponseParsingService', () => {
self: 'https://rest.api/config/submissiondefinitions/traditional/sections' self: 'https://rest.api/config/submissiondefinitions/traditional/sections'
}); });
const definitions = const definitions =
Object.assign(new NormalizedSubmissionDefinitionsModel(), { Object.assign(new NormalizedSubmissionDefinitionModel(), {
isDefault: true, isDefault: true,
name: 'traditional', name: 'traditional',
type: 'submissiondefinition', type: 'submissiondefinition',

View File

@@ -5,10 +5,8 @@ import { RestRequest } from '../data/request.models';
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model'; import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
import { ConfigSuccessResponse, ErrorResponse, RestResponse } from '../cache/response.models'; import { ConfigSuccessResponse, ErrorResponse, RestResponse } from '../cache/response.models';
import { isNotEmpty } from '../../shared/empty.util'; import { isNotEmpty } from '../../shared/empty.util';
import { ConfigObjectFactory } from './models/config-object-factory';
import { ConfigObject } from './models/config.model'; import { ConfigObject } from './models/config.model';
import { ConfigType } from './models/config-type';
import { BaseResponseParsingService } from '../data/base-response-parsing.service'; import { BaseResponseParsingService } from '../data/base-response-parsing.service';
import { GLOBAL_CONFIG } from '../../../config'; import { GLOBAL_CONFIG } from '../../../config';
import { GlobalConfig } from '../../../config/global-config.interface'; import { GlobalConfig } from '../../../config/global-config.interface';
@@ -16,8 +14,6 @@ import { ObjectCacheService } from '../cache/object-cache.service';
@Injectable() @Injectable()
export class ConfigResponseParsingService extends BaseResponseParsingService implements ResponseParsingService { export class ConfigResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {
protected objectFactory = ConfigObjectFactory;
protected toCache = false; protected toCache = false;
constructor( constructor(
@@ -28,7 +24,7 @@ export class ConfigResponseParsingService extends BaseResponseParsingService imp
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse { parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
if (isNotEmpty(data.payload) && isNotEmpty(data.payload._links) && (data.statusCode === 201 || data.statusCode === 200)) { 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)); return new ConfigSuccessResponse(configDefinition, data.statusCode, data.statusText, this.processPageInfo(data.payload));
} else { } else {
return new ErrorResponse( return new ErrorResponse(

View File

@@ -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;
}
}
}
}

View File

@@ -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>;
}

View File

@@ -1,17 +1,7 @@
import { ConfigObject } from './config.model'; import { SubmissionDefinitionModel } from './config-submission-definition.model';
import { SubmissionSectionModel } from './config-submission-section.model'; import { ResourceType } from '../../shared/resource-type';
import { PaginatedList } from '../../data/paginated-list';
export class SubmissionDefinitionsModel extends ConfigObject { export class SubmissionDefinitionsModel extends SubmissionDefinitionModel {
static type = new ResourceType('submissiondefinitions');
/**
* 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>;
} }

View 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[];
}

View File

@@ -1,20 +1,9 @@
import { ConfigObject } from './config.model'; import { SubmissionFormModel } from './config-submission-form.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. * A model class for a NormalizedObject.
*/ */
export class SubmissionFormsModel extends ConfigObject { export class SubmissionFormsModel extends SubmissionFormModel {
static type = new ResourceType('submissionforms');
/**
* An array of [FormRowModel] that are present in this form
*/
rows: FormRowModel[];
} }

View File

@@ -1,5 +1,6 @@
import { ConfigObject } from './config.model'; import { ConfigObject } from './config.model';
import { SectionsType } from '../../../submission/sections/sections-type'; import { SectionsType } from '../../../submission/sections/sections-type';
import { ResourceType } from '../../shared/resource-type';
/** /**
* An interface that define section visibility and its properties. * An interface that define section visibility and its properties.
@@ -10,6 +11,7 @@ export interface SubmissionSectionVisibility {
} }
export class SubmissionSectionModel extends ConfigObject { export class SubmissionSectionModel extends ConfigObject {
static type = new ResourceType('submissionsection');
/** /**
* The header for this section * The header for this section

View File

@@ -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');
}

View File

@@ -1,9 +1,10 @@
import { ConfigObject } from './config.model'; import { ConfigObject } from './config.model';
import { AccessConditionOption } from './config-access-condition-option.model'; import { AccessConditionOption } from './config-access-condition-option.model';
import { SubmissionFormsModel } from './config-submission-forms.model'; import { SubmissionFormsModel } from './config-submission-forms.model';
import { ResourceType } from '../../shared/resource-type';
export class SubmissionUploadsModel extends ConfigObject { export class SubmissionUploadsModel extends ConfigObject {
static type = new ResourceType('submissionupload');
/** /**
* A list of available bitstream access conditions * A list of available bitstream access conditions
*/ */

View File

@@ -8,11 +8,6 @@ export abstract class ConfigObject implements CacheableObject {
*/ */
public name: string; 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. * The links to all related resources returned by the rest api.
*/ */

View File

@@ -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>;
}

View File

@@ -1,25 +1,13 @@
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize'; import { inheritSerialization } from 'cerialize';
import { SubmissionSectionModel } from './config-submission-section.model';
import { PaginatedList } from '../../data/paginated-list';
import { NormalizedConfigObject } from './normalized-config.model'; import { NormalizedConfigObject } from './normalized-config.model';
import { SubmissionDefinitionsModel } from './config-submission-definitions.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 * Normalized class for the configuration describing the submission
*/ */
@mapsTo(SubmissionDefinitionsModel)
@inheritSerialization(NormalizedConfigObject) @inheritSerialization(NormalizedConfigObject)
export class NormalizedSubmissionDefinitionsModel extends NormalizedConfigObject<SubmissionDefinitionsModel> { export class NormalizedSubmissionDefinitionsModel extends NormalizedSubmissionDefinitionModel {
/**
* 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>;
} }

Some files were not shown because too many files have changed in this diff Show More