an atproto pds written in F# (.NET 9) 馃
pds fsharp giraffe dotnet atproto
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 5259dc4041c642cb16f2aacdc2d9d072058a7c9e 138 lines 4.2 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 } 21 22 Assert.Equal("did:web:example.com", config.DidHost) 23 24[<Fact>] 25let ``CID TryParse roundtrip`` () = 26 let hash = Crypto.sha256Str "test-data" 27 let cid = Cid.FromHash hash 28 let cidStr = cid.ToString() 29 30 match Cid.TryParse cidStr with 31 | Some parsed -> Assert.Equal<byte[]>(cid.Bytes, parsed.Bytes) 32 | None -> Assert.Fail "TryParse should succeed for valid CID" 33 34[<Fact>] 35let ``CID TryParse returns None for invalid`` () = 36 Assert.True(Cid.TryParse("invalid").IsNone) 37 Assert.True(Cid.TryParse("").IsNone) 38 Assert.True(Cid.TryParse("btooshort").IsNone) 39 40[<Fact>] 41let ``Can instantiate DescribeServerResponse`` () = 42 let response = { 43 availableUserDomains = [ "example.com" ] 44 did = "did:web:example.com" 45 inviteCodeRequired = true 46 } 47 48 Assert.Equal("did:web:example.com", response.did) 49 Assert.Equal(1, response.availableUserDomains.Length) 50 51[<Fact>] 52let ``SHA-256 Hashing correct`` () = 53 let input = "hello world" 54 let hash = sha256Str input 55 let expected = "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9" 56 let actual = Hex.ToHexString(hash) 57 Assert.Equal(expected, actual) 58 59[<Fact>] 60let ``ECDSA P-256 Sign and Verify`` () = 61 let keyPair = generateKey P256 62 let data = Encoding.UTF8.GetBytes("test message") 63 let hash = sha256 data 64 65 let signature = sign keyPair hash 66 Assert.True(signature.Length = 64, "Signature should be 64 bytes (R|S)") 67 68 let valid = verify keyPair hash signature 69 Assert.True(valid, "Signature verification failed") 70 71[<Fact>] 72let ``ECDSA K-256 Sign and Verify`` () = 73 let keyPair = generateKey K256 74 let data = Encoding.UTF8.GetBytes("test k256") 75 let hash = sha256 data 76 77 let signature = sign keyPair hash 78 Assert.True(signature.Length = 64, "Signature should be 64 bytes") 79 80 let valid = verify keyPair hash signature 81 Assert.True(valid, "Signature verification failed") 82 83[<Fact>] 84let ``Low-S Enforcement Logic`` () = 85 let n = 86 BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16) // secp256k1 N 87 88 let halfN = n.ShiftRight(1) 89 let highS = halfN.Add(BigInteger.One) 90 91 let lowS = enforceLowS highS n 92 Assert.True(lowS.CompareTo halfN <= 0, "S value should be <= N/2") 93 Assert.Equal(n.Subtract highS, lowS) 94 95[<Fact>] 96let ``DidDocument JSON deserialization`` () = 97 let json = 98 """{ 99 "id": "did:web:example.com", 100 "verificationMethod": [{ 101 "id": "did:web:example.com#atproto", 102 "type": "Multikey", 103 "controller": "did:web:example.com", 104 "publicKeyMultibase": "zQ3sh..." 105 }] 106 }""" 107 108 let doc = 109 JsonSerializer.Deserialize<DidDocument>(json, JsonSerializerOptions(PropertyNameCaseInsensitive = true)) 110 111 Assert.Equal("did:web:example.com", doc.Id) 112 Assert.Single doc.VerificationMethod |> ignore 113 Assert.Equal("Multikey", doc.VerificationMethod.Head.Type) 114 115[<Fact>] 116let ``CID Generation from Hash`` () = 117 let hash = 118 Hex.Decode("b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9") 119 120 let cid = Cid.FromHash hash 121 Assert.Equal<byte>(0x01uy, cid.Bytes.[0]) 122 Assert.Equal<byte>(0x71uy, cid.Bytes.[1]) 123 Assert.Equal<byte>(0x12uy, cid.Bytes.[2]) 124 Assert.Equal<byte>(0x20uy, cid.Bytes.[3]) 125 126[<Fact>] 127let ``DAG-CBOR Canonical Sorting`` () = 128 let m = Map.ofList [ ("b", box 1); ("a", box 2) ] 129 let encoded = DagCbor.encode m 130 let hex = Hex.ToHexString encoded 131 Assert.Equal("a2616102616201", hex) 132 133[<Fact>] 134let ``DAG-CBOR Sorting Length vs Bytes`` () = 135 let m = Map.ofList [ ("aa", box 1); ("b", box 2) ] 136 let encoded = DagCbor.encode m 137 let hex = Hex.ToHexString encoded 138 Assert.Equal("a261620262616101", hex)