using System.Net.Http.Json; using ItWorx.KnowledgeHub.Contracts.Knowledge; using ItWorx.KnowledgeHub.IntegrationTests.Infrastructure; namespace ItWorx.KnowledgeHub.IntegrationTests.Knowledge; /// Backlinks ("what links here") update correctly after link, title, slug and /// tree changes (docs/27-acceptance-matrix.md, M3-A03). [Collection(PostgresTestGroup.Name)] public sealed class BacklinksTests(PostgresContainerFixture postgres) : OwnerSetupTestBase(postgres) { [Fact] public async Task A_page_appears_in_another_pages_backlinks_once_it_links_there_and_disappears_once_the_link_is_removed() { using var client = Factory.CreateClient(); await SetupHelper.LoginAsync(client, OwnerEmail, OwnerPassword); var targetResponse = await SetupHelper.PostWithCsrfAsync( client, "/api/v1/pages", new CreatePageRequest(null, "Doelpagina", "WikiPage", "De doelpagina.", null)); var target = await targetResponse.Content.ReadFromJsonAsync(); Assert.NotNull(target); var sourceResponse = await SetupHelper.PostWithCsrfAsync( client, "/api/v1/pages", new CreatePageRequest(null, "Bronpagina", "WikiPage", "Zie [[Doelpagina]].", null)); var source = await sourceResponse.Content.ReadFromJsonAsync(); Assert.NotNull(source); var backlinks = await client.GetFromJsonAsync($"/api/v1/pages/{target.Id}/backlinks"); Assert.NotNull(backlinks); Assert.Contains(backlinks.Items, entry => entry.Id == source.Id); // Renaming the target must not break the already-resolved backlink relationship. var renamedTargetResponse = await SetupHelper.PutWithCsrfAsync( client, $"/api/v1/pages/{target.Id}", new UpdatePageRequest("Doelpagina (hernoemd)", "De doelpagina.", "WikiPage", "Active", null), target.ETag); Assert.True(renamedTargetResponse.IsSuccessStatusCode); var backlinksAfterRename = await client.GetFromJsonAsync($"/api/v1/pages/{target.Id}/backlinks"); Assert.NotNull(backlinksAfterRename); Assert.Contains(backlinksAfterRename.Items, entry => entry.Id == source.Id); // Removing the link from the source page removes the backlink. var unlinkedSourceResponse = await SetupHelper.PutWithCsrfAsync( client, $"/api/v1/pages/{source.Id}", new UpdatePageRequest("Bronpagina", "Geen verwijzing meer.", "WikiPage", "Active", null), source.ETag); Assert.True(unlinkedSourceResponse.IsSuccessStatusCode); var backlinksAfterUnlink = await client.GetFromJsonAsync($"/api/v1/pages/{target.Id}/backlinks"); Assert.NotNull(backlinksAfterUnlink); Assert.DoesNotContain(backlinksAfterUnlink.Items, entry => entry.Id == source.Id); } [Fact] public async Task A_page_with_no_incoming_links_has_an_empty_backlinks_list() { using var client = Factory.CreateClient(); await SetupHelper.LoginAsync(client, OwnerEmail, OwnerPassword); var response = await SetupHelper.PostWithCsrfAsync( client, "/api/v1/pages", new CreatePageRequest(null, "Eenzame pagina", "WikiPage", "Niemand linkt hierheen.", null)); var page = await response.Content.ReadFromJsonAsync(); Assert.NotNull(page); var backlinks = await client.GetFromJsonAsync($"/api/v1/pages/{page.Id}/backlinks"); Assert.NotNull(backlinks); Assert.Empty(backlinks.Items); } }