Add unit tests for InvokeAction placeholder replacement

Introduce InvokeActionTests.cs with comprehensive tests for:
- Placeholder replacement logic (ReplacePlaceholders) across int, bool, string, DateTime, DateTimeOffset types, multiple placeholders, and various prefix formats.
- Value extraction by column name (GetValueByColumnName), including models with and without [Column] attributes.
- Exception handling for unresolvable placeholders and invalid input scenarios.
These tests ensure robust coverage of both normal and error cases.
This commit is contained in:
2026-03-26 14:37:58 +01:00
parent c2e073dade
commit c405f369ac

View File

@@ -0,0 +1,257 @@
using System.ComponentModel.DataAnnotations.Schema;
using ReC.Application.Common.Behaviors.InvokeAction;
using ReC.Application.Common.Exceptions;
namespace ReC.Tests.Application.Behaviors;
#region Test Models
public class Foo
{
[Column("BAZ")]
public int Baz { get; set; }
[Column("FOO_NAME")]
public string FooName { get; set; } = string.Empty;
}
public class Bar
{
[Column("QUX")]
public bool Qux { get; set; }
[Column("BAR_DATE")]
public DateTime BarDate { get; set; }
}
public class Fuz
{
[Column("QUZ")]
public string Quz { get; set; } = string.Empty;
[Column("FUZ_OFFSET")]
public DateTimeOffset FuzOffset { get; set; }
}
public class NoColumnModel
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
}
#endregion
[TestFixture]
public class InvokeActionTests
{
private Foo _foo = null!;
private Bar _bar = null!;
private Fuz _fuz = null!;
[SetUp]
public void Setup()
{
_foo = new Foo { Baz = 2, FooName = "TestFoo" };
_bar = new Bar { Qux = true, BarDate = new DateTime(2025, 6, 15, 14, 30, 0) };
_fuz = new Fuz { Quz = "QuZ", FuzOffset = new DateTimeOffset(2025, 6, 15, 14, 30, 0, TimeSpan.FromHours(3)) };
}
#region GetValueByColumnName Tests
[Test]
public void GetValueByColumnName_ExistingColumn_ReturnsValue()
{
var result = _foo.GetValueByColumnName("BAZ");
Assert.That(result, Is.EqualTo(2));
}
[Test]
public void GetValueByColumnName_NonExistingColumn_ReturnsNull()
{
var result = _foo.GetValueByColumnName("NON_EXISTING");
Assert.That(result, Is.Null);
}
[Test]
public void GetValueByColumnName_PropertyNameInsteadOfColumnName_ReturnsNull()
{
var result = _foo.GetValueByColumnName("Baz");
Assert.That(result, Is.Null);
}
[Test]
public void GetValueByColumnName_ModelWithoutColumnAttribute_ReturnsNull()
{
var model = new NoColumnModel { Id = 1, Name = "Test" };
var result = model.GetValueByColumnName("Id");
Assert.That(result, Is.Null);
}
#endregion
#region ReplacePlaceholders - Basic Type Tests
[TestCase("SELECT * FROM T WHERE BAZ = {#INT#BAZ}", "SELECT * FROM T WHERE BAZ = 2")]
[TestCase("... WHERE BAZ = {#INT#BAZ}", "... WHERE BAZ = 2")]
public void ReplacePlaceholders_IntValue_ReplacesCorrectly(string input, string expected)
{
var result = input.ReplacePlaceholders(_foo, _bar, _fuz);
Assert.That(result, Is.EqualTo(expected));
}
[TestCase("SELECT * FROM T WHERE QUX = {#BOOL#QUX}", "SELECT * FROM T WHERE QUX = TRUE")]
[TestCase("... WHERE QUX = {#INT#QUX}", "... WHERE QUX = TRUE")]
public void ReplacePlaceholders_BoolTrueValue_ReplacesWithTRUE(string input, string expected)
{
var result = input.ReplacePlaceholders(_foo, _bar, _fuz);
Assert.That(result, Is.EqualTo(expected));
}
[Test]
public void ReplacePlaceholders_BoolFalseValue_ReplacesWithFALSE()
{
var bar = new Bar { Qux = false };
var result = "WHERE QUX = {#BOOL#QUX}".ReplacePlaceholders(bar);
Assert.That(result, Is.EqualTo("WHERE QUX = FALSE"));
}
[TestCase("... WHERE QUZ <> '{#STR#QUZ}'", "... WHERE QUZ <> 'QuZ'")]
[TestCase("SELECT * FROM T WHERE QUZ = '{#TEXT#QUZ}'", "SELECT * FROM T WHERE QUZ = 'QuZ'")]
public void ReplacePlaceholders_StringValue_ReplacesCorrectly(string input, string expected)
{
var result = input.ReplacePlaceholders(_foo, _bar, _fuz);
Assert.That(result, Is.EqualTo(expected));
}
[Test]
public void ReplacePlaceholders_DateTimeValue_FormatsAsSqlDateTime()
{
var result = "WHERE D = '{#DATE#BAR_DATE}'".ReplacePlaceholders(_bar);
Assert.That(result, Is.EqualTo("WHERE D = '2025-06-15 14:30:00'"));
}
[Test]
public void ReplacePlaceholders_DateTimeOffsetValue_FormatsWithOffset()
{
var result = "WHERE D = '{#DTO#FUZ_OFFSET}'".ReplacePlaceholders(_fuz);
Assert.That(result, Is.EqualTo("WHERE D = '2025-06-15 14:30:00 +03:00'"));
}
#endregion
#region ReplacePlaceholders - Multiple Placeholders
[Test]
public void ReplacePlaceholders_MultiplePlaceholdersInSameString_ReplacesAll()
{
var input = "WHERE BAZ = {#INT#BAZ} AND QUX = {#BOOL#QUX} AND QUZ = '{#STR#QUZ}'";
var expected = "WHERE BAZ = 2 AND QUX = TRUE AND QUZ = 'QuZ'";
var result = input.ReplacePlaceholders(_foo, _bar, _fuz);
Assert.That(result, Is.EqualTo(expected));
}
[Test]
public void ReplacePlaceholders_SamePlaceholderTwice_ReplacesBoth()
{
var input = "WHERE BAZ = {#INT#BAZ} OR BAZ = {#INT#BAZ}";
var expected = "WHERE BAZ = 2 OR BAZ = 2";
var result = input.ReplacePlaceholders(_foo);
Assert.That(result, Is.EqualTo(expected));
}
#endregion
#region ReplacePlaceholders - Object Resolution Order
[Test]
public void ReplacePlaceholders_ValueFoundInSecondObject_ReturnsValueFromSecondObject()
{
var result = "WHERE QUX = {#BOOL#QUX}".ReplacePlaceholders(_foo, _bar);
Assert.That(result, Is.EqualTo("WHERE QUX = TRUE"));
}
[Test]
public void ReplacePlaceholders_ValueFoundInThirdObject_ReturnsValueFromThirdObject()
{
var result = "WHERE QUZ = '{#STR#QUZ}'".ReplacePlaceholders(_foo, _bar, _fuz);
Assert.That(result, Is.EqualTo("WHERE QUZ = 'QuZ'"));
}
#endregion
#region ReplacePlaceholders - No Placeholder
[TestCase("SELECT * FROM T WHERE X = 1")]
[TestCase("")]
[TestCase("some random text")]
public void ReplacePlaceholders_NoPlaceholders_ReturnsOriginalString(string input)
{
var result = input.ReplacePlaceholders(_foo, _bar, _fuz);
Assert.That(result, Is.EqualTo(input));
}
#endregion
#region ReplacePlaceholders - Different Prefix Strings
[TestCase("WHERE BAZ = {#VAR#BAZ}", "WHERE BAZ = 2")]
[TestCase("WHERE BAZ = {#PARAM#BAZ}", "WHERE BAZ = 2")]
[TestCase("WHERE BAZ = {#X#BAZ}", "WHERE BAZ = 2")]
[TestCase("WHERE BAZ = {#SOME_LONG_PREFIX#BAZ}", "WHERE BAZ = 2")]
public void ReplacePlaceholders_DifferentPrefixes_AllResolveCorrectly(string input, string expected)
{
var result = input.ReplacePlaceholders(_foo);
Assert.That(result, Is.EqualTo(expected));
}
#endregion
#region ReplacePlaceholders - Exception Tests
[Test]
public void ReplacePlaceholders_UnresolvableColumn_ThrowsPlaceholderResolutionException()
{
var input = "WHERE X = {#INT#NON_EXISTING}";
var ex = Assert.Throws<PlaceholderResolutionException>(() =>
input.ReplacePlaceholders(_foo, _bar, _fuz));
Assert.That(ex!.ColumnName, Is.EqualTo("NON_EXISTING"));
Assert.That(ex.Placeholder, Is.EqualTo("{#INT#NON_EXISTING}"));
Assert.That(ex.Input, Is.EqualTo(input));
}
[Test]
public void ReplacePlaceholders_NoObjectsProvided_ThrowsPlaceholderResolutionException()
{
var input = "WHERE X = {#INT#BAZ}";
Assert.Throws<PlaceholderResolutionException>(() =>
input.ReplacePlaceholders());
}
[Test]
public void ReplacePlaceholders_ObjectWithoutColumnAttributes_ThrowsPlaceholderResolutionException()
{
var model = new NoColumnModel { Id = 1, Name = "Test" };
var input = "WHERE X = {#INT#Id}";
Assert.Throws<PlaceholderResolutionException>(() =>
input.ReplacePlaceholders(model));
}
[Test]
public void ReplacePlaceholders_MixedResolvableAndUnresolvable_ThrowsOnUnresolvable()
{
var input = "WHERE BAZ = {#INT#BAZ} AND X = {#INT#UNKNOWN}";
var ex = Assert.Throws<PlaceholderResolutionException>(() =>
input.ReplacePlaceholders(_foo, _bar, _fuz));
Assert.That(ex!.ColumnName, Is.EqualTo("UNKNOWN"));
}
#endregion
}