test(core/browser/platform): 26 extreme RED/GREEN TDD cycles and full regression hardening (3,235 PASS)
Some checks failed
release / test (push) Failing after 14m5s
release / windows (push) Has been cancelled
release / android (push) Has been cancelled
release / linux (push) Has been cancelled
release / macos (push) Has been cancelled

This commit is contained in:
Yun Chan 2026-09-18 23:32:32 +09:00
parent bcd242691f
commit 8677853822
100 changed files with 4814 additions and 333 deletions

View file

@ -0,0 +1,252 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text.Json;
using Paca.Core.Net;
using Paca.Core.Security;
using Xunit;
namespace Paca.Tests.Core;
public class P2pAndE2eeVaultExtremeRedTests
{
// ==========================================
// 1. P2pSwarmEngine Extreme Scenarios
// ==========================================
[Theory]
[InlineData(0)]
[InlineData(-1024)]
public void P2pSwarmEngine_CreateManifestFromBytes_ZeroOrNegativePieceLength_ClampsToDefault512KB(int pieceLength)
{
byte[] dummyData = new byte[1024 * 1024]; // 1MB
var manifest = P2pSwarmEngine.CreateManifestFromBytes("test.mp4", dummyData, pieceLength);
Assert.NotNull(manifest);
Assert.True(manifest.PieceLength >= 16 * 1024, "PieceLength must be safely clamped to at least 16KB");
}
[Fact]
public void P2pSwarmEngine_CreateManifestFromBytes_NullData_ThrowsArgumentNullException()
{
Assert.Throws<ArgumentNullException>(() =>
P2pSwarmEngine.CreateManifestFromBytes("test.mp4", null!));
}
[Fact]
public void P2pSwarmEngine_InitializeSession_NullManifest_ThrowsArgumentNullException()
{
var engine = new P2pSwarmEngine();
Assert.Throws<ArgumentNullException>(() => engine.InitializeSession(null!));
}
[Fact]
public void P2pSwarmEngine_AddPeer_NullPeer_DoesNotThrow()
{
var engine = new P2pSwarmEngine();
var ex = Record.Exception(() => engine.AddPeer(null!));
Assert.Null(ex);
Assert.Equal(0, engine.ConnectedPeerCount);
}
[Fact]
public void P2pSwarmEngine_AddPeer_NullBitfield_InitializesSafeBitfield()
{
var engine = new P2pSwarmEngine();
var peer = new SwarmPeer { PeerId = "peer1", Bitfield = null! };
var ex = Record.Exception(() => engine.AddPeer(peer));
Assert.Null(ex);
Assert.NotNull(peer.Bitfield);
}
[Fact]
public void P2pSwarmEngine_IngestPieceData_NullData_ReturnsFalseWithoutThrowing()
{
var engine = new P2pSwarmEngine();
var manifest = P2pSwarmEngine.CreateManifestFromBytes("sample.mp4", new byte[100], 50);
engine.InitializeSession(manifest);
bool ingested = engine.IngestPieceData(0, null!);
Assert.False(ingested);
}
[Fact]
public void P2pSwarmEngine_IngestPieceData_LengthMismatch_ReturnsFalse()
{
var engine = new P2pSwarmEngine();
var data = new byte[100];
var manifest = P2pSwarmEngine.CreateManifestFromBytes("sample.mp4", data, 50);
engine.InitializeSession(manifest);
// Piece 0 expects 50 bytes, passing 10 bytes must fail even if empty
bool ingested = engine.IngestPieceData(0, new byte[10]);
Assert.False(ingested);
}
// ==========================================
// 2. CredentialDataExchange Extreme Scenarios
// ==========================================
[Fact]
public void CredentialDataExchange_ExportEncryptedVault_NullRecords_ThrowsArgumentNullException()
{
Assert.Throws<ArgumentNullException>(() =>
CredentialDataExchange.ExportEncryptedVault(null!, "MasterPass123!"));
}
[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData(" ")]
public void CredentialDataExchange_ExportEncryptedVault_NullOrWhitespacePassword_ThrowsArgumentException(string? badPass)
{
var records = new List<SiteCredentialRecord>
{
new() { Id = "1", Domain = "example.com", Username = "user", DecryptedPassword = "pw" }
};
Assert.Throws<ArgumentException>(() =>
CredentialDataExchange.ExportEncryptedVault(records, badPass!));
}
[Fact]
public void CredentialDataExchange_ImportEncryptedVault_DeclaredLengthExceedsAvailableData_ThrowsInvalidDataException()
{
// Valid header with huge declared ciphertext length
byte[] magic = System.Text.Encoding.ASCII.GetBytes("PACAVAULT_V1");
using var ms = new MemoryStream();
using var bw = new BinaryWriter(ms);
bw.Write(magic);
bw.Write(new byte[32]); // salt
bw.Write(new byte[12]); // nonce
bw.Write(new byte[16]); // tag
bw.Write(10_000_000); // claimed 10MB
bw.Write(new byte[10]); // but only 10 bytes present!
bw.Flush();
var malformedData = ms.ToArray();
Assert.Throws<InvalidDataException>(() =>
CredentialDataExchange.ImportEncryptedVault(malformedData, "MasterPass123!"));
}
[Fact]
public void CredentialDataExchange_ExportCsv_NullRecords_ReturnsHeaderOnly()
{
var csv = CredentialDataExchange.ExportCsv(null!);
Assert.NotNull(csv);
Assert.Contains("name,url,username,password", csv);
}
[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData(" ")]
public void CredentialDataExchange_ImportCsv_NullOrWhitespace_ReturnsEmptyList(string? badCsv)
{
var list = CredentialDataExchange.ImportCsv(badCsv!);
Assert.NotNull(list);
Assert.Empty(list);
}
[Fact]
public void CredentialDataExchange_ExportCsv_FormulaInjectionPrefixes_SanitizedSafely()
{
var maliciousRecord = new SiteCredentialRecord
{
Id = "evil",
SiteName = "=cmd|' /C calc'!A0",
Domain = "+1234567890",
Username = "@dangerousUser",
DecryptedPassword = "-unsafePassword",
Notes = "\tmaliciousTab"
};
var csv = CredentialDataExchange.ExportCsv(new[] { maliciousRecord });
Assert.NotNull(csv);
// Formula injection prefixes (=, +, -, @, tab) should be sanitized
var lines = csv.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
Assert.True(lines.Length >= 2);
string dataRow = lines[1];
Assert.DoesNotContain(",=cmd", dataRow);
Assert.DoesNotContain(",+123", dataRow);
Assert.DoesNotContain(",@dan", dataRow);
}
// ==========================================
// 3. CrdtVaultSyncEngine Extreme Scenarios
// ==========================================
[Fact]
public void CrdtVaultSyncEngine_Merge_NullRemote_ReturnsZeroWithoutThrowing()
{
var engine = new CrdtVaultSyncEngine<string>();
int applied = engine.Merge(null!);
Assert.Equal(0, applied);
}
[Fact]
public void CrdtVaultSyncEngine_Merge_NullOrEmptyIds_SkippedSafely()
{
var engine = new CrdtVaultSyncEngine<string>();
var items = new List<CrdtItemRecord<string>>
{
null!,
new() { Id = null!, Value = "A" },
new() { Id = "", Value = "B" },
new() { Id = "valid_1", Value = "C", LamportTimestamp = 1 }
};
int applied = engine.Merge(items);
Assert.Equal(1, applied);
Assert.Single(engine.GetActiveItems());
}
[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData(" ")]
public void CrdtVaultSyncEngine_Set_NullOrEmptyId_ThrowsArgumentException(string? invalidId)
{
var engine = new CrdtVaultSyncEngine<string>();
Assert.Throws<ArgumentException>(() => engine.Set(invalidId!, "value"));
}
// ==========================================
// 4. E2eeRemoteBackupProvider Extreme Scenarios
// ==========================================
[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData(" ")]
public void E2eeRemoteBackupProvider_EncryptPayload_NullOrEmptyPassword_ThrowsArgumentException(string? badPass)
{
Assert.Throws<ArgumentException>(() =>
E2eeRemoteBackupProvider.EncryptPayload("{}", badPass!));
}
[Fact]
public void E2eeRemoteBackupProvider_DecryptPayload_InvalidMagic_ThrowsInvalidDataException()
{
var bogusHeader = new VaultBackupHeader
{
Magic = "HACKERVAULT",
SaltBase64 = Convert.ToBase64String(new byte[16]),
NonceBase64 = Convert.ToBase64String(new byte[12]),
TagBase64 = Convert.ToBase64String(new byte[16]),
CiphertextBase64 = Convert.ToBase64String(new byte[32])
};
string json = JsonSerializer.Serialize(bogusHeader);
Assert.Throws<InvalidDataException>(() =>
E2eeRemoteBackupProvider.DecryptPayload(json, "MasterPassword123!"));
}
[Theory]
[InlineData("not-json")]
[InlineData("{\"Magic\":\"PACAVAULT\",\"SaltBase64\":\"%%%not-base64%%%\"}")]
public void E2eeRemoteBackupProvider_DecryptPayload_CorruptedBase64_ThrowsInvalidDataException(string corruptJson)
{
Assert.Throws<InvalidDataException>(() =>
E2eeRemoteBackupProvider.DecryptPayload(corruptJson, "MasterPassword123!"));
}
}