From 2368df95136889008287bfdf141921c63cdc62b1 Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Sat, 22 Dec 2018 23:03:45 -0500 Subject: [PATCH 1/6] DS-4107 Retrieve and model metadata as a map --- .../modify-item-overview.component.html | 14 ++- .../modify-item-overview.component.ts | 4 +- .../metadata-uri-values.component.html | 4 +- .../metadata-uri-values.component.ts | 3 +- .../metadata-values.component.html | 4 +- .../metadata-values.component.ts | 4 +- .../full-file-section.component.html | 2 +- .../full/full-item-page.component.html | 12 +- .../full/full-item-page.component.ts | 4 +- .../item-page-specific-field.component.html | 2 +- .../item-page-title-field.component.html | 2 +- .../uri/item-page-uri-field.component.html | 2 +- .../normalized-search-result.model.ts | 4 +- src/app/+search-page/search-result.model.ts | 4 +- src/app/core/browse/browse.service.ts | 12 +- .../models/normalized-dspace-object.model.ts | 9 +- .../data/search-response-parsing.service.ts | 16 +-- .../dspace-rest-v2/dspace-rest-v2.service.ts | 6 +- src/app/core/metadata/metadata.service.ts | 54 ++------ src/app/core/shared/collection.model.ts | 10 +- src/app/core/shared/community.model.ts | 8 +- src/app/core/shared/dspace-object.model.ts | 65 ++++------ src/app/core/shared/metadata.interfaces.ts | 30 +++++ src/app/core/shared/metadata.model.ts | 119 ++++++++++++++++++ src/app/core/shared/metadatum.model.ts | 23 ---- .../comcol-form/comcol-form.component.ts | 25 ++-- .../abstract-listable-element.component.ts | 5 - .../item-grid-element.component.html | 10 +- ...-search-result-grid-element.component.html | 12 +- .../search-result-grid-element.component.ts | 40 ++---- .../item-list-element.component.html | 14 +-- ...-search-result-list-element.component.html | 4 +- ...-search-result-list-element.component.html | 4 +- ...-search-result-list-element.component.html | 20 +-- .../search-result-list-element.component.ts | 40 ++---- 35 files changed, 310 insertions(+), 281 deletions(-) create mode 100644 src/app/core/shared/metadata.interfaces.ts create mode 100644 src/app/core/shared/metadata.model.ts delete mode 100644 src/app/core/shared/metadatum.model.ts diff --git a/src/app/+item-page/edit-item-page/modify-item-overview/modify-item-overview.component.html b/src/app/+item-page/edit-item-page/modify-item-overview/modify-item-overview.component.html index d59d29ddbf4..861c20ada7d 100644 --- a/src/app/+item-page/edit-item-page/modify-item-overview/modify-item-overview.component.html +++ b/src/app/+item-page/edit-item-page/modify-item-overview/modify-item-overview.component.html @@ -7,10 +7,12 @@ - - {{metadatum.key}} - {{metadatum.value}} - {{metadatum.language}} - + + + {{entry.key}} + {{value.value}} + {{value.language}} + + - \ No newline at end of file + diff --git a/src/app/+item-page/edit-item-page/modify-item-overview/modify-item-overview.component.ts b/src/app/+item-page/edit-item-page/modify-item-overview/modify-item-overview.component.ts index d32a98d5e01..282f8687e16 100644 --- a/src/app/+item-page/edit-item-page/modify-item-overview/modify-item-overview.component.ts +++ b/src/app/+item-page/edit-item-page/modify-item-overview/modify-item-overview.component.ts @@ -1,6 +1,6 @@ import {Component, Input, OnInit} from '@angular/core'; import {Item} from '../../../core/shared/item.model'; -import {Metadatum} from '../../../core/shared/metadatum.model'; +import {MetadataMap} from '../../../core/shared/metadata.interfaces'; @Component({ selector: 'ds-modify-item-overview', @@ -12,7 +12,7 @@ import {Metadatum} from '../../../core/shared/metadatum.model'; export class ModifyItemOverviewComponent implements OnInit { @Input() item: Item; - metadata: Metadatum[]; + metadata: MetadataMap; ngOnInit(): void { this.metadata = this.item.metadata; diff --git a/src/app/+item-page/field-components/metadata-uri-values/metadata-uri-values.component.html b/src/app/+item-page/field-components/metadata-uri-values/metadata-uri-values.component.html index cc618bcd501..344a32841b3 100644 --- a/src/app/+item-page/field-components/metadata-uri-values/metadata-uri-values.component.html +++ b/src/app/+item-page/field-components/metadata-uri-values/metadata-uri-values.component.html @@ -1,5 +1,5 @@ - - {{ linktext || metadatum.value }} + + {{ linktext || value.value }} diff --git a/src/app/+item-page/field-components/metadata-uri-values/metadata-uri-values.component.ts b/src/app/+item-page/field-components/metadata-uri-values/metadata-uri-values.component.ts index 212dcddee88..b5870f16b8e 100644 --- a/src/app/+item-page/field-components/metadata-uri-values/metadata-uri-values.component.ts +++ b/src/app/+item-page/field-components/metadata-uri-values/metadata-uri-values.component.ts @@ -1,6 +1,7 @@ import { Component, Input } from '@angular/core'; import { MetadataValuesComponent } from '../metadata-values/metadata-values.component'; +import { MetadataValue } from '../../../core/shared/metadata.interfaces'; /** * This component renders the configured 'values' into the ds-metadata-field-wrapper component as a link. @@ -18,7 +19,7 @@ export class MetadataUriValuesComponent extends MetadataValuesComponent { @Input() linktext: any; - @Input() values: any; + @Input() values: MetadataValue[]; @Input() separator: string; diff --git a/src/app/+item-page/field-components/metadata-values/metadata-values.component.html b/src/app/+item-page/field-components/metadata-values/metadata-values.component.html index f16655c63c7..fbc1e11a079 100644 --- a/src/app/+item-page/field-components/metadata-values/metadata-values.component.html +++ b/src/app/+item-page/field-components/metadata-values/metadata-values.component.html @@ -1,5 +1,5 @@ - - {{metadatum.value}} + + {{value.value}} diff --git a/src/app/+item-page/field-components/metadata-values/metadata-values.component.ts b/src/app/+item-page/field-components/metadata-values/metadata-values.component.ts index 1c94b56d57c..2be7291dcd6 100644 --- a/src/app/+item-page/field-components/metadata-values/metadata-values.component.ts +++ b/src/app/+item-page/field-components/metadata-values/metadata-values.component.ts @@ -1,5 +1,5 @@ import { Component, Input } from '@angular/core'; -import { Metadatum } from '../../../core/shared/metadatum.model'; +import { MetadataValue } from '../../../core/shared/metadata.interfaces'; /** * This component renders the configured 'values' into the ds-metadata-field-wrapper component. @@ -12,7 +12,7 @@ import { Metadatum } from '../../../core/shared/metadatum.model'; }) export class MetadataValuesComponent { - @Input() values: Metadatum[]; + @Input() values: MetadataValue[]; @Input() separator: string; diff --git a/src/app/+item-page/full/field-components/file-section/full-file-section.component.html b/src/app/+item-page/full/field-components/file-section/full-file-section.component.html index d5a7febeb93..a68993cd16d 100644 --- a/src/app/+item-page/full/field-components/file-section/full-file-section.component.html +++ b/src/app/+item-page/full/field-components/file-section/full-file-section.component.html @@ -17,7 +17,7 @@
{{"item.page.filesection.description" | translate}}
-
{{file.findMetadata("dc.description")}}
+
{{file.firstMetadataValue("dc.description")}}
diff --git a/src/app/+item-page/full/full-item-page.component.html b/src/app/+item-page/full/full-item-page.component.html index 1d0c4ab8125..7080ba2e96f 100644 --- a/src/app/+item-page/full/full-item-page.component.html +++ b/src/app/+item-page/full/full-item-page.component.html @@ -9,11 +9,13 @@
- - - - - + + + + + + +
{{metadatum.key}}{{metadatum.value}}{{metadatum.language}}
{{entry.key}}{{value.value}}{{value.language}}
diff --git a/src/app/+item-page/full/full-item-page.component.ts b/src/app/+item-page/full/full-item-page.component.ts index d09ac268ec0..fcb724b564c 100644 --- a/src/app/+item-page/full/full-item-page.component.ts +++ b/src/app/+item-page/full/full-item-page.component.ts @@ -6,7 +6,7 @@ import { ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs'; import { ItemPageComponent } from '../simple/item-page.component'; -import { Metadatum } from '../../core/shared/metadatum.model'; +import { MetadataMap } from '../../core/shared/metadata.interfaces'; import { ItemDataService } from '../../core/data/item-data.service'; import { RemoteData } from '../../core/data/remote-data'; @@ -34,7 +34,7 @@ export class FullItemPageComponent extends ItemPageComponent implements OnInit { itemRD$: Observable>; - metadata$: Observable; + metadata$: Observable; constructor(route: ActivatedRoute, items: ItemDataService, metadataService: MetadataService) { super(route, items, metadataService); diff --git a/src/app/+item-page/simple/field-components/specific-field/item-page-specific-field.component.html b/src/app/+item-page/simple/field-components/specific-field/item-page-specific-field.component.html index 4a27848ec66..c0d948fc766 100644 --- a/src/app/+item-page/simple/field-components/specific-field/item-page-specific-field.component.html +++ b/src/app/+item-page/simple/field-components/specific-field/item-page-specific-field.component.html @@ -1,3 +1,3 @@
- +
diff --git a/src/app/+item-page/simple/field-components/specific-field/title/item-page-title-field.component.html b/src/app/+item-page/simple/field-components/specific-field/title/item-page-title-field.component.html index 4c53e2e3e21..40f54ec6364 100644 --- a/src/app/+item-page/simple/field-components/specific-field/title/item-page-title-field.component.html +++ b/src/app/+item-page/simple/field-components/specific-field/title/item-page-title-field.component.html @@ -1,3 +1,3 @@

- +

diff --git a/src/app/+item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.html b/src/app/+item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.html index fde79d6a04a..771fef53fc7 100644 --- a/src/app/+item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.html +++ b/src/app/+item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.html @@ -1,3 +1,3 @@
- +
diff --git a/src/app/+search-page/normalized-search-result.model.ts b/src/app/+search-page/normalized-search-result.model.ts index 0683c74aede..3c1a46872cb 100644 --- a/src/app/+search-page/normalized-search-result.model.ts +++ b/src/app/+search-page/normalized-search-result.model.ts @@ -1,5 +1,5 @@ import { autoserialize } from 'cerialize'; -import { Metadatum } from '../core/shared/metadatum.model'; +import { MetadataMap } from '../core/shared/metadata.interfaces'; import { ListableObject } from '../shared/object-collection/shared/listable-object.model'; /** @@ -16,6 +16,6 @@ export class NormalizedSearchResult implements ListableObject { * The metadata that was used to find this item, hithighlighted */ @autoserialize - hitHighlights: Metadatum[]; + hitHighlights: MetadataMap; } diff --git a/src/app/+search-page/search-result.model.ts b/src/app/+search-page/search-result.model.ts index 00b1c62a993..b2e5eafdec6 100644 --- a/src/app/+search-page/search-result.model.ts +++ b/src/app/+search-page/search-result.model.ts @@ -1,5 +1,5 @@ import { DSpaceObject } from '../core/shared/dspace-object.model'; -import { Metadatum } from '../core/shared/metadatum.model'; +import { MetadataMap } from '../core/shared/metadata.interfaces'; import { ListableObject } from '../shared/object-collection/shared/listable-object.model'; /** @@ -14,6 +14,6 @@ export class SearchResult implements ListableObject { /** * The metadata that was used to find this item, hithighlighted */ - hitHighlights: Metadatum[]; + hitHighlights: MetadataMap; } diff --git a/src/app/core/browse/browse.service.ts b/src/app/core/browse/browse.service.ts index b807a77e99e..41675632dd7 100644 --- a/src/app/core/browse/browse.service.ts +++ b/src/app/core/browse/browse.service.ts @@ -38,8 +38,8 @@ import { DSpaceObject } from '../shared/dspace-object.model'; export class BrowseService { protected linkPath = 'browses'; - private static toSearchKeyArray(metadatumKey: string): string[] { - const keyParts = metadatumKey.split('.'); + private static toSearchKeyArray(metadataKey: string): string[] { + const keyParts = metadataKey.split('.'); const searchFor = []; searchFor.push('*'); for (let i = 0; i < keyParts.length - 1; i++) { @@ -47,7 +47,7 @@ export class BrowseService { const nextPart = [...prevParts, '*'].join('.'); searchFor.push(nextPart); } - searchFor.push(metadatumKey); + searchFor.push(metadataKey); return searchFor; } @@ -179,8 +179,8 @@ export class BrowseService { return this.rdb.toRemoteDataObservable(requestEntry$, payload$); } - getBrowseURLFor(metadatumKey: string, linkPath: string): Observable { - const searchKeyArray = BrowseService.toSearchKeyArray(metadatumKey); + getBrowseURLFor(metadataKey: string, linkPath: string): Observable { + const searchKeyArray = BrowseService.toSearchKeyArray(metadataKey); return this.getBrowseDefinitions().pipe( getRemoteDataPayload(), map((browseDefinitions: BrowseDefinition[]) => browseDefinitions @@ -191,7 +191,7 @@ export class BrowseService { ), map((def: BrowseDefinition) => { if (isEmpty(def) || isEmpty(def._links) || isEmpty(def._links[linkPath])) { - throw new Error(`A browse endpoint for ${linkPath} on ${metadatumKey} isn't configured`); + throw new Error(`A browse endpoint for ${linkPath} on ${metadataKey} isn't configured`); } else { return def._links[linkPath]; } diff --git a/src/app/core/cache/models/normalized-dspace-object.model.ts b/src/app/core/cache/models/normalized-dspace-object.model.ts index 030e17364ac..87bd4b4369c 100644 --- a/src/app/core/cache/models/normalized-dspace-object.model.ts +++ b/src/app/core/cache/models/normalized-dspace-object.model.ts @@ -1,7 +1,6 @@ import { autoserialize, autoserializeAs, deserialize, serialize } from 'cerialize'; import { DSpaceObject } from '../../shared/dspace-object.model'; - -import { Metadatum } from '../../shared/metadatum.model'; +import { MetadataMap } from '../../shared/metadata.interfaces'; import { ResourceType } from '../../shared/resource-type'; import { mapsTo } from '../builders/build-decorators'; import { NormalizedObject } from './normalized-object.model'; @@ -46,10 +45,10 @@ export class NormalizedDSpaceObject extends NormalizedObject { type: ResourceType; /** - * An array containing all metadata of this DSpaceObject + * All metadata of this DSpaceObject */ - @autoserializeAs(Metadatum) - metadata: Metadatum[]; + @autoserialize + metadata: MetadataMap; /** * An array of DSpaceObjects that are direct parents of this DSpaceObject diff --git a/src/app/core/data/search-response-parsing.service.ts b/src/app/core/data/search-response-parsing.service.ts index 7ee2b60f895..46b2572c4e4 100644 --- a/src/app/core/data/search-response-parsing.service.ts +++ b/src/app/core/data/search-response-parsing.service.ts @@ -7,7 +7,7 @@ import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response. import { DSpaceRESTv2Serializer } from '../dspace-rest-v2/dspace-rest-v2.serializer'; import { hasValue } from '../../shared/empty.util'; import { SearchQueryResponse } from '../../+search-page/search-service/search-query-response.model'; -import { Metadatum } from '../shared/metadatum.model'; +import { MetadataMap, MetadataValue } from '../shared/metadata.interfaces'; @Injectable() export class SearchResponseParsingService implements ResponseParsingService { @@ -16,17 +16,17 @@ export class SearchResponseParsingService implements ResponseParsingService { parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse { const payload = data.payload._embedded.searchResult; - const hitHighlights = payload._embedded.objects + const hitHighlights: MetadataMap[] = payload._embedded.objects .map((object) => object.hitHighlights) .map((hhObject) => { + const mdMap: MetadataMap = {}; if (hhObject) { - return Object.keys(hhObject).map((key) => Object.assign(new Metadatum(), { - key: key, - value: hhObject[key].join('...') - })) - } else { - return []; + for (const key of Object.keys(hhObject)) { + const value: MetadataValue = { value: hhObject[key].join('...'), language: null }; + mdMap[key] = [ value ]; + } } + return mdMap; }); const dsoSelfLinks = payload._embedded.objects diff --git a/src/app/core/dspace-rest-v2/dspace-rest-v2.service.ts b/src/app/core/dspace-rest-v2/dspace-rest-v2.service.ts index 20d6b1dfb3f..6bf5eb08184 100644 --- a/src/app/core/dspace-rest-v2/dspace-rest-v2.service.ts +++ b/src/app/core/dspace-rest-v2/dspace-rest-v2.service.ts @@ -91,9 +91,9 @@ export class DSpaceRESTv2Service { const form: FormData = new FormData(); form.append('name', dso.name); if (dso.metadata) { - for (const i of Object.keys(dso.metadata)) { - if (isNotEmpty(dso.metadata[i].value)) { - form.append(dso.metadata[i].key, dso.metadata[i].value); + for (const key of Object.keys(dso.metadata)) { + for (const value of dso.allMetadataValues(key)) { + form.append(key, value); } } } diff --git a/src/app/core/metadata/metadata.service.ts b/src/app/core/metadata/metadata.service.ts index 9dbfae3f906..736bf119234 100644 --- a/src/app/core/metadata/metadata.service.ts +++ b/src/app/core/metadata/metadata.service.ts @@ -294,6 +294,10 @@ export class MetadataService { } } + private hasType(value: string): boolean { + return this.currentObject.value.hasMetadata('dc.type', { value: value, ignoreCase: true }); + } + /** * Returns true if this._item is a dissertation * @@ -301,14 +305,7 @@ export class MetadataService { * true if this._item has a dc.type equal to 'Thesis' */ private isDissertation(): boolean { - let isDissertation = false; - for (const metadatum of this.currentObject.value.metadata) { - if (metadatum.key === 'dc.type') { - isDissertation = metadatum.value.toLowerCase() === 'thesis'; - break; - } - } - return isDissertation; + return this.hasType('thesis'); } /** @@ -318,40 +315,15 @@ export class MetadataService { * true if this._item has a dc.type equal to 'Technical Report' */ private isTechReport(): boolean { - let isTechReport = false; - for (const metadatum of this.currentObject.value.metadata) { - if (metadatum.key === 'dc.type') { - isTechReport = metadatum.value.toLowerCase() === 'technical report'; - break; - } - } - return isTechReport; + return this.hasType('technical report'); } private getMetaTagValue(key: string): string { - let value: string; - for (const metadatum of this.currentObject.value.metadata) { - if (metadatum.key === key) { - value = metadatum.value; - } - } - return value; + return this.currentObject.value.firstMetadataValue(key); } private getFirstMetaTagValue(keys: string[]): string { - let value: string; - for (const metadatum of this.currentObject.value.metadata) { - for (const key of keys) { - if (key === metadatum.key) { - value = metadatum.value; - break; - } - } - if (value !== undefined) { - break; - } - } - return value; + return this.currentObject.value.firstMetadataValue(keys); } private getMetaTagValuesAndCombine(key: string): string { @@ -359,15 +331,7 @@ export class MetadataService { } private getMetaTagValues(keys: string[]): string[] { - const values: string[] = []; - for (const metadatum of this.currentObject.value.metadata) { - for (const key of keys) { - if (key === metadatum.key) { - values.push(metadatum.value); - } - } - } - return values; + return this.currentObject.value.allMetadataValues(keys); } private addMetaTag(property: string, content: string): void { diff --git a/src/app/core/shared/collection.model.ts b/src/app/core/shared/collection.model.ts index 8fdc14bd6e5..c630c9dd572 100644 --- a/src/app/core/shared/collection.model.ts +++ b/src/app/core/shared/collection.model.ts @@ -16,7 +16,7 @@ export class Collection extends DSpaceObject { * Corresponds to the metadata field dc.description */ get introductoryText(): string { - return this.findMetadata('dc.description'); + return this.firstMetadataValue('dc.description'); } /** @@ -24,7 +24,7 @@ export class Collection extends DSpaceObject { * Corresponds to the metadata field dc.description.abstract */ get shortDescription(): string { - return this.findMetadata('dc.description.abstract'); + return this.firstMetadataValue('dc.description.abstract'); } /** @@ -32,7 +32,7 @@ export class Collection extends DSpaceObject { * Corresponds to the metadata field dc.rights */ get copyrightText(): string { - return this.findMetadata('dc.rights'); + return this.firstMetadataValue('dc.rights'); } /** @@ -40,7 +40,7 @@ export class Collection extends DSpaceObject { * Corresponds to the metadata field dc.rights.license */ get license(): string { - return this.findMetadata('dc.rights.license'); + return this.firstMetadataValue('dc.rights.license'); } /** @@ -48,7 +48,7 @@ export class Collection extends DSpaceObject { * Corresponds to the metadata field dc.description.tableofcontents */ get sidebarText(): string { - return this.findMetadata('dc.description.tableofcontents'); + return this.firstMetadataValue('dc.description.tableofcontents'); } /** diff --git a/src/app/core/shared/community.model.ts b/src/app/core/shared/community.model.ts index c5f6e0ab876..c4e703fd7f8 100644 --- a/src/app/core/shared/community.model.ts +++ b/src/app/core/shared/community.model.ts @@ -17,7 +17,7 @@ export class Community extends DSpaceObject { * Corresponds to the metadata field dc.description */ get introductoryText(): string { - return this.findMetadata('dc.description'); + return this.firstMetadataValue('dc.description'); } /** @@ -25,7 +25,7 @@ export class Community extends DSpaceObject { * Corresponds to the metadata field dc.description.abstract */ get shortDescription(): string { - return this.findMetadata('dc.description.abstract'); + return this.firstMetadataValue('dc.description.abstract'); } /** @@ -33,7 +33,7 @@ export class Community extends DSpaceObject { * Corresponds to the metadata field dc.rights */ get copyrightText(): string { - return this.findMetadata('dc.rights'); + return this.firstMetadataValue('dc.rights'); } /** @@ -41,7 +41,7 @@ export class Community extends DSpaceObject { * Corresponds to the metadata field dc.description.tableofcontents */ get sidebarText(): string { - return this.findMetadata('dc.description.tableofcontents'); + return this.firstMetadataValue('dc.description.tableofcontents'); } /** diff --git a/src/app/core/shared/dspace-object.model.ts b/src/app/core/shared/dspace-object.model.ts index 3e08da151ce..1dba79865fb 100644 --- a/src/app/core/shared/dspace-object.model.ts +++ b/src/app/core/shared/dspace-object.model.ts @@ -1,5 +1,5 @@ -import { Metadatum } from './metadatum.model' -import { isEmpty, isNotEmpty } from '../../shared/empty.util'; +import { MetadataMap, MetadataValue, MetadataValueFilter } from './metadata.interfaces'; +import { Metadata } from './metadata.model'; import { CacheableObject } from '../cache/object-cache.reducer'; import { RemoteData } from '../data/remote-data'; import { ResourceType } from './resource-type'; @@ -35,14 +35,14 @@ export class DSpaceObject implements CacheableObject, ListableObject { * The name for this DSpaceObject */ get name(): string { - return this.findMetadata('dc.title'); + return this.firstMetadataValue('dc.title'); } /** - * An array containing all metadata of this DSpaceObject + * All metadata of this DSpaceObject */ @autoserialize - metadata: Metadatum[] = []; + metadata: MetadataMap; /** * An array of DSpaceObjects that are direct parents of this DSpaceObject @@ -54,42 +54,29 @@ export class DSpaceObject implements CacheableObject, ListableObject { */ owner: Observable>; - /** - * Find a metadata field by key and language - * - * This method returns the value of the first element - * in the metadata array that matches the provided - * key and language - * - * @param key - * @param language - * @return string - */ - findMetadata(key: string, language?: string): string { - const metadatum = this.metadata.find((m: Metadatum) => { - return m.key === key && (isEmpty(language) || m.language === language) - }); - if (isNotEmpty(metadatum)) { - return metadatum.value; - } else { - return undefined; - } + /** Gets all matching metadata in this DSpaceObject. See `Metadata.all` for more information. */ + allMetadata(keyOrKeys: string | string[], valueFilter?: MetadataValueFilter): MetadataValue[] { + return Metadata.all(this.metadata, keyOrKeys, valueFilter); } - /** - * Find metadata by an array of keys - * - * This method returns the values of the element - * in the metadata array that match the provided - * key(s) - * - * @param key(s) - * @return Array - */ - filterMetadata(keys: string[]): Metadatum[] { - return this.metadata.filter((metadatum: Metadatum) => { - return keys.some((key) => key === metadatum.key); - }); + /** Like `allMetadata`, but only returns string values. */ + allMetadataValues(keyOrKeys: string | string[], valueFilter?: MetadataValueFilter): string[] { + return Metadata.allValues(this.metadata, keyOrKeys, valueFilter); + } + + /** Gets the first matching metadata in this DSpaceObject, or `undefined`. */ + firstMetadata(keyOrKeys: string | string[], valueFilter?: MetadataValueFilter): MetadataValue { + return Metadata.first(this.metadata, keyOrKeys, valueFilter); + } + + /** Like `firstMetadata`, but only returns a string value, or `undefined`. */ + firstMetadataValue(keyOrKeys: string | string[], valueFilter?: MetadataValueFilter): string { + return Metadata.firstValue(this.metadata, keyOrKeys, valueFilter); + } + + /** Checks for matching metadata in this DSpaceObject. */ + hasMetadata(keyOrKeys: string | string[], valueFilter?: MetadataValueFilter): boolean { + return Metadata.has(this.metadata, keyOrKeys, valueFilter); } } diff --git a/src/app/core/shared/metadata.interfaces.ts b/src/app/core/shared/metadata.interfaces.ts new file mode 100644 index 00000000000..3590117ce8d --- /dev/null +++ b/src/app/core/shared/metadata.interfaces.ts @@ -0,0 +1,30 @@ +/** A map of metadata keys to an ordered list of MetadataValue objects. */ +export interface MetadataMap { + [ key: string ]: MetadataValue[]; +} + +/** A single metadata value and its properties. */ +export interface MetadataValue { + + /** The language. */ + language: string; + + /** The string value. */ + value: string; +} + +/** Constraints for matching metadata values. */ +export interface MetadataValueFilter { + + /** The language constraint. */ + language?: string; + + /** The value constraint. */ + value?: string; + + /** Whether the value constraint should match without regard to case. */ + ignoreCase?: boolean; + + /** Whether the value constraint should match as a substring. */ + substring?: boolean; +} diff --git a/src/app/core/shared/metadata.model.ts b/src/app/core/shared/metadata.model.ts new file mode 100644 index 00000000000..c774af189bf --- /dev/null +++ b/src/app/core/shared/metadata.model.ts @@ -0,0 +1,119 @@ +import { isEmpty } from '../../shared/empty.util'; +import { MetadataMap, MetadataValue, MetadataValueFilter } from './metadata.interfaces'; + +/** + * Static utility methods for working with DSpace metadata. + */ +export class Metadata { + + /** + * Gets all matching metadata. + * + * @param {MetadataMap|MetadataMap[]} mapOrMaps The source map(s). Values will only be returned from one map -- + * the first with at least one match. + * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported, so `'*'` will + * match all keys, `'dc.date.*'` will match all qualified dc dates, and so on. Exact keys will be evaluated + * (and matches returned) in the order they are given in the parameter. When multiple keys match a wildcard, + * they are evaluated in the order they are stored in the map (alphanumeric if obtained from the REST api). + * If duplicate or overlapping keys are specified, the first one takes precedence. For example, specifying + * `['dc.date', 'dc.*', '*']` will cause any `dc.date` values to be evaluated (and returned, if matched) + * first, followed by any other `dc` metadata values, followed by any other (non-dc) metadata values. + * @param {MetadataValueFilter} filter The value filter to use. + * @returns {MetadataValue[]} the matching values or an empty array. + */ + public static all(mapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[], + filter?: MetadataValueFilter): MetadataValue[] { + const mdMaps: MetadataMap[] = mapOrMaps instanceof Array ? mapOrMaps : [ mapOrMaps ]; + const matches: MetadataValue[] = []; + for (const mdMap of mdMaps) { + for (const mdKey of Metadata.resolveKeys(mdMap, keyOrKeys)) { + const candidates = mdMap[mdKey]; + if (candidates) { + for (const candidate of candidates) { + if (Metadata.valueMatches(candidate, filter)) { + matches.push(candidate); + } + } + } + } + if (!isEmpty(matches)) { + return matches; + } + } + return matches; + } + + /** Like `all`, but only returns string values. */ + public static allValues(mapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[], + filter?: MetadataValueFilter): string[] { + return Metadata.all(mapOrMaps, keyOrKeys, filter).map((mdValue) => mdValue.value); + } + + /** Gets the first matching MetadataValue object in a map, or `undefined`. */ + public static first(mdMapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[], + filter?: MetadataValueFilter): MetadataValue { + const mdMaps: MetadataMap[] = mdMapOrMaps instanceof Array ? mdMapOrMaps : [ mdMapOrMaps ]; + for (const mdMap of mdMaps) { + for (const key of Metadata.resolveKeys(mdMap, keyOrKeys)) { + const values: MetadataValue[] = mdMap[key]; + if (values) { + return values.find((value: MetadataValue) => Metadata.valueMatches(value, filter)); + } + } + } + } + + /** Like `first`, but only returns a string value, or `undefined`. */ + public static firstValue(mdMapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[], + filter?: MetadataValueFilter): string { + const value = Metadata.first(mdMapOrMaps, keyOrKeys, filter); + return value === undefined ? undefined : value.value; + } + + /** Checks the given map for a matching value. */ + public static has(mdMapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[], + filter?: MetadataValueFilter): boolean { + return Metadata.first(mdMapOrMaps, keyOrKeys, filter) !== undefined; + } + + /** Checks if a value matches a filter. */ + public static valueMatches(mdValue: MetadataValue, filter: MetadataValueFilter) { + if (!filter) { + return true; + } else if (filter.language && filter.language !== mdValue.language) { + return false; + } else if (filter.value) { + let fValue = filter.value; + let mValue = mdValue.value; + if (filter.ignoreCase) { + fValue = filter.value.toLowerCase(); + mValue = mdValue.value.toLowerCase(); + } + if (filter.substring) { + return mValue.includes(fValue); + } else { + return mValue === fValue; + } + } + return true; + } + + /** Gets the list of keys in the map limited by, and in the order given by `keyOrKeys` */ + private static resolveKeys(mdMap: MetadataMap, keyOrKeys: string | string[]): string[] { + const inputKeys: string[] = keyOrKeys instanceof Array ? keyOrKeys : [ keyOrKeys ]; + const outputKeys: string[] = []; + for (const inputKey of inputKeys) { + if (inputKey.includes('*')) { + const inputKeyRegex = new RegExp('^' + inputKey.replace('.', '\.').replace('*', '.*') + '$'); + for (const mapKey of Object.keys(mdMap)) { + if (!outputKeys.includes(mapKey) && inputKeyRegex.test(mapKey)) { + outputKeys.push(mapKey); + } + } + } else if (mdMap.hasOwnProperty(inputKey) && !outputKeys.includes(inputKey)) { + outputKeys.push(inputKey); + } + } + return outputKeys; + } +} diff --git a/src/app/core/shared/metadatum.model.ts b/src/app/core/shared/metadatum.model.ts deleted file mode 100644 index a3c5830608e..00000000000 --- a/src/app/core/shared/metadatum.model.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { autoserialize } from 'cerialize'; - -export class Metadatum { - - /** - * The metadata field of this Metadatum - */ - @autoserialize - key: string; - - /** - * The language of this Metadatum - */ - @autoserialize - language: string; - - /** - * The value of this Metadatum - */ - @autoserialize - value: string; - -} diff --git a/src/app/shared/comcol-forms/comcol-form/comcol-form.component.ts b/src/app/shared/comcol-forms/comcol-form/comcol-form.component.ts index 17710fd1c61..0e0195aaaa0 100644 --- a/src/app/shared/comcol-forms/comcol-form/comcol-form.component.ts +++ b/src/app/shared/comcol-forms/comcol-form/comcol-form.component.ts @@ -8,6 +8,7 @@ import { FormGroup } from '@angular/forms'; import { DynamicFormControlModel } from '@ng-dynamic-forms/core/src/model/dynamic-form-control.model'; import { TranslateService } from '@ngx-translate/core'; import { DSpaceObject } from '../../../core/shared/dspace-object.model'; +import { MetadataMap, MetadataValue } from '../../../core/shared/metadata.interfaces'; import { isNotEmpty } from '../../empty.util'; import { ResourceType } from '../../../core/shared/resource-type'; @@ -64,7 +65,7 @@ export class ComColFormComponent implements OnInit { ngOnInit(): void { this.formModel.forEach( (fieldModel: DynamicInputModel) => { - fieldModel.value = this.dso.findMetadata(fieldModel.name); + fieldModel.value = this.dso.firstMetadataValue(fieldModel.name); } ); this.formGroup = this.formService.createFormGroup(this.formModel); @@ -77,20 +78,24 @@ export class ComColFormComponent implements OnInit { } /** - * Checks which new fields where added and sends the updated version of the DSO to the parent component + * Checks which new fields were added and sends the updated version of the DSO to the parent component */ onSubmit() { - const metadata = this.formModel.map( - (fieldModel: DynamicInputModel) => { - return { key: fieldModel.name, value: fieldModel.value } + const formMetadata = new Object() as MetadataMap; + this.formModel.forEach((fieldModel: DynamicInputModel) => { + const value: MetadataValue = { value: fieldModel.value as string, language: null }; + if (formMetadata.hasOwnProperty(fieldModel.name)) { + formMetadata[fieldModel.name].push(value); + } else { + formMetadata[fieldModel.name] = [ value ]; } - ); - const filteredOldMetadata = this.dso.metadata.filter((filter) => !metadata.map((md) => md.key).includes(filter.key)); - const filteredNewMetadata = metadata.filter((md) => isNotEmpty(md.value)); + }); - const newMetadata = [...filteredOldMetadata, ...filteredNewMetadata]; const updatedDSO = Object.assign({}, this.dso, { - metadata: newMetadata, + metadata: { + ...this.dso.metadata, + ...formMetadata + }, type: ResourceType.Community }); this.submitForm.emit(updatedDSO); diff --git a/src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts b/src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts index 59df86fdffd..d52036b5dc5 100644 --- a/src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts +++ b/src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts @@ -1,6 +1,5 @@ import { Component, Inject } from '@angular/core'; import { ListableObject } from '../listable-object.model'; -import { hasValue } from '../../../empty.util'; @Component({ selector: 'ds-abstract-object-element', @@ -11,8 +10,4 @@ export class AbstractListableElementComponent { public constructor(@Inject('objectElementProvider') public listableObject: ListableObject) { this.object = listableObject as T; } - - hasValue(data) { - return hasValue(data); - } } diff --git a/src/app/shared/object-grid/item-grid-element/item-grid-element.component.html b/src/app/shared/object-grid/item-grid-element/item-grid-element.component.html index 728dba75496..6bb2cfa99d9 100644 --- a/src/app/shared/object-grid/item-grid-element/item-grid-element.component.html +++ b/src/app/shared/object-grid/item-grid-element/item-grid-element.component.html @@ -5,19 +5,19 @@
-

{{object.findMetadata('dc.title')}}

+

{{object.firstMetadataValue('dc.title')}}

-

- {{authorMd.value}} +

+ {{author}} ; - {{object.findMetadata("dc.date.issued")}} + {{object.firstMetadataValue("dc.date.issued")}}

-

{{object.findMetadata("dc.description.abstract") }}

+

{{object.firstMetadataValue("dc.description.abstract")}}

diff --git a/src/app/shared/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.html b/src/app/shared/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.html index 1e4f6f3c647..c7e2f524f38 100644 --- a/src/app/shared/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.html +++ b/src/app/shared/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.html @@ -8,20 +8,20 @@
-

+

-

- {{dso.findMetadata("dc.date.issued")}} - , - + {{dso.firstMetadataValue('dc.date.issued')}} + , +

- +

diff --git a/src/app/shared/object-grid/search-result-grid-element/search-result-grid-element.component.ts b/src/app/shared/object-grid/search-result-grid-element/search-result-grid-element.component.ts index 5fd1c87edd4..c3a80604dbf 100644 --- a/src/app/shared/object-grid/search-result-grid-element/search-result-grid-element.component.ts +++ b/src/app/shared/object-grid/search-result-grid-element/search-result-grid-element.component.ts @@ -2,12 +2,11 @@ import { Component, Inject } from '@angular/core'; import { SearchResult } from '../../../+search-page/search-result.model'; import { DSpaceObject } from '../../../core/shared/dspace-object.model'; -import { Metadatum } from '../../../core/shared/metadatum.model'; -import { isEmpty, hasNoValue, hasValue } from '../../empty.util'; import { AbstractListableElementComponent } from '../../object-collection/shared/object-collection-element/abstract-listable-element.component'; import { ListableObject } from '../../object-collection/shared/listable-object.model'; import { TruncatableService } from '../../truncatable/truncatable.service'; import { Observable } from 'rxjs'; +import { Metadata } from '../../../core/shared/metadata.model'; @Component({ selector: 'ds-search-result-grid-element', @@ -22,39 +21,14 @@ export class SearchResultGridElementComponent, K exten this.dso = this.object.dspaceObject; } - getValues(keys: string[]): string[] { - const results: string[] = new Array(); - this.object.hitHighlights.forEach( - (md: Metadatum) => { - if (keys.indexOf(md.key) > -1) { - results.push(md.value); - } - } - ); - if (isEmpty(results)) { - this.dso.filterMetadata(keys).forEach( - (md: Metadatum) => { - results.push(md.value); - } - ); - } - return results; + /** Gets all matching metadata string values from hitHighlights or dso metadata, preferring hitHighlights. */ + allMetadataValues(keyOrKeys: string | string[]): string[] { + return Metadata.allValues([this.object.hitHighlights, this.dso.metadata], keyOrKeys); } - getFirstValue(key: string): string { - let result: string; - this.object.hitHighlights.some( - (md: Metadatum) => { - if (key === md.key) { - result = md.value; - return true; - } - } - ); - if (hasNoValue(result)) { - result = this.dso.findMetadata(key); - } - return result; + /** Gets the first matching metadata string value from hitHighlights or dso metadata, preferring hitHighlights. */ + firstMetadataValue(keyOrKeys: string | string[]): string { + return Metadata.firstValue([this.object.hitHighlights, this.dso.metadata], keyOrKeys); } isCollapsed(): Observable { diff --git a/src/app/shared/object-list/item-list-element/item-list-element.component.html b/src/app/shared/object-list/item-list-element/item-list-element.component.html index 711ce190375..8179b776297 100644 --- a/src/app/shared/object-list/item-list-element/item-list-element.component.html +++ b/src/app/shared/object-list/item-list-element/item-list-element.component.html @@ -1,23 +1,23 @@ - {{object.findMetadata("dc.title")}} + {{object.firstMetadataValue("dc.title")}}
- - {{authorMd.value}} + {{author}} ; - ({{object.findMetadata("dc.publisher")}}, {{object.findMetadata("dc.date.issued")}}) + ({{object.firstMetadataValue("dc.publisher")}}, {{object.firstMetadataValue("dc.date.issued")}}) -
- {{object.findMetadata("dc.description.abstract")}} +
+ {{object.firstMetadataValue("dc.description.abstract")}}
diff --git a/src/app/shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component.html b/src/app/shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component.html index be549b2b76a..b4af631e83f 100644 --- a/src/app/shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component.html +++ b/src/app/shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component.html @@ -1,2 +1,2 @@ - -
+ +
diff --git a/src/app/shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component.html b/src/app/shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component.html index 150ca503cc8..9444a637715 100644 --- a/src/app/shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component.html +++ b/src/app/shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component.html @@ -1,2 +1,2 @@ - -
+ +
diff --git a/src/app/shared/object-list/search-result-list-element/item-search-result/item-search-result-list-element.component.html b/src/app/shared/object-list/search-result-list-element/item-search-result/item-search-result-list-element.component.html index 584d476e733..6261220459e 100644 --- a/src/app/shared/object-list/search-result-list-element/item-search-result/item-search-result-list-element.component.html +++ b/src/app/shared/object-list/search-result-list-element/item-search-result/item-search-result-list-element.component.html @@ -1,24 +1,24 @@ + [innerHTML]="firstMetadataValue('dc.title')"> - () - ) + - + -
+
+ [innerHTML]="firstMetadataValue('dc.description.abstract')">
- \ No newline at end of file + diff --git a/src/app/shared/object-list/search-result-list-element/search-result-list-element.component.ts b/src/app/shared/object-list/search-result-list-element/search-result-list-element.component.ts index 6a3b698dd6e..a9a3050ac8f 100644 --- a/src/app/shared/object-list/search-result-list-element/search-result-list-element.component.ts +++ b/src/app/shared/object-list/search-result-list-element/search-result-list-element.component.ts @@ -3,11 +3,10 @@ import { Observable } from 'rxjs'; import { SearchResult } from '../../../+search-page/search-result.model'; import { DSpaceObject } from '../../../core/shared/dspace-object.model'; -import { Metadatum } from '../../../core/shared/metadatum.model'; -import { hasNoValue, isEmpty } from '../../empty.util'; import { ListableObject } from '../../object-collection/shared/listable-object.model'; import { AbstractListableElementComponent } from '../../object-collection/shared/object-collection-element/abstract-listable-element.component'; import { TruncatableService } from '../../truncatable/truncatable.service'; +import { Metadata } from '../../../core/shared/metadata.model'; @Component({ selector: 'ds-search-result-list-element', @@ -22,39 +21,14 @@ export class SearchResultListElementComponent, K exten this.dso = this.object.dspaceObject; } - getValues(keys: string[]): string[] { - const results: string[] = new Array(); - this.object.hitHighlights.forEach( - (md: Metadatum) => { - if (keys.indexOf(md.key) > -1) { - results.push(md.value); - } - } - ); - if (isEmpty(results)) { - this.dso.filterMetadata(keys).forEach( - (md: Metadatum) => { - results.push(md.value); - } - ); - } - return results; + /** Gets all matching metadata string values from hitHighlights or dso metadata, preferring hitHighlights. */ + allMetadataValues(keyOrKeys: string | string[]): string[] { + return Metadata.allValues([this.object.hitHighlights, this.dso.metadata], keyOrKeys); } - getFirstValue(key: string): string { - let result: string; - this.object.hitHighlights.some( - (md: Metadatum) => { - if (key === md.key) { - result = md.value; - return true; - } - } - ); - if (hasNoValue(result)) { - result = this.dso.findMetadata(key); - } - return result; + /** Gets the first matching metadata string value from hitHighlights or dso metadata, preferring hitHighlights. */ + firstMetadataValue(keyOrKeys: string | string[]): string { + return Metadata.firstValue([this.object.hitHighlights, this.dso.metadata], keyOrKeys); } isCollapsed(): Observable { From ea9ce6194cf567b4e7522952c70388db66a1bd06 Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Sat, 22 Dec 2018 23:05:57 -0500 Subject: [PATCH 2/6] DS-4107 Update tests and mocks for metadata as map --- ...-page-sub-community-list.component.spec.ts | 44 ++-- .../modify-item-overview.component.spec.ts | 28 ++- .../collections/collections.component.spec.ts | 14 +- .../search-results.component.spec.ts | 118 +++++----- .../auth-response-parsing.service.spec.ts | 37 +-- src/app/core/browse/browse.service.spec.ts | 28 +-- .../remote-data-build.service.spec.ts | 28 ++- ...wse-items-response-parsing-service.spec.ts | 45 ++-- .../core/metadata/metadata.service.spec.ts | 21 +- .../comcol-form/comcol-form.component.spec.ts | 42 ++-- src/app/shared/mocks/mock-item.ts | 222 +++++++++--------- .../collection-grid-element.component.spec.ts | 28 ++- .../community-grid-element.component.spec.ts | 28 ++- .../item-grid-element.component.spec.ts | 50 ++-- ...arch-result-grid-element.component.spec.ts | 32 +-- ...arch-result-grid-element.component.spec.ts | 32 +-- ...arch-result-grid-element.component.spec.ts | 54 +++-- ...rowse-entry-list-element.component.spec.ts | 3 +- .../collection-list-element.component.spec.ts | 28 ++- .../community-list-element.component.spec.ts | 28 ++- .../item-list-element.component.spec.ts | 50 ++-- ...arch-result-list-element.component.spec.ts | 32 +-- ...arch-result-list-element.component.spec.ts | 32 +-- ...arch-result-list-element.component.spec.ts | 54 +++-- .../search-form/search-form.component.spec.ts | 119 +++++----- 25 files changed, 646 insertions(+), 551 deletions(-) diff --git a/src/app/+community-page/sub-community-list/community-page-sub-community-list.component.spec.ts b/src/app/+community-page/sub-community-list/community-page-sub-community-list.component.spec.ts index ace748c7dec..3e6190ae6d2 100644 --- a/src/app/+community-page/sub-community-list/community-page-sub-community-list.component.spec.ts +++ b/src/app/+community-page/sub-community-list/community-page-sub-community-list.component.spec.ts @@ -18,42 +18,38 @@ describe('SubCommunityList Component', () => { const subcommunities = [Object.assign(new Community(), { id: '123456789-1', - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'SubCommunity 1' - }] + metadata: { + 'dc.title': [ + { language: 'en_US', value: 'SubCommunity 1' } + ] + } }), Object.assign(new Community(), { id: '123456789-2', - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'SubCommunity 2' - }] + metadata: { + 'dc.title': [ + { language: 'en_US', value: 'SubCommunity 2' } + ] + } }) ]; const emptySubCommunitiesCommunity = Object.assign(new Community(), { - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'Test title' - }], + metadata: { + 'dc.title': [ + { language: 'en_US', value: 'Test title' } + ] + }, subcommunities: observableOf(new RemoteData(true, true, true, undefined, new PaginatedList(new PageInfo(), []))) }); const mockCommunity = Object.assign(new Community(), { - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'Test title' - }], + metadata: { + 'dc.title': [ + { language: 'en_US', value: 'Test title' } + ] + }, subcommunities: observableOf(new RemoteData(true, true, true, undefined, new PaginatedList(new PageInfo(), subcommunities))) }) diff --git a/src/app/+item-page/edit-item-page/modify-item-overview/modify-item-overview.component.spec.ts b/src/app/+item-page/edit-item-page/modify-item-overview/modify-item-overview.component.spec.ts index 942357dc5a1..07ad9a347ca 100644 --- a/src/app/+item-page/edit-item-page/modify-item-overview/modify-item-overview.component.spec.ts +++ b/src/app/+item-page/edit-item-page/modify-item-overview/modify-item-overview.component.spec.ts @@ -11,10 +11,14 @@ const mockItem = Object.assign(new Item(), { id: 'fake-id', handle: 'fake/handle', lastModified: '2018', - metadata: [ - {key: 'dc.title', value: 'Mock item title', language: 'en'}, - {key: 'dc.contributor.author', value: 'Mayer, Ed', language: ''} - ] + metadata: { + 'dc.title': [ + { value: 'Mock item title', language: 'en' } + ], + 'dc.contributor.author': [ + { value: 'Mayer, Ed', language: '' } + ] + } }); describe('ModifyItemOverviewComponent', () => { @@ -37,19 +41,19 @@ describe('ModifyItemOverviewComponent', () => { const metadataRows = fixture.debugElement.queryAll(By.css('tr.metadata-row')); expect(metadataRows.length).toEqual(2); - const titleRow = metadataRows[0].queryAll(By.css('td')); - expect(titleRow.length).toEqual(3); - - expect(titleRow[0].nativeElement.innerHTML).toContain('dc.title'); - expect(titleRow[1].nativeElement.innerHTML).toContain('Mock item title'); - expect(titleRow[2].nativeElement.innerHTML).toContain('en'); - - const authorRow = metadataRows[1].queryAll(By.css('td')); + const authorRow = metadataRows[0].queryAll(By.css('td')); expect(authorRow.length).toEqual(3); expect(authorRow[0].nativeElement.innerHTML).toContain('dc.contributor.author'); expect(authorRow[1].nativeElement.innerHTML).toContain('Mayer, Ed'); expect(authorRow[2].nativeElement.innerHTML).toEqual(''); + const titleRow = metadataRows[1].queryAll(By.css('td')); + expect(titleRow.length).toEqual(3); + + expect(titleRow[0].nativeElement.innerHTML).toContain('dc.title'); + expect(titleRow[1].nativeElement.innerHTML).toContain('Mock item title'); + expect(titleRow[2].nativeElement.innerHTML).toContain('en'); + }); }); diff --git a/src/app/+item-page/field-components/collections/collections.component.spec.ts b/src/app/+item-page/field-components/collections/collections.component.spec.ts index 865ce78a392..53fcded9e3e 100644 --- a/src/app/+item-page/field-components/collections/collections.component.spec.ts +++ b/src/app/+item-page/field-components/collections/collections.component.spec.ts @@ -14,12 +14,14 @@ let collectionsComponent: CollectionsComponent; let fixture: ComponentFixture; const mockCollection1: Collection = Object.assign(new Collection(), { - metadata: [ - { - key: 'dc.description.abstract', - language: 'en_US', - value: 'Short description' - }] + metadata: { + 'dc.description.abstract': [ + { + language: 'en_US', + value: 'Short description' + } + ] + } }); const succeededMockItem: Item = Object.assign(new Item(), {owningCollection: observableOf(new RemoteData(false, false, true, null, mockCollection1))}); diff --git a/src/app/+search-page/search-results/search-results.component.spec.ts b/src/app/+search-page/search-results/search-results.component.spec.ts index b7ac11553a1..8d0566d1df2 100644 --- a/src/app/+search-page/search-results/search-results.component.spec.ts +++ b/src/app/+search-page/search-results/search-results.component.spec.ts @@ -111,33 +111,38 @@ export const objects = [ id: '7669c72a-3f2a-451f-a3b9-9210e7a4c02f', uuid: '7669c72a-3f2a-451f-a3b9-9210e7a4c02f', type: ResourceType.Community, - metadata: [ - { - key: 'dc.description', - language: null, - value: '' - }, - { - key: 'dc.description.abstract', - language: null, - value: 'This is a test community to hold content for the OR2017 demostration' - }, - { - key: 'dc.description.tableofcontents', - language: null, - value: '' - }, - { - key: 'dc.rights', - language: null, - value: '' - }, - { - key: 'dc.title', - language: null, - value: 'OR2017 - Demonstration' - } - ] + metadata: { + 'dc.description': [ + { + language: null, + value: '' + } + ], + 'dc.description.abstract': [ + { + language: null, + value: 'This is a test community to hold content for the OR2017 demostration' + } + ], + 'dc.description.tableofcontents': [ + { + language: null, + value: '' + } + ], + 'dc.rights': [ + { + language: null, + value: '' + } + ], + 'dc.title': [ + { + language: null, + value: 'OR2017 - Demonstration' + } + ] + } }), Object.assign(new Community(), { @@ -160,33 +165,38 @@ export const objects = [ id: '9076bd16-e69a-48d6-9e41-0238cb40d863', uuid: '9076bd16-e69a-48d6-9e41-0238cb40d863', type: ResourceType.Community, - metadata: [ - { - key: 'dc.description', - language: null, - value: '

This is the introductory text for the Sample Community on the DSpace Demonstration Site. It is editable by System or Community Administrators (of this Community).

\r\n

DSpace Communities may contain one or more Sub-Communities or Collections (of Items).

\r\n

This particular Community has its own logo (the DuraSpace logo).

' - }, - { - key: 'dc.description.abstract', - language: null, - value: 'This is a sample top-level community' - }, - { - key: 'dc.description.tableofcontents', - language: null, - value: '

This is the news section for this Sample Community. System or Community Administrators (of this Community) can edit this News field.

' - }, - { - key: 'dc.rights', - language: null, - value: '

If this Community had special copyright text to display, it would be displayed here.

' - }, - { - key: 'dc.title', - language: null, - value: 'Sample Community' - } - ] + metadata: { + 'dc.description': [ + { + language: null, + value: '

This is the introductory text for the Sample Community on the DSpace Demonstration Site. It is editable by System or Community Administrators (of this Community).

\r\n

DSpace Communities may contain one or more Sub-Communities or Collections (of Items).

\r\n

This particular Community has its own logo (the DuraSpace logo).

' + } + ], + 'dc.description.abstract': [ + { + language: null, + value: 'This is a sample top-level community' + } + ], + 'dc.description.tableofcontents': [ + { + language: null, + value: '

This is the news section for this Sample Community. System or Community Administrators (of this Community) can edit this News field.

' + } + ], + 'dc.rights': [ + { + language: null, + value: '

If this Community had special copyright text to display, it would be displayed here.

' + } + ], + 'dc.title': [ + { + language: null, + value: 'Sample Community' + } + ] + } } ) ]; diff --git a/src/app/core/auth/auth-response-parsing.service.spec.ts b/src/app/core/auth/auth-response-parsing.service.spec.ts index a4131db4890..ee9f2e571bb 100644 --- a/src/app/core/auth/auth-response-parsing.service.spec.ts +++ b/src/app/core/auth/auth-response-parsing.service.spec.ts @@ -60,23 +60,26 @@ describe('AuthResponseParsingService', () => { handle: null, id: '4dc70ab5-cd73-492f-b007-3179d2d9296b', lastActive: '2018-05-14T17:03:31.277+0000', - metadata: [ - { - key: 'eperson.firstname', - language: null, - value: 'User' - }, - { - key: 'eperson.lastname', - language: null, - value: 'Test' - }, - { - key: 'eperson.language', - language: null, - value: 'en' - } - ], + 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, diff --git a/src/app/core/browse/browse.service.spec.ts b/src/app/core/browse/browse.service.spec.ts index da75e1a877e..1ce0f6b1566 100644 --- a/src/app/core/browse/browse.service.spec.ts +++ b/src/app/core/browse/browse.service.spec.ts @@ -219,44 +219,44 @@ describe('BrowseService', () => { }})); }); - it('should return the URL for the given metadatumKey and linkPath', () => { - const metadatumKey = 'dc.date.issued'; + it('should return the URL for the given metadataKey and linkPath', () => { + const metadataKey = 'dc.date.issued'; const linkPath = 'items'; const expectedURL = browseDefinitions[0]._links[linkPath]; - const result = service.getBrowseURLFor(metadatumKey, linkPath); + const result = service.getBrowseURLFor(metadataKey, linkPath); const expected = cold('c-d-', { c: undefined, d: expectedURL }); expect(result).toBeObservable(expected); }); - it('should work when the definition uses a wildcard in the metadatumKey', () => { - const metadatumKey = 'dc.contributor.author'; // should match dc.contributor.* in the definition + it('should work when the definition uses a wildcard in the metadataKey', () => { + const metadataKey = 'dc.contributor.author'; // should match dc.contributor.* in the definition const linkPath = 'items'; const expectedURL = browseDefinitions[1]._links[linkPath]; - const result = service.getBrowseURLFor(metadatumKey, linkPath); + const result = service.getBrowseURLFor(metadataKey, linkPath); const expected = cold('c-d-', { c: undefined, d: expectedURL }); expect(result).toBeObservable(expected); }); it('should throw an error when the key doesn\'t match', () => { - const metadatumKey = 'dc.title'; // isn't in the definitions + const metadataKey = 'dc.title'; // isn't in the definitions const linkPath = 'items'; - const result = service.getBrowseURLFor(metadatumKey, linkPath); - const expected = cold('c-#-', { c: undefined }, new Error(`A browse endpoint for ${linkPath} on ${metadatumKey} isn't configured`)); + const result = service.getBrowseURLFor(metadataKey, linkPath); + const expected = cold('c-#-', { c: undefined }, new Error(`A browse endpoint for ${linkPath} on ${metadataKey} isn't configured`)); expect(result).toBeObservable(expected); }); it('should throw an error when the link doesn\'t match', () => { - const metadatumKey = 'dc.date.issued'; + const metadataKey = 'dc.date.issued'; const linkPath = 'collections'; // isn't in the definitions - const result = service.getBrowseURLFor(metadatumKey, linkPath); - const expected = cold('c-#-', { c: undefined }, new Error(`A browse endpoint for ${linkPath} on ${metadatumKey} isn't configured`)); + const result = service.getBrowseURLFor(metadataKey, linkPath); + const expected = cold('c-#-', { c: undefined }, new Error(`A browse endpoint for ${linkPath} on ${metadataKey} isn't configured`)); expect(result).toBeObservable(expected); }); @@ -271,10 +271,10 @@ describe('BrowseService', () => { spyOn(service, 'getBrowseDefinitions').and .returnValue(hot('----')); - const metadatumKey = 'dc.date.issued'; + const metadataKey = 'dc.date.issued'; const linkPath = 'items'; - const result = service.getBrowseURLFor(metadatumKey, linkPath); + const result = service.getBrowseURLFor(metadataKey, linkPath); const expected = cold('b---', { b: undefined }); expect(result).toBeObservable(expected); }); diff --git a/src/app/core/cache/builders/remote-data-build.service.spec.ts b/src/app/core/cache/builders/remote-data-build.service.spec.ts index e4444ca8031..272969050d8 100644 --- a/src/app/core/cache/builders/remote-data-build.service.spec.ts +++ b/src/app/core/cache/builders/remote-data-build.service.spec.ts @@ -8,20 +8,24 @@ import { of as observableOf } from 'rxjs'; const pageInfo = new PageInfo(); const array = [ Object.assign(new Item(), { - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'Item nr 1' - }] + metadata: { + 'dc.title': [ + { + language: 'en_US', + value: 'Item nr 1' + } + ] + } }), Object.assign(new Item(), { - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'Item nr 2' - }] + metadata: { + 'dc.title': [ + { + language: 'en_US', + value: 'Item nr 2' + } + ] + } }) ]; const paginatedList = new PaginatedList(pageInfo, array); diff --git a/src/app/core/data/browse-items-response-parsing-service.spec.ts b/src/app/core/data/browse-items-response-parsing-service.spec.ts index 99ea474dc6e..f512a9af260 100644 --- a/src/app/core/data/browse-items-response-parsing-service.spec.ts +++ b/src/app/core/data/browse-items-response-parsing-service.spec.ts @@ -24,13 +24,14 @@ describe('BrowseItemsResponseParsingService', () => { uuid: 'd7b6bc6f-ff6c-444a-a0d3-0cd9b68043e7', name: 'Development of Local Supply Chain : A Critical Link for Concentrated Solar Power in India', handle: '10986/17472', - metadata: [ - { - key: 'dc.creator', - value: 'World Bank', - language: null - } - ], + metadata: { + 'dc.creator': [ + { + value: 'World Bank', + language: null + } + ] + }, inArchive: true, discoverable: true, withdrawn: false, @@ -56,13 +57,14 @@ describe('BrowseItemsResponseParsingService', () => { uuid: '27c6f976-257c-4ad0-a0ef-c5e34ffe4d5b', name: 'Development of Local Supply Chain : The Missing Link for Concentrated Solar Power Projects in India', handle: '10986/17475', - metadata: [ - { - key: 'dc.creator', - value: 'World Bank', - language: null - } - ], + metadata: { + 'dc.creator': [ + { + value: 'World Bank', + language: null + } + ] + }, inArchive: true, discoverable: true, withdrawn: false, @@ -115,13 +117,14 @@ describe('BrowseItemsResponseParsingService', () => { uuid: 'd7b6bc6f-ff6c-444a-a0d3-0cd9b68043e7', name: 'Development of Local Supply Chain : A Critical Link for Concentrated Solar Power in India', handle: '10986/17472', - metadata: [ - { - key: 'dc.creator', - value: 'World Bank', - language: null - } - ], + metadata: { + 'dc.creator': [ + { + value: 'World Bank', + language: null + } + ] + }, inArchive: true, discoverable: true, withdrawn: false, diff --git a/src/app/core/metadata/metadata.service.spec.ts b/src/app/core/metadata/metadata.service.spec.ts index 90c811db7a9..f2dd0770ed7 100644 --- a/src/app/core/metadata/metadata.service.spec.ts +++ b/src/app/core/metadata/metadata.service.spec.ts @@ -37,6 +37,7 @@ import { HttpClient } from '@angular/common/http'; import { EmptyError } from 'rxjs/internal-compatibility'; import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service'; import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; +import { MetadataValue } from '../shared/metadata.interfaces'; /* tslint:disable:max-classes-per-file */ @Component({ @@ -152,7 +153,7 @@ describe('MetadataService', () => { expect(title.getTitle()).toEqual('Test PowerPoint Document'); expect(tagStore.get('citation_title')[0].content).toEqual('Test PowerPoint Document'); expect(tagStore.get('citation_author')[0].content).toEqual('Doe, Jane'); - expect(tagStore.get('citation_date')[0].content).toEqual('1650-06-26T19:58:25Z'); + expect(tagStore.get('citation_date')[0].content).toEqual('1650-06-26'); expect(tagStore.get('citation_issn')[0].content).toEqual('123456789'); expect(tagStore.get('citation_language')[0].content).toEqual('en'); expect(tagStore.get('citation_keywords')[0].content).toEqual('keyword1; keyword2; keyword3'); @@ -216,22 +217,18 @@ describe('MetadataService', () => { const mockType = (mockItem: Item, type: string): Item => { const typedMockItem = Object.assign(new Item(), mockItem) as Item; - for (const metadatum of typedMockItem.metadata) { - if (metadatum.key === 'dc.type') { - metadatum.value = type; - break; - } - } + typedMockItem.metadata['dc.type'] = [ { value: type } ] as MetadataValue[]; return typedMockItem; } const mockPublisher = (mockItem: Item): Item => { const publishedMockItem = Object.assign(new Item(), mockItem) as Item; - publishedMockItem.metadata.push({ - key: 'dc.publisher', - language: 'en_US', - value: 'Mock Publisher' - }); + publishedMockItem.metadata['dc.publisher'] = [ + { + language: 'en_US', + value: 'Mock Publisher' + } + ] as MetadataValue[]; return publishedMockItem; } diff --git a/src/app/shared/comcol-forms/comcol-form/comcol-form.component.spec.ts b/src/app/shared/comcol-forms/comcol-form/comcol-form.component.spec.ts index a6f5e0d45a1..cc1e2063ffa 100644 --- a/src/app/shared/comcol-forms/comcol-form/comcol-form.component.spec.ts +++ b/src/app/shared/comcol-forms/comcol-form/comcol-form.component.spec.ts @@ -11,7 +11,6 @@ import { ResourceType } from '../../../core/shared/resource-type'; import { ComColFormComponent } from './comcol-form.component'; import { DSpaceObject } from '../../../core/shared/dspace-object.model'; import { hasValue } from '../../empty.util'; -import { Metadatum } from '../../../core/shared/metadatum.model'; describe('ComColFormComponent', () => { let comp: ComColFormComponent; @@ -29,23 +28,24 @@ describe('ComColFormComponent', () => { return undefined; } }; - const titleMD = { key: 'dc.title', value: 'Community Title' } as Metadatum; - const randomMD = { key: 'dc.random', value: 'Random metadata excluded from form' } as Metadatum; - const abstractMD = { - key: 'dc.description.abstract', - value: 'Community description' - } as Metadatum; - const newTitleMD = { key: 'dc.title', value: 'New Community Title' } as Metadatum; + const dcTitle = 'dc.title'; + const dcRandom = 'dc.random'; + const dcAbstract = 'dc.description.abstract'; + + const titleMD = { [dcTitle]: [ { value: 'Community Title', language: null } ] }; + const randomMD = { [dcRandom]: [ { value: 'Random metadata excluded from form', language: null } ] }; + const abstractMD = { [dcAbstract]: [ { value: 'Community description', language: null } ] }; + const newTitleMD = { [dcTitle]: [ { value: 'New Community Title', language: null } ] }; const formModel = [ new DynamicInputModel({ id: 'title', - name: newTitleMD.key, - value: 'New Community Title' + name: dcTitle, + value: newTitleMD[dcTitle][0].value }), new DynamicInputModel({ id: 'abstract', - name: abstractMD.key, - value: abstractMD.value + name: dcAbstract, + value: abstractMD[dcAbstract][0].value }) ]; @@ -87,10 +87,10 @@ describe('ComColFormComponent', () => { comp.dso = Object.assign( new Community(), { - metadata: [ - titleMD, - randomMD - ] + metadata: { + ...titleMD, + ...randomMD + } } ); @@ -101,11 +101,11 @@ describe('ComColFormComponent', () => { {}, new Community(), { - metadata: [ - randomMD, - newTitleMD, - abstractMD - ], + metadata: { + ...newTitleMD, + ...randomMD, + ...abstractMD + }, type: ResourceType.Community }, ) diff --git a/src/app/shared/mocks/mock-item.ts b/src/app/shared/mocks/mock-item.ts index 2e5c764ee24..98881436b9c 100644 --- a/src/app/shared/mocks/mock-item.ts +++ b/src/app/shared/mocks/mock-item.ts @@ -51,13 +51,14 @@ export const MockItem: Item = Object.assign(new Item(), { id: 'cf9b0c8e-a1eb-4b65-afd0-567366448713', uuid: 'cf9b0c8e-a1eb-4b65-afd0-567366448713', type: 'bitstream', - metadata: [ - { - key: 'dc.title', - language: null, - value: 'test_word.docx' - } - ] + metadata: { + 'dc.title': [ + { + language: null, + value: 'test_word.docx' + } + ] + } }, { sizeBytes: 31302, @@ -85,13 +86,14 @@ export const MockItem: Item = Object.assign(new Item(), { id: '99b00f3c-1cc6-4689-8158-91965bee6b28', uuid: '99b00f3c-1cc6-4689-8158-91965bee6b28', type: 'bitstream', - metadata: [ - { - key: 'dc.title', - language: null, - value: 'test_pdf.pdf' - } - ] + metadata: { + 'dc.title': [ + { + language: null, + value: 'test_pdf.pdf' + } + ] + } } ] } @@ -100,98 +102,106 @@ export const MockItem: Item = Object.assign(new Item(), { id: '0ec7ff22-f211-40ab-a69e-c819b0b1f357', uuid: '0ec7ff22-f211-40ab-a69e-c819b0b1f357', type: 'item', - metadata: [ - { - key: 'dc.creator', - language: 'en_US', - value: 'Doe, Jane' - }, - { - 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' - } - ], + metadata: { + 'dc.creator': [ + { + language: 'en_US', + value: 'Doe, Jane' + } + ], + 'dc.date.accessioned': [ + { + language: null, + value: '1650-06-26T19:58:25Z' + } + ], + 'dc.date.available': [ + { + language: null, + value: '1650-06-26T19:58:25Z' + } + ], + 'dc.date.issued': [ + { + language: null, + value: '1650-06-26' + } + ], + 'dc.identifier.issn': [ + { + language: 'en_US', + value: '123456789' + } + ], + 'dc.identifier.uri': [ + { + language: null, + value: 'http://dspace7.4science.it/xmlui/handle/10673/6' + } + ], + '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!' + } + ], + '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)' + }, + { + language: 'en', + value: 'Restored into DSpace on 2013-06-13T09:17:34Z (GMT).' + }, + { + language: 'en', + value: 'Restored into DSpace on 2013-06-13T11:04:16Z (GMT).' + }, + { + language: 'en', + value: 'Restored into DSpace on 2017-04-24T19:44:08Z (GMT).' + } + ], + 'dc.language': [ + { + language: 'en_US', + value: 'en' + } + ], + 'dc.rights': [ + { + language: 'en_US', + value: '© Jane Doe' + } + ], + 'dc.subject': [ + { + language: 'en_US', + value: 'keyword1' + }, + { + language: 'en_US', + value: 'keyword2' + }, + { + language: 'en_US', + value: 'keyword3' + } + ], + 'dc.title': [ + { + language: 'en_US', + value: 'Test PowerPoint Document' + } + ], + 'dc.type': [ + { + language: 'en_US', + value: 'text' + } + ] + }, owningCollection: observableOf({ self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/collections/1c11f3f1-ba1f-4f36-908a-3f1ea9a557eb', requestPending: false, diff --git a/src/app/shared/object-grid/collection-grid-element/collection-grid-element.component.spec.ts b/src/app/shared/object-grid/collection-grid-element/collection-grid-element.component.spec.ts index cc72ff30436..66807c6b209 100644 --- a/src/app/shared/object-grid/collection-grid-element/collection-grid-element.component.spec.ts +++ b/src/app/shared/object-grid/collection-grid-element/collection-grid-element.component.spec.ts @@ -8,21 +8,25 @@ let collectionGridElementComponent: CollectionGridElementComponent; let fixture: ComponentFixture; const mockCollectionWithAbstract: Collection = Object.assign(new Collection(), { - metadata: [ - { - key: 'dc.description.abstract', - language: 'en_US', - value: 'Short description' - }] + metadata: { + 'dc.description.abstract': [ + { + language: 'en_US', + value: 'Short description' + } + ] + } }); const mockCollectionWithoutAbstract: Collection = Object.assign(new Collection(), { - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'Test title' - }] + metadata: { + 'dc.title': [ + { + language: 'en_US', + value: 'Test title' + } + ] + } }); describe('CollectionGridElementComponent', () => { diff --git a/src/app/shared/object-grid/community-grid-element/community-grid-element.component.spec.ts b/src/app/shared/object-grid/community-grid-element/community-grid-element.component.spec.ts index dabb137ea72..bb6c81144a8 100644 --- a/src/app/shared/object-grid/community-grid-element/community-grid-element.component.spec.ts +++ b/src/app/shared/object-grid/community-grid-element/community-grid-element.component.spec.ts @@ -8,21 +8,25 @@ let communityGridElementComponent: CommunityGridElementComponent; let fixture: ComponentFixture; const mockCommunityWithAbstract: Community = Object.assign(new Community(), { - metadata: [ - { - key: 'dc.description.abstract', - language: 'en_US', - value: 'Short description' - }] + metadata: { + 'dc.description.abstract': [ + { + language: 'en_US', + value: 'Short description' + } + ] + } }); const mockCommunityWithoutAbstract: Community = Object.assign(new Community(), { - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'Test title' - }] + metadata: { + 'dc.title': [ + { + language: 'en_US', + value: 'Test title' + } + ] + } }); describe('CommunityGridElementComponent', () => { diff --git a/src/app/shared/object-grid/item-grid-element/item-grid-element.component.spec.ts b/src/app/shared/object-grid/item-grid-element/item-grid-element.component.spec.ts index f2aa5942968..7b286cc4157 100644 --- a/src/app/shared/object-grid/item-grid-element/item-grid-element.component.spec.ts +++ b/src/app/shared/object-grid/item-grid-element/item-grid-element.component.spec.ts @@ -11,31 +11,37 @@ let fixture: ComponentFixture; const mockItemWithAuthorAndDate: Item = Object.assign(new Item(), { bitstreams: observableOf({}), - metadata: [ - { - key: 'dc.contributor.author', - language: 'en_US', - value: 'Smith, Donald' - }, - { - key: 'dc.date.issued', - language: null, - value: '2015-06-26' - }] + metadata: { + 'dc.contributor.author': [ + { + language: 'en_US', + value: 'Smith, Donald' + } + ], + 'dc.date.issued': [ + { + language: null, + value: '2015-06-26' + } + ] + } }); const mockItemWithoutAuthorAndDate: Item = Object.assign(new Item(), { bitstreams: observableOf({}), - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'This is just another title' - }, - { - key: 'dc.type', - language: null, - value: 'Article' - }] + metadata: { + 'dc.title': [ + { + language: 'en_US', + value: 'This is just another title' + } + ], + 'dc.type': [ + { + language: null, + value: 'Article' + } + ] + } }); describe('ItemGridElementComponent', () => { diff --git a/src/app/shared/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.spec.ts b/src/app/shared/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.spec.ts index 8e6ff0696fe..e8f8b1330e3 100644 --- a/src/app/shared/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.spec.ts +++ b/src/app/shared/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component.spec.ts @@ -16,25 +16,29 @@ const truncatableServiceStub: any = { }; const mockCollectionWithAbstract: CollectionSearchResult = new CollectionSearchResult(); -mockCollectionWithAbstract.hitHighlights = []; +mockCollectionWithAbstract.hitHighlights = {}; mockCollectionWithAbstract.dspaceObject = Object.assign(new Collection(), { - metadata: [ - { - key: 'dc.description.abstract', - language: 'en_US', - value: 'Short description' - } ] + metadata: { + 'dc.description.abstract': [ + { + language: 'en_US', + value: 'Short description' + } + ] + } }); const mockCollectionWithoutAbstract: CollectionSearchResult = new CollectionSearchResult(); -mockCollectionWithoutAbstract.hitHighlights = []; +mockCollectionWithoutAbstract.hitHighlights = {}; mockCollectionWithoutAbstract.dspaceObject = Object.assign(new Collection(), { - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'Test title' - } ] + metadata: { + 'dc.title': [ + { + language: 'en_US', + value: 'Test title' + } + ] + } }); describe('CollectionSearchResultGridElementComponent', () => { diff --git a/src/app/shared/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.spec.ts b/src/app/shared/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.spec.ts index df8fdf026de..e111e624c59 100644 --- a/src/app/shared/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.spec.ts +++ b/src/app/shared/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component.spec.ts @@ -16,25 +16,29 @@ const truncatableServiceStub: any = { }; const mockCommunityWithAbstract: CommunitySearchResult = new CommunitySearchResult(); -mockCommunityWithAbstract.hitHighlights = []; +mockCommunityWithAbstract.hitHighlights = {}; mockCommunityWithAbstract.dspaceObject = Object.assign(new Community(), { - metadata: [ - { - key: 'dc.description.abstract', - language: 'en_US', - value: 'Short description' - } ] + metadata: { + 'dc.description.abstract': [ + { + language: 'en_US', + value: 'Short description' + } + ] + } }); const mockCommunityWithoutAbstract: CommunitySearchResult = new CommunitySearchResult(); -mockCommunityWithoutAbstract.hitHighlights = []; +mockCommunityWithoutAbstract.hitHighlights = {}; mockCommunityWithoutAbstract.dspaceObject = Object.assign(new Community(), { - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'Test title' - } ] + metadata: { + 'dc.title': [ + { + language: 'en_US', + value: 'Test title' + } + ] + } }); describe('CommunitySearchResultGridElementComponent', () => { diff --git a/src/app/shared/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.spec.ts b/src/app/shared/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.spec.ts index ecc218f11d1..0103fa5c49b 100644 --- a/src/app/shared/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.spec.ts +++ b/src/app/shared/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component.spec.ts @@ -17,37 +17,43 @@ const truncatableServiceStub: any = { }; const mockItemWithAuthorAndDate: ItemSearchResult = new ItemSearchResult(); -mockItemWithAuthorAndDate.hitHighlights = []; +mockItemWithAuthorAndDate.hitHighlights = {}; mockItemWithAuthorAndDate.dspaceObject = Object.assign(new Item(), { bitstreams: observableOf({}), - metadata: [ - { - key: 'dc.contributor.author', - language: 'en_US', - value: 'Smith, Donald' - }, - { - key: 'dc.date.issued', - language: null, - value: '2015-06-26' - }] + metadata: { + 'dc.contributor.author': [ + { + language: 'en_US', + value: 'Smith, Donald' + } + ], + 'dc.date.issued': [ + { + language: null, + value: '2015-06-26' + } + ] + } }); const mockItemWithoutAuthorAndDate: ItemSearchResult = new ItemSearchResult(); -mockItemWithoutAuthorAndDate.hitHighlights = []; +mockItemWithoutAuthorAndDate.hitHighlights = {}; mockItemWithoutAuthorAndDate.dspaceObject = Object.assign(new Item(), { bitstreams: observableOf({}), - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'This is just another title' - }, - { - key: 'dc.type', - language: null, - value: 'Article' - }] + metadata: { + 'dc.title': [ + { + language: 'en_US', + value: 'This is just another title' + } + ], + 'dc.type': [ + { + language: null, + value: 'Article' + } + ] + } }); describe('ItemSearchResultGridElementComponent', () => { diff --git a/src/app/shared/object-list/browse-entry-list-element/browse-entry-list-element.component.spec.ts b/src/app/shared/object-list/browse-entry-list-element/browse-entry-list-element.component.spec.ts index de53f2e0959..54b58e131a1 100644 --- a/src/app/shared/object-list/browse-entry-list-element/browse-entry-list-element.component.spec.ts +++ b/src/app/shared/object-list/browse-entry-list-element/browse-entry-list-element.component.spec.ts @@ -2,7 +2,6 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; import { TruncatePipe } from '../../utils/truncate.pipe'; -import { Metadatum } from '../../../core/shared/metadatum.model'; import { BrowseEntryListElementComponent } from './browse-entry-list-element.component'; import { BrowseEntry } from '../../../core/shared/browse-entry.model'; @@ -33,7 +32,7 @@ describe('MetadataListElementComponent', () => { browseEntryListElementComponent = fixture.componentInstance; })); - describe('When the metadatum is loaded', () => { + describe('When the metadata is loaded', () => { beforeEach(() => { browseEntryListElementComponent.object = mockValue; fixture.detectChanges(); diff --git a/src/app/shared/object-list/collection-list-element/collection-list-element.component.spec.ts b/src/app/shared/object-list/collection-list-element/collection-list-element.component.spec.ts index a31af1e50cc..bde6b4b97a1 100644 --- a/src/app/shared/object-list/collection-list-element/collection-list-element.component.spec.ts +++ b/src/app/shared/object-list/collection-list-element/collection-list-element.component.spec.ts @@ -8,21 +8,25 @@ let collectionListElementComponent: CollectionListElementComponent; let fixture: ComponentFixture; const mockCollectionWithAbstract: Collection = Object.assign(new Collection(), { - metadata: [ - { - key: 'dc.description.abstract', - language: 'en_US', - value: 'Short description' - }] + metadata: { + 'dc.description.abstract': [ + { + language: 'en_US', + value: 'Short description' + } + ] + } }); const mockCollectionWithoutAbstract: Collection = Object.assign(new Collection(), { - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'Test title' - }] + metadata: { + 'dc.title': [ + { + language: 'en_US', + value: 'Test title' + } + ] + } }); describe('CollectionListElementComponent', () => { diff --git a/src/app/shared/object-list/community-list-element/community-list-element.component.spec.ts b/src/app/shared/object-list/community-list-element/community-list-element.component.spec.ts index 08147d85738..46ba27eb00d 100644 --- a/src/app/shared/object-list/community-list-element/community-list-element.component.spec.ts +++ b/src/app/shared/object-list/community-list-element/community-list-element.component.spec.ts @@ -8,21 +8,25 @@ let communityListElementComponent: CommunityListElementComponent; let fixture: ComponentFixture; const mockCommunityWithAbstract: Community = Object.assign(new Community(), { - metadata: [ - { - key: 'dc.description.abstract', - language: 'en_US', - value: 'Short description' - }] + metadata: { + 'dc.description.abstract': [ + { + language: 'en_US', + value: 'Short description' + } + ] + } }); const mockCommunityWithoutAbstract: Community = Object.assign(new Community(), { - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'Test title' - }] + metadata: { + 'dc.title': [ + { + language: 'en_US', + value: 'Test title' + } + ] + } }); describe('CommunityListElementComponent', () => { diff --git a/src/app/shared/object-list/item-list-element/item-list-element.component.spec.ts b/src/app/shared/object-list/item-list-element/item-list-element.component.spec.ts index 64108fd5b03..392d81bee44 100644 --- a/src/app/shared/object-list/item-list-element/item-list-element.component.spec.ts +++ b/src/app/shared/object-list/item-list-element/item-list-element.component.spec.ts @@ -11,31 +11,37 @@ let fixture: ComponentFixture; const mockItemWithAuthorAndDate: Item = Object.assign(new Item(), { bitstreams: observableOf({}), - metadata: [ - { - key: 'dc.contributor.author', - language: 'en_US', - value: 'Smith, Donald' - }, - { - key: 'dc.date.issued', - language: null, - value: '2015-06-26' - }] + metadata: { + 'dc.contributor.author': [ + { + language: 'en_US', + value: 'Smith, Donald' + } + ], + 'dc.date.issued': [ + { + language: null, + value: '2015-06-26' + } + ] + } }); const mockItemWithoutAuthorAndDate: Item = Object.assign(new Item(), { bitstreams: observableOf({}), - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'This is just another title' - }, - { - key: 'dc.type', - language: null, - value: 'Article' - }] + metadata: { + 'dc.title': [ + { + language: 'en_US', + value: 'This is just another title' + } + ], + 'dc.type': [ + { + language: null, + value: 'Article' + } + ] + } }); describe('ItemListElementComponent', () => { diff --git a/src/app/shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component.spec.ts b/src/app/shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component.spec.ts index 2ffaf38b535..e897071a001 100644 --- a/src/app/shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component.spec.ts +++ b/src/app/shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component.spec.ts @@ -16,25 +16,29 @@ const truncatableServiceStub: any = { }; const mockCollectionWithAbstract: CollectionSearchResult = new CollectionSearchResult(); -mockCollectionWithAbstract.hitHighlights = []; +mockCollectionWithAbstract.hitHighlights = {}; mockCollectionWithAbstract.dspaceObject = Object.assign(new Collection(), { - metadata: [ - { - key: 'dc.description.abstract', - language: 'en_US', - value: 'Short description' - } ] + metadata: { + 'dc.description.abstract': [ + { + language: 'en_US', + value: 'Short description' + } + ] + } }); const mockCollectionWithoutAbstract: CollectionSearchResult = new CollectionSearchResult(); -mockCollectionWithoutAbstract.hitHighlights = []; +mockCollectionWithoutAbstract.hitHighlights = {}; mockCollectionWithoutAbstract.dspaceObject = Object.assign(new Collection(), { - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'Test title' - } ] + metadata: { + 'dc.title': [ + { + language: 'en_US', + value: 'Test title' + } + ] + } }); describe('CollectionSearchResultListElementComponent', () => { diff --git a/src/app/shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component.spec.ts b/src/app/shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component.spec.ts index 70877d0744a..75d5966767e 100644 --- a/src/app/shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component.spec.ts +++ b/src/app/shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component.spec.ts @@ -16,25 +16,29 @@ const truncatableServiceStub: any = { }; const mockCommunityWithAbstract: CommunitySearchResult = new CommunitySearchResult(); -mockCommunityWithAbstract.hitHighlights = []; +mockCommunityWithAbstract.hitHighlights = {}; mockCommunityWithAbstract.dspaceObject = Object.assign(new Community(), { - metadata: [ - { - key: 'dc.description.abstract', - language: 'en_US', - value: 'Short description' - } ] + metadata: { + 'dc.description.abstract': [ + { + language: 'en_US', + value: 'Short description' + } + ] + } }); const mockCommunityWithoutAbstract: CommunitySearchResult = new CommunitySearchResult(); -mockCommunityWithoutAbstract.hitHighlights = []; +mockCommunityWithoutAbstract.hitHighlights = {}; mockCommunityWithoutAbstract.dspaceObject = Object.assign(new Community(), { - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'Test title' - } ] + metadata: { + 'dc.title': [ + { + language: 'en_US', + value: 'Test title' + } + ] + } }); describe('CommunitySearchResultListElementComponent', () => { diff --git a/src/app/shared/object-list/search-result-list-element/item-search-result/item-search-result-list-element.component.spec.ts b/src/app/shared/object-list/search-result-list-element/item-search-result/item-search-result-list-element.component.spec.ts index bdc8ebcecfb..8567fc17825 100644 --- a/src/app/shared/object-list/search-result-list-element/item-search-result/item-search-result-list-element.component.spec.ts +++ b/src/app/shared/object-list/search-result-list-element/item-search-result/item-search-result-list-element.component.spec.ts @@ -17,37 +17,43 @@ const truncatableServiceStub: any = { }; const mockItemWithAuthorAndDate: ItemSearchResult = new ItemSearchResult(); -mockItemWithAuthorAndDate.hitHighlights = []; +mockItemWithAuthorAndDate.hitHighlights = {}; mockItemWithAuthorAndDate.dspaceObject = Object.assign(new Item(), { bitstreams: observableOf({}), - metadata: [ - { - key: 'dc.contributor.author', - language: 'en_US', - value: 'Smith, Donald' - }, - { - key: 'dc.date.issued', - language: null, - value: '2015-06-26' - }] + metadata: { + 'dc.contributor.author': [ + { + language: 'en_US', + value: 'Smith, Donald' + } + ], + 'dc.date.issued': [ + { + language: null, + value: '2015-06-26' + } + ] + } }); const mockItemWithoutAuthorAndDate: ItemSearchResult = new ItemSearchResult(); -mockItemWithoutAuthorAndDate.hitHighlights = []; +mockItemWithoutAuthorAndDate.hitHighlights = {}; mockItemWithoutAuthorAndDate.dspaceObject = Object.assign(new Item(), { bitstreams: observableOf({}), - metadata: [ - { - key: 'dc.title', - language: 'en_US', - value: 'This is just another title' - }, - { - key: 'dc.type', - language: null, - value: 'Article' - }] + metadata: { + 'dc.title': [ + { + language: 'en_US', + value: 'This is just another title' + } + ], + 'dc.type': [ + { + language: null, + value: 'Article' + } + ] + } }); describe('ItemSearchResultListElementComponent', () => { diff --git a/src/app/shared/search-form/search-form.component.spec.ts b/src/app/shared/search-form/search-form.component.spec.ts index 004d0c5b214..b164abee1ff 100644 --- a/src/app/shared/search-form/search-form.component.spec.ts +++ b/src/app/shared/search-form/search-form.component.spec.ts @@ -30,6 +30,7 @@ describe('SearchFormComponent', () => { }); it('should display scopes when available with default and all scopes', () => { + comp.scopes = objects; fixture.detectChanges(); const select: HTMLElement = de.query(By.css('select')).nativeElement; @@ -121,33 +122,38 @@ export const objects: DSpaceObject[] = [ id: '7669c72a-3f2a-451f-a3b9-9210e7a4c02f', uuid: '7669c72a-3f2a-451f-a3b9-9210e7a4c02f', type: ResourceType.Community, - metadata: [ - { - key: 'dc.description', - language: null, - value: '' - }, - { - key: 'dc.description.abstract', - language: null, - value: 'This is a test community to hold content for the OR2017 demostration' - }, - { - key: 'dc.description.tableofcontents', - language: null, - value: '' - }, - { - key: 'dc.rights', - language: null, - value: '' - }, - { - key: 'dc.title', - language: null, - value: 'OR2017 - Demonstration' - } - ] + metadata: { + 'dc.description': [ + { + language: null, + value: '' + } + ], + 'dc.description.abstract': [ + { + language: null, + value: 'This is a test community to hold content for the OR2017 demostration' + } + ], + 'dc.description.tableofcontents': [ + { + language: null, + value: '' + } + ], + 'dc.rights': [ + { + language: null, + value: '' + } + ], + 'dc.title': [ + { + language: null, + value: 'OR2017 - Demonstration' + } + ] + } }), Object.assign(new Community(), { @@ -170,33 +176,38 @@ export const objects: DSpaceObject[] = [ id: '9076bd16-e69a-48d6-9e41-0238cb40d863', uuid: '9076bd16-e69a-48d6-9e41-0238cb40d863', type: ResourceType.Community, - metadata: [ - { - key: 'dc.description', - language: null, - value: '

This is the introductory text for the Sample Community on the DSpace Demonstration Site. It is editable by System or Community Administrators (of this Community).

\r\n

DSpace Communities may contain one or more Sub-Communities or Collections (of Items).

\r\n

This particular Community has its own logo (the DuraSpace logo).

' - }, - { - key: 'dc.description.abstract', - language: null, - value: 'This is a sample top-level community' - }, - { - key: 'dc.description.tableofcontents', - language: null, - value: '

This is the news section for this Sample Community. System or Community Administrators (of this Community) can edit this News field.

' - }, - { - key: 'dc.rights', - language: null, - value: '

If this Community had special copyright text to display, it would be displayed here.

' - }, - { - key: 'dc.title', - language: null, - value: 'Sample Community' - } - ] + metadata: { + 'dc.description': [ + { + language: null, + value: '

This is the introductory text for the Sample Community on the DSpace Demonstration Site. It is editable by System or Community Administrators (of this Community).

\r\n

DSpace Communities may contain one or more Sub-Communities or Collections (of Items).

\r\n

This particular Community has its own logo (the DuraSpace logo).

' + } + ], + 'dc.description.abstract': [ + { + language: null, + value: 'This is a sample top-level community' + } + ], + 'dc.description.tableofcontents': [ + { + language: null, + value: '

This is the news section for this Sample Community. System or Community Administrators (of this Community) can edit this News field.

' + } + ], + 'dc.rights': [ + { + language: null, + value: '

If this Community had special copyright text to display, it would be displayed here.

' + } + ], + 'dc.title': [ + { + language: null, + value: 'Sample Community' + } + ] + } } ) ]; From 6474cbfafbf9a5859ad22eae474fd343feda8cc4 Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Sat, 22 Dec 2018 23:08:00 -0500 Subject: [PATCH 3/6] DS-4107 Add tests for Metadata utility methods --- src/app/core/shared/metadata.model.spec.ts | 174 +++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 src/app/core/shared/metadata.model.spec.ts diff --git a/src/app/core/shared/metadata.model.spec.ts b/src/app/core/shared/metadata.model.spec.ts new file mode 100644 index 00000000000..8f44dee5fd9 --- /dev/null +++ b/src/app/core/shared/metadata.model.spec.ts @@ -0,0 +1,174 @@ +import { MetadataValue, MetadataValueFilter } from './metadata.interfaces'; +import { Metadata } from './metadata.model'; + +const mdValue = (value: string, language?: string): MetadataValue => { + return { value: value, language: language === undefined ? null : language }; +} + +const dcDescription = mdValue('Some description'); +const dcAbstract = mdValue('Some abstract'); +const dcTitle0 = mdValue('Title 0'); +const dcTitle1 = mdValue('Title 1'); +const dcTitle2 = mdValue('Title 2', 'en_US'); +const bar = mdValue('Bar'); + +const singleMap = { 'dc.title': [ dcTitle0 ] }; + +const multiMap = { + 'dc.description': [ dcDescription ], + 'dc.description.abstract': [ dcAbstract ], + 'dc.title': [ dcTitle1, dcTitle2 ], + 'foo': [ bar ] +}; + +const testMethod = (fn, resultKind, mapOrMaps, keyOrKeys, expected, filter?) => { + const keys = keyOrKeys instanceof Array ? keyOrKeys : [ keyOrKeys ]; + describe('and key' + (keys.length === 1 ? (' ' + keys[0]) : ('s ' + JSON.stringify(keys))) + + ' with ' + (filter === undefined ? 'no filter' : 'filter ' + JSON.stringify(filter)), () => { + const result = fn(mapOrMaps, keys, filter); + let shouldReturn; + if (resultKind === 'boolean') { + shouldReturn = expected; + } else if (expected === undefined) { + shouldReturn = 'undefined'; + } else if (expected instanceof Array) { + shouldReturn = 'an array with ' + expected.length + ' ' + (expected.length > 1 ? 'ordered ' : '') + + resultKind + (expected.length !== 1 ? 's' : ''); + } else { + shouldReturn = 'a ' + resultKind; + } + it('should return ' + shouldReturn, () => { + expect(result).toEqual(expected); + }); + }) +}; + +describe('Metadata', () => { + + describe('all method', () => { + + const testAll = (mapOrMaps, keyOrKeys, expected, filter?: MetadataValueFilter) => + testMethod(Metadata.all, 'value', mapOrMaps, keyOrKeys, expected, filter); + + describe('with emptyMap', () => { + testAll({}, 'foo', []); + testAll({}, '*', []); + }); + describe('with singleMap', () => { + testAll(singleMap, 'foo', []); + testAll(singleMap, '*', [ dcTitle0 ]); + testAll(singleMap, '*', [], { value: 'baz' }); + testAll(singleMap, 'dc.title', [ dcTitle0 ]); + testAll(singleMap, 'dc.*', [ dcTitle0 ]); + }); + describe('with multiMap', () => { + testAll(multiMap, 'foo', [ bar ]); + testAll(multiMap, '*', [ dcDescription, dcAbstract, dcTitle1, dcTitle2, bar ]); + testAll(multiMap, 'dc.title', [ dcTitle1, dcTitle2 ]); + testAll(multiMap, 'dc.*', [ dcDescription, dcAbstract, dcTitle1, dcTitle2 ]); + testAll(multiMap, [ 'dc.title', 'dc.*' ], [ dcTitle1, dcTitle2, dcDescription, dcAbstract ]); + }); + describe('with [ singleMap, multiMap ]', () => { + testAll([ singleMap, multiMap ], 'foo', [ bar ]); + testAll([ singleMap, multiMap ], '*', [ dcTitle0 ]); + testAll([ singleMap, multiMap ], 'dc.title', [ dcTitle0 ]); + testAll([ singleMap, multiMap ], 'dc.*', [ dcTitle0 ]); + }); + describe('with [ multiMap, singleMap ]', () => { + testAll([ multiMap, singleMap ], 'foo', [ bar ]); + testAll([ multiMap, singleMap ], '*', [ dcDescription, dcAbstract, dcTitle1, dcTitle2, bar ]); + testAll([ multiMap, singleMap ], 'dc.title', [ dcTitle1, dcTitle2 ]); + testAll([ multiMap, singleMap ], 'dc.*', [ dcDescription, dcAbstract, dcTitle1, dcTitle2 ]); + testAll([ multiMap, singleMap ], [ 'dc.title', 'dc.*' ], [ dcTitle1, dcTitle2, dcDescription, dcAbstract ]); + }); + }); + + describe('allValues method', () => { + + const testAllValues = (mapOrMaps, keyOrKeys, expected) => + testMethod(Metadata.allValues, 'string', mapOrMaps, keyOrKeys, expected); + + describe('with emptyMap', () => { + testAllValues({}, '*', []); + }); + describe('with singleMap', () => { + testAllValues([ singleMap, multiMap ], '*', [ dcTitle0.value ]); + }); + describe('with [ multiMap, singleMap ]', () => { + testAllValues([ multiMap, singleMap ], '*', [ dcDescription.value, dcAbstract.value, dcTitle1.value, dcTitle2.value, bar.value ]); + }); + }); + + describe('first method', () => { + + const testFirst = (mapOrMaps, keyOrKeys, expected) => + testMethod(Metadata.first, 'value', mapOrMaps, keyOrKeys, expected); + + describe('with emptyMap', () => { + testFirst({}, '*', undefined); + }); + describe('with singleMap', () => { + testFirst(singleMap, '*', dcTitle0); + }); + describe('with [ multiMap, singleMap ]', () => { + testFirst([ multiMap, singleMap ], '*', dcDescription); + }); + }); + + describe('firstValue method', () => { + + const testFirstValue = (mapOrMaps, keyOrKeys, expected) => + testMethod(Metadata.firstValue, 'value', mapOrMaps, keyOrKeys, expected); + + describe('with emptyMap', () => { + testFirstValue({}, '*', undefined); + }); + describe('with singleMap', () => { + testFirstValue(singleMap, '*', dcTitle0.value); + }); + describe('with [ multiMap, singleMap ]', () => { + testFirstValue([ multiMap, singleMap ], '*', dcDescription.value); + }); + }); + + describe('has method', () => { + + const testHas = (mapOrMaps, keyOrKeys, expected, filter?: MetadataValueFilter) => + testMethod(Metadata.has, 'boolean', mapOrMaps, keyOrKeys, expected, filter); + + describe('with emptyMap', () => { + testHas({}, '*', false); + }); + describe('with singleMap', () => { + testHas(singleMap, '*', true); + testHas(singleMap, '*', false, { value: 'baz' }); + }); + describe('with [ multiMap, singleMap ]', () => { + testHas([ multiMap, singleMap ], '*', true); + }); + }); + + describe('valueMatches method', () => { + + const testValueMatches = (value: MetadataValue, expected: boolean, filter?: MetadataValueFilter) => { + describe('with value ' + JSON.stringify(value) + ' and filter ' + + (filter === undefined ? 'undefined' : JSON.stringify(filter)), () => { + const result = Metadata.valueMatches(value, filter); + it('should return ' + expected, () => { + expect(result).toEqual(expected); + }); + }); + }; + + testValueMatches(mdValue('a'), true); + testValueMatches(mdValue('a'), true, { value: 'a' }); + testValueMatches(mdValue('a'), false, { value: 'A' }); + testValueMatches(mdValue('a'), true, { value: 'A', ignoreCase: true }); + testValueMatches(mdValue('ab'), false, { value: 'b' }); + testValueMatches(mdValue('ab'), true, { value: 'b', substring: true }); + testValueMatches(mdValue('a'), true, { language: null }); + testValueMatches(mdValue('a'), false, { language: 'en_US' }); + testValueMatches(mdValue('a', 'en_US'), true, { language: 'en_US' }); + }); + +}); From 4c8747a3455026b9ec363a7935d26e99d6e78b4c Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Thu, 14 Feb 2019 14:46:27 -0500 Subject: [PATCH 4/6] DS-4107 Improve TypeDocs --- src/app/core/browse/browse.service.ts | 3 + src/app/core/shared/dspace-object.model.ts | 40 ++++++++-- src/app/core/shared/metadata.model.ts | 80 ++++++++++++++----- .../search-result-grid-element.component.ts | 14 +++- .../search-result-list-element.component.ts | 14 +++- 5 files changed, 124 insertions(+), 27 deletions(-) diff --git a/src/app/core/browse/browse.service.ts b/src/app/core/browse/browse.service.ts index 41675632dd7..f0d8935b5c8 100644 --- a/src/app/core/browse/browse.service.ts +++ b/src/app/core/browse/browse.service.ts @@ -34,6 +34,9 @@ import { URLCombiner } from '../url-combiner/url-combiner'; import { Item } from '../shared/item.model'; import { DSpaceObject } from '../shared/dspace-object.model'; +/** + * Service that performs all actions that have to do with browse. + */ @Injectable() export class BrowseService { protected linkPath = 'browses'; diff --git a/src/app/core/shared/dspace-object.model.ts b/src/app/core/shared/dspace-object.model.ts index 1dba79865fb..edd82eca853 100644 --- a/src/app/core/shared/dspace-object.model.ts +++ b/src/app/core/shared/dspace-object.model.ts @@ -54,27 +54,57 @@ export class DSpaceObject implements CacheableObject, ListableObject { */ owner: Observable>; - /** Gets all matching metadata in this DSpaceObject. See `Metadata.all` for more information. */ + /** + * Gets all matching metadata in this DSpaceObject. + * + * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see [[Metadata]]. + * @param {MetadataValueFilter} filter The value filter to use. If unspecified, no filtering will be done. + * @returns {MetadataValue[]} the matching values or an empty array. + */ allMetadata(keyOrKeys: string | string[], valueFilter?: MetadataValueFilter): MetadataValue[] { return Metadata.all(this.metadata, keyOrKeys, valueFilter); } - /** Like `allMetadata`, but only returns string values. */ + /** + * Like [[allMetadata]], but only returns string values. + * + * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see [[Metadata]]. + * @param {MetadataValueFilter} filter The value filter to use. If unspecified, no filtering will be done. + * @returns {string[]} the matching string values or an empty array. + */ allMetadataValues(keyOrKeys: string | string[], valueFilter?: MetadataValueFilter): string[] { return Metadata.allValues(this.metadata, keyOrKeys, valueFilter); } - /** Gets the first matching metadata in this DSpaceObject, or `undefined`. */ + /** + * Gets the first matching MetadataValue object in this DSpaceObject, or `undefined`. + * + * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see [[Metadata]]. + * @param {MetadataValueFilter} filter The value filter to use. If unspecified, no filtering will be done. + * @returns {MetadataValue} the first matching value, or `undefined`. + */ firstMetadata(keyOrKeys: string | string[], valueFilter?: MetadataValueFilter): MetadataValue { return Metadata.first(this.metadata, keyOrKeys, valueFilter); } - /** Like `firstMetadata`, but only returns a string value, or `undefined`. */ + /** + * Like [[firstMetadata]], but only returns a string value, or `undefined`. + * + * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see [[Metadata]]. + * @param {MetadataValueFilter} filter The value filter to use. If unspecified, no filtering will be done. + * @returns {string} the first matching string value, or `undefined`. + */ firstMetadataValue(keyOrKeys: string | string[], valueFilter?: MetadataValueFilter): string { return Metadata.firstValue(this.metadata, keyOrKeys, valueFilter); } - /** Checks for matching metadata in this DSpaceObject. */ + /** + * Checks for a matching metadata value in this DSpaceObject. + * + * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see [[Metadata]]. + * @param {MetadataValueFilter} filter The value filter to use. If unspecified, no filtering will be done. + * @returns {boolean} whether a match is found. + */ hasMetadata(keyOrKeys: string | string[], valueFilter?: MetadataValueFilter): boolean { return Metadata.has(this.metadata, keyOrKeys, valueFilter); } diff --git a/src/app/core/shared/metadata.model.ts b/src/app/core/shared/metadata.model.ts index c774af189bf..c64827ffdb1 100644 --- a/src/app/core/shared/metadata.model.ts +++ b/src/app/core/shared/metadata.model.ts @@ -2,23 +2,27 @@ import { isEmpty } from '../../shared/empty.util'; import { MetadataMap, MetadataValue, MetadataValueFilter } from './metadata.interfaces'; /** - * Static utility methods for working with DSpace metadata. + * Utility class for working with DSpace object metadata. + * + * When specifying metadata keys, wildcards are supported, so `'*'` will match all keys, `'dc.date.*'` will + * match all qualified dc dates, and so on. Exact keys will be evaluated (and matches returned) in the order + * they are given. + * + * When multiple keys in a map match a given wildcard, they are evaluated in the order they are stored in + * the map (alphanumeric if obtained from the REST api). If duplicate or overlapping keys are specified, the + * first one takes precedence. For example, specifying `['dc.date', 'dc.*', '*']` will cause any `dc.date` + * values to be evaluated (and returned, if matched) first, followed by any other `dc` metadata values, + * followed by any other (non-dc) metadata values. */ export class Metadata { /** - * Gets all matching metadata. + * Gets all matching metadata in the map(s). * - * @param {MetadataMap|MetadataMap[]} mapOrMaps The source map(s). Values will only be returned from one map -- - * the first with at least one match. - * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported, so `'*'` will - * match all keys, `'dc.date.*'` will match all qualified dc dates, and so on. Exact keys will be evaluated - * (and matches returned) in the order they are given in the parameter. When multiple keys match a wildcard, - * they are evaluated in the order they are stored in the map (alphanumeric if obtained from the REST api). - * If duplicate or overlapping keys are specified, the first one takes precedence. For example, specifying - * `['dc.date', 'dc.*', '*']` will cause any `dc.date` values to be evaluated (and returned, if matched) - * first, followed by any other `dc` metadata values, followed by any other (non-dc) metadata values. - * @param {MetadataValueFilter} filter The value filter to use. + * @param {MetadataMap|MetadataMap[]} mapOrMaps The source map(s). When multiple maps are given, they will be + * checked in order, and only values from the first with at least one match will be returned. + * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see above. + * @param {MetadataValueFilter} filter The value filter to use. If unspecified, no filtering will be done. * @returns {MetadataValue[]} the matching values or an empty array. */ public static all(mapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[], @@ -43,13 +47,28 @@ export class Metadata { return matches; } - /** Like `all`, but only returns string values. */ + /** + * Like [[Metadata.all]], but only returns string values. + * + * @param {MetadataMap|MetadataMap[]} mapOrMaps The source map(s). When multiple maps are given, they will be + * checked in order, and only values from the first with at least one match will be returned. + * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see above. + * @param {MetadataValueFilter} filter The value filter to use. If unspecified, no filtering will be done. + * @returns {string[]} the matching string values or an empty array. + */ public static allValues(mapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[], filter?: MetadataValueFilter): string[] { return Metadata.all(mapOrMaps, keyOrKeys, filter).map((mdValue) => mdValue.value); } - /** Gets the first matching MetadataValue object in a map, or `undefined`. */ + /** + * Gets the first matching MetadataValue object in the map(s), or `undefined`. + * + * @param {MetadataMap|MetadataMap[]} mapOrMaps The source map(s). + * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see above. + * @param {MetadataValueFilter} filter The value filter to use. If unspecified, no filtering will be done. + * @returns {MetadataValue} the first matching value, or `undefined`. + */ public static first(mdMapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[], filter?: MetadataValueFilter): MetadataValue { const mdMaps: MetadataMap[] = mdMapOrMaps instanceof Array ? mdMapOrMaps : [ mdMapOrMaps ]; @@ -63,20 +82,40 @@ export class Metadata { } } - /** Like `first`, but only returns a string value, or `undefined`. */ + /** + * Like [[Metadata.first]], but only returns a string value, or `undefined`. + * + * @param {MetadataMap|MetadataMap[]} mapOrMaps The source map(s). + * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see above. + * @param {MetadataValueFilter} filter The value filter to use. If unspecified, no filtering will be done. + * @returns {string} the first matching string value, or `undefined`. + */ public static firstValue(mdMapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[], filter?: MetadataValueFilter): string { const value = Metadata.first(mdMapOrMaps, keyOrKeys, filter); return value === undefined ? undefined : value.value; } - /** Checks the given map for a matching value. */ + /** + * Checks for a matching metadata value in the given map(s). + * + * @param {MetadataMap|MetadataMap[]} mapOrMaps The source map(s). + * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see above. + * @param {MetadataValueFilter} filter The value filter to use. If unspecified, no filtering will be done. + * @returns {boolean} whether a match is found. + */ public static has(mdMapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[], filter?: MetadataValueFilter): boolean { return Metadata.first(mdMapOrMaps, keyOrKeys, filter) !== undefined; } - /** Checks if a value matches a filter. */ + /** + * Checks if a value matches a filter. + * + * @param {MetadataValue} mdValue the value to check. + * @param {MetadataValueFilter} filter the filter to use. + * @returns {boolean} whether the filter matches, or true if no filter is given. + */ public static valueMatches(mdValue: MetadataValue, filter: MetadataValueFilter) { if (!filter) { return true; @@ -98,7 +137,12 @@ export class Metadata { return true; } - /** Gets the list of keys in the map limited by, and in the order given by `keyOrKeys` */ + /** + * Gets the list of keys in the map limited by, and in the order given by `keyOrKeys`. + * + * @param {MetadataMap} mdMap The source map. + * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see above. + */ private static resolveKeys(mdMap: MetadataMap, keyOrKeys: string | string[]): string[] { const inputKeys: string[] = keyOrKeys instanceof Array ? keyOrKeys : [ keyOrKeys ]; const outputKeys: string[] = []; diff --git a/src/app/shared/object-grid/search-result-grid-element/search-result-grid-element.component.ts b/src/app/shared/object-grid/search-result-grid-element/search-result-grid-element.component.ts index c3a80604dbf..0901b7b8cc4 100644 --- a/src/app/shared/object-grid/search-result-grid-element/search-result-grid-element.component.ts +++ b/src/app/shared/object-grid/search-result-grid-element/search-result-grid-element.component.ts @@ -21,12 +21,22 @@ export class SearchResultGridElementComponent, K exten this.dso = this.object.dspaceObject; } - /** Gets all matching metadata string values from hitHighlights or dso metadata, preferring hitHighlights. */ + /** + * Gets all matching metadata string values from hitHighlights or dso metadata, preferring hitHighlights. + * + * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see [[Metadata]]. + * @returns {string[]} the matching string values or an empty array. + */ allMetadataValues(keyOrKeys: string | string[]): string[] { return Metadata.allValues([this.object.hitHighlights, this.dso.metadata], keyOrKeys); } - /** Gets the first matching metadata string value from hitHighlights or dso metadata, preferring hitHighlights. */ + /** + * Gets the first matching metadata string value from hitHighlights or dso metadata, preferring hitHighlights. + * + * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see [[Metadata]]. + * @returns {string} the first matching string value, or `undefined`. + */ firstMetadataValue(keyOrKeys: string | string[]): string { return Metadata.firstValue([this.object.hitHighlights, this.dso.metadata], keyOrKeys); } diff --git a/src/app/shared/object-list/search-result-list-element/search-result-list-element.component.ts b/src/app/shared/object-list/search-result-list-element/search-result-list-element.component.ts index a9a3050ac8f..2a16b0b7545 100644 --- a/src/app/shared/object-list/search-result-list-element/search-result-list-element.component.ts +++ b/src/app/shared/object-list/search-result-list-element/search-result-list-element.component.ts @@ -21,12 +21,22 @@ export class SearchResultListElementComponent, K exten this.dso = this.object.dspaceObject; } - /** Gets all matching metadata string values from hitHighlights or dso metadata, preferring hitHighlights. */ + /** + * Gets all matching metadata string values from hitHighlights or dso metadata, preferring hitHighlights. + * + * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see [[Metadata]]. + * @returns {string[]} the matching string values or an empty array. + */ allMetadataValues(keyOrKeys: string | string[]): string[] { return Metadata.allValues([this.object.hitHighlights, this.dso.metadata], keyOrKeys); } - /** Gets the first matching metadata string value from hitHighlights or dso metadata, preferring hitHighlights. */ + /** + * Gets the first matching metadata string value from hitHighlights or dso metadata, preferring hitHighlights. + * + * @param {string|string[]} keyOrKeys The metadata key(s) in scope. Wildcards are supported; see [[Metadata]]. + * @returns {string} the first matching string value, or `undefined`. + */ firstMetadataValue(keyOrKeys: string | string[]): string { return Metadata.firstValue([this.object.hitHighlights, this.dso.metadata], keyOrKeys); } From e499f792e87b26ace299fecc3f0e501843062778 Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Thu, 14 Feb 2019 14:52:43 -0500 Subject: [PATCH 5/6] DS-4107 Use isUndefined and isNotUndefined where appropriate --- src/app/core/shared/metadata.model.spec.ts | 9 +++++---- src/app/core/shared/metadata.model.ts | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/app/core/shared/metadata.model.spec.ts b/src/app/core/shared/metadata.model.spec.ts index 8f44dee5fd9..dfeff8d6009 100644 --- a/src/app/core/shared/metadata.model.spec.ts +++ b/src/app/core/shared/metadata.model.spec.ts @@ -1,8 +1,9 @@ +import { isUndefined } from '../../shared/empty.util'; import { MetadataValue, MetadataValueFilter } from './metadata.interfaces'; import { Metadata } from './metadata.model'; const mdValue = (value: string, language?: string): MetadataValue => { - return { value: value, language: language === undefined ? null : language }; + return { value: value, language: isUndefined(language) ? null : language }; } const dcDescription = mdValue('Some description'); @@ -24,12 +25,12 @@ const multiMap = { const testMethod = (fn, resultKind, mapOrMaps, keyOrKeys, expected, filter?) => { const keys = keyOrKeys instanceof Array ? keyOrKeys : [ keyOrKeys ]; describe('and key' + (keys.length === 1 ? (' ' + keys[0]) : ('s ' + JSON.stringify(keys))) - + ' with ' + (filter === undefined ? 'no filter' : 'filter ' + JSON.stringify(filter)), () => { + + ' with ' + (isUndefined(filter) ? 'no filter' : 'filter ' + JSON.stringify(filter)), () => { const result = fn(mapOrMaps, keys, filter); let shouldReturn; if (resultKind === 'boolean') { shouldReturn = expected; - } else if (expected === undefined) { + } else if (isUndefined(expected)) { shouldReturn = 'undefined'; } else if (expected instanceof Array) { shouldReturn = 'an array with ' + expected.length + ' ' + (expected.length > 1 ? 'ordered ' : '') @@ -152,7 +153,7 @@ describe('Metadata', () => { const testValueMatches = (value: MetadataValue, expected: boolean, filter?: MetadataValueFilter) => { describe('with value ' + JSON.stringify(value) + ' and filter ' - + (filter === undefined ? 'undefined' : JSON.stringify(filter)), () => { + + (isUndefined(filter) ? 'undefined' : JSON.stringify(filter)), () => { const result = Metadata.valueMatches(value, filter); it('should return ' + expected, () => { expect(result).toEqual(expected); diff --git a/src/app/core/shared/metadata.model.ts b/src/app/core/shared/metadata.model.ts index c64827ffdb1..2b296592527 100644 --- a/src/app/core/shared/metadata.model.ts +++ b/src/app/core/shared/metadata.model.ts @@ -1,4 +1,4 @@ -import { isEmpty } from '../../shared/empty.util'; +import { isEmpty, isNotUndefined, isUndefined } from '../../shared/empty.util'; import { MetadataMap, MetadataValue, MetadataValueFilter } from './metadata.interfaces'; /** @@ -93,7 +93,7 @@ export class Metadata { public static firstValue(mdMapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[], filter?: MetadataValueFilter): string { const value = Metadata.first(mdMapOrMaps, keyOrKeys, filter); - return value === undefined ? undefined : value.value; + return isUndefined(value) ? undefined : value.value; } /** @@ -106,7 +106,7 @@ export class Metadata { */ public static has(mdMapOrMaps: MetadataMap | MetadataMap[], keyOrKeys: string | string[], filter?: MetadataValueFilter): boolean { - return Metadata.first(mdMapOrMaps, keyOrKeys, filter) !== undefined; + return isNotUndefined(Metadata.first(mdMapOrMaps, keyOrKeys, filter)); } /** From c2c59cd85a63b63ce0db91c3e9959e85a60f4cff Mon Sep 17 00:00:00 2001 From: Chris Wilper Date: Wed, 20 Feb 2019 16:36:09 -0500 Subject: [PATCH 6/6] DS-4107 Improve variable naming --- .../modify-item-overview.component.html | 10 +++++----- .../metadata-uri-values.component.html | 4 ++-- .../metadata-uri-values.component.ts | 2 +- .../metadata-values/metadata-values.component.html | 4 ++-- .../metadata-values/metadata-values.component.ts | 2 +- src/app/+item-page/full/full-item-page.component.html | 10 +++++----- .../item-page-specific-field.component.html | 2 +- .../title/item-page-title-field.component.html | 2 +- .../uri/item-page-uri-field.component.html | 2 +- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/app/+item-page/edit-item-page/modify-item-overview/modify-item-overview.component.html b/src/app/+item-page/edit-item-page/modify-item-overview/modify-item-overview.component.html index 861c20ada7d..ce6e01df3df 100644 --- a/src/app/+item-page/edit-item-page/modify-item-overview/modify-item-overview.component.html +++ b/src/app/+item-page/edit-item-page/modify-item-overview/modify-item-overview.component.html @@ -7,11 +7,11 @@ - - - {{entry.key}} - {{value.value}} - {{value.language}} + + + {{mdEntry.key}} + {{mdValue.value}} + {{mdValue.language}} diff --git a/src/app/+item-page/field-components/metadata-uri-values/metadata-uri-values.component.html b/src/app/+item-page/field-components/metadata-uri-values/metadata-uri-values.component.html index 344a32841b3..b5d7c118ddc 100644 --- a/src/app/+item-page/field-components/metadata-uri-values/metadata-uri-values.component.html +++ b/src/app/+item-page/field-components/metadata-uri-values/metadata-uri-values.component.html @@ -1,5 +1,5 @@ - - {{ linktext || value.value }} + + {{ linktext || mdValue.value }} diff --git a/src/app/+item-page/field-components/metadata-uri-values/metadata-uri-values.component.ts b/src/app/+item-page/field-components/metadata-uri-values/metadata-uri-values.component.ts index b5870f16b8e..09d855e9516 100644 --- a/src/app/+item-page/field-components/metadata-uri-values/metadata-uri-values.component.ts +++ b/src/app/+item-page/field-components/metadata-uri-values/metadata-uri-values.component.ts @@ -19,7 +19,7 @@ export class MetadataUriValuesComponent extends MetadataValuesComponent { @Input() linktext: any; - @Input() values: MetadataValue[]; + @Input() mdValues: MetadataValue[]; @Input() separator: string; diff --git a/src/app/+item-page/field-components/metadata-values/metadata-values.component.html b/src/app/+item-page/field-components/metadata-values/metadata-values.component.html index fbc1e11a079..980c9402553 100644 --- a/src/app/+item-page/field-components/metadata-values/metadata-values.component.html +++ b/src/app/+item-page/field-components/metadata-values/metadata-values.component.html @@ -1,5 +1,5 @@ - - {{value.value}} + + {{mdValue.value}} diff --git a/src/app/+item-page/field-components/metadata-values/metadata-values.component.ts b/src/app/+item-page/field-components/metadata-values/metadata-values.component.ts index 2be7291dcd6..708bdb49c71 100644 --- a/src/app/+item-page/field-components/metadata-values/metadata-values.component.ts +++ b/src/app/+item-page/field-components/metadata-values/metadata-values.component.ts @@ -12,7 +12,7 @@ import { MetadataValue } from '../../../core/shared/metadata.interfaces'; }) export class MetadataValuesComponent { - @Input() values: MetadataValue[]; + @Input() mdValues: MetadataValue[]; @Input() separator: string; diff --git a/src/app/+item-page/full/full-item-page.component.html b/src/app/+item-page/full/full-item-page.component.html index 7080ba2e96f..7aec57da0cf 100644 --- a/src/app/+item-page/full/full-item-page.component.html +++ b/src/app/+item-page/full/full-item-page.component.html @@ -9,11 +9,11 @@
- - - - - + + + + + diff --git a/src/app/+item-page/simple/field-components/specific-field/item-page-specific-field.component.html b/src/app/+item-page/simple/field-components/specific-field/item-page-specific-field.component.html index c0d948fc766..d6a569198c8 100644 --- a/src/app/+item-page/simple/field-components/specific-field/item-page-specific-field.component.html +++ b/src/app/+item-page/simple/field-components/specific-field/item-page-specific-field.component.html @@ -1,3 +1,3 @@
- +
diff --git a/src/app/+item-page/simple/field-components/specific-field/title/item-page-title-field.component.html b/src/app/+item-page/simple/field-components/specific-field/title/item-page-title-field.component.html index 40f54ec6364..aac85d335fd 100644 --- a/src/app/+item-page/simple/field-components/specific-field/title/item-page-title-field.component.html +++ b/src/app/+item-page/simple/field-components/specific-field/title/item-page-title-field.component.html @@ -1,3 +1,3 @@

- +

diff --git a/src/app/+item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.html b/src/app/+item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.html index 771fef53fc7..a5561b22e5d 100644 --- a/src/app/+item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.html +++ b/src/app/+item-page/simple/field-components/specific-field/uri/item-page-uri-field.component.html @@ -1,3 +1,3 @@
- +
{{entry.key}}{{value.value}}{{value.language}}
{{mdEntry.key}}{{mdValue.value}}{{mdValue.language}}