using System.ComponentModel.DataAnnotations.Schema; using ReC.Application.Common.Dto; 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(() => 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(() => input.ReplacePlaceholders()); } [Test] public void ReplacePlaceholders_ObjectWithoutColumnAttributes_ThrowsPlaceholderResolutionException() { var model = new NoColumnModel { Id = 1, Name = "Test" }; var input = "WHERE X = {#INT#Id}"; Assert.Throws(() => input.ReplacePlaceholders(model)); } [Test] public void ReplacePlaceholders_MixedResolvableAndUnresolvable_ThrowsOnUnresolvable() { var input = "WHERE BAZ = {#INT#BAZ} AND X = {#INT#UNKNOWN}"; var ex = Assert.Throws(() => input.ReplacePlaceholders(_foo, _bar, _fuz)); Assert.That(ex!.ColumnName, Is.EqualTo("UNKNOWN")); } #endregion }