@@ -1003,6 +1003,40 @@ public void testBearerTokenAuth() throws Exception {
10031003 }
10041004 }
10051005
1006+ @ Test (groups = { "integration" })
1007+ public void testBasicAuthWithNoPassword () throws Exception {
1008+ WireMockServer mockServer = new WireMockServer (WireMockConfiguration
1009+ .options ().port (9090 ).notifier (new ConsoleNotifier (false )));
1010+ mockServer .start ();
1011+
1012+ try {
1013+ // Expected: "default:" with empty password, not "default:null"
1014+ String expectedAuth = "Basic " + Base64 .getEncoder ()
1015+ .encodeToString ("default:" .getBytes (StandardCharsets .UTF_8 ));
1016+
1017+ mockServer .addStubMapping (WireMock .post (WireMock .anyUrl ())
1018+ .withHeader ("Authorization" , WireMock .equalTo (expectedAuth ))
1019+ .willReturn (WireMock .aResponse ()
1020+ .withHeader ("X-ClickHouse-Summary" ,
1021+ "{ \" read_bytes\" : \" 10\" , \" read_rows\" : \" 1\" }" )).build ());
1022+
1023+ try (Client client = new Client .Builder ()
1024+ .addEndpoint (Protocol .HTTP , "localhost" , mockServer .port (), false )
1025+ .compressServerResponse (false )
1026+ // no setPassword() call — password should default to empty, not "null"
1027+ .build ()) {
1028+
1029+ try (QueryResponse response = client .query ("SELECT 1" ).get (1 , TimeUnit .SECONDS )) {
1030+ Assert .assertEquals (response .getReadBytes (), 10 );
1031+ } catch (Exception e ) {
1032+ Assert .fail ("Basic auth with no password should send empty password, not 'null'" , e );
1033+ }
1034+ }
1035+ } finally {
1036+ mockServer .stop ();
1037+ }
1038+ }
1039+
10061040 @ Test (groups = { "integration" })
10071041 public void testJWTWithCloud () throws Exception {
10081042 if (!isCloud ()) {
0 commit comments