using System.Data; using Autofac; using Insight.Database; using Newtonsoft.Json; using PlanTempus.Core.Sql.ConnectionFactory; using Shouldly; namespace PlanTempus.X.TDD.ConfigurationSystem; [TestClass] public class SetupConfigurationTests : TestFixture { private IDbConnection _connection; [TestInitialize] public void Setup() { var connectionFactory = Container.Resolve(); _connection = connectionFactory.Create(); } [TestCleanup] public void Cleanup() { _connection.ExecuteSql(@" TRUNCATE TABLE app_configuration_history; TRUNCATE TABLE app_configuration CASCADE;"); _connection.Dispose(); } [TestMethod] public void InsertConfiguration_ShouldCreateHistoryRecord() { // Arrange var configData = new { key = "test.key", value = "test value", label = "Test Label" }; // Act var result = _connection.QuerySql(@" INSERT INTO app_configuration (key, value, label) VALUES (@key, @value, @label) RETURNING *", configData).Single(); var history = _connection.QuerySql(@" SELECT key, value, label, action_type FROM app_configuration_history WHERE id = @id AND action_type = 'I'", new { id = (int)result.id }) .Single(); // Assert var expected = JsonConvert.SerializeObject(new { configData.key, configData.value, configData.label, action_type = "I" }); var actual = JsonConvert.SerializeObject(history) as string; actual.ShouldBe(expected); } [TestMethod] public void UpdateConfiguration_ShouldUpdateModifiedAt() { // Arrange var configData = new { key = "test.key", value = "original value" }; var original = _connection.QuerySql(@" INSERT INTO app_configuration (key, value) VALUES (@key, @value) RETURNING modified_at", configData) .Single(); Thread.Sleep(1000); // Act var updated = _connection.QuerySql(@" UPDATE app_configuration SET value = @value WHERE key = @key RETURNING modified_at", new { configData.key, value = "updated value" }) .Single(); // Assert ((DateTime)updated.modified_at).ShouldBeGreaterThan((DateTime)original.modified_at); } [TestMethod] public void DeleteConfiguration_ShouldCreateHistoryRecord() { // Arrange var configData = new { key = "test.key", value = "test value" }; var original = _connection.QuerySql(@" INSERT INTO app_configuration (key, value) VALUES (@key, @value) RETURNING id", configData) .Single(); // Act _connection.ExecuteSql( "DELETE FROM app_configuration WHERE id = @id", new { id = (int)original.id }); // Assert var history = _connection.QuerySql(@" SELECT key, value, action_type FROM app_configuration_history WHERE id = @id AND action_type = 'D'", new { id = (int)original.id }) .Single(); var expected = JsonConvert.SerializeObject(new { configData.key, configData.value, action_type = "D" }); var actual = JsonConvert.SerializeObject(history) as string; actual.ShouldBe(expected); } [TestMethod] public void InsertConfiguration_ShouldSetAllColumns() { // Arrange var now = DateTime.UtcNow; now = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0, DateTimeKind.Utc); var configData = new { key = "test.columns", value = "test value", label = "Test Label", content_type = "application/json", valid_from = now, expires_at = now.AddDays(30) }; // Act var result = _connection.QuerySql(@" INSERT INTO app_configuration ( key, value, label, content_type, valid_from, expires_at) VALUES ( @key, @value, @label, @content_type, @valid_from, @expires_at) RETURNING key, value, label, content_type, CAST(EXTRACT(EPOCH FROM date_trunc('minute', valid_from)) AS INTEGER) as valid_from, CAST(EXTRACT(EPOCH FROM date_trunc('minute', expires_at)) AS INTEGER) as expires_at", configData) .Single(); // Assert var expected = JsonConvert.SerializeObject(new { configData.key, configData.value, configData.label, configData.content_type, valid_from = ((DateTimeOffset)configData.valid_from).ToUnixTimeSeconds(), expires_at = ((DateTimeOffset)configData.expires_at).ToUnixTimeSeconds() }); Assert.AreEqual(expected, JsonConvert.SerializeObject(result)); } }