104 lines
4.9 KiB
C#
104 lines
4.9 KiB
C#
using System.Net.Http.Json;
|
|
using ItWorx.KnowledgeHub.Contracts.Knowledge;
|
|
using ItWorx.KnowledgeHub.IntegrationTests.Infrastructure;
|
|
|
|
namespace ItWorx.KnowledgeHub.IntegrationTests.Knowledge;
|
|
|
|
/// <summary>Internal links resolve by stable page identity and survive title, slug and
|
|
/// tree changes (docs/27-acceptance-matrix.md, M2-A02).</summary>
|
|
[Collection(PostgresTestGroup.Name)]
|
|
public sealed class InternalLinkResolutionTests(PostgresContainerFixture postgres) : OwnerSetupTestBase(postgres)
|
|
{
|
|
[Fact]
|
|
public async Task A_resolved_internal_link_keeps_working_after_the_target_is_renamed_and_moved()
|
|
{
|
|
using var client = Factory.CreateClient();
|
|
await SetupHelper.LoginAsync(client, OwnerEmail, OwnerPassword);
|
|
|
|
var target = await CreatePageAsync(client, null, "PostgreSQL back-up herstellen");
|
|
var newParent = await CreatePageAsync(client, null, "Nieuwe categorie");
|
|
|
|
var sourceResponse = await SetupHelper.PostWithCsrfAsync(
|
|
client,
|
|
"/api/v1/pages",
|
|
new CreatePageRequest(
|
|
null,
|
|
"Runbook overzicht",
|
|
"WikiPage",
|
|
"Zie [[PostgreSQL back-up herstellen|het herstelrunbook]] voor details.",
|
|
null));
|
|
var source = await sourceResponse.Content.ReadFromJsonAsync<PageDetail>();
|
|
Assert.NotNull(source);
|
|
|
|
Assert.Contains($"href=\"/knowledge/{target.Id}/{target.Slug}\"", source.RenderedHtml, StringComparison.Ordinal);
|
|
Assert.Contains("het herstelrunbook", source.RenderedHtml, StringComparison.Ordinal);
|
|
|
|
// Rename AND move the target page.
|
|
var renamed = await SetupHelper.PutWithCsrfAsync(
|
|
client,
|
|
$"/api/v1/pages/{target.Id}",
|
|
new UpdatePageRequest("PostgreSQL herstelprocedure (bijgewerkt)", target.Markdown, "Runbook", "Active", null),
|
|
target.ETag);
|
|
renamed.EnsureSuccessStatusCode();
|
|
var renamedTarget = await renamed.Content.ReadFromJsonAsync<PageDetail>();
|
|
Assert.NotNull(renamedTarget);
|
|
|
|
var moveResponse = await SetupHelper.PostWithCsrfAndIfMatchAsync(
|
|
client, $"/api/v1/pages/{target.Id}/move", new MovePageRequest(newParent.Id, null), renamedTarget.ETag);
|
|
moveResponse.EnsureSuccessStatusCode();
|
|
|
|
// Re-fetch the SOURCE page: its stored link must still resolve to the same
|
|
// page ID even though the source page's own Markdown/authored link text was
|
|
// never touched, and the target's title/slug/parent all changed.
|
|
var sourceAfter = await client.GetFromJsonAsync<PageDetail>($"/api/v1/pages/{source.Id}");
|
|
Assert.NotNull(sourceAfter);
|
|
Assert.Contains($"/knowledge/{target.Id}/", sourceAfter.RenderedHtml, StringComparison.Ordinal);
|
|
Assert.DoesNotContain("[[PostgreSQL", sourceAfter.RenderedHtml, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task An_unresolved_internal_link_target_remains_visible_as_plain_bracket_text()
|
|
{
|
|
using var client = Factory.CreateClient();
|
|
await SetupHelper.LoginAsync(client, OwnerEmail, OwnerPassword);
|
|
|
|
var response = await SetupHelper.PostWithCsrfAsync(
|
|
client,
|
|
"/api/v1/pages",
|
|
new CreatePageRequest(null, "Verwijzing naar niets", "WikiPage", "Zie [[Pagina die niet bestaat]].", null));
|
|
var page = await response.Content.ReadFromJsonAsync<PageDetail>();
|
|
|
|
Assert.NotNull(page);
|
|
Assert.Contains("[[Pagina die niet bestaat]]", page.RenderedHtml, StringComparison.Ordinal);
|
|
Assert.DoesNotContain("<a ", page.RenderedHtml, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task An_ambiguous_internal_link_target_also_remains_unresolved_rather_than_guessing()
|
|
{
|
|
using var client = Factory.CreateClient();
|
|
await SetupHelper.LoginAsync(client, OwnerEmail, OwnerPassword);
|
|
|
|
await CreatePageAsync(client, null, "Overzicht");
|
|
await CreatePageAsync(client, null, "Overzicht");
|
|
|
|
var response = await SetupHelper.PostWithCsrfAsync(
|
|
client, "/api/v1/pages", new CreatePageRequest(null, "Verwijst dubbelzinnig", "WikiPage", "Zie [[Overzicht]].", null));
|
|
var page = await response.Content.ReadFromJsonAsync<PageDetail>();
|
|
|
|
Assert.NotNull(page);
|
|
Assert.Contains("[[Overzicht]]", page.RenderedHtml, StringComparison.Ordinal);
|
|
Assert.DoesNotContain("<a ", page.RenderedHtml, StringComparison.Ordinal);
|
|
}
|
|
|
|
private static async Task<PageDetail> CreatePageAsync(HttpClient client, Guid? parentId, string title)
|
|
{
|
|
var response = await SetupHelper.PostWithCsrfAsync(
|
|
client, "/api/v1/pages", new CreatePageRequest(parentId, title, "WikiPage", $"# {title}", null));
|
|
response.EnsureSuccessStatusCode();
|
|
var page = await response.Content.ReadFromJsonAsync<PageDetail>();
|
|
Assert.NotNull(page);
|
|
return page;
|
|
}
|
|
}
|