@@ -353,4 +353,80 @@ public void testExecuteThrowsUnexpectedStatus() throws Exception {
353353 mockHttpResponse (500 , "Server Error" );
354354 client .validateServerId ("http://pdns" , 8081 , "apikey" , "abc" );
355355 }
356+ // Route helper: GET /servers/abc → validate; GET /zones/... → zone response
357+ private void mockDnsRecordExists (String zoneJson ) throws IOException {
358+ when (httpClientMock .execute (any (HttpUriRequest .class ))).thenAnswer (new Answer <CloseableHttpResponse >() {
359+ @ Override
360+ public CloseableHttpResponse answer (InvocationOnMock invocation ) {
361+ HttpUriRequest request = invocation .getArgument (0 );
362+ String path = request .getURI ().getPath ();
363+ if (path .endsWith ("/abc" )) {
364+ return createResponse (200 , "{\" id\" :\" abc\" , \" daemon_type\" :\" authoritative\" }" );
365+ }
366+ // zone query (contains /zones/)
367+ if (zoneJson == null ) {
368+ return createResponse (200 , null ); // empty body → execute() returns null
369+ }
370+ return createResponse (200 , zoneJson );
371+ }
372+ });
373+ }
374+
375+ @ Test
376+ public void testDnsRecordExistsZoneNodeNull () throws Exception {
377+ // execute() returns null → zoneNode == null → false
378+ mockDnsRecordExists (null );
379+ boolean result = client .dnsRecordExists ("http://pdns" , 8081 , "apikey" , "abc" , "example.com" , "www" , "A" );
380+ assertEquals (false , result );
381+ }
382+
383+ @ Test
384+ public void testDnsRecordExistsMissingRrSetsField () throws Exception {
385+ // response has no "rrsets" key → !zoneNode.has(RR_SETS) → false
386+ mockDnsRecordExists ("{}" );
387+ boolean result = client .dnsRecordExists ("http://pdns" , 8081 , "apikey" , "abc" , "example.com" , "www" , "A" );
388+ assertEquals (false , result );
389+ }
390+
391+ @ Test
392+ public void testDnsRecordExistsRrSetsNotArray () throws Exception {
393+ // rrsets is a scalar string, not an ArrayNode → isArray() == false → false
394+ mockDnsRecordExists ("{\" rrsets\" :\" not-an-array\" }" );
395+ boolean result = client .dnsRecordExists ("http://pdns" , 8081 , "apikey" , "abc" , "example.com" , "www" , "A" );
396+ assertEquals (false , result );
397+ }
398+
399+ @ Test
400+ public void testDnsRecordExistsEmptyRrSetsArray () throws Exception {
401+ // rrsets is an empty array → isArray() == true && isEmpty() == true → false
402+ mockDnsRecordExists ("{\" rrsets\" :[]}" );
403+ boolean result = client .dnsRecordExists ("http://pdns" , 8081 , "apikey" , "abc" , "example.com" , "www" , "A" );
404+ assertEquals (false , result );
405+ }
406+
407+ @ Test
408+ public void testDnsRecordExistsNonEmptyRrSetsArray () throws Exception {
409+ // rrsets is a non-empty array → isArray() == true && !isEmpty() → true
410+ mockDnsRecordExists ("{\" rrsets\" :[{\" name\" :\" www.example.com.\" ,\" type\" :\" A\" }]}" );
411+ boolean result = client .dnsRecordExists ("http://pdns" , 8081 , "apikey" , "abc" , "example.com" , "www" , "A" );
412+ assertEquals (true , result );
413+ }
414+
415+ @ Test
416+ public void testCloseSucceeds () throws Exception {
417+ // httpClient.close() completes normally → no exception propagated
418+ CloseableHttpClient mockClient = mock (CloseableHttpClient .class );
419+ ReflectionTestUtils .setField (client , "httpClient" , mockClient );
420+ client .close ();
421+ org .mockito .Mockito .verify (mockClient ).close ();
422+ }
423+
424+ @ Test
425+ public void testCloseSwallowsIOException () throws Exception {
426+ // httpClient.close() throws IOException → caught and logged (warn), no rethrow
427+ CloseableHttpClient mockClient = mock (CloseableHttpClient .class );
428+ org .mockito .Mockito .doThrow (new IOException ("connection reset" )).when (mockClient ).close ();
429+ ReflectionTestUtils .setField (client , "httpClient" , mockClient );
430+ client .close (); // must NOT throw
431+ }
356432}
0 commit comments