Files
itworx-knowledge-hub-Public/tests/backend/ItWorx.KnowledgeHub.IntegrationTests/Platform/PlatformSettingsApiTests.cs
T

108 lines
5.2 KiB
C#

using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
using ItWorx.KnowledgeHub.Contracts.Ingestion;
using ItWorx.KnowledgeHub.Contracts.Platform;
using ItWorx.KnowledgeHub.IntegrationTests.Infrastructure;
namespace ItWorx.KnowledgeHub.IntegrationTests.Platform;
[Collection(PostgresTestGroup.Name)]
public sealed class PlatformSettingsApiTests(PostgresContainerFixture postgres) : OwnerSetupTestBase(postgres)
{
private async Task<HttpClient> AuthenticatedClientAsync()
{
var client = Factory.CreateClient();
await SetupHelper.LoginAsync(client, OwnerEmail, OwnerPassword);
return client;
}
private static PlatformSettingsRequest Settings(
bool ingestionEnabled = false,
int maximumSourceCount = 20,
long maximumSourceBytes = 10_485_760) => new(
"ItWorx Knowledge Hub Test",
"nl-BE",
"Europe/Brussels",
new IngestionProposalPolicyContract(ingestionEnabled, maximumSourceCount, maximumSourceBytes, 2),
new BackupPolicyExpectationRequest(24, "Extern beheerd", 7, 4, 6, 1, 90),
new InventoryFreshnessPolicyContract(24));
[Fact]
public async Task Missing_settings_are_reported_as_environment_backed_defaults()
{
using var client = await AuthenticatedClientAsync();
using var response = await client.GetAsync("/api/v1/admin/platform-settings");
using var json = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("\"0\"", response.Headers.ETag?.Tag);
Assert.Equal("0", json.RootElement.GetProperty("eTag").GetString());
Assert.True(json.RootElement.GetProperty("isDefault").GetBoolean());
Assert.Equal("nl-BE", json.RootElement.GetProperty("primaryLocale").GetString());
Assert.Equal("operator-managed", json.RootElement.GetProperty("backupPolicyExpectation").GetProperty("enforcement").GetString());
}
[Fact]
public async Task Admin_replacement_persists_and_changes_the_effective_ingestion_policy()
{
using var client = await AuthenticatedClientAsync();
using var updated = await SetupHelper.PutWithCsrfAsync(
client, "/api/v1/admin/platform-settings", Settings(ingestionEnabled: true, maximumSourceCount: 5), "0");
using var updatedJson = JsonDocument.Parse(await updated.Content.ReadAsStringAsync());
using var session = await client.GetAsync("/api/v1/auth/session");
using var sessionJson = JsonDocument.Parse(await session.Content.ReadAsStringAsync());
using var intake = await client.GetAsync("/api/v1/ingestion-proposals");
var csrf = await SetupHelper.GetCsrfTokenAsync(client);
using var createRequest = new HttpRequestMessage(HttpMethod.Post, "/api/v1/ingestion-proposals")
{
Content = JsonContent.Create(new CreateIngestionProposalRequest("Platform policy test", "settings-policy"))
};
createRequest.Headers.Add(csrf.HeaderName, csrf.Value);
createRequest.Headers.Add("Idempotency-Key", "settings-policy-test");
using var created = await client.SendAsync(createRequest);
using var createdJson = JsonDocument.Parse(await created.Content.ReadAsStringAsync());
Assert.Equal(HttpStatusCode.OK, updated.StatusCode);
Assert.Equal("\"1\"", updated.Headers.ETag?.Tag);
Assert.Equal("operator-managed", updatedJson.RootElement.GetProperty("backupPolicyExpectation").GetProperty("enforcement").GetString());
Assert.True(sessionJson.RootElement.GetProperty("features").GetProperty("ingestionProposals").GetBoolean());
Assert.Equal(HttpStatusCode.OK, intake.StatusCode);
Assert.Equal(HttpStatusCode.Created, created.StatusCode);
Assert.Equal(2, createdJson.RootElement.GetProperty("maxPublishRetries").GetInt32());
}
[Fact]
public async Task Stale_settings_etags_and_values_over_the_intake_ceiling_are_rejected()
{
using var client = await AuthenticatedClientAsync();
using var invalid = await SetupHelper.PutWithCsrfAsync(
client, "/api/v1/admin/platform-settings", Settings(maximumSourceCount: 21), "0");
using var current = await SetupHelper.PutWithCsrfAsync(
client, "/api/v1/admin/platform-settings", Settings(), "0");
using var stale = await SetupHelper.PutWithCsrfAsync(
client, "/api/v1/admin/platform-settings", Settings(ingestionEnabled: true), "0");
Assert.Equal(HttpStatusCode.UnprocessableEntity, invalid.StatusCode);
Assert.Equal(HttpStatusCode.OK, current.StatusCode);
Assert.Equal(HttpStatusCode.PreconditionFailed, stale.StatusCode);
}
[Fact]
public async Task Settings_updates_require_csrf_even_with_a_valid_etag()
{
using var client = await AuthenticatedClientAsync();
using var request = new HttpRequestMessage(HttpMethod.Put, "/api/v1/admin/platform-settings")
{
Content = System.Net.Http.Json.JsonContent.Create(Settings())
};
request.Headers.Add("If-Match", "\"0\"");
using var response = await client.SendAsync(request);
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
}
}