@@ -97,4 +97,82 @@ public void VersionString_ShouldNotBeEscapedInJson()
9797 Assert . IsFalse ( json . Contains ( "\\ u002B" ) ,
9898 "Plus sign should not be escaped as Unicode in JSON output" ) ;
9999 }
100+
101+ [ TestMethod ]
102+ public void AddPrivateLeaf_ShouldCreateLeafWithOnlyHash ( )
103+ {
104+ // Arrange
105+ var tree = new MerkleTree ( MerkleTreeVersionStrings . V2_0 ) ;
106+ var hash = Hex . Parse ( "0x1234567890abcdef" ) ;
107+
108+ // Act
109+ var leaf = tree . AddPrivateLeaf ( hash ) ;
110+ tree . RecomputeSha256Root ( ) ;
111+
112+ // Assert
113+ Assert . IsTrue ( leaf . IsPrivate , "Private leaf should be marked as private" ) ;
114+ Assert . AreEqual ( hash , leaf . Hash , "Hash should match the provided hash" ) ;
115+ Assert . IsTrue ( leaf . Data . IsEmpty ( ) , "Data should be empty" ) ;
116+ Assert . IsTrue ( leaf . Salt . IsEmpty ( ) , "Salt should be empty" ) ;
117+ Assert . AreEqual ( string . Empty , leaf . ContentType , "Content type should be empty" ) ;
118+
119+ // Verify the leaf is properly serialized
120+ string json = tree . ToJson ( MerkleTree . ComputeSha256Hash ) ;
121+
122+ Console . WriteLine ( json ) ;
123+
124+ var jsonDoc = JsonDocument . Parse ( json ) ;
125+ var leaves = jsonDoc . RootElement . GetProperty ( "leaves" ) . EnumerateArray ( ) . ToArray ( ) ;
126+
127+ Assert . AreEqual ( 1 , leaves . Length , "Should have one leaf" ) ;
128+ var leafJson = leaves [ 0 ] ;
129+
130+ Assert . IsTrue ( leafJson . TryGetProperty ( "hash" , out var hashProp ) , "Should have hash property" ) ;
131+ Assert . AreEqual ( hash . ToString ( ) , hashProp . GetString ( ) , "Hash should match" ) ;
132+ Assert . IsFalse ( leafJson . TryGetProperty ( "data" , out _ ) , "Should not have data property" ) ;
133+ Assert . IsFalse ( leafJson . TryGetProperty ( "salt" , out _ ) , "Should not have salt property" ) ;
134+ Assert . IsFalse ( leafJson . TryGetProperty ( "contentType" , out _ ) , "Should not have contentType property" ) ;
135+ }
136+
137+ [ TestMethod ]
138+ public void RoundTrip_WithPrivateLeaf_ShouldPreservePrivacy ( )
139+ {
140+ // Arrange - Create a tree with one private leaf
141+ var tree = new MerkleTree ( MerkleTreeVersionStrings . V2_0 ) ;
142+ var hash = Hex . Parse ( "0x1234567890abcdef" ) ;
143+ var leaf = tree . AddPrivateLeaf ( hash ) ;
144+ tree . RecomputeSha256Root ( ) ;
145+
146+ // Act - Roundtrip through JSON
147+ string json = tree . ToJson ( ) ;
148+ var parsedTree = MerkleTree . Parse ( json ) ;
149+
150+ // Assert
151+ Assert . AreEqual ( 1 , parsedTree . Leaves . Count , "Should have one leaf after roundtrip" ) ;
152+ var roundtrippedLeaf = parsedTree . Leaves [ 0 ] ;
153+
154+ // Verify the leaf is still private
155+ Assert . IsTrue ( roundtrippedLeaf . IsPrivate , "Leaf should still be private after roundtrip" ) ;
156+ Assert . AreEqual ( hash , roundtrippedLeaf . Hash , "Hash should be preserved" ) ;
157+ Assert . IsTrue ( roundtrippedLeaf . Data . IsEmpty ( ) , "Data should still be empty" ) ;
158+ Assert . IsTrue ( roundtrippedLeaf . Salt . IsEmpty ( ) , "Salt should still be empty" ) ;
159+ Assert . AreEqual ( string . Empty , roundtrippedLeaf . ContentType , "Content type should be empty." ) ;
160+
161+ // Verify the tree still validates
162+ Assert . IsTrue ( parsedTree . VerifySha256Root ( ) , "Tree should still verify after roundtrip" ) ;
163+
164+ // Verify the JSON still only contains the hash
165+ string roundtrippedJson = parsedTree . ToJson ( ) ;
166+ var jsonDoc = JsonDocument . Parse ( roundtrippedJson ) ;
167+ var leaves = jsonDoc . RootElement . GetProperty ( "leaves" ) . EnumerateArray ( ) . ToArray ( ) ;
168+
169+ Assert . AreEqual ( 1 , leaves . Length , "Should have one leaf in JSON" ) ;
170+ var leafJson = leaves [ 0 ] ;
171+
172+ Assert . IsTrue ( leafJson . TryGetProperty ( "hash" , out var hashProp ) , "Should have hash property" ) ;
173+ Assert . AreEqual ( hash . ToString ( ) , hashProp . GetString ( ) , "Hash should match" ) ;
174+ Assert . IsFalse ( leafJson . TryGetProperty ( "data" , out _ ) , "Should not have data property" ) ;
175+ Assert . IsFalse ( leafJson . TryGetProperty ( "salt" , out _ ) , "Should not have salt property" ) ;
176+ Assert . IsFalse ( leafJson . TryGetProperty ( "contentType" , out _ ) , "Should not have contentType property" ) ;
177+ }
100178}
0 commit comments