@@ -6,28 +6,38 @@ package hiero
66
77import (
88 "net"
9+ "net/url"
910 "testing"
1011
1112 "github.com/stretchr/testify/assert"
1213 "github.com/stretchr/testify/require"
1314)
1415
15- func TestUnitRegisteredNodeAddressBookQuerySetterChaining (t * testing.T ) {
16+ // ----- setters / getters -----
17+
18+ func TestUnitRegisteredNodeAddressBookQuerySettersChain (t * testing.T ) {
1619 t .Parallel ()
1720
1821 q := NewRegisteredNodeAddressBookQuery ()
1922 require .NotNil (t , q )
2023
21- result := q .SetRegisteredNodeId (42 )
22- assert .Same (t , q , result , "SetRegisteredNodeId should return the same query for chaining" )
24+ assert .Same (t , q , q .SetRegisteredNodeId (42 ))
2325 assert .Equal (t , uint64 (42 ), q .GetRegisteredNodeId ())
26+
27+ assert .Same (t , q , q .SetLimit (50 ))
28+ assert .Equal (t , int32 (50 ), q .GetLimit ())
29+
30+ assert .Same (t , q , q .SetMaxAttempts (3 ))
31+ assert .Equal (t , uint64 (3 ), q .GetMaxAttempts ())
2432}
2533
26- func TestUnitRegisteredNodeAddressBookQueryGetRegisteredNodeIdDefault (t * testing.T ) {
34+ func TestUnitRegisteredNodeAddressBookQueryDefaults (t * testing.T ) {
2735 t .Parallel ()
2836
2937 q := NewRegisteredNodeAddressBookQuery ()
30- assert .Equal (t , uint64 (0 ), q .GetRegisteredNodeId (), "unset ID should default to 0" )
38+ assert .Equal (t , uint64 (0 ), q .GetRegisteredNodeId ())
39+ assert .Equal (t , int32 (0 ), q .GetLimit ())
40+ assert .Equal (t , uint64 (0 ), q .GetMaxAttempts ())
3141}
3242
3343func TestUnitRegisteredNodeAddressBookQueryExecuteNilClient (t * testing.T ) {
@@ -38,6 +48,89 @@ func TestUnitRegisteredNodeAddressBookQueryExecuteNilClient(t *testing.T) {
3848 assert .Equal (t , RegisteredNodeAddressBook {}, book )
3949}
4050
51+ // ----- buildURL -----
52+
53+ func TestUnitRegisteredNodeAddressBookQueryBuildURL (t * testing.T ) {
54+ t .Parallel ()
55+
56+ id := uint64 (7 )
57+ tests := []struct {
58+ name string
59+ q * RegisteredNodeAddressBookQuery
60+ want string
61+ }{
62+ {
63+ name : "no params" ,
64+ q : & RegisteredNodeAddressBookQuery {},
65+ want : "https://example/api/v1/network/registered-nodes" ,
66+ },
67+ {
68+ name : "id only" ,
69+ q : & RegisteredNodeAddressBookQuery {registeredNodeId : & id },
70+ want : "https://example/api/v1/network/registered-nodes?registerednode.id=7" ,
71+ },
72+ {
73+ name : "limit only" ,
74+ q : & RegisteredNodeAddressBookQuery {limit : 25 },
75+ want : "https://example/api/v1/network/registered-nodes?limit=25" ,
76+ },
77+ {
78+ name : "id and limit" ,
79+ q : & RegisteredNodeAddressBookQuery {registeredNodeId : & id , limit : 25 },
80+ want : "https://example/api/v1/network/registered-nodes?limit=25®isterednode.id=7" ,
81+ },
82+ {
83+ name : "limit zero is omitted" ,
84+ q : & RegisteredNodeAddressBookQuery {registeredNodeId : & id , limit : 0 },
85+ want : "https://example/api/v1/network/registered-nodes?registerednode.id=7" ,
86+ },
87+ }
88+
89+ for _ , tt := range tests {
90+ t .Run (tt .name , func (t * testing.T ) {
91+ t .Parallel ()
92+ assert .Equal (t , tt .want , tt .q .buildURL ("https://example/api/v1" ))
93+ })
94+ }
95+ }
96+
97+ // ----- resolveNextURL -----
98+
99+ func TestUnitResolveNextURL (t * testing.T ) {
100+ t .Parallel ()
101+
102+ base , err := url .Parse ("https://mirror.example/api/v1" )
103+ require .NoError (t , err )
104+
105+ tests := []struct {
106+ name string
107+ next string
108+ want string
109+ }{
110+ {
111+ name : "absolute path replaces base path" ,
112+ next : "/api/v1/network/registered-nodes?limit=25®isterednode.id=gt:5" ,
113+ want : "https://mirror.example/api/v1/network/registered-nodes?limit=25®isterednode.id=gt:5" ,
114+ },
115+ {
116+ name : "absolute URL passes through" ,
117+ next : "https://other.example/api/v1/network/registered-nodes?limit=25" ,
118+ want : "https://other.example/api/v1/network/registered-nodes?limit=25" ,
119+ },
120+ }
121+
122+ for _ , tt := range tests {
123+ t .Run (tt .name , func (t * testing.T ) {
124+ t .Parallel ()
125+ got , err := resolveNextURL (base , tt .next )
126+ require .NoError (t , err )
127+ assert .Equal (t , tt .want , got )
128+ })
129+ }
130+ }
131+
132+ // ----- blockNodeApiFromString -----
133+
41134func TestUnitBlockNodeApiFromString (t * testing.T ) {
42135 t .Parallel ()
43136
@@ -52,14 +145,16 @@ func TestUnitBlockNodeApiFromString(t *testing.T) {
52145 {"OTHER" , BlockNodeApiOther },
53146 {"unrecognised" , BlockNodeApiOther },
54147 {"" , BlockNodeApiOther },
55- {"status" , BlockNodeApiStatus }, // lower-case should still match
148+ {"status" , BlockNodeApiStatus },
56149 }
57150
58151 for _ , tt := range tests {
59152 assert .Equal (t , tt .want , blockNodeApiFromString (tt .in ), "input %q" , tt .in )
60153 }
61154}
62155
156+ // ----- adminKeyFromJSON -----
157+
63158func TestUnitAdminKeyFromJSONEd25519 (t * testing.T ) {
64159 t .Parallel ()
65160
@@ -69,7 +164,6 @@ func TestUnitAdminKeyFromJSONEd25519(t *testing.T) {
69164
70165 key , err := adminKeyFromJSON (adminKeyJSON {Type : "ED25519" , Key : pub })
71166 require .NoError (t , err )
72- require .NotNil (t , key )
73167 assert .Equal (t , pub , key .(PublicKey ).String ())
74168}
75169
@@ -85,13 +179,27 @@ func TestUnitAdminKeyFromJSONEcdsa(t *testing.T) {
85179 require .NotNil (t , key )
86180}
87181
88- func TestUnitAdminKeyFromJSONInvalid (t * testing.T ) {
182+ func TestUnitAdminKeyFromJSONDefaultBranch (t * testing.T ) {
183+ t .Parallel ()
184+
185+ priv , err := PrivateKeyFromString (mockPrivateKey )
186+ require .NoError (t , err )
187+ pub := priv .PublicKey ().String ()
188+
189+ key , err := adminKeyFromJSON (adminKeyJSON {Type : "MYSTERY" , Key : pub })
190+ require .NoError (t , err )
191+ require .NotNil (t , key )
192+ }
193+
194+ func TestUnitAdminKeyFromJSONInvalidKey (t * testing.T ) {
89195 t .Parallel ()
90196
91197 _ , err := adminKeyFromJSON (adminKeyJSON {Type : "ED25519" , Key : "not-a-key" })
92198 assert .Error (t , err )
93199}
94200
201+ // ----- serviceEndpointFromJSON -----
202+
95203func TestUnitServiceEndpointFromJSONBlockNode (t * testing.T ) {
96204 t .Parallel ()
97205
@@ -105,15 +213,33 @@ func TestUnitServiceEndpointFromJSONBlockNode(t *testing.T) {
105213 })
106214 require .NoError (t , err )
107215
108- block , ok := ep .(* BlockNodeServiceEndpoint )
216+ bn , ok := ep .(* BlockNodeServiceEndpoint )
109217 require .True (t , ok , "expected *BlockNodeServiceEndpoint" )
110- assert .Equal (t , net .IPv4 ( 192 , 168 , 1 , 1 ).To4 (), net . IP ( block . GetIPAddress () ))
111- assert .Equal (t , uint32 (50211 ), block .GetPort ())
112- assert .True (t , block .GetRequiresTls ())
113- assert .Equal (t , []BlockNodeApi {BlockNodeApiPublish , BlockNodeApiStatus }, block .GetEndpointApis ())
218+ assert .Equal (t , [] byte ( net .ParseIP ( ip ).To4 ()), bn . GetIPAddress ())
219+ assert .Equal (t , uint32 (50211 ), bn .GetPort ())
220+ assert .True (t , bn .GetRequiresTls ())
221+ assert .Equal (t , []BlockNodeApi {BlockNodeApiPublish , BlockNodeApiStatus }, bn .GetEndpointApis ())
114222}
115223
116- func TestUnitServiceEndpointFromJSONMirrorNode (t * testing.T ) {
224+ func TestUnitServiceEndpointFromJSONMirrorNodeIPv4 (t * testing.T ) {
225+ t .Parallel ()
226+
227+ ip := "10.0.0.1"
228+ ep , err := serviceEndpointFromJSON (serviceEndpointJSON {
229+ Type : "MIRROR_NODE" ,
230+ IPAddress : & ip ,
231+ Port : 443 ,
232+ })
233+ require .NoError (t , err )
234+
235+ mn , ok := ep .(* MirrorNodeServiceEndpoint )
236+ require .True (t , ok )
237+ assert .Equal (t , []byte (net .ParseIP (ip ).To4 ()), mn .GetIPAddress ())
238+ assert .Equal (t , uint32 (443 ), mn .GetPort ())
239+ assert .Empty (t , mn .GetDomainName ())
240+ }
241+
242+ func TestUnitServiceEndpointFromJSONMirrorNodeDomain (t * testing.T ) {
117243 t .Parallel ()
118244
119245 domain := "mirror.example.com"
@@ -124,39 +250,61 @@ func TestUnitServiceEndpointFromJSONMirrorNode(t *testing.T) {
124250 })
125251 require .NoError (t , err )
126252
127- mirror , ok := ep .(* MirrorNodeServiceEndpoint )
128- require .True (t , ok , "expected *MirrorNodeServiceEndpoint" )
129- assert .Equal (t , "mirror.example.com" , mirror . GetDomainName ())
130- assert .Equal (t , uint32 ( 443 ), mirror . GetPort ())
253+ mn , ok := ep .(* MirrorNodeServiceEndpoint )
254+ require .True (t , ok )
255+ assert .Empty (t , mn . GetIPAddress ())
256+ assert .Equal (t , domain , mn . GetDomainName ())
131257}
132258
133259func TestUnitServiceEndpointFromJSONRpcRelay (t * testing.T ) {
134260 t .Parallel ()
135261
136- domain := "rpc .example.com"
262+ domain := "relay .example.com"
137263 ep , err := serviceEndpointFromJSON (serviceEndpointJSON {
138264 Type : "RPC_RELAY" ,
139265 DomainName : & domain ,
140- Port : 8545 ,
266+ Port : 7546 ,
141267 })
142268 require .NoError (t , err )
143269
144- rpc , ok := ep .(* RpcRelayServiceEndpoint )
145- require .True (t , ok , "expected *RpcRelayServiceEndpoint" )
146- assert .Equal (t , "rpc.example.com" , rpc .GetDomainName ())
147- assert .Equal (t , uint32 (8545 ), rpc .GetPort ())
270+ rr , ok := ep .(* RpcRelayServiceEndpoint )
271+ require .True (t , ok )
272+ assert .Equal (t , domain , rr .GetDomainName ())
273+ assert .Equal (t , uint32 (7546 ), rr .GetPort ())
148274}
149275
150- func TestUnitServiceEndpointFromJSONUnknownType (t * testing.T ) {
276+ func TestUnitServiceEndpointFromJSONGeneralService (t * testing.T ) {
151277 t .Parallel ()
152278
153- domain := "x.example.com"
154- _ , err := serviceEndpointFromJSON (serviceEndpointJSON {
155- Type : "SOMETHING_ELSE" ,
279+ domain := "general.example.com"
280+ ep , err := serviceEndpointFromJSON (serviceEndpointJSON {
281+ Type : "GENERAL_SERVICE" ,
282+ DomainName : & domain ,
283+ Port : 9000 ,
284+ GeneralService : & generalServiceJSON {Description : "custom-service" },
285+ })
286+ require .NoError (t , err )
287+
288+ gs , ok := ep .(* GeneralServiceEndpoint )
289+ require .True (t , ok )
290+ assert .Equal (t , domain , gs .GetDomainName ())
291+ assert .Equal (t , "custom-service" , gs .GetDescription ())
292+ }
293+
294+ func TestUnitServiceEndpointFromJSONGeneralServiceMissingNested (t * testing.T ) {
295+ t .Parallel ()
296+
297+ domain := "general.example.com"
298+ ep , err := serviceEndpointFromJSON (serviceEndpointJSON {
299+ Type : "GENERAL_SERVICE" ,
156300 DomainName : & domain ,
157- Port : 80 ,
301+ Port : 9000 ,
158302 })
159- assert .ErrorContains (t , err , "unknown endpoint type" )
303+ require .NoError (t , err )
304+
305+ gs , ok := ep .(* GeneralServiceEndpoint )
306+ require .True (t , ok )
307+ assert .Empty (t , gs .GetDescription ())
160308}
161309
162310func TestUnitServiceEndpointFromJSONIPv6 (t * testing.T ) {
@@ -170,79 +318,29 @@ func TestUnitServiceEndpointFromJSONIPv6(t *testing.T) {
170318 })
171319 require .NoError (t , err )
172320
173- mirror , ok := ep .( * MirrorNodeServiceEndpoint )
174- require .True (t , ok )
175- assert .Equal (t , net .ParseIP (ip ).To16 (), net . IP ( mirror . GetIPAddress ()) )
321+ got := ep .GetIPAddress ( )
322+ require .Len (t , got , 16 , "IPv6 should be 16 bytes" )
323+ assert .Equal (t , [] byte ( net .ParseIP (ip ).To16 ()), got )
176324}
177325
178326func TestUnitServiceEndpointFromJSONInvalidIP (t * testing.T ) {
179327 t .Parallel ()
180328
181- ip := "not-an-ip"
329+ bad := "not-an-ip"
182330 _ , err := serviceEndpointFromJSON (serviceEndpointJSON {
183331 Type : "MIRROR_NODE" ,
184- IPAddress : & ip ,
332+ IPAddress : & bad ,
185333 Port : 443 ,
186334 })
187- assert .ErrorContains (t , err , "invalid IP address" )
188- }
189-
190- func TestUnitRegisteredNodeFromJSON (t * testing.T ) {
191- t .Parallel ()
192-
193- priv , err := PrivateKeyFromString (mockPrivateKey )
194- require .NoError (t , err )
195- pub := priv .PublicKey ().String ()
196-
197- ip := "10.0.0.1"
198- domain := "rpc.example.com"
199- raw := registeredNodeJSON {
200- AdminKey : & adminKeyJSON {Type : "ED25519" , Key : pub },
201- CreatedTimestamp : "1700000000.000000000" ,
202- Description : "node description" ,
203- RegisteredNodeID : 7 ,
204- ServiceEndpoints : []serviceEndpointJSON {
205- {
206- Type : "BLOCK_NODE" ,
207- IPAddress : & ip ,
208- Port : 50211 ,
209- BlockNode : & blockNodeJSON {EndpointApis : []string {"PUBLISH" }},
210- },
211- {
212- Type : "RPC_RELAY" ,
213- DomainName : & domain ,
214- Port : 8545 ,
215- },
216- },
217- }
218-
219- node , err := registeredNodeFromJSON (raw )
220- require .NoError (t , err )
221-
222- assert .Equal (t , "node description" , node .Description )
223- assert .Equal (t , uint64 (7 ), node .RegisteredNodeID )
224- assert .Equal (t , "1700000000.000000000" , node .CreatedTimestamp )
225- require .NotNil (t , node .AdminKey )
226- assert .Equal (t , pub , node .AdminKey .(PublicKey ).String ())
227- require .Len (t , node .ServiceEndpoints , 2 )
228-
229- _ , isBlock := node .ServiceEndpoints [0 ].(* BlockNodeServiceEndpoint )
230- assert .True (t , isBlock )
231- _ , isRpc := node .ServiceEndpoints [1 ].(* RpcRelayServiceEndpoint )
232- assert .True (t , isRpc )
335+ assert .Error (t , err )
233336}
234337
235- func TestUnitRegisteredNodeFromJSONPropagatesEndpointError (t * testing.T ) {
338+ func TestUnitServiceEndpointFromJSONUnknownType (t * testing.T ) {
236339 t .Parallel ()
237340
238- ip := "bad-ip"
239- raw := registeredNodeJSON {
240- RegisteredNodeID : 1 ,
241- ServiceEndpoints : []serviceEndpointJSON {
242- {Type : "MIRROR_NODE" , IPAddress : & ip , Port : 443 },
243- },
244- }
245-
246- _ , err := registeredNodeFromJSON (raw )
247- assert .ErrorContains (t , err , "failed to parse service endpoint" )
341+ _ , err := serviceEndpointFromJSON (serviceEndpointJSON {
342+ Type : "MYSTERY" ,
343+ Port : 443 ,
344+ })
345+ assert .Error (t , err )
248346}
0 commit comments