Initial curated itworx-knowledge-hub source from 3b1751d0d9dee551aa6994eee0093704dc334817
This commit is contained in:
commit
ad8ad252a9
825 files changed
+124216
No files matched your search
@@ -0,0 +1,145 @@
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using ItWorx.KnowledgeHub.Contracts.Admin;
|
||||
using ItWorx.KnowledgeHub.Contracts.Auth;
|
||||
using ItWorx.KnowledgeHub.Contracts.Runbooks;
|
||||
using ItWorx.KnowledgeHub.IntegrationTests.Infrastructure;
|
||||
|
||||
namespace ItWorx.KnowledgeHub.IntegrationTests.Projects;
|
||||
|
||||
[Collection(PostgresTestGroup.Name)]
|
||||
public sealed class RunbookTests(PostgresContainerFixture postgres) : OwnerSetupTestBase(postgres)
|
||||
{
|
||||
private async Task<HttpClient> AuthenticatedClientAsync()
|
||||
{
|
||||
var client = Factory.CreateClient();
|
||||
await SetupHelper.LoginAsync(client, OwnerEmail, OwnerPassword);
|
||||
return client;
|
||||
}
|
||||
|
||||
private static async Task<RunbookDetail> CreateRunbookAsync(HttpClient client, string title)
|
||||
{
|
||||
var response = await SetupHelper.PostWithCsrfAsync(
|
||||
client, "/api/v1/runbooks",
|
||||
new CreateRunbookRequest(null, title, "## Doel\n\nHerstel de dienst.", null, "High", true, 45));
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var runbook = await response.Content.ReadFromJsonAsync<RunbookDetail>();
|
||||
Assert.NotNull(runbook);
|
||||
return runbook;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Creating_a_runbook_creates_a_backing_Runbook_page_with_a_profile_and_is_stale_until_validated()
|
||||
{
|
||||
using var client = await AuthenticatedClientAsync();
|
||||
|
||||
var runbook = await CreateRunbookAsync(client, "Databaseherstel");
|
||||
|
||||
Assert.Equal("Draft", runbook.Status);
|
||||
Assert.Equal("High", runbook.RiskLevel);
|
||||
Assert.True(runbook.IsStale);
|
||||
Assert.Null(runbook.LastValidatedAt);
|
||||
|
||||
var pageResponse = await client.GetAsync($"/api/v1/pages/{runbook.PageId}");
|
||||
var page = await pageResponse.Content.ReadFromJsonAsync<ItWorx.KnowledgeHub.Contracts.Knowledge.PageDetail>();
|
||||
Assert.Equal("Runbook", page!.DocumentType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Validating_a_runbook_against_its_current_revision_clears_staleness()
|
||||
{
|
||||
using var client = await AuthenticatedClientAsync();
|
||||
var runbook = await CreateRunbookAsync(client, "Te valideren procedure");
|
||||
|
||||
var response = await SetupHelper.PostWithCsrfAndIfMatchAsync(
|
||||
client, $"/api/v1/runbooks/{runbook.Id}/validate", new { }, runbook.ETag);
|
||||
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var validated = await response.Content.ReadFromJsonAsync<RunbookDetail>();
|
||||
Assert.False(validated!.IsStale);
|
||||
Assert.NotNull(validated.LastValidatedAt);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Editing_the_underlying_page_after_validation_makes_the_runbook_stale_again()
|
||||
{
|
||||
using var client = await AuthenticatedClientAsync();
|
||||
var runbook = await CreateRunbookAsync(client, "Procedure die verandert");
|
||||
|
||||
var validateResponse = await SetupHelper.PostWithCsrfAndIfMatchAsync(
|
||||
client, $"/api/v1/runbooks/{runbook.Id}/validate", new { }, runbook.ETag);
|
||||
var validated = await validateResponse.Content.ReadFromJsonAsync<RunbookDetail>();
|
||||
Assert.False(validated!.IsStale);
|
||||
|
||||
var pageResponse = await client.GetFromJsonAsync<ItWorx.KnowledgeHub.Contracts.Knowledge.PageDetail>($"/api/v1/pages/{runbook.PageId}");
|
||||
await SetupHelper.PutWithCsrfAsync(
|
||||
client,
|
||||
$"/api/v1/pages/{runbook.PageId}",
|
||||
new ItWorx.KnowledgeHub.Contracts.Knowledge.UpdatePageRequest(
|
||||
pageResponse!.Title, "## Doel\n\nBijgewerkte procedure.", "Runbook", "Active", "Procedure bijgewerkt."),
|
||||
pageResponse.ETag);
|
||||
|
||||
var afterEdit = await client.GetFromJsonAsync<RunbookDetail>($"/api/v1/runbooks/{runbook.Id}");
|
||||
Assert.True(afterEdit!.IsStale);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Updating_the_runbook_profile_changes_risk_level_and_status()
|
||||
{
|
||||
using var client = await AuthenticatedClientAsync();
|
||||
var runbook = await CreateRunbookAsync(client, "Aan te passen profiel");
|
||||
|
||||
var response = await SetupHelper.PutWithCsrfAsync(
|
||||
client, $"/api/v1/runbooks/{runbook.Id}/profile",
|
||||
new UpdateRunbookProfileRequest(runbook.Owner, "Critical", "Active", true, 90, null),
|
||||
runbook.ETag);
|
||||
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var updated = await response.Content.ReadFromJsonAsync<RunbookDetail>();
|
||||
Assert.Equal("Critical", updated!.RiskLevel);
|
||||
Assert.Equal("Active", updated.Status);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Runbooks_appear_in_the_workspace_runbook_list()
|
||||
{
|
||||
using var client = await AuthenticatedClientAsync();
|
||||
var runbook = await CreateRunbookAsync(client, "Vindbare procedure");
|
||||
|
||||
var list = await client.GetFromJsonAsync<RunbookListResponse>("/api/v1/runbooks");
|
||||
|
||||
Assert.NotNull(list);
|
||||
Assert.Contains(list.Items, item => item.Id == runbook.Id && item.Title == "Vindbare procedure");
|
||||
}
|
||||
|
||||
// Reuses the exact reader-boundary pattern already established in
|
||||
// ProjectHubTests.A_reader_cannot_create_or_mutate_projects_but_can_read_them —
|
||||
// see DecisionTests' identical addition for the same V2-M5 rationale.
|
||||
[Fact]
|
||||
public async Task A_reader_can_read_runbooks_but_cannot_create_or_validate_them()
|
||||
{
|
||||
using var adminClient = await AuthenticatedClientAsync();
|
||||
var runbook = await CreateRunbookAsync(adminClient, "Alleen-lezenprocedure");
|
||||
|
||||
const string readerEmail = "runbooklezer@itworx.test";
|
||||
const string readerPassword = "reader-strong-password";
|
||||
var createUserResponse = await SetupHelper.PostWithCsrfAsync(
|
||||
adminClient, "/api/v1/admin/users", new CreateUserRequest("Testlezer", readerEmail, readerPassword, "Reader"));
|
||||
Assert.Equal(HttpStatusCode.OK, createUserResponse.StatusCode);
|
||||
|
||||
using var readerClient = Factory.CreateClient();
|
||||
await SetupHelper.LoginAsync(readerClient, readerEmail, readerPassword);
|
||||
|
||||
var readResponse = await readerClient.GetAsync($"/api/v1/runbooks/{runbook.Id}");
|
||||
Assert.Equal(HttpStatusCode.OK, readResponse.StatusCode);
|
||||
|
||||
var createResponse = await SetupHelper.PostWithCsrfAsync(
|
||||
readerClient, "/api/v1/runbooks",
|
||||
new CreateRunbookRequest(null, "Ongeautoriseerde procedure", "## Doel\n\nX.", null, "Low", false, null));
|
||||
Assert.Equal(HttpStatusCode.Forbidden, createResponse.StatusCode);
|
||||
|
||||
var validateResponse = await SetupHelper.PostWithCsrfAndIfMatchAsync(
|
||||
readerClient, $"/api/v1/runbooks/{runbook.Id}/validate", new { }, runbook.ETag);
|
||||
Assert.Equal(HttpStatusCode.Forbidden, validateResponse.StatusCode);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user