Exemplo n.º 1
0
        public void Clear_Cache_Removes_Specific_Editors()
        {
            var sut = new ValueEditorCache();

            var dataEditor1 = new FakeDataEditor("Editor 1");
            var dataEditor2 = new FakeDataEditor("Editor 2");

            IDataType dataType1 = CreateDataTypeMock(1).Object;
            IDataType dataType2 = CreateDataTypeMock(2).Object;

            // Load the editors into cache
            IDataValueEditor editor1DataType1 = sut.GetValueEditor(dataEditor1, dataType1);
            IDataValueEditor editor1Datatype2 = sut.GetValueEditor(dataEditor1, dataType2);
            IDataValueEditor editor2DataType1 = sut.GetValueEditor(dataEditor2, dataType1);
            IDataValueEditor editor2Datatype2 = sut.GetValueEditor(dataEditor2, dataType2);

            sut.ClearCache(new [] { dataType1.Id });

            // New value editor objects should be created after it's cleared
            Assert.AreNotSame(editor1DataType1, sut.GetValueEditor(dataEditor1, dataType1), "Value editor was not cleared from cache");
            Assert.AreNotSame(editor2DataType1, sut.GetValueEditor(dataEditor2, dataType1), "Value editor was not cleared from cache");

            // But the value editors for data type 2 should be the same
            Assert.AreSame(editor1Datatype2, sut.GetValueEditor(dataEditor1, dataType2), "Too many editors was cleared from cache");
            Assert.AreSame(editor2Datatype2, sut.GetValueEditor(dataEditor2, dataType2), "Too many editors was cleared from cache");
        }
    /// <inheritdoc />
    protected override IDataValueEditor CreateValueEditor()
    {
        IDataValueEditor editor = base.CreateValueEditor();

        editor.Validators.Add(new DateTimeValidator());
        return(editor);
    }
Exemplo n.º 3
0
    /// <inheritdoc />
    protected override IDataValueEditor CreateValueEditor()
    {
        IDataValueEditor editor = base.CreateValueEditor();

        editor.Validators.Add(new IntegerValidator()); // ensure the value is validated
        return(editor);
    }
        public override IDataValueEditor GetValueEditor(object configuration)
        {
            IDataValueEditor editor = base.GetValueEditor(configuration);

            if (editor is DataValueEditor dve)
            {
                dve.View += $"?v={_backOfficeHelper.GetCacheBuster()}";
            }

            return(editor);
        }
Exemplo n.º 5
0
        public void Different_Data_Types_Returns_Different_Value_Editors()
        {
            var       sut        = new ValueEditorCache();
            var       dataEditor = new FakeDataEditor("Editor");
            IDataType dataType1  = CreateDataTypeMock(1).Object;
            IDataType dataType2  = CreateDataTypeMock(2).Object;

            IDataValueEditor firstEditor  = sut.GetValueEditor(dataEditor, dataType1);
            IDataValueEditor secondEditor = sut.GetValueEditor(dataEditor, dataType2);

            Assert.AreNotSame(firstEditor, secondEditor);
        }
        public void DropDownMultipleValueEditor_Format_Data_For_Cache()
        {
            var dataValueEditorFactoryMock = new Mock <IDataValueEditorFactory>();
            var serializer = new ConfigurationEditorJsonSerializer();
            var checkBoxListPropertyEditor = new CheckBoxListPropertyEditor(dataValueEditorFactoryMock.Object, Mock.Of <ILocalizedTextService>(), Mock.Of <IIOHelper>(), Mock.Of <IEditorConfigurationParser>());
            var dataType = new DataType(checkBoxListPropertyEditor, serializer)
            {
                Configuration = new ValueListConfiguration
                {
                    Items = new List <ValueListConfiguration.ValueListItem>
                    {
                        new ValueListConfiguration.ValueListItem {
                            Id = 4567, Value = "Value 1"
                        },
                        new ValueListConfiguration.ValueListItem {
                            Id = 1234, Value = "Value 2"
                        },
                        new ValueListConfiguration.ValueListItem {
                            Id = 8910, Value = "Value 3"
                        }
                    }
                },
                Id = 1
            };

            var dataTypeServiceMock = new Mock <IDataTypeService>();

            dataTypeServiceMock
            .Setup(x => x.GetDataType(It.IsAny <int>()))
            .Returns(dataType);

            //TODO use builders instead of this mess
            var multipleValueEditor = new MultipleValueEditor(Mock.Of <ILocalizedTextService>(), Mock.Of <IShortStringHelper>(), Mock.Of <IJsonSerializer>(), Mock.Of <IIOHelper>(), new DataEditorAttribute(Constants.PropertyEditors.Aliases.TextBox, "Test Textbox", "textbox"));

            dataValueEditorFactoryMock
            .Setup(x => x.Create <MultipleValueEditor>(It.IsAny <DataEditorAttribute>()))
            .Returns(multipleValueEditor);

            var prop = new Property(1, new PropertyType(Mock.Of <IShortStringHelper>(), dataType));

            prop.SetValue("Value 1,Value 2,Value 3");

            IDataValueEditor valueEditor = dataType.Editor.GetValueEditor();

            ((DataValueEditor)valueEditor).Configuration = dataType.Configuration;
            var result = valueEditor.ConvertDbToString(prop.PropertyType, prop.GetValue());

            Assert.AreEqual("Value 1,Value 2,Value 3", result);
        }
Exemplo n.º 7
0
        public override IDataValueEditor GetValueEditor(object configuration)
        {
            IDataValueEditor editor = base.GetValueEditor(configuration);

            if (editor is DataValueEditor dve)
            {
                dve.View     += $"?v={_backOfficeHelper.GetCacheBuster()}";
                dve.HideLabel = configuration is InboundRedirectsConfiguration {
                    HideLabel : true
                };
            }

            return(editor);
        }
    }
    /// <summary>
    ///     Determines whether a value is valid for this property type.
    /// </summary>
    private bool IsPropertyValueValid(IPropertyType propertyType, object?value)
    {
        IDataEditor?editor = _propertyEditors[propertyType.PropertyEditorAlias];

        if (editor == null)
        {
            // nothing much we can do validation wise if the property editor has been removed.
            // the property will be displayed as a label, so flagging it as invalid would be pointless.
            return(true);
        }

        var configuration            = _dataTypeService.GetDataType(propertyType.DataTypeId)?.Configuration;
        IDataValueEditor valueEditor = editor.GetValueEditor(configuration);

        return(!valueEditor.Validate(value, propertyType.Mandatory, propertyType.ValidationRegExp).Any());
    }
Exemplo n.º 9
0
        public void CanParseManifest_ParameterEditors()
        {
            const string json = @"{'parameterEditors': [
    {
        alias: 'parameter1',
        name: 'My Parameter',
        view: '~/App_Plugins/MyPackage/PropertyEditors/MyEditor.html'
    },
    {
        alias: 'parameter2',
        name: 'Another parameter',
        config: { key1: 'some config val' },
        view: '~/App_Plugins/MyPackage/PropertyEditors/CsvEditor.html'
    },
    {
        alias: 'parameter3',
        name: 'Yet another parameter'
    }
]}";

            PackageManifest manifest = _parser.ParseManifest(json);

            Assert.AreEqual(3, manifest.ParameterEditors.Length);

            Assert.IsTrue(manifest.ParameterEditors.All(x => (x.Type & EditorType.MacroParameter) > 0));

            IDataEditor editor = manifest.ParameterEditors[1];

            Assert.AreEqual("parameter2", editor.Alias);
            Assert.AreEqual("Another parameter", editor.Name);

            IDictionary <string, object> config = editor.DefaultConfiguration;

            Assert.AreEqual(1, config.Count);
            Assert.IsTrue(config.ContainsKey("key1"));
            Assert.AreEqual("some config val", config["key1"]);

            IDataValueEditor valueEditor = editor.GetValueEditor();

            Assert.AreEqual(_ioHelper.ResolveUrl("/App_Plugins/MyPackage/PropertyEditors/CsvEditor.html"), valueEditor.View);

            editor = manifest.ParameterEditors[2];
            Assert.Throws <InvalidOperationException>(() =>
            {
                IDataValueEditor valueEditor = editor.GetValueEditor();
            });
        }
Exemplo n.º 10
0
        public void Caches_ValueEditor()
        {
            var sut = new ValueEditorCache();

            var       dataEditor = new FakeDataEditor("TestEditor");
            IDataType dataType   = CreateDataTypeMock(1).Object;

            // Request the same value editor twice
            IDataValueEditor firstEditor  = sut.GetValueEditor(dataEditor, dataType);
            IDataValueEditor secondEditor = sut.GetValueEditor(dataEditor, dataType);

            Assert.Multiple(() =>
            {
                Assert.AreSame(firstEditor, secondEditor);
                Assert.AreEqual(1, dataEditor.ValueEditorCount, "GetValueEditor invoked more than once.");
            });
        }
        public ElementsPropertyType(PropertyType propertyType, IDataType dataType)
        {
            IDataValueEditor valueEditor = dataType.Editor.GetValueEditor(dataType.Configuration);

            DataType = new ElementsDataType(dataType);

            Alias       = propertyType.Alias;
            Label       = propertyType.Name;
            Description = propertyType.Description;
            View        = valueEditor.View;
            Config      = DataType.Config;
            HideLabel   = valueEditor.HideLabel;
            Validation  = new ElementsValidation(propertyType);
            IsReadOnly  = valueEditor.IsReadOnly;
            DataTypeKey = propertyType.DataTypeKey;
            Editor      = dataType.EditorAlias;
        }
Exemplo n.º 12
0
        public override IDataEditor Build()
        {
            var name  = _name ?? Guid.NewGuid().ToString();
            var alias = _alias ?? name.ToCamelCase();

            IDictionary <string, object> defaultConfiguration        = _defaultConfiguration ?? new Dictionary <string, object>();
            IConfigurationEditor         explicitConfigurationEditor = _explicitConfigurationEditorBuilder.Build();
            IDataValueEditor             explicitValueEditor         = _explicitValueEditorBuilder.Build();

            return(new DataEditor(
                       Mock.Of <IDataValueEditorFactory>())
            {
                Alias = alias,
                Name = name,
                DefaultConfiguration = defaultConfiguration,
                ExplicitConfigurationEditor = explicitConfigurationEditor,
                ExplicitValueEditor = explicitValueEditor
            });
        }
Exemplo n.º 13
0
        /// <inheritdoc />
        public IEnumerable <ValidationResult> ValidatePropertyValue(
            IDataEditor editor,
            IDataType dataType,
            object?postedValue,
            bool isRequired,
            string?validationRegExp,
            string?isRequiredMessage,
            string?validationRegExpMessage)
        {
            // Retrieve default messages used for required and regex validatation.  We'll replace these
            // if set with custom ones if they've been provided for a given property.
            var requiredDefaultMessages = new[]
            {
                _textService.Localize("validation", "invalidNull"),
                _textService.Localize("validation", "invalidEmpty")
            };
            var formatDefaultMessages = new[]
            {
                _textService.Localize("validation", "invalidPattern"),
            };

            IDataValueEditor valueEditor = _valueEditorCache.GetValueEditor(editor, dataType);

            foreach (var validationResult in valueEditor.Validate(postedValue, isRequired, validationRegExp))
            {
                // If we've got custom error messages, we'll replace the default ones that will have been applied in the call to Validate().
                if (isRequired && !string.IsNullOrWhiteSpace(isRequiredMessage) && requiredDefaultMessages.Contains(validationResult.ErrorMessage, StringComparer.OrdinalIgnoreCase))
                {
                    validationResult.ErrorMessage = isRequiredMessage;
                }
                if (!string.IsNullOrWhiteSpace(validationRegExp) && !string.IsNullOrWhiteSpace(validationRegExpMessage) && formatDefaultMessages.Contains(validationResult.ErrorMessage, StringComparer.OrdinalIgnoreCase))
                {
                    validationResult.ErrorMessage = validationRegExpMessage;
                }
                yield return(validationResult);
            }
        }
Exemplo n.º 14
0
        public void CanParseManifest_PropertyEditors()
        {
            const string json = @"{'propertyEditors': [
    {
        alias: 'Test.Test1',
        name: 'Test 1',
        editor: {
            view: '~/App_Plugins/MyPackage/PropertyEditors/MyEditor.html',
            valueType: 'int',
            hideLabel: true,
            validation: {
                'required': true,
                'Regex': '\\d*'
            }
        },
        prevalues: {
                fields: [
                    {
                        label: 'Some config 1',
                        key: 'key1',
                        view: '~/App_Plugins/MyPackage/PropertyEditors/Views/pre-val1.html',
                        validation: {
                            required: true
                        }
                    },
                    {
                        label: 'Some config 2',
                        key: 'key2',
                        view: '~/App_Plugins/MyPackage/PropertyEditors/Views/pre-val2.html'
                    }
                ]
            }
    },
    {
        alias: 'Test.Test2',
        name: 'Test 2',
        isParameterEditor: true,
        defaultConfig: { key1: 'some default val' },
        editor: {
            view: '~/App_Plugins/MyPackage/PropertyEditors/MyEditor.html',
            valueType: 'int',
            validation: {
                required : true,
                regex : '\\d*'
            }
        }
    }
]}";

            PackageManifest manifest = _parser.ParseManifest(json);

            Assert.AreEqual(2, manifest.PropertyEditors.Length);

            IDataEditor editor = manifest.PropertyEditors[1];

            Assert.IsTrue((editor.Type & EditorType.MacroParameter) > 0);
            Assert.IsNotEmpty(editor.DefaultConfiguration);
            Assert.AreEqual("some default val", editor.DefaultConfiguration["key1"]);

            editor = manifest.PropertyEditors[0];
            Assert.AreEqual("Test.Test1", editor.Alias);
            Assert.AreEqual("Test 1", editor.Name);
            Assert.IsFalse((editor.Type & EditorType.MacroParameter) > 0);

            IDataValueEditor valueEditor = editor.GetValueEditor();

            Assert.AreEqual(_ioHelper.ResolveUrl("/App_Plugins/MyPackage/PropertyEditors/MyEditor.html"), valueEditor.View);
            Assert.AreEqual("int", valueEditor.ValueType);
            Assert.IsTrue(valueEditor.HideLabel);

            // these two don't make much sense here
            //// valueEditor.RegexValidator;
            //// valueEditor.RequiredValidator;

            List <IValueValidator> validators = valueEditor.Validators;

            Assert.AreEqual(2, validators.Count);
            IValueValidator validator = validators[0];
            var             v1        = validator as RequiredValidator;

            Assert.IsNotNull(v1);
            Assert.AreEqual("Required", v1.ValidationName);
            validator = validators[1];
            var v2 = validator as RegexValidator;

            Assert.IsNotNull(v2);
            Assert.AreEqual("Regex", v2.ValidationName);
            Assert.AreEqual("\\d*", v2.Configuration);

            // this is not part of the manifest
            IDictionary <string, object> preValues = editor.GetConfigurationEditor().DefaultConfiguration;

            Assert.IsEmpty(preValues);

            IConfigurationEditor preValueEditor = editor.GetConfigurationEditor();

            Assert.IsNotNull(preValueEditor);
            Assert.IsNotNull(preValueEditor.Fields);
            Assert.AreEqual(2, preValueEditor.Fields.Count);

            ConfigurationField f = preValueEditor.Fields[0];

            Assert.AreEqual("key1", f.Key);
            Assert.AreEqual("Some config 1", f.Name);
            Assert.AreEqual(_ioHelper.ResolveUrl("/App_Plugins/MyPackage/PropertyEditors/Views/pre-val1.html"), f.View);
            List <IValueValidator> fvalidators = f.Validators;

            Assert.IsNotNull(fvalidators);
            Assert.AreEqual(1, fvalidators.Count);
            var fv = fvalidators[0] as RequiredValidator;

            Assert.IsNotNull(fv);
            Assert.AreEqual("Required", fv.ValidationName);

            f = preValueEditor.Fields[1];
            Assert.AreEqual("key2", f.Key);
            Assert.AreEqual("Some config 2", f.Name);
            Assert.AreEqual(_ioHelper.ResolveUrl("/App_Plugins/MyPackage/PropertyEditors/Views/pre-val2.html"), f.View);
            fvalidators = f.Validators;
            Assert.IsNotNull(fvalidators);
            Assert.AreEqual(0, fvalidators.Count);
        }
Exemplo n.º 15
0
 /// <inheritdoc />
 /// <remarks>
 /// <para>If an explicit value editor has been assigned, then this explicit
 /// instance is returned. Otherwise, a new instance is created by CreateValueEditor.</para>
 /// <para>The instance created by CreateValueEditor is not cached, i.e.
 /// a new instance is created each time the property value is retrieved. The
 /// property editor is a singleton, and the value editor cannot be a singleton
 /// since it depends on the datatype configuration.</para>
 /// <para>Technically, it could be cached by datatype but let's keep things
 /// simple enough for now.</para>
 /// </remarks>
 // TODO: point of that one? shouldn't we always configure?
 public IDataValueEditor GetValueEditor() => ExplicitValueEditor ?? (_reusableEditor ?? (_reusableEditor = CreateValueEditor()));
        /// <summary>
        /// Maps the dto property values to the persisted model
        /// </summary>
        internal void MapPropertyValuesForPersistence <TPersisted, TSaved>(
            TSaved contentItem,
            ContentPropertyCollectionDto?dto,
            Func <TSaved, IProperty?, object?> getPropertyValue,
            Action <TSaved, IProperty?, object?> savePropertyValue,
            string?culture)
            where TPersisted : IContentBase
            where TSaved : IContentSave <TPersisted>
        {
            if (dto is null)
            {
                return;
            }

            // map the property values
            foreach (ContentPropertyDto propertyDto in dto.Properties)
            {
                // get the property editor
                if (propertyDto.PropertyEditor == null)
                {
                    _logger.LogWarning("No property editor found for property {PropertyAlias}", propertyDto.Alias);
                    continue;
                }

                // get the value editor
                // nothing to save/map if it is readonly
                IDataValueEditor valueEditor = propertyDto.PropertyEditor.GetValueEditor();
                if (valueEditor.IsReadOnly)
                {
                    continue;
                }

                // get the property
                IProperty property = contentItem.PersistedContent.Properties[propertyDto.Alias] !;

                // prepare files, if any matching property and culture
                ContentPropertyFile[] files = contentItem.UploadedFiles
                                              .Where(x => x.PropertyAlias == propertyDto.Alias && x.Culture == propertyDto.Culture && x.Segment == propertyDto.Segment)
                                              .ToArray();

                foreach (ContentPropertyFile file in files)
                {
                    file.FileName = file.FileName?.ToSafeFileName(ShortStringHelper);
                }


                // create the property data for the property editor
                var data = new ContentPropertyData(propertyDto.Value, propertyDto.DataType?.Configuration)
                {
                    ContentKey      = contentItem.PersistedContent !.Key,
                    PropertyTypeKey = property.PropertyType.Key,
                    Files           = files
                };

                // let the editor convert the value that was received, deal with files, etc
                object?value = valueEditor.FromEditor(data, getPropertyValue(contentItem, property));

                // set the value - tags are special
                TagsPropertyEditorAttribute?tagAttribute = propertyDto.PropertyEditor.GetTagAttribute();
                if (tagAttribute != null)
                {
                    TagConfiguration?tagConfiguration = ConfigurationEditor.ConfigurationAs <TagConfiguration>(propertyDto.DataType?.Configuration);
                    if (tagConfiguration is not null && tagConfiguration.Delimiter == default)
                    {
                        tagConfiguration.Delimiter = tagAttribute.Delimiter;
                    }

                    var tagCulture = property?.PropertyType.VariesByCulture() ?? false ? culture : null;
                    property?.SetTagsValue(_serializer, value, tagConfiguration, tagCulture);
                }
                else
                {
                    savePropertyValue(contentItem, property, value);
                }
            }
        }
Exemplo n.º 17
0
 public TextCountDataValueEditor(DataEditorAttribute attribute, IDataValueEditor wrapped, IDataTypeService dataTypeService) : base(attribute)
 {
     _wrapped         = wrapped;
     _dataTypeService = dataTypeService;
 }