an atproto pds written in F# (.NET 9) 馃
pds fsharp giraffe dotnet atproto
at main 4.3 kB view raw
1锘縨odule Tests 2 3open Xunit 4open PDSharp.Core.Models 5open PDSharp.Core.Config 6open PDSharp.Core.Crypto 7open PDSharp.Core 8open PDSharp.Core.DidResolver 9open Org.BouncyCastle.Utilities.Encoders 10open System.Text 11open System.Text.Json 12open Org.BouncyCastle.Math 13 14[<Fact>] 15let ``Can instantiate AppConfig`` () = 16 let config = { 17 PublicUrl = "https://example.com" 18 DidHost = "did:web:example.com" 19 JwtSecret = "test-secret-key-for-testing-only" 20 SqliteConnectionString = "Data Source=:memory:" 21 DisableWalAutoCheckpoint = false 22 BlobStore = Disk "blobs" 23 } 24 25 Assert.Equal("did:web:example.com", config.DidHost) 26 27[<Fact>] 28let ``CID TryParse roundtrip`` () = 29 let hash = Crypto.sha256Str "test-data" 30 let cid = Cid.FromHash hash 31 let cidStr = cid.ToString() 32 33 match Cid.TryParse cidStr with 34 | Some parsed -> Assert.Equal<byte[]>(cid.Bytes, parsed.Bytes) 35 | None -> Assert.Fail "TryParse should succeed for valid CID" 36 37[<Fact>] 38let ``CID TryParse returns None for invalid`` () = 39 Assert.True(Cid.TryParse("invalid").IsNone) 40 Assert.True(Cid.TryParse("").IsNone) 41 Assert.True(Cid.TryParse("btooshort").IsNone) 42 43[<Fact>] 44let ``Can instantiate DescribeServerResponse`` () = 45 let response = { 46 availableUserDomains = [ "example.com" ] 47 did = "did:web:example.com" 48 inviteCodeRequired = true 49 } 50 51 Assert.Equal("did:web:example.com", response.did) 52 Assert.Equal(1, response.availableUserDomains.Length) 53 54[<Fact>] 55let ``SHA-256 Hashing correct`` () = 56 let input = "hello world" 57 let hash = sha256Str input 58 let expected = "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9" 59 let actual = Hex.ToHexString(hash) 60 Assert.Equal(expected, actual) 61 62[<Fact>] 63let ``ECDSA P-256 Sign and Verify`` () = 64 let keyPair = generateKey P256 65 let data = Encoding.UTF8.GetBytes("test message") 66 let hash = sha256 data 67 let signature = sign keyPair hash 68 Assert.True(signature.Length = 64, "Signature should be 64 bytes (R|S)") 69 70 let valid = verify keyPair hash signature 71 Assert.True(valid, "Signature verification failed") 72 73[<Fact>] 74let ``ECDSA K-256 Sign and Verify`` () = 75 let keyPair = generateKey K256 76 let data = Encoding.UTF8.GetBytes("test k256") 77 let hash = sha256 data 78 let signature = sign keyPair hash 79 Assert.True(signature.Length = 64, "Signature should be 64 bytes") 80 81 let valid = verify keyPair hash signature 82 Assert.True(valid, "Signature verification failed") 83 84[<Fact>] 85let ``Low-S Enforcement Logic`` () = 86 let n = 87 BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16) // secp256k1 N 88 89 let halfN = n.ShiftRight(1) 90 let highS = halfN.Add(BigInteger.One) 91 92 let lowS = enforceLowS highS n 93 Assert.True(lowS.CompareTo halfN <= 0, "S value should be <= N/2") 94 Assert.Equal(n.Subtract highS, lowS) 95 96[<Fact>] 97let ``DidDocument JSON deserialization`` () = 98 let json = 99 """{ 100 "id": "did:web:example.com", 101 "verificationMethod": [{ 102 "id": "did:web:example.com#atproto", 103 "type": "Multikey", 104 "controller": "did:web:example.com", 105 "publicKeyMultibase": "zQ3sh..." 106 }] 107 }""" 108 109 let doc = 110 JsonSerializer.Deserialize<DidDocument>(json, JsonSerializerOptions(PropertyNameCaseInsensitive = true)) 111 112 Assert.Equal("did:web:example.com", doc.Id) 113 Assert.Single doc.VerificationMethod |> ignore 114 Assert.Equal("Multikey", doc.VerificationMethod.Head.Type) 115 116[<Fact>] 117let ``CID Generation from Hash`` () = 118 let hash = 119 Hex.Decode "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9" 120 121 let cid = Cid.FromHash hash 122 Assert.Equal<byte>(0x01uy, cid.Bytes.[0]) 123 Assert.Equal<byte>(0x71uy, cid.Bytes.[1]) 124 Assert.Equal<byte>(0x12uy, cid.Bytes.[2]) 125 Assert.Equal<byte>(0x20uy, cid.Bytes.[3]) 126 127[<Fact>] 128let ``DAG-CBOR Canonical Sorting`` () = 129 let m = Map.ofList [ "b", box 1; "a", box 2 ] 130 let encoded = DagCbor.encode m 131 let hex = Hex.ToHexString encoded 132 Assert.Equal("a2616102616201", hex) 133 134[<Fact>] 135let ``DAG-CBOR Sorting Length vs Bytes`` () = 136 let m = Map.ofList [ "aa", box 1; "b", box 2 ] 137 let encoded = DagCbor.encode m 138 let hex = Hex.ToHexString encoded 139 Assert.Equal("a261620262616101", hex)