From 2ccc9f14c5a207f4b559eaaac0b1cd456e062cba Mon Sep 17 00:00:00 2001
From: mehdiboudjoudi <m.boudjoudi@neusta.de>
Date: Wed, 26 Feb 2025 11:51:45 +0100
Subject: [PATCH] TD-34: Solved comments made by reviewer

---
 api/api.yml                                   | 67 ++++++++---------
 .../server/admin/AdminApiController.java      | 25 +++++--
 .../GetAllPlayersPaginatedAndSortedTest.java  | 73 +++++++++++--------
 3 files changed, 93 insertions(+), 72 deletions(-)

diff --git a/api/api.yml b/api/api.yml
index 74ca498..15aa501 100644
--- a/api/api.yml
+++ b/api/api.yml
@@ -69,6 +69,32 @@ components:
           type: string
       required:
         - username
+    #############################################
+    #  GetAllPlayersConfigurationData                                   #
+    #############################################
+    GetAllPlayersConfigurationData:
+      description: Configuration data for query for the getting all players endpoint
+      type: object
+      properties:
+        page:
+          type: integer
+          default: 0
+          description: "Page number (zero-based index)."
+        pageSize:
+          type: integer
+          default: 10
+          description: "Number of players per page."
+        sortBy:
+          type: string
+          default: "username"
+          description: "Field to sort by (default is username)."
+        order:
+          type: string
+          enum: [ascending, descending]
+          description: "Sorting order (asc or desc)."
+        username:
+          type: string
+          description: "Filter players by username (case-insensitive, partial match)."
   responses:
     201PlayerCreated:
       description: "201 - Player Created"
@@ -164,42 +190,11 @@ paths:
       operationId: "GetAllPlayers"
       summary: "Retrieve a paginated list of players"
       description: "Returns a paginated list of players, optionally filtered by username."
-      parameters:
-        - name: page
-          in: query
-          description: "Page number (zero-based index)."
-          required: false
-          schema:
-            type: integer
-            default: 0
-        - name: pageSize
-          in: query
-          description: "Number of players per page."
-          required: false
-          schema:
-            type: integer
-            default: 10
-        - name: sortBy
-          in: query
-          description: "Field to sort by (default is username)."
-          required: false
-          schema:
-            type: string
-            default: "username"
-        - name: order
-          in: query
-          description: "Sorting order (asc or desc)."
-          required: false
-          schema:
-            type: string
-            enum: [asc, desc]
-            default: "asc"
-        - name: username
-          in: query
-          description: "Filter players by username (case-insensitive, partial match)."
-          required: false
-          schema:
-            type: string
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: "#/components/schemas/GetAllPlayersConfigurationData"
       tags:
         - admin
       responses:
diff --git a/src/main/java/de/towerdefence/server/admin/AdminApiController.java b/src/main/java/de/towerdefence/server/admin/AdminApiController.java
index 2be1f3f..35c2c25 100644
--- a/src/main/java/de/towerdefence/server/admin/AdminApiController.java
+++ b/src/main/java/de/towerdefence/server/admin/AdminApiController.java
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import de.towerdefence.server.auth.UserSession;
 import de.towerdefence.server.oas.AdminApi;
 import de.towerdefence.server.oas.models.AdminAuthInfo;
+import de.towerdefence.server.oas.models.GetAllPlayersConfigurationData;
 import de.towerdefence.server.oas.models.PlayerApiModel;
 import de.towerdefence.server.player.Player;
 import de.towerdefence.server.player.PlayerRepository;
@@ -53,15 +54,27 @@ public class AdminApiController implements AdminApi {
     }
 
     @Override
-    public ResponseEntity<List<PlayerApiModel>> getAllPlayers(Integer page, Integer pageSize, String sortBy,
-                                                              String order, String username) {
+    public ResponseEntity<List<PlayerApiModel>> getAllPlayers(GetAllPlayersConfigurationData body) {
 
-        Sort.Direction direction = order.equalsIgnoreCase("asc") ? Sort.Direction.ASC : Sort.Direction.DESC;
+        var order = body.getOrder();
+        var page = body.getPage();
+        var pageSize = body.getPageSize();
+        var sortBy = body.getSortBy();
+        var username = body.getUsername();
+
+        if (order == null) {
+            order = GetAllPlayersConfigurationData.OrderEnum.DESCENDING;
+        }
+        Sort.Direction direction = order == GetAllPlayersConfigurationData.OrderEnum.ASCENDING ? Sort.Direction.ASC : Sort.Direction.DESC;
         Pageable pageable = PageRequest.of(page, pageSize, Sort.by(direction, sortBy));
 
-        Page<Player> playerPage = (username != null && !username.trim().isEmpty())
-                ? playerRepository.findByUsernameContainingIgnoreCase(username, pageable)
-                : playerRepository.findAll(pageable);
+        Page<Player> playerPage;
+
+        if (username != null && !username.trim().isEmpty()) {
+            playerPage = playerRepository.findByUsernameContainingIgnoreCase(username, pageable);
+        } else {
+            playerPage = playerRepository.findAll(pageable);
+        }
 
         List<PlayerApiModel> playersMapped = playerMapperService.mapPlayerToApiPlayers(playerPage.getContent());
 
diff --git a/src/test/java/de/towerdefence/server/server/GetAllPlayersPaginatedAndSortedTest.java b/src/test/java/de/towerdefence/server/server/GetAllPlayersPaginatedAndSortedTest.java
index f4835a8..918d75d 100644
--- a/src/test/java/de/towerdefence/server/server/GetAllPlayersPaginatedAndSortedTest.java
+++ b/src/test/java/de/towerdefence/server/server/GetAllPlayersPaginatedAndSortedTest.java
@@ -4,21 +4,30 @@ import de.towerdefence.server.IntegrationTest;
 import org.junit.jupiter.api.Test;
 import org.springframework.http.MediaType;
 import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
 
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
 
 class GetAllPlayersPaginatedAndSortedTest extends IntegrationTest {
 
+    private MockHttpServletRequestBuilder createGetAllPlayersRequest(String requestBody) {
+        return MockMvcRequestBuilders.get(baseUri + "/admin/players")
+                .contentType(MediaType.APPLICATION_JSON)
+                .content(requestBody);
+    }
+
     @Test
     void playersExist() throws Exception {
-        //Testing if list ist being returned successfully
-        this.mvc.perform(MockMvcRequestBuilders.get(baseUri + "/admin/players")
-                        .param("page", "0")
-                        .param("pageSize", "10")
-                        .param("sortBy", "username")
-                        .param("order", "desc")
-                        .contentType(MediaType.APPLICATION_JSON))
+        String requestBody = "{" +
+                "\"page\": 0," +
+                "\"pageSize\": 10," +
+                "\"sortBy\": \"username\"," +
+                "\"order\": \"descending\"," +
+                "\"username\": \"\"" +
+                "}";
+
+        this.mvc.perform(createGetAllPlayersRequest(requestBody))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$").isArray())
                 .andExpect(jsonPath("$[0]").exists());
@@ -26,29 +35,31 @@ class GetAllPlayersPaginatedAndSortedTest extends IntegrationTest {
 
     @Test
     void playersSortedByAsc() throws Exception {
-        //Test list ist being sorted correctly
-        this.mvc.perform(MockMvcRequestBuilders.get(baseUri + "/admin/players")
-                        .param("page", "0")
-                        .param("pageSize", "10")
-                        .param("sortBy", "username")
-                        .param("order", "asc")
-                        .contentType(MediaType.APPLICATION_JSON))
+        String requestBody = "{" +
+                "\"page\": 0," +
+                "\"pageSize\": 10," +
+                "\"sortBy\": \"username\"," +
+                "\"order\": \"ascending\"," +
+                "\"username\": \"\"" +
+                "}";
+
+        this.mvc.perform(createGetAllPlayersRequest(requestBody))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$[0].username").value("Alex"))
                 .andExpect(jsonPath("$[1].username").value("Zorro"));
-
-
     }
 
     @Test
     void playersSortedByDesc() throws Exception {
-        //Test list ist being sorted correctly
-        this.mvc.perform(MockMvcRequestBuilders.get(baseUri + "/admin/players")
-                        .param("page", "0")
-                        .param("pageSize", "10")
-                        .param("sortBy", "username")
-                        .param("order", "desc")
-                        .contentType(MediaType.APPLICATION_JSON))
+        String requestBody = "{" +
+                "\"page\": 0," +
+                "\"pageSize\": 10," +
+                "\"sortBy\": \"username\"," +
+                "\"order\": \"descending\"," +
+                "\"username\": \"\"" +
+                "}";
+
+        this.mvc.perform(createGetAllPlayersRequest(requestBody))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$[1].username").value("Alex"))
                 .andExpect(jsonPath("$[0].username").value("Zorro"));
@@ -56,15 +67,17 @@ class GetAllPlayersPaginatedAndSortedTest extends IntegrationTest {
 
     @Test
     void playersFiltered() throws Exception {
-        //testing if specific username that is being filtered by is in the result list
-        this.mvc.perform(MockMvcRequestBuilders.get(baseUri + "/admin/players")
-                        .param("page", "0")
-                        .param("pageSize", "10")
-                        .param("username", "Alex")
-                        .contentType(MediaType.APPLICATION_JSON))
+        String requestBody = "{" +
+                "\"page\": 0," +
+                "\"pageSize\": 10," +
+                "\"username\": \"Alex\","+
+                "\"order\": \"ascending\""+
+                "}";
+
+        this.mvc.perform(createGetAllPlayersRequest(requestBody))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$").isArray())
                 .andExpect(jsonPath("$[0].username").value("Alex"))
                 .andExpect(jsonPath("$").isNotEmpty());
     }
-}
+}
\ No newline at end of file