Backend/e-suite.Database.Audit/e-suite.Database.Audit.UnitTests/AuditEngineCore/SoftDeleteUnitTests.cs
2026-01-20 21:50:10 +00:00

418 lines
18 KiB
C#

using e_suite.Database.Audit.AuditEngine;
using e_suite.Database.Audit.UnitTests.Helpers;
using e_suite.Database.Audit.UnitTests.Helpers.Tables;
using NUnit.Framework;
namespace e_suite.Database.Audit.UnitTests.AuditEngineCore;
[TestFixture]
public class SoftDeleteUnitTests : AuditEngineCoreTestBase
{
[Test]
public async Task AddRow_ItemEditedHasNotDeleted_AuditEntryShowsAsUpdate()
{
//Arrange
var auditUserDetails = new AuditUserDetails
{
UserId = 1,
UserDisplayName = "Testy McTester",
Comment = "Test comment"
};
var leafTreeValue = new DeletableTreeValue
{
Id = 2000,
Name = "Leaf Level item",
Deleted = false
};
testDBContext.DeletableTreeValues.Add(leafTreeValue);
await testDBContext.NoAuditSaveChangesAsync();
//Act
var itemToEdit = testDBContext.DeletableTreeValues.Single(x => x.Id == leafTreeValue.Id);
itemToEdit.Name = "Altered Name";
itemToEdit.Deleted = false;
await testDBContext.SaveChangesAsync(auditUserDetails);
//Assert
Assert.That(testDBContext.AuditDetails.Count(), Is.EqualTo(1));
var auditDetail = testDBContext.AuditDetails.First();
Assert.That(auditDetail.Type, Is.EqualTo(AuditType.Update.ToString()));
}
[Test]
public async Task AddRow_ItemIsUndeleted_AuditEntryShowsAsRestore()
{
//Arrange
var auditUserDetails = new AuditUserDetails
{
UserId = 1,
UserDisplayName = "Testy McTester",
Comment = "Test comment"
};
var leafTreeValue = new DeletableTreeValue
{
Id = 2000,
Name = "Leaf Level item",
Deleted = true
};
testDBContext.DeletableTreeValues.Add(leafTreeValue);
await testDBContext.NoAuditSaveChangesAsync();
//Act
var itemToEdit = testDBContext.DeletableTreeValues.Single(x => x.Id == leafTreeValue.Id);
itemToEdit.Name = "Altered Name";
itemToEdit.Deleted = false;
await testDBContext.SaveChangesAsync(auditUserDetails);
//Assert
Assert.That(testDBContext.AuditDetails.Count(), Is.EqualTo(1));
var auditDetail = testDBContext.AuditDetails.First();
Assert.That(auditDetail.Type, Is.EqualTo(AuditType.Restore.ToString()));
}
[TestCase(true)] //Soft delete
[TestCase(false)] //Undelete
public async Task AddRow_TableHasSelfReferenceAndReferenceNull_AuditForSoftDeleteOrUndeleteRecorded(bool deleteRow)
{
//Arrange
var auditUserDetails = new AuditUserDetails
{
UserId = 1,
UserDisplayName = "Testy McTester",
Comment = "Test comment"
};
var leafTreeValue = new DeletableTreeValue
{
Id = 30000,
Name = "Leaf Level item",
Deleted = !deleteRow
};
testDBContext.DeletableTreeValues.Add(leafTreeValue);
await testDBContext.NoAuditSaveChangesAsync();
//Act
var itemToEdit = testDBContext.DeletableTreeValues.Single(x => x.Id == leafTreeValue.Id);
itemToEdit.Deleted = deleteRow;
await testDBContext.SaveChangesAsync(auditUserDetails);
//Assert
Assert.That(testDBContext.AuditDetails.Count(), Is.EqualTo(1));
var auditDetail = testDBContext.AuditDetails.First();
Assert.That(auditDetail.UserDisplayName, Is.EqualTo(auditUserDetails.UserDisplayName));
Assert.That(auditDetail.UserId, Is.EqualTo(auditUserDetails.UserId));
Assert.That(auditDetail.Comment, Is.EqualTo(auditUserDetails.Comment));
Assert.That(auditDetail.Id, Is.EqualTo(1));
Assert.That(auditDetail.Type, Is.EqualTo(deleteRow ? AuditType.Delete.ToString() : AuditType.Restore.ToString()));
Assert.That(auditDetail.Fields, Is.EqualTo( string.Empty));
Assert.That(testDBContext.AuditEntries.Count(), Is.EqualTo(1));
var auditEntries = testDBContext.AuditEntries.ToList();
var childAuditEntry = auditEntries[0];
Assert.That(childAuditEntry.Id, Is.EqualTo(1));
Assert.That(childAuditEntry.EntityName, Is.EqualTo(typeof(DeletableTreeValue).FullName));
Assert.That(childAuditEntry.DisplayName, Is.EqualTo(leafTreeValue.Name));
Assert.That(childAuditEntry.AuditLogId, Is.EqualTo(auditDetail.Id));
Assert.That(childAuditEntry.PrimaryKey, Is.EqualTo($"{{\"Id\":{leafTreeValue.Id}}}"));
Assert.That(childAuditEntry.IsPrimary, Is.True);
Assert.That(testDBContext.AuditDrillHierarchies.Count(), Is.EqualTo(0));
}
[TestCase(true)] //Soft delete
[TestCase(false)] //Undelete
public async Task AddRow_TableHasSingleParentItem_AuditForSoftDeleteOrUndeleteRecorded(bool deleteRow)
{
//Arrange
var auditUserDetails = new AuditUserDetails
{
UserId = 1,
UserDisplayName = "Testy McTester",
Comment = "Test comment"
};
var rootTreeValue = new DeletableTreeValue
{
Id = 3000,
Name = "Root Level item",
Deleted = !deleteRow
};
var leafTreeValue = new DeletableTreeValue
{
Id = 30000,
Name = "Leaf Level item",
Deleted = !deleteRow,
ParentId = rootTreeValue.Id
};
testDBContext.DeletableTreeValues.Add(rootTreeValue);
testDBContext.DeletableTreeValues.Add(leafTreeValue);
await testDBContext.NoAuditSaveChangesAsync();
//Act
var itemToEdit = testDBContext.DeletableTreeValues.Single(x => x.Id == leafTreeValue.Id);
itemToEdit.Deleted = deleteRow;
await testDBContext.SaveChangesAsync(auditUserDetails);
//Assert
Assert.That(testDBContext.AuditDetails.Count(), Is.EqualTo(1));
var auditDetail = testDBContext.AuditDetails.First();
Assert.That(auditDetail.UserDisplayName, Is.EqualTo(auditUserDetails.UserDisplayName));
Assert.That(auditDetail.UserId, Is.EqualTo(auditUserDetails.UserId));
Assert.That(auditDetail.Comment, Is.EqualTo(auditUserDetails.Comment));
Assert.That(auditDetail.Id, Is.EqualTo(1));
Assert.That(auditDetail.Type, Is.EqualTo(deleteRow ? AuditType.Delete.ToString() : AuditType.Restore.ToString()));
Assert.That(testDBContext.DeletableTreeValues.Count(), Is.EqualTo(2));
Assert.That(testDBContext.AuditEntries.Count(), Is.EqualTo(2));
var auditEntries = testDBContext.AuditEntries.ToList();
var childAuditEntry = auditEntries[0];
Assert.That(childAuditEntry.Id, Is.EqualTo(1));
Assert.That(childAuditEntry.EntityName, Is.EqualTo(typeof(DeletableTreeValue).FullName));
Assert.That(childAuditEntry.DisplayName, Is.EqualTo(leafTreeValue.Name));
Assert.That(childAuditEntry.AuditLogId, Is.EqualTo(auditDetail.Id));
Assert.That(childAuditEntry.PrimaryKey, Is.EqualTo($"{{\"Id\":{leafTreeValue.Id}}}"));
Assert.That(childAuditEntry.IsPrimary, Is.True);
var parentAuditEntry = auditEntries[1];
Assert.That(parentAuditEntry.Id, Is.EqualTo(2));
Assert.That(parentAuditEntry.EntityName, Is.EqualTo(typeof(DeletableTreeValue).FullName));
Assert.That(parentAuditEntry.DisplayName, Is.EqualTo(rootTreeValue.Name));
Assert.That(parentAuditEntry.AuditLogId, Is.EqualTo(auditDetail.Id));
Assert.That(parentAuditEntry.PrimaryKey, Is.EqualTo($"{{\"Id\":{rootTreeValue.Id}}}"));
Assert.That(parentAuditEntry.IsPrimary, Is.False);
Assert.That(testDBContext.AuditDrillHierarchies.Count(), Is.EqualTo(1));
var auditDrillHierarchies = testDBContext.AuditDrillHierarchies.ToList();
Assert.That(auditDrillHierarchies[0].ChildAuditDrillDownEntityId, Is.EqualTo(1));
Assert.That(auditDrillHierarchies[0].ParentAuditDrillDownEntityId, Is.EqualTo(2));
}
[TestCase(true)] //Soft delete
[TestCase(false)] //Undelete
public async Task AddRow_TableHasTwoParentLevels_AuditForSoftDeleteOrUndeleteRecorded(bool deleteRow)
{
//Arrange
var auditUserDetails = new AuditUserDetails
{
UserId = 1,
UserDisplayName = "Testy McTester",
Comment = "Test comment"
};
var rootTreeValue = new DeletableTreeValue
{
Id = 300,
Name = "Root Level item",
Deleted = !deleteRow
};
var level1TreeValue = new DeletableTreeValue
{
Id = 3000,
Name = "Level 1 item",
Deleted = !deleteRow,
ParentId = rootTreeValue.Id
};
var leafTreeValue = new DeletableTreeValue
{
Id = 30000,
Name = "Leaf Level item",
Deleted = !deleteRow,
ParentId = level1TreeValue.Id
};
testDBContext.DeletableTreeValues.Add(rootTreeValue);
testDBContext.DeletableTreeValues.Add(level1TreeValue);
testDBContext.DeletableTreeValues.Add(leafTreeValue);
await testDBContext.NoAuditSaveChangesAsync();
//Act
var itemToEdit = testDBContext.DeletableTreeValues.Single(x => x.Id == leafTreeValue.Id);
itemToEdit.Deleted = deleteRow;
await testDBContext.SaveChangesAsync(auditUserDetails);
//Assert
Assert.That(testDBContext.AuditDetails.Count(), Is.EqualTo(1));
var auditDetail = testDBContext.AuditDetails.First();
Assert.That(auditDetail.UserDisplayName, Is.EqualTo(auditUserDetails.UserDisplayName));
Assert.That(auditDetail.UserId, Is.EqualTo(auditUserDetails.UserId));
Assert.That(auditDetail.Comment, Is.EqualTo(auditUserDetails.Comment));
Assert.That(auditDetail.Id, Is.EqualTo(1));
Assert.That(auditDetail.Type, Is.EqualTo(deleteRow ? AuditType.Delete.ToString() : AuditType.Restore.ToString()));
Assert.That(testDBContext.DeletableTreeValues.Count(), Is.EqualTo(3));
Assert.That(testDBContext.AuditEntries.Count(), Is.EqualTo(3));
var auditEntries = testDBContext.AuditEntries.ToList();
var childAuditEntry = auditEntries[0];
Assert.That(childAuditEntry.Id, Is.EqualTo(1));
Assert.That(childAuditEntry.EntityName, Is.EqualTo(typeof(DeletableTreeValue).FullName));
Assert.That(childAuditEntry.DisplayName, Is.EqualTo(leafTreeValue.Name));
Assert.That(childAuditEntry.AuditLogId, Is.EqualTo(auditDetail.Id));
Assert.That(childAuditEntry.PrimaryKey, Is.EqualTo($"{{\"Id\":{leafTreeValue.Id}}}"));
Assert.That(childAuditEntry.IsPrimary, Is.True);
var level1AuditEntry = auditEntries[1];
Assert.That(level1AuditEntry.Id, Is.EqualTo(2));
Assert.That(level1AuditEntry.EntityName, Is.EqualTo(typeof(DeletableTreeValue).FullName));
Assert.That(level1AuditEntry.DisplayName, Is.EqualTo(level1TreeValue.Name));
Assert.That(level1AuditEntry.AuditLogId, Is.EqualTo(auditDetail.Id));
Assert.That(level1AuditEntry.PrimaryKey, Is.EqualTo($"{{\"Id\":{level1TreeValue.Id}}}"));
Assert.That(level1AuditEntry.IsPrimary, Is.False);
var parentAuditEntry = auditEntries[2];
Assert.That(parentAuditEntry.Id, Is.EqualTo(3));
Assert.That(parentAuditEntry.EntityName, Is.EqualTo(typeof(DeletableTreeValue).FullName));
Assert.That(parentAuditEntry.DisplayName, Is.EqualTo(rootTreeValue.Name));
Assert.That(parentAuditEntry.AuditLogId, Is.EqualTo(auditDetail.Id));
Assert.That(parentAuditEntry.PrimaryKey, Is.EqualTo($"{{\"Id\":{rootTreeValue.Id}}}"));
Assert.That(parentAuditEntry.IsPrimary, Is.False);
Assert.That(testDBContext.AuditDrillHierarchies.Count(), Is.EqualTo(2));
var auditDrillHierarchies = testDBContext.AuditDrillHierarchies.ToList();
Assert.That(auditDrillHierarchies[0].ChildAuditDrillDownEntityId, Is.EqualTo(1));
Assert.That(auditDrillHierarchies[0].ParentAuditDrillDownEntityId, Is.EqualTo(2));
Assert.That(auditDrillHierarchies[1].ChildAuditDrillDownEntityId, Is.EqualTo(2));
Assert.That(auditDrillHierarchies[1].ParentAuditDrillDownEntityId, Is.EqualTo(3));
}
[TestCase(true)] //Soft delete
[TestCase(false)] //Undelete
public async Task AddRow_TableHasThreeParentLevels_AuditForSoftDeleteOrUndeleteRecorded(bool deleteRow)
{
//Arrange
var auditUserDetails = new AuditUserDetails
{
UserId = 1,
UserDisplayName = "Testy McTester",
Comment = "Test comment"
};
var rootTreeValue = new DeletableTreeValue
{
Id = 30,
Name = "Root Level item",
Deleted = !deleteRow
};
var level1TreeValue = new DeletableTreeValue
{
Id = 300,
Name = "Level 1 item",
Deleted = !deleteRow,
ParentId = rootTreeValue.Id
};
var level2TreeValue = new DeletableTreeValue
{
Id = 3000,
Name = "Level 2 item",
Deleted = !deleteRow,
ParentId = level1TreeValue.Id
};
var leafTreeValue = new DeletableTreeValue
{
Id = 30000,
Name = "Leaf Level item",
Deleted = !deleteRow,
ParentId = level2TreeValue.Id
};
testDBContext.DeletableTreeValues.Add(rootTreeValue);
await testDBContext.NoAuditSaveChangesAsync();
testDBContext.DeletableTreeValues.Add(level1TreeValue);
await testDBContext.NoAuditSaveChangesAsync();
testDBContext.DeletableTreeValues.Add(level2TreeValue);
await testDBContext.NoAuditSaveChangesAsync();
testDBContext.DeletableTreeValues.Add(leafTreeValue);
await testDBContext.NoAuditSaveChangesAsync();
//Act
var itemToEdit = testDBContext.DeletableTreeValues.Single(x => x.Id == leafTreeValue.Id);
itemToEdit.Deleted = deleteRow;
await testDBContext.SaveChangesAsync(auditUserDetails);
//Assert
Assert.That(testDBContext.AuditDetails.Count(), Is.EqualTo(1));
var auditDetail = testDBContext.AuditDetails.First();
Assert.That(auditDetail.UserDisplayName, Is.EqualTo(auditUserDetails.UserDisplayName));
Assert.That(auditDetail.UserId, Is.EqualTo(auditUserDetails.UserId));
Assert.That(auditDetail.Comment, Is.EqualTo(auditUserDetails.Comment));
Assert.That(auditDetail.Id, Is.EqualTo(1));
Assert.That(auditDetail.Type, Is.EqualTo(deleteRow ? AuditType.Delete.ToString() : AuditType.Restore.ToString()));
Assert.That(testDBContext.DeletableTreeValues.Count(), Is.EqualTo(4));
Assert.That(testDBContext.AuditEntries.Count(), Is.EqualTo(4));
var auditEntries = testDBContext.AuditEntries.ToList();
var childAuditEntry = auditEntries[0];
Assert.That(childAuditEntry.Id, Is.EqualTo(1));
Assert.That(childAuditEntry.EntityName, Is.EqualTo(typeof(DeletableTreeValue).FullName));
Assert.That(childAuditEntry.DisplayName, Is.EqualTo(leafTreeValue.Name));
Assert.That(childAuditEntry.AuditLogId, Is.EqualTo(auditDetail.Id));
Assert.That(childAuditEntry.PrimaryKey, Is.EqualTo($"{{\"Id\":{leafTreeValue.Id}}}"));
Assert.That(childAuditEntry.IsPrimary, Is.True);
var level1AuditEntry = auditEntries[1];
Assert.That(level1AuditEntry.Id, Is.EqualTo(2));
Assert.That(level1AuditEntry.EntityName, Is.EqualTo(typeof(DeletableTreeValue).FullName));
Assert.That(level1AuditEntry.DisplayName, Is.EqualTo(level2TreeValue.Name));
Assert.That(level1AuditEntry.AuditLogId, Is.EqualTo(auditDetail.Id));
Assert.That(level1AuditEntry.PrimaryKey, Is.EqualTo($"{{\"Id\":{level2TreeValue.Id}}}"));
Assert.That(level1AuditEntry.IsPrimary, Is.False);
var level2AuditEntry = auditEntries[2];
Assert.That(level2AuditEntry.Id, Is.EqualTo(3));
Assert.That(level2AuditEntry.EntityName, Is.EqualTo(typeof(DeletableTreeValue).FullName));
Assert.That(level2AuditEntry.DisplayName, Is.EqualTo(level1TreeValue.Name));
Assert.That(level2AuditEntry.AuditLogId, Is.EqualTo(auditDetail.Id));
Assert.That(level2AuditEntry.PrimaryKey, Is.EqualTo($"{{\"Id\":{level1TreeValue.Id}}}"));
Assert.That(level2AuditEntry.IsPrimary, Is.False);
var parentAuditEntry = auditEntries[3];
Assert.That(parentAuditEntry.Id, Is.EqualTo(4));
Assert.That(parentAuditEntry.EntityName, Is.EqualTo(typeof(DeletableTreeValue).FullName));
Assert.That(parentAuditEntry.DisplayName, Is.EqualTo(rootTreeValue.Name));
Assert.That(parentAuditEntry.AuditLogId, Is.EqualTo(auditDetail.Id));
Assert.That(parentAuditEntry.PrimaryKey, Is.EqualTo($"{{\"Id\":{rootTreeValue.Id}}}"));
Assert.That(parentAuditEntry.IsPrimary, Is.False);
Assert.That(testDBContext.AuditDrillHierarchies.Count(), Is.EqualTo(3));
var auditDrillHierarchies = testDBContext.AuditDrillHierarchies.ToList();
Assert.That(auditDrillHierarchies[0].ChildAuditDrillDownEntityId, Is.EqualTo(1));
Assert.That(auditDrillHierarchies[0].ParentAuditDrillDownEntityId, Is.EqualTo(2));
Assert.That(auditDrillHierarchies[1].ChildAuditDrillDownEntityId, Is.EqualTo(2));
Assert.That(auditDrillHierarchies[1].ParentAuditDrillDownEntityId, Is.EqualTo(3));
Assert.That(auditDrillHierarchies[2].ChildAuditDrillDownEntityId, Is.EqualTo(3));
Assert.That(auditDrillHierarchies[2].ParentAuditDrillDownEntityId, Is.EqualTo(4));
}
}