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 EditRowUnitTests : AuditEngineCoreTestBase { [Test] public async Task UpdateRow_TableNotAudited_NoAuditRecordCreated() { //Arrange var auditUserDetails = new AuditUserDetails { UserId = 1, UserDisplayName = "Testy McTester", Comment = "Test comment" }; var leafTreeValue = new GeneralComment { Id = 30000, Comment = "Original Comment", }; testDBContext.GeneralComments.Add(leafTreeValue); await testDBContext.NoAuditSaveChangesAsync(); //Act var itemToEdit = testDBContext.GeneralComments.Single(x => x.Id == leafTreeValue.Id); itemToEdit.Comment = "Modified Comment"; await testDBContext.SaveChangesAsync(auditUserDetails); //Assert Assert.That(testDBContext.AuditDetails.Count(), Is.EqualTo(0)); Assert.That(testDBContext.AuditEntries.Count(), Is.EqualTo(0)); Assert.That(testDBContext.AuditDrillHierarchies.Count(), Is.EqualTo(0)); } [Test] public async Task UpdateRow_TableAudited_AuditRecordIsCreated() { //Arrange const string unmodifiedName = "Leaf Level item"; const string modifiedName = "Modified Name"; var auditUserDetails = new AuditUserDetails { UserId = 1, UserDisplayName = "Testy McTester", Comment = "Test comment" }; var leafTreeValue = new DeletableTreeValue { Id = 30000, Name = unmodifiedName, Test = "Test Value" }; testDBContext.DeletableTreeValues.Add(leafTreeValue); await testDBContext.NoAuditSaveChangesAsync(); //Act var itemToEdit = testDBContext.DeletableTreeValues.Single(x => x.Id == leafTreeValue.Id); itemToEdit.Name = modifiedName; 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(AuditType.Update.ToString())); Assert.That(auditDetail.Fields, Is.EqualTo($"{{\"Name\":{{\"OldValue\":\"{unmodifiedName}\",\"NewValue\":\"{modifiedName}\"}}}}")); 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(modifiedName)); 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)); } [Test] public async Task UpdateRow_MultipleFieldsEdited_AuditRecordIsCreated() { //Arrange const string unmodifiedName = "Leaf Level item"; const string modifiedName = "Modified Name"; const string unmodifiedTestValue = "Test Value"; const string modifiedTestValue = "Altered Test Value"; var auditUserDetails = new AuditUserDetails { UserId = 1, UserDisplayName = "Testy McTester", Comment = "Test comment" }; var leafTreeValue = new DeletableTreeValue { Id = 30000, Name = unmodifiedName, Test = unmodifiedTestValue }; testDBContext.DeletableTreeValues.Add(leafTreeValue); await testDBContext.NoAuditSaveChangesAsync(); //Act var itemToEdit = testDBContext.DeletableTreeValues.Single(x => x.Id == leafTreeValue.Id); itemToEdit.Name = modifiedName; itemToEdit.Test = modifiedTestValue; 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(AuditType.Update.ToString())); Assert.That(auditDetail.Fields, Is.EqualTo($"{{\"Name\":{{\"OldValue\":\"{unmodifiedName}\",\"NewValue\":\"{modifiedName}\"}},\"Test\":{{\"OldValue\":\"{unmodifiedTestValue}\",\"NewValue\":\"{modifiedTestValue}\"}}}}")); 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(modifiedName)); 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)); } [Test] public async Task UpdateRow_WhenUpdatingSecretValue_AuditRecordIsMarkedAsRedacted() { //Arrange const string originalSecret = "I've forgotten"; const string modifiedSecret = "I'm not telling you"; var auditUserDetails = new AuditUserDetails { UserId = 1, UserDisplayName = "Testy McTester", Comment = "Test comment" }; var leafTreeValue = new SecretValue { Id = 30000, Name = "Test secret", Secret = originalSecret }; testDBContext.SecretValues.Add(leafTreeValue); await testDBContext.NoAuditSaveChangesAsync(); //Act var itemToEdit = testDBContext.SecretValues.Single(x => x.Id == leafTreeValue.Id); itemToEdit.Secret = modifiedSecret; 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(AuditType.Update.ToString())); Assert.That(auditDetail.Fields, Is.EqualTo($"{{\"Secret\":{{\"OldValue\":\"\",\"NewValue\":\"\"}}}}")); 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(SecretValue).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)); } [Test] public async Task UpdateRow_WhenChangingParentIdInChildValueFromNull_NewNameIsPopulatedCorrectly() { //Arrange var auditUserDetails = new AuditUserDetails { UserId = 1, UserDisplayName = "Testy McTester", Comment = "Test comment" }; testDBContext.ParentValues.Add(new ParentValue { Id = 10, Name = "Parent 10", }); testDBContext.ParentValues.Add(new ParentValue { Id = 20, Name = "Parent 20", }); testDBContext.ChildValues.Add(new ChildValue { Id = 1, Name = "ChildValue", ParentId = null }); await testDBContext.NoAuditSaveChangesAsync(); //Act var childValue = testDBContext.ChildValues.Single(x => x.Id == 1); childValue.ParentId = 20; await testDBContext.SaveChangesAsync(auditUserDetails); //Assert var auditEntries = testDBContext.AuditEntries.Where( x => x.IsPrimary == true).ToList(); Assert.That(auditEntries.Count, Is.EqualTo(1)); var entry = auditEntries.First(); Assert.That(entry.AuditLog.Fields, Is.EqualTo("{\"ParentId\":{\"NewValue\":20,\"NewDisplayName\":\"Parent 20\"}}")); } [Test] public async Task UpdateRow_WhenChangingParentIdInChildValueChanged_OldNameAndNewNamePopulatedCorrectly() { //Arrange var auditUserDetails = new AuditUserDetails { UserId = 1, UserDisplayName = "Testy McTester", Comment = "Test comment" }; testDBContext.ParentValues.Add(new ParentValue { Id = 10, Name = "Parent 10", }); testDBContext.ParentValues.Add(new ParentValue { Id = 20, Name = "Parent 20", }); testDBContext.ChildValues.Add(new ChildValue { Id = 1, Name = "ChildValue", ParentId = 10 }); await testDBContext.NoAuditSaveChangesAsync(); //Act var childValue = testDBContext.ChildValues.Single(x => x.Id == 1); childValue.ParentId = 20; await testDBContext.SaveChangesAsync(auditUserDetails); //Assert var auditEntries = testDBContext.AuditEntries.Where(x => x.IsPrimary == true).ToList(); Assert.That(auditEntries.Count, Is.EqualTo(1)); var entry = auditEntries.First(); Assert.That(entry.AuditLog.Fields, Is.EqualTo("{\"ParentId\":{\"OldValue\":10,\"OldDisplayName\":\"Parent 10\",\"NewValue\":20,\"NewDisplayName\":\"Parent 20\"}}")); } [Test] public async Task UpdateRow_WhenChangingParentIdInChildValueChangedToNull_OldNameAndNewNamePopulatedCorrectly() { //Arrange var auditUserDetails = new AuditUserDetails { UserId = 1, UserDisplayName = "Testy McTester", Comment = "Test comment" }; testDBContext.ParentValues.Add(new ParentValue { Id = 10, Name = "Parent 10", }); testDBContext.ParentValues.Add(new ParentValue { Id = 20, Name = "Parent 20", }); testDBContext.ChildValues.Add(new ChildValue { Id = 1, Name = "ChildValue", ParentId = 10 }); await testDBContext.NoAuditSaveChangesAsync(); //Act var childValue = testDBContext.ChildValues.Single(x => x.Id == 1); childValue.ParentId = null; await testDBContext.SaveChangesAsync(auditUserDetails); //Assert var auditEntries = testDBContext.AuditEntries.Where(x => x.IsPrimary == true).ToList(); Assert.That(auditEntries.Count, Is.EqualTo(1)); var entry = auditEntries.First(); Assert.That(entry.AuditLog.Fields, Is.EqualTo("{\"ParentId\":{\"OldValue\":10,\"OldDisplayName\":\"Parent 10\"}}")); } }