Skip to content

Commit

Permalink
Merge branch 'feat/webhook-reporter'
Browse files Browse the repository at this point in the history
  • Loading branch information
warriordog committed Aug 22, 2024
2 parents 6f2b518 + 9367196 commit c3102d7
Show file tree
Hide file tree
Showing 30 changed files with 929 additions and 166 deletions.
11 changes: 7 additions & 4 deletions ModShark.Tests/Reports/Document/DocumentBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public void ToString_ShouldRenderMarkdownDocument()
RenderDocument(builder);
var document = builder.ToString();

document.Should().Be("# Title1\n# Title2\n\nSection1\n\n## Header1\n## Header2\n**Bold1** **Bold2** *Italics1* *Italics2* `Code1` `Code2`\n[Link1](https://example.com) [Link2](https://example.com)\n* Item1\n* Item2\n\n");
document.Should().Be("# Title1\n# Title2\n\nSection1\n\n## Header1\n## Header2\n**Bold1** **Bold2** *Italics1* *Italics2* `Code1` `Code2`\n[Link1](https://example.com) [Link2](https://example.com)\n* Item1\n* Item2\n * Item3\n\n");
}

[Test]
Expand All @@ -24,7 +24,7 @@ public void ToString_ShouldRenderMFMDocument()
RenderDocument(builder);
var document = builder.ToString();

document.Should().Be("<b>Title1</b>\n<b>Title2</b>\n\nSection1\n\n<b>Header1</b>\n<b>Header2</b>\n<b>Bold1</b> <b>Bold2</b> <i>Italics1</i> <i>Italics2</i> `Code1` `Code2`\n[Link1](https://example.com) [Link2](https://example.com)\n- Item1\n- Item2\n\n");
document.Should().Be("<b>Title1</b>\n<b>Title2</b>\n\nSection1\n\n<b>Header1</b>\n<b>Header2</b>\n<b>Bold1</b> <b>Bold2</b> <i>Italics1</i> <i>Italics2</i> `Code1` `Code2`\n[Link1](https://example.com) [Link2](https://example.com)\n- Item1\n- Item2\n - Item3\n\n");
}

[Test]
Expand All @@ -35,7 +35,7 @@ public void ToString_ShouldRenderHTMLDocument()
RenderDocument(builder);
var document = builder.ToString();

document.Should().Be("<h1>Title1</h1><h1>Title2</h1><div>Section1</div><div><h2>Header1</h2><h2>Header2</h2><span style=\"font-weight: bold\">Bold1</span> <span style=\"font-weight: bold\">Bold2</span> <span style=\"font-style: italic\">Italics1</span> <span style=\"font-style: italic\">Italics2</span> <code>Code1</code> <code>Code2</code><br><a href=\"https://example.com\">Link1</a> <a href=\"https://example.com\">Link2</a><ul><li>Item1</li><li>Item2</li></ul></div>");
document.Should().Be("<h1>Title1</h1><h1>Title2</h1><div>Section1</div><div><h2>Header1</h2><h2>Header2</h2><span style=\"font-weight: bold\">Bold1</span> <span style=\"font-weight: bold\">Bold2</span> <span style=\"font-style: italic\">Italics1</span> <span style=\"font-style: italic\">Italics2</span> <code>Code1</code> <code>Code2</code><br><a href=\"https://example.com\">Link1</a> <a href=\"https://example.com\">Link2</a><ul><li>Item1</li><li>Item2</li><li><ul><li>Item3</li></ul></li></ul></div>");
}

[Test]
Expand All @@ -46,7 +46,7 @@ public void ToString_ShouldRenderHTML5Document()
RenderDocument(builder);
var document = builder.ToString();

document.Should().Be("<h1>Title1</h1><h1>Title2</h1><section>Section1</section><section><h2>Header1</h2><h2>Header2</h2><span style=\"font-weight: bold\">Bold1</span> <span style=\"font-weight: bold\">Bold2</span> <span style=\"font-style: italic\">Italics1</span> <span style=\"font-style: italic\">Italics2</span> <code>Code1</code> <code>Code2</code><br><a href=\"https://example.com\">Link1</a> <a href=\"https://example.com\">Link2</a><ul><li>Item1</li><li>Item2</li></ul></section>");
document.Should().Be("<h1>Title1</h1><h1>Title2</h1><section>Section1</section><section><h2>Header1</h2><h2>Header2</h2><span style=\"font-weight: bold\">Bold1</span> <span style=\"font-weight: bold\">Bold2</span> <span style=\"font-style: italic\">Italics1</span> <span style=\"font-style: italic\">Italics2</span> <code>Code1</code> <code>Code2</code><br><a href=\"https://example.com\">Link1</a> <a href=\"https://example.com\">Link2</a><ul><li>Item1</li><li>Item2</li><li><ul><li>Item3</li></ul></li></ul></section>");
}

[TestCase(0)]
Expand Down Expand Up @@ -132,6 +132,9 @@ private void RenderDocument(DocumentBuilder builder)
.BeginListItem()
.Append("Item2")
.End()
.BeginList()
.AppendListItem("Item3")
.End()
.End()
.End();
}
Expand Down
6 changes: 0 additions & 6 deletions ModShark.Tests/Reports/Render/RenderServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,6 @@ public void Setup()
};
}

[Test]
public void DefaultHints_ShouldNotLimitWidth()
{
ServiceUnderTest.DefaultHints.LimitWidth.Should().BeFalse();
}

[Test]
public void RenderReport_ShouldRenderTitle()
{
Expand Down
19 changes: 17 additions & 2 deletions ModShark.Tests/Reports/ReportServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class ReportServiceTests
private Mock<IConsoleReporter> MockConsoleReporter { get; set; } = null!;
private Mock<INativeReporter> MockNativeReporter { get; set; } = null!;
private Mock<IPostReporter> MockPostReporter { get; set; } = null!;
private Mock<IWebHookReporter> MockWebHookReporter { get; set; } = null!;

private Report FakeReport { get; set; } = null!;

Expand Down Expand Up @@ -42,8 +43,9 @@ public void Setup()
MockConsoleReporter = new Mock<IConsoleReporter>();
MockNativeReporter = new Mock<INativeReporter>();
MockPostReporter = new Mock<IPostReporter>();
MockWebHookReporter = new Mock<IWebHookReporter>();

ServiceUnderTest = new ReportService(MockLogger.Object, MockSendGridReporter.Object, MockConsoleReporter.Object, MockNativeReporter.Object, MockPostReporter.Object);
ServiceUnderTest = new ReportService(MockLogger.Object, MockSendGridReporter.Object, MockConsoleReporter.Object, MockNativeReporter.Object, MockPostReporter.Object, MockWebHookReporter.Object);
}

[Test]
Expand All @@ -55,6 +57,7 @@ public async Task MakeReports_ShouldSkip_WhenReportIsEmpty()
MockConsoleReporter.Verify(r => r.MakeReport(It.IsAny<Report>(), It.IsAny<CancellationToken>()), Times.Never);
MockNativeReporter.Verify(r => r.MakeReport(It.IsAny<Report>(), It.IsAny<CancellationToken>()), Times.Never);
MockPostReporter.Verify(r => r.MakeReport(It.IsAny<Report>(), It.IsAny<CancellationToken>()), Times.Never);
MockWebHookReporter.Verify(r => r.MakeReport(It.IsAny<Report>(), It.IsAny<CancellationToken>()), Times.Never);
}

[Test]
Expand Down Expand Up @@ -89,6 +92,14 @@ public async Task MakeReports_ShouldRunPostReporter()
MockPostReporter.Verify(r => r.MakeReport(FakeReport, default), Times.Once);
}

[Test]
public async Task MakeReports_ShouldRunWebHookReporter()
{
await ServiceUnderTest.MakeReports(FakeReport, default);

MockWebHookReporter.Verify(r => r.MakeReport(FakeReport, default), Times.Once);
}

[Test]
public async Task MakeReports_ShouldHandleExceptions()
{
Expand All @@ -104,13 +115,17 @@ public async Task MakeReports_ShouldHandleExceptions()
MockPostReporter
.Setup(r => r.MakeReport(FakeReport, default))
.Throws<ApplicationException>();
MockWebHookReporter
.Setup(r => r.MakeReport(FakeReport, default))
.Throws<ApplicationException>();

await ServiceUnderTest.MakeReports(FakeReport, default);

MockSendGridReporter.Verify(r => r.MakeReport(FakeReport, default), Times.Once);
MockConsoleReporter.Verify(r => r.MakeReport(FakeReport, default), Times.Once);
MockNativeReporter.Verify(r => r.MakeReport(FakeReport, default), Times.Once);
MockPostReporter.Verify(r => r.MakeReport(FakeReport, default), Times.Once);
MockLogger.Verify(l => l.Log(LogLevel.Error, It.IsAny<EventId>(), It.IsAny<It.IsAnyType>(), It.IsAny<ApplicationException>(), It.IsAny<Func<It.IsAnyType, Exception?, string>>()), Times.Exactly(4));
MockWebHookReporter.Verify(r => r.MakeReport(FakeReport, default), Times.Once);
MockLogger.Verify(l => l.Log(LogLevel.Error, It.IsAny<EventId>(), It.IsAny<It.IsAnyType>(), It.IsAny<ApplicationException>(), It.IsAny<Func<It.IsAnyType, Exception?, string>>()), Times.Exactly(5));
}
}
6 changes: 3 additions & 3 deletions ModShark.Tests/Reports/Reporter/SendGridReporterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
using Moq;
using SharkeyDB.Entities;

// This inspection gets confused by the moqs
// This inspection gets confused by the mocks
// ReSharper disable StructuredMessageTemplateProblem

namespace ModShark.Tests.Reports.Reporter;
Expand All @@ -34,8 +34,8 @@ public void Setup()
.ReturnsAsync(new HttpResponseMessage(HttpStatusCode.Accepted));
MockRenderService = new Mock<IRenderService>();
MockRenderService
.Setup(r => r.RenderReport(It.IsAny<Report>(), It.IsAny<DocumentFormat>(), It.IsAny<RenderHints?>()))
.Returns((Report _, DocumentFormat f, RenderHints? _) => new DocumentBuilder(f));
.Setup(r => r.RenderReport(It.IsAny<Report>(), It.IsAny<DocumentFormat>()))
.Returns((Report _, DocumentFormat f) => new DocumentBuilder(f));

FakeReporterConfig = new SendGridReporterConfig
{
Expand Down
129 changes: 129 additions & 0 deletions ModShark.Tests/Reports/Reporter/WebHookReporterTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
using Microsoft.Extensions.Logging;
using ModShark.Reports;
using ModShark.Reports.Reporter;
using ModShark.Reports.Reporter.WebHooks;
using ModShark.Tests._Utils;
using Moq;

namespace ModShark.Tests.Reports.Reporter;

public class WebHookReporterTests
{
private WebHookReporterConfig ReporterConfig { get; set; } = null!;
private WebHook Hook1 { get; set; } = null!;
private WebHook Hook2 { get; set; } = null!;

private Mock<ILogger<WebHookReporter>> MockLogger { get; set; } = null!;
private Mock<IDiscordPublisher> MockDiscordPublisher { get; set; } = null!;

private WebHookReporter ReporterUnderTest { get; set; } = null!;

[SetUp]
public void Setup()
{
Hook1 = new WebHook
{
MaxLength = 2000,
Type = WebHookType.Discord,
Url = "https://example.com/1"
};
Hook2 = new WebHook
{
MaxLength = 2000,
Type = WebHookType.Discord,
Url = "https://example.com/2"
};
ReporterConfig = new WebHookReporterConfig
{
Enabled = true,
Hooks =
[
Hook1,
Hook2
]
};
MockLogger = new Mock<ILogger<WebHookReporter>>();
MockDiscordPublisher = new Mock<IDiscordPublisher>();

ReporterUnderTest = new WebHookReporter(MockLogger.Object, ReporterConfig, MockDiscordPublisher.Object);
}

[Test]
public async Task MakeReport_ShouldSkip_WhenDisabled()
{
ReporterConfig.Enabled = false;

await ReporterUnderTest.MakeReport(new Report(), default);

MockLogger.VerifyLog(LogLevel.Debug, "Skipping WebHooks - disabled in config", Times.Once());
}

[Test]
public async Task MakeReport_ShouldSkip_WhenNoHooksDefined()
{
ReporterConfig.Hooks = [];

await ReporterUnderTest.MakeReport(new Report(), default);

MockLogger.VerifyLog(LogLevel.Warning, "Skipping WebHooks - No hooks defined", Times.Once());
}

[Test]
public async Task MakeReport_ShouldRunAllHooks()
{
var report = new Report();

await ReporterUnderTest.MakeReport(report, default);

MockDiscordPublisher.Verify(d => d.SendReport(Hook1, report, It.IsAny<CancellationToken>()), Times.Once);
MockDiscordPublisher.Verify(d => d.SendReport(Hook2, report, It.IsAny<CancellationToken>()), Times.Once);
}

[Test]
public async Task MakeReport_ShouldSkipHook_WhenUrlIsMissing()
{
Hook1.Url = "";

await ReporterUnderTest.MakeReport(new Report(), default);

MockDiscordPublisher.Verify(d => d.SendReport(Hook1, It.IsAny<Report>(), It.IsAny<CancellationToken>()), Times.Never);
MockDiscordPublisher.Verify(d => d.SendReport(Hook2, It.IsAny<Report>(), It.IsAny<CancellationToken>()), Times.Once);
}

[Test]
public async Task MakeReport_ShouldSkipHook_WhenTypeIsInvalid()
{
Hook1.Type = (WebHookType)999;

await ReporterUnderTest.MakeReport(new Report(), default);

MockDiscordPublisher.Verify(d => d.SendReport(Hook1, It.IsAny<Report>(), It.IsAny<CancellationToken>()), Times.Never);
MockDiscordPublisher.Verify(d => d.SendReport(Hook2, It.IsAny<Report>(), It.IsAny<CancellationToken>()), Times.Once);
}

[TestCase(99)]
[TestCase(0)]
[TestCase(-5)]
public async Task MakeReport_ShouldSkipHook_WhenMaxLengthIsTooLow(int maxLength)
{
Hook1.MaxLength = maxLength;

await ReporterUnderTest.MakeReport(new Report(), default);

MockDiscordPublisher.Verify(d => d.SendReport(Hook1, It.IsAny<Report>(), It.IsAny<CancellationToken>()), Times.Never);
MockDiscordPublisher.Verify(d => d.SendReport(Hook2, It.IsAny<Report>(), It.IsAny<CancellationToken>()), Times.Once);
}

[Test]
public async Task MakeReport_ShouldCatchHookExceptions()
{
MockDiscordPublisher
.Setup(d => d.SendReport(It.IsAny<WebHook>(), It.IsAny<Report>(), It.IsAny<CancellationToken>()))
.ThrowsAsync(new ApplicationException());

await ReporterUnderTest.MakeReport(new Report(), default);

MockDiscordPublisher.Verify(d => d.SendReport(Hook1, It.IsAny<Report>(), It.IsAny<CancellationToken>()), Times.Once);
MockDiscordPublisher.Verify(d => d.SendReport(Hook2, It.IsAny<Report>(), It.IsAny<CancellationToken>()), Times.Once);
}
}
Loading

0 comments on commit c3102d7

Please sign in to comment.