mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
[TLC-254] WIP tests
This commit is contained in:
@@ -0,0 +1,131 @@
|
|||||||
|
import {inject, TestBed, waitForAsync} from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||||
|
import {
|
||||||
|
DYNAMIC_FORM_CONTROL_TYPE_ARRAY,
|
||||||
|
DYNAMIC_FORM_CONTROL_TYPE_GROUP,
|
||||||
|
DynamicFormControlEvent, DynamicFormControlRelation, DynamicFormValidationService,
|
||||||
|
DynamicFormControlMatcher, DynamicFormRelationService,
|
||||||
|
DynamicInputModel, MATCH_VISIBLE, OR_OPERATOR, HIDDEN_MATCHER, DYNAMIC_MATCHERS
|
||||||
|
} from '@ng-dynamic-forms/core';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import {
|
||||||
|
mockInputWithTypeBindModel, MockRelationModel, mockDcTypeInputModel
|
||||||
|
} from '../../../mocks/form-models.mock';
|
||||||
|
import {DsDynamicTypeBindRelationService} from './ds-dynamic-type-bind-relation.service';
|
||||||
|
import {FormFieldMetadataValueObject} from "../models/form-field-metadata-value.model";
|
||||||
|
import {FormControl, NG_ASYNC_VALIDATORS, NG_VALIDATORS, ReactiveFormsModule} from "@angular/forms";
|
||||||
|
import {FormBuilderService} from "../form-builder.service";
|
||||||
|
import {getMockFormBuilderService} from "../../../mocks/form-builder-service.mock";
|
||||||
|
import {DsDynamicFormComponent} from "./ds-dynamic-form.component";
|
||||||
|
import {DsDynamicInputModel} from "./models/ds-dynamic-input.model";
|
||||||
|
import {FieldParser} from "../parsers/field-parser";
|
||||||
|
|
||||||
|
describe('DSDynamicTypeBindRelationService test suite', () => {
|
||||||
|
let service: DsDynamicTypeBindRelationService;
|
||||||
|
let dynamicFormRelationService: DynamicFormRelationService;
|
||||||
|
let dynamicFormControlMatchers: DynamicFormControlMatcher[];
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [ReactiveFormsModule],
|
||||||
|
providers: [
|
||||||
|
//{ provide: FormBuilderService, useValue: getMockFormBuilderService() },
|
||||||
|
{ provide: FormBuilderService, useValue: getMockFormBuilderService() },
|
||||||
|
{ provide: DsDynamicTypeBindRelationService, useClass: DsDynamicTypeBindRelationService },
|
||||||
|
{ provide: DynamicFormRelationService },
|
||||||
|
]
|
||||||
|
}).compileComponents().then();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(inject([DsDynamicTypeBindRelationService, DynamicFormRelationService],
|
||||||
|
(relationService: DsDynamicTypeBindRelationService,
|
||||||
|
formRelationService: DynamicFormRelationService
|
||||||
|
) => {
|
||||||
|
service = relationService;
|
||||||
|
dynamicFormRelationService = formRelationService;
|
||||||
|
dynamicFormControlMatchers = [];
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('Test getTypeBindValue method', () => {
|
||||||
|
it('Should get type bind "boundType" from the given metadata object value', () => {
|
||||||
|
const mockMetadataValueObject: FormFieldMetadataValueObject = new FormFieldMetadataValueObject(
|
||||||
|
'boundType', null, null, 'Bound Type'
|
||||||
|
);
|
||||||
|
const bindType = service.getTypeBindValue(mockMetadataValueObject);
|
||||||
|
expect(bindType).toBe('boundType');
|
||||||
|
});
|
||||||
|
it('Should get type authority key "bound-auth-key" from the given metadata object value', () => {
|
||||||
|
const mockMetadataValueObject: FormFieldMetadataValueObject = new FormFieldMetadataValueObject(
|
||||||
|
'boundType', null, 'bound-auth-key', 'Bound Type'
|
||||||
|
);
|
||||||
|
const bindType = service.getTypeBindValue(mockMetadataValueObject);
|
||||||
|
console.dir(bindType);
|
||||||
|
expect(bindType).toBe('bound-auth-key');
|
||||||
|
});
|
||||||
|
it('Should get passed string returned directly as string passed instead of metadata', () => {
|
||||||
|
const bindType = service.getTypeBindValue('rawString');
|
||||||
|
expect(bindType).toBe('rawString');
|
||||||
|
});
|
||||||
|
it('Should get "undefined" returned directly as no object given', () => {
|
||||||
|
const bindType = service.getTypeBindValue(undefined);
|
||||||
|
expect(bindType).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Test getRelatedFormModel method', () => {
|
||||||
|
it('Should get 0 related form models for simple type bind mock data', () => {
|
||||||
|
const testModel = mockInputWithTypeBindModel;
|
||||||
|
const relatedModels = service.getRelatedFormModel(testModel);
|
||||||
|
expect(relatedModels).toHaveSize(0);
|
||||||
|
});
|
||||||
|
it('Should get 1 related form models for mock relation model data', () => {
|
||||||
|
const testModel = MockRelationModel;
|
||||||
|
testModel.typeBindRelations = getTypeBindRelations(['boundType']);
|
||||||
|
const relatedModels = service.getRelatedFormModel(testModel);
|
||||||
|
expect(relatedModels).toHaveSize(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Test matchesCondition method', () => {
|
||||||
|
it('Should receive one subscription to dc.type type binding"', () => {
|
||||||
|
const testModel = MockRelationModel;
|
||||||
|
//testModel.typeBindRelations = getTypeBindRelations(['boundType']);
|
||||||
|
const relatedModels = service.getRelatedFormModel(testModel);
|
||||||
|
const dcTypeControl = new FormControl();
|
||||||
|
dcTypeControl.setValue('boundType');
|
||||||
|
expect(service.subscribeRelations(testModel, dcTypeControl)).toHaveSize(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TEST MTACHe"', () => {
|
||||||
|
const testModel = MockRelationModel;
|
||||||
|
testModel.typeBindRelations = getTypeBindRelations(['boundType']);
|
||||||
|
const relatedModels = service.getRelatedFormModel(testModel);
|
||||||
|
const dcTypeControl = new FormControl();
|
||||||
|
dcTypeControl.setValue('boundType');
|
||||||
|
testModel.typeBindRelations[0].when[0].value = 'asdfaf';
|
||||||
|
const relation = dynamicFormRelationService.findRelationByMatcher((testModel as any).typeBindRelations, HIDDEN_MATCHER);
|
||||||
|
// console.dir(relation);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function getTypeBindRelations(configuredTypeBindValues: string[]): DynamicFormControlRelation[] {
|
||||||
|
const bindValues = [];
|
||||||
|
configuredTypeBindValues.forEach((value) => {
|
||||||
|
bindValues.push({
|
||||||
|
id: 'dc.type',
|
||||||
|
value: value
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return [{
|
||||||
|
match: MATCH_VISIBLE,
|
||||||
|
operator: OR_OPERATOR,
|
||||||
|
when: bindValues
|
||||||
|
}];
|
||||||
|
}
|
@@ -15,10 +15,11 @@ import {
|
|||||||
OR_OPERATOR
|
OR_OPERATOR
|
||||||
} from '@ng-dynamic-forms/core';
|
} from '@ng-dynamic-forms/core';
|
||||||
|
|
||||||
import { isNotUndefined, isUndefined } from '../../../empty.util';
|
import { isNotUndefined, isUndefined, hasNoValue, hasValue } from '../../../empty.util';
|
||||||
import { FormBuilderService } from '../form-builder.service';
|
import { FormBuilderService } from '../form-builder.service';
|
||||||
import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model';
|
import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model';
|
||||||
import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from './ds-dynamic-form-constants';
|
import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from './ds-dynamic-form-constants';
|
||||||
|
import {DsDynamicInputModel} from "./models/ds-dynamic-input.model";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service to manage type binding for submission input fields
|
* Service to manage type binding for submission input fields
|
||||||
@@ -39,11 +40,12 @@ export class DsDynamicTypeBindRelationService {
|
|||||||
* @param bindModelValue
|
* @param bindModelValue
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
private static getTypeBindValue(bindModelValue: string | FormFieldMetadataValueObject): string {
|
public getTypeBindValue(bindModelValue: string | FormFieldMetadataValueObject): string {
|
||||||
let value;
|
let value;
|
||||||
if (isUndefined(bindModelValue) || typeof bindModelValue === 'string') {
|
if (hasNoValue(bindModelValue) || typeof bindModelValue === 'string') {
|
||||||
value = bindModelValue;
|
value = bindModelValue;
|
||||||
} else if (bindModelValue.hasAuthority()) {
|
} else if (bindModelValue instanceof FormFieldMetadataValueObject
|
||||||
|
&& bindModelValue.hasAuthority()) {
|
||||||
value = bindModelValue.authority;
|
value = bindModelValue.authority;
|
||||||
} else {
|
} else {
|
||||||
value = bindModelValue.value;
|
value = bindModelValue.value;
|
||||||
@@ -110,9 +112,9 @@ export class DsDynamicTypeBindRelationService {
|
|||||||
// be used, or where the entry doesn't have .value but is a string itself, etc)
|
// be used, or where the entry doesn't have .value but is a string itself, etc)
|
||||||
// If values isn't an array, make it a single element array with the looked-up type bind value.
|
// If values isn't an array, make it a single element array with the looked-up type bind value.
|
||||||
if (Array.isArray(bindModelValue)) {
|
if (Array.isArray(bindModelValue)) {
|
||||||
values = [...bindModelValue.map((entry) => DsDynamicTypeBindRelationService.getTypeBindValue(entry))];
|
values = [...bindModelValue.map((entry) => this.getTypeBindValue(entry))];
|
||||||
} else {
|
} else {
|
||||||
values = [DsDynamicTypeBindRelationService.getTypeBindValue(bindModelValue)];
|
values = [this.getTypeBindValue(bindModelValue)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// If bind model evaluates to 'true' (is not undefined, is not null, is not false etc,
|
// If bind model evaluates to 'true' (is not undefined, is not null, is not false etc,
|
||||||
@@ -186,10 +188,12 @@ export class DsDynamicTypeBindRelationService {
|
|||||||
const relatedModels = this.getRelatedFormModel(model);
|
const relatedModels = this.getRelatedFormModel(model);
|
||||||
const subscriptions: Subscription[] = [];
|
const subscriptions: Subscription[] = [];
|
||||||
|
|
||||||
|
console.dir(relatedModels);
|
||||||
|
|
||||||
Object.values(relatedModels).forEach((relatedModel: any) => {
|
Object.values(relatedModels).forEach((relatedModel: any) => {
|
||||||
|
|
||||||
if (isNotUndefined(relatedModel)) {
|
if (hasValue(relatedModel)) {
|
||||||
const initValue = (isUndefined(relatedModel.value) || typeof relatedModel.value === 'string') ? relatedModel.value :
|
const initValue = (hasNoValue(relatedModel.value) || typeof relatedModel.value === 'string') ? relatedModel.value :
|
||||||
(Array.isArray(relatedModel.value) ? relatedModel.value : relatedModel.value.value);
|
(Array.isArray(relatedModel.value) ? relatedModel.value : relatedModel.value.value);
|
||||||
|
|
||||||
const valueChanges = relatedModel.valueChanges.pipe(
|
const valueChanges = relatedModel.valueChanges.pipe(
|
||||||
@@ -200,20 +204,22 @@ export class DsDynamicTypeBindRelationService {
|
|||||||
// I still don't fully understand what is happening here, or the triggers in various form usage that
|
// I still don't fully understand what is happening here, or the triggers in various form usage that
|
||||||
// cause which / what to fire change events, why the matcher has onChange() instead of a field value or
|
// cause which / what to fire change events, why the matcher has onChange() instead of a field value or
|
||||||
// form model, etc.
|
// form model, etc.
|
||||||
subscriptions.push(valueChanges.subscribe(() => {
|
if (hasValue(this.dynamicMatchers) || true) {
|
||||||
// Iterate each matcher
|
subscriptions.push(valueChanges.subscribe(() => {
|
||||||
this.dynamicMatchers.forEach((matcher) => {
|
// Iterate each matcher
|
||||||
|
this.dynamicMatchers.forEach((matcher) => {
|
||||||
|
|
||||||
// Find the relation
|
// Find the relation
|
||||||
const relation = this.dynamicFormRelationService.findRelationByMatcher((model as any).typeBindRelations, matcher);
|
const relation = this.dynamicFormRelationService.findRelationByMatcher((model as any).typeBindRelations, matcher);
|
||||||
|
|
||||||
// If the relation is defined, get matchesCondition result and pass it to the onChange event listener
|
// If the relation is defined, get matchesCondition result and pass it to the onChange event listener
|
||||||
if (relation !== undefined) {
|
if (relation !== undefined) {
|
||||||
const hasMatch = this.matchesCondition(relation, matcher);
|
const hasMatch = this.matchesCondition(relation, matcher);
|
||||||
matcher.onChange(hasMatch, model, control, this.injector);
|
matcher.onChange(hasMatch, model, control, this.injector);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1,7 +1,30 @@
|
|||||||
import { FormBuilderService } from '../form/builder/form-builder.service';
|
import { FormBuilderService } from '../form/builder/form-builder.service';
|
||||||
import { FormControl, FormGroup } from '@angular/forms';
|
import { FormControl, FormGroup } from '@angular/forms';
|
||||||
|
import {DynamicFormControlModel, DynamicInputModel} from "@ng-dynamic-forms/core";
|
||||||
|
import {DsDynamicInputModel} from "../form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model";
|
||||||
|
|
||||||
export function getMockFormBuilderService(): FormBuilderService {
|
export function getMockFormBuilderService(): FormBuilderService {
|
||||||
|
|
||||||
|
const inputWithTypeBindConfig = {
|
||||||
|
name: 'testWithTypeBind',
|
||||||
|
id: 'testWithTypeBind',
|
||||||
|
readOnly: false,
|
||||||
|
disabled: false,
|
||||||
|
repeatable: false,
|
||||||
|
value: {
|
||||||
|
value: 'testWithTypeBind',
|
||||||
|
display: 'testWithTypeBind'
|
||||||
|
},
|
||||||
|
submissionId: '1234',
|
||||||
|
metadataFields: [],
|
||||||
|
hasSelectableMetadata: false,
|
||||||
|
typeBindRelations: [
|
||||||
|
{match: 'VISIBLE', operator: 'OR', when: [{'id': 'dc.type', 'value': 'boundType'}]}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const thing = new DsDynamicInputModel(inputWithTypeBindConfig);
|
||||||
|
|
||||||
return jasmine.createSpyObj('FormBuilderService', {
|
return jasmine.createSpyObj('FormBuilderService', {
|
||||||
modelFromConfiguration: [],
|
modelFromConfiguration: [],
|
||||||
createFormGroup: new FormGroup({}),
|
createFormGroup: new FormGroup({}),
|
||||||
@@ -17,8 +40,26 @@ export function getMockFormBuilderService(): FormBuilderService {
|
|||||||
isQualdropGroup: false,
|
isQualdropGroup: false,
|
||||||
isModelInCustomGroup: true,
|
isModelInCustomGroup: true,
|
||||||
isRelationGroup: true,
|
isRelationGroup: true,
|
||||||
hasArrayGroupValue: true
|
hasArrayGroupValue: true,
|
||||||
|
getTypeBindModel: new DsDynamicInputModel({
|
||||||
|
name: 'testWithTypeBind',
|
||||||
|
id: 'testWithTypeBind',
|
||||||
|
readOnly: false,
|
||||||
|
disabled: false,
|
||||||
|
repeatable: false,
|
||||||
|
value: {
|
||||||
|
value: 'testWithTypeBind',
|
||||||
|
display: 'testWithTypeBind',
|
||||||
|
authority: 'bound-auth-key'
|
||||||
|
},
|
||||||
|
submissionId: '1234',
|
||||||
|
metadataFields: [],
|
||||||
|
hasSelectableMetadata: false,
|
||||||
|
typeBindRelations: [
|
||||||
|
{match: 'VISIBLE', operator: 'OR', when: [{'id': 'dc.type', 'value': 'boundType'}]}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -306,3 +306,57 @@ export const mockFileFormEditRowGroupModel = new DynamicRowGroupModel({
|
|||||||
id: 'mockRowGroupModel',
|
id: 'mockRowGroupModel',
|
||||||
group: [mockFileFormEditInputModel]
|
group: [mockFileFormEditInputModel]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Mock configuration and model for an input with type binding
|
||||||
|
export const inputWithTypeBindConfig = {
|
||||||
|
name: 'testWithTypeBind',
|
||||||
|
id: 'testWithTypeBind',
|
||||||
|
readOnly: false,
|
||||||
|
disabled: false,
|
||||||
|
repeatable: false,
|
||||||
|
value: {
|
||||||
|
value: 'testWithTypeBind',
|
||||||
|
display: 'testWithTypeBind',
|
||||||
|
authority: 'bound-auth-key'
|
||||||
|
},
|
||||||
|
submissionId: '1234',
|
||||||
|
metadataFields: [],
|
||||||
|
hasSelectableMetadata: false,
|
||||||
|
getTypeBindModel: new DsDynamicInputModel({
|
||||||
|
name: 'testWithTypeBind',
|
||||||
|
id: 'testWithTypeBind',
|
||||||
|
readOnly: false,
|
||||||
|
disabled: false,
|
||||||
|
repeatable: false,
|
||||||
|
value: {
|
||||||
|
value: 'testWithTypeBind',
|
||||||
|
display: 'testWithTypeBind',
|
||||||
|
authority: 'bound-auth-key'
|
||||||
|
},
|
||||||
|
submissionId: '1234',
|
||||||
|
metadataFields: [],
|
||||||
|
hasSelectableMetadata: false,
|
||||||
|
typeBindRelations: [
|
||||||
|
{match: 'VISIBLE', operator: 'OR', when: [{'id': 'dc.type', 'value': 'boundType'}]}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockInputWithTypeBindModel = new DsDynamicInputModel(inputWithAuthorityValueConfig);
|
||||||
|
|
||||||
|
export const dcTypeInputConfig = {
|
||||||
|
name: 'dc.type',
|
||||||
|
id: 'dc_type',
|
||||||
|
readOnly: false,
|
||||||
|
disabled: false,
|
||||||
|
repeatable: false,
|
||||||
|
submissionId: '1234',
|
||||||
|
metadataFields: [],
|
||||||
|
hasSelectableMetadata: false,
|
||||||
|
value: {
|
||||||
|
value: 'boundType'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockDcTypeInputModel = new DsDynamicInputModel(dcTypeInputConfig);
|
||||||
|
Reference in New Issue
Block a user