@@ -499,6 +499,43 @@ public void batchCheck_withHeaders() throws Exception {
499499 assertTrue (response .getResult ().isEmpty ());
500500 }
501501
502+ @ Test
503+ public void clientBatchCheck_withHeaders () throws Exception {
504+ // Given
505+ String postUrl = String .format ("https://api.fga.example/stores/%s/check" , DEFAULT_STORE_ID );
506+ String expectedBody = String .format (
507+ "{\" tuple_key\" :{\" user\" :\" %s\" ,\" relation\" :\" %s\" ,\" object\" :\" %s\" },\" contextual_tuples\" :null,\" authorization_model_id\" :\" %s\" ,\" trace\" :null,\" context\" :null,\" consistency\" :\" UNSPECIFIED\" }" ,
508+ DEFAULT_USER , DEFAULT_RELATION , DEFAULT_OBJECT , DEFAULT_AUTH_MODEL_ID );
509+ mockHttpClient
510+ .onPost (postUrl )
511+ .withBody (is (expectedBody ))
512+ .withHeader ("another-header" , "another-value" )
513+ .withHeader ("test-header" , "test-value-per-call" )
514+ .doReturn (200 , "{\" allowed\" :true}" );
515+ ClientCheckRequest request = new ClientCheckRequest ()
516+ ._object (DEFAULT_OBJECT )
517+ .relation (DEFAULT_RELATION )
518+ .user (DEFAULT_USER );
519+ Map <String , String > headers = new java .util .HashMap <>();
520+ headers .put ("test-header" , "test-value-per-call" );
521+ ClientBatchCheckClientOptions options = new ClientBatchCheckClientOptions ()
522+ .additionalHeaders (headers );
523+
524+ // When
525+ List <ClientBatchCheckClientResponse > response =
526+ fga .clientBatchCheck (List .of (request ), options ).get ();
527+
528+ // Then
529+ mockHttpClient
530+ .verify ()
531+ .post (postUrl )
532+ .withBody (is (expectedBody ))
533+ .withHeader ("another-header" , "another-value" )
534+ .withHeader ("test-header" , "test-value-per-call" )
535+ .called (1 );
536+ assertEquals (Boolean .TRUE , response .get (0 ).getAllowed ());
537+ }
538+
502539 @ Test
503540 public void expand_withHeaders () throws Exception {
504541 // Given
@@ -721,6 +758,7 @@ public void listRelations_withHeaders() throws Exception {
721758 ClientListRelationsResponse response =
722759 fga .listRelations (request , options ).get ();
723760
761+ // Then
724762 mockHttpClient
725763 .verify ()
726764 .post (postUrl )
@@ -729,6 +767,74 @@ public void listRelations_withHeaders() throws Exception {
729767 .called (1 );
730768 }
731769
770+ @ Test
771+ public void listRelations_withNullHeaders () throws Exception {
772+ // Given
773+ String postUrl = String .format ("https://api.fga.example/stores/%s/check" , DEFAULT_STORE_ID );
774+ String expectedBody = String .format (
775+ "{\" tuple_key\" :{\" user\" :\" %s\" ,\" relation\" :\" %s\" ,\" object\" :\" %s\" },\" contextual_tuples\" :null,\" authorization_model_id\" :\" %s\" ,\" trace\" :null,\" context\" :null,\" consistency\" :\" UNSPECIFIED\" }" ,
776+ DEFAULT_USER , DEFAULT_RELATION , DEFAULT_OBJECT , DEFAULT_AUTH_MODEL_ID );
777+
778+ mockHttpClient
779+ .onPost (postUrl )
780+ .withBody (is (expectedBody ))
781+ .withHeader ("another-header" , "another-value" )
782+ .withHeader ("test-header" , "test-value" )
783+ .doReturn (200 , "{\" allowed\" :true}" );
784+
785+ ClientListRelationsRequest request = new ClientListRelationsRequest ()
786+ .relations (List .of (DEFAULT_RELATION ))
787+ .user (DEFAULT_USER )
788+ ._object (DEFAULT_OBJECT );
789+ ClientListRelationsOptions options = new ClientListRelationsOptions ().additionalHeaders (null );
790+
791+ // When - this should not throw even though additionalHeaders is null
792+ ClientListRelationsResponse response = fga .listRelations (request , options ).get ();
793+
794+ // Then
795+ mockHttpClient
796+ .verify ()
797+ .post (postUrl )
798+ .withHeader ("another-header" , "another-value" )
799+ .withHeader ("test-header" , "test-value" )
800+ .called (1 );
801+ assertNotNull (response );
802+ }
803+
804+ @ Test
805+ public void clientBatchCheck_withNullHeaders () throws Exception {
806+ // Given
807+ String postUrl = String .format ("https://api.fga.example/stores/%s/check" , DEFAULT_STORE_ID );
808+ String expectedBody = String .format (
809+ "{\" tuple_key\" :{\" user\" :\" %s\" ,\" relation\" :\" %s\" ,\" object\" :\" %s\" },\" contextual_tuples\" :null,\" authorization_model_id\" :\" %s\" ,\" trace\" :null,\" context\" :null,\" consistency\" :\" UNSPECIFIED\" }" ,
810+ DEFAULT_USER , DEFAULT_RELATION , DEFAULT_OBJECT , DEFAULT_AUTH_MODEL_ID );
811+ mockHttpClient
812+ .onPost (postUrl )
813+ .withBody (is (expectedBody ))
814+ .withHeader ("another-header" , "another-value" )
815+ .withHeader ("test-header" , "test-value" )
816+ .doReturn (200 , "{\" allowed\" :true}" );
817+ ClientCheckRequest request = new ClientCheckRequest ()
818+ ._object (DEFAULT_OBJECT )
819+ .relation (DEFAULT_RELATION )
820+ .user (DEFAULT_USER );
821+ ClientBatchCheckClientOptions options = new ClientBatchCheckClientOptions ().additionalHeaders (null );
822+
823+ // When - this should not throw even though additionalHeaders is null
824+ List <ClientBatchCheckClientResponse > response =
825+ fga .clientBatchCheck (List .of (request ), options ).get ();
826+
827+ // Then
828+ mockHttpClient
829+ .verify ()
830+ .post (postUrl )
831+ .withBody (is (expectedBody ))
832+ .withHeader ("another-header" , "another-value" )
833+ .withHeader ("test-header" , "test-value" )
834+ .called (1 );
835+ assertEquals (Boolean .TRUE , response .get (0 ).getAllowed ());
836+ }
837+
732838 /**
733839 * Edge case: No default headers configured on client.
734840 */
0 commit comments