feat: 初始化NewLife Studio项目,完成基础框架与数据管理模块
何炳宏 authored at 2026-05-26 12:09:09
3.46 KiB
NewLife.Studio
using Xunit;

namespace NewLife.Studio.Store.Tests;

public class SecretProtectionTests
{
    [Fact]
    public void Protect_Then_Unprotect_RoundTrip()
    {
        var protection = new SecretProtection();
        const string original = "Server=localhost;Database=mydb;Uid=admin;Pwd=secret123;";

        var encrypted = protection.Protect(original);
        var decrypted = protection.Unprotect(encrypted);

        Assert.Equal(original, decrypted);
        Assert.NotEqual(original, encrypted);
    }

    [Fact]
    public void Unprotect_EmptyString_ReturnsEmpty()
    {
        var protection = new SecretProtection();

        var result = protection.Unprotect("");

        Assert.Equal("", result);
    }

    [Fact]
    public void Unprotect_NullString_ReturnsEmpty()
    {
        var protection = new SecretProtection();

        var result = protection.Unprotect(null!);

        Assert.Equal("", result);
    }

    [Fact]
    public void Protect_EmptyString_ReturnsEmpty()
    {
        var protection = new SecretProtection();

        var result = protection.Protect("");

        Assert.Equal("", result);
    }

    [Fact]
    public void Protect_NullString_ReturnsEmpty()
    {
        var protection = new SecretProtection();

        var result = protection.Protect(null!);

        Assert.Equal("", result);
    }

    [Fact]
    public void DifferentInputs_ProduceDifferentCiphertext()
    {
        var protection = new SecretProtection();
        const string input1 = "connection-string-one";
        const string input2 = "connection-string-two";

        var cipher1 = protection.Protect(input1);
        var cipher2 = protection.Protect(input2);

        Assert.NotEqual(cipher1, cipher2);
    }

    [Fact]
    public void SameInput_ProducesDeterministicCiphertext()
    {
        var protection = new SecretProtection();
        const string input = "deterministic-test-input";

        var cipher1 = protection.Protect(input);
        var cipher2 = protection.Protect(input);

        Assert.Equal(cipher1, cipher2);
    }

    [Fact]
    public void Unprotect_InvalidBase64_ReturnsOriginalInput()
    {
        var protection = new SecretProtection();
        const string invalid = "this-is-not-base64!!";

        var result = protection.Unprotect(invalid);

        Assert.Equal(invalid, result);
    }

    [Fact]
    public void Protect_Unprotect_WithSpecialCharacters()
    {
        var protection = new SecretProtection();
        const string original = "p@$$w0rd!测试中文\n\t\\特殊字符";

        var encrypted = protection.Protect(original);
        var decrypted = protection.Unprotect(encrypted);

        Assert.Equal(original, decrypted);
    }

    [Fact]
    public void Protect_Unprotect_WithVeryLongString()
    {
        var protection = new SecretProtection();
        var original = new string('x', 10000);

        var encrypted = protection.Protect(original);
        var decrypted = protection.Unprotect(encrypted);

        Assert.Equal(original, decrypted);
    }

    [Fact]
    public void Unprotect_TamperedCiphertext_ReturnsOriginalInput()
    {
        var protection = new SecretProtection();
        var encrypted = protection.Protect("secret-value");
        // Flip a character in the middle
        var chars = encrypted.ToCharArray();
        chars[chars.Length / 2] = chars[chars.Length / 2] == 'A' ? 'B' : 'A';
        var tampered = new string(chars);

        var result = protection.Unprotect(tampered);

        Assert.Equal(tampered, result);
    }
}