Skip to content

Commit fc80fc7

Browse files
committed
add more unit test coverage
1 parent 5ff6419 commit fc80fc7

File tree

2 files changed

+304
-3
lines changed

2 files changed

+304
-3
lines changed

src/main/java/com/datastax/cdm/data/AstraDevOpsClient.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,7 @@ private String extractDownloadUrl(String jsonResponse, String scbType, PKFactory
284284

285285
if (rootNode.has("customDomainBundles") && rootNode.get("customDomainBundles").isArray()) {
286286
for (JsonNode customNode : rootNode.get("customDomainBundles")) {
287-
if (customNode.has("sniDomain")
288-
&& customDomain.equalsIgnoreCase(customNode.get("sniDomain").asText())
287+
if (customNode.has("domain") && customDomain.equalsIgnoreCase(customNode.get("domain").asText())
289288
&& customNode.has("downloadURL")) {
290289

291290
return customNode.get("downloadURL").asText();

src/test/java/com/datastax/cdm/data/AstraDevOpsClientTest.java

Lines changed: 303 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,20 @@
1818
import static org.junit.jupiter.api.Assertions.*;
1919
import static org.mockito.Mockito.*;
2020

21+
import java.io.ByteArrayInputStream;
2122
import java.io.IOException;
23+
import java.io.InputStream;
2224
import java.lang.reflect.Field;
2325
import java.lang.reflect.Method;
26+
import java.net.URI;
2427
import java.net.http.HttpClient;
28+
import java.net.http.HttpRequest;
2529
import java.net.http.HttpResponse;
2630

2731
import org.junit.jupiter.api.BeforeEach;
2832
import org.junit.jupiter.api.Test;
2933
import org.junit.jupiter.api.extension.ExtendWith;
34+
import org.mockito.ArgumentCaptor;
3035
import org.mockito.Mock;
3136
import org.mockito.junit.jupiter.MockitoExtension;
3237

@@ -46,6 +51,9 @@ class AstraDevOpsClientTest {
4651
@Mock
4752
private HttpResponse<String> httpResponse;
4853

54+
@Mock
55+
private HttpResponse<InputStream> httpResponseStream;
56+
4957
private AstraDevOpsClient client;
5058

5159
@BeforeEach
@@ -197,5 +205,299 @@ void testExtractDownloadUrlDefaultType() throws Exception {
197205
assertEquals("https://example.com/bundle.zip", url);
198206
}
199207

200-
// More tests for extractDownloadUrl with different SCB types can be added here
208+
@Test
209+
void testExtractDownloadUrlRegionType() throws Exception {
210+
// Setup
211+
String jsonResponse = "{ \"downloadURLs\": ["
212+
+ "{ \"region\": \"us-east-1\", \"downloadURL\": \"https://us-east-1.example.com/bundle.zip\" },"
213+
+ "{ \"region\": \"us-west-2\", \"downloadURL\": \"https://us-west-2.example.com/bundle.zip\" },"
214+
+ "{ \"region\": \"eu-central-1\", \"downloadURL\": \"https://eu-central-1.example.com/bundle.zip\" }"
215+
+ "]}";
216+
217+
when(propertyHelper.getAsString(KnownProperties.ORIGIN_ASTRA_SCB_REGION)).thenReturn("us-west-2");
218+
219+
// Use reflection to access the private method
220+
Method extractDownloadUrlMethod = AstraDevOpsClient.class.getDeclaredMethod("extractDownloadUrl", String.class,
221+
String.class, PKFactory.Side.class);
222+
extractDownloadUrlMethod.setAccessible(true);
223+
224+
// Test
225+
String url = (String) extractDownloadUrlMethod.invoke(client, jsonResponse, "region", PKFactory.Side.ORIGIN);
226+
227+
// Verify
228+
assertEquals("https://us-west-2.example.com/bundle.zip", url);
229+
}
230+
231+
@Test
232+
void testExtractDownloadUrlRegionTypeWithMissingRegion() throws Exception {
233+
// Setup
234+
String jsonResponse = "{ \"downloadURLs\": ["
235+
+ "{ \"region\": \"us-east-1\", \"downloadURL\": \"https://us-east-1.example.com/bundle.zip\" },"
236+
+ "{ \"region\": \"us-west-2\", \"downloadURL\": \"https://us-west-2.example.com/bundle.zip\" }" + "]}";
237+
238+
when(propertyHelper.getAsString(KnownProperties.ORIGIN_ASTRA_SCB_REGION)).thenReturn(null);
239+
240+
// Use reflection to access the private method
241+
Method extractDownloadUrlMethod = AstraDevOpsClient.class.getDeclaredMethod("extractDownloadUrl", String.class,
242+
String.class, PKFactory.Side.class);
243+
extractDownloadUrlMethod.setAccessible(true);
244+
245+
// Test
246+
String url = (String) extractDownloadUrlMethod.invoke(client, jsonResponse, "region", PKFactory.Side.ORIGIN);
247+
248+
// Verify
249+
assertNull(url);
250+
}
251+
252+
@Test
253+
void testExtractDownloadUrlRegionTypeWithNoMatchingRegion() throws Exception {
254+
// Setup
255+
String jsonResponse = "{ \"downloadURLs\": ["
256+
+ "{ \"region\": \"us-east-1\", \"downloadURL\": \"https://us-east-1.example.com/bundle.zip\" },"
257+
+ "{ \"region\": \"us-west-2\", \"downloadURL\": \"https://us-west-2.example.com/bundle.zip\" }" + "]}";
258+
259+
when(propertyHelper.getAsString(KnownProperties.ORIGIN_ASTRA_SCB_REGION)).thenReturn("ap-south-1");
260+
261+
// Use reflection to access the private method
262+
Method extractDownloadUrlMethod = AstraDevOpsClient.class.getDeclaredMethod("extractDownloadUrl", String.class,
263+
String.class, PKFactory.Side.class);
264+
extractDownloadUrlMethod.setAccessible(true);
265+
266+
// Test
267+
String url = (String) extractDownloadUrlMethod.invoke(client, jsonResponse, "region", PKFactory.Side.ORIGIN);
268+
269+
// Verify
270+
assertNull(url);
271+
}
272+
273+
@Test
274+
void testExtractDownloadUrlCustomDomainType() throws Exception {
275+
// Setup
276+
String jsonResponse = "{ \"customDomainBundles\": ["
277+
+ "{ \"domain\": \"db1.example.com\", \"downloadURL\": \"https://db1.example.com/bundle.zip\" },"
278+
+ "{ \"domain\": \"db2.example.com\", \"downloadURL\": \"https://db2.example.com/bundle.zip\" }" + "]}";
279+
280+
when(propertyHelper.getAsString(KnownProperties.TARGET_ASTRA_SCB_CUSTOM_DOMAIN)).thenReturn("db2.example.com");
281+
282+
// Use reflection to access the private method
283+
Method extractDownloadUrlMethod = AstraDevOpsClient.class.getDeclaredMethod("extractDownloadUrl", String.class,
284+
String.class, PKFactory.Side.class);
285+
extractDownloadUrlMethod.setAccessible(true);
286+
287+
// Test
288+
String url = (String) extractDownloadUrlMethod.invoke(client, jsonResponse, "custom", PKFactory.Side.TARGET);
289+
290+
// Verify
291+
assertEquals("https://db2.example.com/bundle.zip", url);
292+
}
293+
294+
@Test
295+
void testExtractDownloadUrlCustomDomainTypeWithMissingDomain() throws Exception {
296+
// Setup
297+
String jsonResponse = "{ \"customDomainBundles\": ["
298+
+ "{ \"domain\": \"db1.example.com\", \"downloadURL\": \"https://db1.example.com/bundle.zip\" },"
299+
+ "{ \"domain\": \"db2.example.com\", \"downloadURL\": \"https://db2.example.com/bundle.zip\" }" + "]}";
300+
301+
when(propertyHelper.getAsString(KnownProperties.TARGET_ASTRA_SCB_CUSTOM_DOMAIN)).thenReturn(null);
302+
303+
// Use reflection to access the private method
304+
Method extractDownloadUrlMethod = AstraDevOpsClient.class.getDeclaredMethod("extractDownloadUrl", String.class,
305+
String.class, PKFactory.Side.class);
306+
extractDownloadUrlMethod.setAccessible(true);
307+
308+
// Test
309+
String url = (String) extractDownloadUrlMethod.invoke(client, jsonResponse, "custom", PKFactory.Side.TARGET);
310+
311+
// Verify
312+
assertNull(url);
313+
}
314+
315+
@Test
316+
void testExtractDownloadUrlUnknownType() throws Exception {
317+
// Setup
318+
String jsonResponse = "{ \"downloadURL\": \"https://example.com/bundle.zip\" }";
319+
320+
// Use reflection to access the private method
321+
Method extractDownloadUrlMethod = AstraDevOpsClient.class.getDeclaredMethod("extractDownloadUrl", String.class,
322+
String.class, PKFactory.Side.class);
323+
extractDownloadUrlMethod.setAccessible(true);
324+
325+
// Test
326+
String url = (String) extractDownloadUrlMethod.invoke(client, jsonResponse, "unknown", PKFactory.Side.ORIGIN);
327+
328+
// Verify
329+
assertNull(url);
330+
}
331+
332+
@Test
333+
void testFetchSecureBundleUrlInfo() throws Exception {
334+
// Mock the HTTP response
335+
when(httpResponse.statusCode()).thenReturn(200);
336+
when(httpResponse.body()).thenReturn("{ \"downloadURL\": \"https://example.com/bundle.zip\" }");
337+
338+
// Mock the HTTP client to return our mocked response
339+
when(httpClient.send(any(), eq(HttpResponse.BodyHandlers.ofString()))).thenReturn(httpResponse);
340+
341+
// Use reflection to access the private method
342+
Method fetchSecureBundleUrlInfoMethod = AstraDevOpsClient.class.getDeclaredMethod(
343+
"fetchSecureBundleUrlInfo", String.class, String.class, boolean.class);
344+
fetchSecureBundleUrlInfoMethod.setAccessible(true);
345+
346+
// Test
347+
String jsonResponse = (String) fetchSecureBundleUrlInfoMethod.invoke(client, "test-token", "test-db-id", false);
348+
349+
// Verify
350+
assertEquals("{ \"downloadURL\": \"https://example.com/bundle.zip\" }", jsonResponse);
351+
352+
// Verify the correct URL was used
353+
ArgumentCaptor<HttpRequest> requestCaptor = ArgumentCaptor.forClass(HttpRequest.class);
354+
verify(httpClient).send(requestCaptor.capture(), eq(HttpResponse.BodyHandlers.ofString()));
355+
356+
HttpRequest capturedRequest = requestCaptor.getValue();
357+
assertEquals(URI.create("https://api.astra.datastax.com/v2/databases/test-db-id/secureBundleURL"),
358+
capturedRequest.uri());
359+
assertTrue(capturedRequest.headers().firstValue("Authorization").isPresent());
360+
assertEquals("Bearer test-token", capturedRequest.headers().firstValue("Authorization").get());
361+
}
362+
363+
@Test
364+
void testFetchSecureBundleUrlInfoWithRegionalFlag() throws Exception {
365+
// Mock the HTTP response
366+
when(httpResponse.statusCode()).thenReturn(200);
367+
when(httpResponse.body()).thenReturn("{ \"downloadURLs\": [] }");
368+
369+
// Mock the HTTP client to return our mocked response
370+
when(httpClient.send(any(), eq(HttpResponse.BodyHandlers.ofString()))).thenReturn(httpResponse);
371+
372+
// Use reflection to access the private method
373+
Method fetchSecureBundleUrlInfoMethod = AstraDevOpsClient.class.getDeclaredMethod(
374+
"fetchSecureBundleUrlInfo", String.class, String.class, boolean.class);
375+
fetchSecureBundleUrlInfoMethod.setAccessible(true);
376+
377+
// Test
378+
String jsonResponse = (String) fetchSecureBundleUrlInfoMethod.invoke(client, "test-token", "test-db-id", true);
379+
380+
// Verify
381+
assertEquals("{ \"downloadURLs\": [] }", jsonResponse);
382+
383+
// Verify the correct URL was used with all=true parameter
384+
ArgumentCaptor<HttpRequest> requestCaptor = ArgumentCaptor.forClass(HttpRequest.class);
385+
verify(httpClient).send(requestCaptor.capture(), eq(HttpResponse.BodyHandlers.ofString()));
386+
387+
HttpRequest capturedRequest = requestCaptor.getValue();
388+
assertEquals(URI.create("https://api.astra.datastax.com/v2/databases/test-db-id/secureBundleURL?all=true"),
389+
capturedRequest.uri());
390+
}
391+
392+
@Test
393+
void testFetchSecureBundleUrlInfoError() throws Exception {
394+
// Mock the HTTP response for an error
395+
when(httpResponse.statusCode()).thenReturn(401);
396+
when(httpResponse.body()).thenReturn("{ \"error\": \"Unauthorized\" }");
397+
398+
// Mock the HTTP client to return our mocked response
399+
when(httpClient.send(any(), eq(HttpResponse.BodyHandlers.ofString()))).thenReturn(httpResponse);
400+
401+
// Use reflection to access the private method
402+
Method fetchSecureBundleUrlInfoMethod = AstraDevOpsClient.class.getDeclaredMethod(
403+
"fetchSecureBundleUrlInfo", String.class, String.class, boolean.class);
404+
fetchSecureBundleUrlInfoMethod.setAccessible(true);
405+
406+
// Test
407+
String jsonResponse = (String) fetchSecureBundleUrlInfoMethod.invoke(client, "invalid-token", "test-db-id", false);
408+
409+
// Verify
410+
assertNull(jsonResponse);
411+
}
412+
413+
@Test
414+
void testDownloadBundleFile() throws Exception {
415+
// Setup
416+
byte[] mockData = new byte[100]; // Mock some binary data
417+
ByteArrayInputStream inputStream = new ByteArrayInputStream(mockData);
418+
419+
// Mock the HTTP response
420+
when(httpResponseStream.statusCode()).thenReturn(200);
421+
when(httpResponseStream.body()).thenReturn(inputStream);
422+
423+
// Mock the HTTP client to return our mocked response
424+
when(httpClient.send(any(), eq(HttpResponse.BodyHandlers.ofInputStream()))).thenReturn(httpResponseStream);
425+
426+
// Use reflection to access the private method
427+
Method downloadBundleFileMethod = AstraDevOpsClient.class.getDeclaredMethod("downloadBundleFile", String.class,
428+
PKFactory.Side.class);
429+
downloadBundleFileMethod.setAccessible(true);
430+
431+
// Test
432+
String filePath = (String) downloadBundleFileMethod.invoke(client, "https://example.com/bundle.zip",
433+
PKFactory.Side.ORIGIN);
434+
435+
// Verify
436+
assertNotNull(filePath);
437+
assertTrue(filePath.contains("origin-secure-bundle.zip"));
438+
439+
// Verify the correct URL was used
440+
ArgumentCaptor<HttpRequest> requestCaptor = ArgumentCaptor.forClass(HttpRequest.class);
441+
verify(httpClient).send(requestCaptor.capture(), eq(HttpResponse.BodyHandlers.ofInputStream()));
442+
443+
HttpRequest capturedRequest = requestCaptor.getValue();
444+
assertEquals(URI.create("https://example.com/bundle.zip"), capturedRequest.uri());
445+
}
446+
447+
@Test
448+
void testDownloadBundleFileHttpError() throws Exception {
449+
// Setup
450+
451+
// Mock the HTTP response with an error status
452+
when(httpResponseStream.statusCode()).thenReturn(404);
453+
454+
// Mock the HTTP client to return our mocked response
455+
when(httpClient.send(any(), eq(HttpResponse.BodyHandlers.ofInputStream()))).thenReturn(httpResponseStream);
456+
457+
// Use reflection to access the private method
458+
Method downloadBundleFileMethod = AstraDevOpsClient.class.getDeclaredMethod(
459+
"downloadBundleFile", String.class, PKFactory.Side.class);
460+
downloadBundleFileMethod.setAccessible(true);
461+
462+
// Test and verify it throws IOException
463+
assertThrows(IOException.class, () -> {
464+
downloadBundleFileMethod.invoke(client, "https://example.com/not-found.zip", PKFactory.Side.ORIGIN);
465+
});
466+
}
467+
468+
@Test
469+
void testDownloadSecureBundleSuccess() throws Exception {
470+
// Setup - mock all the components for a successful download
471+
472+
// Step 1: Mock the API response for fetching the SCB URL
473+
when(httpResponse.statusCode()).thenReturn(200);
474+
when(httpResponse.body()).thenReturn("{ \"downloadURL\": \"https://example.com/bundle.zip\" }");
475+
476+
// Step 2: Mock the binary download
477+
byte[] mockData = new byte[100]; // Mock some binary data
478+
ByteArrayInputStream inputStream = new ByteArrayInputStream(mockData);
479+
480+
// Mock the HTTP response
481+
when(httpResponseStream.statusCode()).thenReturn(200);
482+
when(httpResponseStream.body()).thenReturn(inputStream);
483+
484+
// Configure the HTTP client to return appropriate responses for different requests
485+
when(httpClient.send(argThat(req -> req.method().equals("POST")), eq(HttpResponse.BodyHandlers.ofString())))
486+
.thenReturn(httpResponse);
487+
488+
when(httpClient.send(argThat(req -> req.method().equals("GET")), eq(HttpResponse.BodyHandlers.ofInputStream())))
489+
.thenReturn(httpResponseStream);
490+
491+
// Mock the property helper
492+
when(propertyHelper.getAsString(KnownProperties.ORIGIN_ASTRA_TOKEN)).thenReturn("test-token");
493+
when(propertyHelper.getAsString(KnownProperties.ORIGIN_ASTRA_DATABASE_ID)).thenReturn("test-db-id");
494+
when(propertyHelper.getAsString(KnownProperties.ORIGIN_ASTRA_SCB_TYPE)).thenReturn("default");
495+
496+
// Test
497+
String filePath = client.downloadSecureBundle(PKFactory.Side.ORIGIN);
498+
499+
// Verify
500+
assertNotNull(filePath);
501+
assertTrue(filePath.contains("origin-secure-bundle.zip"));
502+
}
201503
}

0 commit comments

Comments
 (0)