From 4075eb78c8e2d20b6a24029249284cf02d1368b3 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 26 Oct 2025 20:30:01 +0530 Subject: [PATCH] ISSUE-44: Hithomelabs/HomeLabDocker#44 Adding unit tests for service layer --- .../Controllers/TunnelControllerTest.java | 98 +++++-------------- .../Services/CloudflareAPIServiceTest.java | 64 +++++++++++- .../hithomelabs/CFTunnels/TestUtils/Util.java | 17 ++++ .../data/tunnelResponseLargeIngress.json | 38 +++++++ .../data/tunnelResponseSmallIngress.json | 33 +++++++ 5 files changed, 174 insertions(+), 76 deletions(-) create mode 100644 src/test/java/com/hithomelabs/CFTunnels/TestUtils/Util.java create mode 100644 src/test/resources/data/tunnelResponseLargeIngress.json create mode 100644 src/test/resources/data/tunnelResponseSmallIngress.json diff --git a/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java b/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java index ac85244..644288e 100644 --- a/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java +++ b/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java @@ -24,9 +24,11 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.web.client.RestTemplate; +import java.io.IOException; import java.time.Instant; import java.util.*; +import static com.hithomelabs.CFTunnels.TestUtils.Util.getClassPathDataResource; import static org.hamcrest.core.IsIterableContaining.hasItem; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -64,82 +66,28 @@ class TunnelControllerTest { @MockitoBean RestTemplateConfig restTemplateConfig; - private static String withAdditionalIngress = """ - { - "success": true, - "errors": [], - "messages": [], - "result": { - "tunnel_id": "50df9101-f625-4618-b7c5-100338a57124", - "version": 63, - "config": { - "ingress": [ - { - "service": "http://192.168.0.100:8928", - "hostname": "giteabkp.hithomelabs.com", - "originRequest": {} - }, - { - "service": "https://192.168.0.100:9442", - "hostname": "devdocker.hithomelabs.com", - "originRequest": { - "noTLSVerify": true - } - }, - { - "service": "http://192.168.0.100:3457", - "hostname": "random.hithomelabs.com", - "originRequest": {} - }, - { - "service": "http_status:404" - } - ], - "warp-routing": { - "enabled": false - } - }, - "source": "cloudflare", - "created_at": "2025-10-24T18:17:26.914217Z" - } - } - """; + private static final String tunnelResponseSmallIngressFile = "tunnelResponseSmallIngress.json"; - private static final String withoutAdditionalIngress = """ - { - "success": true, - "errors": [], - "messages": [], - "result": { - "tunnel_id": "50df9101-f625-4618-b7c5-100338a57124", - "version": 63, - "config": { - "ingress": [ - { - "service": "http://192.168.0.100:8928", - "hostname": "giteabkp.hithomelabs.com", - "originRequest": {} - }, - { - "service": "https://192.168.0.100:9442", - "hostname": "devdocker.hithomelabs.com", - "originRequest": { - "noTLSVerify": true - } - }, - { - "service": "http_status:404" - } - ], - "warp-routing": { - "enabled": false - } - }, - "source": "cloudflare", - "created_at": "2025-10-24T18:17:26.914217Z" - } - } - """; + private static final String tunnelResponseLargeIngressFile = "tunnelResponseLargeIngress.json"; + + private static final String withAdditionalIngress; + + static { + try { + withAdditionalIngress = getClassPathDataResource(tunnelResponseLargeIngressFile); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static final String withoutAdditionalIngress; + static { + try { + withoutAdditionalIngress = getClassPathDataResource(tunnelResponseSmallIngressFile); + } catch (IOException e) { + throw new RuntimeException(e); + } + } private static final String ingressJson = """ { diff --git a/src/test/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIServiceTest.java b/src/test/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIServiceTest.java index dbafc60..03374e5 100644 --- a/src/test/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIServiceTest.java +++ b/src/test/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIServiceTest.java @@ -1,7 +1,11 @@ package com.hithomelabs.CFTunnels.Services; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.hithomelabs.CFTunnels.Config.CloudflareConfig; import com.hithomelabs.CFTunnels.Headers.AuthKeyEmailHeader; +import com.hithomelabs.CFTunnels.Models.Config; +import com.hithomelabs.CFTunnels.Models.TunnelResponse; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -9,9 +13,12 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.http.*; import org.springframework.web.client.RestTemplate; + +import java.io.IOException; import java.util.List; import java.util.Map; +import static com.hithomelabs.CFTunnels.TestUtils.Util.getClassPathDataResource; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -32,6 +39,18 @@ class CloudflareAPIServiceTest { @Mock CloudflareConfig cloudflareConfig; + private static final String tunnelResponseLargeIngressFile = "tunnelResponseLargeIngress.json"; + + private static final String bigTunnelResponse; + + static { + try { + bigTunnelResponse = getClassPathDataResource(tunnelResponseLargeIngressFile); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + @Test void testGetCloudflareTunnels() { @@ -52,4 +71,47 @@ class CloudflareAPIServiceTest { } - } \ No newline at end of file + @Test + void getCloudflareTunnelConfigurations() throws JsonProcessingException { + + when(cloudflareConfig.getAccountId()).thenReturn("account-123"); + when(authKeyEmailHeader.getHttpHeaders()).thenReturn(new HttpHeaders()); + + TunnelResponse tunnelResponse = new ObjectMapper().readValue(bigTunnelResponse, TunnelResponse.class); + ResponseEntity tunnelResponseResponseEntity = new ResponseEntity<>(tunnelResponse, HttpStatus.OK); + + when(restTemplate.exchange( + any(String.class), + eq(HttpMethod.GET), + any(HttpEntity.class), + eq(TunnelResponse.class) + )).thenReturn(tunnelResponseResponseEntity); + + ResponseEntity response = cloudflareAPIService.getCloudflareTunnelConfigurations("sampleTunnelID", restTemplate, TunnelResponse.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals(response.getBody().getResult().getConfig().getIngress().get(0).getHostname(), "giteabkp.hithomelabs.com"); + } + + @Test + void putCloudflareTunnelConfigurations() throws JsonProcessingException { + + when(cloudflareConfig.getAccountId()).thenReturn("account-123"); + when(authKeyEmailHeader.getHttpHeaders()).thenReturn(new HttpHeaders()); + + TunnelResponse tunnelResponse = new ObjectMapper().readValue(bigTunnelResponse, TunnelResponse.class); + ResponseEntity tunnelResponseResponseEntity = new ResponseEntity<>(tunnelResponse, HttpStatus.OK); + + Config config = tunnelResponse.getResult().getConfig(); + + when(restTemplate.exchange( + any(String.class), + eq(HttpMethod.PUT), + any(HttpEntity.class), + eq(TunnelResponse.class) + )).thenReturn(tunnelResponseResponseEntity); + + ResponseEntity response = cloudflareAPIService.putCloudflareTunnelConfigurations("sampleTunnelID", restTemplate, TunnelResponse.class, config); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals(response.getBody().getResult().getConfig().getIngress().get(2).getHostname(), "random.hithomelabs.com"); + } +} \ No newline at end of file diff --git a/src/test/java/com/hithomelabs/CFTunnels/TestUtils/Util.java b/src/test/java/com/hithomelabs/CFTunnels/TestUtils/Util.java new file mode 100644 index 0000000..a5f8c36 --- /dev/null +++ b/src/test/java/com/hithomelabs/CFTunnels/TestUtils/Util.java @@ -0,0 +1,17 @@ +package com.hithomelabs.CFTunnels.TestUtils; + +import org.springframework.core.io.ClassPathResource; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; + +public class Util { + + public static String getClassPathDataResource(String filename) throws IOException { + return Files.readString( + new ClassPathResource(String.format("data/%s", filename)).getFile().toPath(), + StandardCharsets.UTF_8); + } + +} diff --git a/src/test/resources/data/tunnelResponseLargeIngress.json b/src/test/resources/data/tunnelResponseLargeIngress.json new file mode 100644 index 0000000..e24b930 --- /dev/null +++ b/src/test/resources/data/tunnelResponseLargeIngress.json @@ -0,0 +1,38 @@ +{ + "success": true, + "errors": [], + "messages": [], + "result": { + "tunnel_id": "50df9101-f625-4618-b7c5-100338a57124", + "version": 63, + "config": { + "ingress": [ + { + "service": "http://192.168.0.100:8928", + "hostname": "giteabkp.hithomelabs.com", + "originRequest": {} + }, + { + "service": "https://192.168.0.100:9442", + "hostname": "devdocker.hithomelabs.com", + "originRequest": { + "noTLSVerify": true + } + }, + { + "service": "http://192.168.0.100:3457", + "hostname": "random.hithomelabs.com", + "originRequest": {} + }, + { + "service": "http_status:404" + } + ], + "warp-routing": { + "enabled": false + } + }, + "source": "cloudflare", + "created_at": "2025-10-24T18:17:26.914217Z" + } +} \ No newline at end of file diff --git a/src/test/resources/data/tunnelResponseSmallIngress.json b/src/test/resources/data/tunnelResponseSmallIngress.json new file mode 100644 index 0000000..9e840f0 --- /dev/null +++ b/src/test/resources/data/tunnelResponseSmallIngress.json @@ -0,0 +1,33 @@ +{ + "success": true, + "errors": [], + "messages": [], + "result": { + "tunnel_id": "50df9101-f625-4618-b7c5-100338a57124", + "version": 63, + "config": { + "ingress": [ + { + "service": "http://192.168.0.100:8928", + "hostname": "giteabkp.hithomelabs.com", + "originRequest": {} + }, + { + "service": "https://192.168.0.100:9442", + "hostname": "devdocker.hithomelabs.com", + "originRequest": { + "noTLSVerify": true + } + }, + { + "service": "http_status:404" + } + ], + "warp-routing": { + "enabled": false + } + }, + "source": "cloudflare", + "created_at": "2025-10-24T18:17:26.914217Z" + } +} \ No newline at end of file