Files
monorepo/LCU.API.Internal.Document/LCU.API.Internal.DocumentTest/Services/DocumentAuditServiceTest.cs
T
2026-03-13 09:11:35 -05:00

557 lines
22 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using FluentAssertions;
using LCU.API.Internal.Document.Exceptions;
using LCU.API.Internal.Document.Services;
using LCU.API.Internal.DocumentLib.Containers;
using LCU.API.Internal.DocumentLib.Repositories;
using LCU.Library.Internal.DocumentModels.Requests;
using Moq;
using NUnit.Framework;
namespace LCU.API.Internal.DocumentTest.Services;
public class DocumentAuditServiceTest
{
private DocumentAuditService _documentAuditService;
private Mock<IDocumentAuditRepository> _mockDocumentAuditRepository;
[SetUp]
public void Setup()
{
_mockDocumentAuditRepository = new Mock<IDocumentAuditRepository>();
_documentAuditService = new DocumentAuditService(_mockDocumentAuditRepository.Object);
}
[Test]
public async Task GetDocumentAudits_RepositoryReturnsActionAudits_ReturnsAuditsTransformedToResponse()
{
var documentId = Guid.NewGuid();
var actionAudits = new List<DocumentAudit>
{
new DocumentActionAudit
(
documentId,
Guid.NewGuid().ToString(),
DateTime.Now,
Guid.NewGuid().ToString(),
Valid<DocumentAction>(),
Guid.NewGuid().ToString()
)
};
_mockDocumentAuditRepository
.Setup(r => r.GetDocumentAudits(documentId))
.ReturnsAsync(actionAudits);
var audits = await _documentAuditService.GetDocumentAudits(documentId);
actionAudits.Should().HaveSameCount(audits);
actionAudits.Should().AllSatisfy(a => audits.Should().ContainEquivalentOf(a));
}
[Test]
public async Task GetDocumentAudits_RepositoryReturnsFieldAudits_ReturnsAuditsTransformedToResponse()
{
var documentId = Guid.NewGuid();
var actionAudits = new List<DocumentAudit>
{
new DocumentFieldAudit
(
documentId,
Guid.NewGuid().ToString(),
DateTime.Now,
Guid.NewGuid().ToString(),
Guid.NewGuid().ToString(),
Guid.NewGuid(),
Guid.NewGuid()
)
};
_mockDocumentAuditRepository
.Setup(r => r.GetDocumentAudits(documentId))
.ReturnsAsync(actionAudits);
var audits = await _documentAuditService.GetDocumentAudits(documentId);
actionAudits.Should().HaveSameCount(audits);
actionAudits.Should().AllSatisfy(a => audits.Should().ContainEquivalentOf(a));
}
[Test]
public async Task GetDocumentAudits_RepositoryReturnsAnyAuditsOfUnknownType_ThrowsDocumentAuditServiceException()
{
var documentId = Guid.NewGuid();
var actionAudits = new List<DocumentAudit>
{
new UnknownAuditType
(
documentId,
Guid.NewGuid().ToString(),
DateTime.Now,
Guid.NewGuid().ToString()
)
};
_mockDocumentAuditRepository
.Setup(r => r.GetDocumentAudits(documentId))
.ReturnsAsync(actionAudits);
Assert.ThrowsAsync<DocumentAuditServiceException>(() => _documentAuditService.GetDocumentAudits(documentId));
}
[Test]
public void GetDocumentAudits_DocumentAuditRepositoryThrowsException_ThrowsDocumentAuditServiceExceptionThrown()
{
var docId = Guid.NewGuid();
_mockDocumentAuditRepository
.Setup(x => x.GetDocumentAudits(docId))
.ThrowsAsync(new Exception("Thrown From Unit Test"))
.Verifiable();
Assert.ThrowsAsync<DocumentAuditServiceException>(async () => await _documentAuditService.GetDocumentAudits(docId));
_mockDocumentAuditRepository.Verify();
}
[Test]
public void GetDocumentAudits_Exception_DocumentAuditServiceExceptionThrown()
{
var docId = Guid.NewGuid();
_mockDocumentAuditRepository
.Setup(x => x.GetDocumentAudits(docId))
.ThrowsAsync(new Exception("Thrown From Unit Test"))
.Verifiable();
Assert.ThrowsAsync<DocumentAuditServiceException>(async () => await _documentAuditService.GetDocumentAudits(docId));
_mockDocumentAuditRepository.Verify();
}
[Test]
public async Task CreateDocumentUploadedAudit_Success()
{
var uploadDate = DateTime.Parse("2022-04-28T17:32:35.093Z");
var documentInformation = GenerateDocumentInformation();
var audits = new DocumentAudit[]
{
new DocumentActionAudit
(
documentInformation.DocumentId,
"System",
uploadDate,
"System",
DocumentAction.Upload,
"Document Uploaded"
)
};
_mockDocumentAuditRepository
.Setup(x => x.SaveDocumentAudits(It.Is<DocumentAudit[]>(list =>
list.Length == 1
&& list.All(a => a is DocumentActionAudit)
&& ((DocumentActionAudit)list.FirstOrDefault()!).Action == DocumentAction.Upload
&& ((DocumentActionAudit)list.FirstOrDefault()!).UserId == "System"
&& ((DocumentActionAudit)list.FirstOrDefault()!).Source == "System"
&& ((DocumentActionAudit)list.FirstOrDefault()!).ActionDescription == "Document Uploaded")))
.ReturnsAsync(audits)
.Verifiable();
var result = await _documentAuditService.CreateDocumentUploadedAudit(documentInformation.DocumentId, uploadDate);
var resultArray = result.ToArray();
Assert.NotNull(result);
audits.Should().HaveSameCount(resultArray);
audits.Should().AllSatisfy(a => resultArray.Should().ContainEquivalentOf(a));
_mockDocumentAuditRepository.Verify();
}
[Test]
public void CreateDocumentUploadedAudit_DocumentAuditRepositoryThrowsException_ThrowsNewDocumentAuditServiceExceptionThrown()
{
var uploadDate = DateTime.Parse("2022-04-28T17:32:35.093Z");
var documentInformation = GenerateDocumentInformation();
_mockDocumentAuditRepository
.Setup(x => x.SaveDocumentAudits(It.Is<DocumentAudit[]>(list => list.Any())))
.ThrowsAsync(new DocumentAuditServiceException("Thrown From Unit Test"))
.Verifiable();
Assert.ThrowsAsync<DocumentAuditServiceException>(() => _documentAuditService.CreateDocumentUploadedAudit(documentInformation.DocumentId, uploadDate));
_mockDocumentAuditRepository.Verify();
}
[Test]
public void CreateDocumentUploadedAudit_Exception_DocumentAuditServiceExceptionThrown()
{
var uploadDate = DateTime.Parse("2022-04-28T17:32:35.093Z");
var documentInformation = GenerateDocumentInformation();
_mockDocumentAuditRepository
.Setup(x => x.SaveDocumentAudits(It.Is<DocumentAudit[]>(list => list.Any())))
.ThrowsAsync(new Exception("Thrown From Unit Test"))
.Verifiable();
Assert.ThrowsAsync<DocumentAuditServiceException>(() => _documentAuditService.CreateDocumentUploadedAudit(documentInformation.DocumentId, uploadDate));
_mockDocumentAuditRepository.Verify();
}
[Test]
public async Task CreateDocumentDeletedAudit_Success()
{
var deleteDate = DateTime.Parse("2022-04-28T17:32:35.093Z");
var documentInformation = GenerateDocumentInformation();
var audits = new DocumentAudit[]
{
new DocumentActionAudit
(
documentInformation.DocumentId,
"System",
deleteDate,
"System",
DocumentAction.Delete,
"Document Deleted"
)
};
_mockDocumentAuditRepository
.Setup(x => x.SaveDocumentAudits(It.Is<DocumentAudit[]>(list =>
list.Length == 1
&& list.All(a => a is DocumentActionAudit)
&& ((DocumentActionAudit)list.FirstOrDefault()!).Action == DocumentAction.Delete
&& ((DocumentActionAudit)list.FirstOrDefault()!).UserId == "System"
&& ((DocumentActionAudit)list.FirstOrDefault()!).Source == "System"
&& ((DocumentActionAudit)list.FirstOrDefault()!).ActionDescription == "Document Deleted")))
.ReturnsAsync(audits)
.Verifiable();
var result = await _documentAuditService.CreateDocumentDeletedAudit(documentInformation.DocumentId, deleteDate);
var resultArray = result.ToArray();
Assert.NotNull(result);
audits.Should().HaveSameCount(resultArray);
audits.Should().AllSatisfy(a => resultArray.Should().ContainEquivalentOf(a));
_mockDocumentAuditRepository.Verify();
}
[Test]
public void CreateDocumentDeletedAudit_DocumentAuditRepositoryThrowsException_ThrowsNewDocumentAuditServiceExceptionThrown()
{
var deleteDate = DateTime.Parse("2022-04-28T17:32:35.093Z");
var documentInformation = GenerateDocumentInformation();
_mockDocumentAuditRepository
.Setup(x => x.SaveDocumentAudits(It.Is<DocumentAudit[]>(list => list.Any())))
.ThrowsAsync(new DocumentAuditServiceException("Thrown From Unit Test"))
.Verifiable();
Assert.ThrowsAsync<DocumentAuditServiceException>(() => _documentAuditService.CreateDocumentDeletedAudit(documentInformation.DocumentId, deleteDate));
_mockDocumentAuditRepository.Verify();
}
[Test]
public void CreateDocumentDeletedAudit_Exception_DocumentAuditServiceExceptionThrown()
{
var deleteDate = DateTime.Parse("2022-04-28T17:32:35.093Z");
var documentInformation = GenerateDocumentInformation();
_mockDocumentAuditRepository
.Setup(x => x.SaveDocumentAudits(It.Is<DocumentAudit[]>(list => list.Any())))
.ThrowsAsync(new Exception("Thrown From Unit Test"))
.Verifiable();
Assert.ThrowsAsync<DocumentAuditServiceException>(() => _documentAuditService.CreateDocumentDeletedAudit(documentInformation.DocumentId, deleteDate));
_mockDocumentAuditRepository.Verify();
}
[Test]
public async Task CreateDocumentContentDeletedAudit_Success()
{
var deleteDate = DateTime.Parse("2022-04-28T17:32:35.093Z");
var documentInformation = GenerateDocumentInformation();
var reason = Guid.NewGuid().ToString();
var reasonFull = $"DocumentContent Deleted. Reason: {reason}";
var audits = new DocumentAudit[]
{
new DocumentActionAudit
(
documentInformation.DocumentId,
"System",
deleteDate,
"System",
DocumentAction.DeleteContent,
reasonFull
)
};
_mockDocumentAuditRepository
.Setup(x => x.SaveDocumentAudits(It.Is<DocumentAudit[]>(list =>
list.Length == 1
&& list.All(a => a is DocumentActionAudit)
&& ((DocumentActionAudit)list.FirstOrDefault()!).Action == DocumentAction.DeleteContent
&& ((DocumentActionAudit)list.FirstOrDefault()!).UserId == "System"
&& ((DocumentActionAudit)list.FirstOrDefault()!).Source == "System"
&& ((DocumentActionAudit)list.FirstOrDefault()!).ActionDescription == reasonFull)))
.ReturnsAsync(audits)
.Verifiable();
var result = await _documentAuditService.CreateDocumentContentDeletedAudit(documentInformation.DocumentId, deleteDate, reason);
var resultArray = result.ToArray();
Assert.NotNull(result);
audits.Should().HaveSameCount(resultArray);
audits.Should().AllSatisfy(a => resultArray.Should().ContainEquivalentOf(a));
_mockDocumentAuditRepository.Verify();
}
[Test]
public void CreateDocumentContentDeletedAudit_DocumentAuditRepositoryThrowsException_ThrowsNewDocumentAuditServiceExceptionThrown()
{
var deleteDate = DateTime.Parse("2022-04-28T17:32:35.093Z");
var documentInformation = GenerateDocumentInformation();
var reason = Guid.NewGuid().ToString();
_mockDocumentAuditRepository
.Setup(x => x.SaveDocumentAudits(It.Is<DocumentAudit[]>(list => list.Any())))
.ThrowsAsync(new DocumentAuditServiceException("Thrown From Unit Test"))
.Verifiable();
Assert.ThrowsAsync<DocumentAuditServiceException>(() => _documentAuditService.CreateDocumentContentDeletedAudit(documentInformation.DocumentId, deleteDate, reason));
_mockDocumentAuditRepository.Verify();
}
[Test]
public void CreateDocumentContentDeletedAudit_Exception_DocumentAuditServiceExceptionThrown()
{
var deleteDate = DateTime.Parse("2022-04-28T17:32:35.093Z");
var documentInformation = GenerateDocumentInformation();
var reason = Guid.NewGuid().ToString();
_mockDocumentAuditRepository
.Setup(x => x.SaveDocumentAudits(It.Is<DocumentAudit[]>(list => list.Any())))
.ThrowsAsync(new Exception("Thrown From Unit Test"))
.Verifiable();
Assert.ThrowsAsync<DocumentAuditServiceException>(() => _documentAuditService.CreateDocumentContentDeletedAudit(documentInformation.DocumentId, deleteDate, reason));
_mockDocumentAuditRepository.Verify();
}
[Test]
public async Task CreateDocumentAudits_No_Differences_Success()
{
var updateDate = DateTime.Parse("2022-04-28T17:32:35.093Z");
var docInformationOld = GenerateDocumentInformation();
var docInformationNew = GenerateDocumentInformation();
var result = await _documentAuditService.CreateDocumentAudits(docInformationOld, docInformationNew, false, updateDate, "testUser");
Assert.NotNull(result);
Assert.IsEmpty(result);
_mockDocumentAuditRepository.Verify(x => x.SaveDocumentAudits(It.IsAny<DocumentAudit[]>()), Times.Never);
}
[Test]
public async Task CreateDocumentAudits_No_Differences_ContentChange_Success()
{
var updateDate = DateTime.Parse("2022-04-28T17:32:35.093Z");
var userId = Guid.NewGuid().ToString();
var docInformationOld = GenerateDocumentInformation();
var docInformationNew = GenerateDocumentInformation();
_mockDocumentAuditRepository
.Setup(x => x.SaveDocumentAudits(It.Is<DocumentAudit[]>(list =>
list.Length == 1
&& list.All(a => a is DocumentFieldAudit)
&& ((DocumentFieldAudit)list.FirstOrDefault()!).Field == "Content"
&& list.All(audit => string.Equals(userId, ((DocumentFieldAudit)audit).UserId)))))
.ReturnsAsync(new List<DocumentAudit>())
.Verifiable();
await _documentAuditService.CreateDocumentAudits(docInformationOld, docInformationNew, true, updateDate, userId);
_mockDocumentAuditRepository.Verify();
}
[Test]
public async Task CreateDocumentAudits_All_Differences_Success()
{
var updateDate = DateTime.Parse("2022-04-28T17:32:35.093Z");
var docInformationOld = GenerateDocumentInformation();
var docInformationEverythingChanges = GenerateDocumentInformation();
var userId = Guid.NewGuid().ToString();
docInformationEverythingChanges.Name = "BrandNewName";
docInformationEverythingChanges.Type = "BrandNewType";
docInformationEverythingChanges.ScanStatus = true;
docInformationEverythingChanges.DataSource = "NEW SOURCE";
docInformationEverythingChanges.Attributes = new Dictionary<string, string>
{
{ "NEW_FIELD", "NEW_VALUE" }
};
_mockDocumentAuditRepository
.Setup(x => x.SaveDocumentAudits(It.Is<DocumentAudit[]>(list =>
list.Length == 4
&& list.All(a => a is DocumentFieldAudit)
&& list.Any(audit => string.Equals("Name", ((DocumentFieldAudit)audit).Field))
&& list.Any(audit => string.Equals("Type", ((DocumentFieldAudit)audit).Field))
&& list.Any(audit => string.Equals("ScanStatus", ((DocumentFieldAudit)audit).Field))
&& list.Any(audit => string.Equals("Attributes", ((DocumentFieldAudit)audit).Field))
&& list.All(audit => string.Equals(userId, ((DocumentFieldAudit)audit).UserId)))))
.ReturnsAsync(new List<DocumentAudit>())
.Verifiable();
await _documentAuditService.CreateDocumentAudits(docInformationOld, docInformationEverythingChanges, false, updateDate, userId);
_mockDocumentAuditRepository.Verify();
}
[Test]
public void CreateDocumentAudits_DocumentAuditRepositoryThrowsException_ThrowsNewDocumentAuditServiceExceptionThrown()
{
var updateDate = DateTime.Parse("2022-04-28T17:32:35.093Z");
var docInformationOld = GenerateDocumentInformation();
var docInformationNew = GenerateDocumentInformation();
var userId = Guid.NewGuid().ToString();
docInformationNew.Name = "NewName.txt";
_mockDocumentAuditRepository
.Setup(x => x.SaveDocumentAudits(It.Is<DocumentAudit[]>(list => list.Any())))
.ThrowsAsync(new DocumentAuditServiceException("Thrown From Unit Test"))
.Verifiable();
Assert.ThrowsAsync<DocumentAuditServiceException>(() => _documentAuditService.CreateDocumentAudits(docInformationOld, docInformationNew, false, updateDate, userId));
_mockDocumentAuditRepository.Verify();
}
[Test]
public void CreateDocumentAudits_Exception_DocumentAuditServiceExceptionThrown()
{
var updateDate = DateTime.Parse("2022-04-28T17:32:35.093Z");
var docInformationOld = GenerateDocumentInformation();
var docInformationNew = GenerateDocumentInformation();
var userId = Guid.NewGuid().ToString();
docInformationNew.Name = "NewName.txt";
_mockDocumentAuditRepository
.Setup(x => x.SaveDocumentAudits(It.Is<DocumentAudit[]>(list => list.Any())))
.ThrowsAsync(new Exception("Thrown From Unit Test"))
.Verifiable();
Assert.ThrowsAsync<DocumentAuditServiceException>(() => _documentAuditService.CreateDocumentAudits(docInformationOld, docInformationNew, false, updateDate, userId));
_mockDocumentAuditRepository.Verify();
}
[Test]
public void AuditAction_RepositoryThrowsException_ThrowsDocumentAuditServiceException()
{
var documentId = Guid.NewGuid();
var userId = Guid.NewGuid().ToString();
var source = Guid.NewGuid().ToString();
var action = Valid<DocumentAction>();
_mockDocumentAuditRepository
.Setup(r => r.SaveDocumentAudits(It.Is<DocumentActionAudit>(a =>
a.DocumentId == documentId
&& a.UserId == userId
&& a.Source == source
&& a.Action == action)))
.ThrowsAsync(new Exception());
Assert.ThrowsAsync<DocumentAuditServiceException>(() => _documentAuditService.AuditAction(documentId, userId, source, action));
}
[Test]
public void AuditAction_UnknownActionType_ThrowsDocumentAuditServiceException()
{
var documentId = Guid.NewGuid();
var userId = Guid.NewGuid().ToString();
var source = Guid.NewGuid().ToString();
var action = Invalid<DocumentAction>();
Assert.ThrowsAsync<DocumentAuditServiceException>(() => _documentAuditService.AuditAction(documentId, userId, source, action));
}
private static DocumentAction[] AllDocumentActions => AllValid<DocumentAction>();
[TestCaseSource(nameof(AllDocumentActions))]
public async Task AuditAction_ValidAction_SavesActionAudit(DocumentAction action)
{
var documentId = Guid.NewGuid();
var userId = Guid.NewGuid().ToString();
var source = Guid.NewGuid().ToString();
_mockDocumentAuditRepository
.Setup(r => r.SaveDocumentAudits(It.Is<DocumentActionAudit>(a =>
a.DocumentId == documentId
&& a.UserId == userId
&& a.Source == source
&& a.Action == action)))
.Verifiable();
await _documentAuditService.AuditAction(documentId, userId, source, action);
_mockDocumentAuditRepository.Verify();
}
private static List<DocumentAudit> GenerateDocumentAudits()
{
return new List<DocumentAudit>
{
new DocumentFieldAudit(Guid.NewGuid(), "UnitTest", DateTime.Parse("2022-04-28T17:32:35.093Z"), "Test", "Test", "0", "1")
};
}
private static DocumentInformation GenerateDocumentInformation()
{
return new DocumentInformation
{
DocumentId = Guid.NewGuid(),
Name = "TestFile.txt",
Type = "Test",
Source = "Developer's Laptop",
ScanStatus = null,
UploadDate = DateTime.Parse("2022-03-25T19:16:12.3665642Z"),
LastModifiedDate = DateTime.Parse("0001-01-01T00:00:00"),
Attributes = new Dictionary<string, string>
{
{ "IsTest", "true" },
{ "Owner", "Me Myself" }
}
};
}
private static T[] AllValid<T>()
where T : struct, Enum
{
return Enum.GetValues<T>();
}
private static T Valid<T>()
where T : struct, Enum
{
var values = Enum.GetValues<T>();
return values[DateTime.Now.Millisecond % values.Length];
}
private static T Invalid<T>()
where T : struct, Enum
{
return (T)Convert.ChangeType(Enum.GetValues<T>().Length + 1, typeof(int));
}
private class UnknownAuditType : DocumentAudit
{
public UnknownAuditType(Guid documentId, string source, DateTime date, string userId)
: base(documentId, source, date, userId)
{
}
}
}