tests: add tests for library

This commit is contained in:
Stevan Freeborn
2025-05-29 22:41:53 -05:00
parent ce45893caa
commit 0d31f12012
11 changed files with 155 additions and 18 deletions
@@ -14,12 +14,7 @@ public static class HostExtensions
public static IHostApplicationBuilder AddTelemetry(this IHostApplicationBuilder builder, Func<IInstrumentation> instrumentationFunc) public static IHostApplicationBuilder AddTelemetry(this IHostApplicationBuilder builder, Func<IInstrumentation> instrumentationFunc)
{ {
ArgumentNullException.ThrowIfNull(builder); ArgumentNullException.ThrowIfNull(builder);
ArgumentNullException.ThrowIfNull(instrumentationFunc);
builder.Services.AddSingleton(instrumentationFunc);
var instrumentation = builder.Services
.BuildServiceProvider()
.GetRequiredService<IInstrumentation>();
var seq = new SeqOptions(); var seq = new SeqOptions();
builder.Configuration.GetSection(nameof(SeqOptions)).Bind(seq); builder.Configuration.GetSection(nameof(SeqOptions)).Bind(seq);
@@ -29,6 +24,12 @@ public static class HostExtensions
return builder; return builder;
} }
builder.Services.AddSingleton(instrumentationFunc());
var instrumentation = builder.Services
.BuildServiceProvider()
.GetRequiredService<IInstrumentation>();
builder.Services.AddOpenTelemetry() builder.Services.AddOpenTelemetry()
.ConfigureResource(resource => .ConfigureResource(resource =>
{ {
@@ -1,5 +1,7 @@
namespace StevesBot.Webhook.YouTube; namespace StevesBot.Webhook.YouTube;
internal interface ILastPostedStreamStore : IStore<string> internal interface ILastPostedStreamStore
{ {
void SetValue(string value);
bool HasValue(string value);
} }
@@ -1,7 +0,0 @@
namespace StevesBot.Webhook.YouTube;
internal interface IStore<T>
{
void SetValue(T value);
bool HasValue(T value);
}
@@ -25,7 +25,7 @@
<CollectCoverage>true</CollectCoverage> <CollectCoverage>true</CollectCoverage>
<CoverletOutput>./TestResults/Coverage/</CoverletOutput> <CoverletOutput>./TestResults/Coverage/</CoverletOutput>
<CoverletOutputFormat>cobertura</CoverletOutputFormat> <CoverletOutputFormat>cobertura</CoverletOutputFormat>
<Include>[StevesBot.Lib]*</Include> <Include>[StevesBot.Library]*</Include>
</PropertyGroup> </PropertyGroup>
<Target Name="GenerateHtmlCoverageReport" AfterTargets="GenerateCoverageResultAfterTest"> <Target Name="GenerateHtmlCoverageReport" AfterTargets="GenerateCoverageResultAfterTest">
@@ -1 +1,41 @@
namespace StevesBot.Library.Tests.Unit; namespace StevesBot.Library.Tests.Unit;
public class DiscordMessageTests
{
[Fact]
public void Constructor_WhenCalled_ItShouldReturnAnInstance()
{
var result = new DiscordMessage();
result.Id.Should().BeEmpty();
result.Type.Should().Be(0);
result.ChannelId.Should().BeEmpty();
result.GuildId.Should().BeEmpty();
result.Author.Should().BeEquivalentTo(new DiscordUser());
}
[Fact]
public void Constructor_WhenCalledWithParameters_ItShouldReturnAnInstance()
{
var id = "12345";
var type = 1;
var channelId = "67890";
var guildId = "54321";
var author = new DiscordUser { Id = "11111" };
var result = new DiscordMessage
{
Id = id,
Type = type,
ChannelId = channelId,
GuildId = guildId,
Author = author
};
result.Id.Should().Be(id);
result.Type.Should().Be(type);
result.ChannelId.Should().Be(channelId);
result.GuildId.Should().Be(guildId);
result.Author.Should().BeEquivalentTo(author);
}
}
@@ -1 +1,21 @@
namespace StevesBot.Library.Tests.Unit; namespace StevesBot.Library.Tests.Unit;
public class DiscordUserTests
{
[Fact]
public void Constructor_WhenCalled_ItShouldReturnAnInstance()
{
var result = new DiscordUser();
result.Id.Should().BeEmpty();
}
[Fact]
public void Constructor_WhenCalledWithId_ItShouldReturnAnInstanceWithId()
{
var id = "12345";
var result = new DiscordUser { Id = id };
result.Id.Should().Be(id);
}
}
@@ -0,0 +1,13 @@
namespace StevesBot.Library.Tests.Unit;
public class GatewayResponseTests
{
[Fact]
public void Constructor_WhenCalled_ItShouldReturnAnInstance()
{
var url = "https://example.com";
var result = new GatewayResponse(url);
result.Url.Should().Be(url);
}
}
@@ -2,5 +2,64 @@ namespace StevesBot.Library.Tests.Unit;
public class HostExtensionsTests public class HostExtensionsTests
{ {
[Fact]
public void AddTelemetry_WhenCalledAndSeqOptionsNotConfigured_ItShouldNotAddTelemetry()
{
var builder = WebApplication.CreateBuilder();
builder.AddTelemetry(static () => new StevesBotWebhookInstrumentation());
var app = builder.Build();
app.Services
.GetService<StevesBotWebhookInstrumentation>()
.Should()
.BeNull();
app.Services
.GetService<OpenTelemetryLoggerProvider>()
.Should()
.BeNull();
app.Services
.GetService<TracerProvider>()
.Should()
.BeNull();
}
[Fact]
public void AddTelemetry_WhenCalledAndSeqOptionsConfigured_ItShouldAddTelemetry()
{
var builder = WebApplication.CreateBuilder();
var json = $@"{{
""SeqOptions"": {{
""ServerUrl"": ""http://localhost:5341"",
""ApiKey"": ""my-api-key"",
""ApiKeyHeader"": ""X-Seq-ApiKey""
}}
}}";
builder.Configuration.AddJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(json)));
builder.AddTelemetry(static () => new StevesBotWebhookInstrumentation());
var app = builder.Build();
app.Services
.GetService<IInstrumentation>()
.Should()
.NotBeNull();
app.Services
.GetServices<ILoggerProvider>()
.Where(static p => p is OpenTelemetryLoggerProvider)
.Should()
.NotBeEmpty();
app.Services
.GetService<TracerProvider>()
.Should()
.NotBeNull();
}
} }
@@ -7,10 +7,12 @@ public class ServicesExtensionsTests
ApiUrl = "https://test.com", ApiUrl = "https://test.com",
AppToken = "test_token", AppToken = "test_token",
}; };
private readonly Mock<IInstrumentation> _instrumentationMock = new();
private readonly ServiceCollection _services = new(); private readonly ServiceCollection _services = new();
public ServicesExtensionsTests() public ServicesExtensionsTests()
{ {
_services.AddSingleton(_instrumentationMock.Object);
_services.AddSingleton(_discordClientOptions); _services.AddSingleton(_discordClientOptions);
} }
@@ -19,7 +19,7 @@ public sealed class StevesBotWebhookInstrumentationTests : IDisposable
[Fact] [Fact]
public void Constructor_WhenCalled_ItShouldReturnInstance() public void Constructor_WhenCalled_ItShouldReturnInstance()
{ {
using var result = new StevesBotWorkerInstrumentation(); using var result = new StevesBotWebhookInstrumentation();
using var expectedSource = new ActivitySource(_instrumentation.SourceName, _instrumentation.SourceVersion); using var expectedSource = new ActivitySource(_instrumentation.SourceName, _instrumentation.SourceVersion);
result.Source.Should().BeEquivalentTo(expectedSource); result.Source.Should().BeEquivalentTo(expectedSource);
@@ -1,16 +1,23 @@
global using System.Diagnostics; global using System.Diagnostics;
global using System.Net; global using System.Net;
global using System.Text;
global using System.Text.Json; global using System.Text.Json;
global using Microsoft.AspNetCore.Builder;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Logging;
global using Moq; global using Moq;
global using OpenTelemetry.Logs;
global using OpenTelemetry.Trace;
global using RichardSzalay.MockHttp; global using RichardSzalay.MockHttp;
global using StevesBot.Library.Discord; global using StevesBot.Library.Discord;
global using StevesBot.Library.Discord.Common; global using StevesBot.Library.Discord.Common;
global using StevesBot.Library.Discord.Rest; global using StevesBot.Library.Discord.Rest;
global using StevesBot.Library.Discord.Rest.Requests; global using StevesBot.Library.Discord.Rest.Requests;
global using StevesBot.Library.Discord.Rest.Responses;
global using StevesBot.Library.Telemetry; global using StevesBot.Library.Telemetry;