diff --git a/src/test/java/com/yashdotdev/distributed_traffic_control/policy/api/PolicyControllerIntegrationTest.java b/src/test/java/com/yashdotdev/distributed_traffic_control/policy/api/PolicyControllerIntegrationTest.java index 3ec55b6..41aa0f4 100644 --- a/src/test/java/com/yashdotdev/distributed_traffic_control/policy/api/PolicyControllerIntegrationTest.java +++ b/src/test/java/com/yashdotdev/distributed_traffic_control/policy/api/PolicyControllerIntegrationTest.java @@ -6,9 +6,12 @@ import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.*; +import org.springframework.web.util.UriComponentsBuilder; import java.time.Instant; +import java.util.List; import static org.junit.jupiter.api.Assertions.*; @@ -109,4 +112,154 @@ void shouldRejectInvalidPolicyThroughRealHttpEndpoint() throws Exception { ResponseEntity response = restTemplate.exchange(url, HttpMethod.POST, request, String.class); assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); } + + @Test + void shouldListPoliciesThroughRealHttpEndpoint() { + String resource = "/api/contract/list"; + + restTemplate.exchange( + baseUrl(), + HttpMethod.POST, + createRequest("list-policy", "List Policy", resource, 10), + PolicyResponse.class + ); + + ResponseEntity> response = + restTemplate.exchange( + baseUrl(), + HttpMethod.GET, + null, + new ParameterizedTypeReference<>() {} + ); + + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); + assertTrue(response.getBody().stream() + .anyMatch(policy -> resource.equals(policy.getResource()))); + } + + @Test + void shouldRetrievePolicyByResourceThroughRealHttpEndpoint() { + String resource = "/api/contract/read"; + + restTemplate.exchange( + baseUrl(), + HttpMethod.POST, + createRequest("read-policy", "Read Policy", resource, 20), + PolicyResponse.class + ); + + ResponseEntity response = + restTemplate.getForEntity( + policyUri(resource), + PolicyResponse.class + ); + + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); + assertEquals("read-policy", response.getBody().getPolicyId()); + assertEquals(resource, response.getBody().getResource()); + assertEquals(20, response.getBody().getCapacity()); + } + + @Test + void shouldReturnNotFoundForMissingPolicy() { + ResponseEntity response = + restTemplate.getForEntity( + policyUri("/api/contract/missing"), + String.class + ); + + assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode()); + } + + @Test + void shouldUpdatePolicyThroughRealHttpEndpoint() { + String resource = "/api/contract/update"; + + restTemplate.exchange( + baseUrl(), + HttpMethod.POST, + createRequest("update-policy", "Original Policy", resource, 10), + PolicyResponse.class + ); + + ResponseEntity response = + restTemplate.exchange( + policyUri(resource), + HttpMethod.PUT, + createRequest("update-policy", "Updated Policy", resource, 50), + PolicyResponse.class + ); + + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertNotNull(response.getBody()); + assertEquals("Updated Policy", response.getBody().getName()); + assertEquals(50, response.getBody().getCapacity()); + assertEquals(resource, response.getBody().getResource()); + } + + @Test + void shouldReturnNotFoundAfterDeletingPolicy() { + String resource = "/api/contract/delete"; + + restTemplate.exchange( + baseUrl(), + HttpMethod.POST, + createRequest("delete-policy-contract", "Delete Policy", resource, 10), + PolicyResponse.class + ); + + ResponseEntity deleteResponse = + restTemplate.exchange( + policyUri(resource), + HttpMethod.DELETE, + HttpEntity.EMPTY, + Void.class + ); + + assertEquals(HttpStatus.NO_CONTENT, deleteResponse.getStatusCode()); + + ResponseEntity getResponse = + restTemplate.getForEntity( + policyUri(resource), + String.class + ); + + assertEquals(HttpStatus.NOT_FOUND, getResponse.getStatusCode()); + } + + private String baseUrl() { + return "http://localhost:" + port + "/api/v1/policies"; + } + + private java.net.URI policyUri(String resource) { + return UriComponentsBuilder.fromUriString(baseUrl()) + .queryParam("resource", resource) + .build() + .encode() + .toUri(); + } + + private HttpEntity createRequest(String policyId, String name, String resource, long capacity) { + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + String body = """ + { + "policyId": "%s", + "name": "%s", + "type": "TOKEN_BUCKET", + "status": "ACTIVE", + "capacity": %d, + "refillRate": 1, + "windowDuration": null, + "createdAt": "2026-09-04T00:00:00Z", + "resource": "%s" + } + """.formatted(policyId, name, capacity, resource); + + return new HttpEntity<>(body, headers); + } } \ No newline at end of file