elsa-core/test/unit/Elsa.Persistence.VNext.UnitTests/RuntimeEntityDefinitionValidatorTests.cs
Sipke Schoorstra 50ef957031
[codex] Add runtime entity validator coverage (#7697)
* Add runtime entity validator coverage

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-06 04:14:12 +02:00

140 lines
4.8 KiB
C#

using Elsa.Persistence.VNext.Runtime;
using Elsa.Persistence.VNext.Runtime.Models;
using Elsa.Persistence.VNext.Runtime.Services;
namespace Elsa.Persistence.VNext.UnitTests;
public class RuntimeEntityDefinitionValidatorTests
{
private readonly RuntimeEntityDefinitionValidator _validator;
public RuntimeEntityDefinitionValidatorTests()
{
_validator = new RuntimeEntityDefinitionValidator(Microsoft.Extensions.Options.Options.Create(new RuntimeEntityOptions()));
}
[Fact]
public void Validate_RejectsMissingDefinitionName()
{
var definition = CreateDefinition();
definition.Name = " ";
var exception = Assert.Throws<InvalidOperationException>(() => _validator.Validate(definition));
Assert.Contains("name is required", exception.Message);
}
[Fact]
public void Validate_RejectsDefinitionWithoutFields()
{
var definition = CreateDefinition();
definition.Fields.Clear();
var exception = Assert.Throws<InvalidOperationException>(() => _validator.Validate(definition));
Assert.Contains("must declare at least one field", exception.Message);
}
[Fact]
public void Validate_RejectsDuplicateFieldsIgnoringCase()
{
var definition = CreateDefinition();
definition.Fields.Add(new("EMAIL", RuntimeEntityFieldType.String));
var exception = Assert.Throws<InvalidOperationException>(() => _validator.Validate(definition));
Assert.Contains("declares field", exception.Message);
Assert.Contains("more than once", exception.Message);
}
[Fact]
public void Validate_RejectsIndexesBeyondConfiguredLimit()
{
var validator = new RuntimeEntityDefinitionValidator(Microsoft.Extensions.Options.Options.Create(new RuntimeEntityOptions { MaxIndexedFields = 2 }));
var definition = CreateDefinition();
definition.Fields.Add(new("region", RuntimeEntityFieldType.String));
definition.Indexes.Add(new("IX_Customer_Email", "email"));
definition.Indexes.Add(new("IX_Customer_Tier", "tier"));
definition.Indexes.Add(new("IX_Customer_Region", "region"));
var exception = Assert.Throws<InvalidOperationException>(() => validator.Validate(definition));
Assert.Contains("declares 3 indexes", exception.Message);
Assert.Contains("only 2 runtime index slots", exception.Message);
}
[Fact]
public void Validate_RejectsIndexesBeyondRuntimeSlotCount()
{
var validator = new RuntimeEntityDefinitionValidator(Microsoft.Extensions.Options.Options.Create(new RuntimeEntityOptions { MaxIndexedFields = 100 }));
var definition = CreateDefinition();
for (var i = 1; i <= RuntimeEntityPersistenceSchemaProvider.IndexedFieldSlotCount + 1; i++)
{
var fieldName = $"indexed{i}";
definition.Fields.Add(new(fieldName, RuntimeEntityFieldType.String));
definition.Indexes.Add(new($"IX_Customer_{fieldName}", fieldName));
}
var exception = Assert.Throws<InvalidOperationException>(() => validator.Validate(definition));
Assert.Contains($"only {RuntimeEntityPersistenceSchemaProvider.IndexedFieldSlotCount} runtime index slots", exception.Message);
}
[Fact]
public void Validate_RejectsIndexReferencingUnknownField()
{
var definition = CreateDefinition();
definition.Indexes.Add(new("IX_Customer_Status", "status"));
var exception = Assert.Throws<InvalidOperationException>(() => _validator.Validate(definition));
Assert.Contains("references unknown field 'status'", exception.Message);
}
[Fact]
public void ValidateInstance_RejectsMissingRequiredField()
{
var definition = CreateDefinition();
var instance = new RuntimeEntityInstance
{
Id = "customer-1",
DefinitionName = definition.Name
};
var exception = Assert.Throws<InvalidOperationException>(() => _validator.ValidateInstance(definition, instance));
Assert.Contains("missing required field 'email'", exception.Message);
}
[Fact]
public void ValidateInstance_MatchesRequiredFieldsIgnoringCase()
{
var definition = CreateDefinition();
var instance = new RuntimeEntityInstance
{
Id = "customer-1",
DefinitionName = definition.Name,
Data =
{
["EMAIL"] = "one@example.com"
}
};
_validator.ValidateInstance(definition, instance);
}
private static RuntimeEntityDefinition CreateDefinition()
{
return new RuntimeEntityDefinition
{
Name = "Customer",
Fields =
{
new("email", RuntimeEntityFieldType.String, IsRequired: true),
new("tier", RuntimeEntityFieldType.String)
}
};
}
}