28
28
import org .junit .jupiter .api .BeforeAll ;
29
29
import org .junit .jupiter .api .BeforeEach ;
30
30
import org .junit .jupiter .api .Test ;
31
+ import org .mockito .ArgumentCaptor ;
31
32
32
33
import org .web3j .abi .TypeEncoder ;
33
34
import org .web3j .abi .datatypes .Utf8String ;
@@ -281,13 +282,60 @@ void buildRequestWhenNotValidSenderTest() {
281
282
}
282
283
283
284
@ Test
284
- void buildRequestWhenNotValidUrl () {
285
+ void buildRequestWithDataParameterOnly () throws Exception {
285
286
String url = "https://example.com/gateway/{data}.json" ;
286
287
sender = "0x226159d592E2b063810a10Ebf6dcbADA94Ed68b8" ;
287
288
data = "0xd5fa2b00" ;
288
289
289
- assertThrows (
290
- EnsResolutionException .class , () -> ensResolver .buildRequest (url , sender , data ));
290
+ okhttp3 .Request request = ensResolver .buildRequest (url , sender , data );
291
+
292
+ assertEquals ("https://example.com/gateway/0xd5fa2b00.json" , request .url ().toString ());
293
+ assertEquals ("GET" , request .method ());
294
+ assertNull (request .body ());
295
+ }
296
+
297
+ @ Test
298
+ void buildRequestWithSenderParameterOnly () throws Exception {
299
+ String url = "https://example.com/gateway/{sender}/lookup" ;
300
+ sender = "0x226159d592E2b063810a10Ebf6dcbADA94Ed68b8" ;
301
+ data = "0xd5fa2b00" ;
302
+
303
+ okhttp3 .Request request = ensResolver .buildRequest (url , sender , data );
304
+
305
+ assertEquals (
306
+ "https://example.com/gateway/0x226159d592E2b063810a10Ebf6dcbADA94Ed68b8/lookup" ,
307
+ request .url ().toString ());
308
+ assertEquals ("POST" , request .method ());
309
+ assertNotNull (request .body ());
310
+ assertEquals ("application/json" , request .header ("Content-Type" ));
311
+ }
312
+
313
+ @ Test
314
+ void verifyPostRequestBodyContainsSenderAndData () throws Exception {
315
+ String url = "https://example.com/gateway/lookup" ;
316
+ sender = "0x226159d592E2b063810a10Ebf6dcbADA94Ed68b8" ;
317
+ data = "0xd5fa2b00" ;
318
+
319
+ okhttp3 .Request request = ensResolver .buildRequest (url , sender , data );
320
+ assertNotNull (request .body ());
321
+ okhttp3 .MediaType contentType = request .body ().contentType ();
322
+ assertNotNull (contentType );
323
+ assertTrue (contentType .toString ().startsWith ("application/json" ));
324
+ }
325
+
326
+ @ Test
327
+ void buildRequestWithBothParameters () throws Exception {
328
+ String url = "https://example.com/gateway/{sender}/{data}" ;
329
+ sender = "0x226159d592E2b063810a10Ebf6dcbADA94Ed68b8" ;
330
+ data = "0xd5fa2b00" ;
331
+
332
+ okhttp3 .Request request = ensResolver .buildRequest (url , sender , data );
333
+
334
+ assertEquals (
335
+ "https://example.com/gateway/0x226159d592E2b063810a10Ebf6dcbADA94Ed68b8/0xd5fa2b00" ,
336
+ request .url ().toString ());
337
+ assertEquals ("GET" , request .method ());
338
+ assertNull (request .body ());
291
339
}
292
340
293
341
@ Test
@@ -420,9 +468,7 @@ void resolveOffchainSuccess() throws Exception {
420
468
when (httpClientMock .newCall (any ())).thenReturn (call );
421
469
when (call .execute ()).thenReturn (responseObj );
422
470
423
- RemoteFunctionCall respWithProof = mock (RemoteFunctionCall .class );
424
- when (resolver .resolveWithProof (any (), any ())).thenReturn (respWithProof );
425
- when (respWithProof .send ()).thenReturn (RESOLVED_NAME_HEX );
471
+ when (resolver .executeCallWithoutDecoding (any ())).thenReturn (RESOLVED_NAME_HEX );
426
472
427
473
String result = ensResolver .resolveOffchain (LOOKUP_HEX , resolver , 4 );
428
474
@@ -447,17 +493,87 @@ void resolveOffchainWhenLookUpCallsOutOfLimit() throws Exception {
447
493
buildResponse (200 , urls .get (0 ), sender , data ),
448
494
buildResponse (200 , urls .get (0 ), sender , data ));
449
495
450
- RemoteFunctionCall respWithProof = mock (RemoteFunctionCall .class );
451
- when (resolver .resolveWithProof (any (), any ()))
452
- .thenReturn (respWithProof , respWithProof , respWithProof );
453
496
String eip3668Data = EnsUtils .EIP_3668_CCIP_INTERFACE_ID + "data" ;
454
- when (respWithProof .send ()).thenReturn (eip3668Data , eip3668Data , eip3668Data );
497
+ when (resolver .executeCallWithoutDecoding (any ()))
498
+ .thenReturn (eip3668Data , eip3668Data , eip3668Data );
455
499
456
500
assertThrows (
457
501
EnsResolutionException .class ,
458
502
() -> ensResolver .resolveOffchain (LOOKUP_HEX , resolver , 2 ));
459
503
}
460
504
505
+ @ Test
506
+ void resolveOffchainWithDynamicCallback () throws Exception {
507
+ OffchainResolverContract resolver = mock (OffchainResolverContract .class );
508
+ when (resolver .getContractAddress ())
509
+ .thenReturn ("0xc1735677a60884abbcf72295e88d47764beda282" );
510
+
511
+ OkHttpClient httpClientMock = mock (OkHttpClient .class );
512
+ Call call = mock (Call .class );
513
+ okhttp3 .Response responseObj = buildResponse (200 , urls .get (0 ), sender , data );
514
+ ensResolver .setHttpClient (httpClientMock );
515
+ when (httpClientMock .newCall (any ())).thenReturn (call );
516
+ when (call .execute ()).thenReturn (responseObj );
517
+
518
+ // Create a custom LOOKUP_HEX with a different callback function
519
+ String customCallbackSelector = "aabbccdd" ;
520
+ String customLookupHex =
521
+ LOOKUP_HEX .substring (0 , 202 ) + customCallbackSelector + LOOKUP_HEX .substring (210 );
522
+
523
+ // Capture the function call to verify the correct callback selector is used
524
+ ArgumentCaptor <String > functionCallCaptor = ArgumentCaptor .forClass (String .class );
525
+ when (resolver .executeCallWithoutDecoding (functionCallCaptor .capture ()))
526
+ .thenReturn (RESOLVED_NAME_HEX );
527
+
528
+ String result = ensResolver .resolveOffchain (customLookupHex , resolver , 4 );
529
+ assertEquals ("0x41563129cdbbd0c5d3e1c86cf9563926b243834d" , result );
530
+
531
+ // Verify that the captured function call starts with our custom callback selector
532
+ String capturedFunctionCall = functionCallCaptor .getValue ();
533
+ assertTrue (
534
+ capturedFunctionCall .startsWith ("0x" + customCallbackSelector ),
535
+ "Function call should start with the custom callback selector" );
536
+ }
537
+
538
+ @ Test
539
+ void resolveOffchainParameterEncoding () throws Exception {
540
+ OffchainResolverContract resolver = mock (OffchainResolverContract .class );
541
+ when (resolver .getContractAddress ())
542
+ .thenReturn ("0xc1735677a60884abbcf72295e88d47764beda282" );
543
+
544
+ OkHttpClient httpClientMock = mock (OkHttpClient .class );
545
+ Call call = mock (Call .class );
546
+ String testData = "0xabcdef" ;
547
+
548
+ EnsGatewayResponseDTO responseDTO = new EnsGatewayResponseDTO (testData );
549
+ String responseJson = om .writeValueAsString (responseDTO );
550
+
551
+ okhttp3 .Response responseObj =
552
+ new okhttp3 .Response .Builder ()
553
+ .request (new okhttp3 .Request .Builder ().url (urls .get (0 )).build ())
554
+ .protocol (Protocol .HTTP_2 )
555
+ .code (200 )
556
+ .body (ResponseBody .create (responseJson , JSON_MEDIA_TYPE ))
557
+ .message ("OK" )
558
+ .build ();
559
+
560
+ ensResolver .setHttpClient (httpClientMock );
561
+ when (httpClientMock .newCall (any ())).thenReturn (call );
562
+ when (call .execute ()).thenReturn (responseObj );
563
+
564
+ ArgumentCaptor <String > functionCallCaptor = ArgumentCaptor .forClass (String .class );
565
+ when (resolver .executeCallWithoutDecoding (functionCallCaptor .capture ()))
566
+ .thenReturn (RESOLVED_NAME_HEX );
567
+
568
+ String result = ensResolver .resolveOffchain (LOOKUP_HEX , resolver , 4 );
569
+ assertEquals ("0x41563129cdbbd0c5d3e1c86cf9563926b243834d" , result );
570
+
571
+ String capturedFunctionCall = functionCallCaptor .getValue ();
572
+ assertTrue (
573
+ capturedFunctionCall .contains (testData .substring (2 )),
574
+ "Function call should contain the encoded test data" );
575
+ }
576
+
461
577
class EnsResolverForTest extends EnsResolver {
462
578
private OffchainResolverContract resolverMock ;
463
579
0 commit comments