using ECMJobRunner.Application.Common.Exceptions; using FluentAssertions; using System; using Xunit; namespace ECMJobRunner.Tests.Application { public class TriggeringDEXJobCommandExceptionTests { [Fact] public void JobSqlException_HasCorrectMessage() { // Arrange var jobName = "Main Query Execution"; var processName = "MainQueryExecution"; var batchId = "12345678901234567890"; var reason = "SQL syntax error"; var query = "SELECT * FROM NonExistentTable"; // Act var exception = new JobSqlException( jobName, processName, batchId, reason, query, null); // Assert exception.JobName.Should().Be(jobName); exception.ProcessName.Should().Be(processName); exception.BatchId.Should().Be(batchId); exception.Query.Should().Be(query); exception.Message.Should().Contain(jobName); exception.Message.Should().Contain(processName); exception.Message.Should().Contain(batchId); exception.Message.Should().Contain(reason); exception.Message.Should().Contain(query); } [Fact] public void JobSqlException_WithInnerException_PreservesInnerException() { // Arrange var innerException = new InvalidOperationException("Database connection failed"); var exception = new JobSqlException( "Main Query", "Execution", "12345678901234567890", "Connection error", "SELECT 1", innerException); // Assert exception.InnerException.Should().Be(innerException); exception.InnerException!.Message.Should().Be("Database connection failed"); } [Fact] public void JobHttpException_HasCorrectMessage() { // Arrange var jobName = "ReC Request Execution"; var processName = "ReCRequestExecution"; var batchId = "12345678901234567890"; var reason = "HTTP 500 Internal Server Error"; var clientLibrary = "ReC.Client"; var clientMethod = "ExecuteAsync"; // Act var exception = new JobHttpException( jobName, processName, batchId, reason, clientLibrary, clientMethod, null); // Assert exception.JobName.Should().Be(jobName); exception.ProcessName.Should().Be(processName); exception.BatchId.Should().Be(batchId); exception.ClientLibrary.Should().Be(clientLibrary); exception.ClientMethod.Should().Be(clientMethod); exception.Message.Should().Contain(jobName); exception.Message.Should().Contain(processName); exception.Message.Should().Contain(batchId); exception.Message.Should().Contain(reason); exception.Message.Should().Contain(clientLibrary); exception.Message.Should().Contain(clientMethod); } [Fact] public void JobHttpException_WithInnerException_PreservesInnerException() { // Arrange var innerException = new TimeoutException("Request timed out"); var exception = new JobHttpException( "ReC Request", "Execution", "12345678901234567890", "Timeout error", "ReC.Client", "ExecuteAsync", innerException); // Assert exception.InnerException.Should().Be(innerException); exception.InnerException!.Message.Should().Be("Request timed out"); } [Fact] public void JobException_OmitsNullValues_WhenIgnoreIfNullIsTrue() { // Arrange & Act var exception = new JobException( "Test Job", "Test Process", "12345678901234567890", null, // reason is null null, ("Custom Detail", "Value", false)); // Assert exception.Message.Should().NotContain("Reason:"); // Should be omitted because it's null and IgnoreIfNull=true exception.Message.Should().Contain("Custom Detail: Value"); } [Fact] public void JobException_IncludesNullValues_WhenIgnoreIfNullIsFalse() { // Arrange & Act var exception = new JobException( "Test Job", "Test Process", "12345678901234567890", null, null, ("Custom Detail", null, false)); // IgnoreIfNull=false // Assert exception.Message.Should().Contain("Custom Detail:"); // Should be included even though value is null } [Fact] public void JobException_FormatsMessageWithSeparators() { // Arrange & Act var exception = new JobException( "Test Job", "Test Process", "12345678901234567890", "Test reason", null); // Assert exception.Message.Should().Contain("─────────────────────────────────────────"); exception.Message.Should().Contain("Test Job could not be completed."); exception.Message.Should().Contain("Process Name: Test Process"); exception.Message.Should().Contain("Batch Id: 12345678901234567890"); } } }