diff --git a/Doxyfile b/Doxyfile
index 25f49f0..dc44b75 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -48,7 +48,7 @@ PROJECT_NAME = Serilog.Sinks.SlackWebHook
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 2.1.1
+PROJECT_NUMBER = 2.1.3
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/src/jjm.one.Serilog.Sinks.SlackWebHook.Example/SlackSinkExample.cs b/src/jjm.one.Serilog.Sinks.SlackWebHook.Example/SlackSinkExample.cs
index dd61400..031243c 100644
--- a/src/jjm.one.Serilog.Sinks.SlackWebHook.Example/SlackSinkExample.cs
+++ b/src/jjm.one.Serilog.Sinks.SlackWebHook.Example/SlackSinkExample.cs
@@ -1,4 +1,5 @@
using System;
+using System.Diagnostics.CodeAnalysis;
using System.Threading;
using Serilog;
using Serilog.Core;
@@ -16,6 +17,7 @@ public static class SlackSinkExample
///
///
///
+ [ExcludeFromCodeCoverage]
public static void Main()
{
string? slackChannel = null;
diff --git a/src/jjm.one.Serilog.Sinks.SlackWebHook.Tests/GlobalUsings.cs b/src/jjm.one.Serilog.Sinks.SlackWebHook.Tests/GlobalUsings.cs
new file mode 100644
index 0000000..a4c5550
--- /dev/null
+++ b/src/jjm.one.Serilog.Sinks.SlackWebHook.Tests/GlobalUsings.cs
@@ -0,0 +1,2 @@
+global using FluentAssertions;
+global using Xunit;
\ No newline at end of file
diff --git a/src/jjm.one.Serilog.Sinks.SlackWebHook.Tests/SlackLoggerConfigurationExtensionsConstructorParameterTests.cs b/src/jjm.one.Serilog.Sinks.SlackWebHook.Tests/SlackLoggerConfigurationExtensionsTests.cs
similarity index 55%
rename from src/jjm.one.Serilog.Sinks.SlackWebHook.Tests/SlackLoggerConfigurationExtensionsConstructorParameterTests.cs
rename to src/jjm.one.Serilog.Sinks.SlackWebHook.Tests/SlackLoggerConfigurationExtensionsTests.cs
index ab191ca..ea71972 100644
--- a/src/jjm.one.Serilog.Sinks.SlackWebHook.Tests/SlackLoggerConfigurationExtensionsConstructorParameterTests.cs
+++ b/src/jjm.one.Serilog.Sinks.SlackWebHook.Tests/SlackLoggerConfigurationExtensionsTests.cs
@@ -1,27 +1,28 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Net.Http;
-using NUnit.Framework;
+using Moq;
using Serilog;
using Serilog.Events;
using Slack.Webhooks;
namespace jjm.one.Serilog.Sinks.SlackWebHook.Tests;
-[TestFixture]
-public class SlackLoggerConfigurationExtensionsConstructorParameterTests
+///
+/// Unit tests for the SlackLoggerConfigurationExtensions class.
+///
+public class SlackLoggerConfigurationExtensionsTests
{
- [SetUp]
- public void SetUp()
- {
- }
-
- private const string ValidWebHook = @"https://slack.com/api/api.test";
+ private const string ValidWebHook = "https://slack.com/api/api.test";
- [Test]
+ ///
+ /// Test to ensure that the constructor throws an ArgumentNullException when the webhook URL is null.
+ ///
+ [Fact]
public void SingleChannel_ConstructorTest_WebHookUrlNull()
{
- Assert.Throws(() =>
+ // Arrange
+ var act = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -29,13 +30,20 @@ public void SingleChannel_ConstructorTest_WebHookUrlNull()
slackChannel: null
)
.CreateLogger();
- });
+ };
+
+ // Act & Assert
+ act.Should().Throw();
}
- [Test]
+ ///
+ /// Test to ensure that the constructor throws an ArgumentException when the webhook URL is empty.
+ ///
+ [Fact]
public void SingleChannel_ConstructorTest_WebHookUrlEmpty()
{
- Assert.Throws(() =>
+ // Arrange
+ var act = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -43,13 +51,20 @@ public void SingleChannel_ConstructorTest_WebHookUrlEmpty()
slackChannel: null
)
.CreateLogger();
- });
+ };
+
+ // Act & Assert
+ act.Should().Throw();
}
- [Test]
+ ///
+ /// Test to ensure that the constructor does not throw an exception when the webhook URL is valid.
+ ///
+ [Fact]
public void SingleChannel_ConstructorTest_WebHookUrlValid()
{
- Assert.DoesNotThrow(() =>
+ // Arrange
+ var act = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -57,13 +72,20 @@ public void SingleChannel_ConstructorTest_WebHookUrlValid()
slackChannel: null
)
.CreateLogger();
- });
+ };
+
+ // Act & Assert
+ act.Should().NotThrow();
}
- [Test]
+ ///
+ /// Test to ensure that the constructor throws an ArgumentNullException when the webhook URL is null.
+ ///
+ [Fact]
public void MultiChannel_ConstructorTest_WebHookUrlNull()
{
- Assert.Throws(() =>
+ // Arrange
+ var act = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -71,13 +93,20 @@ public void MultiChannel_ConstructorTest_WebHookUrlNull()
slackChannel: null
)
.CreateLogger();
- });
+ };
+
+ // Act & Assert
+ act.Should().Throw();
}
- [Test]
+ ///
+ /// Test to ensure that the constructor throws an ArgumentException when the webhook URL is empty.
+ ///
+ [Fact]
public void MultiChannel_ConstructorTest_WebHookUrlEmpty()
{
- Assert.Throws(() =>
+ // Arrange
+ var act = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -85,13 +114,20 @@ public void MultiChannel_ConstructorTest_WebHookUrlEmpty()
slackChannels: null
)
.CreateLogger();
- });
+ };
+
+ // Act & Assert
+ act.Should().Throw();
}
- [Test]
+ ///
+ /// Test to ensure that the constructor does not throw an exception when the webhook URL is valid.
+ ///
+ [Fact]
public void MultiChannel_ConstructorTest_WebHookUrlValid()
{
- Assert.DoesNotThrow(() =>
+ // Arrange
+ var act = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -99,13 +135,21 @@ public void MultiChannel_ConstructorTest_WebHookUrlValid()
slackChannels: null
)
.CreateLogger();
- });
+ };
+
+ // Act & Assert
+ act.Should().NotThrow();
}
- [Test]
+ ///
+ /// Test to ensure that the constructor throws an InvalidCastException when the slackParseObj is a string.
+ /// Also, it should not throw any exception when the slackParseObj is of type ParseMode.
+ ///
+ [Fact]
public void SingleChannel_ConstructorTest_SlackParseObjCast()
{
- Assert.Throws(() =>
+ // Arrange
+ var actInvalidCast = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -114,9 +158,9 @@ public void SingleChannel_ConstructorTest_SlackParseObjCast()
slackParseObj: "TestObject"
)
.CreateLogger();
- });
+ };
- Assert.DoesNotThrow(() =>
+ var actValidCast = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -125,13 +169,22 @@ public void SingleChannel_ConstructorTest_SlackParseObjCast()
slackParseObj: ParseMode.None
)
.CreateLogger();
- });
+ };
+
+ // Act & Assert
+ actInvalidCast.Should().Throw();
+ actValidCast.Should().NotThrow();
}
- [Test]
+ ///
+ /// Test to ensure that the constructor throws an InvalidCastException when the slackParseObj is a string.
+ /// Also, it should not throw any exception when the slackParseObj is of type ParseMode.
+ ///
+ [Fact]
public void MultiChannel_ConstructorTest_SlackParseObjCast()
{
- Assert.Throws(() =>
+ // Arrange
+ var actInvalidCast = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -140,9 +193,9 @@ public void MultiChannel_ConstructorTest_SlackParseObjCast()
slackParseObj: "TestObject"
)
.CreateLogger();
- });
+ };
- Assert.DoesNotThrow(() =>
+ var actValidCast = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -151,13 +204,23 @@ public void MultiChannel_ConstructorTest_SlackParseObjCast()
slackParseObj: ParseMode.None
)
.CreateLogger();
- });
+ };
+
+ // Act & Assert
+ actInvalidCast.Should().Throw();
+ actValidCast.Should().NotThrow();
}
- [Test]
+ ///
+ /// Test to ensure that the constructor throws an InvalidCastException when the slackAttachmentColorsObj is a string.
+ /// Also, it should not throw any exception when the slackAttachmentColorsObj is of type Dictionary
+ /// .
+ ///
+ [Fact]
public void SingleChannel_ConstructorTest_SlackAttachmentColorsObjCast()
{
- Assert.Throws(() =>
+ // Arrange
+ var actInvalidCast = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -166,9 +229,9 @@ public void SingleChannel_ConstructorTest_SlackAttachmentColorsObjCast()
slackAttachmentColorsObj: "TestObject"
)
.CreateLogger();
- });
+ };
- Assert.DoesNotThrow(() =>
+ var actValidCast = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -180,13 +243,23 @@ public void SingleChannel_ConstructorTest_SlackAttachmentColorsObjCast()
}
)
.CreateLogger();
- });
+ };
+
+ // Act & Assert
+ actInvalidCast.Should().Throw();
+ actValidCast.Should().NotThrow();
}
- [Test]
+ ///
+ /// Test to ensure that the constructor throws an InvalidCastException when the slackAttachmentColorsObj is a string.
+ /// Also, it should not throw any exception when the slackAttachmentColorsObj is of type Dictionary
+ /// .
+ ///
+ [Fact]
public void MultiChannel_ConstructorTest_SlackAttachmentColorsObjCast()
{
- Assert.Throws(() =>
+ // Arrange
+ var actInvalidCast = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -195,9 +268,9 @@ public void MultiChannel_ConstructorTest_SlackAttachmentColorsObjCast()
slackAttachmentColorsObj: "TestObject"
)
.CreateLogger();
- });
+ };
- Assert.DoesNotThrow(() =>
+ var actValidCast = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -209,13 +282,24 @@ public void MultiChannel_ConstructorTest_SlackAttachmentColorsObjCast()
}
)
.CreateLogger();
- });
+ };
+
+ // Act & Assert
+ actInvalidCast.Should().Throw();
+ actValidCast.Should().NotThrow();
}
- [Test]
+ ///
+ /// Test to ensure that the constructor throws an InvalidCastException when the slackAttachmentFooterIconObj is a
+ /// string.
+ /// Also, it should not throw any exception when the slackAttachmentFooterIconObj is of type Dictionary
+ /// .
+ ///
+ [Fact]
public void SingleChannel_ConstructorTest_SlackAttachmentFooterIconObjCast()
{
- Assert.Throws(() =>
+ // Arrange
+ var actInvalidCast = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -224,9 +308,9 @@ public void SingleChannel_ConstructorTest_SlackAttachmentFooterIconObjCast()
slackAttachmentFooterIconObj: "TestObject"
)
.CreateLogger();
- });
+ };
- Assert.DoesNotThrow(() =>
+ var actValidCast = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -238,13 +322,24 @@ public void SingleChannel_ConstructorTest_SlackAttachmentFooterIconObjCast()
}
)
.CreateLogger();
- });
+ };
+
+ // Act & Assert
+ actInvalidCast.Should().Throw();
+ actValidCast.Should().NotThrow();
}
- [Test]
+ ///
+ /// Test to ensure that the constructor throws an InvalidCastException when the slackAttachmentFooterIconObj is a
+ /// string.
+ /// Also, it should not throw any exception when the slackAttachmentFooterIconObj is of type Dictionary
+ /// .
+ ///
+ [Fact]
public void MultiChannel_ConstructorTest_SlackAttachmentFooterIconObjCast()
{
- Assert.Throws(() =>
+ // Arrange
+ var actInvalidCast = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -253,9 +348,9 @@ public void MultiChannel_ConstructorTest_SlackAttachmentFooterIconObjCast()
slackAttachmentFooterIconObj: "TestObject"
)
.CreateLogger();
- });
+ };
- Assert.DoesNotThrow(() =>
+ var actValidCast = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -267,13 +362,22 @@ public void MultiChannel_ConstructorTest_SlackAttachmentFooterIconObjCast()
}
)
.CreateLogger();
- });
+ };
+
+ // Act & Assert
+ actInvalidCast.Should().Throw();
+ actValidCast.Should().NotThrow();
}
- [Test]
+ ///
+ /// Test to ensure that the constructor throws an InvalidCastException when the slackHttpClientObj is a string.
+ /// Also, it should not throw any exception when the slackHttpClientObj is of type HttpClient.
+ ///
+ [Fact]
public void SingleChannel_ConstructorTest_SlackHttpClientObjCast()
{
- Assert.Throws(() =>
+ // Arrange
+ var actInvalidCast = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -282,24 +386,34 @@ public void SingleChannel_ConstructorTest_SlackHttpClientObjCast()
slackHttpClientObj: "TestObject"
)
.CreateLogger();
- });
+ };
- Assert.DoesNotThrow(() =>
+ var actValidCast = () =>
{
+ var mockHttpClient = new Mock();
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
ValidWebHook,
slackChannel: null,
- slackHttpClientObj: new HttpClient()
+ slackHttpClientObj: mockHttpClient.Object
)
.CreateLogger();
- });
+ };
+
+ // Act & Assert
+ actInvalidCast.Should().Throw();
+ actValidCast.Should().NotThrow();
}
- [Test]
+ ///
+ /// Test to ensure that the constructor throws an InvalidCastException when the slackHttpClientObj is a string.
+ /// Also, it should not throw any exception when the slackHttpClientObj is of type HttpClient.
+ ///
+ [Fact]
public void MultiChannel_ConstructorTest_SlackHttpClientObjCast()
{
- Assert.Throws(() =>
+ // Arrange
+ var actInvalidCast = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -308,18 +422,23 @@ public void MultiChannel_ConstructorTest_SlackHttpClientObjCast()
slackHttpClientObj: "TestObject"
)
.CreateLogger();
- });
+ };
- Assert.DoesNotThrow(() =>
+ var actValidCast = () =>
{
+ var mockHttpClient = new Mock();
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
ValidWebHook,
slackChannels: null,
- slackHttpClientObj: new HttpClient()
+ slackHttpClientObj: mockHttpClient.Object
)
.CreateLogger();
- });
+ };
+
+ // Act & Assert
+ actInvalidCast.Should().Throw();
+ actValidCast.Should().NotThrow();
}
private static string? TestF1(LogEvent a, IFormatProvider b, object c)
@@ -337,14 +456,19 @@ public void MultiChannel_ConstructorTest_SlackHttpClientObjCast()
return null;
}
- [Test]
+ ///
+ /// Test to ensure that the constructor throws an InvalidCastException when the generateSlackFunctions is a Tuple of
+ /// strings.
+ /// Also, it should not throw any exception when the generateSlackFunctions is a Tuple of functions.
+ ///
+ [Fact]
public void SingleChannel_ConstructorTest_GenerateSlackFunctionsCast()
{
var f1 = TestF1;
var f2 = TestF2;
var f3 = TestF3;
- Assert.Throws(() =>
+ var actInvalidCast = () =>
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Slack(
@@ -353,9 +477,9 @@ public void SingleChannel_ConstructorTest_GenerateSlackFunctionsCast()
generateSlackFunctions: new Tuple