Backend/e-suite.Database.Core/e-suite.Database.Core.UnitTests/SunDatabaseEntityContextUnitTests.cs
2026-01-20 21:50:10 +00:00

195 lines
5.8 KiB
C#

using e_suite.Database.Core.UnitTests.Helpers;
using e_suite.Database.Core.UnitTests.Helpers.Tables;
using eSuite.Core.Clock;
using Moq;
using NUnit.Framework;
namespace e_suite.Database.Core.UnitTests;
[TestFixture]
public class SunDatabaseEntityContextUnitTests
{
protected TestDbContextFactory testDbContextFactory = null!;
protected Mock<IClock> _clockMock = null!;
public DateTimeOffset TestNow = DateTimeOffset.Now;
protected TestDbContext TestDbContext = null!;
[SetUp]
public void Setup()
{
testDbContextFactory = new TestDbContextFactory();
_clockMock = new Mock<IClock>();
_clockMock.Setup(x => x.GetNow).Returns(() => TestNow);
TestDbContext = testDbContextFactory.CreateContext(_clockMock.Object);
}
[Test]
public void OnModelCreating_Executes_WithoutExceptions()
{
//Arrange
//Act
// dealt with by the Setup method, as this ensures the database is created.
//Assert
Assert.That(TestDbContext.TableWithKey.Count(), Is.EqualTo(1));
}
[Test]
public async Task TransActionAsyncAction_Executing_CodeRunsInATransaction()
{
//Arrange
Guid? transactionId = null;
//Act
await TestDbContext.TransactionAsync(async () =>
{
transactionId = TestDbContext.Database.CurrentTransaction?.TransactionId;
await TestDbContext.SaveChangesAsync();
});
//Assert
Assert.That(transactionId, Is.Not.Null); //Was in a transaction when the code was executed
Assert.That(TestDbContext.Database.CurrentTransaction?.TransactionId, Is.Null); //No longer in a transaction
}
[Test]
public async Task TransActionAsyncAction_AlreadyInTransaction_DoesNotStartAnotherTransaction()
{
//Arrange
Guid? transactionId = null;
Guid? innerTransactionId = null;
await TestDbContext.TransactionAsync(async () =>
{
transactionId = TestDbContext.Database.CurrentTransaction?.TransactionId;
//Act
await TestDbContext.TransactionAsync( async () =>
{
innerTransactionId = TestDbContext.Database.CurrentTransaction?.TransactionId;
await TestDbContext.SaveChangesAsync();
});
});
//Assert
Assert.That(transactionId, Is.Not.Null); //Was in a transaction when the code was executed
Assert.That(innerTransactionId, Is.EqualTo(transactionId)); //The inner transaction is the same as the outer transaction. Transaction inception is not allowed.
}
[Test]
public async Task TransActionAsyncAction_InsertedRecordWithNoException_TransactionCompletes()
{
//Arrange
var newItem = new TableWithKey()
{
Id = 2,
TotalTimeMS = 5000
};
Assert.That(TestDbContext.TableWithKey.Count(), Is.EqualTo(1));
//Act
await TestDbContext.TransactionAsync(async () =>
{
TestDbContext.TableWithKey.Add(newItem);
await TestDbContext.SaveChangesAsync();
});
//Assert
Assert.That(TestDbContext.TableWithKey.Count(), Is.EqualTo(2));
}
[Test]
public async Task TransActionAsyncAction_InsertedRecordThenException_TransactionIsRolledback()
{
//Arrange
var newItem = new TableWithKey()
{
Id = 2,
TotalTimeMS = 5000
};
Assert.That(TestDbContext.TableWithKey.Count(), Is.EqualTo(1));
//Act
try
{
await TestDbContext.TransactionAsync(async () =>
{
TestDbContext.TableWithKey.Add(newItem);
await TestDbContext.SaveChangesAsync();
throw new Exception("Testing rollback");
});
}
catch
{
//This was supposed to happen
}
//Assert
Assert.That(TestDbContext.TableWithKey.Count(), Is.EqualTo(1));
}
[Test]
public async Task TransActionAsyncFunc_Executing_CodeRunsInATransaction()
{
//Arrange
Guid? transactionId = null;
//Act
var result = await TestDbContext.TransactionAsync(async () =>
{
transactionId = TestDbContext.Database.CurrentTransaction?.TransactionId;
await TestDbContext.SaveChangesAsync();
return true;
});
//Assert
Assert.That(result, Is.True);
Assert.That(transactionId, Is.Not.Null); //Was in a transaction when the code was executed
Assert.That(TestDbContext.Database.CurrentTransaction?.TransactionId, Is.Null); //No longer in a transaction
}
[Test]
public async Task TransActionAsyncFunc_InsertedRecordThenException_TransactionIsRolledback()
{
//Arrange
var newItem = new TableWithKey()
{
Id = 2,
TotalTimeMS = 5000
};
Assert.That(TestDbContext.TableWithKey.Count(), Is.EqualTo(1));
//Act
try
{
var result = await TestDbContext.TransactionAsync(async () =>
{
TestDbContext.TableWithKey.Add(newItem);
await TestDbContext.SaveChangesAsync();
throw new Exception("Testing rollback");
#pragma warning disable CS0162
//This code will never be hit because this is a test, but it's needed so that the code will compile.
return 1;
#pragma warning restore CS0162
});
}
catch
{
//This was supposed to happen
}
//Assert
Assert.That(TestDbContext.TableWithKey.Count(), Is.EqualTo(1));
}
}