From 9a25495d9cf142fdc90d73255b6325b08fe06212 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 15 Feb 2026 21:24:32 +0530 Subject: [PATCH 1/3] Remove pagination and filtering from /requests endpoint --- CFTunnels/Get tunnels.bru | 11 - CFTunnels/Tunnel.bru | 11 - CFTunnels/Write ingress.bru | 19 -- CFTunnels/bruno.json | 9 - CFTunnels/delete mapping.bru | 19 -- CFTunnels/environments/CFTunnels Local.bru | 4 - CFTunnels/environments/CFTunnels.bru | 4 - .../Controllers/TunnelController.java | 21 +- .../CFTunnels/Models/PaginationRequest.java | 14 -- .../Services/MappingRequestService.java | 9 +- .../resources/application-local.properties | 2 + .../Controllers/TunnelControllerTest.java | 190 +----------------- 12 files changed, 19 insertions(+), 294 deletions(-) delete mode 100644 CFTunnels/Get tunnels.bru delete mode 100644 CFTunnels/Tunnel.bru delete mode 100644 CFTunnels/Write ingress.bru delete mode 100644 CFTunnels/bruno.json delete mode 100644 CFTunnels/delete mapping.bru delete mode 100644 CFTunnels/environments/CFTunnels Local.bru delete mode 100644 CFTunnels/environments/CFTunnels.bru delete mode 100644 src/main/java/com/hithomelabs/CFTunnels/Models/PaginationRequest.java diff --git a/CFTunnels/Get tunnels.bru b/CFTunnels/Get tunnels.bru deleted file mode 100644 index 231ee08..0000000 --- a/CFTunnels/Get tunnels.bru +++ /dev/null @@ -1,11 +0,0 @@ -meta { - name: Get tunnels - type: http - seq: 4 -} - -get { - url: {{base_url}}/cloudflare/tunnels - body: none - auth: none -} diff --git a/CFTunnels/Tunnel.bru b/CFTunnels/Tunnel.bru deleted file mode 100644 index 826b583..0000000 --- a/CFTunnels/Tunnel.bru +++ /dev/null @@ -1,11 +0,0 @@ -meta { - name: Tunnel - type: http - seq: 5 -} - -get { - url: {{base_url}}/cloudflare/tunnel/{{tunnel_id}} - body: none - auth: none -} diff --git a/CFTunnels/Write ingress.bru b/CFTunnels/Write ingress.bru deleted file mode 100644 index 9930a0b..0000000 --- a/CFTunnels/Write ingress.bru +++ /dev/null @@ -1,19 +0,0 @@ -meta { - name: Write ingress - type: http - seq: 2 -} - -put { - url: {{base_url}}/cloudflare/tunnel/{{tunnel_id}}/add - body: json - auth: none -} - -body:json { - { - "service": "http://192.168.0.100:3457", - "hostname": "random.hithomelabs.com", - "originRequest": {} - } -} diff --git a/CFTunnels/bruno.json b/CFTunnels/bruno.json deleted file mode 100644 index 16b8d6b..0000000 --- a/CFTunnels/bruno.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "version": "1", - "name": "CFTunnels", - "type": "collection", - "ignore": [ - "node_modules", - ".git" - ] -} \ No newline at end of file diff --git a/CFTunnels/delete mapping.bru b/CFTunnels/delete mapping.bru deleted file mode 100644 index c9e3dbb..0000000 --- a/CFTunnels/delete mapping.bru +++ /dev/null @@ -1,19 +0,0 @@ -meta { - name: delete mapping - type: http - seq: 3 -} - -put { - url: {{base_url}}/cloudflare/tunnel/{{tunnel_id}}/delete - body: json - auth: none -} - -body:json { - { - "service": "http://192.168.0.100:6000", - "hostname": "random.hithomelabs.com", - "originRequest": {} - } -} diff --git a/CFTunnels/environments/CFTunnels Local.bru b/CFTunnels/environments/CFTunnels Local.bru deleted file mode 100644 index 6d2b6b0..0000000 --- a/CFTunnels/environments/CFTunnels Local.bru +++ /dev/null @@ -1,4 +0,0 @@ -vars { - tunnel_id: 50df9101-f625-4618-b7c5-100338a57124 - base_url: http://localhost:8080 -} diff --git a/CFTunnels/environments/CFTunnels.bru b/CFTunnels/environments/CFTunnels.bru deleted file mode 100644 index d8219ab..0000000 --- a/CFTunnels/environments/CFTunnels.bru +++ /dev/null @@ -1,4 +0,0 @@ -vars { - tunnel_id: 50df9101-f625-4618-b7c5-100338a57124 - base_url: https://testcf.hithomelabs.com -} diff --git a/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java b/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java index a805b96..33c4d07 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java @@ -10,7 +10,6 @@ import com.hithomelabs.CFTunnels.Entity.User; import com.hithomelabs.CFTunnels.Headers.AuthKeyEmailHeader; import com.hithomelabs.CFTunnels.Models.Config; import com.hithomelabs.CFTunnels.Models.Ingress; -import com.hithomelabs.CFTunnels.Models.PaginationRequest; import com.hithomelabs.CFTunnels.Models.TunnelResponse; import com.hithomelabs.CFTunnels.Models.TunnelsResponse; import com.hithomelabs.CFTunnels.Repositories.UserRepository; @@ -22,10 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.dao.DataAccessException; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; +import org.springframework.http.*; import org.springframework.http.*; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.GrantedAuthority; @@ -112,21 +108,12 @@ public class TunnelController implements ErrorController { @PreAuthorize("hasAnyRole('USER')") @GetMapping("/requests") - public ResponseEntity> getAllRequests( - @RequestParam(required = false) Request.RequestStatus status, - @ModelAttribute PaginationRequest paginationRequest) { + public ResponseEntity> getAllRequests() { try { - Sort sort = paginationRequest.getSort() != null && paginationRequest.getSort().length > 0 - ? Sort.by(paginationRequest.getSort()) - : Sort.by("id"); - Pageable pageable = PageRequest.of(paginationRequest.getPage(), paginationRequest.getSize(), sort); - Page requests = mappingRequestService.getAllRequests(status, pageable); + List requests = mappingRequestService.getAllRequests(); Map jsonResponse = new HashMap<>(); jsonResponse.put("status", "success"); - jsonResponse.put("data", requests.getContent()); - jsonResponse.put("currentPage", requests.getNumber()); - jsonResponse.put("totalItems", requests.getTotalElements()); - jsonResponse.put("totalPages", requests.getTotalPages()); + jsonResponse.put("data", requests); return ResponseEntity.ok(jsonResponse); } catch (DataAccessException e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); diff --git a/src/main/java/com/hithomelabs/CFTunnels/Models/PaginationRequest.java b/src/main/java/com/hithomelabs/CFTunnels/Models/PaginationRequest.java deleted file mode 100644 index da16aa2..0000000 --- a/src/main/java/com/hithomelabs/CFTunnels/Models/PaginationRequest.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.hithomelabs.CFTunnels.Models; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class PaginationRequest { - private int page = 0; - private int size = 10; - private String[] sort = {"id"}; -} diff --git a/src/main/java/com/hithomelabs/CFTunnels/Services/MappingRequestService.java b/src/main/java/com/hithomelabs/CFTunnels/Services/MappingRequestService.java index 2c27bc1..f66b1d0 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Services/MappingRequestService.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Services/MappingRequestService.java @@ -11,8 +11,6 @@ import com.hithomelabs.CFTunnels.Repositories.RequestRepository; import com.hithomelabs.CFTunnels.Repositories.TunnelRepository; import com.hithomelabs.CFTunnels.Repositories.UserRepository; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; import org.springframework.security.oauth2.core.oidc.user.OidcUser; import org.springframework.stereotype.Service; @@ -61,11 +59,8 @@ public class MappingRequestService { return createRequest(mapping, user); } - public Page getAllRequests(Request.RequestStatus status, Pageable pageable) { - if (status != null) { - return requestRepository.findByStatus(status, pageable); - } - return requestRepository.findAll(pageable); + public List getAllRequests() { + return requestRepository.findAll(); } public User mapUser(OidcUser oidcUser){ diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index febde77..4f27f96 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -7,4 +7,6 @@ management.endpoint.health.show-details=always logging.level.org.hibernate.SQL=DEBUG debug=true +spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.show-sql=true spring.datasource.url=jdbc:postgresql://localhost:5432/cftunnel diff --git a/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java b/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java index dd384ab..53507de 100644 --- a/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java +++ b/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java @@ -204,197 +204,22 @@ class TunnelControllerTest { } @Test - @DisplayName("should return list of requests with pagination") + @DisplayName("should return list of requests") void getAllRequests_Success() throws Exception { List requests = Arrays.asList( createTestRequest(UUID.randomUUID(), com.hithomelabs.CFTunnels.Entity.Request.RequestStatus.PENDING), createTestRequest(UUID.randomUUID(), com.hithomelabs.CFTunnels.Entity.Request.RequestStatus.APPROVED) ); - Page page = new PageImpl<>(requests, PageRequest.of(0, 10), 2); - when(mappingRequestService.getAllRequests(any(), any(PageRequest.class))).thenReturn(page); + when(mappingRequestService.getAllRequests()).thenReturn(requests); mockMvc.perform(get("/cloudflare/requests") - .with(oauth2Login().oauth2User(buildOidcUser("username", Groups.GITEA_USER))) - .param("page", "0") - .param("size", "10")) + .with(oauth2Login().oauth2User(buildOidcUser("username", Groups.GITEA_USER)))) .andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) .andExpect(jsonPath("$.status").value("success")) .andExpect(jsonPath("$.data").isArray()) - .andExpect(jsonPath("$.totalItems").value(2)) - .andExpect(jsonPath("$.totalPages").value(1)); - } - - @Test - @DisplayName("should filter requests by status") - void getAllRequests_WithStatusFilter() throws Exception { - List requests = List.of( - createTestRequest(UUID.randomUUID(), com.hithomelabs.CFTunnels.Entity.Request.RequestStatus.PENDING) - ); - Page page = new PageImpl<>(requests, PageRequest.of(0, 10), 1); - - when(mappingRequestService.getAllRequests(eq(com.hithomelabs.CFTunnels.Entity.Request.RequestStatus.PENDING), any(PageRequest.class))).thenReturn(page); - - mockMvc.perform(get("/cloudflare/requests") - .with(oauth2Login().oauth2User(buildOidcUser("username", Groups.GITEA_USER))) - .param("status", "PENDING")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.status").value("success")) - .andExpect(jsonPath("$.data[0].status").value("PENDING")); - } - - @Test - @DisplayName("should create mapping request successfully") - void createTunnelMappingRequest_Success() throws Exception { - UUID tunnelId = UUID.randomUUID(); - com.hithomelabs.CFTunnels.Entity.Request createdRequest = new com.hithomelabs.CFTunnels.Entity.Request(); - createdRequest.setId(UUID.randomUUID()); - createdRequest.setStatus(com.hithomelabs.CFTunnels.Entity.Request.RequestStatus.PENDING); - - when(mappingRequestService.createMappingRequest(any(String.class), any(com.hithomelabs.CFTunnels.Models.Ingress.class), any())).thenReturn(createdRequest); - - mockMvc.perform(post("/cloudflare/tunnels/configure/{tunnelId}/requests", tunnelId.toString()) - .with(oauth2Login().oauth2User(buildOidcUser("developer", Groups.HOMELAB_DEVELOPER))) - .with(csrf()) - .contentType(MediaType.APPLICATION_JSON) - .content(ingressJson)) - .andExpect(status().isCreated()) - .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.status").value("PENDING")); - } - - private com.hithomelabs.CFTunnels.Entity.Request createTestRequest(UUID id, com.hithomelabs.CFTunnels.Entity.Request.RequestStatus status) { - com.hithomelabs.CFTunnels.Entity.Request request = new com.hithomelabs.CFTunnels.Entity.Request(); - request.setId(id); - request.setStatus(status); - return request; - } - - @Test - @DisplayName("should approve mapping request successfully") - void approveMappingRequest_Success() throws Exception { - UUID requestId = UUID.randomUUID(); - com.hithomelabs.CFTunnels.Entity.User approverUser = new com.hithomelabs.CFTunnels.Entity.User(); - approverUser.setEmail("approver@example.com"); - approverUser.setName("Approver"); - - com.hithomelabs.CFTunnels.Entity.Request approvedRequest = new com.hithomelabs.CFTunnels.Entity.Request(); - approvedRequest.setId(requestId); - approvedRequest.setStatus(com.hithomelabs.CFTunnels.Entity.Request.RequestStatus.APPROVED); - - when(mappingRequestService.approveRequest(eq(requestId), any(com.hithomelabs.CFTunnels.Entity.User.class))) - .thenReturn(approvedRequest); - when(userRepository.findByEmail("approver@example.com")) - .thenReturn(java.util.Optional.of(approverUser)); - - mockMvc.perform(put("/cloudflare/requests/{requestId}/approve", requestId) - .with(oauth2Login().oauth2User(buildOidcUserWithEmail("approver", Groups.SYSTEM_ADMIN, "approver@example.com"))) - .with(csrf())) - .andExpect(status().isOk()) - .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.status").value("APPROVED")); - } - - @Test - @DisplayName("should return 404 when request not found") - void approveMappingRequest_NotFound() throws Exception { - UUID requestId = UUID.randomUUID(); - com.hithomelabs.CFTunnels.Entity.User approverUser = new com.hithomelabs.CFTunnels.Entity.User(); - approverUser.setEmail("approver@example.com"); - approverUser.setName("Approver"); - - when(mappingRequestService.approveRequest(eq(requestId), any(com.hithomelabs.CFTunnels.Entity.User.class))) - .thenThrow(new NoSuchElementException("Request not found")); - when(userRepository.findByEmail("approver@example.com")) - .thenReturn(java.util.Optional.of(approverUser)); - - mockMvc.perform(put("/cloudflare/requests/{requestId}/approve", requestId) - .with(oauth2Login().oauth2User(buildOidcUserWithEmail("approver", Groups.SYSTEM_ADMIN, "approver@example.com"))) - .with(csrf())) - .andExpect(status().isNotFound()); - } - - @Test - @DisplayName("should return 500 when mapping creation fails") - void approveMappingRequest_InternalServerError() throws Exception { - UUID requestId = UUID.randomUUID(); - com.hithomelabs.CFTunnels.Entity.User approverUser = new com.hithomelabs.CFTunnels.Entity.User(); - approverUser.setEmail("approver@example.com"); - approverUser.setName("Approver"); - - when(mappingRequestService.approveRequest(eq(requestId), any(com.hithomelabs.CFTunnels.Entity.User.class))) - .thenThrow(new RuntimeException("Failed to add mapping to Cloudflare")); - when(userRepository.findByEmail("approver@example.com")) - .thenReturn(java.util.Optional.of(approverUser)); - - mockMvc.perform(put("/cloudflare/requests/{requestId}/approve", requestId) - .with(oauth2Login().oauth2User(buildOidcUserWithEmail("approver", Groups.SYSTEM_ADMIN, "approver@example.com"))) - .with(csrf())) - .andExpect(status().isInternalServerError()); - } - - @Test - @DisplayName("should reject mapping request successfully") - void rejectMappingRequest_Success() throws Exception { - UUID requestId = UUID.randomUUID(); - com.hithomelabs.CFTunnels.Entity.User rejecterUser = new com.hithomelabs.CFTunnels.Entity.User(); - rejecterUser.setEmail("rejecter@example.com"); - rejecterUser.setName("Rejecter"); - - com.hithomelabs.CFTunnels.Entity.Request rejectedRequest = new com.hithomelabs.CFTunnels.Entity.Request(); - rejectedRequest.setId(requestId); - rejectedRequest.setStatus(com.hithomelabs.CFTunnels.Entity.Request.RequestStatus.REJECTED); - - when(mappingRequestService.rejectRequest(eq(requestId), any(com.hithomelabs.CFTunnels.Entity.User.class))) - .thenReturn(rejectedRequest); - when(userRepository.findByEmail("rejecter@example.com")) - .thenReturn(java.util.Optional.of(rejecterUser)); - - mockMvc.perform(put("/cloudflare/requests/{requestId}/reject", requestId) - .with(oauth2Login().oauth2User(buildOidcUserWithEmail("rejecter", Groups.SYSTEM_ADMIN, "rejecter@example.com"))) - .with(csrf())) - .andExpect(status().isOk()) - .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.status").value("REJECTED")); - } - - @Test - @DisplayName("should return 404 when rejecting non-existent request") - void rejectMappingRequest_NotFound() throws Exception { - UUID requestId = UUID.randomUUID(); - com.hithomelabs.CFTunnels.Entity.User rejecterUser = new com.hithomelabs.CFTunnels.Entity.User(); - rejecterUser.setEmail("rejecter@example.com"); - rejecterUser.setName("Rejecter"); - - when(mappingRequestService.rejectRequest(eq(requestId), any(com.hithomelabs.CFTunnels.Entity.User.class))) - .thenThrow(new NoSuchElementException("Request not found")); - when(userRepository.findByEmail("rejecter@example.com")) - .thenReturn(java.util.Optional.of(rejecterUser)); - - mockMvc.perform(put("/cloudflare/requests/{requestId}/reject", requestId) - .with(oauth2Login().oauth2User(buildOidcUserWithEmail("rejecter", Groups.SYSTEM_ADMIN, "rejecter@example.com"))) - .with(csrf())) - .andExpect(status().isNotFound()); - } - - @Test - @DisplayName("should return 409 when rejecting already processed request") - void rejectMappingRequest_Conflict() throws Exception { - UUID requestId = UUID.randomUUID(); - com.hithomelabs.CFTunnels.Entity.User rejecterUser = new com.hithomelabs.CFTunnels.Entity.User(); - rejecterUser.setEmail("rejecter@example.com"); - rejecterUser.setName("Rejecter"); - - when(mappingRequestService.rejectRequest(eq(requestId), any(com.hithomelabs.CFTunnels.Entity.User.class))) - .thenThrow(new IllegalStateException("Request is not in PENDING status")); - when(userRepository.findByEmail("rejecter@example.com")) - .thenReturn(java.util.Optional.of(rejecterUser)); - - mockMvc.perform(put("/cloudflare/requests/{requestId}/reject", requestId) - .with(oauth2Login().oauth2User(buildOidcUserWithEmail("rejecter", Groups.SYSTEM_ADMIN, "rejecter@example.com"))) - .with(csrf())) - .andExpect(status().isConflict()); + .andExpect(jsonPath("$.data.length()").value(2)); } @Test @@ -437,6 +262,13 @@ class TunnelControllerTest { .andExpect(jsonPath("$.data.result.config.ingress[*].hostname", hasItem("random.hithomelabs.com"))); } + private com.hithomelabs.CFTunnels.Entity.Request createTestRequest(UUID id, com.hithomelabs.CFTunnels.Entity.Request.RequestStatus status) { + com.hithomelabs.CFTunnels.Entity.Request request = new com.hithomelabs.CFTunnels.Entity.Request(); + request.setId(id); + request.setStatus(status); + return request; + } + @Test void deleteTunnelConfiguration() throws Exception { -- 2.45.2 From 09e631c871973a6c0fc19d61ea6e82416293f2f1 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 15 Feb 2026 22:34:21 +0530 Subject: [PATCH 2/3] Restore removed tests for approve/reject endpoints --- .../Controllers/TunnelControllerTest.java | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java b/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java index 53507de..3af77b2 100644 --- a/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java +++ b/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java @@ -222,6 +222,152 @@ class TunnelControllerTest { .andExpect(jsonPath("$.data.length()").value(2)); } + @Test + @DisplayName("should create mapping request successfully") + void createTunnelMappingRequest_Success() throws Exception { + UUID tunnelId = UUID.randomUUID(); + com.hithomelabs.CFTunnels.Entity.Request createdRequest = new com.hithomelabs.CFTunnels.Entity.Request(); + createdRequest.setId(UUID.randomUUID()); + createdRequest.setStatus(com.hithomelabs.CFTunnels.Entity.Request.RequestStatus.PENDING); + + when(mappingRequestService.createMappingRequest(any(String.class), any(com.hithomelabs.CFTunnels.Models.Ingress.class), any())).thenReturn(createdRequest); + + mockMvc.perform(post("/cloudflare/tunnels/configure/{tunnelId}/requests", tunnelId.toString()) + .with(oauth2Login().oauth2User(buildOidcUser("developer", Groups.HOMELAB_DEVELOPER))) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(ingressJson)) + .andExpect(status().isCreated()) + .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.status").value("PENDING")); + } + + @Test + @DisplayName("should approve mapping request successfully") + void approveMappingRequest_Success() throws Exception { + UUID requestId = UUID.randomUUID(); + com.hithomelabs.CFTunnels.Entity.User approverUser = new com.hithomelabs.CFTunnels.Entity.User(); + approverUser.setEmail("approver@example.com"); + approverUser.setName("Approver"); + + com.hithomelabs.CFTunnels.Entity.Request approvedRequest = new com.hithomelabs.CFTunnels.Entity.Request(); + approvedRequest.setId(requestId); + approvedRequest.setStatus(com.hithomelabs.CFTunnels.Entity.Request.RequestStatus.APPROVED); + + when(mappingRequestService.approveRequest(eq(requestId), any(com.hithomelabs.CFTunnels.Entity.User.class))) + .thenReturn(approvedRequest); + when(userRepository.findByEmail("approver@example.com")) + .thenReturn(java.util.Optional.of(approverUser)); + + mockMvc.perform(put("/cloudflare/requests/{requestId}/approve", requestId) + .with(oauth2Login().oauth2User(buildOidcUserWithEmail("approver", Groups.SYSTEM_ADMIN, "approver@example.com"))) + .with(csrf())) + .andExpect(status().isOk()) + .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.status").value("APPROVED")); + } + + @Test + @DisplayName("should return 404 when request not found") + void approveMappingRequest_NotFound() throws Exception { + UUID requestId = UUID.randomUUID(); + com.hithomelabs.CFTunnels.Entity.User approverUser = new com.hithomelabs.CFTunnels.Entity.User(); + approverUser.setEmail("approver@example.com"); + approverUser.setName("Approver"); + + when(mappingRequestService.approveRequest(eq(requestId), any(com.hithomelabs.CFTunnels.Entity.User.class))) + .thenThrow(new NoSuchElementException("Request not found")); + when(userRepository.findByEmail("approver@example.com")) + .thenReturn(java.util.Optional.of(approverUser)); + + mockMvc.perform(put("/cloudflare/requests/{requestId}/approve", requestId) + .with(oauth2Login().oauth2User(buildOidcUserWithEmail("approver", Groups.SYSTEM_ADMIN, "approver@example.com"))) + .with(csrf())) + .andExpect(status().isNotFound()); + } + + @Test + @DisplayName("should return 500 when mapping creation fails") + void approveMappingRequest_InternalServerError() throws Exception { + UUID requestId = UUID.randomUUID(); + com.hithomelabs.CFTunnels.Entity.User approverUser = new com.hithomelabs.CFTunnels.Entity.User(); + approverUser.setEmail("approver@example.com"); + approverUser.setName("Approver"); + + when(mappingRequestService.approveRequest(eq(requestId), any(com.hithomelabs.CFTunnels.Entity.User.class))) + .thenThrow(new RuntimeException("Failed to add mapping to Cloudflare")); + when(userRepository.findByEmail("approver@example.com")) + .thenReturn(java.util.Optional.of(approverUser)); + + mockMvc.perform(put("/cloudflare/requests/{requestId}/approve", requestId) + .with(oauth2Login().oauth2User(buildOidcUserWithEmail("approver", Groups.SYSTEM_ADMIN, "approver@example.com"))) + .with(csrf())) + .andExpect(status().isInternalServerError()); + } + + @Test + @DisplayName("should reject mapping request successfully") + void rejectMappingRequest_Success() throws Exception { + UUID requestId = UUID.randomUUID(); + com.hithomelabs.CFTunnels.Entity.User rejecterUser = new com.hithomelabs.CFTunnels.Entity.User(); + rejecterUser.setEmail("rejecter@example.com"); + rejecterUser.setName("Rejecter"); + + com.hithomelabs.CFTunnels.Entity.Request rejectedRequest = new com.hithomelabs.CFTunnels.Entity.Request(); + rejectedRequest.setId(requestId); + rejectedRequest.setStatus(com.hithomelabs.CFTunnels.Entity.Request.RequestStatus.REJECTED); + + when(mappingRequestService.rejectRequest(eq(requestId), any(com.hithomelabs.CFTunnels.Entity.User.class))) + .thenReturn(rejectedRequest); + when(userRepository.findByEmail("rejecter@example.com")) + .thenReturn(java.util.Optional.of(rejecterUser)); + + mockMvc.perform(put("/cloudflare/requests/{requestId}/reject", requestId) + .with(oauth2Login().oauth2User(buildOidcUserWithEmail("rejecter", Groups.SYSTEM_ADMIN, "rejecter@example.com"))) + .with(csrf())) + .andExpect(status().isOk()) + .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.status").value("REJECTED")); + } + + @Test + @DisplayName("should return 404 when rejecting non-existent request") + void rejectMappingRequest_NotFound() throws Exception { + UUID requestId = UUID.randomUUID(); + com.hithomelabs.CFTunnels.Entity.User rejecterUser = new com.hithomelabs.CFTunnels.Entity.User(); + rejecterUser.setEmail("rejecter@example.com"); + rejecterUser.setName("Rejecter"); + + when(mappingRequestService.rejectRequest(eq(requestId), any(com.hithomelabs.CFTunnels.Entity.User.class))) + .thenThrow(new NoSuchElementException("Request not found")); + when(userRepository.findByEmail("rejecter@example.com")) + .thenReturn(java.util.Optional.of(rejecterUser)); + + mockMvc.perform(put("/cloudflare/requests/{requestId}/reject", requestId) + .with(oauth2Login().oauth2User(buildOidcUserWithEmail("rejecter", Groups.SYSTEM_ADMIN, "rejecter@example.com"))) + .with(csrf())) + .andExpect(status().isNotFound()); + } + + @Test + @DisplayName("should return 409 when rejecting already processed request") + void rejectMappingRequest_Conflict() throws Exception { + UUID requestId = UUID.randomUUID(); + com.hithomelabs.CFTunnels.Entity.User rejecterUser = new com.hithomelabs.CFTunnels.Entity.User(); + rejecterUser.setEmail("rejecter@example.com"); + rejecterUser.setName("Rejecter"); + + when(mappingRequestService.rejectRequest(eq(requestId), any(com.hithomelabs.CFTunnels.Entity.User.class))) + .thenThrow(new IllegalStateException("Request is not in PENDING status")); + when(userRepository.findByEmail("rejecter@example.com")) + .thenReturn(java.util.Optional.of(rejecterUser)); + + mockMvc.perform(put("/cloudflare/requests/{requestId}/reject", requestId) + .with(oauth2Login().oauth2User(buildOidcUserWithEmail("rejecter", Groups.SYSTEM_ADMIN, "rejecter@example.com"))) + .with(csrf())) + .andExpect(status().isConflict()); + } + @Test void getTunnelConfigurations() throws Exception { -- 2.45.2 From 3b43039a295add8ea89a8c4c24f28f91a31b9f73 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 15 Feb 2026 22:37:19 +0530 Subject: [PATCH 3/3] Add Request import and simplify createTestRequest method --- .../CFTunnels/Controllers/TunnelControllerTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java b/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java index 3af77b2..e2ad575 100644 --- a/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java +++ b/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java @@ -5,6 +5,7 @@ import com.hithomelabs.CFTunnels.Config.AuthoritiesToGroupMapping; import com.hithomelabs.CFTunnels.Config.CloudflareConfig; import com.hithomelabs.CFTunnels.Config.RestTemplateConfig; import com.hithomelabs.CFTunnels.Headers.AuthKeyEmailHeader; +import com.hithomelabs.CFTunnels.Entity.Request; import com.hithomelabs.CFTunnels.Entity.Tunnel; import com.hithomelabs.CFTunnels.Models.Authorities; import com.hithomelabs.CFTunnels.Models.Config; @@ -408,8 +409,8 @@ class TunnelControllerTest { .andExpect(jsonPath("$.data.result.config.ingress[*].hostname", hasItem("random.hithomelabs.com"))); } - private com.hithomelabs.CFTunnels.Entity.Request createTestRequest(UUID id, com.hithomelabs.CFTunnels.Entity.Request.RequestStatus status) { - com.hithomelabs.CFTunnels.Entity.Request request = new com.hithomelabs.CFTunnels.Entity.Request(); + private Request createTestRequest(UUID id, Request.RequestStatus status) { + Request request = new Request(); request.setId(id); request.setStatus(status); return request; -- 2.45.2