265 lines
11 KiB
Java
265 lines
11 KiB
Java
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.Entity.Tunnel;
|
|
import com.hithomelabs.cftunnels.Exceptions.ExternalServiceException;
|
|
import com.hithomelabs.cftunnels.Headers.AuthKeyEmailHeader;
|
|
import com.hithomelabs.cftunnels.Models.Config;
|
|
import com.hithomelabs.cftunnels.Models.Ingress;
|
|
import com.hithomelabs.cftunnels.Models.TunnelResponse;
|
|
import com.hithomelabs.cftunnels.Models.TunnelResult;
|
|
import com.hithomelabs.cftunnels.Models.TunnelsResponse;
|
|
import com.hithomelabs.cftunnels.Repositories.TunnelRepository;
|
|
import org.junit.jupiter.api.Test;
|
|
import org.junit.jupiter.api.extension.ExtendWith;
|
|
import org.mockito.InjectMocks;
|
|
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.NoSuchElementException;
|
|
import java.util.Optional;
|
|
import java.util.UUID;
|
|
|
|
import static com.hithomelabs.cftunnels.TestUtils.Util.getClassPathDataResource;
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
import static org.mockito.ArgumentMatchers.any;
|
|
import static org.mockito.ArgumentMatchers.eq;
|
|
import static org.mockito.Mockito.verify;
|
|
import static org.mockito.Mockito.when;
|
|
|
|
@ExtendWith(MockitoExtension.class)
|
|
class CloudflareAPIServiceTest {
|
|
|
|
@InjectMocks
|
|
private CloudflareAPIService cloudflareAPIService;
|
|
|
|
@Mock
|
|
AuthKeyEmailHeader authKeyEmailHeader;
|
|
|
|
@Mock
|
|
private RestTemplate restTemplate;
|
|
|
|
@Mock
|
|
CloudflareConfig cloudflareConfig;
|
|
|
|
@Mock
|
|
TunnelRepository tunnelRepository;
|
|
|
|
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() {
|
|
|
|
when(cloudflareConfig.getAccountId()).thenReturn("account-123");
|
|
when(authKeyEmailHeader.getHttpHeaders()).thenReturn(new HttpHeaders());
|
|
List<TunnelResult> tunnelResults = List.of(new TunnelResult("t1", "test-tunnel"));
|
|
TunnelsResponse mockBody = new TunnelsResponse(tunnelResults, null, null, true);
|
|
ResponseEntity<TunnelsResponse> mockResponse = new ResponseEntity<>(mockBody, HttpStatus.OK);
|
|
|
|
when(restTemplate.exchange(
|
|
any(String.class),
|
|
eq(HttpMethod.GET),
|
|
any(HttpEntity.class),
|
|
eq(TunnelsResponse.class)
|
|
)).thenReturn(mockResponse);
|
|
|
|
ResponseEntity<TunnelsResponse> response = cloudflareAPIService.getCloudflareTunnels();
|
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
|
}
|
|
|
|
|
|
@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<TunnelResponse> tunnelResponseResponseEntity = new ResponseEntity<>(tunnelResponse, HttpStatus.OK);
|
|
|
|
when(restTemplate.exchange(
|
|
any(String.class),
|
|
eq(HttpMethod.GET),
|
|
any(HttpEntity.class),
|
|
eq(TunnelResponse.class)
|
|
)).thenReturn(tunnelResponseResponseEntity);
|
|
|
|
ResponseEntity<TunnelResponse> 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<TunnelResponse> 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<TunnelResponse> 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");
|
|
}
|
|
|
|
@Test
|
|
void createOrUpdateTunnel_Success() {
|
|
String tunnelId = "50df9101-f625-4618-b7c5-100338a57124";
|
|
String environment = "dev";
|
|
|
|
List<TunnelResult> tunnelResults = List.of(new TunnelResult(tunnelId, "devtunnel"));
|
|
TunnelsResponse mockBody = new TunnelsResponse(tunnelResults, null, null, true);
|
|
ResponseEntity<TunnelsResponse> mockResponse = new ResponseEntity<>(mockBody, HttpStatus.OK);
|
|
|
|
when(restTemplate.exchange(
|
|
any(String.class),
|
|
eq(HttpMethod.GET),
|
|
any(HttpEntity.class),
|
|
eq(TunnelsResponse.class)
|
|
)).thenReturn(mockResponse);
|
|
|
|
when(tunnelRepository.findById(UUID.fromString(tunnelId))).thenReturn(Optional.empty());
|
|
|
|
Tunnel result = cloudflareAPIService.createOrUpdateTunnel(tunnelId, environment);
|
|
|
|
assertEquals(UUID.fromString(tunnelId), result.getId());
|
|
assertEquals("devtunnel", result.getName());
|
|
assertEquals(environment, result.getEnvironment());
|
|
verify(tunnelRepository).save(any(Tunnel.class));
|
|
}
|
|
|
|
@Test
|
|
void createOrUpdateTunnel_UpdatesExistingTunnel() {
|
|
String tunnelId = "50df9101-f625-4618-b7c5-100338a57124";
|
|
String environment = "prod";
|
|
|
|
List<TunnelResult> tunnelResults = List.of(new TunnelResult(tunnelId, "devtunnel"));
|
|
TunnelsResponse mockBody = new TunnelsResponse(tunnelResults, null, null, true);
|
|
ResponseEntity<TunnelsResponse> mockResponse = new ResponseEntity<>(mockBody, HttpStatus.OK);
|
|
|
|
when(restTemplate.exchange(
|
|
any(String.class),
|
|
eq(HttpMethod.GET),
|
|
any(HttpEntity.class),
|
|
eq(TunnelsResponse.class)
|
|
)).thenReturn(mockResponse);
|
|
|
|
Tunnel existingTunnel = new Tunnel(UUID.fromString(tunnelId), "dev", "oldname");
|
|
when(tunnelRepository.findById(UUID.fromString(tunnelId))).thenReturn(Optional.of(existingTunnel));
|
|
|
|
cloudflareAPIService.createOrUpdateTunnel(tunnelId, environment);
|
|
|
|
verify(tunnelRepository).deleteById(UUID.fromString(tunnelId));
|
|
verify(tunnelRepository).save(any(Tunnel.class));
|
|
}
|
|
|
|
@Test
|
|
void createOrUpdateTunnel_ThrowsExternalServiceExceptionOnApiError() {
|
|
String tunnelId = "50df9101-f625-4618-b7c5-100338a57124";
|
|
|
|
ResponseEntity<TunnelsResponse> mockResponse = new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
|
|
|
|
when(restTemplate.exchange(
|
|
any(String.class),
|
|
eq(HttpMethod.GET),
|
|
any(HttpEntity.class),
|
|
eq(TunnelsResponse.class)
|
|
)).thenReturn(mockResponse);
|
|
|
|
assertThrows(ExternalServiceException.class, () ->
|
|
cloudflareAPIService.createOrUpdateTunnel(tunnelId, "dev")
|
|
);
|
|
}
|
|
|
|
@Test
|
|
void createOrUpdateTunnel_ThrowsNoSuchElementExceptionWhenTunnelNotFound() {
|
|
String tunnelId = "50df9101-f625-4618-b7c5-100338a57124";
|
|
|
|
List<TunnelResult> tunnelResults = List.of(new TunnelResult("other-tunnel-id", "othertunnel"));
|
|
TunnelsResponse mockBody = new TunnelsResponse(tunnelResults, null, null, true);
|
|
ResponseEntity<TunnelsResponse> mockResponse = new ResponseEntity<>(mockBody, HttpStatus.OK);
|
|
|
|
when(restTemplate.exchange(
|
|
any(String.class),
|
|
eq(HttpMethod.GET),
|
|
any(HttpEntity.class),
|
|
eq(TunnelsResponse.class)
|
|
)).thenReturn(mockResponse);
|
|
|
|
assertThrows(NoSuchElementException.class, () ->
|
|
cloudflareAPIService.createOrUpdateTunnel(tunnelId, "dev")
|
|
);
|
|
}
|
|
|
|
@Test
|
|
void getAllConfiguredTunnels_ReturnsAllTunnels() {
|
|
List<Tunnel> tunnels = List.of(
|
|
new Tunnel(UUID.fromString("50df9101-f625-4618-b7c5-100338a57124"), "dev", "devtunnel"),
|
|
new Tunnel(UUID.fromString("60df9101-f625-4618-b7c5-100338a57125"), "prod", "prodtunnel")
|
|
);
|
|
when(tunnelRepository.findAll()).thenReturn(tunnels);
|
|
|
|
List<Tunnel> result = cloudflareAPIService.getAllConfiguredTunnels();
|
|
|
|
assertEquals(2, result.size());
|
|
assertEquals("devtunnel", result.get(0).getName());
|
|
assertEquals("prodtunnel", result.get(1).getName());
|
|
}
|
|
|
|
@Test
|
|
void addTunnelIngress_Success() throws JsonProcessingException {
|
|
String tunnelId = "50df9101-f625-4618-b7c5-100338a57124";
|
|
Ingress ingress = new Ingress("http://192.168.0.100:8080", "test.hithomelabs.com", null, null);
|
|
|
|
when(cloudflareConfig.getAccountId()).thenReturn("account-123");
|
|
when(authKeyEmailHeader.getHttpHeaders()).thenReturn(new HttpHeaders());
|
|
|
|
TunnelResponse tunnelResponse = new ObjectMapper().readValue(bigTunnelResponse, TunnelResponse.class);
|
|
ResponseEntity<TunnelResponse> getResponse = new ResponseEntity<>(tunnelResponse, HttpStatus.OK);
|
|
when(restTemplate.exchange(
|
|
any(String.class),
|
|
eq(HttpMethod.GET),
|
|
any(HttpEntity.class),
|
|
eq(TunnelResponse.class)
|
|
)).thenReturn(getResponse);
|
|
|
|
ResponseEntity<TunnelResponse> putResponse = new ResponseEntity<>(tunnelResponse, HttpStatus.OK);
|
|
when(restTemplate.exchange(
|
|
any(String.class),
|
|
eq(HttpMethod.PUT),
|
|
any(HttpEntity.class),
|
|
eq(TunnelResponse.class)
|
|
)).thenReturn(putResponse);
|
|
|
|
ResponseEntity<TunnelResponse> result = cloudflareAPIService.addTunnelIngress(tunnelId, ingress);
|
|
|
|
assertEquals(HttpStatus.OK, result.getStatusCode());
|
|
}
|
|
} |