|
|
|
@ -5,71 +5,89 @@ |
|
|
|
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
|
|
|
*/ |
|
|
|
|
|
|
|
import { AbstractControl, FormArray } from '@angular/forms'; |
|
|
|
|
|
|
|
import { |
|
|
|
AppLanguageDto, |
|
|
|
ArrayFieldPropertiesDto, |
|
|
|
AssetsFieldPropertiesDto, |
|
|
|
BooleanFieldPropertiesDto, |
|
|
|
createProperties, |
|
|
|
DateTime, |
|
|
|
DateTimeFieldPropertiesDto, |
|
|
|
EditContentForm, |
|
|
|
FieldDefaultValue, |
|
|
|
FieldFormatter, |
|
|
|
FieldPropertiesDto, |
|
|
|
FieldValidatorsFactory, |
|
|
|
FieldsValidators, |
|
|
|
GeolocationFieldPropertiesDto, |
|
|
|
getContentValue, |
|
|
|
HtmlValue, |
|
|
|
ImmutableArray, |
|
|
|
JsonFieldPropertiesDto, |
|
|
|
LanguageDto, |
|
|
|
NestedFieldDto, |
|
|
|
NumberFieldPropertiesDto, |
|
|
|
PartitionConfig, |
|
|
|
ReferencesFieldPropertiesDto, |
|
|
|
RootFieldDto, |
|
|
|
SchemaDetailsDto, |
|
|
|
SchemaPropertiesDto, |
|
|
|
StringFieldPropertiesDto, |
|
|
|
TagsFieldPropertiesDto |
|
|
|
TagsFieldPropertiesDto, |
|
|
|
Version |
|
|
|
} from '@app/shared/internal'; |
|
|
|
|
|
|
|
import { TestValues } from './_test-helpers'; |
|
|
|
|
|
|
|
const { |
|
|
|
modified, |
|
|
|
modifier, |
|
|
|
creation, |
|
|
|
creator |
|
|
|
} = TestValues; |
|
|
|
|
|
|
|
describe('SchemaDetailsDto', () => { |
|
|
|
it('should return label as display name', () => { |
|
|
|
const schema = createSchema(new SchemaPropertiesDto('Label'), 1, []); |
|
|
|
const schema = createSchema({ properties: new SchemaPropertiesDto('Label') }); |
|
|
|
|
|
|
|
expect(schema.displayName).toBe('Label'); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return name as display name if label is undefined', () => { |
|
|
|
const schema = createSchema(new SchemaPropertiesDto(undefined), 1, []); |
|
|
|
const schema = createSchema({ properties: new SchemaPropertiesDto(undefined) }); |
|
|
|
|
|
|
|
expect(schema.displayName).toBe('schema1'); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return name as display name label is empty', () => { |
|
|
|
const schema = createSchema(new SchemaPropertiesDto(''), 1, []); |
|
|
|
const schema = createSchema({ properties: new SchemaPropertiesDto('') }); |
|
|
|
|
|
|
|
expect(schema.displayName).toBe('schema1'); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return configured fields as list fields if no schema field are declared', () => { |
|
|
|
const field1 = createField(new ArrayFieldPropertiesDto({ isListField: true }), 1); |
|
|
|
const field2 = createField(new ArrayFieldPropertiesDto({ isListField: false }), 2); |
|
|
|
const field3 = createField(new ArrayFieldPropertiesDto({ isListField: true }), 3); |
|
|
|
const field1 = createField({ properties: new ArrayFieldPropertiesDto({ isListField: true }) }); |
|
|
|
const field2 = createField({ properties: new ArrayFieldPropertiesDto({ isListField: false }), id: 2 }); |
|
|
|
const field3 = createField({ properties: new ArrayFieldPropertiesDto({ isListField: true }), id: 3 }); |
|
|
|
|
|
|
|
const schema = createSchema(new SchemaPropertiesDto(''), 1, [field1, field2, field3]); |
|
|
|
const schema = createSchema({ properties: new SchemaPropertiesDto(''), fields: [field1, field2, field3] }); |
|
|
|
|
|
|
|
expect(schema.listFields).toEqual([field1, field3]); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return first fields as list fields if no schema field is declared', () => { |
|
|
|
const field1 = createField(new ArrayFieldPropertiesDto(), 1); |
|
|
|
const field2 = createField(new ArrayFieldPropertiesDto(), 2); |
|
|
|
const field3 = createField(new ArrayFieldPropertiesDto(), 3); |
|
|
|
const field1 = createField({ properties: new ArrayFieldPropertiesDto() }); |
|
|
|
const field2 = createField({ properties: new ArrayFieldPropertiesDto(), id: 2 }); |
|
|
|
const field3 = createField({ properties: new ArrayFieldPropertiesDto(), id: 3 }); |
|
|
|
|
|
|
|
const schema = createSchema(new SchemaPropertiesDto(''), 1, [field1, field2, field3]); |
|
|
|
const schema = createSchema({ properties: new SchemaPropertiesDto(''), fields: [field1, field2, field3] }); |
|
|
|
|
|
|
|
expect(schema.listFields).toEqual([field1]); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return empty list fields if fields is empty', () => { |
|
|
|
const schema = createSchema(new SchemaPropertiesDto(), 1, []); |
|
|
|
const schema = createSchema({ properties: new SchemaPropertiesDto() }); |
|
|
|
|
|
|
|
expect(schema.listFields[0].fieldId).toEqual(-1); |
|
|
|
}); |
|
|
|
@ -77,53 +95,53 @@ describe('SchemaDetailsDto', () => { |
|
|
|
|
|
|
|
describe('FieldDto', () => { |
|
|
|
it('should return label as display name', () => { |
|
|
|
const field = createField(new AssetsFieldPropertiesDto({ label: 'Label' }), 1); |
|
|
|
const field = createField({ properties: new AssetsFieldPropertiesDto({ label: 'Label' }) }); |
|
|
|
|
|
|
|
expect(field.displayName).toBe('Label'); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return name as display name if label is null', () => { |
|
|
|
const field = createField(new AssetsFieldPropertiesDto(), 1); |
|
|
|
const field = createField({ properties: new AssetsFieldPropertiesDto() }); |
|
|
|
|
|
|
|
expect(field.displayName).toBe('field1'); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return name as display name label is empty', () => { |
|
|
|
const field = createField(new AssetsFieldPropertiesDto({ label: '' }), 1); |
|
|
|
const field = createField({ properties: new AssetsFieldPropertiesDto({ label: '' }) }); |
|
|
|
|
|
|
|
expect(field.displayName).toBe('field1'); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return placeholder as display placeholder', () => { |
|
|
|
const field = createField(new AssetsFieldPropertiesDto({ placeholder: 'Placeholder' }), 1); |
|
|
|
const field = createField({ properties: new AssetsFieldPropertiesDto({ placeholder: 'Placeholder' }) }); |
|
|
|
|
|
|
|
expect(field.displayPlaceholder).toBe('Placeholder'); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return empty as display placeholder if placeholder is null', () => { |
|
|
|
const field = createField(new AssetsFieldPropertiesDto()); |
|
|
|
const field = createField({ properties: new AssetsFieldPropertiesDto() }); |
|
|
|
|
|
|
|
expect(field.displayPlaceholder).toBe(''); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return localizable if partitioning is language', () => { |
|
|
|
const field = createField(new AssetsFieldPropertiesDto(), 1, 'language'); |
|
|
|
const field = createField({ properties: new AssetsFieldPropertiesDto(), partitioning: 'language' }); |
|
|
|
|
|
|
|
expect(field.isLocalizable).toBeTruthy(); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should not return localizable if partitioning is invarient', () => { |
|
|
|
const field = createField(new AssetsFieldPropertiesDto(), 1, 'invariant'); |
|
|
|
const field = createField({ properties: new AssetsFieldPropertiesDto(), partitioning: 'invariant' }); |
|
|
|
|
|
|
|
expect(field.isLocalizable).toBeFalsy(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
describe('ArrayField', () => { |
|
|
|
const field = createField(new ArrayFieldPropertiesDto({ isRequired: true, minItems: 1, maxItems: 5 })); |
|
|
|
const field = createField({ properties: new ArrayFieldPropertiesDto({ isRequired: true, minItems: 1, maxItems: 5 }) }); |
|
|
|
|
|
|
|
it('should create validators', () => { |
|
|
|
expect(FieldValidatorsFactory.createValidators(field, false).length).toBe(2); |
|
|
|
expect(FieldsValidators.create(field, false).length).toBe(2); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should format to empty string if null', () => { |
|
|
|
@ -144,10 +162,10 @@ describe('ArrayField', () => { |
|
|
|
}); |
|
|
|
|
|
|
|
describe('AssetsField', () => { |
|
|
|
const field = createField(new AssetsFieldPropertiesDto({ isRequired: true, minItems: 1, maxItems: 5 })); |
|
|
|
const field = createField({ properties: new AssetsFieldPropertiesDto({ isRequired: true, minItems: 1, maxItems: 5 }) }); |
|
|
|
|
|
|
|
it('should create validators', () => { |
|
|
|
expect(FieldValidatorsFactory.createValidators(field, false).length).toBe(3); |
|
|
|
expect(FieldsValidators.create(field, false).length).toBe(3); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should format to empty string if null', () => { |
|
|
|
@ -168,10 +186,10 @@ describe('AssetsField', () => { |
|
|
|
}); |
|
|
|
|
|
|
|
describe('TagsField', () => { |
|
|
|
const field = createField(new TagsFieldPropertiesDto('Tags', { isRequired: true, minItems: 1, maxItems: 5 })); |
|
|
|
const field = createField({ properties: new TagsFieldPropertiesDto({ isRequired: true, minItems: 1, maxItems: 5 }) }); |
|
|
|
|
|
|
|
it('should create validators', () => { |
|
|
|
expect(FieldValidatorsFactory.createValidators(field, false).length).toBe(2); |
|
|
|
expect(FieldsValidators.create(field, false).length).toBe(2); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should format to empty string if null', () => { |
|
|
|
@ -192,10 +210,10 @@ describe('TagsField', () => { |
|
|
|
}); |
|
|
|
|
|
|
|
describe('BooleanField', () => { |
|
|
|
const field = createField(new BooleanFieldPropertiesDto('Checkbox', { isRequired: true })); |
|
|
|
const field = createField({ properties: new BooleanFieldPropertiesDto('Checkbox', { isRequired: true }) }); |
|
|
|
|
|
|
|
it('should create validators', () => { |
|
|
|
expect(FieldValidatorsFactory.createValidators(field, false).length).toBe(1); |
|
|
|
expect(FieldsValidators.create(field, false).length).toBe(1); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should format to empty string if null', () => { |
|
|
|
@ -211,7 +229,7 @@ describe('BooleanField', () => { |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return default value for default properties', () => { |
|
|
|
const field2 = createField(new BooleanFieldPropertiesDto('Checkbox', { defaultValue: true })); |
|
|
|
const field2 = createField({ properties: new BooleanFieldPropertiesDto('Checkbox', { defaultValue: true }) }); |
|
|
|
|
|
|
|
expect(FieldDefaultValue.get(field2)).toBeTruthy(); |
|
|
|
}); |
|
|
|
@ -219,10 +237,10 @@ describe('BooleanField', () => { |
|
|
|
|
|
|
|
describe('DateTimeField', () => { |
|
|
|
const now = DateTime.parseISO_UTC('2017-10-12T16:30:10Z'); |
|
|
|
const field = createField(new DateTimeFieldPropertiesDto('DateTime', { isRequired: true })); |
|
|
|
const field = createField({ properties: new DateTimeFieldPropertiesDto('DateTime', { isRequired: true }) }); |
|
|
|
|
|
|
|
it('should create validators', () => { |
|
|
|
expect(FieldValidatorsFactory.createValidators(field, false).length).toBe(1); |
|
|
|
expect(FieldsValidators.create(field, false).length).toBe(1); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should format to empty string if null', () => { |
|
|
|
@ -234,41 +252,41 @@ describe('DateTimeField', () => { |
|
|
|
}); |
|
|
|
|
|
|
|
it('should format to date', () => { |
|
|
|
const dateField = createField(new DateTimeFieldPropertiesDto('Date')); |
|
|
|
const dateField = createField({ properties: new DateTimeFieldPropertiesDto('Date') }); |
|
|
|
|
|
|
|
expect(FieldFormatter.format(dateField, '2017-12-12T16:00:00Z')).toBe('2017-12-12'); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should format to date time', () => { |
|
|
|
const field2 = createField(new DateTimeFieldPropertiesDto('DateTime')); |
|
|
|
const field2 = createField({ properties: new DateTimeFieldPropertiesDto('DateTime') }); |
|
|
|
|
|
|
|
expect(FieldFormatter.format(field2, '2017-12-12T16:00:00Z')).toBe('2017-12-12 16:00:00'); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return default for DateFieldProperties', () => { |
|
|
|
const field2 = createField(new DateTimeFieldPropertiesDto('DateTime', { defaultValue: '2017-10-12T16:00:00Z' })); |
|
|
|
const field2 = createField({ properties: new DateTimeFieldPropertiesDto('DateTime', { defaultValue: '2017-10-12T16:00:00Z' }) }); |
|
|
|
|
|
|
|
expect(FieldDefaultValue.get(field2)).toEqual('2017-10-12T16:00:00Z'); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return calculated date when Today for DateFieldProperties', () => { |
|
|
|
const field2 = createField(new DateTimeFieldPropertiesDto('DateTime', { calculatedDefaultValue: 'Today' })); |
|
|
|
const field2 = createField({ properties: new DateTimeFieldPropertiesDto('DateTime', { calculatedDefaultValue: 'Today' }) }); |
|
|
|
|
|
|
|
expect(FieldDefaultValue.get(field2, now)).toEqual('2017-10-12'); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return calculated date when Now for DateFieldProperties', () => { |
|
|
|
const field2 = createField(new DateTimeFieldPropertiesDto('DateTime', { calculatedDefaultValue: 'Now' })); |
|
|
|
const field2 = createField({ properties: new DateTimeFieldPropertiesDto('DateTime', { calculatedDefaultValue: 'Now' }) }); |
|
|
|
|
|
|
|
expect(FieldDefaultValue.get(field2, now)).toEqual('2017-10-12T16:30:10Z'); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
describe('GeolocationField', () => { |
|
|
|
const field = createField(new GeolocationFieldPropertiesDto({ isRequired: true })); |
|
|
|
const field = createField({ properties: new GeolocationFieldPropertiesDto({ isRequired: true }) }); |
|
|
|
|
|
|
|
it('should create validators', () => { |
|
|
|
expect(FieldValidatorsFactory.createValidators(field, false).length).toBe(1); |
|
|
|
expect(FieldsValidators.create(field, false).length).toBe(1); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should format to empty string if null', () => { |
|
|
|
@ -285,10 +303,10 @@ describe('GeolocationField', () => { |
|
|
|
}); |
|
|
|
|
|
|
|
describe('JsonField', () => { |
|
|
|
const field = createField(new JsonFieldPropertiesDto({ isRequired: true })); |
|
|
|
const field = createField({ properties: new JsonFieldPropertiesDto({ isRequired: true }) }); |
|
|
|
|
|
|
|
it('should create validators', () => { |
|
|
|
expect(FieldValidatorsFactory.createValidators(field, false).length).toBe(1); |
|
|
|
expect(FieldsValidators.create(field, false).length).toBe(1); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should format to empty string if null', () => { |
|
|
|
@ -305,10 +323,10 @@ describe('JsonField', () => { |
|
|
|
}); |
|
|
|
|
|
|
|
describe('NumberField', () => { |
|
|
|
const field = createField(new NumberFieldPropertiesDto('Input', { isRequired: true, minValue: 1, maxValue: 6, allowedValues: [1, 3] })); |
|
|
|
const field = createField({ properties: new NumberFieldPropertiesDto('Input', { isRequired: true, minValue: 1, maxValue: 6, allowedValues: [1, 3] }) }); |
|
|
|
|
|
|
|
it('should create validators', () => { |
|
|
|
expect(FieldValidatorsFactory.createValidators(field, false).length).toBe(3); |
|
|
|
expect(FieldsValidators.create(field, false).length).toBe(3); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should format to empty string if null', () => { |
|
|
|
@ -320,47 +338,47 @@ describe('NumberField', () => { |
|
|
|
}); |
|
|
|
|
|
|
|
it('should format to stars if html allowed', () => { |
|
|
|
const field2 = createField(new NumberFieldPropertiesDto('Stars')); |
|
|
|
const field2 = createField({ properties: new NumberFieldPropertiesDto('Stars') }); |
|
|
|
|
|
|
|
expect(FieldFormatter.format(field2, 3)).toEqual(new HtmlValue('★ ★ ★ ')); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should format to short star view for many stars', () => { |
|
|
|
const field2 = createField(new NumberFieldPropertiesDto('Stars')); |
|
|
|
const field2 = createField({ properties: new NumberFieldPropertiesDto('Stars') }); |
|
|
|
|
|
|
|
expect(FieldFormatter.format(field2, 42)).toEqual(new HtmlValue('★ 42')); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should format to short star view for no stars', () => { |
|
|
|
const field2 = createField(new NumberFieldPropertiesDto('Stars')); |
|
|
|
const field2 = createField({ properties: new NumberFieldPropertiesDto('Stars') }); |
|
|
|
|
|
|
|
expect(FieldFormatter.format(field2, 0)).toEqual(new HtmlValue('★ 0')); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should format to short star view for negative stars', () => { |
|
|
|
const field2 = createField(new NumberFieldPropertiesDto('Stars')); |
|
|
|
const field2 = createField({ properties: new NumberFieldPropertiesDto('Stars') }); |
|
|
|
|
|
|
|
expect(FieldFormatter.format(field2, -13)).toEqual(new HtmlValue('★ -13')); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should not format to stars if html not allowed', () => { |
|
|
|
const field2 = createField(new NumberFieldPropertiesDto('Stars')); |
|
|
|
const field2 = createField({ properties: new NumberFieldPropertiesDto('Stars') }); |
|
|
|
|
|
|
|
expect(FieldFormatter.format(field2, 3, false)).toEqual('3'); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return default value for default properties', () => { |
|
|
|
const field2 = createField(new NumberFieldPropertiesDto('Input', { defaultValue: 13 })); |
|
|
|
const field2 = createField({ properties: new NumberFieldPropertiesDto('Input', { defaultValue: 13 }) }); |
|
|
|
|
|
|
|
expect(FieldDefaultValue.get(field2)).toEqual(13); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
describe('ReferencesField', () => { |
|
|
|
const field = createField(new ReferencesFieldPropertiesDto('List', { isRequired: true, minItems: 1, maxItems: 5 })); |
|
|
|
const field = createField({ properties: new ReferencesFieldPropertiesDto('List', { isRequired: true, minItems: 1, maxItems: 5 }) }); |
|
|
|
|
|
|
|
it('should create validators', () => { |
|
|
|
expect(FieldValidatorsFactory.createValidators(field, false).length).toBe(3); |
|
|
|
expect(FieldsValidators.create(field, false).length).toBe(3); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should format to empty string if null', () => { |
|
|
|
@ -381,10 +399,10 @@ describe('ReferencesField', () => { |
|
|
|
}); |
|
|
|
|
|
|
|
describe('StringField', () => { |
|
|
|
const field = createField(new StringFieldPropertiesDto('Input', { isRequired: true, pattern: 'pattern', minLength: 1, maxLength: 5, allowedValues: ['a', 'b'] })); |
|
|
|
const field = createField({ properties: new StringFieldPropertiesDto('Input', { isRequired: true, pattern: 'pattern', minLength: 1, maxLength: 5, allowedValues: ['a', 'b'] }) }); |
|
|
|
|
|
|
|
it('should create validators', () => { |
|
|
|
expect(FieldValidatorsFactory.createValidators(field, false).length).toBe(4); |
|
|
|
expect(FieldsValidators.create(field, false).length).toBe(4); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should format to empty string if null', () => { |
|
|
|
@ -396,7 +414,7 @@ describe('StringField', () => { |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return default value for default properties', () => { |
|
|
|
const field2 = createField(new StringFieldPropertiesDto('Input', { defaultValue: 'MyDefault' })); |
|
|
|
const field2 = createField({ properties: new StringFieldPropertiesDto('Input', { defaultValue: 'MyDefault' }) }); |
|
|
|
|
|
|
|
expect(FieldDefaultValue.get(field2)).toEqual('MyDefault'); |
|
|
|
}); |
|
|
|
@ -404,8 +422,8 @@ describe('StringField', () => { |
|
|
|
|
|
|
|
describe('GetContentValue', () => { |
|
|
|
const language = new LanguageDto('en', 'English'); |
|
|
|
const fieldInvariant = createField(new NumberFieldPropertiesDto('Input'), 1, 'invariant'); |
|
|
|
const fieldLocalized = createField(new NumberFieldPropertiesDto('Input')); |
|
|
|
const fieldInvariant = createField({ properties: new NumberFieldPropertiesDto('Input'), partitioning: 'invariant' }); |
|
|
|
const fieldLocalized = createField({ properties: new NumberFieldPropertiesDto('Input') }); |
|
|
|
|
|
|
|
it('should resolve invariant field from references value', () => { |
|
|
|
const content: any = { |
|
|
|
@ -498,10 +516,268 @@ describe('GetContentValue', () => { |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
function createSchema(properties: SchemaPropertiesDto, index = 1, fields: RootFieldDto[]) { |
|
|
|
return new SchemaDetailsDto({}, 'id' + index, 'schema' + index, '', properties, false, true, null!, null!, null!, null!, null!, fields); |
|
|
|
describe('ContentForm', () => { |
|
|
|
const languages = ImmutableArray.of([ |
|
|
|
new AppLanguageDto({}, 'en', 'English', true, false, []), |
|
|
|
new AppLanguageDto({}, 'de', 'English', false, true, []) |
|
|
|
]); |
|
|
|
|
|
|
|
const complexSchema = createSchema({ fields: [ |
|
|
|
createField({ id: 1, properties: createProperties('String'), partitioning: 'invariant' }), |
|
|
|
createField({ id: 2, properties: createProperties('String'), isDisabled: true }), |
|
|
|
createField({ id: 3, properties: createProperties('String', { isRequired: true }) }), |
|
|
|
createField({ id: 4, properties: createProperties('Array'), partitioning: 'invariant', nested: [ |
|
|
|
createNestedField({ id: 41, properties: createProperties('String') }), |
|
|
|
createNestedField({ id: 42, properties: createProperties('String', { defaultValue: 'Default' }), isDisabled: true }) |
|
|
|
]}) |
|
|
|
]}); |
|
|
|
|
|
|
|
describe('should resolve partitions', () => { |
|
|
|
const partitions = new PartitionConfig(languages); |
|
|
|
|
|
|
|
it('should return invariant partitions', () => { |
|
|
|
const result = partitions.getAll(createField({ id: 3, properties: createProperties('String'), partitioning: 'invariant' })); |
|
|
|
|
|
|
|
expect(result).toEqual([ |
|
|
|
{ key: 'iv', isOptional: false } |
|
|
|
]); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return language partitions', () => { |
|
|
|
const result = partitions.getAll(createField({ id: 3, properties: createProperties('String') })); |
|
|
|
|
|
|
|
expect(result).toEqual([ |
|
|
|
{ key: 'en', isOptional: false }, |
|
|
|
{ key: 'de', isOptional: true } |
|
|
|
]); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return partition for language', () => { |
|
|
|
const result = partitions.get(languages.at(1)); |
|
|
|
|
|
|
|
expect(result).toEqual({ key: 'de', isOptional: true }); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should return partition for no language', () => { |
|
|
|
const result = partitions.get(); |
|
|
|
|
|
|
|
expect(result).toEqual({ key: 'iv', isOptional: false }); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
describe('with complex form', () => { |
|
|
|
it('should not enabled disabled fields', () => { |
|
|
|
const contentForm = createForm([ |
|
|
|
createField({ id: 1, properties: createProperties('String') }), |
|
|
|
createField({ id: 2, properties: createProperties('String'), isDisabled: true }) |
|
|
|
]); |
|
|
|
|
|
|
|
expectForm(contentForm.form, 'field1', { disabled: false }); |
|
|
|
expectForm(contentForm.form, 'field2', { disabled: true }); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should not create required validator for optional language', () => { |
|
|
|
const contentForm = createForm([ |
|
|
|
createField({ id: 3, properties: createProperties('String', { isRequired: true }) }) |
|
|
|
]); |
|
|
|
|
|
|
|
expectForm(contentForm.form, 'field3.en', { invalid: true }); |
|
|
|
expectForm(contentForm.form, 'field3.de', { invalid: false }); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should load with array and not enable disabled nested fields', () => { |
|
|
|
const contentForm = createForm([ |
|
|
|
createField({ id: 4, properties: createProperties('Array'), partitioning: 'invariant', nested: [ |
|
|
|
createNestedField({ id: 41, properties: createProperties('String') }), |
|
|
|
createNestedField({ id: 42, properties: createProperties('String'), isDisabled: true }) |
|
|
|
]}) |
|
|
|
]); |
|
|
|
|
|
|
|
contentForm.load({ |
|
|
|
field4: { |
|
|
|
iv: [{ |
|
|
|
nested41: 'Text' |
|
|
|
}] |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
const nestedForm = contentForm.form.get('field4.iv') as FormArray; |
|
|
|
const nestedItem = nestedForm.get([0])!; |
|
|
|
|
|
|
|
expect(nestedForm.controls.length).toBe(1); |
|
|
|
|
|
|
|
expectForm(nestedItem, 'nested41', { disabled: false, value: 'Text' }); |
|
|
|
expectForm(nestedItem, 'nested42', { disabled: true, value: null }); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should add array item', () => { |
|
|
|
const contentForm = createForm([ |
|
|
|
createField({ id: 4, properties: createProperties('Array'), partitioning: 'invariant', nested: [ |
|
|
|
createNestedField({ id: 41, properties: createProperties('String') }), |
|
|
|
createNestedField({ id: 42, properties: createProperties('String', { defaultValue: 'Default' }), isDisabled: true }) |
|
|
|
]}) |
|
|
|
]); |
|
|
|
|
|
|
|
contentForm.arrayItemInsert(complexSchema.fields[3], languages[0]); |
|
|
|
|
|
|
|
const nestedForm = contentForm.form.get('field4.iv') as FormArray; |
|
|
|
const nestedItem = nestedForm.get([0])!; |
|
|
|
|
|
|
|
expect(nestedForm.controls.length).toBe(1); |
|
|
|
|
|
|
|
expectForm(nestedItem, 'nested41', { disabled: false, value: null }); |
|
|
|
expectForm(nestedItem, 'nested42', { disabled: true, value: 'Default' }); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should remove array item', () => { |
|
|
|
const contentForm = createForm([ |
|
|
|
createField({ id: 4, properties: createProperties('Array'), partitioning: 'invariant', nested: [ |
|
|
|
createNestedField({ id: 41, properties: createProperties('String') }) |
|
|
|
]}) |
|
|
|
]); |
|
|
|
|
|
|
|
contentForm.arrayItemInsert(complexSchema.fields[3], languages[0]); |
|
|
|
contentForm.arrayItemRemove(complexSchema.fields[3], languages[0], 0); |
|
|
|
|
|
|
|
const nestedForm = contentForm.form.get('field4.iv') as FormArray; |
|
|
|
|
|
|
|
expect(nestedForm.controls.length).toBe(0); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should not array item if field has no nested fields', () => { |
|
|
|
const contentForm = createForm([ |
|
|
|
createField({ id: 4, properties: createProperties('Array'), partitioning: 'invariant' }) |
|
|
|
]); |
|
|
|
const nestedForm = contentForm.form.get('field4.iv') as FormArray; |
|
|
|
|
|
|
|
expect(nestedForm.controls.length).toBe(0); |
|
|
|
}); |
|
|
|
|
|
|
|
function expectForm(parent: AbstractControl, path: string, test: { invalid?: boolean, disabled?: boolean, value?: any }) { |
|
|
|
const form = parent.get(path); |
|
|
|
|
|
|
|
if (form) { |
|
|
|
for (let key in test) { |
|
|
|
if (test.hasOwnProperty(key)) { |
|
|
|
const a = form[key]; |
|
|
|
const e = test[key]; |
|
|
|
|
|
|
|
expect(a).toBe(e, `Expected ${key} of ${path} to be <${e}>, but found <${a}>.`); |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
expect(form).not.toBeNull(`Expected to find form ${path}, but form not found.`); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
describe('for new content', () => { |
|
|
|
let simpleForm: EditContentForm; |
|
|
|
|
|
|
|
beforeEach(() => { |
|
|
|
simpleForm = createForm([ |
|
|
|
createField({ id: 1, properties: createProperties('String'), partitioning: 'invariant' }) |
|
|
|
]); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should not be an unsaved change when nothing has changed', () => { |
|
|
|
expect(simpleForm.hasChanged()).toBeFalsy(); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should be an unsaved change when value has changed but not saved', () => { |
|
|
|
simpleForm.form.setValue({ field1: { iv: 'Change' }}); |
|
|
|
|
|
|
|
expect(simpleForm.hasChanged()).toBeTruthy(); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should not be an unsaved change when value has changed and saved', () => { |
|
|
|
simpleForm.form.setValue({ field1: { iv: 'Change' }}); |
|
|
|
simpleForm.submit(); |
|
|
|
simpleForm.submitCompleted(); |
|
|
|
|
|
|
|
expect(simpleForm.hasChanged()).toBeFalsy(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
describe('for editing content', () => { |
|
|
|
let simpleForm: EditContentForm; |
|
|
|
|
|
|
|
beforeEach(() => { |
|
|
|
simpleForm = createForm([ |
|
|
|
createField({ id: 1, properties: createProperties('String'), partitioning: 'invariant' }) |
|
|
|
]); |
|
|
|
simpleForm.load({ field1: { iv: 'Initial' } }, true); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should not be an unsaved change when nothing has changed', () => { |
|
|
|
simpleForm.load({ field1: { iv: 'Initial' } }, true); |
|
|
|
|
|
|
|
expect(simpleForm.hasChanged()).toBeFalsy(); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should be an unsaved change when value has changed but not saved', () => { |
|
|
|
simpleForm.form.setValue({ field1: { iv: 'Change' }}); |
|
|
|
|
|
|
|
expect(simpleForm.hasChanged()).toBeTruthy(); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should be an unsaved change when value has been loaded but not saved', () => { |
|
|
|
simpleForm.load({ field1: { iv: 'Prev' } }); |
|
|
|
|
|
|
|
expect(simpleForm.hasChanged()).toBeTruthy(); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should not be an unsaved change when value has changed and saved', () => { |
|
|
|
simpleForm.form.setValue({ field1: { iv: 'Change' }}); |
|
|
|
simpleForm.submit(); |
|
|
|
simpleForm.submitCompleted(); |
|
|
|
|
|
|
|
expect(simpleForm.hasChanged()).toBeFalsy(); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should not be an unsaved change when value has been loaded but not saved', () => { |
|
|
|
simpleForm.load({ field1: { iv: 'Prev' } }); |
|
|
|
simpleForm.submit(); |
|
|
|
simpleForm.submitCompleted(); |
|
|
|
|
|
|
|
expect(simpleForm.hasChanged()).toBeFalsy(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
function createForm(fields: RootFieldDto[]) { |
|
|
|
return new EditContentForm(languages, |
|
|
|
createSchema({ fields })); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
type SchemaValues = { properties?: SchemaPropertiesDto; id?: number; fields?: RootFieldDto[]; }; |
|
|
|
|
|
|
|
function createSchema({ properties, id, fields }: SchemaValues = {}) { |
|
|
|
id = id || 1; |
|
|
|
|
|
|
|
return new SchemaDetailsDto({}, |
|
|
|
`schema${1}`, |
|
|
|
`schema${1}`, |
|
|
|
'category', |
|
|
|
properties || new SchemaPropertiesDto(), false, true, |
|
|
|
creation, |
|
|
|
creator, |
|
|
|
modified, |
|
|
|
modifier, |
|
|
|
new Version('1'), |
|
|
|
fields); |
|
|
|
} |
|
|
|
|
|
|
|
type FieldValues = { properties: FieldPropertiesDto; id?: number; partitioning?: string; isDisabled?: boolean, nested?: NestedFieldDto[] }; |
|
|
|
|
|
|
|
function createField({ properties, id, partitioning, isDisabled, nested }: FieldValues) { |
|
|
|
id = id || 1; |
|
|
|
|
|
|
|
return new RootFieldDto({}, id, `field${id}`, properties, partitioning || 'language', false, false, isDisabled, nested); |
|
|
|
} |
|
|
|
|
|
|
|
function createField(properties: FieldPropertiesDto, index = 1, partitioning = 'language') { |
|
|
|
return new RootFieldDto({}, index, 'field' + index, properties, partitioning); |
|
|
|
function createNestedField({ properties, id, isDisabled }: FieldValues) { |
|
|
|
id = id || 1; |
|
|
|
|
|
|
|
return new NestedFieldDto({}, id, `nested${id}`, properties, 0, false, false, isDisabled); |
|
|
|
} |