Move test projects from src/ to tests/ (#11357)

* Update gitignore

* Move csproj

* Update project references

* Update solutions

* Update build scripts

* Tests used to share editorconfig with projects in src

* Fix broken tests.

* Stop copying around .editorconfig

merged root one with linting

* csharp_style_expression_bodied -> suggestion

* Move StyleCop rulesets to matching directories and update shared build properties

* Remove legacy build files, update NuGet.cofig and solution files

* Restore myget source

* Clean up .gitignore

* Update .gitignore

* Move new test classes to tests after merge

* Gitignore + nuget config

* Move new test

Co-authored-by: Ronald Barendse <ronald@barend.se>
This commit is contained in:
Paul Johnson
2021-10-18 08:14:04 +01:00
committed by GitHub
parent c005673a96
commit 00133e880d
752 changed files with 650 additions and 1844 deletions

View File

@@ -0,0 +1,105 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System;
using System.Reflection;
using System.Text;
using NUnit.Framework;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Services.Implement;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{
[TestFixture]
public class AmbiguousEventTests
{
[Explicit]
[TestCase(typeof(ContentService))]
[TestCase(typeof(MediaService))]
public void ListAmbiguousEvents(Type serviceType)
{
var typedEventHandler = typeof(TypedEventHandler<,>);
// get all events
var events = serviceType.GetEvents(BindingFlags.Static | BindingFlags.Public);
string TypeName(Type type)
{
if (!type.IsGenericType)
{
return type.Name;
}
var sb = new StringBuilder();
TypeNameSb(type, sb);
return sb.ToString();
}
void TypeNameSb(Type type, StringBuilder sb)
{
var name = type.Name;
var pos = name.IndexOf('`');
name = pos > 0 ? name.Substring(0, pos) : name;
sb.Append(name);
if (!type.IsGenericType)
{
return;
}
sb.Append("<");
var first = true;
foreach (var arg in type.GetGenericArguments())
{
if (first)
{
first = false;
}
else
{
sb.Append(", ");
}
TypeNameSb(arg, sb);
}
sb.Append(">");
}
foreach (var e in events)
{
// only continue if this is a TypedEventHandler
if (!e.EventHandlerType.IsGenericType)
{
continue;
}
var typeDef = e.EventHandlerType.GetGenericTypeDefinition();
if (typedEventHandler != typeDef)
{
continue;
}
// get the event args type
var eventArgsType = e.EventHandlerType.GenericTypeArguments[1];
// try to find the event back, based upon sender type + args type
// exclude -ing (eg Saving) events, we don't deal with them in EventDefinitionBase (they always trigger)
var found = EventNameExtractor.FindEvents(serviceType, eventArgsType, EventNameExtractor.MatchIngNames);
if (found.Length == 1)
{
continue;
}
if (found.Length == 0)
{
Console.WriteLine($"{typeof(ContentService).Name} {e.Name} {TypeName(eventArgsType)} NotFound");
continue;
}
Console.WriteLine($"{typeof(ContentService).Name} {e.Name} {TypeName(eventArgsType)} Ambiguous");
Console.WriteLine("\t" + string.Join(", ", found));
}
}
}
}

View File

@@ -0,0 +1,388 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using NUnit.Framework;
using Umbraco.Cms.Core.Services.Implement;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{
[TestFixture]
public class LocalizedTextServiceTests
{
private static readonly ILoggerFactory s_loggerFactory = NullLoggerFactory.Instance;
[Test]
public void Using_Dictionary_Gets_All_Stored_Values()
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
new Dictionary<CultureInfo, IDictionary<string, IDictionary<string, string>>>
{
{
culture, new Dictionary<string, IDictionary<string, string>>
{
{
"testArea1", new Dictionary<string, string>
{
{ "testKey1", "testValue1" },
{ "testKey2", "testValue2" }
}
},
{
"testArea2", new Dictionary<string, string>
{
{ "blah1", "blahValue1" },
{ "blah2", "blahValue2" }
}
},
}
}
}, s_loggerFactory.CreateLogger<LocalizedTextService>());
IDictionary<string, string> result = txtService.GetAllStoredValues(culture);
Assert.AreEqual(4, result.Count);
Assert.AreEqual("testArea1/testKey1", result.ElementAt(0).Key);
Assert.AreEqual("testArea1/testKey2", result.ElementAt(1).Key);
Assert.AreEqual("testArea2/blah1", result.ElementAt(2).Key);
Assert.AreEqual("testArea2/blah2", result.ElementAt(3).Key);
Assert.AreEqual("testValue1", result["testArea1/testKey1"]);
Assert.AreEqual("testValue2", result["testArea1/testKey2"]);
Assert.AreEqual("blahValue1", result["testArea2/blah1"]);
Assert.AreEqual("blahValue2", result["testArea2/blah2"]);
}
[Test]
public void Using_XDocument_Gets_All_Stored_Values()
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
new Dictionary<CultureInfo, Lazy<XDocument>>
{
{
culture, new Lazy<XDocument>(() => new XDocument(
new XElement(
"language",
new XElement("area", new XAttribute("alias", "testArea1"),
new XElement("key", new XAttribute("alias", "testKey1"), "testValue1"),
new XElement("key", new XAttribute("alias", "testKey2"), "testValue2")),
new XElement("area", new XAttribute("alias", "testArea2"),
new XElement("key", new XAttribute("alias", "blah1"), "blahValue1"),
new XElement("key", new XAttribute("alias", "blah2"), "blahValue2")))))
}
}, s_loggerFactory.CreateLogger<LocalizedTextService>());
IDictionary<string, string> result = txtService.GetAllStoredValues(culture);
Assert.AreEqual(4, result.Count());
Assert.AreEqual("testArea1/testKey1", result.ElementAt(0).Key);
Assert.AreEqual("testArea1/testKey2", result.ElementAt(1).Key);
Assert.AreEqual("testArea2/blah1", result.ElementAt(2).Key);
Assert.AreEqual("testArea2/blah2", result.ElementAt(3).Key);
Assert.AreEqual("testValue1", result["testArea1/testKey1"]);
Assert.AreEqual("testValue2", result["testArea1/testKey2"]);
Assert.AreEqual("blahValue1", result["testArea2/blah1"]);
Assert.AreEqual("blahValue2", result["testArea2/blah2"]);
}
[Test]
public void Using_XDocument_Gets_All_Stored_Values_With_Duplicates()
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
new Dictionary<CultureInfo, Lazy<XDocument>>
{
{
culture, new Lazy<XDocument>(() => new XDocument(
new XElement(
"language",
new XElement("area", new XAttribute("alias", "testArea1"),
new XElement("key", new XAttribute("alias", "testKey1"), "testValue1"),
new XElement("key", new XAttribute("alias", "testKey1"), "testValue1")))))
}
}, s_loggerFactory.CreateLogger<LocalizedTextService>());
IDictionary<string, string> result = txtService.GetAllStoredValues(culture);
Assert.AreEqual(1, result.Count());
}
[Test]
public void Using_Dictionary_Returns_Text_With_Area()
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
new Dictionary<CultureInfo, IDictionary<string, IDictionary<string, string>>>
{
{
culture, new Dictionary<string, IDictionary<string, string>>
{
{
"testArea", new Dictionary<string, string>
{
{ "testKey", "testValue" }
}
}
}
}
}, s_loggerFactory.CreateLogger<LocalizedTextService>());
string result = txtService.Localize("testArea/testKey", culture);
Assert.AreEqual("testValue", result);
}
[Test]
public void Using_Dictionary_Returns_Text_Without_Area()
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
new Dictionary<CultureInfo, IDictionary<string, IDictionary<string, string>>>
{
{
culture, new Dictionary<string, IDictionary<string, string>>
{
{
"testArea", new Dictionary<string, string>
{
{ "testKey", "testValue" }
}
}
}
}
}, s_loggerFactory.CreateLogger<LocalizedTextService>());
string result = txtService.Localize("testKey", culture);
Assert.AreEqual("testValue", result);
}
[Test]
public void Using_Dictionary_Returns_Default_Text_When_Not_Found_With_Area()
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
new Dictionary<CultureInfo, IDictionary<string, IDictionary<string, string>>>
{
{
culture, new Dictionary<string, IDictionary<string, string>>
{
{
"testArea", new Dictionary<string, string>
{
{ "testKey", "testValue" }
}
}
}
}
}, s_loggerFactory.CreateLogger<LocalizedTextService>());
string result = txtService.Localize("testArea/doNotFind", culture);
// NOTE: Based on how legacy works, the default text does not contain the area, just the key
Assert.AreEqual("[doNotFind]", result);
}
[Test]
public void Using_Dictionary_Returns_Default_Text_When_Not_Found_Without_Area()
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
new Dictionary<CultureInfo, IDictionary<string, IDictionary<string, string>>>
{
{
culture, new Dictionary<string, IDictionary<string, string>>
{
{
"testArea", new Dictionary<string, string>
{
{ "testKey", "testValue" }
}
}
}
}
}, s_loggerFactory.CreateLogger<LocalizedTextService>());
string result = txtService.Localize("doNotFind", culture);
Assert.AreEqual("[doNotFind]", result);
}
[Test]
public void Using_Dictionary_Returns_Tokenized_Text()
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
new Dictionary<CultureInfo, IDictionary<string, IDictionary<string, string>>>
{
{
culture, new Dictionary<string, IDictionary<string, string>>
{
{
"testArea", new Dictionary<string, string>
{
{ "testKey", "Hello %0%, you are such a %1% %2%" }
}
}
}
}
}, s_loggerFactory.CreateLogger<LocalizedTextService>());
string result = txtService.Localize(
"testKey",
culture,
new Dictionary<string, string> { { "0", "world" }, { "1", "great" }, { "2", "planet" } });
Assert.AreEqual("Hello world, you are such a great planet", result);
}
[Test]
public void Using_XDocument_Returns_Text_With_Area()
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
new Dictionary<CultureInfo, Lazy<XDocument>>
{
{
culture, new Lazy<XDocument>(() => new XDocument(
new XElement("area", new XAttribute("alias", "testArea"),
new XElement("key", new XAttribute("alias", "testKey"),
"testValue"))))
}
}, s_loggerFactory.CreateLogger<LocalizedTextService>());
string result = txtService.Localize("testArea/testKey", culture);
Assert.AreEqual("testValue", result);
}
[Test]
public void Using_XDocument_Returns_Text_Without_Area()
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
new Dictionary<CultureInfo, Lazy<XDocument>>
{
{
culture, new Lazy<XDocument>(() => new XDocument(
new XElement("area", new XAttribute("alias", "testArea"),
new XElement("key", new XAttribute("alias", "testKey"),
"testValue"))))
}
}, s_loggerFactory.CreateLogger<LocalizedTextService>());
string result = txtService.Localize("testKey", culture);
Assert.AreEqual("testValue", result);
}
[Test]
public void Using_XDocument_Returns_Default_Text_When_Not_Found_With_Area()
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
new Dictionary<CultureInfo, Lazy<XDocument>>
{
{
culture, new Lazy<XDocument>(() => new XDocument(
new XElement("area", new XAttribute("alias", "testArea"),
new XElement("key", new XAttribute("alias", "testKey"),
"testValue"))))
}
}, s_loggerFactory.CreateLogger<LocalizedTextService>());
string result = txtService.Localize("testArea/doNotFind", culture);
// NOTE: Based on how legacy works, the default text does not contain the area, just the key
Assert.AreEqual("[doNotFind]", result);
}
[Test]
public void Using_XDocument_Returns_Default_Text_When_Not_Found_Without_Area()
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
new Dictionary<CultureInfo, Lazy<XDocument>>
{
{
culture, new Lazy<XDocument>(() => new XDocument(
new XElement("area", new XAttribute("alias", "testArea"),
new XElement("key", new XAttribute("alias", "testKey"),
"testValue"))))
}
}, s_loggerFactory.CreateLogger<LocalizedTextService>());
string result = txtService.Localize("doNotFind", culture);
Assert.AreEqual("[doNotFind]", result);
}
[Test]
public void Using_XDocument_Returns_Tokenized_Text()
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
new Dictionary<CultureInfo, Lazy<XDocument>>
{
{
culture, new Lazy<XDocument>(() => new XDocument(
new XElement("area", new XAttribute("alias", "testArea"),
new XElement("key", new XAttribute("alias", "testKey"),
"Hello %0%, you are such a %1% %2%"))))
}
}, s_loggerFactory.CreateLogger<LocalizedTextService>());
string result = txtService.Localize("testKey", culture,
new Dictionary<string, string> { { "0", "world" }, { "1", "great" }, { "2", "planet" } });
Assert.AreEqual("Hello world, you are such a great planet", result);
}
[Test]
public void Using_Dictionary_Returns_Default_Text__When_No_Culture_Found()
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
new Dictionary<CultureInfo, IDictionary<string, IDictionary<string, string>>>
{
{
culture, new Dictionary<string, IDictionary<string, string>>
{
{
"testArea", new Dictionary<string, string>
{
{ "testKey", "testValue" }
}
}
}
}
}, s_loggerFactory.CreateLogger<LocalizedTextService>());
Assert.AreEqual("[testKey]", txtService.Localize("testArea/testKey", CultureInfo.GetCultureInfo("en-AU")));
}
[Test]
public void Using_XDocument_Returns_Default_Text_When_No_Culture_Found()
{
var culture = CultureInfo.GetCultureInfo("en-US");
var txtService = new LocalizedTextService(
new Dictionary<CultureInfo, Lazy<XDocument>>
{
{
culture, new Lazy<XDocument>(() => new XDocument(
new XElement("area", new XAttribute("alias", "testArea"),
new XElement("key", new XAttribute("alias", "testKey"), "testValue"))))
}
}, s_loggerFactory.CreateLogger<LocalizedTextService>());
Assert.AreEqual("[testKey]", txtService.Localize("testArea/testKey", CultureInfo.GetCultureInfo("en-AU")));
}
}
}

View File

@@ -0,0 +1,189 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Threading;
using Moq;
using NUnit.Framework;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.PropertyEditors.Validators;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.Implement;
using Umbraco.Cms.Core.Strings;
using Umbraco.Cms.Infrastructure.Serialization;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services
{
[TestFixture]
public class PropertyValidationServiceTests
{
private IShortStringHelper ShortStringHelper => new DefaultShortStringHelper(new DefaultShortStringHelperConfig());
private void MockObjects(out PropertyValidationService validationService, out IDataType dt)
{
var textService = new Mock<ILocalizedTextService>();
textService.Setup(x => x.Localize(It.IsAny<string>(),It.IsAny<string>(), Thread.CurrentThread.CurrentCulture, null)).Returns("Localized text");
var dataTypeService = new Mock<IDataTypeService>();
IDataType dataType = Mock.Of<IDataType>(
x => x.Configuration == (object)string.Empty // irrelevant but needs a value
&& x.DatabaseType == ValueStorageType.Nvarchar
&& x.EditorAlias == Constants.PropertyEditors.Aliases.TextBox);
dataTypeService.Setup(x => x.GetDataType(It.IsAny<int>())).Returns(() => dataType);
dt = dataType;
// new data editor that returns a TextOnlyValueEditor which will do the validation for the properties
IDataEditor dataEditor = Mock.Of<IDataEditor>(
x => x.Type == EditorType.PropertyValue
&& x.Alias == Constants.PropertyEditors.Aliases.TextBox);
Mock.Get(dataEditor).Setup(x => x.GetValueEditor(It.IsAny<object>()))
.Returns(new CustomTextOnlyValueEditor(new DataEditorAttribute(Constants.PropertyEditors.Aliases.TextBox, "Test Textbox", "textbox"), textService.Object, Mock.Of<IShortStringHelper>(), new JsonNetSerializer(), Mock.Of<IIOHelper>()));
var propEditors = new PropertyEditorCollection(new DataEditorCollection(() => new[] { dataEditor }));
validationService = new PropertyValidationService(propEditors, dataTypeService.Object, Mock.Of<ILocalizedTextService>(), new ValueEditorCache());
}
[Test]
public void Validate_Invariant_Properties_On_Variant_Default_Culture()
{
MockObjects(out PropertyValidationService validationService, out IDataType dataType);
var p1 = new Property(new PropertyType(ShortStringHelper, dataType, "test1") { Mandatory = true, Variations = ContentVariation.Culture });
p1.SetValue("Hello", "en-US");
var p2 = new Property(new PropertyType(ShortStringHelper, dataType, "test2") { Mandatory = true, Variations = ContentVariation.Nothing });
p2.SetValue("Hello", null);
var p3 = new Property(new PropertyType(ShortStringHelper, dataType, "test3") { Mandatory = true, Variations = ContentVariation.Culture });
p3.SetValue(null, "en-US"); // invalid
var p4 = new Property(new PropertyType(ShortStringHelper, dataType, "test4") { Mandatory = true, Variations = ContentVariation.Nothing });
p4.SetValue(null, null); // invalid
IContent content = Mock.Of<IContent>(
x => x.Published == true // set to published, the default culture will validate invariant anyways
&& x.Properties == new PropertyCollection(new[] { p1, p2, p3, p4 }));
bool result = validationService.IsPropertyDataValid(content, out IProperty[] invalid, CultureImpact.Explicit("en-US", true));
Assert.IsFalse(result);
Assert.AreEqual(2, invalid.Length);
}
[Test]
public void Validate_Invariant_Properties_On_Variant_Non_Default_Culture()
{
MockObjects(out PropertyValidationService validationService, out IDataType dataType);
var p1 = new Property(new PropertyType(ShortStringHelper, dataType, "test1") { Mandatory = true, Variations = ContentVariation.Culture });
p1.SetValue("Hello", "en-US");
var p2 = new Property(new PropertyType(ShortStringHelper, dataType, "test2") { Mandatory = true, Variations = ContentVariation.Nothing });
p2.SetValue("Hello", null);
var p3 = new Property(new PropertyType(ShortStringHelper, dataType, "test3") { Mandatory = true, Variations = ContentVariation.Culture });
p3.SetValue(null, "en-US"); // invalid
var p4 = new Property(new PropertyType(ShortStringHelper, dataType, "test4") { Mandatory = true, Variations = ContentVariation.Nothing });
p4.SetValue(null, null); // invalid
IContent content = Mock.Of<IContent>(
x => x.Published == false // set to not published, the non default culture will need to validate invariant too
&& x.Properties == new PropertyCollection(new[] { p1, p2, p3, p4 }));
bool result = validationService.IsPropertyDataValid(content, out IProperty[] invalid, CultureImpact.Explicit("en-US", false));
Assert.IsFalse(result);
Assert.AreEqual(2, invalid.Length);
}
[Test]
public void Validate_Variant_Properties_On_Variant()
{
MockObjects(out PropertyValidationService validationService, out IDataType dataType);
var p1 = new Property(new PropertyType(ShortStringHelper, dataType, "test1") { Mandatory = true, Variations = ContentVariation.Culture });
p1.SetValue(null, "en-US"); // invalid
var p2 = new Property(new PropertyType(ShortStringHelper, dataType, "test2") { Mandatory = true, Variations = ContentVariation.Nothing });
p2.SetValue(null, null); // invalid
var p3 = new Property(new PropertyType(ShortStringHelper, dataType, "test3") { Mandatory = true, Variations = ContentVariation.Culture });
p3.SetValue(null, "en-US"); // ignored because the impact isn't the default lang + the content is published
var p4 = new Property(new PropertyType(ShortStringHelper, dataType, "test4") { Mandatory = true, Variations = ContentVariation.Nothing });
p4.SetValue(null, null); // ignored because the impact isn't the default lang + the content is published
IContent content = Mock.Of<IContent>(
x => x.Published == true // set to published
&& x.Properties == new PropertyCollection(new[] { p1, p2, p3, p4 }));
bool result = validationService.IsPropertyDataValid(content, out IProperty[] invalid, CultureImpact.Explicit("en-US", false));
Assert.IsFalse(result);
Assert.AreEqual(2, invalid.Length);
}
[Test]
public void Validate_Invariant_Properties_On_Invariant()
{
MockObjects(out PropertyValidationService validationService, out IDataType dataType);
var p1 = new Property(new PropertyType(ShortStringHelper, dataType, "test1") { Mandatory = true, Variations = ContentVariation.Culture });
p1.SetValue(null, "en-US"); // ignored since this is variant
var p2 = new Property(new PropertyType(ShortStringHelper, dataType, "test2") { Mandatory = true, Variations = ContentVariation.Nothing });
p2.SetValue(null, null); // invalid
var p3 = new Property(new PropertyType(ShortStringHelper, dataType, "test3") { Mandatory = true, Variations = ContentVariation.Culture });
p3.SetValue("Hello", "en-US"); // ignored since this is variant
var p4 = new Property(new PropertyType(ShortStringHelper, dataType, "test4") { Mandatory = true, Variations = ContentVariation.Nothing });
p4.SetValue(null, null); // invalid
IContent content = Mock.Of<IContent>(
x => x.Properties == new PropertyCollection(new[] { p1, p2, p3, p4 }));
bool result = validationService.IsPropertyDataValid(content, out IProperty[] invalid, CultureImpact.Invariant);
Assert.IsFalse(result);
Assert.AreEqual(2, invalid.Length);
}
[Test]
public void Validate_Properties_On_All()
{
MockObjects(out PropertyValidationService validationService, out IDataType dataType);
var p1 = new Property(new PropertyType(ShortStringHelper, dataType, "test1") { Mandatory = true, Variations = ContentVariation.Culture });
p1.SetValue(null, "en-US"); // invalid
var p2 = new Property(new PropertyType(ShortStringHelper, dataType, "test2") { Mandatory = true, Variations = ContentVariation.Nothing });
p2.SetValue(null, null); // invalid
var p3 = new Property(new PropertyType(ShortStringHelper, dataType, "test3") { Mandatory = true, Variations = ContentVariation.Culture });
p3.SetValue(null, "en-US"); // invalid
var p4 = new Property(new PropertyType(ShortStringHelper, dataType, "test4") { Mandatory = true, Variations = ContentVariation.Nothing });
p4.SetValue(null, null); // invalid
IContent content = Mock.Of<IContent>(
x => x.Properties == new PropertyCollection(new[] { p1, p2, p3, p4 }));
bool result = validationService.IsPropertyDataValid(content, out IProperty[] invalid, CultureImpact.All);
Assert.IsFalse(result);
Assert.AreEqual(4, invalid.Length);
}
// used so we can inject a mock - we should fix the base class DataValueEditor to be able to have the ILocalizedTextField passed
// in to create the Requried and Regex validators so we aren't using singletons
private class CustomTextOnlyValueEditor : TextOnlyValueEditor
{
private readonly ILocalizedTextService _textService;
public CustomTextOnlyValueEditor(
DataEditorAttribute attribute,
ILocalizedTextService textService,
IShortStringHelper shortStringHelper,
IJsonSerializer jsonSerializer,
IIOHelper ioHelper)
: base(attribute, textService, shortStringHelper, jsonSerializer, ioHelper) => _textService = textService;
public override IValueRequiredValidator RequiredValidator => new RequiredValidator(_textService);
public override IValueFormatValidator FormatValidator => new RegexValidator(_textService, null);
}
}
}