using ColaFlow.Modules.Mcp.Domain.ValueObjects; using Xunit; namespace ColaFlow.Modules.Mcp.Tests.Domain; public class DiffPreviewTests { [Fact] public void ForCreate_ValidInput_Success() { // Arrange & Act var diff = DiffPreview.ForCreate( entityType: "Epic", afterData: "{\"title\": \"New Epic\"}", entityKey: "COLA-1" ); // Assert Assert.Equal("CREATE", diff.Operation); Assert.Equal("Epic", diff.EntityType); Assert.Null(diff.EntityId); Assert.Equal("COLA-1", diff.EntityKey); Assert.Null(diff.BeforeData); Assert.Equal("{\"title\": \"New Epic\"}", diff.AfterData); Assert.Empty(diff.ChangedFields); Assert.True(diff.IsCreate()); Assert.False(diff.IsUpdate()); Assert.False(diff.IsDelete()); } [Fact] public void ForUpdate_ValidInput_Success() { // Arrange var entityId = Guid.NewGuid(); var changedFields = new List { new DiffField("Title", "Title", "Old", "New") }.AsReadOnly(); // Act var diff = DiffPreview.ForUpdate( entityType: "Story", entityId: entityId, beforeData: "{\"title\": \"Old\"}", afterData: "{\"title\": \"New\"}", changedFields: changedFields, entityKey: "COLA-2" ); // Assert Assert.Equal("UPDATE", diff.Operation); Assert.Equal("Story", diff.EntityType); Assert.Equal(entityId, diff.EntityId); Assert.Equal("COLA-2", diff.EntityKey); Assert.Equal("{\"title\": \"Old\"}", diff.BeforeData); Assert.Equal("{\"title\": \"New\"}", diff.AfterData); Assert.Single(diff.ChangedFields); Assert.False(diff.IsCreate()); Assert.True(diff.IsUpdate()); Assert.False(diff.IsDelete()); } [Fact] public void ForDelete_ValidInput_Success() { // Arrange var entityId = Guid.NewGuid(); // Act var diff = DiffPreview.ForDelete( entityType: "Task", entityId: entityId, beforeData: "{\"title\": \"Task to delete\"}", entityKey: "COLA-3" ); // Assert Assert.Equal("DELETE", diff.Operation); Assert.Equal("Task", diff.EntityType); Assert.Equal(entityId, diff.EntityId); Assert.Equal("COLA-3", diff.EntityKey); Assert.Equal("{\"title\": \"Task to delete\"}", diff.BeforeData); Assert.Null(diff.AfterData); Assert.Empty(diff.ChangedFields); Assert.False(diff.IsCreate()); Assert.False(diff.IsUpdate()); Assert.True(diff.IsDelete()); } [Fact] public void Create_InvalidOperation_ThrowsException() { // Act & Assert Assert.Throws(() => new DiffPreview( operation: "INVALID", entityType: "Epic", entityId: null, entityKey: null, beforeData: null, afterData: "{}" )); } [Fact] public void Create_EmptyOperation_ThrowsException() { // Act & Assert Assert.Throws(() => new DiffPreview( operation: "", entityType: "Epic", entityId: null, entityKey: null, beforeData: null, afterData: "{}" )); } [Fact] public void Create_EmptyEntityType_ThrowsException() { // Act & Assert Assert.Throws(() => new DiffPreview( operation: "CREATE", entityType: "", entityId: null, entityKey: null, beforeData: null, afterData: "{}" )); } [Fact] public void Create_UpdateWithoutEntityId_ThrowsException() { // Arrange var changedFields = new List { new DiffField("Title", "Title", "Old", "New") }.AsReadOnly(); // Act & Assert Assert.Throws(() => new DiffPreview( operation: "UPDATE", entityType: "Epic", entityId: null, entityKey: null, beforeData: "{}", afterData: "{}", changedFields: changedFields )); } [Fact] public void Create_UpdateWithoutChangedFields_ThrowsException() { // Act & Assert Assert.Throws(() => new DiffPreview( operation: "UPDATE", entityType: "Epic", entityId: Guid.NewGuid(), entityKey: null, beforeData: "{}", afterData: "{}", changedFields: null )); } [Fact] public void Create_UpdateWithEmptyChangedFields_ThrowsException() { // Act & Assert Assert.Throws(() => new DiffPreview( operation: "UPDATE", entityType: "Epic", entityId: Guid.NewGuid(), entityKey: null, beforeData: "{}", afterData: "{}", changedFields: new List().AsReadOnly() )); } [Fact] public void Create_DeleteWithoutEntityId_ThrowsException() { // Act & Assert Assert.Throws(() => new DiffPreview( operation: "DELETE", entityType: "Epic", entityId: null, entityKey: null, beforeData: "{}", afterData: null )); } [Fact] public void Create_CreateWithoutAfterData_ThrowsException() { // Act & Assert Assert.Throws(() => new DiffPreview( operation: "CREATE", entityType: "Epic", entityId: null, entityKey: null, beforeData: null, afterData: null )); } [Fact] public void Equality_SameValues_AreEqual() { // Arrange var diff1 = DiffPreview.ForCreate("Epic", "{\"title\": \"New Epic\"}", "COLA-1"); var diff2 = DiffPreview.ForCreate("Epic", "{\"title\": \"New Epic\"}", "COLA-1"); // Act & Assert Assert.Equal(diff1, diff2); Assert.True(diff1 == diff2); Assert.False(diff1 != diff2); } [Fact] public void Equality_DifferentValues_AreNotEqual() { // Arrange var diff1 = DiffPreview.ForCreate("Epic", "{\"title\": \"Epic 1\"}", "COLA-1"); var diff2 = DiffPreview.ForCreate("Epic", "{\"title\": \"Epic 2\"}", "COLA-2"); // Act & Assert Assert.NotEqual(diff1, diff2); Assert.False(diff1 == diff2); Assert.True(diff1 != diff2); } [Fact] public void GetSummary_Create_ReturnsFormattedString() { // Arrange var diff = DiffPreview.ForCreate("Epic", "{}", "COLA-1"); // Act var summary = diff.GetSummary(); // Assert Assert.Equal("CREATE Epic (COLA-1)", summary); } [Fact] public void GetSummary_Update_ReturnsFormattedString() { // Arrange var entityId = Guid.NewGuid(); var changedFields = new List { new DiffField("Title", "Title", "Old", "New") }.AsReadOnly(); var diff = DiffPreview.ForUpdate("Story", entityId, "{}", "{}", changedFields, "COLA-2"); // Act var summary = diff.GetSummary(); // Assert Assert.Equal("UPDATE Story (COLA-2)", summary); } [Fact] public void GetSummary_Delete_ReturnsFormattedString() { // Arrange var entityId = Guid.NewGuid(); var diff = DiffPreview.ForDelete("Task", entityId, "{}", "COLA-3"); // Act var summary = diff.GetSummary(); // Assert Assert.Equal("DELETE Task (COLA-3)", summary); } [Fact] public void GetChangedFieldCount_Create_ReturnsZero() { // Arrange var diff = DiffPreview.ForCreate("Epic", "{}"); // Act var count = diff.GetChangedFieldCount(); // Assert Assert.Equal(0, count); } [Fact] public void GetChangedFieldCount_Update_ReturnsCorrectCount() { // Arrange var changedFields = new List { new DiffField("Title", "Title", "Old", "New"), new DiffField("Status", "Status", "Todo", "Done") }.AsReadOnly(); var diff = DiffPreview.ForUpdate("Story", Guid.NewGuid(), "{}", "{}", changedFields); // Act var count = diff.GetChangedFieldCount(); // Assert Assert.Equal(2, count); } [Fact] public void Operation_LowercaseInput_NormalizedToUppercase() { // Arrange & Act var diff = new DiffPreview( operation: "create", entityType: "Epic", entityId: null, entityKey: null, beforeData: null, afterData: "{}" ); // Assert Assert.Equal("CREATE", diff.Operation); } }