Skip to content

Commit

Permalink
Stash: multiple field value validation WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
GPortas committed Jan 12, 2024
1 parent 2c35633 commit 1b4b29a
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 16 deletions.
69 changes: 69 additions & 0 deletions src/datasets/domain/useCases/validators/NewDatasetValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { IMetadataBlocksRepository } from '../../../../metadataBlocks/domain/rep
import { MetadataFieldInfo } from '../../../../metadataBlocks';
import { ResourceValidationError } from '../../../../core/domain/useCases/validators/errors/ResourceValidationError';
import { EmptyFieldError } from '../../../../core/domain/useCases/validators/errors/EmptyFieldError';
import { FieldValidationError } from '../../../../core/domain/useCases/validators/errors/FieldValidationError';

export class NewDatasetValidator implements NewResourceValidator<NewDataset> {
private metadataBlockRepository: IMetadataBlocksRepository;
Expand All @@ -25,10 +26,78 @@ export class NewDatasetValidator implements NewResourceValidator<NewDataset> {
throw new EmptyFieldError(metadataFieldKey, newDatasetMetadataBlockName);
}

this.validateMetadataFieldValueType(
metadataFieldInfo,
metadataFieldKey,
newDatasetMetadataFieldValue,
newDatasetMetadataBlockName,
);

if (metadataFieldInfo.childMetadataFields != undefined) {
// TODO: child fields validation
}
}
}
}

validateMetadataFieldValueType(
metadataFieldInfo: MetadataFieldInfo,
metadataFieldKey: string,
newDatasetMetadataFieldValue: NewDatasetMetadataFieldValue,
newDatasetMetadataBlockName: string,
): void {
if (metadataFieldInfo.multiple) {
if (!Array.isArray(newDatasetMetadataFieldValue)) {
throw this.createValidationError(
metadataFieldKey,
newDatasetMetadataBlockName,
undefined,
'Expecting an array of values.',
);
}
if (this.isValidArrayType(newDatasetMetadataFieldValue, 'string') && metadataFieldInfo.type === 'NONE') {
throw this.createValidationError(
metadataFieldKey,
newDatasetMetadataBlockName,
undefined,
'Expecting an array of sub fields, not strings.',
);
} else if (this.isValidArrayType(newDatasetMetadataFieldValue, 'object') && metadataFieldInfo.type !== 'NONE') {
throw this.createValidationError(
metadataFieldKey,
newDatasetMetadataBlockName,
undefined,
'Expecting an array of strings, not sub fields.',
);
} else if (
!this.isValidArrayType(newDatasetMetadataFieldValue, 'object') &&
!this.isValidArrayType(newDatasetMetadataFieldValue, 'string')
) {
throw this.createValidationError(
metadataFieldKey,
newDatasetMetadataBlockName,
undefined,
'The provided array of values is not valid.',
);
}
}
}

private isValidArrayType(
newDatasetMetadataFieldValue: Array<string | NewDatasetMetadataFieldValue>,
expectedType: 'string' | 'object',
): boolean {
return newDatasetMetadataFieldValue.every(
(item: string | NewDatasetMetadataFieldValue) => typeof item === expectedType,
);
}

private createValidationError(
metadataFieldKey: string,
newDatasetMetadataBlockName: string,
parentMetadataFieldName: string | undefined,
reason: string,
): FieldValidationError {
return new FieldValidationError(metadataFieldKey, newDatasetMetadataBlockName, parentMetadataFieldName, reason);
}
}
49 changes: 36 additions & 13 deletions test/testHelpers/datasets/newDatasetHelper.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,59 @@
import { NewDataset } from '../../../src/datasets/domain/models/NewDataset';
import { NewDataset, NewDatasetMetadataFieldValue } from '../../../src/datasets/domain/models/NewDataset';
import { MetadataBlock } from '../../../src';

export const createNewDatasetModel = (): NewDataset => {
export const createNewDatasetModel = (authorFieldValue?: NewDatasetMetadataFieldValue | string): NewDataset => {
const validAuthorFieldValue = [
{
authorName: 'Admin, Dataverse',
authorAffiliation: 'Dataverse.org',
},
{
authorName: 'Owner, Dataverse',
authorAffiliation: 'Dataverse.org',
},
];
return {
metadataBlockValues: [
{
name: 'citation',
fields: {
title: 'test dataset',
author: authorFieldValue !== undefined ? authorFieldValue : validAuthorFieldValue,
},
},
],
};
};

export const createNewDatasetModelWithoutFirstLevelRequiredField = (): NewDataset => {
return {
metadataBlockValues: [
{
name: 'citation',
fields: {
title: 'test dataset',
author: [
{
authorName: 'Admin, Dataverse',
authorAffiliation: 'Dataverse.org',
},
{
authorName: 'Owner, Dataverse',
authorAffiliation: 'Dataverse.org',
},
],
},
},
],
};
};

export const createNewDatasetModelWithoutRequiredField = (): NewDataset => {
export const createNewDatasetModelWithoutSecondLevelRequiredField = (): NewDataset => {
return {
metadataBlockValues: [
{
name: 'citation',
fields: {
title: 'test dataset',
author: [
{
authorName: 'Admin, Dataverse',
authorAffiliation: 'Dataverse.org',
},
{
authorAffiliation: 'Dataverse.org',
},
],
},
},
],
Expand Down
33 changes: 30 additions & 3 deletions test/unit/datasets/NewDatasetValidator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import { assert, createSandbox, SinonSandbox } from 'sinon';
import {
createNewDatasetModel,
createNewDatasetMetadataBlockModel,
createNewDatasetModelWithoutRequiredField,
createNewDatasetModelWithoutFirstLevelRequiredField,
} from '../../testHelpers/datasets/newDatasetHelper';
import { fail } from 'assert';
import { IMetadataBlocksRepository } from '../../../src/metadataBlocks/domain/repositories/IMetadataBlocksRepository';
import { EmptyFieldError } from '../../../src/core/domain/useCases/validators/errors/EmptyFieldError';
import { FieldValidationError } from '../../../src/core/domain/useCases/validators/errors/FieldValidationError';

describe('execute', () => {
const sandbox: SinonSandbox = createSandbox();
Expand All @@ -27,8 +28,8 @@ describe('execute', () => {
await sut.validate(testNewDataset).catch((e) => fail(e));
});

test('should raise empty field error when a first level field is missing', async () => {
const testNewDataset = createNewDatasetModelWithoutRequiredField();
test('should raise an empty field error when a first level field is missing', async () => {
const testNewDataset = createNewDatasetModelWithoutFirstLevelRequiredField();
const testMetadataBlock = createNewDatasetMetadataBlockModel();
const metadataBlocksRepositoryStub = <IMetadataBlocksRepository>{};
const getMetadataBlockByNameStub = sandbox.stub().resolves(testMetadataBlock);
Expand All @@ -51,4 +52,30 @@ describe('execute', () => {
);
});
});

test('should raise an error when the provided field value for a multiple field is a string', async () => {
const invalidAuthorFieldValue = 'invalidValue';
const testNewDataset = createNewDatasetModel(invalidAuthorFieldValue);
const testMetadataBlock = createNewDatasetMetadataBlockModel();
const metadataBlocksRepositoryStub = <IMetadataBlocksRepository>{};
const getMetadataBlockByNameStub = sandbox.stub().resolves(testMetadataBlock);
metadataBlocksRepositoryStub.getMetadataBlockByName = getMetadataBlockByNameStub;
const sut = new NewDatasetValidator(metadataBlocksRepositoryStub);

await sut
.validate(testNewDataset)
.then(() => {
fail('Validation should fail');
})
.catch((error) => {
const emptyFieldError = error as FieldValidationError;
assert.match(emptyFieldError.citationBlockName, 'citation');
assert.match(emptyFieldError.metadataFieldName, 'author');
assert.match(emptyFieldError.parentMetadataFieldName, undefined);
assert.match(
emptyFieldError.message,
'There was an error when validating the field author from metadata block citation. Reason was: Expecting an array of values.',
);
});
});
});

0 comments on commit 1b4b29a

Please sign in to comment.