Add unit tests for CfDnsClient, Fluent API, and CfDnsClientBuilder. Minor error message refinement in CfBasicHttpClient.
This commit is contained in:
@@ -33,6 +33,9 @@ abstract class CfBasicHttpClient {
|
|||||||
private final CfDnsClientBuilder.CfAuth auth;
|
private final CfDnsClientBuilder.CfAuth auth;
|
||||||
private final ObjectMapper objectMapper;
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
private record ResultWrapper(int statusCode, String responseBody) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Cloudflare HTTP client with the specified base URL and authentication.
|
* Creates a new Cloudflare HTTP client with the specified base URL and authentication.
|
||||||
*
|
*
|
||||||
@@ -97,7 +100,7 @@ abstract class CfBasicHttpClient {
|
|||||||
log.error("JSON parsing error for request to {}", logUri, e);
|
log.error("JSON parsing error for request to {}", logUri, e);
|
||||||
throw new CloudflareApiException("Error processing JSON response", e);
|
throw new CloudflareApiException("Error processing JSON response", e);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new CloudflareApiException("Server error!", e);
|
throw new CloudflareApiException("Unexpected error!", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +190,4 @@ abstract class CfBasicHttpClient {
|
|||||||
private String buildUrl(String endpoint) {
|
private String buildUrl(String endpoint) {
|
||||||
return baseUrl + endpoint;
|
return baseUrl + endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
private record ResultWrapper(int statusCode, String responseBody) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,157 @@
|
|||||||
|
package codes.thischwa.cf;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import codes.thischwa.cf.model.RecordEntity;
|
||||||
|
import codes.thischwa.cf.model.RecordSingleResponse;
|
||||||
|
import codes.thischwa.cf.model.RecordType;
|
||||||
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for CfBasicHttpClient using mocked HTTP components.
|
||||||
|
* Tests HTTP client functionality without requiring actual network calls.
|
||||||
|
*/
|
||||||
|
class CfBasicHttpClientTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test implementation of CfBasicHttpClient for testing purposes.
|
||||||
|
*/
|
||||||
|
private static class TestCfBasicHttpClient extends CfBasicHttpClient {
|
||||||
|
|
||||||
|
TestCfBasicHttpClient(String baseUrl, CfDnsClientBuilder.CfAuth auth) {
|
||||||
|
super(baseUrl, auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expose protected methods for testing
|
||||||
|
public <T extends codes.thischwa.cf.model.AbstractResponse> T testGetRequest(String endpoint, Class<T> responseType)
|
||||||
|
throws CloudflareApiException {
|
||||||
|
return getRequest(endpoint, responseType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends codes.thischwa.cf.model.AbstractResponse> T testPostRequest(String endpoint, Object payload, Class<T> responseType)
|
||||||
|
throws CloudflareApiException {
|
||||||
|
return postRequest(endpoint, payload, responseType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends codes.thischwa.cf.model.AbstractResponse> T testPutRequest(String endpoint, Object payload, Class<T> responseType)
|
||||||
|
throws CloudflareApiException {
|
||||||
|
return putRequest(endpoint, payload, responseType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends codes.thischwa.cf.model.AbstractResponse> T testPatchRequest(String endpoint, Object payload, Class<T> responseType)
|
||||||
|
throws CloudflareApiException {
|
||||||
|
return patchRequest(endpoint, payload, responseType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends codes.thischwa.cf.model.AbstractResponse> T testDeleteRequest(String endpoint, Class<T> responseType)
|
||||||
|
throws CloudflareApiException {
|
||||||
|
return deleteRequest(endpoint, responseType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testConstructor_WithApiToken() {
|
||||||
|
CfDnsClientBuilder.ApiTokenAuth auth = new CfDnsClientBuilder.ApiTokenAuth("test-token");
|
||||||
|
TestCfBasicHttpClient client = new TestCfBasicHttpClient("https://api.cloudflare.com", auth);
|
||||||
|
assertNotNull(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testConstructor_WithEmailKey() {
|
||||||
|
CfDnsClientBuilder.EmailKeyAuth auth = new CfDnsClientBuilder.EmailKeyAuth("test@example.com", "test-key");
|
||||||
|
TestCfBasicHttpClient client = new TestCfBasicHttpClient("https://api.cloudflare.com", auth);
|
||||||
|
assertNotNull(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testApiException_unknowEndpoint() {
|
||||||
|
CfDnsClientBuilder.ApiTokenAuth auth = new CfDnsClientBuilder.ApiTokenAuth("test-token");
|
||||||
|
TestCfBasicHttpClient client = new TestCfBasicHttpClient("https://api.cloudflare.com", auth);
|
||||||
|
|
||||||
|
// Invalid JSON will cause a parsing error
|
||||||
|
CloudflareApiException exception = assertThrows(CloudflareApiException.class, () -> {
|
||||||
|
client.testGetRequest("/invalid-endpoint", RecordSingleResponse.class);
|
||||||
|
});
|
||||||
|
|
||||||
|
assertNotNull(exception);
|
||||||
|
assertTrue(exception.getMessage().contains("Unexpected error"));
|
||||||
|
Throwable cause = exception.getCause();
|
||||||
|
assertInstanceOf(CloudflareApiException.class, cause);
|
||||||
|
assertTrue(cause.getMessage().contains("API error: 10404: No route for that URI"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testResultWrapper() throws Exception {
|
||||||
|
// Test the private ResultWrapper record indirectly through client behavior
|
||||||
|
CfDnsClientBuilder.ApiTokenAuth auth = new CfDnsClientBuilder.ApiTokenAuth("test-token");
|
||||||
|
TestCfBasicHttpClient client = new TestCfBasicHttpClient("https://api.cloudflare.com", auth);
|
||||||
|
|
||||||
|
// Any request will create and use a ResultWrapper internally
|
||||||
|
assertThrows(CloudflareApiException.class, () -> {
|
||||||
|
client.testGetRequest("/test", RecordSingleResponse.class);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testAuthApplicationHeader_ApiToken() {
|
||||||
|
CfDnsClientBuilder.ApiTokenAuth auth = new CfDnsClientBuilder.ApiTokenAuth("my-token");
|
||||||
|
HttpGet request = new HttpGet("https://api.cloudflare.com/test");
|
||||||
|
|
||||||
|
auth.applyAuth(request);
|
||||||
|
|
||||||
|
assertTrue(request.containsHeader("Authorization"));
|
||||||
|
assertEquals("Bearer my-token", request.getFirstHeader("Authorization").getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testAuthApplicationHeader_EmailKey() {
|
||||||
|
CfDnsClientBuilder.EmailKeyAuth auth = new CfDnsClientBuilder.EmailKeyAuth("test@example.com", "my-key");
|
||||||
|
HttpGet request = new HttpGet("https://api.cloudflare.com/test");
|
||||||
|
|
||||||
|
auth.applyAuth(request);
|
||||||
|
|
||||||
|
assertTrue(request.containsHeader("X-Auth-Email"));
|
||||||
|
assertTrue(request.containsHeader("X-Auth-Key"));
|
||||||
|
assertEquals("test@example.com", request.getFirstHeader("X-Auth-Email").getValue());
|
||||||
|
assertEquals("my-key", request.getFirstHeader("X-Auth-Key").getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBaseUrlConstruction() {
|
||||||
|
CfDnsClientBuilder.ApiTokenAuth auth = new CfDnsClientBuilder.ApiTokenAuth("test-token");
|
||||||
|
|
||||||
|
// Test default base URL
|
||||||
|
TestCfBasicHttpClient client = new TestCfBasicHttpClient("https://api.cloudflare.com", auth);
|
||||||
|
assertNotNull(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testObjectMapperInitialization() {
|
||||||
|
// ObjectMapper is initialized in constructor via JsonConf
|
||||||
|
CfDnsClientBuilder.ApiTokenAuth auth = new CfDnsClientBuilder.ApiTokenAuth("test-token");
|
||||||
|
TestCfBasicHttpClient client = new TestCfBasicHttpClient("https://api.cloudflare.com", auth);
|
||||||
|
|
||||||
|
// If ObjectMapper wasn't initialized, any request would fail with NullPointerException
|
||||||
|
assertThrows(CloudflareApiException.class, () -> {
|
||||||
|
client.testGetRequest("/test", RecordSingleResponse.class);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRequestPayloadSerialization() {
|
||||||
|
CfDnsClientBuilder.ApiTokenAuth auth = new CfDnsClientBuilder.ApiTokenAuth("test-token");
|
||||||
|
TestCfBasicHttpClient client = new TestCfBasicHttpClient("https://api.cloudflare.com", auth);
|
||||||
|
|
||||||
|
RecordEntity record = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
|
||||||
|
// The payload serialization happens inside postRequest
|
||||||
|
assertThrows(CloudflareApiException.class, () -> {
|
||||||
|
client.testPostRequest("/test", record, RecordSingleResponse.class);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -198,7 +198,6 @@ public class CfClientTest {
|
|||||||
// test recordList with types without SLD
|
// test recordList with types without SLD
|
||||||
List<RecordEntity> aList = client.recordList(z, RecordType.A);
|
List<RecordEntity> aList = client.recordList(z, RecordType.A);
|
||||||
assertFalse(aList.isEmpty());
|
assertFalse(aList.isEmpty());
|
||||||
assertTrue(aList.size() >= 1);
|
|
||||||
assertTrue(aList.stream().anyMatch(re -> re.getId().equals(createdRe1.getId())));
|
assertTrue(aList.stream().anyMatch(re -> re.getId().equals(createdRe1.getId())));
|
||||||
assertTrue(aList.stream().noneMatch(re -> re.getId().equals(createdRe2.getId())));
|
assertTrue(aList.stream().noneMatch(re -> re.getId().equals(createdRe2.getId())));
|
||||||
assertTrue(aList.stream().allMatch(re -> re.getType().equals(RecordType.A.getType())));
|
assertTrue(aList.stream().allMatch(re -> re.getType().equals(RecordType.A.getType())));
|
||||||
|
|||||||
@@ -0,0 +1,150 @@
|
|||||||
|
package codes.thischwa.cf;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for CfDnsClientBuilder and its authentication classes.
|
||||||
|
*/
|
||||||
|
class CfDnsClientBuilderTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuildWithApiToken() {
|
||||||
|
CfDnsClient client = new CfDnsClientBuilder()
|
||||||
|
.withApiTokenAuth("test-token")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertNotNull(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuildWithEmailKey() {
|
||||||
|
CfDnsClient client = new CfDnsClientBuilder()
|
||||||
|
.withEmailKeyAuth("test@example.com", "test-key")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertNotNull(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuildWithCustomBaseUrl() {
|
||||||
|
CfDnsClient client = new CfDnsClientBuilder()
|
||||||
|
.withApiTokenAuth("test-token")
|
||||||
|
.withBaseUrl("https://custom-api.example.com")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertNotNull(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuildWithDefaultBaseUrl() {
|
||||||
|
CfDnsClient client = new CfDnsClientBuilder()
|
||||||
|
.withApiTokenAuth("test-token")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertNotNull(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuildWithEmptyResultThrowsException() {
|
||||||
|
CfDnsClient client = new CfDnsClientBuilder()
|
||||||
|
.withApiTokenAuth("test-token")
|
||||||
|
.withEmptyResultThrowsException(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertNotNull(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuildWithEmptyResultDoesNotThrowException() {
|
||||||
|
CfDnsClient client = new CfDnsClientBuilder()
|
||||||
|
.withApiTokenAuth("test-token")
|
||||||
|
.withEmptyResultThrowsException(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertNotNull(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuilderMethodChaining() {
|
||||||
|
CfDnsClient client = new CfDnsClientBuilder()
|
||||||
|
.withApiTokenAuth("test-token")
|
||||||
|
.withBaseUrl("https://custom-api.example.com")
|
||||||
|
.withEmptyResultThrowsException(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertNotNull(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testApiTokenAuth_BlankToken() {
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> new CfDnsClientBuilder.ApiTokenAuth(" "));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEmailKeyAuth_ValidCredentials() {
|
||||||
|
CfDnsClientBuilder.EmailKeyAuth auth = new CfDnsClientBuilder.EmailKeyAuth(
|
||||||
|
"test@example.com",
|
||||||
|
"valid-key"
|
||||||
|
);
|
||||||
|
assertNotNull(auth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEmailKeyAuth_BlankEmail() {
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> new CfDnsClientBuilder.EmailKeyAuth(" ", "valid-key"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEmailKeyAuth_BlankKey() {
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> new CfDnsClientBuilder.EmailKeyAuth("test@example.com", " "));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEmailKeyAuth_BothBlank() {
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> new CfDnsClientBuilder.EmailKeyAuth(" ", " "));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDefaultBaseUrl() {
|
||||||
|
assertEquals("https://api.cloudflare.com/client/v4", CfDnsClientBuilder.DEFAULT_BASEURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuilderWithMultipleConfigurations() {
|
||||||
|
// Test switching auth methods in the same builder (last one wins)
|
||||||
|
CfDnsClient client = new CfDnsClientBuilder()
|
||||||
|
.withEmailKeyAuth("test@example.com", "old-key")
|
||||||
|
.withApiTokenAuth("new-token") // This should override the email/key auth
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertNotNull(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBuilderWithMultipleBaseUrls() {
|
||||||
|
// Test setting base URL multiple times (last one wins)
|
||||||
|
CfDnsClient client = new CfDnsClientBuilder()
|
||||||
|
.withApiTokenAuth("test-token")
|
||||||
|
.withBaseUrl("https://old-api.example.com")
|
||||||
|
.withBaseUrl("https://new-api.example.com") // This should override
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertNotNull(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEmptyResultThrowsExceptionToggle() {
|
||||||
|
// Test toggling the flag multiple times (last one wins)
|
||||||
|
CfDnsClient client = new CfDnsClientBuilder()
|
||||||
|
.withApiTokenAuth("test-token")
|
||||||
|
.withEmptyResultThrowsException(true)
|
||||||
|
.withEmptyResultThrowsException(false) // This should override
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertNotNull(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,399 @@
|
|||||||
|
package codes.thischwa.cf;
|
||||||
|
|
||||||
|
import codes.thischwa.cf.fluent.ZoneOperations;
|
||||||
|
import codes.thischwa.cf.model.*;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.ArgumentMatchers.*;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for CfDnsClient using mocked HTTP client responses.
|
||||||
|
* Tests all public methods without requiring actual Cloudflare API access.
|
||||||
|
*/
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class CfDnsClientMockTest {
|
||||||
|
|
||||||
|
private CfDnsClient client;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CfBasicHttpClient mockHttpClient;
|
||||||
|
|
||||||
|
private static final String TEST_ZONE_ID = "zone123";
|
||||||
|
private static final String TEST_ZONE_NAME = "example.com";
|
||||||
|
private static final String TEST_RECORD_ID = "rec123";
|
||||||
|
|
||||||
|
private ZoneEntity createTestZone() {
|
||||||
|
ZoneEntity zone = new ZoneEntity();
|
||||||
|
zone.setId(TEST_ZONE_ID);
|
||||||
|
zone.setName(TEST_ZONE_NAME);
|
||||||
|
return zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResponseResultInfo createSuccessResultInfo() {
|
||||||
|
ResponseResultInfo resultInfo = new ResponseResultInfo();
|
||||||
|
resultInfo.setSuccess(true);
|
||||||
|
return resultInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BatchResponse createBatchResponse() throws Exception {
|
||||||
|
// Use reflection to access package-private constructor
|
||||||
|
java.lang.reflect.Constructor<BatchResponse> constructor = BatchResponse.class.getDeclaredConstructor();
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
return constructor.newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResultInfo createResultInfo(int count) {
|
||||||
|
return new ResultInfo(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() throws Exception {
|
||||||
|
// Create a real client with API token auth
|
||||||
|
client = new CfDnsClientBuilder()
|
||||||
|
.withApiTokenAuth("test-token")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Replace the internal HTTP client with our mock using reflection
|
||||||
|
// Note: This is a workaround since CfBasicHttpClient methods are package-private
|
||||||
|
Field responseValidatorField = CfDnsClient.class.getDeclaredField("responseValidator");
|
||||||
|
responseValidatorField.setAccessible(true);
|
||||||
|
responseValidatorField.set(client, new ResponseValidator(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGroupRecordsByFqdn() {
|
||||||
|
RecordEntity rec1 = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
RecordEntity rec2 = RecordEntity.build("test.example.com", RecordType.AAAA, 300, "::1");
|
||||||
|
RecordEntity rec3 = RecordEntity.build("www.example.com", RecordType.A, 300, "1.2.3.5");
|
||||||
|
|
||||||
|
List<RecordEntity> records = List.of(rec1, rec2, rec3);
|
||||||
|
Map<String, List<RecordEntity>> grouped = CfDnsClient.groupRecordsByFqdn(records);
|
||||||
|
|
||||||
|
assertEquals(2, grouped.size());
|
||||||
|
assertEquals(2, grouped.get("test.example.com").size());
|
||||||
|
assertEquals(1, grouped.get("www.example.com").size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGroupRecordsByFqdn_NullInput() {
|
||||||
|
Map<String, List<RecordEntity>> grouped = CfDnsClient.groupRecordsByFqdn(null);
|
||||||
|
assertNotNull(grouped);
|
||||||
|
assertTrue(grouped.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testZoneList() throws Exception {
|
||||||
|
// Create mock zone response
|
||||||
|
ZoneMultipleResponse mockResponse = new ZoneMultipleResponse();
|
||||||
|
ZoneEntity zone1 = new ZoneEntity();
|
||||||
|
zone1.setId("zone1");
|
||||||
|
zone1.setName("example.com");
|
||||||
|
ZoneEntity zone2 = new ZoneEntity();
|
||||||
|
zone2.setId("zone2");
|
||||||
|
zone2.setName("test.com");
|
||||||
|
mockResponse.setResult(List.of(zone1, zone2));
|
||||||
|
ResponseResultInfo resultInfo = new ResponseResultInfo();
|
||||||
|
resultInfo.setSuccess(true);
|
||||||
|
mockResponse.setResponseResultInfo(resultInfo);
|
||||||
|
|
||||||
|
// Mock the HTTP client via spy
|
||||||
|
CfDnsClient spyClient = spy(client);
|
||||||
|
doReturn(mockResponse).when(spyClient).getRequest(anyString(), eq(ZoneMultipleResponse.class));
|
||||||
|
|
||||||
|
List<ZoneEntity> zones = spyClient.zoneList();
|
||||||
|
|
||||||
|
assertNotNull(zones);
|
||||||
|
assertEquals(2, zones.size());
|
||||||
|
assertEquals("example.com", zones.get(0).getName());
|
||||||
|
assertEquals("test.com", zones.get(1).getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testZoneGet() throws Exception {
|
||||||
|
// Create mock zone response
|
||||||
|
ZoneMultipleResponse mockResponse = new ZoneMultipleResponse();
|
||||||
|
ZoneEntity zone = new ZoneEntity();
|
||||||
|
zone.setId(TEST_ZONE_ID);
|
||||||
|
zone.setName(TEST_ZONE_NAME);
|
||||||
|
mockResponse.setResult(List.of(zone));
|
||||||
|
ResponseResultInfo resultInfo = new ResponseResultInfo();
|
||||||
|
resultInfo.setSuccess(true);
|
||||||
|
mockResponse.setResponseResultInfo(resultInfo);
|
||||||
|
|
||||||
|
CfDnsClient spyClient = spy(client);
|
||||||
|
doReturn(mockResponse).when(spyClient).getRequest(anyString(), eq(ZoneMultipleResponse.class));
|
||||||
|
|
||||||
|
ZoneEntity result = spyClient.zoneGet(TEST_ZONE_NAME);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(TEST_ZONE_ID, result.getId());
|
||||||
|
assertEquals(TEST_ZONE_NAME, result.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testZoneOperations() throws Exception {
|
||||||
|
// Create mock zone response
|
||||||
|
ZoneMultipleResponse mockResponse = new ZoneMultipleResponse();
|
||||||
|
ZoneEntity zone = new ZoneEntity();
|
||||||
|
zone.setId(TEST_ZONE_ID);
|
||||||
|
zone.setName(TEST_ZONE_NAME);
|
||||||
|
mockResponse.setResult(List.of(zone));
|
||||||
|
ResponseResultInfo resultInfo = new ResponseResultInfo();
|
||||||
|
resultInfo.setSuccess(true);
|
||||||
|
mockResponse.setResponseResultInfo(resultInfo);
|
||||||
|
|
||||||
|
CfDnsClient spyClient = spy(client);
|
||||||
|
doReturn(mockResponse).when(spyClient).getRequest(anyString(), eq(ZoneMultipleResponse.class));
|
||||||
|
|
||||||
|
ZoneOperations ops = spyClient.zone(TEST_ZONE_NAME);
|
||||||
|
|
||||||
|
assertNotNull(ops);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordList_Zone() throws Exception {
|
||||||
|
ZoneEntity zone = new ZoneEntity();
|
||||||
|
zone.setId(TEST_ZONE_ID);
|
||||||
|
zone.setName(TEST_ZONE_NAME);
|
||||||
|
|
||||||
|
RecordMultipleResponse mockResponse = new RecordMultipleResponse();
|
||||||
|
mockResponse.setResultInfo(createResultInfo(1));
|
||||||
|
RecordEntity rec1 = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
RecordEntity rec2 = RecordEntity.build("www.example.com", RecordType.A, 300, "1.2.3.5");
|
||||||
|
mockResponse.setResult(List.of(rec1, rec2));
|
||||||
|
ResponseResultInfo resultInfo = new ResponseResultInfo();
|
||||||
|
resultInfo.setSuccess(true);
|
||||||
|
mockResponse.setResponseResultInfo(resultInfo);
|
||||||
|
|
||||||
|
CfDnsClient spyClient = spy(client);
|
||||||
|
doReturn(mockResponse).when(spyClient).getRequest(anyString(), eq(RecordMultipleResponse.class));
|
||||||
|
|
||||||
|
List<RecordEntity> records = spyClient.recordList(zone);
|
||||||
|
|
||||||
|
assertNotNull(records);
|
||||||
|
assertEquals(2, records.size());
|
||||||
|
assertEquals("1.2.3.4", records.get(0).getContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordList_WithPaging() throws Exception {
|
||||||
|
ZoneEntity zone = createTestZone();
|
||||||
|
PagingRequest pagingRequest = PagingRequest.of(10, 1);
|
||||||
|
|
||||||
|
RecordMultipleResponse mockResponse = new RecordMultipleResponse();
|
||||||
|
mockResponse.setResultInfo(createResultInfo(1));
|
||||||
|
RecordEntity rec1 = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
mockResponse.setResult(List.of(rec1));
|
||||||
|
mockResponse.setResponseResultInfo(createSuccessResultInfo());
|
||||||
|
|
||||||
|
CfDnsClient spyClient = spy(client);
|
||||||
|
doReturn(mockResponse).when(spyClient).getRequest(anyString(), eq(RecordMultipleResponse.class));
|
||||||
|
|
||||||
|
List<RecordEntity> records = spyClient.recordList(zone, pagingRequest);
|
||||||
|
|
||||||
|
assertNotNull(records);
|
||||||
|
assertEquals(1, records.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordList_BySld() throws Exception {
|
||||||
|
ZoneEntity zone = createTestZone();
|
||||||
|
|
||||||
|
RecordMultipleResponse mockResponse = new RecordMultipleResponse();
|
||||||
|
mockResponse.setResultInfo(createResultInfo(1));
|
||||||
|
RecordEntity rec1 = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
mockResponse.setResult(List.of(rec1));
|
||||||
|
mockResponse.setResponseResultInfo(createSuccessResultInfo());
|
||||||
|
|
||||||
|
CfDnsClient spyClient = spy(client);
|
||||||
|
doReturn(mockResponse).when(spyClient).getRequest(anyString(), eq(RecordMultipleResponse.class));
|
||||||
|
|
||||||
|
List<RecordEntity> records = spyClient.recordList(zone, "test");
|
||||||
|
|
||||||
|
assertNotNull(records);
|
||||||
|
assertEquals(1, records.size());
|
||||||
|
assertEquals(TEST_ZONE_ID, records.get(0).getZoneId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordList_BySldAndType() throws Exception {
|
||||||
|
ZoneEntity zone = createTestZone();
|
||||||
|
|
||||||
|
RecordMultipleResponse mockResponse = new RecordMultipleResponse();
|
||||||
|
mockResponse.setResultInfo(createResultInfo(1));
|
||||||
|
RecordEntity rec1 = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
RecordEntity rec2 = RecordEntity.build("test.example.com", RecordType.AAAA, 300, "::1");
|
||||||
|
mockResponse.setResult(List.of(rec1, rec2));
|
||||||
|
mockResponse.setResponseResultInfo(createSuccessResultInfo());
|
||||||
|
|
||||||
|
CfDnsClient spyClient = spy(client);
|
||||||
|
doReturn(mockResponse).when(spyClient).getRequest(anyString(), eq(RecordMultipleResponse.class));
|
||||||
|
|
||||||
|
List<RecordEntity> records = spyClient.recordList(zone, "test", RecordType.A);
|
||||||
|
|
||||||
|
assertNotNull(records);
|
||||||
|
assertEquals(1, records.size());
|
||||||
|
assertEquals(RecordType.A, RecordType.valueOf(records.get(0).getType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordList_ByType() throws Exception {
|
||||||
|
ZoneEntity zone = createTestZone();
|
||||||
|
|
||||||
|
RecordMultipleResponse mockResponse = new RecordMultipleResponse();
|
||||||
|
mockResponse.setResultInfo(createResultInfo(1));
|
||||||
|
RecordEntity rec1 = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
RecordEntity rec2 = RecordEntity.build("www.example.com", RecordType.AAAA, 300, "::1");
|
||||||
|
mockResponse.setResult(List.of(rec1, rec2));
|
||||||
|
mockResponse.setResponseResultInfo(createSuccessResultInfo());
|
||||||
|
|
||||||
|
CfDnsClient spyClient = spy(client);
|
||||||
|
doReturn(mockResponse).when(spyClient).getRequest(anyString(), eq(RecordMultipleResponse.class));
|
||||||
|
|
||||||
|
List<RecordEntity> records = spyClient.recordList(zone, RecordType.A);
|
||||||
|
|
||||||
|
assertNotNull(records);
|
||||||
|
assertEquals(1, records.size());
|
||||||
|
assertEquals(RecordType.A, RecordType.valueOf(records.get(0).getType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordCreateSld() throws Exception {
|
||||||
|
ZoneEntity zone = createTestZone();
|
||||||
|
|
||||||
|
RecordSingleResponse mockResponse = new RecordSingleResponse();
|
||||||
|
RecordEntity createdRecord = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
createdRecord.setId(TEST_RECORD_ID);
|
||||||
|
mockResponse.setResult(createdRecord);
|
||||||
|
mockResponse.setResponseResultInfo(createSuccessResultInfo());
|
||||||
|
|
||||||
|
CfDnsClient spyClient = spy(client);
|
||||||
|
doReturn(mockResponse).when(spyClient).postRequest(anyString(), any(), eq(RecordSingleResponse.class));
|
||||||
|
|
||||||
|
RecordEntity result = spyClient.recordCreate(zone, "test.example.com", 300, RecordType.A, "1.2.3.4");
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(TEST_RECORD_ID, result.getId());
|
||||||
|
assertEquals(TEST_ZONE_ID, result.getZoneId());
|
||||||
|
assertEquals("1.2.3.4", result.getContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordDelete() throws Exception {
|
||||||
|
ZoneEntity zone = createTestZone();
|
||||||
|
|
||||||
|
RecordSingleResponse mockResponse = new RecordSingleResponse();
|
||||||
|
RecordEntity deletedRecord = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
deletedRecord.setId(TEST_RECORD_ID);
|
||||||
|
mockResponse.setResult(deletedRecord);
|
||||||
|
mockResponse.setResponseResultInfo(createSuccessResultInfo());
|
||||||
|
|
||||||
|
CfDnsClient spyClient = spy(client);
|
||||||
|
doReturn(mockResponse).when(spyClient).deleteRequest(anyString(), eq(RecordSingleResponse.class));
|
||||||
|
|
||||||
|
boolean result = spyClient.recordDelete(zone, TEST_RECORD_ID);
|
||||||
|
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordUpdate() throws Exception {
|
||||||
|
ZoneEntity zone = createTestZone();
|
||||||
|
RecordEntity record = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
record.setId(TEST_RECORD_ID);
|
||||||
|
|
||||||
|
RecordSingleResponse mockResponse = new RecordSingleResponse();
|
||||||
|
RecordEntity updatedRecord = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.5");
|
||||||
|
updatedRecord.setId(TEST_RECORD_ID);
|
||||||
|
mockResponse.setResult(updatedRecord);
|
||||||
|
mockResponse.setResponseResultInfo(createSuccessResultInfo());
|
||||||
|
|
||||||
|
CfDnsClient spyClient = spy(client);
|
||||||
|
doReturn(mockResponse).when(spyClient).patchRequest(anyString(), any(), eq(RecordSingleResponse.class));
|
||||||
|
|
||||||
|
RecordEntity result = spyClient.recordUpdate(zone, record);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(TEST_RECORD_ID, result.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordDeleteTypeIfExists() throws Exception {
|
||||||
|
ZoneEntity zone = createTestZone();
|
||||||
|
|
||||||
|
RecordMultipleResponse listResponse = new RecordMultipleResponse();
|
||||||
|
listResponse.setResultInfo(createResultInfo(1));
|
||||||
|
RecordEntity rec1 = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
rec1.setId(TEST_RECORD_ID);
|
||||||
|
listResponse.setResult(List.of(rec1));
|
||||||
|
listResponse.setResponseResultInfo(createSuccessResultInfo());
|
||||||
|
|
||||||
|
RecordSingleResponse deleteResponse = new RecordSingleResponse();
|
||||||
|
RecordEntity deletedRecord = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
deletedRecord.setId(TEST_RECORD_ID);
|
||||||
|
deleteResponse.setResult(deletedRecord);
|
||||||
|
deleteResponse.setResponseResultInfo(createSuccessResultInfo());
|
||||||
|
|
||||||
|
CfDnsClient spyClient = spy(client);
|
||||||
|
doReturn(listResponse).when(spyClient).getRequest(anyString(), eq(RecordMultipleResponse.class));
|
||||||
|
doReturn(deleteResponse).when(spyClient).deleteRequest(anyString(), eq(RecordSingleResponse.class));
|
||||||
|
|
||||||
|
// Should not throw exception
|
||||||
|
spyClient.recordDeleteTypeIfExists(zone, "test", RecordType.A);
|
||||||
|
|
||||||
|
verify(spyClient, times(1)).getRequest(anyString(), eq(RecordMultipleResponse.class));
|
||||||
|
verify(spyClient, times(1)).deleteRequest(anyString(), eq(RecordSingleResponse.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordDeleteTypeIfExists_NotFound() throws Exception {
|
||||||
|
ZoneEntity zone = createTestZone();
|
||||||
|
|
||||||
|
CfDnsClient spyClient = spy(client);
|
||||||
|
doThrow(new CloudflareNotFoundException("Not found")).when(spyClient).recordList(any(), anyString(), any());
|
||||||
|
|
||||||
|
// Should not throw exception when record doesn't exist
|
||||||
|
assertDoesNotThrow(() -> spyClient.recordDeleteTypeIfExists(zone, "test", RecordType.A));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordBatch() throws Exception {
|
||||||
|
ZoneEntity zone = createTestZone();
|
||||||
|
|
||||||
|
RecordEntity postRecord = RecordEntity.build("new.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
RecordEntity patchRecord = RecordEntity.build(TEST_RECORD_ID, "1.2.3.5");
|
||||||
|
RecordEntity deleteRecord = RecordEntity.build("old.example.com", RecordType.A, 300, "1.2.3.6");
|
||||||
|
deleteRecord.setId("rec999");
|
||||||
|
|
||||||
|
BatchResponse mockResponse = createBatchResponse();
|
||||||
|
BatchEntry resultEntry = new BatchEntry();
|
||||||
|
resultEntry.setPosts(List.of(postRecord));
|
||||||
|
resultEntry.setPatches(List.of(patchRecord));
|
||||||
|
mockResponse.setResult(resultEntry);
|
||||||
|
mockResponse.setResponseResultInfo(createSuccessResultInfo());
|
||||||
|
|
||||||
|
CfDnsClient spyClient = spy(client);
|
||||||
|
doReturn(mockResponse).when(spyClient).postRequest(anyString(), any(), eq(BatchResponse.class));
|
||||||
|
|
||||||
|
BatchEntry result = spyClient.recordBatch(zone,
|
||||||
|
List.of(postRecord),
|
||||||
|
null,
|
||||||
|
List.of(patchRecord),
|
||||||
|
List.of(deleteRecord));
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertNotNull(result.getPosts());
|
||||||
|
assertEquals(1, result.getPosts().size());
|
||||||
|
assertEquals(TEST_ZONE_ID, result.getPosts().get(0).getZoneId());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,248 @@
|
|||||||
|
package codes.thischwa.cf.fluent;
|
||||||
|
|
||||||
|
import codes.thischwa.cf.CfDnsClient;
|
||||||
|
import codes.thischwa.cf.CloudflareApiException;
|
||||||
|
import codes.thischwa.cf.model.*;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.ArgumentMatchers.*;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for the Fluent API package (ZoneOperations and RecordOperations).
|
||||||
|
*/
|
||||||
|
class FluentApiTest {
|
||||||
|
|
||||||
|
private CfDnsClient mockClient;
|
||||||
|
private ZoneEntity testZone;
|
||||||
|
|
||||||
|
private static final String TEST_ZONE_ID = "zone123";
|
||||||
|
private static final String TEST_ZONE_NAME = "example.com";
|
||||||
|
private static final String TEST_SLD = "test";
|
||||||
|
private static final String TEST_RECORD_ID = "rec123";
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
mockClient = mock(CfDnsClient.class);
|
||||||
|
testZone = new ZoneEntity();
|
||||||
|
testZone.setId(TEST_ZONE_ID);
|
||||||
|
testZone.setName(TEST_ZONE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testZoneOperations_GetRecord() throws CloudflareApiException {
|
||||||
|
ZoneOperations zoneOps = new ZoneOperationsImpl(mockClient, testZone);
|
||||||
|
|
||||||
|
RecordOperations recordOps = zoneOps.getRecord(TEST_SLD);
|
||||||
|
|
||||||
|
assertNotNull(recordOps);
|
||||||
|
assertInstanceOf(RecordOperationsImpl.class, recordOps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testZoneOperations_GetRecordWithTypes() throws CloudflareApiException {
|
||||||
|
ZoneOperations zoneOps = new ZoneOperationsImpl(mockClient, testZone);
|
||||||
|
|
||||||
|
RecordOperations recordOps = zoneOps.getRecord(TEST_SLD, RecordType.A, RecordType.AAAA);
|
||||||
|
|
||||||
|
assertNotNull(recordOps);
|
||||||
|
assertInstanceOf(RecordOperationsImpl.class, recordOps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testZoneOperations_List() throws CloudflareApiException {
|
||||||
|
RecordEntity rec1 = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
RecordEntity rec2 = RecordEntity.build("www.example.com", RecordType.A, 300, "1.2.3.5");
|
||||||
|
List<RecordEntity> expectedRecords = List.of(rec1, rec2);
|
||||||
|
|
||||||
|
when(mockClient.recordList(eq(testZone), any(RecordType[].class)))
|
||||||
|
.thenReturn(expectedRecords);
|
||||||
|
|
||||||
|
ZoneOperations zoneOps = new ZoneOperationsImpl(mockClient, testZone);
|
||||||
|
List<RecordEntity> result = zoneOps.list();
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(2, result.size());
|
||||||
|
verify(mockClient, times(1)).recordList(eq(testZone), any(RecordType[].class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testZoneOperations_ListWithTypes() throws CloudflareApiException {
|
||||||
|
RecordEntity rec1 = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
List<RecordEntity> expectedRecords = List.of(rec1);
|
||||||
|
|
||||||
|
when(mockClient.recordList(eq(testZone), any(RecordType[].class)))
|
||||||
|
.thenReturn(expectedRecords);
|
||||||
|
|
||||||
|
ZoneOperations zoneOps = new ZoneOperationsImpl(mockClient, testZone);
|
||||||
|
List<RecordEntity> result = zoneOps.list(RecordType.A);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(1, result.size());
|
||||||
|
verify(mockClient, times(1)).recordList(eq(testZone), any(RecordType[].class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordOperations_Get() throws CloudflareApiException {
|
||||||
|
RecordEntity rec1 = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
List<RecordEntity> expectedRecords = List.of(rec1);
|
||||||
|
|
||||||
|
when(mockClient.recordList(eq(testZone), eq(TEST_SLD), any()))
|
||||||
|
.thenReturn(expectedRecords);
|
||||||
|
|
||||||
|
RecordOperations recordOps = new RecordOperationsImpl(mockClient, testZone, TEST_SLD, null);
|
||||||
|
List<RecordEntity> result = recordOps.get();
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(1, result.size());
|
||||||
|
assertEquals("1.2.3.4", result.get(0).getContent());
|
||||||
|
verify(mockClient, times(1)).recordList(eq(testZone), eq(TEST_SLD), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordOperations_GetWithTypes() throws CloudflareApiException {
|
||||||
|
RecordEntity rec1 = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
List<RecordEntity> expectedRecords = List.of(rec1);
|
||||||
|
|
||||||
|
RecordType[] types = {RecordType.A};
|
||||||
|
when(mockClient.recordList(eq(testZone), eq(TEST_SLD), eq(types)))
|
||||||
|
.thenReturn(expectedRecords);
|
||||||
|
|
||||||
|
RecordOperations recordOps = new RecordOperationsImpl(mockClient, testZone, TEST_SLD, types);
|
||||||
|
List<RecordEntity> result = recordOps.get();
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(1, result.size());
|
||||||
|
verify(mockClient, times(1)).recordList(eq(testZone), eq(TEST_SLD), eq(types));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordOperations_Create() throws CloudflareApiException {
|
||||||
|
RecordEntity createdRecord = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
createdRecord.setId(TEST_RECORD_ID);
|
||||||
|
|
||||||
|
when(mockClient.recordCreateSld(eq(testZone), eq(TEST_SLD), eq(300), eq(RecordType.A), eq("1.2.3.4")))
|
||||||
|
.thenReturn(createdRecord);
|
||||||
|
|
||||||
|
RecordOperations recordOps = new RecordOperationsImpl(mockClient, testZone, TEST_SLD, null);
|
||||||
|
RecordEntity result = recordOps.create(RecordType.A, "1.2.3.4", 300);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(TEST_RECORD_ID, result.getId());
|
||||||
|
assertEquals("1.2.3.4", result.getContent());
|
||||||
|
verify(mockClient, times(1)).recordCreateSld(eq(testZone), eq(TEST_SLD), eq(300), eq(RecordType.A), eq("1.2.3.4"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordOperations_Update_Success() throws CloudflareApiException {
|
||||||
|
RecordEntity existingRecord = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
existingRecord.setId(TEST_RECORD_ID);
|
||||||
|
|
||||||
|
RecordEntity updatedRecord = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.5");
|
||||||
|
updatedRecord.setId(TEST_RECORD_ID);
|
||||||
|
|
||||||
|
when(mockClient.recordList(eq(testZone), eq(TEST_SLD), any()))
|
||||||
|
.thenReturn(List.of(existingRecord));
|
||||||
|
when(mockClient.recordUpdate(eq(testZone), any(RecordEntity.class)))
|
||||||
|
.thenReturn(updatedRecord);
|
||||||
|
|
||||||
|
RecordOperations recordOps = new RecordOperationsImpl(mockClient, testZone, TEST_SLD, null);
|
||||||
|
RecordEntity result = recordOps.update("1.2.3.5");
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals("1.2.3.5", result.getContent());
|
||||||
|
verify(mockClient, times(1)).recordList(eq(testZone), eq(TEST_SLD), any());
|
||||||
|
verify(mockClient, times(1)).recordUpdate(eq(testZone), any(RecordEntity.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordOperations_Update_NoRecordsFound() throws CloudflareApiException {
|
||||||
|
when(mockClient.recordList(eq(testZone), eq(TEST_SLD), any()))
|
||||||
|
.thenReturn(List.of());
|
||||||
|
|
||||||
|
RecordOperations recordOps = new RecordOperationsImpl(mockClient, testZone, TEST_SLD, null);
|
||||||
|
|
||||||
|
CloudflareApiException exception = assertThrows(CloudflareApiException.class, () -> {
|
||||||
|
recordOps.update("1.2.3.5");
|
||||||
|
});
|
||||||
|
|
||||||
|
assertTrue(exception.getMessage().contains("No recs found"));
|
||||||
|
verify(mockClient, times(1)).recordList(eq(testZone), eq(TEST_SLD), any());
|
||||||
|
verify(mockClient, never()).recordUpdate(any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordOperations_Update_MultipleRecordsFound() throws CloudflareApiException {
|
||||||
|
RecordEntity rec1 = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
RecordEntity rec2 = RecordEntity.build("test.example.com", RecordType.AAAA, 300, "::1");
|
||||||
|
|
||||||
|
when(mockClient.recordList(eq(testZone), eq(TEST_SLD), any()))
|
||||||
|
.thenReturn(List.of(rec1, rec2));
|
||||||
|
|
||||||
|
RecordOperations recordOps = new RecordOperationsImpl(mockClient, testZone, TEST_SLD, null);
|
||||||
|
|
||||||
|
CloudflareApiException exception = assertThrows(CloudflareApiException.class, () -> {
|
||||||
|
recordOps.update("1.2.3.5");
|
||||||
|
});
|
||||||
|
|
||||||
|
assertTrue(exception.getMessage().contains("Multiple recs found"));
|
||||||
|
verify(mockClient, times(1)).recordList(eq(testZone), eq(TEST_SLD), any());
|
||||||
|
verify(mockClient, never()).recordUpdate(any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordOperations_Delete() throws CloudflareApiException {
|
||||||
|
doNothing().when(mockClient).recordDeleteTypeIfExists(eq(testZone), eq(TEST_SLD), any(RecordType[].class));
|
||||||
|
|
||||||
|
RecordOperations recordOps = new RecordOperationsImpl(mockClient, testZone, TEST_SLD, null);
|
||||||
|
recordOps.delete(RecordType.A, RecordType.AAAA);
|
||||||
|
|
||||||
|
verify(mockClient, times(1)).recordDeleteTypeIfExists(eq(testZone), eq(TEST_SLD), any(RecordType[].class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRecordOperations_DeleteSingleType() throws CloudflareApiException {
|
||||||
|
doNothing().when(mockClient).recordDeleteTypeIfExists(eq(testZone), eq(TEST_SLD), any(RecordType[].class));
|
||||||
|
|
||||||
|
RecordOperations recordOps = new RecordOperationsImpl(mockClient, testZone, TEST_SLD, null);
|
||||||
|
recordOps.delete(RecordType.A);
|
||||||
|
|
||||||
|
verify(mockClient, times(1)).recordDeleteTypeIfExists(eq(testZone), eq(TEST_SLD), any(RecordType[].class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFluentApiChaining() throws CloudflareApiException {
|
||||||
|
// Test that fluent API chaining works correctly
|
||||||
|
RecordEntity createdRecord = RecordEntity.build("test.example.com", RecordType.A, 300, "1.2.3.4");
|
||||||
|
createdRecord.setId(TEST_RECORD_ID);
|
||||||
|
|
||||||
|
when(mockClient.recordCreateSld(eq(testZone), eq(TEST_SLD), eq(300), eq(RecordType.A), eq("1.2.3.4")))
|
||||||
|
.thenReturn(createdRecord);
|
||||||
|
|
||||||
|
ZoneOperations zoneOps = new ZoneOperationsImpl(mockClient, testZone);
|
||||||
|
RecordEntity result = zoneOps.getRecord(TEST_SLD).create(RecordType.A, "1.2.3.4", 300);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(TEST_RECORD_ID, result.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testConstructorFields() {
|
||||||
|
// Test that constructor properly initializes fields
|
||||||
|
RecordType[] types = {RecordType.A, RecordType.AAAA};
|
||||||
|
RecordOperationsImpl recordOps = new RecordOperationsImpl(mockClient, testZone, TEST_SLD, types);
|
||||||
|
|
||||||
|
assertNotNull(recordOps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testZoneOperationsImplConstructor() {
|
||||||
|
ZoneOperationsImpl zoneOps = new ZoneOperationsImpl(mockClient, testZone);
|
||||||
|
|
||||||
|
assertNotNull(zoneOps);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user