Fix build and code structure improvements. New but essential UI functionality. CI improvements. Documentation improvements. AI module improvements.
This commit is contained in:
@@ -11,7 +11,6 @@ using StellaOps.EvidenceLocker.Core.Domain;
|
||||
using StellaOps.EvidenceLocker.Infrastructure.Db;
|
||||
using Xunit;
|
||||
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.EvidenceLocker.Tests;
|
||||
|
||||
@@ -44,7 +43,7 @@ public sealed class DatabaseMigrationTests : IAsyncLifetime
|
||||
Assert.Skip(_skipReason);
|
||||
}
|
||||
|
||||
var cancellationToken = TestContext.Current.CancellationToken;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
|
||||
await _migrationRunner!.ApplyAsync(cancellationToken);
|
||||
|
||||
@@ -101,7 +100,6 @@ public sealed class DatabaseMigrationTests : IAsyncLifetime
|
||||
Assert.Equal(0, otherVisible);
|
||||
|
||||
await using var violationConnection = await _dataSource.OpenConnectionAsync(tenant, cancellationToken);
|
||||
using StellaOps.TestKit;
|
||||
await using var violationCommand = new NpgsqlCommand(@"
|
||||
INSERT INTO evidence_locker.evidence_bundles
|
||||
(bundle_id, tenant_id, kind, status, root_hash, storage_key)
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using StellaOps.Cryptography;
|
||||
using StellaOps.EvidenceLocker.Core.Builders;
|
||||
using StellaOps.EvidenceLocker.Core.Domain;
|
||||
using StellaOps.EvidenceLocker.Core.Repositories;
|
||||
@@ -19,7 +20,7 @@ public sealed class EvidenceBundleBuilderTests
|
||||
|
||||
public EvidenceBundleBuilderTests()
|
||||
{
|
||||
_builder = new EvidenceBundleBuilder(_repository, new MerkleTreeCalculator());
|
||||
_builder = new EvidenceBundleBuilder(_repository, new MerkleTreeCalculator(new DefaultCryptoHasher(HashAlgorithms.Sha256)));
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
|
||||
@@ -64,7 +64,7 @@ public sealed class EvidenceBundleImmutabilityTests : IAsyncLifetime
|
||||
Assert.Skip(_skipReason);
|
||||
}
|
||||
|
||||
var cancellationToken = TestContext.Current.CancellationToken;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
var tenantId = TenantId.FromGuid(Guid.NewGuid());
|
||||
var bundleId = EvidenceBundleId.FromGuid(Guid.NewGuid());
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
@@ -107,7 +107,7 @@ public sealed class EvidenceBundleImmutabilityTests : IAsyncLifetime
|
||||
Assert.Skip(_skipReason);
|
||||
}
|
||||
|
||||
var cancellationToken = TestContext.Current.CancellationToken;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
var tenant1 = TenantId.FromGuid(Guid.NewGuid());
|
||||
var tenant2 = TenantId.FromGuid(Guid.NewGuid());
|
||||
var bundleId = EvidenceBundleId.FromGuid(Guid.NewGuid());
|
||||
@@ -153,7 +153,7 @@ public sealed class EvidenceBundleImmutabilityTests : IAsyncLifetime
|
||||
Assert.Skip(_skipReason);
|
||||
}
|
||||
|
||||
var cancellationToken = TestContext.Current.CancellationToken;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
var tenantId = TenantId.FromGuid(Guid.NewGuid());
|
||||
var bundleId = EvidenceBundleId.FromGuid(Guid.NewGuid());
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
@@ -193,7 +193,7 @@ public sealed class EvidenceBundleImmutabilityTests : IAsyncLifetime
|
||||
Assert.Skip(_skipReason);
|
||||
}
|
||||
|
||||
var cancellationToken = TestContext.Current.CancellationToken;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
var tenantId = TenantId.FromGuid(Guid.NewGuid());
|
||||
var bundleId = EvidenceBundleId.FromGuid(Guid.NewGuid());
|
||||
var nonExistentBundleId = EvidenceBundleId.FromGuid(Guid.NewGuid());
|
||||
@@ -235,7 +235,7 @@ public sealed class EvidenceBundleImmutabilityTests : IAsyncLifetime
|
||||
Assert.Skip(_skipReason);
|
||||
}
|
||||
|
||||
var cancellationToken = TestContext.Current.CancellationToken;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
var tenantId = TenantId.FromGuid(Guid.NewGuid());
|
||||
var bundleId = EvidenceBundleId.FromGuid(Guid.NewGuid());
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
@@ -311,7 +311,7 @@ public sealed class EvidenceBundleImmutabilityTests : IAsyncLifetime
|
||||
Assert.Skip(_skipReason);
|
||||
}
|
||||
|
||||
var cancellationToken = TestContext.Current.CancellationToken;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
var tenantId = TenantId.FromGuid(Guid.NewGuid());
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
|
||||
@@ -360,7 +360,7 @@ public sealed class EvidenceBundleImmutabilityTests : IAsyncLifetime
|
||||
Assert.Skip(_skipReason);
|
||||
}
|
||||
|
||||
var cancellationToken = TestContext.Current.CancellationToken;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
var tenantId = TenantId.FromGuid(Guid.NewGuid());
|
||||
var bundleId = EvidenceBundleId.FromGuid(Guid.NewGuid());
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
@@ -407,7 +407,7 @@ public sealed class EvidenceBundleImmutabilityTests : IAsyncLifetime
|
||||
Assert.Skip(_skipReason);
|
||||
}
|
||||
|
||||
var cancellationToken = TestContext.Current.CancellationToken;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
var tenantId = TenantId.FromGuid(Guid.NewGuid());
|
||||
var bundleId = EvidenceBundleId.FromGuid(Guid.NewGuid());
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
@@ -473,7 +473,7 @@ public sealed class EvidenceBundleImmutabilityTests : IAsyncLifetime
|
||||
Assert.Skip(_skipReason);
|
||||
}
|
||||
|
||||
var cancellationToken = TestContext.Current.CancellationToken;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
var tenantId = TenantId.FromGuid(Guid.NewGuid());
|
||||
var bundleId = EvidenceBundleId.FromGuid(Guid.NewGuid());
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
@@ -515,7 +515,7 @@ public sealed class EvidenceBundleImmutabilityTests : IAsyncLifetime
|
||||
Assert.Skip(_skipReason);
|
||||
}
|
||||
|
||||
var cancellationToken = TestContext.Current.CancellationToken;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
var tenantId = TenantId.FromGuid(Guid.NewGuid());
|
||||
var bundleId = EvidenceBundleId.FromGuid(Guid.NewGuid());
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
@@ -561,7 +561,7 @@ public sealed class EvidenceBundleImmutabilityTests : IAsyncLifetime
|
||||
Assert.Skip(_skipReason);
|
||||
}
|
||||
|
||||
var cancellationToken = TestContext.Current.CancellationToken;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
var tenantId = TenantId.FromGuid(Guid.NewGuid());
|
||||
var bundleId = EvidenceBundleId.FromGuid(Guid.NewGuid());
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
@@ -589,7 +589,8 @@ public sealed class EvidenceBundleImmutabilityTests : IAsyncLifetime
|
||||
CaseId: $"CASE-{i:D4}",
|
||||
Reason: $"Legal hold reason {i}",
|
||||
CreatedAt: now.AddMinutes(i),
|
||||
ExpiresAt: now.AddDays(30 + i));
|
||||
ExpiresAt: now.AddDays(30 + i),
|
||||
ReleasedAt: null);
|
||||
|
||||
var createdHold = await _repository.CreateHoldAsync(hold, cancellationToken);
|
||||
holds.Add(createdHold);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Buffers.Binary;
|
||||
using System.Buffers.Binary;
|
||||
using System.Formats.Tar;
|
||||
using System.IO.Compression;
|
||||
using System.Security.Cryptography;
|
||||
@@ -348,11 +348,12 @@ public sealed class EvidenceBundlePackagingServiceTests
|
||||
continue;
|
||||
}
|
||||
|
||||
var posixEntry = entry as PosixTarEntry;
|
||||
entries[entry.Name] = new TarEntryMetadata(
|
||||
entry.Uid,
|
||||
entry.Gid,
|
||||
entry.UserName ?? string.Empty,
|
||||
entry.GroupName ?? string.Empty,
|
||||
posixEntry?.UserName ?? string.Empty,
|
||||
posixEntry?.GroupName ?? string.Empty,
|
||||
entry.ModificationTime);
|
||||
}
|
||||
|
||||
@@ -443,7 +444,6 @@ public sealed class EvidenceBundlePackagingServiceTests
|
||||
{
|
||||
Stored = true;
|
||||
using var memory = new MemoryStream();
|
||||
using StellaOps.TestKit;
|
||||
content.CopyTo(memory);
|
||||
StoredBytes = memory.ToArray();
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
// EvidenceLockerIntegrationTests.cs
|
||||
// Sprint: SPRINT_5100_0010_0001_evidencelocker_tests
|
||||
// Task: EVIDENCE-5100-007
|
||||
// Description: Integration test: store artifact → retrieve artifact → verify hash matches
|
||||
// Description: Integration test: store artifact → retrieve artifact → verify hash matches
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.Net;
|
||||
@@ -20,7 +20,7 @@ namespace StellaOps.EvidenceLocker.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Integration Tests for EvidenceLocker
|
||||
/// Task EVIDENCE-5100-007: store artifact → retrieve artifact → verify hash matches
|
||||
/// Task EVIDENCE-5100-007: store artifact → retrieve artifact → verify hash matches
|
||||
/// </summary>
|
||||
public sealed class EvidenceLockerIntegrationTests : IDisposable
|
||||
{
|
||||
@@ -34,7 +34,7 @@ public sealed class EvidenceLockerIntegrationTests : IDisposable
|
||||
_client = _factory.CreateClient();
|
||||
}
|
||||
|
||||
#region EVIDENCE-5100-007: Store → Retrieve → Verify Hash
|
||||
#region EVIDENCE-5100-007: Store → Retrieve → Verify Hash
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
@@ -72,10 +72,10 @@ public sealed class EvidenceLockerIntegrationTests : IDisposable
|
||||
var storeResponse = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
payload,
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
storeResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var storeResult = await storeResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
|
||||
var storeResult = await storeResponse.Content.ReadFromJsonAsync<JsonElement>(CancellationToken.None);
|
||||
var bundleId = storeResult.GetProperty("bundleId").GetString();
|
||||
var storedRootHash = storeResult.GetProperty("rootHash").GetString();
|
||||
|
||||
@@ -85,10 +85,10 @@ public sealed class EvidenceLockerIntegrationTests : IDisposable
|
||||
// Act - Retrieve
|
||||
var retrieveResponse = await _client.GetAsync(
|
||||
$"/evidence/{bundleId}",
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
retrieveResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var retrieveResult = await retrieveResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
|
||||
var retrieveResult = await retrieveResponse.Content.ReadFromJsonAsync<JsonElement>(CancellationToken.None);
|
||||
var retrievedRootHash = retrieveResult.GetProperty("rootHash").GetString();
|
||||
var retrievedBundleId = retrieveResult.GetProperty("bundleId").GetString();
|
||||
|
||||
@@ -111,22 +111,22 @@ public sealed class EvidenceLockerIntegrationTests : IDisposable
|
||||
var storeResponse = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
payload,
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
storeResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var storeResult = await storeResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
|
||||
var storeResult = await storeResponse.Content.ReadFromJsonAsync<JsonElement>(CancellationToken.None);
|
||||
var bundleId = storeResult.GetProperty("bundleId").GetString();
|
||||
|
||||
// Act - Download
|
||||
var downloadResponse = await _client.GetAsync(
|
||||
$"/evidence/{bundleId}/download",
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
downloadResponse.EnsureSuccessStatusCode();
|
||||
|
||||
// Assert
|
||||
downloadResponse.Content.Headers.ContentType?.MediaType.Should().Be("application/gzip");
|
||||
|
||||
var archiveBytes = await downloadResponse.Content.ReadAsByteArrayAsync(TestContext.Current.CancellationToken);
|
||||
var archiveBytes = await downloadResponse.Content.ReadAsByteArrayAsync(CancellationToken.None);
|
||||
archiveBytes.Should().NotBeEmpty();
|
||||
|
||||
// Verify archive contains manifest with correct bundleId
|
||||
@@ -174,10 +174,10 @@ public sealed class EvidenceLockerIntegrationTests : IDisposable
|
||||
var response = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
payload,
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var result = await response.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
|
||||
var result = await response.Content.ReadFromJsonAsync<JsonElement>(CancellationToken.None);
|
||||
hashes.Add(result.GetProperty("rootHash").GetString()!);
|
||||
}
|
||||
|
||||
@@ -199,10 +199,10 @@ public sealed class EvidenceLockerIntegrationTests : IDisposable
|
||||
var storeResponse = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
payload,
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
storeResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var storeResult = await storeResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
|
||||
var storeResult = await storeResponse.Content.ReadFromJsonAsync<JsonElement>(CancellationToken.None);
|
||||
|
||||
// Assert - Signature should be present and valid
|
||||
storeResult.TryGetProperty("signature", out var signature).Should().BeTrue();
|
||||
@@ -249,19 +249,19 @@ public sealed class EvidenceLockerIntegrationTests : IDisposable
|
||||
var storeResponse = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
payload,
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
storeResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var storeResult = await storeResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
|
||||
var storeResult = await storeResponse.Content.ReadFromJsonAsync<JsonElement>(CancellationToken.None);
|
||||
var bundleId = storeResult.GetProperty("bundleId").GetString();
|
||||
|
||||
// Act - Retrieve
|
||||
var retrieveResponse = await _client.GetAsync(
|
||||
$"/evidence/{bundleId}",
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
retrieveResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var retrieveResult = await retrieveResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
|
||||
var retrieveResult = await retrieveResponse.Content.ReadFromJsonAsync<JsonElement>(CancellationToken.None);
|
||||
|
||||
// Assert - Metadata preserved
|
||||
retrieveResult.TryGetProperty("metadata", out var retrievedMetadata).Should().BeTrue();
|
||||
@@ -289,10 +289,10 @@ public sealed class EvidenceLockerIntegrationTests : IDisposable
|
||||
var storeResponse = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
payload,
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
storeResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var storeResult = await storeResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
|
||||
var storeResult = await storeResponse.Content.ReadFromJsonAsync<JsonElement>(CancellationToken.None);
|
||||
var bundleId = storeResult.GetProperty("bundleId").GetString();
|
||||
|
||||
// Assert - Timeline event emitted
|
||||
@@ -318,22 +318,22 @@ public sealed class EvidenceLockerIntegrationTests : IDisposable
|
||||
var storeResponse = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
payload,
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
storeResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var storeResult = await storeResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
|
||||
var storeResult = await storeResponse.Content.ReadFromJsonAsync<JsonElement>(CancellationToken.None);
|
||||
var bundleId = storeResult.GetProperty("bundleId").GetString();
|
||||
|
||||
// Act - Portable download
|
||||
var portableResponse = await _client.GetAsync(
|
||||
$"/evidence/{bundleId}/portable",
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
portableResponse.EnsureSuccessStatusCode();
|
||||
|
||||
// Assert
|
||||
portableResponse.Content.Headers.ContentType?.MediaType.Should().Be("application/gzip");
|
||||
|
||||
var archiveBytes = await portableResponse.Content.ReadAsByteArrayAsync(TestContext.Current.CancellationToken);
|
||||
var archiveBytes = await portableResponse.Content.ReadAsByteArrayAsync(CancellationToken.None);
|
||||
var entries = ReadGzipTarEntries(archiveBytes);
|
||||
|
||||
// Portable bundle should have manifest but be sanitized
|
||||
@@ -395,7 +395,6 @@ public sealed class EvidenceLockerIntegrationTests : IDisposable
|
||||
if (entry.DataStream is not null)
|
||||
{
|
||||
using var contentStream = new MemoryStream();
|
||||
using StellaOps.TestKit;
|
||||
entry.DataStream.CopyTo(contentStream);
|
||||
entries[entry.Name] = Encoding.UTF8.GetString(contentStream.ToArray());
|
||||
}
|
||||
|
||||
@@ -29,9 +29,11 @@ using StellaOps.EvidenceLocker.Core.Incident;
|
||||
using StellaOps.EvidenceLocker.Core.Timeline;
|
||||
using StellaOps.EvidenceLocker.Core.Storage;
|
||||
|
||||
using EvidenceLockerProgram = StellaOps.EvidenceLocker.WebService.Program;
|
||||
|
||||
namespace StellaOps.EvidenceLocker.Tests;
|
||||
|
||||
internal sealed class EvidenceLockerWebApplicationFactory : WebApplicationFactory<Program>
|
||||
internal sealed class EvidenceLockerWebApplicationFactory : WebApplicationFactory<EvidenceLockerProgram>
|
||||
{
|
||||
private readonly string _contentRoot;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
// EvidenceLockerWebServiceContractTests.cs
|
||||
// Sprint: SPRINT_5100_0010_0001_evidencelocker_tests
|
||||
// Tasks: EVIDENCE-5100-004, EVIDENCE-5100-005, EVIDENCE-5100-006
|
||||
@@ -53,12 +53,12 @@ public sealed class EvidenceLockerWebServiceContractTests : IDisposable
|
||||
var payload = CreateValidSnapshotPayload();
|
||||
|
||||
// Act
|
||||
var response = await _client.PostAsJsonAsync("/evidence/snapshot", payload, TestContext.Current.CancellationToken);
|
||||
var response = await _client.PostAsJsonAsync("/evidence/snapshot", payload, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
|
||||
var content = await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
|
||||
var content = await response.Content.ReadAsStringAsync(CancellationToken.None);
|
||||
using var doc = JsonDocument.Parse(content);
|
||||
var root = doc.RootElement;
|
||||
|
||||
@@ -85,21 +85,20 @@ public sealed class EvidenceLockerWebServiceContractTests : IDisposable
|
||||
var createResponse = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
CreateValidSnapshotPayload(),
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
createResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var created = await createResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
|
||||
var created = await createResponse.Content.ReadFromJsonAsync<JsonElement>(CancellationToken.None);
|
||||
var bundleId = created.GetProperty("bundleId").GetString();
|
||||
|
||||
// Act
|
||||
var response = await _client.GetAsync($"/evidence/{bundleId}", TestContext.Current.CancellationToken);
|
||||
var response = await _client.GetAsync($"/evidence/{bundleId}", CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
|
||||
var content = await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
|
||||
var content = await response.Content.ReadAsStringAsync(CancellationToken.None);
|
||||
using var doc = JsonDocument.Parse(content);
|
||||
using StellaOps.TestKit;
|
||||
var root = doc.RootElement;
|
||||
|
||||
// Verify contract schema for retrieved bundle
|
||||
@@ -121,14 +120,14 @@ using StellaOps.TestKit;
|
||||
var createResponse = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
CreateValidSnapshotPayload(),
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
createResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var created = await createResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
|
||||
var created = await createResponse.Content.ReadFromJsonAsync<JsonElement>(CancellationToken.None);
|
||||
var bundleId = created.GetProperty("bundleId").GetString();
|
||||
|
||||
// Act
|
||||
var response = await _client.GetAsync($"/evidence/{bundleId}/download", TestContext.Current.CancellationToken);
|
||||
var response = await _client.GetAsync($"/evidence/{bundleId}/download", CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
@@ -145,7 +144,7 @@ using StellaOps.TestKit;
|
||||
var response = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
CreateValidSnapshotPayload(),
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
|
||||
// Assert - Unauthorized should return consistent error schema
|
||||
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
|
||||
@@ -161,7 +160,7 @@ using StellaOps.TestKit;
|
||||
var nonExistentId = Guid.NewGuid();
|
||||
|
||||
// Act
|
||||
var response = await _client.GetAsync($"/evidence/{nonExistentId}", TestContext.Current.CancellationToken);
|
||||
var response = await _client.GetAsync($"/evidence/{nonExistentId}", CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
response.StatusCode.Should().Be(HttpStatusCode.NotFound);
|
||||
@@ -181,7 +180,7 @@ using StellaOps.TestKit;
|
||||
var response = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
CreateValidSnapshotPayload(),
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
|
||||
@@ -199,7 +198,7 @@ using StellaOps.TestKit;
|
||||
var response = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
CreateValidSnapshotPayload(),
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
response.StatusCode.Should().BeOneOf(HttpStatusCode.Forbidden, HttpStatusCode.Unauthorized);
|
||||
@@ -217,7 +216,7 @@ using StellaOps.TestKit;
|
||||
var response = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
CreateValidSnapshotPayload(),
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
@@ -234,17 +233,17 @@ using StellaOps.TestKit;
|
||||
var createResponse = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
CreateValidSnapshotPayload(),
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
createResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var created = await createResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
|
||||
var created = await createResponse.Content.ReadFromJsonAsync<JsonElement>(CancellationToken.None);
|
||||
var bundleId = created.GetProperty("bundleId").GetString();
|
||||
|
||||
// Change to no read scope
|
||||
ConfigureAuthHeaders(_client, tenantId, scopes: StellaOpsScopes.EvidenceCreate);
|
||||
|
||||
// Act
|
||||
var response = await _client.GetAsync($"/evidence/{bundleId}", TestContext.Current.CancellationToken);
|
||||
var response = await _client.GetAsync($"/evidence/{bundleId}", CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
response.StatusCode.Should().BeOneOf(HttpStatusCode.Forbidden, HttpStatusCode.Unauthorized);
|
||||
@@ -261,10 +260,10 @@ using StellaOps.TestKit;
|
||||
var createResponse = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
CreateValidSnapshotPayload(),
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
createResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var created = await createResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
|
||||
var created = await createResponse.Content.ReadFromJsonAsync<JsonElement>(CancellationToken.None);
|
||||
var bundleId = created.GetProperty("bundleId").GetString();
|
||||
|
||||
// Try to access as tenant B
|
||||
@@ -272,7 +271,7 @@ using StellaOps.TestKit;
|
||||
ConfigureAuthHeaders(_client, tenantB, scopes: $"{StellaOpsScopes.EvidenceRead}");
|
||||
|
||||
// Act
|
||||
var response = await _client.GetAsync($"/evidence/{bundleId}", TestContext.Current.CancellationToken);
|
||||
var response = await _client.GetAsync($"/evidence/{bundleId}", CancellationToken.None);
|
||||
|
||||
// Assert - Should not be accessible across tenants
|
||||
response.StatusCode.Should().BeOneOf(HttpStatusCode.NotFound, HttpStatusCode.Forbidden);
|
||||
@@ -289,17 +288,17 @@ using StellaOps.TestKit;
|
||||
var createResponse = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
CreateValidSnapshotPayload(),
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
createResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var created = await createResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
|
||||
var created = await createResponse.Content.ReadFromJsonAsync<JsonElement>(CancellationToken.None);
|
||||
var bundleId = created.GetProperty("bundleId").GetString();
|
||||
|
||||
// Remove read scope
|
||||
ConfigureAuthHeaders(_client, tenantId, scopes: StellaOpsScopes.EvidenceCreate);
|
||||
|
||||
// Act
|
||||
var response = await _client.GetAsync($"/evidence/{bundleId}/download", TestContext.Current.CancellationToken);
|
||||
var response = await _client.GetAsync($"/evidence/{bundleId}/download", CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
response.StatusCode.Should().BeOneOf(HttpStatusCode.Forbidden, HttpStatusCode.Unauthorized);
|
||||
@@ -340,10 +339,10 @@ using StellaOps.TestKit;
|
||||
var response = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
CreateValidSnapshotPayload(),
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var created = await response.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
|
||||
var created = await response.Content.ReadFromJsonAsync<JsonElement>(CancellationToken.None);
|
||||
var bundleId = created.GetProperty("bundleId").GetString();
|
||||
|
||||
// Assert
|
||||
@@ -369,7 +368,7 @@ using StellaOps.TestKit;
|
||||
var response = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
CreateValidSnapshotPayload(),
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
// Assert
|
||||
@@ -391,17 +390,17 @@ using StellaOps.TestKit;
|
||||
var createResponse = await _client.PostAsJsonAsync(
|
||||
"/evidence/snapshot",
|
||||
CreateValidSnapshotPayload(),
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
createResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var created = await createResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
|
||||
var created = await createResponse.Content.ReadFromJsonAsync<JsonElement>(CancellationToken.None);
|
||||
var bundleId = created.GetProperty("bundleId").GetString();
|
||||
|
||||
// Clear timeline events before retrieve
|
||||
_factory.TimelinePublisher.ClearEvents();
|
||||
|
||||
// Act
|
||||
var response = await _client.GetAsync($"/evidence/{bundleId}", TestContext.Current.CancellationToken);
|
||||
var response = await _client.GetAsync($"/evidence/{bundleId}", CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
@@ -417,12 +416,12 @@ using StellaOps.TestKit;
|
||||
ConfigureAuthHeaders(_client, tenantId, scopes: StellaOpsScopes.EvidenceRead);
|
||||
|
||||
// Act - Request non-existent bundle
|
||||
var response = await _client.GetAsync($"/evidence/{Guid.NewGuid()}", TestContext.Current.CancellationToken);
|
||||
var response = await _client.GetAsync($"/evidence/{Guid.NewGuid()}", CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
response.StatusCode.Should().Be(HttpStatusCode.NotFound);
|
||||
|
||||
var content = await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
|
||||
var content = await response.Content.ReadAsStringAsync(CancellationToken.None);
|
||||
content.Should().NotContain("Exception");
|
||||
content.Should().NotContain("StackTrace");
|
||||
content.Should().NotContain("InnerException");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Buffers.Binary;
|
||||
using System.Buffers.Binary;
|
||||
using System.Collections.Generic;
|
||||
using System.Formats.Tar;
|
||||
using System.IO;
|
||||
@@ -50,10 +50,10 @@ public sealed class EvidenceLockerWebServiceTests
|
||||
}
|
||||
};
|
||||
|
||||
var snapshotResponse = await client.PostAsJsonAsync("/evidence/snapshot", payload, TestContext.Current.CancellationToken);
|
||||
var snapshotResponse = await client.PostAsJsonAsync("/evidence/snapshot", payload, CancellationToken.None);
|
||||
snapshotResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var snapshot = await snapshotResponse.Content.ReadFromJsonAsync<EvidenceSnapshotResponseDto>(TestContext.Current.CancellationToken);
|
||||
var snapshot = await snapshotResponse.Content.ReadFromJsonAsync<EvidenceSnapshotResponseDto>(CancellationToken.None);
|
||||
Assert.NotNull(snapshot);
|
||||
Assert.NotEqual(Guid.Empty, snapshot!.BundleId);
|
||||
Assert.False(string.IsNullOrEmpty(snapshot.RootHash));
|
||||
@@ -65,7 +65,7 @@ public sealed class EvidenceLockerWebServiceTests
|
||||
Assert.Contains(snapshot.BundleId.ToString("D"), timelineEvent);
|
||||
Assert.Contains(snapshot.RootHash, timelineEvent);
|
||||
|
||||
var bundle = await client.GetFromJsonAsync<EvidenceBundleResponseDto>($"/evidence/{snapshot.BundleId}", TestContext.Current.CancellationToken);
|
||||
var bundle = await client.GetFromJsonAsync<EvidenceBundleResponseDto>($"/evidence/{snapshot.BundleId}", CancellationToken.None);
|
||||
Assert.NotNull(bundle);
|
||||
Assert.Equal(snapshot.RootHash, bundle!.RootHash);
|
||||
Assert.NotNull(bundle.Signature);
|
||||
@@ -105,13 +105,13 @@ public sealed class EvidenceLockerWebServiceTests
|
||||
}
|
||||
};
|
||||
|
||||
var snapshotResponse = await client.PostAsJsonAsync("/evidence/snapshot", payload, TestContext.Current.CancellationToken);
|
||||
var snapshotResponse = await client.PostAsJsonAsync("/evidence/snapshot", payload, CancellationToken.None);
|
||||
snapshotResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var snapshot = await snapshotResponse.Content.ReadFromJsonAsync<EvidenceSnapshotResponseDto>(TestContext.Current.CancellationToken);
|
||||
var snapshot = await snapshotResponse.Content.ReadFromJsonAsync<EvidenceSnapshotResponseDto>(CancellationToken.None);
|
||||
Assert.NotNull(snapshot);
|
||||
|
||||
var bundle = await client.GetFromJsonAsync<EvidenceBundleResponseDto>($"/evidence/{snapshot!.BundleId}", TestContext.Current.CancellationToken);
|
||||
var bundle = await client.GetFromJsonAsync<EvidenceBundleResponseDto>($"/evidence/{snapshot!.BundleId}", CancellationToken.None);
|
||||
Assert.NotNull(bundle);
|
||||
Assert.NotNull(bundle!.ExpiresAt);
|
||||
Assert.True(bundle.ExpiresAt > bundle.CreatedAt);
|
||||
@@ -141,17 +141,17 @@ public sealed class EvidenceLockerWebServiceTests
|
||||
}
|
||||
};
|
||||
|
||||
var snapshotResponse = await client.PostAsJsonAsync("/evidence/snapshot", payload, TestContext.Current.CancellationToken);
|
||||
var snapshotResponse = await client.PostAsJsonAsync("/evidence/snapshot", payload, CancellationToken.None);
|
||||
snapshotResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var snapshot = await snapshotResponse.Content.ReadFromJsonAsync<EvidenceSnapshotResponseDto>(TestContext.Current.CancellationToken);
|
||||
var snapshot = await snapshotResponse.Content.ReadFromJsonAsync<EvidenceSnapshotResponseDto>(CancellationToken.None);
|
||||
Assert.NotNull(snapshot);
|
||||
|
||||
var downloadResponse = await client.GetAsync($"/evidence/{snapshot!.BundleId}/download", TestContext.Current.CancellationToken);
|
||||
var downloadResponse = await client.GetAsync($"/evidence/{snapshot!.BundleId}/download", CancellationToken.None);
|
||||
downloadResponse.EnsureSuccessStatusCode();
|
||||
Assert.Equal("application/gzip", downloadResponse.Content.Headers.ContentType?.MediaType);
|
||||
|
||||
var archiveBytes = await downloadResponse.Content.ReadAsByteArrayAsync(TestContext.Current.CancellationToken);
|
||||
var archiveBytes = await downloadResponse.Content.ReadAsByteArrayAsync(CancellationToken.None);
|
||||
var mtime = BinaryPrimitives.ReadInt32LittleEndian(archiveBytes.AsSpan(4, 4));
|
||||
var expectedSeconds = (int)(new DateTimeOffset(2025, 1, 1, 0, 0, 0, TimeSpan.Zero) - DateTimeOffset.UnixEpoch).TotalSeconds;
|
||||
Assert.Equal(expectedSeconds, mtime);
|
||||
@@ -196,16 +196,16 @@ public sealed class EvidenceLockerWebServiceTests
|
||||
}
|
||||
};
|
||||
|
||||
var snapshotResponse = await client.PostAsJsonAsync("/evidence/snapshot", payload, TestContext.Current.CancellationToken);
|
||||
var snapshotResponse = await client.PostAsJsonAsync("/evidence/snapshot", payload, CancellationToken.None);
|
||||
snapshotResponse.EnsureSuccessStatusCode();
|
||||
var snapshot = await snapshotResponse.Content.ReadFromJsonAsync<EvidenceSnapshotResponseDto>(TestContext.Current.CancellationToken);
|
||||
var snapshot = await snapshotResponse.Content.ReadFromJsonAsync<EvidenceSnapshotResponseDto>(CancellationToken.None);
|
||||
Assert.NotNull(snapshot);
|
||||
|
||||
var portableResponse = await client.GetAsync($"/evidence/{snapshot!.BundleId}/portable", TestContext.Current.CancellationToken);
|
||||
var portableResponse = await client.GetAsync($"/evidence/{snapshot!.BundleId}/portable", CancellationToken.None);
|
||||
portableResponse.EnsureSuccessStatusCode();
|
||||
Assert.Equal("application/gzip", portableResponse.Content.Headers.ContentType?.MediaType);
|
||||
|
||||
var archiveBytes = await portableResponse.Content.ReadAsByteArrayAsync(TestContext.Current.CancellationToken);
|
||||
var archiveBytes = await portableResponse.Content.ReadAsByteArrayAsync(CancellationToken.None);
|
||||
var entries = ReadArchiveEntries(archiveBytes);
|
||||
Assert.Contains("bundle.json", entries.Keys);
|
||||
Assert.Contains("instructions-portable.txt", entries.Keys);
|
||||
@@ -243,11 +243,11 @@ public sealed class EvidenceLockerWebServiceTests
|
||||
}
|
||||
};
|
||||
|
||||
var response = await client.PostAsJsonAsync("/evidence/snapshot", payload, TestContext.Current.CancellationToken);
|
||||
var response = await client.PostAsJsonAsync("/evidence/snapshot", payload, CancellationToken.None);
|
||||
|
||||
var responseContent = await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
|
||||
var responseContent = await response.Content.ReadAsStringAsync(CancellationToken.None);
|
||||
Assert.True(response.StatusCode == HttpStatusCode.BadRequest, $"Expected 400 but received {(int)response.StatusCode}: {responseContent}");
|
||||
var problem = await response.Content.ReadFromJsonAsync<ValidationProblemDetails>(TestContext.Current.CancellationToken);
|
||||
var problem = await response.Content.ReadFromJsonAsync<ValidationProblemDetails>(CancellationToken.None);
|
||||
Assert.NotNull(problem);
|
||||
Assert.True(problem!.Errors.TryGetValue("message", out var messages));
|
||||
Assert.Contains(messages, m => m.Contains("exceeds", StringComparison.OrdinalIgnoreCase));
|
||||
@@ -272,9 +272,9 @@ public sealed class EvidenceLockerWebServiceTests
|
||||
}
|
||||
};
|
||||
|
||||
var response = await client.PostAsJsonAsync("/evidence/snapshot", payload, TestContext.Current.CancellationToken);
|
||||
var response = await client.PostAsJsonAsync("/evidence/snapshot", payload, CancellationToken.None);
|
||||
|
||||
var responseContent = await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
|
||||
var responseContent = await response.Content.ReadAsStringAsync(CancellationToken.None);
|
||||
Assert.True(response.StatusCode == HttpStatusCode.Forbidden, $"Expected 403 but received {(int)response.StatusCode}: {responseContent}");
|
||||
}
|
||||
|
||||
@@ -296,11 +296,11 @@ public sealed class EvidenceLockerWebServiceTests
|
||||
{
|
||||
reason = "legal-hold"
|
||||
},
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
|
||||
var responseContent = await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
|
||||
var responseContent = await response.Content.ReadAsStringAsync(CancellationToken.None);
|
||||
Assert.True(response.StatusCode == HttpStatusCode.BadRequest, $"Expected 400 but received {(int)response.StatusCode}: {responseContent}");
|
||||
var problem = await response.Content.ReadFromJsonAsync<ValidationProblemDetails>(TestContext.Current.CancellationToken);
|
||||
var problem = await response.Content.ReadFromJsonAsync<ValidationProblemDetails>(CancellationToken.None);
|
||||
Assert.NotNull(problem);
|
||||
Assert.True(problem!.Errors.TryGetValue("message", out var messages));
|
||||
Assert.Contains(messages, m => m.IndexOf("already exists", StringComparison.OrdinalIgnoreCase) >= 0);
|
||||
@@ -323,10 +323,10 @@ public sealed class EvidenceLockerWebServiceTests
|
||||
reason = "retention",
|
||||
notes = "retain for investigation"
|
||||
},
|
||||
TestContext.Current.CancellationToken);
|
||||
CancellationToken.None);
|
||||
|
||||
response.EnsureSuccessStatusCode();
|
||||
var hold = await response.Content.ReadFromJsonAsync<EvidenceHoldResponseDto>(TestContext.Current.CancellationToken);
|
||||
var hold = await response.Content.ReadFromJsonAsync<EvidenceHoldResponseDto>(CancellationToken.None);
|
||||
Assert.NotNull(hold);
|
||||
Assert.Contains($"hold:{hold!.CaseId}", factory.TimelinePublisher.PublishedEvents);
|
||||
}
|
||||
@@ -347,7 +347,6 @@ public sealed class EvidenceLockerWebServiceTests
|
||||
}
|
||||
|
||||
using var entryStream = new MemoryStream();
|
||||
using StellaOps.TestKit;
|
||||
entry.DataStream!.CopyTo(entryStream);
|
||||
var content = Encoding.UTF8.GetString(entryStream.ToArray());
|
||||
entries[entry.Name] = content;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Formats.Tar;
|
||||
using System.Formats.Tar;
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
@@ -248,11 +248,12 @@ public sealed class EvidencePortableBundleServiceTests
|
||||
continue;
|
||||
}
|
||||
|
||||
var posixEntry = entry as PosixTarEntry;
|
||||
entries[entry.Name] = new TarEntryMetadata(
|
||||
entry.Uid,
|
||||
entry.Gid,
|
||||
entry.UserName ?? string.Empty,
|
||||
entry.GroupName ?? string.Empty,
|
||||
posixEntry?.UserName ?? string.Empty,
|
||||
posixEntry?.GroupName ?? string.Empty,
|
||||
entry.ModificationTime);
|
||||
}
|
||||
|
||||
@@ -337,7 +338,6 @@ public sealed class EvidencePortableBundleServiceTests
|
||||
{
|
||||
Stored = true;
|
||||
using var memory = new MemoryStream();
|
||||
using StellaOps.TestKit;
|
||||
content.CopyTo(memory);
|
||||
StoredBytes = memory.ToArray();
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Security.Cryptography;
|
||||
@@ -200,7 +200,6 @@ public sealed class EvidenceSignatureServiceTests
|
||||
private static SigningKeyMaterialOptions CreateKeyMaterial()
|
||||
{
|
||||
using var ecdsa = ECDsa.Create(ECCurve.NamedCurves.nistP256);
|
||||
using StellaOps.TestKit;
|
||||
var privatePem = ecdsa.ExportECPrivateKeyPem();
|
||||
var publicPem = ecdsa.ExportSubjectPublicKeyInfoPem();
|
||||
return new SigningKeyMaterialOptions
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Reflection;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Cryptography;
|
||||
using System.Linq;
|
||||
@@ -477,7 +477,6 @@ public sealed class EvidenceSnapshotServiceTests
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
using var memory = new MemoryStream();
|
||||
using StellaOps.TestKit;
|
||||
content.CopyTo(memory);
|
||||
var bytes = memory.ToArray();
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Text;
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using StellaOps.EvidenceLocker.Core.Configuration;
|
||||
using StellaOps.EvidenceLocker.Core.Domain;
|
||||
@@ -22,7 +22,7 @@ public sealed class FileSystemEvidenceObjectStoreTests : IDisposable
|
||||
[Fact]
|
||||
public async Task StoreAsync_EnforcesWriteOnceWhenConfigured()
|
||||
{
|
||||
var cancellationToken = TestContext.Current.CancellationToken;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
var store = CreateStore(enforceWriteOnce: true);
|
||||
var options = CreateWriteOptions();
|
||||
|
||||
@@ -37,7 +37,7 @@ public sealed class FileSystemEvidenceObjectStoreTests : IDisposable
|
||||
[Fact]
|
||||
public async Task StoreAsync_AllowsOverwriteWhenWriteOnceDisabled()
|
||||
{
|
||||
var cancellationToken = TestContext.Current.CancellationToken;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
var store = CreateStore(enforceWriteOnce: false);
|
||||
var options = CreateWriteOptions() with { EnforceWriteOnce = false };
|
||||
|
||||
@@ -45,7 +45,6 @@ public sealed class FileSystemEvidenceObjectStoreTests : IDisposable
|
||||
var firstMetadata = await store.StoreAsync(first, options, cancellationToken);
|
||||
|
||||
using var second = CreateStream("payload-1");
|
||||
using StellaOps.TestKit;
|
||||
var secondMetadata = await store.StoreAsync(second, options, cancellationToken);
|
||||
|
||||
Assert.Equal(firstMetadata.Sha256, secondMetadata.Sha256);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
@@ -77,7 +77,6 @@ public sealed class GoldenFixturesTests
|
||||
private static JsonElement ReadJson(string path)
|
||||
{
|
||||
using var doc = JsonDocument.Parse(File.ReadAllText(path), new JsonDocumentOptions { AllowTrailingCommas = true });
|
||||
using StellaOps.TestKit;
|
||||
return doc.RootElement.Clone();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Amazon;
|
||||
@@ -116,7 +116,6 @@ public sealed class S3EvidenceObjectStoreTests
|
||||
var ifNoneMatch = request.Headers?["If-None-Match"];
|
||||
|
||||
using var memory = new MemoryStream();
|
||||
using StellaOps.TestKit;
|
||||
request.InputStream.CopyTo(memory);
|
||||
|
||||
PutRequests.Add(new CapturedPutObjectRequest(
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<UseXunitV3>true</UseXunitV3>
|
||||
<OutputType>Exe</OutputType>
|
||||
<IsPackable>false</IsPackable>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseConcelierTestInfra>false</UseConcelierTestInfra>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DotNet.Testcontainers" Version="1.6.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||
<PackageReference Include="Npgsql" Version="9.0.3" />
|
||||
<PackageReference Include="xunit.v3" Version="3.0.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.3" />
|
||||
<PackageReference Include="DotNet.Testcontainers" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
|
||||
<PackageReference Include="Npgsql" />
|
||||
<PackageReference Include="xunit.v3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -35,5 +33,6 @@
|
||||
<ProjectReference Include="..\StellaOps.EvidenceLocker.Infrastructure\StellaOps.EvidenceLocker.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\StellaOps.EvidenceLocker.WebService\StellaOps.EvidenceLocker.WebService.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.Cryptography/StellaOps.Cryptography.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
@@ -125,7 +125,6 @@ public sealed class TimelineIndexerEvidenceTimelinePublisherTests
|
||||
Assert.Equal(HttpMethod.Post, request.Method);
|
||||
|
||||
using var json = JsonDocument.Parse(request.Content!);
|
||||
using StellaOps.TestKit;
|
||||
var root = json.RootElement;
|
||||
Assert.Equal("evidence.hold.created", root.GetProperty("kind").GetString());
|
||||
Assert.Equal(hold.CaseId, root.GetProperty("attributes").GetProperty("caseId").GetString());
|
||||
|
||||
Reference in New Issue
Block a user