setup and mock fixes
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Platform.WebService.Tests;
|
||||
|
||||
public sealed class SeedEndpointsTests : IClassFixture<PlatformWebApplicationFactory>
|
||||
{
|
||||
private readonly PlatformWebApplicationFactory _factory;
|
||||
|
||||
public SeedEndpointsTests(PlatformWebApplicationFactory factory)
|
||||
{
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task SeedDemo_WhenDisabled_ReturnsServiceUnavailableProblem()
|
||||
{
|
||||
using var client = _factory.CreateClient();
|
||||
client.DefaultRequestHeaders.Add("X-StellaOps-Tenant", $"tenant-seed-disabled-{Guid.NewGuid():N}");
|
||||
client.DefaultRequestHeaders.Add("X-StellaOps-Actor", "seed-tester");
|
||||
|
||||
var response = await client.PostAsJsonAsync(
|
||||
"/api/v1/admin/seed-demo",
|
||||
new { dryRun = true },
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(HttpStatusCode.ServiceUnavailable, response.StatusCode);
|
||||
|
||||
var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>(
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.NotNull(problem);
|
||||
Assert.Equal("Demo seeding is disabled", problem!.Title);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task SeedDemo_WhenModuleFilterMixesAllAndSpecific_ReturnsBadRequestProblem()
|
||||
{
|
||||
using WebApplicationFactory<Program> enabledFactory = _factory.WithWebHostBuilder(builder =>
|
||||
{
|
||||
builder.ConfigureAppConfiguration((_, config) =>
|
||||
{
|
||||
config.AddInMemoryCollection(new Dictionary<string, string?>
|
||||
{
|
||||
["STELLAOPS_ENABLE_DEMO_SEED"] = "true",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
using var client = enabledFactory.CreateClient();
|
||||
client.DefaultRequestHeaders.Add("X-StellaOps-Tenant", $"tenant-seed-invalid-{Guid.NewGuid():N}");
|
||||
client.DefaultRequestHeaders.Add("X-StellaOps-Actor", "seed-tester");
|
||||
|
||||
var response = await client.PostAsJsonAsync(
|
||||
"/api/v1/admin/seed-demo",
|
||||
new
|
||||
{
|
||||
dryRun = true,
|
||||
modules = new[] { "all", "policy" },
|
||||
},
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
|
||||
var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>(
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.NotNull(problem);
|
||||
Assert.Equal("Invalid module filter", problem!.Title);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task SeedDemo_WhenConnectionMissing_ReturnsServiceUnavailableProblem()
|
||||
{
|
||||
using WebApplicationFactory<Program> enabledFactory = _factory.WithWebHostBuilder(builder =>
|
||||
{
|
||||
builder.ConfigureAppConfiguration((_, config) =>
|
||||
{
|
||||
config.AddInMemoryCollection(new Dictionary<string, string?>
|
||||
{
|
||||
["STELLAOPS_ENABLE_DEMO_SEED"] = "true",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
using var client = enabledFactory.CreateClient();
|
||||
client.DefaultRequestHeaders.Add("X-StellaOps-Tenant", $"tenant-seed-missing-conn-{Guid.NewGuid():N}");
|
||||
client.DefaultRequestHeaders.Add("X-StellaOps-Actor", "seed-tester");
|
||||
|
||||
var response = await client.PostAsJsonAsync(
|
||||
"/api/v1/admin/seed-demo",
|
||||
new { dryRun = true },
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(HttpStatusCode.ServiceUnavailable, response.StatusCode);
|
||||
|
||||
var problem = await response.Content.ReadFromJsonAsync<ProblemDetails>(
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.NotNull(problem);
|
||||
Assert.Equal("Database connection unavailable", problem!.Title);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task SeedDemo_WhenUnauthenticated_ReturnsUnauthorized()
|
||||
{
|
||||
using WebApplicationFactory<Program> unauthenticatedFactory = _factory.WithWebHostBuilder(builder =>
|
||||
{
|
||||
builder.ConfigureTestServices(services =>
|
||||
{
|
||||
services.AddAuthentication(RejectingAuthHandler.SchemeName)
|
||||
.AddScheme<AuthenticationSchemeOptions, RejectingAuthHandler>(
|
||||
RejectingAuthHandler.SchemeName, _ => { });
|
||||
|
||||
services.PostConfigureAll<AuthenticationOptions>(options =>
|
||||
{
|
||||
options.DefaultAuthenticateScheme = RejectingAuthHandler.SchemeName;
|
||||
options.DefaultChallengeScheme = RejectingAuthHandler.SchemeName;
|
||||
options.DefaultScheme = RejectingAuthHandler.SchemeName;
|
||||
});
|
||||
|
||||
services.RemoveAll<IAuthorizationHandler>();
|
||||
services.AddSingleton<IAuthorizationHandler, DenyAllAuthorizationHandler>();
|
||||
});
|
||||
});
|
||||
|
||||
using var client = unauthenticatedFactory.CreateClient();
|
||||
var response = await client.PostAsJsonAsync(
|
||||
"/api/v1/admin/seed-demo",
|
||||
new { dryRun = true },
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task SeedDemo_WhenAuthorizationFails_ReturnsForbidden()
|
||||
{
|
||||
using WebApplicationFactory<Program> forbiddenFactory = _factory.WithWebHostBuilder(builder =>
|
||||
{
|
||||
builder.ConfigureTestServices(services =>
|
||||
{
|
||||
services.RemoveAll<IAuthorizationHandler>();
|
||||
services.AddSingleton<IAuthorizationHandler, DenyAllAuthorizationHandler>();
|
||||
});
|
||||
});
|
||||
|
||||
using var client = forbiddenFactory.CreateClient();
|
||||
client.DefaultRequestHeaders.Add("X-StellaOps-Tenant", $"tenant-seed-forbidden-{Guid.NewGuid():N}");
|
||||
client.DefaultRequestHeaders.Add("X-StellaOps-Actor", "seed-tester");
|
||||
|
||||
var response = await client.PostAsJsonAsync(
|
||||
"/api/v1/admin/seed-demo",
|
||||
new { dryRun = true },
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
|
||||
}
|
||||
|
||||
private sealed class RejectingAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||
{
|
||||
public const string SchemeName = "SeedRejectingScheme";
|
||||
|
||||
public RejectingAuthHandler(
|
||||
IOptionsMonitor<AuthenticationSchemeOptions> options,
|
||||
ILoggerFactory logger,
|
||||
UrlEncoder encoder)
|
||||
: base(options, logger, encoder)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
return Task.FromResult(AuthenticateResult.NoResult());
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class DenyAllAuthorizationHandler : IAuthorizationHandler
|
||||
{
|
||||
public Task HandleAsync(AuthorizationHandlerContext context)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user