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,88 @@
|
||||
using System.Net.Http.Json;
|
||||
using ItWorx.KnowledgeHub.Application.Operations;
|
||||
using ItWorx.KnowledgeHub.Contracts.Knowledge;
|
||||
using ItWorx.KnowledgeHub.IntegrationTests.Infrastructure;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ItWorx.KnowledgeHub.IntegrationTests.Operations;
|
||||
|
||||
/// <summary>Proves M7-A03 ("A full backup captures database, attachments, manifest and
|
||||
/// integrity hashes") against a real running application and real PostgreSQL, not a
|
||||
/// mock.</summary>
|
||||
[Collection(PostgresTestGroup.Name)]
|
||||
public sealed class BackupServiceTests(PostgresContainerFixture postgres)
|
||||
: OwnerSetupTestBase(postgres, new Dictionary<string, string?> { ["KnowledgeHub:Backup:RetainedCount"] = "2" })
|
||||
{
|
||||
[Fact]
|
||||
public async Task A_backup_captures_every_table_and_verifies_its_own_hashes()
|
||||
{
|
||||
using var client = Factory.CreateClient();
|
||||
await SetupHelper.LoginAsync(client, OwnerEmail, OwnerPassword);
|
||||
await SetupHelper.PostWithCsrfAsync(
|
||||
client, "/api/v1/pages", new CreatePageRequest(null, "Back-uptestpagina", "WikiPage", "Inhoud.", null));
|
||||
|
||||
using var scope = Factory.Services.CreateScope();
|
||||
var backups = scope.ServiceProvider.GetRequiredService<IBackupService>();
|
||||
|
||||
var summary = await backups.CreateBackupAsync(CancellationToken.None);
|
||||
|
||||
Assert.True(summary.TableCount > 0);
|
||||
Assert.True(summary.TotalRowCount > 0);
|
||||
|
||||
var manifest = await backups.GetManifestAsync(summary.BackupId, CancellationToken.None);
|
||||
Assert.NotNull(manifest);
|
||||
var pagesTable = Assert.Single(manifest.Tables, table => table.TableName == "pages");
|
||||
Assert.True(pagesTable.RowCount >= 1);
|
||||
Assert.False(string.IsNullOrWhiteSpace(pagesTable.Sha256));
|
||||
// Never a migration-bookkeeping table — that is recreated by the target's own
|
||||
// startup migration, not restored as user data (ADR-016 decision 2).
|
||||
Assert.DoesNotContain(manifest.Tables, table => table.TableName == "__EFMigrationsHistory");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task A_backup_includes_uploaded_attachments_with_verified_hashes()
|
||||
{
|
||||
using var client = Factory.CreateClient();
|
||||
await SetupHelper.LoginAsync(client, OwnerEmail, OwnerPassword);
|
||||
var pageResponse = await SetupHelper.PostWithCsrfAsync(
|
||||
client, "/api/v1/pages", new CreatePageRequest(null, "Pagina met bijlage", "WikiPage", "Inhoud.", null));
|
||||
var page = await pageResponse.Content.ReadFromJsonAsync<PageDetail>();
|
||||
Assert.NotNull(page);
|
||||
|
||||
var uploadResponse = await SetupHelper.PostMultipartWithCsrfAsync(
|
||||
client,
|
||||
$"/api/v1/pages/{page.Id}/attachments",
|
||||
"Testbestand voor back-up."u8.ToArray(),
|
||||
"backup-test.txt",
|
||||
"text/plain");
|
||||
Assert.True(uploadResponse.IsSuccessStatusCode);
|
||||
|
||||
using var scope = Factory.Services.CreateScope();
|
||||
var backups = scope.ServiceProvider.GetRequiredService<IBackupService>();
|
||||
var summary = await backups.CreateBackupAsync(CancellationToken.None);
|
||||
|
||||
Assert.Equal(1, summary.AttachmentCount);
|
||||
var manifest = await backups.GetManifestAsync(summary.BackupId, CancellationToken.None);
|
||||
Assert.NotNull(manifest);
|
||||
Assert.Single(manifest.Attachments);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Listing_backups_returns_newest_first_and_retention_prunes_older_ones()
|
||||
{
|
||||
using var scope = Factory.Services.CreateScope();
|
||||
var backups = scope.ServiceProvider.GetRequiredService<IBackupService>();
|
||||
|
||||
var first = await backups.CreateBackupAsync(CancellationToken.None);
|
||||
var second = await backups.CreateBackupAsync(CancellationToken.None);
|
||||
var third = await backups.CreateBackupAsync(CancellationToken.None);
|
||||
|
||||
var list = await backups.ListBackupsAsync(CancellationToken.None);
|
||||
|
||||
// Configured KnowledgeHub:Backup:RetainedCount = 2 for this test class.
|
||||
Assert.Equal(2, list.Count);
|
||||
Assert.Equal(third.BackupId, list[0].BackupId);
|
||||
Assert.Equal(second.BackupId, list[1].BackupId);
|
||||
Assert.DoesNotContain(list, entry => entry.BackupId == first.BackupId);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user