moved meta service into applicable page components

This commit is contained in:
William Welling
2017-10-13 13:09:00 -05:00
parent 617f3ad029
commit 6f42fa5af5
10 changed files with 108 additions and 181 deletions

View File

@@ -2,12 +2,11 @@ import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { CollectionPageComponent } from './collection-page.component'; import { CollectionPageComponent } from './collection-page.component';
import { NormalizedCollection } from '../core/cache/models/normalized-collection.model';
@NgModule({ @NgModule({
imports: [ imports: [
RouterModule.forChild([ RouterModule.forChild([
{ path: ':id', component: CollectionPageComponent, pathMatch: 'full', data: { type: NormalizedCollection } } { path: ':id', component: CollectionPageComponent, pathMatch: 'full' }
]) ])
] ]
}) })

View File

@@ -7,6 +7,8 @@ import {
} from '@angular/core'; } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router'; import { ActivatedRoute, Params } from '@angular/router';
import { PageInfo } from '../core/shared/page-info.model';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription'; import { Subscription } from 'rxjs/Subscription';
import { Collection } from '../core/shared/collection.model'; import { Collection } from '../core/shared/collection.model';
@@ -18,8 +20,8 @@ import { Item } from '../core/shared/item.model';
import { SortOptions, SortDirection } from '../core/cache/models/sort-options.model'; import { SortOptions, SortDirection } from '../core/cache/models/sort-options.model';
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
import { hasValue, isNotEmpty, isUndefined } from '../shared/empty.util'; import { hasValue, isNotEmpty, isUndefined } from '../shared/empty.util';
import { PageInfo } from '../core/shared/page-info.model';
import { Observable } from 'rxjs/Observable'; import { MetadataService } from '../core/metadata/metadata.service';
import { fadeIn, fadeInOut } from '../shared/animations/fade'; import { fadeIn, fadeInOut } from '../shared/animations/fade';
@@ -41,9 +43,12 @@ export class CollectionPageComponent implements OnInit, OnDestroy {
private subs: Subscription[] = []; private subs: Subscription[] = [];
private collectionId: string; private collectionId: string;
constructor(private collectionDataService: CollectionDataService, constructor(
private collectionDataService: CollectionDataService,
private itemDataService: ItemDataService, private itemDataService: ItemDataService,
private route: ActivatedRoute) { private metadata: MetadataService,
private route: ActivatedRoute
) {
this.paginationConfig = new PaginationComponentOptions(); this.paginationConfig = new PaginationComponentOptions();
this.paginationConfig.id = 'collection-page-pagination'; this.paginationConfig.id = 'collection-page-pagination';
this.paginationConfig.pageSizeOptions = [4]; this.paginationConfig.pageSizeOptions = [4];
@@ -63,6 +68,7 @@ export class CollectionPageComponent implements OnInit, OnDestroy {
.subscribe((params) => { .subscribe((params) => {
this.collectionId = params.id; this.collectionId = params.id;
this.collectionData = this.collectionDataService.findById(this.collectionId); this.collectionData = this.collectionDataService.findById(this.collectionId);
this.metadata.processRemoteData(this.collectionData);
this.subs.push(this.collectionData.payload.subscribe((collection) => this.logoData = collection.logo)); this.subs.push(this.collectionData.payload.subscribe((collection) => this.logoData = collection.logo));
const page = +params.page || this.paginationConfig.currentPage; const page = +params.page || this.paginationConfig.currentPage;

View File

@@ -2,12 +2,11 @@ import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { CommunityPageComponent } from './community-page.component'; import { CommunityPageComponent } from './community-page.component';
import { NormalizedCommunity } from '../core/cache/models/normalized-community.model';
@NgModule({ @NgModule({
imports: [ imports: [
RouterModule.forChild([ RouterModule.forChild([
{ path: ':id', component: CommunityPageComponent, pathMatch: 'full', data: { type: NormalizedCommunity } } { path: ':id', component: CommunityPageComponent, pathMatch: 'full' }
]) ])
] ]
}) })

View File

@@ -9,6 +9,8 @@ import { RemoteData } from '../core/data/remote-data';
import { CommunityDataService } from '../core/data/community-data.service'; import { CommunityDataService } from '../core/data/community-data.service';
import { hasValue } from '../shared/empty.util'; import { hasValue } from '../shared/empty.util';
import { MetadataService } from '../core/metadata/metadata.service';
import { fadeInOut } from '../shared/animations/fade'; import { fadeInOut } from '../shared/animations/fade';
@Component({ @Component({
@@ -24,6 +26,7 @@ export class CommunityPageComponent implements OnInit, OnDestroy {
constructor( constructor(
private communityDataService: CommunityDataService, private communityDataService: CommunityDataService,
private metadata: MetadataService,
private route: ActivatedRoute private route: ActivatedRoute
) { ) {
@@ -32,15 +35,13 @@ export class CommunityPageComponent implements OnInit, OnDestroy {
ngOnInit(): void { ngOnInit(): void {
this.route.params.subscribe((params: Params) => { this.route.params.subscribe((params: Params) => {
this.communityData = this.communityDataService.findById(params.id); this.communityData = this.communityDataService.findById(params.id);
this.subs.push(this.communityData.payload this.metadata.processRemoteData(this.communityData);
.subscribe((community) => this.logoData = community.logo)); this.subs.push(this.communityData.payload.subscribe((community) => this.logoData = community.logo));
}); });
} }
ngOnDestroy(): void { ngOnDestroy(): void {
this.subs this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
.filter((sub) => hasValue(sub))
.forEach((sub) => sub.unsubscribe());
} }
} }

View File

@@ -1,15 +1,17 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { animate, state, transition, trigger, style, keyframes } from '@angular/animations'; import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { ItemPageComponent } from '../simple/item-page.component'; import { ItemPageComponent } from '../simple/item-page.component';
import { Metadatum } from '../../core/shared/metadatum.model'; import { Metadatum } from '../../core/shared/metadatum.model';
import { ItemDataService } from '../../core/data/item-data.service'; import { ItemDataService } from '../../core/data/item-data.service';
import { ActivatedRoute } from '@angular/router';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { Item } from '../../core/shared/item.model'; import { Item } from '../../core/shared/item.model';
import { MetadataService } from '../../core/metadata/metadata.service';
import { fadeInOut } from '../../shared/animations/fade'; import { fadeInOut } from '../../shared/animations/fade';
/** /**
@@ -30,8 +32,8 @@ export class FullItemPageComponent extends ItemPageComponent implements OnInit {
metadata: Observable<Metadatum[]>; metadata: Observable<Metadatum[]>;
constructor(route: ActivatedRoute, items: ItemDataService) { constructor(route: ActivatedRoute, items: ItemDataService, metadataService: MetadataService) {
super(route, items); super(route, items, metadataService);
} }
/*** AoT inheritance fix, will hopefully be resolved in the near future **/ /*** AoT inheritance fix, will hopefully be resolved in the near future **/

View File

@@ -3,13 +3,12 @@ import { RouterModule } from '@angular/router';
import { ItemPageComponent } from './simple/item-page.component'; import { ItemPageComponent } from './simple/item-page.component';
import { FullItemPageComponent } from './full/full-item-page.component'; import { FullItemPageComponent } from './full/full-item-page.component';
import { NormalizedItem } from '../core/cache/models/normalized-item.model';
@NgModule({ @NgModule({
imports: [ imports: [
RouterModule.forChild([ RouterModule.forChild([
{ path: ':id', component: ItemPageComponent, pathMatch: 'full', data: { type: NormalizedItem } }, { path: ':id', component: ItemPageComponent, pathMatch: 'full' },
{ path: ':id/full', component: FullItemPageComponent, data: { type: NormalizedItem } } { path: ':id/full', component: FullItemPageComponent }
]) ])
] ]
}) })

View File

@@ -8,6 +8,8 @@ import { ItemDataService } from '../../core/data/item-data.service';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { Bitstream } from '../../core/shared/bitstream.model'; import { Bitstream } from '../../core/shared/bitstream.model';
import { MetadataService } from '../../core/metadata/metadata.service';
import { fadeInOut } from '../../shared/animations/fade'; import { fadeInOut } from '../../shared/animations/fade';
/** /**
@@ -31,7 +33,11 @@ export class ItemPageComponent implements OnInit {
thumbnail: Observable<Bitstream>; thumbnail: Observable<Bitstream>;
constructor(private route: ActivatedRoute, private items: ItemDataService) { constructor(
private route: ActivatedRoute,
private items: ItemDataService,
private metadataService: MetadataService
) {
} }
@@ -44,6 +50,7 @@ export class ItemPageComponent implements OnInit {
initialize(params) { initialize(params) {
this.id = +params.id; this.id = +params.id;
this.item = this.items.findById(params.id); this.item = this.items.findById(params.id);
this.metadataService.processRemoteData(this.item);
this.thumbnail = this.item.payload.flatMap((i) => i.getThumbnail()); this.thumbnail = this.item.payload.flatMap((i) => i.getThumbnail());
} }

View File

@@ -4,7 +4,7 @@ import { RouterTestingModule } from '@angular/router/testing';
import { Location, CommonModule } from '@angular/common'; import { Location, CommonModule } from '@angular/common';
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { By, Meta, MetaDefinition, Title } from '@angular/platform-browser'; import { By, Meta, MetaDefinition, Title } from '@angular/platform-browser';
import { Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
@@ -19,17 +19,16 @@ import { CoreState } from '../core.reducers';
import { GlobalConfig } from '../../../config/global-config.interface'; import { GlobalConfig } from '../../../config/global-config.interface';
import { ENV_CONFIG, GLOBAL_CONFIG } from '../../../config'; import { ENV_CONFIG, GLOBAL_CONFIG } from '../../../config';
import { ItemDataService } from '../data/item-data.service';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { RequestService } from '../data/request.service'; import { RequestService } from '../data/request.service';
import { ResponseCacheService } from '../cache/response-cache.service'; import { ResponseCacheService } from '../cache/response-cache.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { RemoteData } from '../../core/data/remote-data';
import { Item } from '../../core/shared/item.model'; import { Item } from '../../core/shared/item.model';
import { NormalizedItem } from '../cache/models/normalized-item.model';
import { MockItem } from '../../shared/mocks/mock-item'; import { MockItem } from '../../shared/mocks/mock-item';
import { MockNormalizedItem } from '../../shared/mocks/mock-normalized-item';
import { MockRouter } from '../../shared/mocks/mock-router';
import { MockTranslateLoader } from '../../shared/mocks/mock-translate-loader'; import { MockTranslateLoader } from '../../shared/mocks/mock-translate-loader';
/* tslint:disable:max-classes-per-file */ /* tslint:disable:max-classes-per-file */
@@ -42,7 +41,13 @@ class TestComponent {
} }
} }
@Component({ template: '' }) class DummyItemComponent { } @Component({ template: '' }) class DummyItemComponent {
constructor(private route: ActivatedRoute, private items: ItemDataService, private metadata: MetadataService) {
this.route.params.subscribe((params) => {
this.metadata.processRemoteData(this.items.findById(params.id));
});
}
}
/* tslint:enable:max-classes-per-file */ /* tslint:enable:max-classes-per-file */
describe('MetadataService', () => { describe('MetadataService', () => {
@@ -58,6 +63,7 @@ describe('MetadataService', () => {
let responseCacheService: ResponseCacheService; let responseCacheService: ResponseCacheService;
let requestService: RequestService; let requestService: RequestService;
let remoteDataBuildService: RemoteDataBuildService; let remoteDataBuildService: RemoteDataBuildService;
let itemDataService: ItemDataService;
let location: Location; let location: Location;
let router: Router; let router: Router;
@@ -88,8 +94,8 @@ describe('MetadataService', () => {
} }
}), }),
RouterTestingModule.withRoutes([ RouterTestingModule.withRoutes([
{ path: 'items/:id', component: DummyItemComponent, pathMatch: 'full', data: { type: NormalizedItem } }, { path: 'items/:id', component: DummyItemComponent, pathMatch: 'full' },
{ path: 'other', component: DummyItemComponent, pathMatch: 'full', data: { title: 'Dummy Title', description: 'This is a dummy component for testing!' } } { path: 'other', component: DummyItemComponent, pathMatch: 'full', data: { title: 'Dummy Title', description: 'This is a dummy item component for testing!' } }
]) ])
], ],
declarations: [ declarations: [
@@ -104,12 +110,14 @@ describe('MetadataService', () => {
{ provide: GLOBAL_CONFIG, useValue: ENV_CONFIG }, { provide: GLOBAL_CONFIG, useValue: ENV_CONFIG },
Meta, Meta,
Title, Title,
ItemDataService,
MetadataService MetadataService
], ],
schemas: [CUSTOM_ELEMENTS_SCHEMA] schemas: [CUSTOM_ELEMENTS_SCHEMA]
}); });
meta = TestBed.get(Meta); meta = TestBed.get(Meta);
title = TestBed.get(Title); title = TestBed.get(Title);
itemDataService = TestBed.get(ItemDataService);
metadataService = TestBed.get(MetadataService); metadataService = TestBed.get(MetadataService);
envConfig = TestBed.get(GLOBAL_CONFIG); envConfig = TestBed.get(GLOBAL_CONFIG);
@@ -122,14 +130,8 @@ describe('MetadataService', () => {
tagStore = metadataService.getTagStore(); tagStore = metadataService.getTagStore();
}); });
beforeEach(() => {
spyOn(objectCacheService, 'getByUUID').and.returnValue(Observable.create((observer) => {
observer.next(MockNormalizedItem);
}));
});
it('items page should set meta tags', fakeAsync(() => { it('items page should set meta tags', fakeAsync(() => {
spyOn(remoteDataBuildService, 'build').and.returnValue(MockItem); spyOn(itemDataService, 'findById').and.returnValue(mockRemoteData(MockItem));
router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']); router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']);
tick(); tick();
expect(title.getTitle()).toEqual('Test PowerPoint Document'); expect(title.getTitle()).toEqual('Test PowerPoint Document');
@@ -142,7 +144,7 @@ describe('MetadataService', () => {
})); }));
it('items page should set meta tags as published Thesis', fakeAsync(() => { it('items page should set meta tags as published Thesis', fakeAsync(() => {
spyOn(remoteDataBuildService, 'build').and.returnValue(mockPublisher(mockType(MockItem, 'Thesis'))); spyOn(itemDataService, 'findById').and.returnValue(mockRemoteData(mockPublisher(mockType(MockItem, 'Thesis'))));
router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']); router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']);
tick(); tick();
expect(tagStore.get('citation_dissertation_name')[0].content).toEqual('Test PowerPoint Document'); expect(tagStore.get('citation_dissertation_name')[0].content).toEqual('Test PowerPoint Document');
@@ -152,14 +154,14 @@ describe('MetadataService', () => {
})); }));
it('items page should set meta tags as published Technical Report', fakeAsync(() => { it('items page should set meta tags as published Technical Report', fakeAsync(() => {
spyOn(remoteDataBuildService, 'build').and.returnValue(mockPublisher(mockType(MockItem, 'Technical Report'))); spyOn(itemDataService, 'findById').and.returnValue(mockRemoteData(mockPublisher(mockType(MockItem, 'Technical Report'))));
router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']); router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']);
tick(); tick();
expect(tagStore.get('citation_technical_report_institution')[0].content).toEqual('Mock Publisher'); expect(tagStore.get('citation_technical_report_institution')[0].content).toEqual('Mock Publisher');
})); }));
it('other navigation should title and description', fakeAsync(() => { it('other navigation should title and description', fakeAsync(() => {
spyOn(remoteDataBuildService, 'build').and.returnValue(MockItem); spyOn(itemDataService, 'findById').and.returnValue(mockRemoteData(MockItem));
router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']); router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']);
tick(); tick();
expect(tagStore.size).toBeGreaterThan(0) expect(tagStore.size).toBeGreaterThan(0)
@@ -168,9 +170,38 @@ describe('MetadataService', () => {
expect(tagStore.size).toEqual(2); expect(tagStore.size).toEqual(2);
expect(title.getTitle()).toEqual('Dummy Title'); expect(title.getTitle()).toEqual('Dummy Title');
expect(tagStore.get('title')[0].content).toEqual('Dummy Title'); expect(tagStore.get('title')[0].content).toEqual('Dummy Title');
expect(tagStore.get('description')[0].content).toEqual('This is a dummy component for testing!'); expect(tagStore.get('description')[0].content).toEqual('This is a dummy item component for testing!');
})); }));
const mockRemoteData = (mockItem: Item): RemoteData<Item> => {
return new RemoteData<Item>(
Observable.create((observer) => {
observer.next('');
}),
Observable.create((observer) => {
observer.next(false);
}),
Observable.create((observer) => {
observer.next(false);
}),
Observable.create((observer) => {
observer.next(true);
}),
Observable.create((observer) => {
observer.next('');
}),
Observable.create((observer) => {
observer.next(200);
}),
Observable.create((observer) => {
observer.next({});
}),
Observable.create((observer) => {
observer.next(MockItem);
})
);
}
const mockType = (mockItem: Item, type: string): Item => { const mockType = (mockItem: Item, type: string): Item => {
const typedMockItem = Object.assign(new Item(), mockItem) as Item; const typedMockItem = Object.assign(new Item(), mockItem) as Item;
for (const metadatum of typedMockItem.metadata) { for (const metadatum of typedMockItem.metadata) {

View File

@@ -17,13 +17,12 @@ import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { RemoteData } from '../data/remote-data';
import { Bitstream } from '../shared/bitstream.model'; import { Bitstream } from '../shared/bitstream.model';
import { CacheableObject } from '../cache/object-cache.reducer'; import { CacheableObject } from '../cache/object-cache.reducer';
import { DSpaceObject } from '../shared/dspace-object.model'; import { DSpaceObject } from '../shared/dspace-object.model';
import { Item } from '../shared/item.model'; import { Item } from '../shared/item.model';
import { Metadatum } from '../shared/metadatum.model'; import { Metadatum } from '../shared/metadatum.model';
import { ObjectCacheService } from '../cache/object-cache.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { GLOBAL_CONFIG, GlobalConfig } from '../../../config'; import { GLOBAL_CONFIG, GlobalConfig } from '../../../config';
@@ -38,8 +37,6 @@ export class MetadataService {
constructor( constructor(
private router: Router, private router: Router,
private objectCacheService: ObjectCacheService,
private remoteDataBuildService: RemoteDataBuildService,
private translate: TranslateService, private translate: TranslateService,
private meta: Meta, private meta: Meta,
private title: Title, private title: Title,
@@ -67,18 +64,19 @@ export class MetadataService {
}); });
} }
private processRouteChange(routeInfo: any): void { public processRemoteData(remoteData: RemoteData<CacheableObject>): void {
if (routeInfo.params.value.id && routeInfo.data.value.type) { remoteData.payload.take(1).subscribe((dspaceObject: DSpaceObject) => {
this.objectCacheService.getByUUID(routeInfo.params.value.id, routeInfo.data.value.type)
.first().subscribe((normalizedObject: CacheableObject) => {
const dspaceObject = this.remoteDataBuildService.build(normalizedObject) as DSpaceObject;
if (!this.initialized) { if (!this.initialized) {
this.initialize(dspaceObject); this.initialize(dspaceObject);
} }
this.currentObject.next(dspaceObject); this.currentObject.next(dspaceObject);
}); });
} else { }
private processRouteChange(routeInfo: any): void {
if (routeInfo.params.value.id === undefined) {
this.clearMetaTags(); this.clearMetaTags();
}
if (routeInfo.data.value.title) { if (routeInfo.data.value.title) {
this.translate.get(routeInfo.data.value.title).take(1).subscribe((translatedTitle: string) => { this.translate.get(routeInfo.data.value.title).take(1).subscribe((translatedTitle: string) => {
this.addMetaTag('title', translatedTitle); this.addMetaTag('title', translatedTitle);
@@ -91,7 +89,6 @@ export class MetadataService {
}); });
} }
} }
}
private initialize(dspaceObject: DSpaceObject): void { private initialize(dspaceObject: DSpaceObject): void {
this.currentObject = new BehaviorSubject<DSpaceObject>(dspaceObject); this.currentObject = new BehaviorSubject<DSpaceObject>(dspaceObject);

View File

@@ -1,114 +0,0 @@
import { NormalizedItem } from '../../core/cache/models/normalized-item.model';
export const MockNormalizedItem: NormalizedItem = Object.assign(new NormalizedItem(), {
handle: '10673/6',
lastModified: new Date('2017-04-24T19:44:08.178+0000'),
isArchived: true,
isDiscoverable: true,
isWithdrawn: false,
bitstreams: [
'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/a7cd7d97-4e40-41db-80a8-fac908b63bb8',
'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/9ff3df0d-1709-472f-8c00-d3e8db2153c8',
'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/d660a4b8-e7cc-45cd-b026-35f98c5bd3ba'
],
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357',
id: '0ec7ff22-f211-40ab-a69e-c819b0b1f357',
uuid: '0ec7ff22-f211-40ab-a69e-c819b0b1f357',
type: 'item',
name: 'Test PowerPoint Document',
metadata: [
{
key: 'dc.creator',
language: 'en_US',
value: 'Doe, Jane L'
},
{
key: 'dc.date.accessioned',
language: null,
value: '1650-06-26T19:58:25Z'
},
{
key: 'dc.date.available',
language: null,
value: '1650-06-26T19:58:25Z'
},
{
key: 'dc.date.issued',
language: null,
value: '1650-06-26'
},
{
key: 'dc.identifier.issn',
language: 'en_US',
value: '123456789'
},
{
key: 'dc.identifier.uri',
language: null,
value: 'http://dspace7.4science.it/xmlui/handle/10673/6'
},
{
key: 'dc.description.abstract',
language: 'en_US',
value: 'This is really just a sample abstract. If it was a real abstract it would contain useful information about this test document. Sorry though, nothing useful in this paragraph. You probably shouldn\'t have even bothered to read it!'
},
{
key: 'dc.description.provenance',
language: 'en',
value: 'Made available in DSpace on 2012-06-26T19:58:25Z (GMT). No. of bitstreams: 2\r\ntest_ppt.ppt: 12707328 bytes, checksum: a353fc7d29b3c558c986f7463a41efd3 (MD5)\r\ntest_ppt.pptx: 12468572 bytes, checksum: 599305edb4ebee329667f2c35b14d1d6 (MD5)'
},
{
key: 'dc.description.provenance',
language: 'en',
value: 'Restored into DSpace on 2013-06-13T09:17:34Z (GMT).'
},
{
key: 'dc.description.provenance',
language: 'en',
value: 'Restored into DSpace on 2013-06-13T11:04:16Z (GMT).'
},
{
key: 'dc.description.provenance',
language: 'en',
value: 'Restored into DSpace on 2017-04-24T19:44:08Z (GMT).'
},
{
key: 'dc.language',
language: 'en_US',
value: 'en'
},
{
key: 'dc.rights',
language: 'en_US',
value: '© Jane Doe'
},
{
key: 'dc.subject',
language: 'en_US',
value: 'keyword1'
},
{
key: 'dc.subject',
language: 'en_US',
value: 'keyword2'
},
{
key: 'dc.subject',
language: 'en_US',
value: 'keyword3'
},
{
key: 'dc.title',
language: 'en_US',
value: 'Test PowerPoint Document'
},
{
key: 'dc.type',
language: 'en_US',
value: 'text'
}
],
owningCollection: [
'https://dspace7.4science.it/dspace-spring-rest/api/core/collections/1c11f3f1-ba1f-4f36-908a-3f1ea9a557eb'
]
})