Inicio
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
using audit_logs.Repositories;
|
||||
using audit.Model;
|
||||
|
||||
namespace audit_test.Repository;
|
||||
|
||||
public class AuditRecordRepositoryTests
|
||||
{
|
||||
private AuditRecordRepository _repository = null!;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_repository = new AuditRecordRepository (IntegrationDb.Database);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task InsertRecord_RecordIsInsertedAndCanBeRetrieved()
|
||||
{
|
||||
var record = new AuditRecord
|
||||
{
|
||||
EntityType = "User",
|
||||
RecordId = "1",
|
||||
UserId = "123",
|
||||
ActionType = "Create",
|
||||
ActionTime = DateTime.UtcNow,
|
||||
Changes = new List<AuditRecord.Change>
|
||||
{
|
||||
new AuditRecord.Change { Field = "Username", OldValue = "oldUser", NewValue = "newUser", ValueType = "String" }
|
||||
},
|
||||
Reason = "Ingreso de paciente"
|
||||
};
|
||||
|
||||
await _repository.InsertOneAsync(record);
|
||||
|
||||
var retrievedRecord = await _repository.FindRecordByIdAsync(record.Id);
|
||||
|
||||
Assert.IsNotNull(retrievedRecord);
|
||||
Assert.AreEqual(record.ActionType, retrievedRecord.ActionType);
|
||||
//Assert.AreEqual(record.Details, retrievedRecord.Details);
|
||||
}
|
||||
[Test]
|
||||
public async Task GetAllAuditRecords_ReturnsAllRecords()
|
||||
{
|
||||
// Prepare data
|
||||
var records = new List<AuditRecord>
|
||||
{
|
||||
new AuditRecord { EntityType = "User", RecordId = "1", UserId = "123", ActionType = "Create", ActionTime = DateTime.UtcNow, Reason = "Test Reason 1" },
|
||||
new AuditRecord { EntityType = "Admin", RecordId = "2", UserId = "456", ActionType = "Delete", ActionTime = DateTime.UtcNow, Reason = "Test Reason 2" }
|
||||
};
|
||||
|
||||
foreach (var rec in records)
|
||||
{
|
||||
await _repository.InsertOneAsync(rec);
|
||||
}
|
||||
|
||||
// Test GetAllAuditRecordsAsync method
|
||||
var allRecords = await _repository.GetAllAuditRecordsAsync();
|
||||
|
||||
// Assert that all records are retrieved
|
||||
Assert.IsNotNull(allRecords);
|
||||
Assert.AreEqual(2, allRecords.Count); // This assumes the database is empty before test starts
|
||||
Assert.IsTrue(allRecords.Exists(r => r.RecordId == "1" && r.EntityType == "User"));
|
||||
Assert.IsTrue(allRecords.Exists(r => r.RecordId == "2" && r.EntityType == "Admin"));
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public async Task Cleanup()
|
||||
{
|
||||
|
||||
await IntegrationDb.Database.DropCollectionAsync("AuditRecords");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
using audit_logs.Utils;
|
||||
|
||||
namespace audit_test.Repository;
|
||||
|
||||
using audit_logs.Repositories;
|
||||
using audit.Model;
|
||||
using audit_logs.Services;
|
||||
|
||||
public class AuditServiceIntegrationTests
|
||||
{
|
||||
private AuditService _service;
|
||||
// private AuditRecordRepository _repository;
|
||||
|
||||
[Order(1)]
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
IntegrationDb.Database.DropCollectionAsync("AuditRecords");
|
||||
//_repository = new AuditRecordRepository(IntegrationDb.Database);
|
||||
_service = new AuditService(IntegrationDb.Database);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task RecordAuditAsync_CreatesAndRetrievesAuditRecord()
|
||||
{
|
||||
// Arrange
|
||||
var changes = new List<AuditRecord.Change>
|
||||
{
|
||||
new AuditRecord.Change
|
||||
{ Field = "Username", OldValue = "oldUser", NewValue = "newUser", ValueType = "String" }
|
||||
};
|
||||
string entityType = "User",
|
||||
recordId = "1",
|
||||
userId = "123",
|
||||
actionType = "Create",
|
||||
reason = "Testing create functionality";
|
||||
DateTime actionTime = DateTime.UtcNow;
|
||||
|
||||
// Act
|
||||
await _service.RecordAuditAsync(entityType, recordId, userId, actionType, reason,actionTime, changes );
|
||||
|
||||
|
||||
// Retrieve all records to validate insertion
|
||||
var allRecords = await _service.AuditLogRepository.GetAllAuditRecordsAsync();
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, allRecords.Count, "There should be exactly three audit record in the database.");
|
||||
var storedRecord = allRecords[0];
|
||||
Assert.AreEqual(entityType, storedRecord.EntityType);
|
||||
Assert.AreEqual(recordId, storedRecord.RecordId);
|
||||
Assert.AreEqual(userId, storedRecord.UserId);
|
||||
Assert.AreEqual(actionType, storedRecord.ActionType);
|
||||
Assert.AreEqual(reason, storedRecord.Reason);
|
||||
// Assert.That(storedRecord.Changes, Is.EquivalentTo(changes).Using(new ChangeComparer()), "Changes should match the input changes.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetAllAuditRecords_ReturnsAllRecords()
|
||||
{
|
||||
// Prepare multiple records
|
||||
var records = new List<AuditRecord>
|
||||
{
|
||||
new AuditRecord
|
||||
{
|
||||
EntityType = "User", RecordId = "1", UserId = "123", ActionType = "Create",
|
||||
ActionTime = DateTime.UtcNow, Reason = "Test Reason 1"
|
||||
},
|
||||
new AuditRecord
|
||||
{
|
||||
EntityType = "Admin", RecordId = "2", UserId = "456", ActionType = "Delete",
|
||||
ActionTime = DateTime.UtcNow, Reason = "Test Reason 2"
|
||||
}
|
||||
};
|
||||
|
||||
foreach (var rec in records)
|
||||
{
|
||||
await _service.AuditLogRepository.InsertOneAsync(rec);
|
||||
}
|
||||
|
||||
// Test retrieval method
|
||||
var allRecords = await _service.AuditLogRepository.GetAllAuditRecordsAsync();
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(2, allRecords.Count, "All records should be retrieved.");
|
||||
Assert.IsTrue(allRecords.Exists(r => r.RecordId == "1" && r.EntityType == "User"));
|
||||
Assert.IsTrue(allRecords.Exists(r => r.RecordId == "2" && r.EntityType == "Admin"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task DetectChangesAsync_DetectsAndRecordsChanges()
|
||||
{
|
||||
// Arrange
|
||||
string originalJson = "{ \"Username\": \"oldUser\", \"Email\": \"old@example.com\", \"address\": 15 }";
|
||||
string modifiedJson =
|
||||
"{ \"Username\": \"newUser\", \"Email\": \"old@example.com\", \"PhoneNumber\": \"123456789\" }";
|
||||
|
||||
// Variables de auditoría
|
||||
string entityType = "User";
|
||||
string recordId = "1";
|
||||
string userId = "123";
|
||||
string actionType = "Update";
|
||||
DateTime actionTime = DateTime.UtcNow;
|
||||
string reason = "Testing change detection";
|
||||
|
||||
// Act - Llamar a DetectChangesAsync para que identifique cambios
|
||||
await _service.CreateAuditLogAsync(entityType, recordId, userId, actionType, reason,actionTime,originalJson, modifiedJson);
|
||||
|
||||
// Act - Registrar la auditoría usando los cambios detectados
|
||||
// List<AuditRecord.Change> changes = new JsonComparer().GetDifferences(originalJson, modifiedJson);
|
||||
//await _service.RecordAuditAsync(entityType, recordId, userId, actionType, reason,actionTime, changes, );
|
||||
|
||||
// Retrieve all records to validate insertion
|
||||
var allRecords = await _service.AuditLogRepository.GetAllAuditRecordsAsync();
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, allRecords.Count, "Debe haber exactamente un registro de auditoría en la base de datos.");
|
||||
var storedRecord = allRecords[0];
|
||||
Assert.AreEqual(entityType, storedRecord.EntityType);
|
||||
Assert.AreEqual(recordId, storedRecord.RecordId);
|
||||
Assert.AreEqual(userId, storedRecord.UserId);
|
||||
Assert.AreEqual(actionType, storedRecord.ActionType);
|
||||
Assert.AreEqual(reason, storedRecord.Reason);
|
||||
|
||||
// Verificar que los cambios detectados sean correctos
|
||||
Assert.AreEqual(3, storedRecord.Changes.Count, "Debería detectar dos cambios.");
|
||||
|
||||
var changeUsername = storedRecord.Changes.Find(c => c.Field == "Username");
|
||||
Assert.NotNull(changeUsername, "Debe existir un cambio en el campo 'Username'.");
|
||||
Assert.AreEqual("oldUser", changeUsername.OldValue.AsString);
|
||||
Assert.AreEqual("newUser", changeUsername.NewValue.AsString);
|
||||
Assert.AreEqual("string", changeUsername.ValueType);
|
||||
|
||||
var changePhoneNumber = storedRecord.Changes.Find(c => c.Field == "PhoneNumber");
|
||||
Assert.NotNull(changePhoneNumber, "Debe existir un cambio en el campo 'PhoneNumber'.");
|
||||
Assert.IsTrue(changePhoneNumber.OldValue.IsBsonNull, "El valor anterior de 'PhoneNumber' debe ser nulo.");
|
||||
Assert.AreEqual("123456789", changePhoneNumber.NewValue.AsString);
|
||||
Assert.AreEqual("string", changePhoneNumber.ValueType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using audit_logs.Utils;
|
||||
|
||||
namespace audit_test.Repository;
|
||||
using Mongo2Go;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Driver;
|
||||
|
||||
[SetUpFixture]
|
||||
[Category("Integration")]
|
||||
public class IntegrationDb
|
||||
{
|
||||
public static MongoDbRunner Runner { get { return _runner; } }
|
||||
public static MongoClient Client { get { return _client; } }
|
||||
public static IMongoDatabase Database { get; private set; } = null!;
|
||||
|
||||
private static MongoDbRunner _runner = null!;
|
||||
private static MongoClient _client = null!;
|
||||
|
||||
private const int TimeoutInSeconds = 60; // Set the desired timeout in seconds.
|
||||
public static string DatabaseName { get; private set; } = "IntegrationTestDb";
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void InitIntegrationTests()
|
||||
{
|
||||
StartMongoDbRunner().Wait();
|
||||
MongoDbHostBuilderExtension.ConfigureMongoDbConventions();
|
||||
//MongoDbHostBuilderExtension.ConfigureRegisterMapClass();
|
||||
_client = new MongoClient(_runner.ConnectionString);
|
||||
Database = _client.GetDatabase(DatabaseName);
|
||||
}
|
||||
|
||||
private static async Task StartMongoDbRunner()
|
||||
{
|
||||
_runner = MongoDbRunner.Start();
|
||||
|
||||
// Wait for the MongoDB server to become available or timeout.
|
||||
var startTime = DateTime.UtcNow;
|
||||
while (DateTime.UtcNow - startTime < TimeSpan.FromSeconds(TimeoutInSeconds))
|
||||
{
|
||||
try
|
||||
{
|
||||
var testClient = new MongoClient(_runner.ConnectionString);
|
||||
var adminDb = testClient.GetDatabase("admin");
|
||||
await adminDb.RunCommandAsync((Command<BsonDocument>)"{ping:1}");
|
||||
return; // MongoDB server is available, continue.
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Retry after a short delay.
|
||||
await Task.Delay(500);
|
||||
}
|
||||
}
|
||||
|
||||
// Timeout reached, dispose the runner and throw an exception.
|
||||
_runner?.Dispose();
|
||||
throw new TimeoutException("Timeout while starting MongoDB server.");
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void TeardownIntegrationTests()
|
||||
{
|
||||
_runner?.Dispose();
|
||||
_runner = null;
|
||||
_client = null;
|
||||
Database = null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using audit.Model;
|
||||
using audit.Repositories.Interfaces;
|
||||
using audit_logs.Services;
|
||||
|
||||
namespace audit_test.Service;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
public class AuditServiceTests
|
||||
{
|
||||
private readonly Mock<IAuditRecordRepository> _mockRepository;
|
||||
private readonly AuditService _auditService;
|
||||
private readonly AuditRecord _testAuditRecord;
|
||||
|
||||
public AuditServiceTests()
|
||||
{
|
||||
// creo el mock del repositorio
|
||||
_mockRepository = new Mock<IAuditRecordRepository>();
|
||||
|
||||
// preparo el servicio con el mock de repositorio
|
||||
_auditService = new AuditService(_mockRepository.Object);
|
||||
|
||||
// configuracion del registro
|
||||
_testAuditRecord = new AuditRecord
|
||||
{
|
||||
EntityType = "User",
|
||||
RecordId = "1",
|
||||
UserId = "123",
|
||||
ActionType = "Create",
|
||||
ActionTime = DateTime.UtcNow,
|
||||
Changes = new List<AuditRecord.Change>
|
||||
{
|
||||
new AuditRecord.Change { Field = "Username", OldValue = "oldUser", NewValue = "newUser", ValueType = "String" }
|
||||
},
|
||||
Reason = "Ingreso de paciente"
|
||||
};
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RecordAuditAsync_ValidRecord_InsertsRecord()
|
||||
{
|
||||
// Arrange
|
||||
_mockRepository.Setup(repo => repo.InsertOneAsync(It.IsAny<AuditRecord>()))
|
||||
.Returns(Task.CompletedTask);
|
||||
|
||||
// Act
|
||||
await _auditService.RecordAuditAsync(
|
||||
_testAuditRecord.EntityType,
|
||||
_testAuditRecord.RecordId,
|
||||
_testAuditRecord.UserId,
|
||||
_testAuditRecord.ActionType,
|
||||
_testAuditRecord.Reason,
|
||||
_testAuditRecord.ActionTime,
|
||||
_testAuditRecord.Changes
|
||||
);
|
||||
|
||||
// Assert
|
||||
_mockRepository.Verify(repo => repo.InsertOneAsync(It.IsAny<AuditRecord>()), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RecordAuditAsync_NullRecord_ThrowsArgumentNullException()
|
||||
{
|
||||
// Act & Assert
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(() =>
|
||||
_auditService.RecordAuditAsync(null, null, null, null, null,DateTime.MinValue, null));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace audit_test;
|
||||
|
||||
public class Tests
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test1()
|
||||
{
|
||||
Assert.Pass();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RootNamespace>audit_test</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
|
||||
<PackageReference Include="Mongo2Go" Version="2.2.16" />
|
||||
<PackageReference Include="Moq" Version="4.20.72" />
|
||||
<PackageReference Include="NUnit" Version="3.14.0"/>
|
||||
<PackageReference Include="NUnit.Analyzers" Version="3.9.0"/>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
||||
<PackageReference Include="xunit" Version="2.9.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="NUnit.Framework"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\audit-logs\audit-logs.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net8.0",
|
||||
"framework": {
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "8.0.0"
|
||||
},
|
||||
"configProperties": {
|
||||
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user