Skip to content

Commit

Permalink
Merged in task/main-cris/DSC-2140 (pull request DSpace#2690)
Browse files Browse the repository at this point in the history
Task/main cris/DSC-2140

Approved-by: Francesco Molinaro
  • Loading branch information
Andrea Barbasso authored and FrancescoMolinaro committed Jan 13, 2025
2 parents 2608f05 + db056cf commit 2dc35b4
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 10 deletions.
37 changes: 33 additions & 4 deletions src/app/core/shared/metadata.utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import {
MetadataValueFilter,
MetadatumViewModel,
} from './metadata.models';
import { Metadata } from './metadata.utils';
import {
Metadata,
PLACEHOLDER_VALUE,
} from './metadata.utils';

const mdValue = (value: string, language?: string, authority?: string): MetadataValue => {
return Object.assign(new MetadataValue(), {
Expand Down Expand Up @@ -50,19 +53,20 @@ const multiViewModelList = [
{ key: 'foo', ...bar, order: 0 },
];

const testMethod = (fn, resultKind, mapOrMaps, keyOrKeys, expected, filter?) => {
const testMethod = (fn, resultKind, mapOrMaps, keyOrKeys, expected, filter?, limit?: number) => {
const keys = keyOrKeys instanceof Array ? keyOrKeys : [keyOrKeys];
describe('and key' + (keys.length === 1 ? (' ' + keys[0]) : ('s ' + JSON.stringify(keys)))
+ ' with ' + (isUndefined(filter) ? 'no filter' : 'filter ' + JSON.stringify(filter)), () => {
const result = fn(mapOrMaps, keys, filter);
const result = fn(mapOrMaps, keys, filter, limit);
let shouldReturn;
if (resultKind === 'boolean') {
shouldReturn = expected;
} else if (isUndefined(expected)) {
shouldReturn = 'undefined';
} else if (expected instanceof Array) {
shouldReturn = 'an array with ' + expected.length + ' ' + (expected.length > 1 ? 'ordered ' : '')
+ resultKind + (expected.length !== 1 ? 's' : '');
+ resultKind + (expected.length !== 1 ? 's' : '')
+ (isUndefined(limit) ? '' : ' (limited to ' + limit + ')');
} else {
shouldReturn = 'a ' + resultKind;
}
Expand Down Expand Up @@ -303,4 +307,29 @@ describe('Metadata', () => {

});

describe('all method with limit', () => {
const testAllWithLimit = (mapOrMaps, keyOrKeys, expected, limit) =>
testMethod(Metadata.all, 'value', mapOrMaps, keyOrKeys, expected, undefined, limit);

describe('with multiMap and limit', () => {
testAllWithLimit(multiMap, 'dc.title', [dcTitle1], 1);
});
});

describe('Placeholder values', () => {
it('should ignore placeholder values in get methods', () => {
const placeholderMd = mdValue(PLACEHOLDER_VALUE);
const key = 'dc.test.placeholder';
const map = { 'dc.test.placeholder': [placeholderMd] };

expect(Metadata.all(map, key).length).toEqual(0);
expect(Metadata.allValues(map, key).length).toEqual(0);
expect(Metadata.has(map, key)).toBeFalsy();
expect(Metadata.first(map, key)).toBeUndefined();
expect(Metadata.firstValue(map, key)).toBeUndefined();
expect(Metadata.hasValue(placeholderMd)).toBeFalsy();
expect(Metadata.valueMatches(placeholderMd, null)).toBeFalsy();
});
});

});
22 changes: 16 additions & 6 deletions src/app/core/shared/metadata.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {

export const AUTHORITY_GENERATE = 'will be generated::';
export const AUTHORITY_REFERENCE = 'will be referenced::';
export const PLACEHOLDER_VALUE = '#PLACEHOLDER_PARENT_METADATA_VALUE#';


/**
* Utility class for working with DSpace object metadata.
Expand All @@ -36,18 +38,21 @@ export const AUTHORITY_REFERENCE = 'will be referenced::';
* followed by any other (non-dc) metadata values.
*/
export class Metadata {

/**
* Gets all matching metadata in the map(s).
*
* @param {MetadataMapInterface|MetadataMapInterface[]} 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.
* @param {number} limit The maximum number of values to return. If unspecified, all matching values will be returned.
* @returns {MetadataValue[]} the matching values or an empty array.
*/
public static all(mapOrMaps: MetadataMapInterface | MetadataMapInterface[], keyOrKeys: string | string[],
filter?: MetadataValueFilter): MetadataValue[] {
public static all(
mapOrMaps: MetadataMapInterface | MetadataMapInterface[],
keyOrKeys: string | string[],
filter?: MetadataValueFilter,
limit?: number): MetadataValue[] {
const mdMaps: MetadataMapInterface[] = mapOrMaps instanceof Array ? mapOrMaps : [mapOrMaps];
const matches: MetadataValue[] = [];
for (const mdMap of mdMaps) {
Expand All @@ -57,6 +62,9 @@ export class Metadata {
for (const candidate of candidates) {
if (Metadata.valueMatches(candidate as MetadataValue, filter)) {
matches.push(candidate as MetadataValue);
if (hasValue(limit) && matches.length >= limit) {
return matches;
}
}
}
}
Expand Down Expand Up @@ -155,11 +163,11 @@ export class Metadata {
* Returns true if this Metadatum's value is defined
*/
public static hasValue(value: MetadataValue|string): boolean {
if (isEmpty(value)) {
if (isEmpty(value) || value === PLACEHOLDER_VALUE) {
return false;
}
if (isObject(value) && value.hasOwnProperty('value')) {
return isNotEmpty(value.value);
return isNotEmpty(value.value) && value.value !== PLACEHOLDER_VALUE;
}
return true;
}
Expand All @@ -172,7 +180,9 @@ export class Metadata {
* @returns {boolean} whether the filter matches, or true if no filter is given.
*/
public static valueMatches(mdValue: MetadataValue, filter: MetadataValueFilter) {
if (!filter) {
if (mdValue.value === PLACEHOLDER_VALUE) {
return false;
} else if (!filter) {
return true;
} else if (filter.language && filter.language !== mdValue.language) {
return false;
Expand Down

0 comments on commit 2dc35b4

Please sign in to comment.