diff --git a/API_DOCUMENTATION.md b/API_DOCUMENTATION.md index 4326619b..0775f6fb 100644 --- a/API_DOCUMENTATION.md +++ b/API_DOCUMENTATION.md @@ -16,34 +16,33 @@ All API requests should be made to the following base URL (Spring Boot's default ## Table of Contents -1. [AdminController](#admincontroller) -2. [AuthInfoController](#authinfocontroller) -3. [IsAssignedController](#isassignedcontroller) -4. [IsMemberOfController](#ismemberofcontroller) -5. [TaskController](#taskcontroller) -6. [TeamController](#teamcontroller) -7. [TeamMemberController](#teammembercontroller) -8. [NotificationController](#notificationcontroller) -9. [Path Variables](#path-variables) -10. [DTO References](#dto-references) -11. [Request and Response Examples](#request-and-response-examples) -12. [Best Practices](#best-practices) -13. [Error Codes](#error-codes) -14. [Example Error Response](#example-error-response) +1. [AdminAccountController](#adminaccountcontroller) +2. [AdminController](#admincontroller) +3. [AuthInfoController](#authinfocontroller) +4. [IsAssignedController](#isassignedcontroller) +5. [IsMemberOfController](#ismemberofcontroller) +6. [TaskController](#taskcontroller) +7. [TeamController](#teamcontroller) +8. [TeamMemberAccountController](#teammemberaccountcontroller) +9. [TeamMemberController](#teammembercontroller) +10. [NotificationController](#notificationcontroller) +11. [Path Variables](#path-variables) +12. [DTO References](#dto-references) +13. [Request and Response Examples](#request-and-response-examples) +14. [Best Practices](#best-practices) +15. [Error Codes](#error-codes) +16. [Example Error Response](#example-error-response) --- -## **AdminController** +## **AdminAccountController** -**Base URL:** `/api/admin` +**Base URL:** `/api/admins` ### **Endpoints** - **Create Admin:** `POST /` - - - **Description:** Creates a new admin in the system. - **Request Body:** - ```json { "name": "Admin Name", @@ -51,9 +50,7 @@ All API requests should be made to the following base URL (Spring Boot's default "password": "securepassword" } ``` - - **Response Body:** - ```json { "accountId": 1, @@ -61,25 +58,21 @@ All API requests should be made to the following base URL (Spring Boot's default "userEmail": "admin@example.com" } ``` + - **Description:** Creates a new admin in the system. - **Delete Admin:** `DELETE /{adminId}` - - **Parameters:** - `adminId` (integer, required): The unique ID of the admin to be deleted. - **Description:** Removes an admin from the system permanently. -- **Modify Admin Name:** `PUT /{adminId}/update-name` - +- **Modify Admin Name:** `PUT /{adminId}/name` - **Request Body:** - ```json { "newName": "Updated Admin Name" } ``` - - **Response Body:** - ```json { "accountId": 1, @@ -87,21 +80,16 @@ All API requests should be made to the following base URL (Spring Boot's default "userEmail": "admin@example.com" } ``` - - **Description:** Updates the admin's **name** field in the database. -- **Modify Admin Email:** `PUT /{adminId}/update-email` - +- **Modify Admin Email:** `PUT /{adminId}/email` - **Request Body:** - ```json { "newEmail": "updated.admin@example.com" } ``` - - **Response Body:** - ```json { "accountId": 1, @@ -109,91 +97,36 @@ All API requests should be made to the following base URL (Spring Boot's default "userEmail": "updated.admin@example.com" } ``` - - **Description:** Updates the admin's **email** field in the database. -- **Create Team Member:** `POST /team-member` - - - **Request Body:** - - ```json - { - "name": "Team Member", - "email": "teammember@example.com", - "password": "securepassword" - } - ``` - - - **Response Body:** - - ```json - { - "accountId": 2, - "userName": "Team Member", - "userEmail": "teammember@example.com" - } - ``` - - - **Description:** Adds a new team member to the system. - -- **Modify Team Member Name:** `PUT /team-member/{teamMemberId}/update-name` - - - **Request Body:** - - ```json - { - "newName": "Updated Team Member" - } - ``` - +- **Get Admin by ID** `GET /{adminId}` + - **Parameters:** + - `adminId` (integer, required): The ID of the admin being retrieved. - **Response Body:** - ```json { - "accountId": 2, - "userName": "Updated Team Member", - "userEmail": "teammember@example.com" - } - ``` - - - **Description:** Updates the **name** field of the specified team member in the database. - -- **Modify Team Member Email:** `PUT /team-member/{teamMemberId}/update-email` - - - **Request Body:** - - ```json - { - "newEmail": "updated.tm@example.com" + "accountId": 1, + "userName": "Admin Name", + "userEmail": "admin@example.com" } ``` + - **Description:** Returns the id, name, and email of the requested admin. - - **Response Body:** - - ```json - { - "accountId": 2, - "userName": "Team Member", - "userEmail": "updated.tm@example.com" - } - ``` +--- - - **Description:** Updates the **email** field of the specified team member in the database. +## **AdminController** -- **Delete Team Member:** `DELETE /team-member/{teamMemberId}` +**Base URL:** `/api/admins/actions` - - **Parameters:** - - `teamMemberId` (integer, required): The unique ID of the team member to be deleted. - - **Description:** Removes a team member from the system permanently. +### **Endpoints** - **Assign Team Member to a Team:** `POST /team-member/{teamMemberId}/assign-to-team/{teamId}` - - **Parameters:** - `teamMemberId` (integer, required): The ID of the team member to assign. - `teamId` (integer, required): The ID of the team to assign them to. - **Description:** Assigns a team member to a specified team. -- **Change Role:** `POST /team-member/{teamMemberId}/change-role` +- **Change Role:** `POST /{teamMemberId}/role` - **Parameters:** - `teamMemberId` (integer, required): The ID of the member having their role changed. - **Request Body:** @@ -214,21 +147,17 @@ All API requests should be made to the following base URL (Spring Boot's default - **Note:** The member's ID will change, provide them with the new one. - **Lock a Task:** `PUT /tasks/{taskId}/lock` - - **Parameters:** - `taskId` (integer, required): The ID of the task to lock. - **Description:** Locks a task to prevent any modifications. Once locked, updates and deletions are restricted. - **Unlock a Task:** `PUT /tasks/{taskId}/unlock` - - **Parameters:** - `taskId` (integer, required): The ID of the task to unlock. - **Description:** Unlocks a task, allowing updates and modifications. -- **Get All Admins:** `GET /admins` - +- **Get All Admins:** `GET ` - **Response Body:** - ```json [ { @@ -243,108 +172,34 @@ All API requests should be made to the following base URL (Spring Boot's default } ] ``` + - **Description:** Returns a list of every admin in the database. - - **Description:** Returns a list of every admin in the database. - -- **Get All Team Members:** `GET /team-members` - - - **Response Body:** - - ```json - [ - { - "accountId": 2, - "userName": "Team Member", - "userEmail": "teammember@example.com", - "role": "TEAM_MEMBER", - "teamLead": true, - "teamLeadOfId": [1, 2], - "teamLeadOfName": ["Team One", "Team Two"] - }, - { - "accountId": 3, - "userName": "Team Member3", - "userEmail": "teammember3@example.com", - "role": "ADMIN", - "teamLead": false, - "teamLeadOfId": [], - "teamLeadOfName": [] - } - ] - ``` - - - **Description:** Returns a list of every team member in the database. - -- **Get All Teams:** `GET /all-teams` - - - **Response Body:** - - ```json - [ - { - "teamId": 1, - "teamName": "Development Team" - }, - { - "teamId": 2, - "teamName": "Marketing Team" - } - ] - ``` - - - **Description:** Returns a list of every team in the database. - -- **Get Admin by ID** `GET /{adminId}` - - - **Parameters:** - - `adminId` (integer, required): The ID of the admin being retrieved. - - **Response Body:** - - ```json - { - "accountId": 1, - "userName": "Admin Name", - "userEmail": "admin@example.com" - } - ``` - - - **Description:** Returns the id, name, and email of the requested admin. - -- **Get Team Member by ID** `GET /team-member/{teamMemberId}` - - **Parameters:** - - `teamMemberId` (integer, required): The ID of the team member being retrieved. - - **Response Body:** +- **Reset Password:** `POST /{teamMemberId}/reset-password` + - **Request Body:** ```json { - "accountId": 1, - "userName": "Team Member Name", - "userEmail": "teamMember@example.com" + "newPassword": "newPassword" } ``` - - **Description:** Returns the id, name, and email of the requested team member. + - **Description:** Updates the password field for a team member without providing the old password. --- ## **AuthInfoController** -**Base URL:** `/api/auth-info` +**Base URL:** `/api/auth` ### Endpoints - **Login:** `POST /login` - - - **Description:** Logs a user in. - **Request Body:** - ```json { "teamMemberId": 1, "password": "password" } ``` - - **Response Body:** - ```json { "id": 1, @@ -352,9 +207,9 @@ All API requests should be made to the following base URL (Spring Boot's default "role": "TEAM_MEMBER" } ``` + - **Description:** Logs a user in. -- **IsAdmin:** `POST /is-admin` - - **Description:** Checks if a user is an admin. +- **IsAdmin:** `POST /{teamMemberId}/is-admin` - **Request Body:** ```json { @@ -379,6 +234,7 @@ All API requests should be made to the following base URL (Spring Boot's default "role": "ADMIN" } ``` + - **Description:** Checks if a user is an admin. --- @@ -422,7 +278,63 @@ All API requests should be made to the following base URL (Spring Boot's default ### Endpoints -- No implemented endpoints. +- **Create a Task:** `POST` + - **Request Body:** + ```json + { + "title": "Task Title", + "description": "Task Description", + "isLocked": false, + "status": "To-Do", + "dueDate": "2025-03-01", + "teamId": 3, + "priority": "HIGH" + } + ``` + - **Response Body:** + ```json + { + "taskId": 4, + "title": "Task Title", + "description": "Task Description", + "isLocked": false, + "status": "To-Do", + "dueDate": "2025-03-01", + "teamId": 3, + "priority": "HIGH" + } + ``` + - **Description:** Creates a task in the database. + +- **Delete a Task:** `DELETE /{taskId}` + - **Description:** Deletes a task from the database. + +- **Edit a Task:** `PUT /{taskId}` + - **Request Body:** (TaskDTO, JSON) + ```json + { + "title": "Updated Title", + "description": "Updated Description", + "isLocked": false, + "status": "In Progress", + "dueDate": "2025-04-01", + "priority": "HIGH" + } + ``` + - **Response Body:** + ```json + { + "taskId": 4, + "title": "Updated Title", + "description": "Updated Description", + "isLocked": false, + "status": "In Progress", + "dueDate": "2025-04-01", + "teamId": 3, + "priority": "HIGH" + } + ``` + - **Description:** Updates the details of a task. --- @@ -456,7 +368,6 @@ All API requests should be made to the following base URL (Spring Boot's default - **Change Team Lead:** `PUT /{teamId}/change-lead` - **Request Body:** - ```json { "teamId": 1, @@ -464,9 +375,7 @@ All API requests should be made to the following base URL (Spring Boot's default "teamLeadId": 1002 } ``` - - **Response Body:** - ```json { "teamId": 1, @@ -474,9 +383,24 @@ All API requests should be made to the following base URL (Spring Boot's default "teamLeadId": 1002 } ``` - - **Description:** Updates the team lead for a specified team by assigning a different team member. +- **Get All Teams:** `GET ` + - **Response Body:** + ```json + [ + { + "teamId": 1, + "teamName": "Development Team" + }, + { + "teamId": 2, + "teamName": "Marketing Team" + } + ] + ``` + - **Description:** Returns a list of every team in the database. + - **Get Team Members:** `GET /{teamId}/members` - **Response Body:** ```json @@ -539,81 +463,128 @@ All API requests should be made to the following base URL (Spring Boot's default --- -## **TeamMemberController** +## **TeamMemberAccountController** -**Base URL:** `/api/tasks` +**Base URL:** `/api/members` ### Endpoints -- **Create a Task:** `POST` +- **Create Team Member:** `POST ` - **Request Body:** ```json { - "title": "Task Title", - "description": "Task Description", - "isLocked": false, - "status": "To-Do", - "dueDate": "2025-03-01", - "teamId": 3, - "priority": "HIGH" + "name": "Team Member", + "email": "teammember@example.com", + "password": "securepassword" } ``` - **Response Body:** ```json { - "taskId": 4, - "title": "Task Title", - "description": "Task Description", - "isLocked": false, - "status": "To-Do", - "dueDate": "2025-03-01", - "teamId": 3, - "priority": "HIGH" + "accountId": 2, + "userName": "Team Member", + "userEmail": "teammember@example.com" } ``` - - **Description:** Creates a task in the database. + - **Description:** Adds a new team member to the system. -- **Delete a Task:** `DELETE /{taskId}` - - **Description:** Deletes a task from the database. +- **Delete Team Member:** `DELETE /{teamMemberId}` + - **Parameters:** + - `teamMemberId` (integer, required): The unique ID of the team member to be deleted. + - **Description:** Removes a team member from the system permanently. -- **Edit a Task:** `PUT /{taskId}` - - **Request Body:** (TaskDTO, JSON) +- **Modify Team Member Name:** `PUT /{teamMemberId}/name` + - **Request Body:** ```json { - "title": "Updated Title", - "description": "Updated Description", - "isLocked": false, - "status": "In Progress", - "dueDate": "2025-04-01", - "priority": "HIGH" + "newName": "Updated Team Member" } ``` - **Response Body:** ```json { - "taskId": 4, - "title": "Updated Title", - "description": "Updated Description", - "isLocked": false, - "status": "In Progress", - "dueDate": "2025-04-01", - "teamId": 3, - "priority": "HIGH" + "accountId": 2, + "userName": "Updated Team Member", + "userEmail": "teammember@example.com" } ``` - - **Description:** Updates the details of a task. + - **Description:** Updates the **name** field of the specified team member in the database. + +- **Modify Team Member Email:** `PUT /{teamMemberId}/email` + - **Request Body:** + ```json + { + "newEmail": "updated.tm@example.com" + } + ``` + - **Response Body:** + ```json + { + "accountId": 2, + "userName": "Team Member", + "userEmail": "updated.tm@example.com" + } + ``` + - **Description:** Updates the **email** field of the specified team member in the database. + +- **Get Team Member by ID** `GET /{teamMemberId}` + - **Parameters:** + - `teamMemberId` (integer, required): The ID of the team member being retrieved. + - **Response Body:** + ```json + { + "accountId": 1, + "userName": "Team Member Name", + "userEmail": "teamMember@example.com" + } + ``` + - **Description:** Returns the id, name, and email of the requested team member. + +- **Get All Team Members:** `GET ` + - **Response Body:** + ```json + [ + { + "accountId": 2, + "userName": "Team Member", + "userEmail": "teammember@example.com", + "role": "TEAM_MEMBER", + "teamLead": true, + "teamLeadOfId": [1, 2], + "teamLeadOfName": ["Team One", "Team Two"] + }, + { + "accountId": 3, + "userName": "Team Member3", + "userEmail": "teammember3@example.com", + "role": "ADMIN", + "teamLead": false, + "teamLeadOfId": [], + "teamLeadOfName": [] + } + ] + ``` + - **Description:** Returns a list of every team member in the database. + +--- + +## **TeamMemberController** + +**Base URL:** `/api/members/actions` + +### Endpoints - **Assign Member to a Task:** `POST /{taskId}/assign/{teamMemberId}` - - **Response Body:** - ```json - { - "isAssignedId": 1, - "taskId": 4, - "teamMemberId": 2, - "teamId": 3 - } - ``` - - **Description:** Assigns a member (admin or team member) to a task. + - **Response Body:** + ```json + { + "isAssignedId": 1, + "taskId": 4, + "teamMemberId": 2, + "teamId": 3 + } + ``` + - **Description:** Assigns a member (admin or team member) to a task. - **Mass Assign Members to a Task:** `POST /{taskId}/mass-assign` - **Request Body:** @@ -645,32 +616,18 @@ All API requests should be made to the following base URL (Spring Boot's default ``` - **Description:** Assigns multiple members (admins and/or team members) to a task. If a member is already assigned to the task they will be skipped, but the others will still be assigned. -- **Change Password:** `POST /team-members/{teamMemberId}/change-password` - +- **Change Password:** `POST /{teamMemberId}/change-password` - **Request Body:** - ```json { "oldPassword": "oldPass123", "newPassword": "newPass456" } ``` - - **Description:** Updates the password field for a team member. -- **Reset Password:** `POST /team-members/{teamMemberId}/reset-password` - - **Request Body:** - ```json - { - "newPassword": "newPassword" - } - ``` - - **Description:** Updates the password field for a team member without providing the old password. - - **Get All Teams for a Team Member:** `GET /{teamMemberId}/teams` - - **Response Body:** - ```json [ { @@ -683,7 +640,6 @@ All API requests should be made to the following base URL (Spring Boot's default } ] ``` - - **Description:** Returns a list of all the teams a team member is a part of. - **Get Assigned Tasks For a Team Member:** `GET /{teamMemberId}/tasks` @@ -754,14 +710,12 @@ All API requests should be made to the following base URL (Spring Boot's default ## **NotificationController** -**Base URL:** `/notifs` +**Base URL:** `/api/notifications` ### Endpoints -- **Get Read Notifications:** `GET /{teamMemberId}/read-notifs` - +- **Get Read Notifications:** `GET /{teamMemberId}/read` - **Response Body:** - ```json { [ @@ -786,13 +740,10 @@ All API requests should be made to the following base URL (Spring Boot's default ] } ``` - - **Description:** Returns a list of all read notifications for a specific team member. -- **Get Unread Notifications:** `GET /{teamMemberId}/unread-notifs` - +- **Get Unread Notifications:** `GET /{teamMemberId}/unread` - **Response Body:** - ```json { [ @@ -817,34 +768,27 @@ All API requests should be made to the following base URL (Spring Boot's default ] } ``` - - **Description:** Returns a list of all unread notifications for a specific team member. - **Mark Notification as Read:** `GET /{notificationId}/mark-as-read` - - **Response Body:** - ```json { "message": "Notification marked as read." } ``` - - **Description:** Marks a notification as read. - **Mark Notification as Unread:** `GET /{notificationId}/mark-as-unread` - - **Response Body:** - ```json { "message": "Notification marked as unread." } ``` - - **Description:** Marks a notification as unread. - - **Delete Notification:** `DELETE /{notificationId}` +- **Delete Notification:** `DELETE /{notificationId}` - **Response Status:** ``` HTTP/1.1 204 No Content diff --git a/backend/task-manager/src/main/java/com/example/task_manager/controller/AdminAccountController.java b/backend/task-manager/src/main/java/com/example/task_manager/controller/AdminAccountController.java new file mode 100644 index 00000000..e082448b --- /dev/null +++ b/backend/task-manager/src/main/java/com/example/task_manager/controller/AdminAccountController.java @@ -0,0 +1,82 @@ +package com.example.task_manager.controller; + +import java.util.NoSuchElementException; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import com.example.task_manager.DTO.AdminDTO; +import com.example.task_manager.DTO.AdminRequestDTO; +import com.example.task_manager.DTO.UpdateEmailRequestDTO; +import com.example.task_manager.DTO.UpdateNameRequestDTO; +import com.example.task_manager.service.AdminService; + +@RestController +@RequestMapping("/api/admins") +public class AdminAccountController { + private final AdminService adminService; + + public AdminAccountController(AdminService adminService) { + this.adminService = adminService; + } + + // Create Admin entity + @PostMapping + public ResponseEntity createAdmin(@RequestBody AdminRequestDTO request) { + try { + AdminDTO createAdmin = adminService.createAdmin( + request.getName(), + request.getEmail(), + request.getPassword() + ); + return ResponseEntity.ok(createAdmin); + } catch (RuntimeException e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } + + // Delete Admin + @DeleteMapping("/{adminId}") + public ResponseEntity deleteAdmin(@PathVariable int adminId) { + try { + adminService.deleteAdmin(adminId); + return ResponseEntity.noContent().build(); + } catch (Exception e) { + return ResponseEntity.status(404).body("Admin not found"); + } + } + + // Modify Admin Name + @PutMapping("/{adminId}/name") + public ResponseEntity updateAdminName(@PathVariable int adminId, @RequestBody UpdateNameRequestDTO request) { + try { + AdminDTO updatedAdmin = adminService.modifyAdminName(adminId, request.getNewName()); + return ResponseEntity.ok(updatedAdmin); + } catch (Exception e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } + + // Modify Admin Email + @PutMapping("/{adminId}/email") + public ResponseEntity updateAdminEmail(@PathVariable int adminId, @RequestBody UpdateEmailRequestDTO request) { + try { + AdminDTO updatedAdmin = adminService.modifyAdminEmail(adminId, request.getNewEmail()); + return ResponseEntity.ok(updatedAdmin); + } catch (NoSuchElementException e) { + return ResponseEntity.status(404).body("Admin not found"); + } catch (RuntimeException e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } + + @GetMapping("/{adminId}") + public ResponseEntity getAdminById(@PathVariable int adminId) { + try { + AdminDTO admin = adminService.getAdminById(adminId); + return ResponseEntity.ok(admin); + } catch (RuntimeException e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } +} \ No newline at end of file diff --git a/backend/task-manager/src/main/java/com/example/task_manager/controller/AdminController.java b/backend/task-manager/src/main/java/com/example/task_manager/controller/AdminController.java index f813c5b1..9b180714 100644 --- a/backend/task-manager/src/main/java/com/example/task_manager/controller/AdminController.java +++ b/backend/task-manager/src/main/java/com/example/task_manager/controller/AdminController.java @@ -1,163 +1,26 @@ package com.example.task_manager.controller; import com.example.task_manager.DTO.AdminDTO; -import com.example.task_manager.DTO.AdminRequestDTO; import com.example.task_manager.DTO.ChangeRoleRequestDTO; -import com.example.task_manager.DTO.TeamDTO; -import com.example.task_manager.DTO.TeamMemberDTO; -import com.example.task_manager.DTO.UpdateEmailRequestDTO; -import com.example.task_manager.DTO.UpdateNameRequestDTO; -import com.example.task_manager.entity.Admin; -import com.example.task_manager.repository.AdminRepository; -import com.example.task_manager.repository.AuthInfoRepository; +import com.example.task_manager.DTO.ResetPasswordRequestDTO; import com.example.task_manager.service.AdminService; +import com.example.task_manager.service.TeamMemberService; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; -import java.util.NoSuchElementException; -import java.util.Optional; - -import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; - -import com.example.task_manager.DTO.TeamMemberWithTeamLeadDTO; @RestController -@RequestMapping("/api/admin") -//This is an admin controller +@RequestMapping("/api/admins/actions") public class AdminController { private final AdminService adminService; + private final TeamMemberService teamMemberService; - private final AuthInfoRepository authInfoRepository; - - private final AuthController authController; - - private final AdminRepository adminRepository; - - public AdminController(AdminService adminService, AdminRepository adminRepository, AuthController authController, AuthInfoRepository authInfoRepository) { + public AdminController(AdminService adminService, TeamMemberService teamMemberService) { this.adminService = adminService; - this.adminRepository = adminRepository; - this.authController = authController; - this.authInfoRepository = authInfoRepository; - } - - // Create Admin entity - @PostMapping - public ResponseEntity createAdmin(@RequestBody AdminRequestDTO request) { - try { - AdminDTO createAdmin = adminService.createAdmin( - request.getName(), - request.getEmail(), - request.getPassword() - ); - return ResponseEntity.ok(createAdmin); - } catch (RuntimeException e) { - return ResponseEntity.badRequest().body(e.getMessage()); - } - } - - // Delete Admin - @DeleteMapping("/{adminId}") - public ResponseEntity deleteAdmin(@PathVariable int adminId) { - try { - adminService.deleteAdmin(adminId); - return ResponseEntity.noContent().build(); - } catch (RuntimeException e) { - return ResponseEntity.status(404).body("Admin not found"); - } catch (Exception e) { - return ResponseEntity.status(500).body("Unexpected error: " + e.getMessage()); - } - } - - // @DeleteMapping("/debug-delete/{adminId}") - // public ResponseEntity debugDelete(@PathVariable int adminId) { - // return ResponseEntity.ok("Received DELETE request for ID: " + adminId); - // } - - - // @GetMapping("/admin/debug/{id}") - // public ResponseEntity debugAdmin(@PathVariable int id) { - // try { - // Optional admin = adminRepository.findById(id); - // return admin.map(a -> ResponseEntity.ok("FOUND: " + a.getUserName())) - // .orElse(ResponseEntity.status(404).body("Not found")); - // } catch (Exception e) { - // return ResponseEntity.status(500).body("Exception: " + e.getMessage()); - // } - // } - - // Modify Admin Name - @PutMapping("/{adminId}/update-name") - public ResponseEntity updateAdminName(@PathVariable int adminId, @RequestBody UpdateNameRequestDTO request) { - try { - AdminDTO updatedAdmin = adminService.modifyAdminName(adminId, request.getNewName()); - return ResponseEntity.ok(updatedAdmin); - } catch (Exception e) { - return ResponseEntity.badRequest().body(e.getMessage()); - } - } - - // Modify Admin Email - @PutMapping("/{adminId}/update-email") - public ResponseEntity updateAdminEmail(@PathVariable int adminId, @RequestBody UpdateEmailRequestDTO request) { - try { - AdminDTO updatedAdmin = adminService.modifyAdminEmail(adminId, request.getNewEmail()); - return ResponseEntity.ok(updatedAdmin); - } catch (NoSuchElementException e) { - return ResponseEntity.status(404).body("Admin not found"); - } catch (RuntimeException e) { - return ResponseEntity.badRequest().body(e.getMessage()); - } - } - - // Create Team Member - @PostMapping("/team-member") - public ResponseEntity createTeamMember(@RequestBody AdminRequestDTO request) { - try { - TeamMemberDTO createTeamMember = adminService.createTeamMember( - request.getName(), - request.getEmail(), - request.getPassword() - ); - return ResponseEntity.ok(createTeamMember); - } catch (RuntimeException e) { - return ResponseEntity.badRequest().body(e.getMessage()); - } - } - - // Modify Team Member Name - @PutMapping("/team-member/{teamMemberId}/update-name") - public ResponseEntity modifyTeamMemberName(@PathVariable int teamMemberId, @RequestBody UpdateNameRequestDTO request) { - try { - return ResponseEntity.ok(adminService.modifyTeamMemberName(teamMemberId, request.getNewName())); - } catch (Exception e) { - return ResponseEntity.badRequest().body(e.getMessage()); - } - } - - // Modify Team Member Email - @PutMapping("/team-member/{teamMemberId}/update-email") - public ResponseEntity modifyTeamMemberEmail(@PathVariable int teamMemberId, @RequestBody UpdateEmailRequestDTO request) { - try { - return ResponseEntity.ok(adminService.modifyTeamMemberEmail(teamMemberId, request.getNewEmail())); - } catch (NoSuchElementException e) { - return ResponseEntity.status(404).body("Team member not found"); - } catch (RuntimeException e) { - return ResponseEntity.badRequest().body(e.getMessage()); - } - } - - // Delete Team Member - @DeleteMapping("/team-member/{teamMemberId}") - public ResponseEntity deleteTeamMember(@PathVariable int teamMemberId) { - try { - adminService.deleteTeamMember(teamMemberId); - return ResponseEntity.noContent().build(); - } catch (RuntimeException e) { - return ResponseEntity.status(404).body("Team member not found"); - } + this.teamMemberService = teamMemberService; } // Assign Team Member to Team @@ -171,7 +34,7 @@ public ResponseEntity assignToTeam(@PathVariable int teamMemberId, @PathVaria } //change the role (promote/demote) of a team member - @PostMapping("/team-member/{teamMemberId}/change-role") + @PostMapping("/{teamMemberId}/role") public ResponseEntity changeRole(@PathVariable int teamMemberId, @RequestBody ChangeRoleRequestDTO request) { try { return ResponseEntity.ok(adminService.changeRole(teamMemberId, request.getRole())); @@ -204,7 +67,7 @@ public ResponseEntity unlockTask(@PathVariable int taskId) { } //get all admins - @GetMapping("/admins") + @GetMapping public ResponseEntity getAdmins() { try { List admins = adminService.getAllAdmins(); @@ -214,44 +77,16 @@ public ResponseEntity getAdmins() { } } - //get all team members - @GetMapping("/team-members") - public ResponseEntity getTeamMembers() { - try { - List teamMembers = adminService.getAllTeamMembers(); - return ResponseEntity.ok(teamMembers); - } catch (RuntimeException e) { - return ResponseEntity.badRequest().body(e.getMessage()); - } - } - - @GetMapping("/all-teams") - public ResponseEntity getAllTeams() { - try { - List teams = adminService.getAllTeams(); - return ResponseEntity.ok(teams); - } catch (RuntimeException e) { - return ResponseEntity.badRequest().body(e.getMessage()); - } - } - - @GetMapping("/{adminId}") - public ResponseEntity getAdminById(@PathVariable int adminId) { + //Reset Password + @PostMapping("/{teamMemberId}/reset-password") + public ResponseEntity resetPassword(@PathVariable int teamMemberId, + @RequestBody ResetPasswordRequestDTO request) { try { - AdminDTO admin = adminService.getAdminById(adminId); - return ResponseEntity.ok(admin); - } catch (RuntimeException e) { - return ResponseEntity.badRequest().body(e.getMessage()); + teamMemberService.resetPassword(teamMemberId, request.getNewPassword()); + return ResponseEntity.noContent().build(); } - } - - @GetMapping("/team-member/{teamMemberId}") - public ResponseEntity getTeamMemberById(@PathVariable int teamMemberId) { - try { - TeamMemberDTO teamMember = adminService.getTeamMemberById(teamMemberId); - return ResponseEntity.ok(teamMember); - } catch (RuntimeException e) { + catch (RuntimeException e) { return ResponseEntity.badRequest().body(e.getMessage()); } } -} +} \ No newline at end of file diff --git a/backend/task-manager/src/main/java/com/example/task_manager/controller/AuthController.java b/backend/task-manager/src/main/java/com/example/task_manager/controller/AuthController.java index 5e390604..97b207de 100644 --- a/backend/task-manager/src/main/java/com/example/task_manager/controller/AuthController.java +++ b/backend/task-manager/src/main/java/com/example/task_manager/controller/AuthController.java @@ -7,7 +7,7 @@ import org.springframework.web.bind.annotation.*; @RestController -@RequestMapping("/auth-info") +@RequestMapping("/api/auth") public class AuthController { private final AuthInfoService authInfoService; diff --git a/backend/task-manager/src/main/java/com/example/task_manager/controller/IsAssignedController.java b/backend/task-manager/src/main/java/com/example/task_manager/controller/IsAssignedController.java index c47b8e88..e6d41228 100644 --- a/backend/task-manager/src/main/java/com/example/task_manager/controller/IsAssignedController.java +++ b/backend/task-manager/src/main/java/com/example/task_manager/controller/IsAssignedController.java @@ -15,7 +15,7 @@ public IsAssignedController(IsAssignedService isAssignedService) { this.isAssignedService = isAssignedService; } - // Assign Team Member to a Task + // Assign a team member to a task @PostMapping("/{teamMemberId}/task/{taskId}") public ResponseEntity assignToTask(@PathVariable int teamMemberId, @PathVariable int taskId) { try { @@ -25,7 +25,7 @@ public ResponseEntity assignToTask(@PathVariable int teamMemberId, @PathVaria } } - // Unassign Team Member from Task + // Unassign a team member from a task @DeleteMapping("/{teamMemberId}/task/{taskId}") public ResponseEntity unassignFromTask(@PathVariable int teamMemberId, @PathVariable int taskId) { try { @@ -40,4 +40,4 @@ public ResponseEntity unassignFromTask(@PathVariable int teamMemberId, @PathV public ResponseEntity isAssignedToTask(@PathVariable int teamMemberId, @PathVariable int taskId) { return ResponseEntity.ok(isAssignedService.isAssignedToTask(teamMemberId, taskId)); } -} +} \ No newline at end of file diff --git a/backend/task-manager/src/main/java/com/example/task_manager/controller/IsMemberOfController.java b/backend/task-manager/src/main/java/com/example/task_manager/controller/IsMemberOfController.java index 55006300..252a0ea9 100644 --- a/backend/task-manager/src/main/java/com/example/task_manager/controller/IsMemberOfController.java +++ b/backend/task-manager/src/main/java/com/example/task_manager/controller/IsMemberOfController.java @@ -40,4 +40,4 @@ public ResponseEntity removeMemberFromTeam(@PathVariable int teamMemberId, @P public ResponseEntity isMemberOfTeam(@PathVariable int teamMemberId, @PathVariable int teamId) { return ResponseEntity.ok(isMemberOfService.isMemberOfTeam(teamMemberId, teamId)); } -} +} \ No newline at end of file diff --git a/backend/task-manager/src/main/java/com/example/task_manager/controller/NotificationController.java b/backend/task-manager/src/main/java/com/example/task_manager/controller/NotificationController.java index c5a0ac5f..07ca8bff 100644 --- a/backend/task-manager/src/main/java/com/example/task_manager/controller/NotificationController.java +++ b/backend/task-manager/src/main/java/com/example/task_manager/controller/NotificationController.java @@ -1,26 +1,22 @@ package com.example.task_manager.controller; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import com.example.task_manager.service.NotificationService; @RestController -@RequestMapping("/notif") +@RequestMapping("/api/notifications") public class NotificationController { - private NotificationService notifService; + private NotificationService notifService; public NotificationController(NotificationService notifService) { this.notifService = notifService; } - @GetMapping("/{teamMemberId}/read-notifs") + //Get all notifications marked as read for a specific team member + @GetMapping("/{teamMemberId}/read") public ResponseEntity getReadNotifications(@PathVariable int teamMemberId) { try { return ResponseEntity.ok(notifService.getReadNotifications(teamMemberId)); @@ -29,7 +25,8 @@ public ResponseEntity getReadNotifications(@PathVariable int teamMemberId) { } } - @GetMapping("/{teamMemberId}/unread-notifs") + //Get all notifications marked as unread for a specific team member + @GetMapping("/{teamMemberId}/unread") public ResponseEntity getUnreadNotifications(@PathVariable int teamMemberId) { try { return ResponseEntity.ok(notifService.getUnreadNotifications(teamMemberId)); @@ -38,6 +35,7 @@ public ResponseEntity getUnreadNotifications(@PathVariable int teamMemberId) } } + //Mark a specific notification as read @PutMapping("/{notificationId}/mark-as-read") public ResponseEntity markAsRead(@PathVariable int notificationId) { try { @@ -49,6 +47,7 @@ public ResponseEntity markAsRead(@PathVariable int notificationId) { } } + //Mark a specific notification as unread @PutMapping("/{notificationId}/mark-as-unread") public ResponseEntity markAsUnread(@PathVariable int notificationId) { try { @@ -60,6 +59,7 @@ public ResponseEntity markAsUnread(@PathVariable int notificationId) { } } + //Delete a notification @DeleteMapping("/{notificationId}") public ResponseEntity deleteNotification(@PathVariable int notificationId) { try { @@ -70,4 +70,4 @@ public ResponseEntity deleteNotification(@PathVariable int notificationId) { return ResponseEntity.badRequest().body(e.getMessage()); } } -} +} \ No newline at end of file diff --git a/backend/task-manager/src/main/java/com/example/task_manager/controller/TaskController.java b/backend/task-manager/src/main/java/com/example/task_manager/controller/TaskController.java index db3f92f3..a6741329 100644 --- a/backend/task-manager/src/main/java/com/example/task_manager/controller/TaskController.java +++ b/backend/task-manager/src/main/java/com/example/task_manager/controller/TaskController.java @@ -1,8 +1,54 @@ package com.example.task_manager.controller; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import com.example.task_manager.DTO.TaskDTO; +import com.example.task_manager.DTO.TaskRequestDTO; +import com.example.task_manager.service.TeamMemberService; + @RestController @RequestMapping("/api/tasks") public class TaskController { -} + + private final TeamMemberService teamMemberService; + + public TaskController(TeamMemberService teamMemberService) { + this.teamMemberService = teamMemberService; + } + + // Create a Task + @PostMapping + public ResponseEntity createTask(@RequestBody TaskRequestDTO request) { + try { + TaskDTO task = teamMemberService.createTask(request); + return ResponseEntity.ok(task); + } catch (RuntimeException e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } + + // Delete Task + @DeleteMapping("/{taskId}") + public ResponseEntity deleteTask(@PathVariable int taskId) { + try { + teamMemberService.deleteTask(taskId); + return ResponseEntity.noContent().build(); + } catch (Exception e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } + + // Edit Task + @PutMapping("/{taskId}") + public ResponseEntity editTask(@PathVariable int taskId, + @RequestBody TaskDTO taskDTO) { + try { + TaskDTO updatedTask = teamMemberService.editTask(taskId, taskDTO); + return ResponseEntity.ok(updatedTask); + } + catch (RuntimeException e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } +} \ No newline at end of file diff --git a/backend/task-manager/src/main/java/com/example/task_manager/controller/TeamController.java b/backend/task-manager/src/main/java/com/example/task_manager/controller/TeamController.java index cdf8d419..8974d364 100644 --- a/backend/task-manager/src/main/java/com/example/task_manager/controller/TeamController.java +++ b/backend/task-manager/src/main/java/com/example/task_manager/controller/TeamController.java @@ -1,7 +1,9 @@ package com.example.task_manager.controller; import com.example.task_manager.DTO.TeamDTO; +import com.example.task_manager.DTO.TeamMemberInTeamDTO; import com.example.task_manager.DTO.TeamRequestDTO; +import com.example.task_manager.service.AdminService; import com.example.task_manager.service.TeamService; import org.springframework.http.ResponseEntity; @@ -10,16 +12,17 @@ import java.util.List; import com.example.task_manager.DTO.TaskDTO; -import com.example.task_manager.DTO.TeamMemberInTeamDTO; @RestController @RequestMapping("/api/teams") public class TeamController { - + private final TeamService teamService; + private final AdminService adminService; - public TeamController(TeamService teamService) { + public TeamController(TeamService teamService, AdminService adminService) { this.teamService = teamService; + this.adminService = adminService; } // Create a Team @@ -55,7 +58,17 @@ public ResponseEntity changeTeamLead(@PathVariable int teamId, @RequestBody T } } - // Get Team Members + @GetMapping + public ResponseEntity getAllTeams() { + try { + List teams = adminService.getAllTeams(); + return ResponseEntity.ok(teams); + } catch (RuntimeException e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } + + // Get team members for a specific team @GetMapping("/{teamId}/members") public ResponseEntity> getTeamMembers(@PathVariable int teamId) { try { @@ -74,4 +87,4 @@ public ResponseEntity> getTeamTasks(@PathVariable int teamId) { return ResponseEntity.badRequest().build(); } } -} +} \ No newline at end of file diff --git a/backend/task-manager/src/main/java/com/example/task_manager/controller/TeamMemberAccountController.java b/backend/task-manager/src/main/java/com/example/task_manager/controller/TeamMemberAccountController.java new file mode 100644 index 00000000..e1900b80 --- /dev/null +++ b/backend/task-manager/src/main/java/com/example/task_manager/controller/TeamMemberAccountController.java @@ -0,0 +1,94 @@ +package com.example.task_manager.controller; + +import java.util.List; +import java.util.NoSuchElementException; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import com.example.task_manager.DTO.AdminRequestDTO; +import com.example.task_manager.DTO.TeamMemberDTO; +import com.example.task_manager.DTO.TeamMemberWithTeamLeadDTO; +import com.example.task_manager.DTO.UpdateEmailRequestDTO; +import com.example.task_manager.DTO.UpdateNameRequestDTO; +import com.example.task_manager.service.AdminService; + +@RestController +@RequestMapping("/api/members") +public class TeamMemberAccountController { + private final AdminService adminService; + + public TeamMemberAccountController(AdminService adminService) { + this.adminService = adminService; + } + + // Create Team Member + @PostMapping + public ResponseEntity createTeamMember(@RequestBody AdminRequestDTO request) { + try { + TeamMemberDTO createTeamMember = adminService.createTeamMember( + request.getName(), + request.getEmail(), + request.getPassword() + ); + return ResponseEntity.ok(createTeamMember); + } catch (RuntimeException e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } + + // Delete Team Member + @DeleteMapping("/{teamMemberId}") + public ResponseEntity deleteTeamMember(@PathVariable int teamMemberId) { + try { + adminService.deleteTeamMember(teamMemberId); + return ResponseEntity.noContent().build(); + } catch (RuntimeException e) { + return ResponseEntity.status(404).body("Team member not found"); + } + } + + // Modify Team Member Name + @PutMapping("/{teamMemberId}/name") + public ResponseEntity modifyTeamMemberName(@PathVariable int teamMemberId, @RequestBody UpdateNameRequestDTO request) { + try { + return ResponseEntity.ok(adminService.modifyTeamMemberName(teamMemberId, request.getNewName())); + } catch (Exception e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } + + // Modify Team Member Email + @PutMapping("/{teamMemberId}/email") + public ResponseEntity modifyTeamMemberEmail(@PathVariable int teamMemberId, @RequestBody UpdateEmailRequestDTO request) { + try { + return ResponseEntity.ok(adminService.modifyTeamMemberEmail(teamMemberId, request.getNewEmail())); + } catch (NoSuchElementException e) { + return ResponseEntity.status(404).body("Team member not found"); + } catch (RuntimeException e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } + + // Get a team member's info with their ID + @GetMapping("/{teamMemberId}") + public ResponseEntity getTeamMemberById(@PathVariable int teamMemberId) { + try { + TeamMemberDTO teamMember = adminService.getTeamMemberById(teamMemberId); + return ResponseEntity.ok(teamMember); + } catch (RuntimeException e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } + + //get all team members + @GetMapping + public ResponseEntity getTeamMembers() { + try { + List teamMembers = adminService.getAllTeamMembers(); + return ResponseEntity.ok(teamMembers); + } catch (RuntimeException e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } +} \ No newline at end of file diff --git a/backend/task-manager/src/main/java/com/example/task_manager/controller/TeamMemberController.java b/backend/task-manager/src/main/java/com/example/task_manager/controller/TeamMemberController.java index dcdfc509..bcdd1003 100644 --- a/backend/task-manager/src/main/java/com/example/task_manager/controller/TeamMemberController.java +++ b/backend/task-manager/src/main/java/com/example/task_manager/controller/TeamMemberController.java @@ -2,11 +2,10 @@ import com.example.task_manager.DTO.IsAssignedDTO; import com.example.task_manager.DTO.PasswordChangeRequestDTO; -import com.example.task_manager.DTO.ResetPasswordRequestDTO; import com.example.task_manager.DTO.TaskDTO; -import com.example.task_manager.DTO.TaskRequestDTO; import com.example.task_manager.DTO.TeamDTO; import com.example.task_manager.service.TeamMemberService; +import com.example.task_manager.service.AdminService; import java.util.List; @@ -14,7 +13,7 @@ import org.springframework.web.bind.annotation.*; @RestController -@RequestMapping("/api/tasks") +@RequestMapping("/api/members/actions") public class TeamMemberController { private final TeamMemberService teamMemberService; @@ -23,41 +22,6 @@ public TeamMemberController(TeamMemberService teamMemberService) { this.teamMemberService = teamMemberService; } - // Create a Task - @PostMapping - public ResponseEntity createTask(@RequestBody TaskRequestDTO request) { - try { - TaskDTO task = teamMemberService.createTask(request); - return ResponseEntity.ok(task); - } catch (RuntimeException e) { - return ResponseEntity.badRequest().body(e.getMessage()); - } - } - - // Delete Task - @DeleteMapping("/{taskId}") - public ResponseEntity deleteTask(@PathVariable int taskId) { - try { - teamMemberService.deleteTask(taskId); - return ResponseEntity.noContent().build(); - } catch (Exception e) { - return ResponseEntity.badRequest().body(e.getMessage()); - } - } - - // Edit Task - @PutMapping("/{taskId}") - public ResponseEntity editTask(@PathVariable int taskId, - @RequestBody TaskDTO taskDTO) { - try { - TaskDTO updatedTask = teamMemberService.editTask(taskId, taskDTO); - return ResponseEntity.ok(updatedTask); - } - catch (RuntimeException e) { - return ResponseEntity.badRequest().body(e.getMessage()); - } - } - // Assign Member to Task @PostMapping("/{taskId}/assign/{teamMemberId}") public ResponseEntity assignToTask(@PathVariable int taskId, @PathVariable int teamMemberId) { @@ -82,7 +46,7 @@ public ResponseEntity massAssignToTask(@PathVariable int taskId, @RequestBody } // Change Password (Placeholder) - @PostMapping("/team-members/{teamMemberId}/change-password") + @PostMapping("/{teamMemberId}/change-password") public ResponseEntity changePassword(@PathVariable int teamMemberId, @RequestBody PasswordChangeRequestDTO request) { try { @@ -92,19 +56,6 @@ public ResponseEntity changePassword(@PathVariable int teamMemberId, return ResponseEntity.badRequest().body(e.getMessage()); } } - - //Reset Password - @PostMapping("/team-members/{teamMemberId}/reset-password") - public ResponseEntity resetPassword(@PathVariable int teamMemberId, - @RequestBody ResetPasswordRequestDTO request) { - try { - teamMemberService.resetPassword(teamMemberId, request.getNewPassword()); - return ResponseEntity.noContent().build(); - } - catch (RuntimeException e) { - return ResponseEntity.badRequest().body(e.getMessage()); - } - } @GetMapping("/{teamMemberId}/teams") public ResponseEntity getTeamsForMember(@PathVariable int teamMemberId) { @@ -125,4 +76,4 @@ public ResponseEntity getAssignedTasks(@PathVariable int teamMemberId) { return ResponseEntity.badRequest().body(e.getMessage()); } } -} +} \ No newline at end of file diff --git a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/AdminAccountControllerTest.java b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/AdminAccountControllerTest.java new file mode 100644 index 00000000..5affe0d7 --- /dev/null +++ b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/AdminAccountControllerTest.java @@ -0,0 +1,126 @@ +package com.example.task_manager.controller_tests; + +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; + +import com.example.task_manager.DTO.AdminDTO; +import com.example.task_manager.DTO.AdminRequestDTO; +import com.example.task_manager.enums.RoleType; +import com.example.task_manager.service.AdminService; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +import com.example.task_manager.DTO.UpdateEmailRequestDTO; +import com.example.task_manager.DTO.UpdateNameRequestDTO; +import com.example.task_manager.controller.AdminAccountController; +import com.fasterxml.jackson.databind.ObjectMapper; + +@WebMvcTest(AdminAccountController.class) +@AutoConfigureMockMvc +@ActiveProfiles("test") +public class AdminAccountControllerTest { + @Autowired + private MockMvc mockMvc; + + @MockBean + private AdminService adminService; + + @Autowired + private ObjectMapper objectMapper; + + /** + * Create an Admin + */ + @Test + void testCreateAdmin() throws Exception { + AdminDTO mockAdmin = new AdminDTO(1, "Admin_" + System.nanoTime(), "admin_" + System.nanoTime() + "@example.com", RoleType.ADMIN); + AdminRequestDTO requestDTO = new AdminRequestDTO(mockAdmin.getUserName(), mockAdmin.getUserEmail(), "securePass"); + + when(adminService.createAdmin(mockAdmin.getUserName(), mockAdmin.getUserEmail(), "securePass")).thenReturn(mockAdmin); + + mockMvc.perform(post("/api/admins") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(requestDTO))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.accountId").value(1)) + .andExpect(jsonPath("$.userName").value(mockAdmin.getUserName())) + .andExpect(jsonPath("$.userEmail").value(mockAdmin.getUserEmail())); + } + + /** + * Delete Admin + */ + @Test + void testDeleteAdmin() throws Exception { + doNothing().when(adminService).deleteAdmin(1); + + mockMvc.perform(delete("/api/admins/1")) + .andExpect(status().isNoContent()); + } + + /** + * Modify Admin Name + */ + @Test + void testModifyAdminName() throws Exception { + AdminDTO updatedAdmin = new AdminDTO(1, "NewAdmin_" + System.nanoTime(), "admin@example.com", RoleType.ADMIN); + UpdateNameRequestDTO requestDTO = new UpdateNameRequestDTO(updatedAdmin.getUserName()); + + when(adminService.modifyAdminName(1, updatedAdmin.getUserName())).thenReturn(updatedAdmin); + + mockMvc.perform(put("/api/admins/1/name") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(requestDTO))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.userName").value(updatedAdmin.getUserName())); + } + + /** + * Modify Admin Email + */ + @Test + void testModifyAdminEmail() throws Exception { + AdminDTO updatedAdmin = new AdminDTO(1, "Admin User", "updated_" + System.nanoTime() + "@example.com", + RoleType.ADMIN); + UpdateEmailRequestDTO requestDTO = new UpdateEmailRequestDTO(updatedAdmin.getUserEmail()); + + when(adminService.modifyAdminEmail(1, updatedAdmin.getUserEmail())).thenReturn(updatedAdmin); + + mockMvc.perform(put("/api/admins/1/email") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(requestDTO))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.userEmail").value(updatedAdmin.getUserEmail())); + } + + @Test + void testGetAdminById() throws Exception { + AdminDTO mockAdmin = new AdminDTO(1, "Admin Sandler", "adam_sandler@example.com", RoleType.ADMIN); + + when(adminService.getAdminById(1)).thenReturn(mockAdmin); + + mockMvc.perform(get("/api/admins/1")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.accountId").value(1)) + .andExpect(jsonPath("$.userName").value("Admin Sandler")) + .andExpect(jsonPath("$.userEmail").value("adam_sandler@example.com")); + } + + @Test + void testGetAdminById_NotFound() throws Exception { + when(adminService.getAdminById(999)).thenThrow(new RuntimeException("Admin not found")); + + mockMvc.perform(get("/api/admins/999")) + .andExpect(status().isBadRequest()) + .andExpect(content().string("Admin not found")); + } +} \ No newline at end of file diff --git a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/AdminControllerTest.java b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/AdminControllerTest.java index b4800d49..f371ea09 100644 --- a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/AdminControllerTest.java +++ b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/AdminControllerTest.java @@ -9,30 +9,21 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import com.example.task_manager.DTO.AdminDTO; -import com.example.task_manager.DTO.AdminRequestDTO; import com.example.task_manager.DTO.ChangeRoleRequestDTO; -import com.example.task_manager.DTO.TeamDTO; import com.example.task_manager.DTO.TeamMemberDTO; -import com.example.task_manager.controller.AdminController; import com.example.task_manager.enums.RoleType; import com.example.task_manager.repository.AdminRepository; import com.example.task_manager.repository.TeamMemberRepository; import com.example.task_manager.service.AdminService; import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; - -import com.example.task_manager.DTO.TeamMemberWithTeamLeadDTO; -import com.example.task_manager.DTO.UpdateEmailRequestDTO; -import com.example.task_manager.DTO.UpdateNameRequestDTO; import com.fasterxml.jackson.databind.ObjectMapper; @SpringBootTest @@ -55,123 +46,6 @@ public class AdminControllerTest { @Autowired private ObjectMapper objectMapper; - /** - * Create an Admin - */ - @Test - void testCreateAdmin() throws Exception { - AdminDTO mockAdmin = new AdminDTO(1, "Admin_" + System.nanoTime(), "admin_" + System.nanoTime() + "@example.com", RoleType.ADMIN); - AdminRequestDTO requestDTO = new AdminRequestDTO(mockAdmin.getUserName(), mockAdmin.getUserEmail(), "securePass"); - - when(adminService.createAdmin(mockAdmin.getUserName(), mockAdmin.getUserEmail(), "securePass")).thenReturn(mockAdmin); - - mockMvc.perform(post("/api/admin") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(requestDTO))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.accountId").value(1)) - .andExpect(jsonPath("$.userName").value(mockAdmin.getUserName())) - .andExpect(jsonPath("$.userEmail").value(mockAdmin.getUserEmail())); - } - - /** - * Delete Admin - */ - @Test - void testDeleteAdmin() throws Exception { - doNothing().when(adminService).deleteAdmin(1); - - mockMvc.perform(delete("/api/admin/1")) - .andExpect(status().isNoContent()); - } - - /** - * Modify Admin Name - */ - @Test - void testModifyAdminName() throws Exception { - AdminDTO updatedAdmin = new AdminDTO(1, "NewAdmin_" + System.nanoTime(), "admin@example.com", RoleType.ADMIN); - UpdateNameRequestDTO requestDTO = new UpdateNameRequestDTO(updatedAdmin.getUserName()); - - when(adminService.modifyAdminName(1, updatedAdmin.getUserName())).thenReturn(updatedAdmin); - - mockMvc.perform(put("/api/admin/1/update-name") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(requestDTO))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.userName").value(updatedAdmin.getUserName())); - } - - /** - * Modify Admin Email - */ - @Test - void testModifyAdminEmail() throws Exception { - AdminDTO updatedAdmin = new AdminDTO(1, "Admin User", "updated_" + System.nanoTime() + "@example.com", RoleType.ADMIN); - UpdateEmailRequestDTO requestDTO = new UpdateEmailRequestDTO(updatedAdmin.getUserEmail()); - - when(adminService.modifyAdminEmail(1, updatedAdmin.getUserEmail())).thenReturn(updatedAdmin); - - mockMvc.perform(put("/api/admin/1/update-email") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(requestDTO))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.userEmail").value(updatedAdmin.getUserEmail())); - } - - /** - * Create Team Member - */ - @Test - void testCreateTeamMember() throws Exception { - TeamMemberDTO mockMember = new TeamMemberDTO(2, "Member_" + System.nanoTime(), "member_" + System.nanoTime() + "@example.com", RoleType.TEAM_MEMBER); - AdminRequestDTO requestDTO = new AdminRequestDTO(mockMember.getUserName(), mockMember.getUserEmail(), "securePass"); - - when(adminService.createTeamMember(mockMember.getUserName(), mockMember.getUserEmail(), "securePass")).thenReturn(mockMember); - - mockMvc.perform(post("/api/admin/team-member") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(requestDTO))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.accountId").value(2)) - .andExpect(jsonPath("$.userName").value(mockMember.getUserName())) - .andExpect(jsonPath("$.userEmail").value(mockMember.getUserEmail())); - } - - /** - * Modify Team Member Name - */ - @Test - void testModifyTeamMemberName() throws Exception { - TeamMemberDTO updatedMember = new TeamMemberDTO(1, "UpdatedMember_" + System.nanoTime(), "member@example.com", RoleType.TEAM_MEMBER); - UpdateNameRequestDTO requestDTO = new UpdateNameRequestDTO(updatedMember.getUserName()); - - when(adminService.modifyTeamMemberName(1, updatedMember.getUserName())).thenReturn(updatedMember); - - mockMvc.perform(put("/api/admin/team-member/1/update-name") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(requestDTO))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.userName").value(updatedMember.getUserName())); - } - - /** - * Modify Team Member Email - */ - @Test - void testModifyTeamMemberEmail() throws Exception { - TeamMemberDTO updatedMember = new TeamMemberDTO(1, "John Doe", "updated_" + System.nanoTime() + "@example.com", - RoleType.TEAM_MEMBER); - UpdateEmailRequestDTO requestDTO = new UpdateEmailRequestDTO(updatedMember.getUserEmail()); - - when(adminService.modifyTeamMemberEmail(1, updatedMember.getUserEmail())).thenReturn(updatedMember); - - mockMvc.perform(put("/api/admin/team-member/1/update-email") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(requestDTO))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.userEmail").value(updatedMember.getUserEmail())); - } //changes role to team member @Test @@ -183,7 +57,7 @@ void testChangeRoleToTeamMember() throws Exception { String request = objectMapper.writeValueAsString(new ChangeRoleRequestDTO(RoleType.ADMIN)); - mockMvc.perform(post("/api/admin/team-member/1/change-role") + mockMvc.perform(post("/api/admins/actions/1/role") .contentType(MediaType.APPLICATION_JSON) .content(request)) .andExpect(status().isOk()) @@ -202,7 +76,7 @@ void testChangeRoleToAdmin() throws Exception { String request = objectMapper.writeValueAsString(new ChangeRoleRequestDTO(RoleType.TEAM_MEMBER)); mockMvc.perform(post( - "/api/admin/team-member/1/change-role") + "/api/admins/actions/1/role") .contentType(MediaType.APPLICATION_JSON) .content(request)) .andExpect(status().isOk()) @@ -220,7 +94,7 @@ void testAssignToTeam() throws Exception { when(adminService.assignToTeam(2, 1)).thenReturn(updatedMember); - mockMvc.perform(post("/api/admin/team-member/2/assign-to-team/1")) + mockMvc.perform(post("/api/admins/actions/team-member/2/assign-to-team/1")) .andExpect(status().isOk()) .andExpect(jsonPath("$.accountId").value(2)) .andExpect(jsonPath("$.userName").value("John Doe")) @@ -234,7 +108,7 @@ void testAssignToTeam() throws Exception { void testLockTask() throws Exception { doNothing().when(adminService).lockTask(1); - mockMvc.perform(put("/api/admin/tasks/1/lock")) + mockMvc.perform(put("/api/admins/actions/tasks/1/lock")) .andExpect(status().isOk()); } @@ -245,7 +119,7 @@ void testLockTask() throws Exception { void testUnlockTask() throws Exception { doNothing().when(adminService).unlockTask(1); - mockMvc.perform(put("/api/admin/tasks/1/unlock")) + mockMvc.perform(put("/api/admins/actions/tasks/1/unlock")) .andExpect(status().isOk()); } @@ -258,67 +132,11 @@ void testGetAllAdmins() throws Exception { when(adminService.getAllAdmins()).thenReturn(mockAdmins); - mockMvc.perform(get("/api/admin/admins")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.size()").value(2)) - .andExpect(jsonPath("$[0].accountId").value(1)) - .andExpect(jsonPath("$[0].userName").value("Alice Johnson")) - .andExpect(jsonPath("$[1].userEmail").value("bob@example.com")); - } - - // Getting all admins - @Test - void getAllTeamMembers() throws Exception { - List mockTMs = Arrays.asList( - new TeamMemberWithTeamLeadDTO(1, "Alice Johnson", "alice@example.com", RoleType.TEAM_MEMBER, false, null, null), - new TeamMemberWithTeamLeadDTO(2, "Bob Smith", "bob@example.com", RoleType.TEAM_MEMBER, false, null, null)); - - when(adminService.getAllTeamMembers()).thenReturn(mockTMs); - - mockMvc.perform(get("/api/admin/team-members")) + mockMvc.perform(get("/api/admins/actions")) .andExpect(status().isOk()) .andExpect(jsonPath("$.size()").value(2)) .andExpect(jsonPath("$[0].accountId").value(1)) .andExpect(jsonPath("$[0].userName").value("Alice Johnson")) .andExpect(jsonPath("$[1].userEmail").value("bob@example.com")); } - - // Getting all teams - @Test - void getAllTeams() throws Exception { - List mockTeams = Arrays.asList( - new TeamDTO(1, "Team 1", 1), - new TeamDTO(2, "Team 2", 2)); - - when(adminService.getAllTeams()).thenReturn(mockTeams); - - mockMvc.perform(get("/api/admin/all-teams")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.size()").value(2)) - .andExpect(jsonPath("$[0].teamId").value(1)) - .andExpect(jsonPath("$[0].teamName").value("Team 1")) - .andExpect(jsonPath("$[1].teamLeadId").value("2")); - } - - @Test - void testGetAdminById() throws Exception { - AdminDTO mockAdmin = new AdminDTO(1, "Admin Sandler", "adam_sandler@example.com", RoleType.ADMIN); - - when(adminService.getAdminById(1)).thenReturn(mockAdmin); - - mockMvc.perform(get("/api/admin/1")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.accountId").value(1)) - .andExpect(jsonPath("$.userName").value("Admin Sandler")) - .andExpect(jsonPath("$.userEmail").value("adam_sandler@example.com")); - } - - @Test - void testGetAdminById_NotFound() throws Exception { - when(adminService.getAdminById(999)).thenThrow(new RuntimeException("Admin not found")); - - mockMvc.perform(get("/api/admin/999")) - .andExpect(status().isBadRequest()) - .andExpect(content().string("Admin not found")); - } -} +} \ No newline at end of file diff --git a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/AuthInfoControllerTest.java b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/AuthInfoControllerTest.java index 896d380e..670ae406 100644 --- a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/AuthInfoControllerTest.java +++ b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/AuthInfoControllerTest.java @@ -10,7 +10,6 @@ import com.example.task_manager.service.AuthInfoService; import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -27,9 +26,6 @@ public class AuthInfoControllerTest { @MockBean private AuthInfoService authInfoService; - @InjectMocks - private AuthController authController; - /** * Test Successful Login */ @@ -39,7 +35,7 @@ void testLogin_Success() throws Exception { when(authInfoService.authenticateUser(1, "correctpassword")).thenReturn(mockUser); - mockMvc.perform(post("/auth-info/login") + mockMvc.perform(post("/api/auth/login") .contentType("application/json") .content("{\"accountId\":1, \"password\":\"correctpassword\"}")) .andExpect(status().isOk()) @@ -59,7 +55,7 @@ void testLogin_AdminSuccess() throws Exception { when(authInfoService.authenticateUser(2, "adminpassword")).thenReturn(mockAdmin); - mockMvc.perform(post("/auth-info/login") + mockMvc.perform(post("/api/auth/login") .contentType("application/json") .content("{\"accountId\":2, \"password\":\"adminpassword\"}")) .andExpect(status().isOk()) @@ -78,7 +74,7 @@ void testLogin_Failure_InvalidCredentials() throws Exception { when(authInfoService.authenticateUser(1, "wrongpassword")) .thenThrow(new RuntimeException("Invalid Credentials")); - mockMvc.perform(post("/auth-info/login") + mockMvc.perform(post("/api/auth/login") .contentType("application/json") .content("{\"accountId\":1, \"password\":\"wrongpassword\"}")) .andExpect(status().isUnauthorized()) @@ -95,7 +91,7 @@ void testLogin_Failure_NonExistentUser() throws Exception { when(authInfoService.authenticateUser(9999, "somepassword")) .thenThrow(new RuntimeException("Team Member not found")); - mockMvc.perform(post("/auth-info/login") + mockMvc.perform(post("/api/auth/login") .contentType("application/json") .content("{\"accountId\":9999, \"password\":\"somepassword\"}")) .andExpect(status().isUnauthorized()) @@ -111,7 +107,7 @@ void testLogin_Failure_NonExistentUser() throws Exception { void testIsAdmin_Success_AdminUser() throws Exception { when(authInfoService.isAdmin(2)).thenReturn(RoleType.ADMIN); - mockMvc.perform(get("/auth-info/2/is-admin")) + mockMvc.perform(get("/api/auth/2/is-admin")) .andExpect(status().isOk()) .andExpect(jsonPath("$").value("ADMIN")); @@ -125,7 +121,7 @@ void testIsAdmin_Success_AdminUser() throws Exception { void testIsAdmin_Success_NonAdminUser() throws Exception { when(authInfoService.isAdmin(1)).thenReturn(RoleType.ADMIN); - mockMvc.perform(get("/auth-info/1/is-admin")) + mockMvc.perform(get("/api/auth/1/is-admin")) .andExpect(status().isOk()) .andExpect(jsonPath("$").value("ADMIN")); @@ -140,10 +136,10 @@ void testIsAdmin_Failure_UserNotFound() throws Exception { when(authInfoService.isAdmin(9999)) .thenThrow(new RuntimeException("Team Member not found")); - mockMvc.perform(get("/auth-info/9999/is-admin")) + mockMvc.perform(get("/api/auth/9999/is-admin")) .andExpect(status().isNotFound()) .andExpect(content().string("")); verify(authInfoService, times(1)).isAdmin(9999); } -} +} \ No newline at end of file diff --git a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/IsAssignedControllerTest.java b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/IsAssignedControllerTest.java index bd018f64..43184a92 100644 --- a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/IsAssignedControllerTest.java +++ b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/IsAssignedControllerTest.java @@ -8,7 +8,6 @@ import com.example.task_manager.controller.IsAssignedController; import com.example.task_manager.service.IsAssignedService; import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -25,9 +24,6 @@ public class IsAssignedControllerTest { @MockBean private IsAssignedService isAssignedService; - @InjectMocks - private IsAssignedController isAssignedController; - /** * Assign a Team Member to a Task */ @@ -83,4 +79,4 @@ void testIsAssignedToTask() throws Exception { .andExpect(status().isOk()) .andExpect(content().string("true")); } -} +} \ No newline at end of file diff --git a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/IsMemberOfControllerTest.java b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/IsMemberOfControllerTest.java index 3a3d84cb..6d618037 100644 --- a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/IsMemberOfControllerTest.java +++ b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/IsMemberOfControllerTest.java @@ -9,7 +9,6 @@ import com.example.task_manager.service.IsMemberOfService; import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -26,9 +25,6 @@ public class IsMemberOfControllerTest { @MockBean private IsMemberOfService isMemberOfService; - @InjectMocks - private IsMemberOfController isMemberOfController; - /** * Test Add Member to a Team */ @@ -79,4 +75,4 @@ void testIsMemberOfTeam() throws Exception { .andExpect(status().isOk()) .andExpect(content().string("true")); } -} +} \ No newline at end of file diff --git a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/NotificationControllerTest.java b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/NotificationControllerTest.java index 97391c86..a6c143bf 100644 --- a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/NotificationControllerTest.java +++ b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/NotificationControllerTest.java @@ -9,10 +9,8 @@ import com.example.task_manager.controller.NotificationController; import com.example.task_manager.enums.NotificationType; import com.example.task_manager.service.NotificationService; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -33,12 +31,6 @@ public class NotificationControllerTest { @MockBean private NotificationService notificationService; - @InjectMocks - private NotificationController notificationController; - - @Autowired - private ObjectMapper objectMapper; - /** * Test Get Unread Notifications */ @@ -51,7 +43,7 @@ void testGetUnreadNotifications() throws Exception { when(notificationService.getUnreadNotifications(17911)).thenReturn(mockNotifications); - mockMvc.perform(get("/notif/17911/unread-notifs")) + mockMvc.perform(get("/api/notifications/17911/unread")) .andExpect(status().isOk()) .andExpect(jsonPath("$.length()").value(2)) .andExpect(jsonPath("$[0].message").value("Task Assigned")) @@ -69,7 +61,7 @@ void testGetReadNotifications() throws Exception { when(notificationService.getReadNotifications(17911)).thenReturn(mockNotifications); - mockMvc.perform(get("/notif/17911/read-notifs")) + mockMvc.perform(get("/api/notifications/17911/read")) .andExpect(status().isOk()) .andExpect(jsonPath("$.length()").value(1)) .andExpect(jsonPath("$[0].message").value("Task Completed")); @@ -82,7 +74,7 @@ void testGetReadNotifications() throws Exception { void testMarkAsRead() throws Exception { doNothing().when(notificationService).markAsRead(1); - mockMvc.perform(put("/notif/1/mark-as-read")) + mockMvc.perform(put("/api/notifications/1/mark-as-read")) .andExpect(status().isOk()) .andExpect(content().string("Notification marked as read.")); } @@ -94,7 +86,7 @@ void testMarkAsRead() throws Exception { void testMarkAsUnread() throws Exception { doNothing().when(notificationService).markAsUnread(1); - mockMvc.perform(put("/notif/1/mark-as-unread")) + mockMvc.perform(put("/api/notifications/1/mark-as-unread")) .andExpect(status().isOk()) .andExpect(content().string("Notification marked as unread.")); } @@ -106,7 +98,7 @@ void testMarkAsUnread() throws Exception { void testDeleteNotification() throws Exception { doNothing().when(notificationService).deleteNotification(1); - mockMvc.perform(delete("/notif/1")) + mockMvc.perform(delete("/api/notifications/1")) .andExpect(status().isNoContent()); } -} +} \ No newline at end of file diff --git a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TaskControllerTest.java b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TaskControllerTest.java index 7a2b6a1d..63aaffd9 100644 --- a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TaskControllerTest.java +++ b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TaskControllerTest.java @@ -1,15 +1,122 @@ package com.example.task_manager.controller_tests; -import com.example.task_manager.controller.TaskController; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; + +import com.example.task_manager.DTO.TaskDTO; +import com.example.task_manager.DTO.TaskRequestDTO; +import com.example.task_manager.service.TeamMemberService; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; +import com.example.task_manager.enums.TaskPriority; + +import java.time.LocalDate; +import java.util.Arrays; + +import com.example.task_manager.controller.TaskController; + @WebMvcTest(TaskController.class) @ActiveProfiles("test") public class TaskControllerTest { + @Autowired + private MockMvc mockMvc; + + @MockBean + private TeamMemberService teamMemberService; + @Autowired - private MockMvc mockMvc; -} + private ObjectMapper objectMapper; + + /** + * Test Create Task + */ + @Test + void testCreateTask() throws Exception { + int uniqueId = (int) System.nanoTime(); + int teamId = uniqueId + 1; + TaskDTO mockTask = new TaskDTO(uniqueId, "Task Title " + uniqueId, "Description", false, "Open", LocalDate.now(), null, teamId, null, TaskPriority.LOW); + + TaskRequestDTO requestDTO = new TaskRequestDTO( + "Task Title " + uniqueId, + "Description", + false, + "Open", + LocalDate.of(2025, 3, 11), + Arrays.asList(1, 2, 3), + teamId, + TaskPriority.LOW + ); + + when(teamMemberService.createTask(any(TaskRequestDTO.class))).thenReturn(mockTask); + + mockMvc.perform(post("/api/tasks") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(requestDTO))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.title").value("Task Title " + uniqueId)) + .andExpect(jsonPath("$.description").value("Description")) + .andExpect(jsonPath("$.isLocked").value(false)) + .andExpect(jsonPath("$.status").value("Open")) + .andExpect(jsonPath("$.teamId").value(teamId)) + .andExpect(jsonPath("$.priority").value("LOW")); + } + + /** + * Test Delete Task + */ + @Test + void testDeleteTask() throws Exception { + int uniqueId = (int) System.nanoTime(); + doNothing().when(teamMemberService).deleteTask(uniqueId); + + mockMvc.perform(delete("/api/tasks/" + uniqueId)) + .andExpect(status().isNoContent()); + } + + /** + * Test Edit Task + */ + @Test + void testEditTask() throws Exception { + int uniqueId = (int) System.nanoTime(); + int teamId = uniqueId + 1; + + TaskDTO requestDTO = new TaskDTO( + uniqueId, + "Updated Title " + uniqueId, + "Updated Description", + false, + "In Progress", + LocalDate.now().plusDays(3), + null, + teamId, + null, + TaskPriority.HIGH + ); + + when(teamMemberService.editTask(eq(uniqueId), any(TaskDTO.class))).thenReturn(requestDTO); + + mockMvc.perform(put("/api/tasks/" + uniqueId) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(requestDTO))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.title").value("Updated Title " + uniqueId)) + .andExpect(jsonPath("$.description").value("Updated Description")) + .andExpect(jsonPath("$.isLocked").value(false)) + .andExpect(jsonPath("$.status").value("In Progress")) + .andExpect(jsonPath("$.teamId").value(teamId)) + .andExpect(jsonPath("$.priority").value("HIGH")); + } +} \ No newline at end of file diff --git a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TeamControllerTest.java b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TeamControllerTest.java index 8b2ef5d2..752ccc7c 100644 --- a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TeamControllerTest.java +++ b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TeamControllerTest.java @@ -10,16 +10,15 @@ import com.example.task_manager.DTO.TaskDTO; import com.example.task_manager.DTO.TeamDTO; -import com.example.task_manager.DTO.TeamMemberDTO; import com.example.task_manager.DTO.TeamRequestDTO; import com.example.task_manager.controller.TeamController; import com.example.task_manager.enums.RoleType; import com.example.task_manager.enums.TaskPriority; +import com.example.task_manager.service.AdminService; import com.example.task_manager.service.TeamService; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -32,7 +31,6 @@ import java.util.List; import com.example.task_manager.DTO.TeamMemberInTeamDTO; -import com.example.task_manager.entity.TeamMember; @WebMvcTest(TeamController.class) @ActiveProfiles("test") @@ -44,8 +42,8 @@ public class TeamControllerTest { @MockBean private TeamService teamService; - @InjectMocks - private TeamController teamController; + @MockBean + private AdminService adminService; @Autowired ObjectMapper objectMapper; @@ -137,9 +135,10 @@ void testGetTeamTasks() throws Exception { int teamId = 1; List mockTasks = Arrays.asList( - new TaskDTO(1, "Task 1", "Thing 1", false, "Open", LocalDate.now(), null, teamId, null, TaskPriority.HIGH), - new TaskDTO(2, "Task 2", "Thing 2", false, "Open", LocalDate.now(), null, teamId, null, TaskPriority.HIGH) - ); + new TaskDTO(1, "Task 1", "Thing 1", false, "Open", LocalDate.now(), null, teamId, null, + TaskPriority.HIGH), + new TaskDTO(2, "Task 2", "Thing 2", false, "Open", LocalDate.now(), null, teamId, null, + TaskPriority.HIGH)); when(teamService.getTeamTasks(teamId)).thenReturn(mockTasks); @@ -150,4 +149,21 @@ void testGetTeamTasks() throws Exception { .andExpect(jsonPath("$[1].status").value("Open")) .andExpect(jsonPath("$[1].teamId").value(teamId)); } -} + + // Getting all teams + @Test + void getAllTeams() throws Exception { + List mockTeams = Arrays.asList( + new TeamDTO(1, "Team 1", 1), + new TeamDTO(2, "Team 2", 2)); + + when(adminService.getAllTeams()).thenReturn(mockTeams); + + mockMvc.perform(get("/api/teams")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.size()").value(2)) + .andExpect(jsonPath("$[0].teamId").value(1)) + .andExpect(jsonPath("$[0].teamName").value("Team 1")) + .andExpect(jsonPath("$[1].teamLeadId").value("2")); + } +} \ No newline at end of file diff --git a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TeamMemberAccountControllerTest.java b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TeamMemberAccountControllerTest.java new file mode 100644 index 00000000..0657d787 --- /dev/null +++ b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TeamMemberAccountControllerTest.java @@ -0,0 +1,93 @@ +package com.example.task_manager.controller_tests; + +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; + +import com.example.task_manager.DTO.AdminRequestDTO; +import com.example.task_manager.DTO.TeamMemberDTO; +import com.example.task_manager.enums.RoleType; +import com.example.task_manager.service.AdminService; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +import com.example.task_manager.DTO.UpdateEmailRequestDTO; +import com.example.task_manager.DTO.UpdateNameRequestDTO; +import com.example.task_manager.controller.TeamMemberAccountController; +import com.fasterxml.jackson.databind.ObjectMapper; + +@WebMvcTest(TeamMemberAccountController.class) +@ActiveProfiles("test") +public class TeamMemberAccountControllerTest { + @Autowired + private MockMvc mockMvc; + + @MockBean + private AdminService adminService; + + @Autowired + private ObjectMapper objectMapper; + + /** + * Create Team Member + */ + @Test + void testCreateTeamMember() throws Exception { + TeamMemberDTO mockMember = new TeamMemberDTO(2, "Member_" + System.nanoTime(), "member_" + System.nanoTime() + "@example.com", RoleType.TEAM_MEMBER); + AdminRequestDTO requestDTO = new AdminRequestDTO(mockMember.getUserName(), mockMember.getUserEmail(), "securePass"); + + when(adminService.createTeamMember(mockMember.getUserName(), mockMember.getUserEmail(), "securePass")).thenReturn(mockMember); + + mockMvc.perform(post("/api/members") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(requestDTO))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.accountId").value(2)) + .andExpect(jsonPath("$.userName").value(mockMember.getUserName())) + .andExpect(jsonPath("$.userEmail").value(mockMember.getUserEmail())); + } + + /** + * Modify Team Member Name + */ + @Test + void testModifyTeamMemberName() throws Exception { + TeamMemberDTO updatedMember = new TeamMemberDTO(1, "UpdatedMember_" + System.nanoTime(), "member@example.com", RoleType.TEAM_MEMBER); + UpdateNameRequestDTO requestDTO = new UpdateNameRequestDTO(updatedMember.getUserName()); + + when(adminService.modifyTeamMemberName(1, updatedMember.getUserName())).thenReturn(updatedMember); + + mockMvc.perform(put("/api/members/1/name") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(requestDTO))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.userName").value(updatedMember.getUserName())); + } + + /** + * Modify Team Member Email + */ + @Test + void testModifyTeamMemberEmail() throws Exception { + TeamMemberDTO updatedMember = new TeamMemberDTO(1, "John Doe", "updated_" + System.nanoTime() + "@example.com", + RoleType.TEAM_MEMBER); + UpdateEmailRequestDTO requestDTO = new UpdateEmailRequestDTO(updatedMember.getUserEmail()); + + when(adminService.modifyTeamMemberEmail(1, updatedMember.getUserEmail())).thenReturn(updatedMember); + + mockMvc.perform(put("/api/members/1/email") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(requestDTO))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.userEmail").value(updatedMember.getUserEmail())); + } + + +} \ No newline at end of file diff --git a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TeamMemberControllerTest.java b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TeamMemberControllerTest.java index c33d1840..ffd4dbea 100644 --- a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TeamMemberControllerTest.java +++ b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TeamMemberControllerTest.java @@ -1,20 +1,14 @@ package com.example.task_manager.controller_tests; -import java.awt.PageAttributes; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import com.example.task_manager.DTO.TaskDTO; -import com.example.task_manager.DTO.TaskRequestDTO; import com.example.task_manager.DTO.TeamDTO; import com.example.task_manager.DTO.IsAssignedDTO; import com.example.task_manager.controller.TeamMemberController; -import com.example.task_manager.entity.TeamMember; import com.example.task_manager.service.TeamMemberService; import com.fasterxml.jackson.databind.ObjectMapper; @@ -23,7 +17,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; @@ -49,87 +42,6 @@ public class TeamMemberControllerTest { @Autowired private ObjectMapper objectMapper; - /** - * Test Create Task - */ - @Test - void testCreateTask() throws Exception { - int uniqueId = (int) System.nanoTime(); - int teamId = uniqueId + 1; - TaskDTO mockTask = new TaskDTO(uniqueId, "Task Title " + uniqueId, "Description", false, "Open", LocalDate.now(), null, teamId, null, TaskPriority.LOW); - - TaskRequestDTO requestDTO = new TaskRequestDTO( - "Task Title " + uniqueId, - "Description", - false, - "Open", - LocalDate.of(2025, 3, 11), - Arrays.asList(1, 2, 3), - teamId, - TaskPriority.LOW - ); - - when(teamMemberService.createTask(any(TaskRequestDTO.class))).thenReturn(mockTask); - - mockMvc.perform(post("/api/tasks") - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(requestDTO))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.title").value("Task Title " + uniqueId)) - .andExpect(jsonPath("$.description").value("Description")) - .andExpect(jsonPath("$.isLocked").value(false)) - .andExpect(jsonPath("$.status").value("Open")) - .andExpect(jsonPath("$.teamId").value(teamId)) - .andExpect(jsonPath("$.priority").value("LOW")); - } - - /** - * Test Delete Task - */ - @Test - void testDeleteTask() throws Exception { - int uniqueId = (int) System.nanoTime(); - doNothing().when(teamMemberService).deleteTask(uniqueId); - - mockMvc.perform(delete("/api/tasks/" + uniqueId)) - .andExpect(status().isNoContent()); - } - - /** - * Test Edit Task - */ - @Test - void testEditTask() throws Exception { - int uniqueId = (int) System.nanoTime(); - int teamId = uniqueId + 1; - - TaskDTO requestDTO = new TaskDTO( - uniqueId, - "Updated Title " + uniqueId, - "Updated Description", - false, - "In Progress", - LocalDate.now().plusDays(3), - null, - teamId, - null, - TaskPriority.HIGH - ); - - when(teamMemberService.editTask(eq(uniqueId), any(TaskDTO.class))).thenReturn(requestDTO); - - mockMvc.perform(put("/api/tasks/" + uniqueId) - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(requestDTO))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.title").value("Updated Title " + uniqueId)) - .andExpect(jsonPath("$.description").value("Updated Description")) - .andExpect(jsonPath("$.isLocked").value(false)) - .andExpect(jsonPath("$.status").value("In Progress")) - .andExpect(jsonPath("$.teamId").value(teamId)) - .andExpect(jsonPath("$.priority").value("HIGH")); - } - /** * Test Assign Member to Task */ @@ -142,7 +54,7 @@ void testAssignToTask() throws Exception { IsAssignedDTO assignedDTO = new IsAssignedDTO(uniqueId, taskId, teamMemberId, uniqueId); when(teamMemberService.assignToTask(taskId, teamMemberId)).thenReturn(assignedDTO); - mockMvc.perform(post("/api/tasks/" + taskId + "/assign/" + teamMemberId)) + mockMvc.perform(post("/api/members/actions/" + taskId + "/assign/" + teamMemberId)) .andExpect(status().isOk()) .andExpect(jsonPath("$.taskId").value(taskId)); } @@ -178,23 +90,6 @@ void testChangePassword() throws Exception { // TODO: Implement Change Password Test } - @Test - void testResetPassword() throws Exception { - int teamMemberId = 1; - String newPassword = "trustmethisissecure"; - - String request = objectMapper.writeValueAsString(new Object() { - public final String newPassword = "BrainStew_GreenDay"; - }); - - doNothing().when(teamMemberService).resetPassword(teamMemberId, newPassword); - - mockMvc.perform(post("/api/tasks/team-members/{teamMemberId}/reset-password", teamMemberId) - .contentType(MediaType.APPLICATION_JSON) - .content(request)) - .andExpect(status().isNoContent()); - } - @Test void testGetTeamsForMember() throws Exception { List mockTeams = Arrays.asList( @@ -203,7 +98,7 @@ void testGetTeamsForMember() throws Exception { when(teamMemberService.getTeamsForMember(1)).thenReturn(mockTeams); - MvcResult result = mockMvc.perform(get("/api/tasks/1/teams")) + MvcResult result = mockMvc.perform(get("/api/members/actions/1/teams")) .andDo(print()) .andExpect(status().isOk()) .andReturn(); @@ -219,11 +114,11 @@ void testGetAssignedTasks() throws Exception { when(teamMemberService.getAssignedTasks(1)).thenReturn(mockTasks); - MvcResult result = mockMvc.perform(get("/api/tasks/1/tasks")) + MvcResult result = mockMvc.perform(get("/api/members/actions/1/tasks")) .andExpect(status().isOk()) .andExpect(jsonPath("$[0].priority").value("MEDIUM")) .andExpect(jsonPath("$[1].priority").value("MEDIUM")) .andReturn(); } -} +} \ No newline at end of file diff --git a/frontend/react-app/src/api/adminAccountApi.js b/frontend/react-app/src/api/adminAccountApi.js new file mode 100644 index 00000000..4194ddd0 --- /dev/null +++ b/frontend/react-app/src/api/adminAccountApi.js @@ -0,0 +1,106 @@ +const BASE_URL = "http://localhost:8080/api/admins"; + +//Create admin +export const createAdmin = async (name, email, password) => { + try { + console.log(JSON.stringify({ name, email, password })) + const response = await fetch(`${BASE_URL}`, { + method: 'POST', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ name, email, password }) + }); + + if (!response.ok) { + console.error(`Failed to create admin: ${response.status} ${response.statusText}`); + throw Error ("FAILED TO CREATE ADMIN") + } + + return await response.json(); + } + catch (error) { + console.error("Error creating admin: ", error); + throw error; + } +}; + +//Delete admin +export const deleteAdmin = async (adminId) => { + console.log(`${BASE_URL}/${adminId}`) + try { + const response = await fetch(`${BASE_URL}/${adminId}`, { + method: 'DELETE', + }); + + if (!response.ok) { + console.error(`Failed to delete admin: ${response.status} ${response.statusText}`); + throw Error(response.body) + } + + return true; + } + catch (error) { + console.error("Error deleting admin: ", error); + throw error; + } +}; + +//Change admin name +export const modifyAdminName = async (adminId, newName) => { + try { + const response = await fetch(`${BASE_URL}/${adminId}/name`, { + method: 'PUT', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({newName}) + }); + + if (!response.ok) { + console.error(`Failed to modify admin name: ${response.status} ${response.statusText}`); + } + + return await response.json(); + } + catch (error) { + console.error("Error modifying admin name: ", error); + throw error; + } +}; + +//Change admin email +export const modifyAdminEmail = async (adminId, newEmail) => { + try { + const response = await fetch(`${BASE_URL}/${adminId}/email`, { + method: 'PUT', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ newEmail }) + }); + + if (!response.ok) { + console.error(`Failed to modify admin email: ${response.status} ${response.statusText}`); + } + + return await response.json(); + } + catch (error) { + console.error("Error modifying admin email: ", error); + throw error; + } +}; + +//Get an admin with their ID +export const getAdminById = async (adminId) => { + try { + const response = await fetch(`${BASE_URL}/${adminId}`, { + method: 'GET' + }); + + if (!response.ok) { + console.error(`Failed to retrieve admin: ${response.status} ${response.statusText}`); + } + + return await response.json(); + } + catch (error) { + console.error(`Failed to retrieve admin: `, error); + throw error; + } +}; \ No newline at end of file diff --git a/frontend/react-app/src/api/adminApi.js b/frontend/react-app/src/api/adminApi.js index 9c2b3137..03ffdf07 100644 --- a/frontend/react-app/src/api/adminApi.js +++ b/frontend/react-app/src/api/adminApi.js @@ -1,173 +1,4 @@ -const BASE_URL = "http://localhost:8080/api/admin"; - -//Create admin -export const createAdmin = async (name, email, password) => { - try { - console.log(JSON.stringify({ name, email, password })) - const response = await fetch(`${BASE_URL}`, { - method: 'POST', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ name, email, password }) - }); - - if (!response.ok) { - console.error(`Failed to create admin: ${response.status} ${response.statusText}`); - throw Error ("FAILED TO CREATE ADMIN") - } - - return await response.json(); - } - catch (error) { - console.error("Error creating admin: ", error); - throw error; - } -}; - -//Delete admin -export const deleteAdmin = async (adminId) => { - console.log(`${BASE_URL}/${adminId}`) - try { - const response = await fetch(`${BASE_URL}/${adminId}`, { - method: 'DELETE', - }); - - if (!response.ok) { - console.error(`Failed to delete admin: ${response.status} ${response.statusText}`); - throw Error(response.body) - } - - return true; - } - catch (error) { - console.error("Error deleting admin: ", error); - throw error; - } -}; - -//Change admin name -export const modifyAdminName = async (adminId, newName) => { - try { - const response = await fetch(`${BASE_URL}/${adminId}/update-name`, { - method: 'PUT', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({newName}) - }); - - if (!response.ok) { - console.error(`Failed to modify admin name: ${response.status} ${response.statusText}`); - } - - return await response.json(); - } - catch (error) { - console.error("Error modifying admin name: ", error); - throw error; - } -}; - -//Change admin email -export const modifyAdminEmail = async (adminId, newEmail) => { - try { - const response = await fetch(`${BASE_URL}/${adminId}/update-email`, { - method: 'PUT', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ newEmail }) - }); - - if (!response.ok) { - console.error(`Failed to modify admin email: ${response.status} ${response.statusText}`); - } - - return await response.json(); - } - catch (error) { - console.error("Error modifying admin email: ", error); - throw error; - } -}; - -//Create team member -export const createTeamMember = async (name, email, password) => { - try { - const response = await fetch(`${BASE_URL}/team-member`, { - method: 'POST', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ name, email, password }) - }); - - if (!response.ok) { - console.error(`Failed to create team member: ${response.status} ${response.statusText}`); - throw Error ("FAILED TO CREATE Team Member") - } - - return await response.json(); - } - catch (error) { - console.error("Error creating team member: ", error); - throw error; - } -}; - -//Change team member name -export const modifyTeamMemberName = async (teamMemberId, newName) => { - try { - const response = await fetch(`${BASE_URL}/team-member/${teamMemberId}/update-name`, { - method: 'PUT', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({newName}) - }); - - if (!response.ok) { - console.error(`Failed to modify team member name: ${response.status} ${response.statusText}`); - } - - return await response.json(); - } - catch (error) { - console.error("Error modifying team member name: ", error); - throw error; - } -}; - -//Change team member email -export const modifyTeamMemberEmail = async (teamMemberId, newEmail) => { - try { - const response = await fetch(`${BASE_URL}/team-member/${teamMemberId}/update-email`, { - method: 'PUT', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ newEmail }) - }); - - if (!response.ok) { - console.error(`Failed to modify team member email: ${response.status} ${response.statusText}`); - } - - return await response.json(); - } - catch (error) { - console.error("Error modifying team member email: ", error); - throw error; - } -}; - -//Delete team member -export const deleteTeamMember = async (teamMemberId) => { - try { - const response = await fetch(`${BASE_URL}/team-member/${teamMemberId}`, { - method: 'DELETE', - }); - - if (!response.ok) { - console.error(`Failed to delete team member: ${response.status} ${response.statusText}`); - } - - return true; - } - catch (error) { - console.error("Error deleting team member: ", error); - throw error; - } -}; +const BASE_URL = "http://localhost:8080/api/admins/actions"; //Assign team member to a team export const assignTeamMemberToTeam = async (teamMemberId, teamId) => { @@ -192,7 +23,7 @@ export const assignTeamMemberToTeam = async (teamMemberId, teamId) => { //Changing the role of a team member or admin export const changeRole = async (teamMemberId, newRole) => { try { - const response = await fetch(`${BASE_URL}/team-member/${teamMemberId}/change-role`, { + const response = await fetch(`${BASE_URL}/${teamMemberId}/role`, { method: 'POST', headers: { "Content-Type": "application/json" }, body: JSON.stringify({ role: newRole }) @@ -254,7 +85,7 @@ export const unlockTask = async (taskId) => { //Get all admins export const getAdmins = async () => { try { - const response = await fetch(`${BASE_URL}/admins`, { + const response = await fetch(`${BASE_URL}`, { method: 'GET' }); @@ -270,78 +101,24 @@ export const getAdmins = async () => { } }; -//Get all team ememebrs -export const getTeamMembers = async () => { - try { - const response = await fetch(`${BASE_URL}/team-members`, { - method: 'GET' - }); - - if (!response.ok) { - console.error(`Failed to retrieve team members: ${response.status} ${response.statusText}`); - } - - return await response.json(); - } - catch (error) { - console.error(`Failed to retrieve all team members: `, error); - throw error; - } -}; - -//Get all teams -export const getTeams = async () => { +//reset password +export const resetPassword = async (teamMemberId, newPassword) => { try { - const response = await fetch(`${BASE_URL}/all-teams`, { - method: 'GET' - }); - - if (!response.ok) { - console.error(`Failed to retrieve teams: ${response.status} ${response.statusText}`); - } - - return await response.json(); - } - catch (error) { - console.error(`Failed to retrieve all teams: `, error); - throw error; - } -}; - -//Get an admin with their ID -export const getAdminById = async (adminId) => { - try { - const response = await fetch(`${BASE_URL}/${adminId}`, { - method: 'GET' + const response = await fetch(`${BASE_URL}/${teamMemberId}/reset-password`, { + method: 'POST', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ newPassword }) }); if (!response.ok) { - console.error(`Failed to retrieve admin: ${response.status} ${response.statusText}`); + console.error(`Failed to reset password: ${response.status} ${response.statusText}`) + return null; } - return await response.json(); + return await true; } catch (error) { - console.error(`Failed to retrieve admin: `, error); + console.error("Error resetting password: ", error); throw error; - } -}; - -//Get a team member with their ID -export const getTeamMemberById = async (teamMemberId) => { - try { - const response = await fetch(`${BASE_URL}/team-member/${teamMemberId}`, { - method: 'GET' - }); - - if (!response.ok) { - console.error(`Failed to retrieve team member: ${response.status} ${response.statusText}`); - } - - return await response.json(); } - catch (error) { - console.error(`Failed to retrieve team member: `, error); - throw error; - } }; \ No newline at end of file diff --git a/frontend/react-app/src/api/authInfo.js b/frontend/react-app/src/api/authInfoApi.js similarity index 90% rename from frontend/react-app/src/api/authInfo.js rename to frontend/react-app/src/api/authInfoApi.js index e367cc86..a9ae2236 100644 --- a/frontend/react-app/src/api/authInfo.js +++ b/frontend/react-app/src/api/authInfoApi.js @@ -1,4 +1,4 @@ -const BASE_URL = "http://localhost:8080/auth-info"; +const BASE_URL = "http://localhost:8080/api/auth"; export const login = async (accountId, password) => { try { @@ -25,7 +25,7 @@ export const login = async (accountId, password) => { export const isAdmin = async (teamMemberId) => { try { - const response = await fetch(`${BASE_URL}/is-admin`, { + const response = await fetch(`${BASE_URL}/${teamMemberId}/is-admin`, { method: 'POST', headers: { "Content-Type": "application/json" diff --git a/frontend/react-app/src/api/notificationApi.js b/frontend/react-app/src/api/notificationApi.js index 1054615d..add7587a 100644 --- a/frontend/react-app/src/api/notificationApi.js +++ b/frontend/react-app/src/api/notificationApi.js @@ -1,9 +1,9 @@ -const BASE_URL = "http://localhost:8080/notif"; +const BASE_URL = "http://localhost:8080/api/notifications"; //get all read notifications export const getReadNotifications = async (teamMemberId) => { try { - const response = await fetch(`${BASE_URL}/${teamMemberId}/read-notifs`, { + const response = await fetch(`${BASE_URL}/${teamMemberId}/read`, { method: 'GET' }); @@ -23,7 +23,7 @@ export const getReadNotifications = async (teamMemberId) => { //get all unread notifications export const getUnreadNotifications = async (teamMemberId) => { try { - const response = await fetch(`${BASE_URL}/${teamMemberId}/unread-notifs`, { + const response = await fetch(`${BASE_URL}/${teamMemberId}/unread`, { method: 'GET' }); diff --git a/frontend/react-app/src/api/taskApi.js b/frontend/react-app/src/api/taskApi.js index db85ca4a..a1555ca5 100644 --- a/frontend/react-app/src/api/taskApi.js +++ b/frontend/react-app/src/api/taskApi.js @@ -1 +1,66 @@ const BASE_URL = "http://localhost:8080/api/tasks"; + +//Create a task +export const createTask = async (title, description, isLocked, status, dueDate, teamId, priority) => { + try { + console.log("Sending this: ", JSON.stringify({title, description, isLocked, status, dueDate, teamId, priority})) + const response = await fetch(`${BASE_URL}`, { + method: 'POST', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({title, description, isLocked, status, dueDate, teamId, priority}) + }); + + if (!response.ok) { + console.error(`Failed to create task: ${response.status} ${response.statusText}`); + return null; + } + + return await response.json(); + } + catch (error) { + console.error("Error creating task: ", error); + throw error; + } +}; + +//Delete a task +export const deleteTask = async (taskId) => { + try { + const response = await fetch(`${BASE_URL}/${taskId}`, { + method: 'DELETE' + }); + + if (!response.ok) { + console.error(`Failed to delete task: ${response.status} ${response.statusText}`); + return null; + } + + return true; + } + catch (error) { + console.error("Error deleting task: ", error); + throw error; + } +}; + +//Edit task +export const editTask = async (taskId, title, description, isLocked, status, dueDate, priority) => { + try { + const response = await fetch(`${BASE_URL}/${taskId}`, { + method: 'PUT', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({title, description, isLocked, status, dueDate, priority}) + }); + + if (!response.ok) { + console.error(`Failed to edit task: ${response.status} ${response.statusText}`); + return null; + } + + return await response.json(); + } + catch (error) { + console.error("Error editing task: ", error); + throw error; + } +}; diff --git a/frontend/react-app/src/api/teamApi.js b/frontend/react-app/src/api/teamApi.js index 411bd54f..722ae497 100644 --- a/frontend/react-app/src/api/teamApi.js +++ b/frontend/react-app/src/api/teamApi.js @@ -64,6 +64,25 @@ export const changeTeamLead = async (teamId, teamLeadId, teamName) => { } }; +//Get all teams +export const getTeams = async () => { + try { + const response = await fetch(`${BASE_URL}`, { + method: 'GET' + }); + + if (!response.ok) { + console.error(`Failed to retrieve teams: ${response.status} ${response.statusText}`); + } + + return await response.json(); + } + catch (error) { + console.error(`Failed to retrieve all teams: `, error); + throw error; + } +}; + //Get all team members of team export const getTeamMembers = async (teamId) => { try { diff --git a/frontend/react-app/src/api/teamMemberAccountApi.js b/frontend/react-app/src/api/teamMemberAccountApi.js new file mode 100644 index 00000000..4da017ee --- /dev/null +++ b/frontend/react-app/src/api/teamMemberAccountApi.js @@ -0,0 +1,124 @@ +const BASE_URL = "http://localhost:8080/api/members"; + +//Create team member +export const createTeamMember = async (name, email, password) => { + try { + const response = await fetch(`${BASE_URL}`, { + method: 'POST', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ name, email, password }) + }); + + if (!response.ok) { + console.error(`Failed to create team member: ${response.status} ${response.statusText}`); + throw Error ("FAILED TO CREATE Team Member") + } + + return await response.json(); + } + catch (error) { + console.error("Error creating team member: ", error); + throw error; + } +}; + + +//Delete team member +export const deleteTeamMember = async (teamMemberId) => { + try { + const response = await fetch(`${BASE_URL}/${teamMemberId}`, { + method: 'DELETE', + }); + + if (!response.ok) { + console.error(`Failed to delete team member: ${response.status} ${response.statusText}`); + } + + return true; + } + catch (error) { + console.error("Error deleting team member: ", error); + throw error; + } +}; + + +//Change team member name +export const modifyTeamMemberName = async (teamMemberId, newName) => { + try { + const response = await fetch(`${BASE_URL}/${teamMemberId}/name`, { + method: 'PUT', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({newName}) + }); + + if (!response.ok) { + console.error(`Failed to modify team member name: ${response.status} ${response.statusText}`); + } + + return await response.json(); + } + catch (error) { + console.error("Error modifying team member name: ", error); + throw error; + } +}; + +//Change team member email +export const modifyTeamMemberEmail = async (teamMemberId, newEmail) => { + try { + const response = await fetch(`${BASE_URL}/${teamMemberId}/email`, { + method: 'PUT', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ newEmail }) + }); + + if (!response.ok) { + console.error(`Failed to modify team member email: ${response.status} ${response.statusText}`); + } + + return await response.json(); + } + catch (error) { + console.error("Error modifying team member email: ", error); + throw error; + } +}; + +//Get a team member with their ID +export const getTeamMemberById = async (teamMemberId) => { + try { + const response = await fetch(`${BASE_URL}/${teamMemberId}`, { + method: 'GET' + }); + + if (!response.ok) { + console.error(`Failed to retrieve team member: ${response.status} ${response.statusText}`); + } + + return await response.json(); + } + catch (error) { + console.error(`Failed to retrieve team member: `, error); + throw error; + } +}; + +//Get all team ememebrs +export const getTeamMembers = async () => { + try { + const response = await fetch(`${BASE_URL}/team-members`, { + method: 'GET' + }); + + if (!response.ok) { + console.error(`Failed to retrieve team members: ${response.status} ${response.statusText}`); + } + + return await response.json(); + } + catch (error) { + console.error(`Failed to retrieve all team members: `, error); + throw error; + } +}; diff --git a/frontend/react-app/src/api/teamMemberApi.js b/frontend/react-app/src/api/teamMemberApi.js index 9697129f..8045c23a 100644 --- a/frontend/react-app/src/api/teamMemberApi.js +++ b/frontend/react-app/src/api/teamMemberApi.js @@ -1,69 +1,4 @@ -const BASE_URL = "http://localhost:8080/api/tasks"; - -//Create a task -export const createTask = async (title, description, isLocked, status, dueDate, teamId, priority) => { - try { - console.log("Sending this: ", JSON.stringify({title, description, isLocked, status, dueDate, teamId, priority})) - const response = await fetch(`${BASE_URL}`, { - method: 'POST', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({title, description, isLocked, status, dueDate, teamId, priority}) - }); - - if (!response.ok) { - console.error(`Failed to create task: ${response.status} ${response.statusText}`); - return null; - } - - return await response.json(); - } - catch (error) { - console.error("Error creating task: ", error); - throw error; - } -}; - -//Delete a task -export const deleteTask = async (taskId) => { - try { - const response = await fetch(`${BASE_URL}/${taskId}`, { - method: 'DELETE' - }); - - if (!response.ok) { - console.error(`Failed to delete task: ${response.status} ${response.statusText}`); - return null; - } - - return true; - } - catch (error) { - console.error("Error deleting task: ", error); - throw error; - } -}; - -//Edit task -export const editTask = async (taskId, title, description, isLocked, status, dueDate, priority) => { - try { - const response = await fetch(`${BASE_URL}/${taskId}`, { - method: 'PUT', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({title, description, isLocked, status, dueDate, priority}) - }); - - if (!response.ok) { - console.error(`Failed to edit task: ${response.status} ${response.statusText}`); - return null; - } - - return await response.json(); - } - catch (error) { - console.error("Error editing task: ", error); - throw error; - } -}; +const BASE_URL = "http://localhost:8080/api/members/actions"; //Assign member to task export const assignMemberToTask = async (taskId, teamMemberId) => { @@ -113,7 +48,7 @@ export const massAssignMemberToTask = async(taskId, teamMemberIds) => { export const changePassword = async (teamMemberId, oldPassword, newPassword) => { try { console.log(JSON.stringify({oldPassword, newPassword})) - const response = await fetch(`${BASE_URL}/team-members/${teamMemberId}/change-password`, { + const response = await fetch(`${BASE_URL}/${teamMemberId}/change-password`, { method: 'POST', headers: { "Content-Type": "application/json" }, body: JSON.stringify({oldPassword, newPassword}) @@ -132,27 +67,7 @@ export const changePassword = async (teamMemberId, oldPassword, newPassword) => } }; -//reset password -export const resetPassword = async (teamMemberId, newPassword) => { - try { - const response = await fetch(`${BASE_URL}/team-members/${teamMemberId}/reset-password`, { - method: 'POST', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ newPassword }) - }); - - if (!response.ok) { - console.error(`Failed to reset password: ${response.status} ${response.statusText}`) - return null; - } - return await true; - } - catch (error) { - console.error("Error resetting password: ", error); - throw error; - } -}; //getting all teams for a specific team member export const getTeamsForMember = async (accountId) => { diff --git a/frontend/react-app/src/components/CreateAccountForm.jsx b/frontend/react-app/src/components/CreateAccountForm.jsx index ebc39b63..8de39504 100644 --- a/frontend/react-app/src/components/CreateAccountForm.jsx +++ b/frontend/react-app/src/components/CreateAccountForm.jsx @@ -1,7 +1,8 @@ import { useEffect } from 'react'; import {Controller, useForm} from 'react-hook-form'; import Select from 'react-select' -import { createTeamMember, createAdmin} from '../api/adminApi'; +import {createAdmin } from '../api/adminAccountApi'; +import { createTeamMember } from '../api/teamMemberAccountApi'; import { addMemberToTeam } from '../api/isMemberOfApi'; export default function CreateAccountForm({teams}){ const { register, handleSubmit, formState: {errors},control} = useForm(); diff --git a/frontend/react-app/src/components/CreateTaskForm.jsx b/frontend/react-app/src/components/CreateTaskForm.jsx index 82be013b..af2f885f 100644 --- a/frontend/react-app/src/components/CreateTaskForm.jsx +++ b/frontend/react-app/src/components/CreateTaskForm.jsx @@ -1,7 +1,8 @@ import { useState, useEffect } from 'react'; import {useForm} from 'react-hook-form' import '../css/CreateTaskForm.css' -import {assignMemberToTask, createTask, getTeamsForMember} from '../api/teamMemberApi' +import {assignMemberToTask, getTeamsForMember} from '../api/teamMemberApi' +import { createTask } from '../api/taskApi'; import { useCookies } from 'react-cookie'; import { getTeamMembers } from '../api/teamApi'; function CreateTaskForm(){ diff --git a/frontend/react-app/src/components/LoginForm.jsx b/frontend/react-app/src/components/LoginForm.jsx index 2fbf8d5c..f15a8cae 100644 --- a/frontend/react-app/src/components/LoginForm.jsx +++ b/frontend/react-app/src/components/LoginForm.jsx @@ -1,5 +1,5 @@ import {useForm} from 'react-hook-form' -import {isAdmin, login} from '../api/authInfo' +import {login, isAdmin} from '../api/authInfoApi' import { useCookies } from 'react-cookie'; function LoginForm(){ const { register, handleSubmit, formState: {errors}} = useForm(); diff --git a/frontend/react-app/src/components/UserTable.jsx b/frontend/react-app/src/components/UserTable.jsx index b579a581..338ff151 100644 --- a/frontend/react-app/src/components/UserTable.jsx +++ b/frontend/react-app/src/components/UserTable.jsx @@ -5,7 +5,10 @@ import SearchFilterSort from './SearchFilterSort'; import { useState} from 'react'; import { getTeamMembers } from '../api/teamApi'; import {Link} from 'react-router-dom' -import { changeRole, deleteAdmin, deleteTeamMember } from '../api/adminApi'; +import { changeRole } from '../api/adminApi'; +import { deleteAdmin } from '../api/adminAccountApi'; +import { deleteTeamMember } from '../api/teamMemberAccountApi'; + const AllTeams = [ { name: "Team1", diff --git a/frontend/react-app/src/pages/AdminAllUsers.jsx b/frontend/react-app/src/pages/AdminAllUsers.jsx index 777ecf22..a794b544 100644 --- a/frontend/react-app/src/pages/AdminAllUsers.jsx +++ b/frontend/react-app/src/pages/AdminAllUsers.jsx @@ -2,7 +2,7 @@ import UserTable from '../components/UserTable' import Header from '../components/Header' import '../css/AdminAllUsers.css' import {useState, useEffect} from 'react' -import { getTeams } from '../api/adminApi'; +import { getTeams } from '../api/teamApi'; function AdminAllUsers(){ diff --git a/frontend/react-app/src/pages/AdminPanel.jsx b/frontend/react-app/src/pages/AdminPanel.jsx index dc18fbe9..fdd4d081 100644 --- a/frontend/react-app/src/pages/AdminPanel.jsx +++ b/frontend/react-app/src/pages/AdminPanel.jsx @@ -4,7 +4,8 @@ import {useForm} from "react-hook-form" import '../css/AdminPanel.css' import {useNavigate} from 'react-router-dom' import { useEffect, useState } from "react"; -import { getTeams } from "../api/adminApi"; +import { getTeams } from "../api/teamApi"; + export default function AdminPanel(){ const { register, handleSubmit} = useForm(); const [teams, setTeams] = useState(); diff --git a/frontend/react-app/src/pages/CreateAccount.jsx b/frontend/react-app/src/pages/CreateAccount.jsx index 6454fbcf..61ec9279 100644 --- a/frontend/react-app/src/pages/CreateAccount.jsx +++ b/frontend/react-app/src/pages/CreateAccount.jsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import '../css/CreateAccount.css'; import Header from '../components/Header'; import CreateAccountForm from '../components/CreateAccountForm'; -import { getTeams } from '../api/adminApi'; +import { getTeams } from '../api/teamApi'; const CreateAccount = () => { const [loading, setLoading]= useState(true); diff --git a/frontend/react-app/src/pages/EditUserDetails.jsx b/frontend/react-app/src/pages/EditUserDetails.jsx index 793dc18c..b1cb2716 100644 --- a/frontend/react-app/src/pages/EditUserDetails.jsx +++ b/frontend/react-app/src/pages/EditUserDetails.jsx @@ -1,10 +1,11 @@ import { useEffect, useState} from "react" import Header from "../components/Header" import {useLocation} from 'react-router-dom' -import { getTeamMemberById, modifyAdminEmail, modifyAdminName, modifyTeamMemberEmail, modifyTeamMemberName } from "../api/adminApi" +import { modifyAdminEmail, modifyAdminName } from "../api/adminAccountApi" +import {getTeamMemberById, modifyTeamMemberEmail, modifyTeamMemberName } from "../api/teamMemberAccountApi" import {useForm} from 'react-hook-form' -import { isAdmin } from "../api/authInfo" -import { resetPassword } from "../api/teamMemberApi" +import { isAdmin } from "../api/authInfoApi" +import { resetPassword } from "../api/adminApi" export default function EditUserDetails(){ const {register, handleSubmit} = useForm(); diff --git a/frontend/react-app/src/pages/TeamTasks.jsx b/frontend/react-app/src/pages/TeamTasks.jsx index baa53dfe..031f372a 100644 --- a/frontend/react-app/src/pages/TeamTasks.jsx +++ b/frontend/react-app/src/pages/TeamTasks.jsx @@ -10,7 +10,6 @@ import { getTeamMembers } from "../api/teamApi"; import { useLocation } from 'react-router-dom'; import { getTeamTasks } from "../api/teamApi"; - function getAssigneesNames(taskItem) { return taskItem.assignedMembers.map((member) => member.userName).join(", "); } diff --git a/frontend/react-app/src/tests/api-tests/adminAccountApiTest.test.js b/frontend/react-app/src/tests/api-tests/adminAccountApiTest.test.js new file mode 100644 index 00000000..765001b4 --- /dev/null +++ b/frontend/react-app/src/tests/api-tests/adminAccountApiTest.test.js @@ -0,0 +1,108 @@ +import { createAdmin, deleteAdmin, modifyAdminName, modifyAdminEmail, getAdminById } from '../../api/adminAccountApi'; + +const BASE_URL = "http://localhost:8080/api/admins"; + +beforeEach(() => { + fetchMock.resetMocks(); +}); + + +describe('Admin Account API', () => { + + //test: creating an admin + test('createAdmin should return admin data on success', async () => { + const mockAdmin = { + name: "Test Admin", + email: "test_admin@example.com", + password: "admin_password" + }; + + fetch.mockResponseOnce(JSON.stringify(mockAdmin), { status: 200 }); + + const result = await createAdmin("Test Admin", "test_admin@example.com", "admin_password"); + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}`, { + method: 'POST', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + name: "Test Admin", + email: "test_admin@example.com", + password: "admin_password" + }) + }); + + expect(result).toEqual(mockAdmin); + }); + + //test: deleting an admin + test('deleteAdmin should return true on success', async () => { + fetch.mockResponseOnce('', { status: 204 }); + + const result = await deleteAdmin(1); + + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1`, { + method: 'DELETE' + }); + + expect(result).toBe(true); + }); + + //test: modifying admin name + test('modifyAdminName should return new admin data on success', async () => { + const updatedAdmin = { + adminId: 1, + newName: "New AdminName" + }; + + fetch.mockResponseOnce(JSON.stringify(updatedAdmin), { status: 200 }); + + const result = await modifyAdminName(1, "New AdminName"); + + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1/name`, { + method: 'PUT', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + newName: "New AdminName" + }) + }); + + expect(result).toEqual(updatedAdmin); + }); + + //test: modifying admin email + test('modifyAdminEmail should return new admin data on success', async () => { + const updatedAdmin = { + adminId: 1, + newEmail: "new_adminEmail@example.com" + }; + + fetch.mockResponseOnce(JSON.stringify(updatedAdmin), { status: 200 }); + + const result = await modifyAdminEmail(1, "new_adminEmail@example.com"); + + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1/email`, { + method: 'PUT', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + newEmail: "new_adminEmail@example.com" + }) + }); + + expect(result).toEqual(updatedAdmin); + }); + + //test: retrieving admin info with their ID + test('getAdminById should return admin data on success', async () => { + const mockAdmin = { + accountId: 1, + userName: "Admin User", + userEmail: "admin@example.com" + }; + + fetch.mockResponseOnce(JSON.stringify(mockAdmin), { status: 200 }); + + const result = await getAdminById(1); + + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1`, { method: 'GET' }); + expect(result).toEqual(mockAdmin); + }); +}); \ No newline at end of file diff --git a/frontend/react-app/src/tests/api-tests/adminApiTest.test.js b/frontend/react-app/src/tests/api-tests/adminApiTest.test.js index 620bb739..1bdc1851 100644 --- a/frontend/react-app/src/tests/api-tests/adminApiTest.test.js +++ b/frontend/react-app/src/tests/api-tests/adminApiTest.test.js @@ -1,175 +1,12 @@ -import { createAdmin, deleteAdmin, modifyAdminName, createTeamMember, deleteTeamMember, modifyTeamMemberName, modifyTeamMemberEmail, modifyAdminEmail, assignTeamMemberToTeam, lockTask, changeRole, unlockTask, getTeamMembers, getAdmins, getTeams, getAdminById, getTeamMemberById } from '../../api/adminApi'; +import { assignTeamMemberToTeam, lockTask, unlockTask, changeRole, getAdmins, resetPassword } from '../../api/adminApi'; -const BASE_URL = "http://localhost:8080/api/admin"; +const BASE_URL = "http://localhost:8080/api/admins/actions"; beforeEach(() => { fetchMock.resetMocks(); }); -describe('Admin API', () => { - - //test: creating an admin - test('createAdmin should return admin data on success', async () => { - const mockAdmin = { - name: "Test Admin", - email: "test_admin@example.com", - password: "admin_password" - }; - - fetch.mockResponseOnce(JSON.stringify(mockAdmin), { status: 200 }); - - const result = await createAdmin("Test Admin", "test_admin@example.com", "admin_password"); - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}`, { - method: 'POST', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - name: "Test Admin", - email: "test_admin@example.com", - password: "admin_password" - }) - }); - - expect(result).toEqual(mockAdmin); - }); - - //test: deleting an admin - test('deleteAdmin should return true on success', async () => { - fetch.mockResponseOnce('', { status: 204 }); - - const result = await deleteAdmin(1); - - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1`, { - method: 'DELETE' - }); - - expect(result).toBe(true); - }); - - //test: modifying admin name - test('modifyAdminName should return new admin data on success', async () => { - const updatedAdmin = { - adminId: 1, - newName: "New AdminName" - }; - - fetch.mockResponseOnce(JSON.stringify(updatedAdmin), { status: 200 }); - - const result = await modifyAdminName(1, "New AdminName"); - - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1/update-name`, { - method: 'PUT', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - newName: "New AdminName" - }) - }); - - expect(result).toEqual(updatedAdmin); - }); - - //test: modifying admin email - test('modifyAdminEmail should return new admin data on success', async () => { - const updatedAdmin = { - adminId: 1, - newEmail: "new_adminEmail@example.com" - }; - - fetch.mockResponseOnce(JSON.stringify(updatedAdmin), { status: 200 }); - - const result = await modifyAdminEmail(1, "new_adminEmail@example.com"); - - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1/update-email`, { - method: 'PUT', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - newEmail: "new_adminEmail@example.com" - }) - }); - - expect(result).toEqual(updatedAdmin); - }); - - //test: creating team member - test('createTeamMember should return team member data on success', async () => { - const mockTeamMember = { - name: "Test TM", - email: "test_tm@example.com", - password: "tm_password" - }; - - fetch.mockResponseOnce(JSON.stringify(mockTeamMember), { status: 200 }); - - const result = await createTeamMember("Test TM", "test_tm@example.com", "tm_password"); - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/team-member`, { - method: 'POST', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - name: "Test TM", - email: "test_tm@example.com", - password: "tm_password" - }) - }); - - expect(result).toEqual(mockTeamMember); - }); - - //test: modify team member name - test('modifyTeamMemberName should return new team member data on success', async () => { - const updatedTeamMember = { - teamMemberId: 1, - newName: "New TMName" - }; - - fetch.mockResponseOnce(JSON.stringify(updatedTeamMember), { status: 200 }); - - const result = await modifyTeamMemberName(1, "New TMName"); - - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/team-member/1/update-name`, { - method: 'PUT', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - newName: "New TMName" - }) - }); - - expect(result).toEqual(updatedTeamMember); - }); - - //test: modify team member email - test('modifyTeamMemberEmail should return new team member data on success', async () => { - const updatedTeamMember = { - teamMemberId: 1, - newEmail: "new@example.com" - }; - - fetch.mockResponseOnce(JSON.stringify(updatedTeamMember), { status: 200 }); - - const result = await modifyTeamMemberEmail(1, "new@example.com"); - - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/team-member/1/update-email`, { - method: 'PUT', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - newEmail: "new@example.com" - }) - }); - - expect(result).toEqual(updatedTeamMember); - }); - - //test: deleting a team member - test('deleteTeamMember should return true on success', async () => { - fetch.mockResponseOnce('', { status: 204 }); - - const result = await deleteTeamMember(1); - - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/team-member/1`, { - method: 'DELETE' - }); - - expect(result).toBe(true); - }); - +describe('Admin Actions API', () => { //test: assigning a team member to a team test('assignTeamMemberToTeam should return true on success', async () => { fetch.mockResponseOnce('', { status: 200 }); @@ -190,7 +27,7 @@ describe('Admin API', () => { const result = await changeRole(1, "ADMIN"); - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/team-member/1/change-role`, { + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1/role`, { method: 'POST', headers: { "Content-Type": "application/json" }, body: JSON.stringify({role: "ADMIN"}) @@ -238,69 +75,24 @@ describe('Admin API', () => { const result = await getAdmins(); - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/admins`, { method: 'GET' }); + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}`, { method: 'GET' }); expect(result).toEqual(mockAdmins); }); - //test: getting all team members - test('getAllTeamMembers should return list of team members on success', async () => { - const mockTeamMembers = [ - { accountId: 3, userName: "TeamMember One", userEmail: "tm1@example.com" }, - { accountId: 4, userName: "TeamMember Two", userEmail: "tm2@example.com" } - ]; - - fetch.mockResponseOnce(JSON.stringify(mockTeamMembers), { status: 200 }); - - const result = await getTeamMembers(); - - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/team-members`, { method: 'GET' }); - expect(result).toEqual(mockTeamMembers); - }); - - //test: getting all teams - test('getTeams should return list of team members on success', async () => { - const mockTeams = [ - { teamId: 1, teamName: "Team Alpha", teamLeadId: 3 }, - { teamId: 2, teamName: "Team Beta", teamLeadId: 4 } - ]; - - fetch.mockResponseOnce(JSON.stringify(mockTeams), { status: 200 }); - - const result = await getTeams(); - - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/all-teams`, { method: 'GET' }); - expect(result).toEqual(mockTeams); - }); - - //test: retrieving admin info with their ID - test('getAdminById should return admin data on success', async () => { - const mockAdmin = { - accountId: 1, - userName: "Admin User", - userEmail: "admin@example.com" - }; - - fetch.mockResponseOnce(JSON.stringify(mockAdmin), { status: 200 }); - - const result = await getAdminById(1); - - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1`, { method: 'GET' }); - expect(result).toEqual(mockAdmin); - }); - - //test: retrieving team emember info with ID - test('getTeamMemberById should return team member data on success', async () => { - const mockTeamMember = { - accountId: 2, - userName: "John Doe", - userEmail: "john.doe@example.com" - }; - - fetch.mockResponseOnce(JSON.stringify(mockTeamMember), { status: 200 }); - - const result = await getTeamMemberById(2); - - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/team-member/2`, { method: 'GET' }); - expect(result).toEqual(mockTeamMember); + //test: resetting a password + test('resetPassword should return success on valid password reset', async () => { + const mockResponse = true; + + fetch.mockResponseOnce(JSON.stringify(mockResponse), { status: 200 }); + + const result = await resetPassword(1, "DefLeppard"); + + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1/reset-password`, { + method: 'POST', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ newPassword: "DefLeppard" }) + }); + + expect(result).toEqual(mockResponse); }); }); \ No newline at end of file diff --git a/frontend/react-app/src/tests/api-tests/authInfoApiTest.test.js b/frontend/react-app/src/tests/api-tests/authInfoApiTest.test.js index f7c66f79..3bc59031 100644 --- a/frontend/react-app/src/tests/api-tests/authInfoApiTest.test.js +++ b/frontend/react-app/src/tests/api-tests/authInfoApiTest.test.js @@ -1,6 +1,6 @@ -import {login, isAdmin} from '../../api/authInfo'; +import {login, isAdmin} from '../../api/authInfoApi'; -const BASE_URL = "http://localhost:8080/auth-info"; +const BASE_URL = "http://localhost:8080/api/auth"; beforeEach(() => { fetchMock.resetMocks(); @@ -34,7 +34,7 @@ describe('AuthInfo API', () => { const response = await isAdmin(1); - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/is-admin`, { + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1/is-admin`, { method: 'POST', headers: { "Content-Type": "application/json" }, body: JSON.stringify({ teamMemberId: 1 }) @@ -49,7 +49,7 @@ describe('AuthInfo API', () => { const response = await isAdmin(1); - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/is-admin`, { + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1/is-admin`, { method: 'POST', headers: { "Content-Type": "application/json" }, body: JSON.stringify({ teamMemberId: 1 }) diff --git a/frontend/react-app/src/tests/api-tests/notificationApiTest.test.js b/frontend/react-app/src/tests/api-tests/notificationApiTest.test.js index d0e34ab7..0a447601 100644 --- a/frontend/react-app/src/tests/api-tests/notificationApiTest.test.js +++ b/frontend/react-app/src/tests/api-tests/notificationApiTest.test.js @@ -1,6 +1,6 @@ import { getReadNotifications, getUnreadNotifications, markAsRead, markAsUnread, deleteNotification } from "../../api/notificationApi"; -const BASE_URL = "http://localhost:8080/notif"; +const BASE_URL = "http://localhost:8080/api/notifications"; beforeEach(() => { fetch.resetMocks(); @@ -20,7 +20,7 @@ describe('Notification API', () => { const result = await getReadNotifications(101); //get notifications for teamMember with ID 101 - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/101/read-notifs`, { + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/101/read`, { method: 'GET' }); @@ -33,7 +33,7 @@ describe('Notification API', () => { const result = await getUnreadNotifications(101); //get notifications for teamMember with ID 101 - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/101/unread-notifs`, { + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/101/unread`, { method: 'GET' }); diff --git a/frontend/react-app/src/tests/api-tests/taskApiTest.test.js b/frontend/react-app/src/tests/api-tests/taskApiTest.test.js index 0ddf7c27..6954a8e3 100644 --- a/frontend/react-app/src/tests/api-tests/taskApiTest.test.js +++ b/frontend/react-app/src/tests/api-tests/taskApiTest.test.js @@ -1,3 +1,4 @@ +import { createTask, deleteTask, editTask} from '../../api/taskApi'; import { notifyMembers} from '../../api/taskApi'; const BASE_URL = "http://localhost:8080/api/tasks"; @@ -7,16 +8,81 @@ beforeEach(() => { }); describe('Task API', () => { - //test: notifying members - test('notifyMembers should return true on success', async () => { - fetch.mockResponseOnce('', { status: 200 }); + //test: creating a task + test('createTask should return task data on sucess', async () => { + const mockTask = { + id: 1, + title: "New Task", + description: "Task description", + isLocked: false, + status: "To-Do", + dueDate: "4-14-2025", + teamId: 2 + }; - const result = await notifyMembers(1, 1); - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1/notify`, { + fetch.mockResponseOnce(JSON.stringify(mockTask), {status: 201}); + + const result = await createTask("New Task", "Task description", false, "To-Do", "4-14-2025", 2, "LOW"); + + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}`, { method: 'POST', - headers: { "Content-Type": "application/json" } + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + title: "New Task", + description: "Task description", + isLocked: false, + status: "To-Do", + dueDate: "4-14-2025", + teamId: 2, + priority: "LOW" + }) + }); + + expect(result).toEqual(mockTask); + }); + + //test: deleting a task + test('deleteTask should return true on success', async () => { + fetch.mockResponseOnce('', { status: 204 }); + + const result = await deleteTask(1); + + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1`, { + method: 'DELETE' }); expect(result).toBe(true); }); + + //test: editing a task + test('editTask should return updated task data on success', async () => { + const updatedTask = { + id: 1, + title: "Updated task", + description: "Updated description", + isLocked: true, + status: "In progress", + dueDate: "2025-03-01", + priority: "HIGH" + }; + + fetch.mockResponseOnce(JSON.stringify(updatedTask), { status: 200 }); + + const result = await editTask(1, "Updated Task", "Updated description", true, "In progress", "2025-03-01", "HIGH"); + + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1`, { + method: 'PUT', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + title: "Updated Task", + description: "Updated description", + isLocked: true, + status: "In progress", + dueDate: "2025-03-01", + priority: "HIGH" + }) + }); + + expect(result).toEqual(updatedTask); + }); }); \ No newline at end of file diff --git a/frontend/react-app/src/tests/api-tests/teamApiTest.test.js b/frontend/react-app/src/tests/api-tests/teamApiTest.test.js index 349bf528..50b9db7f 100644 --- a/frontend/react-app/src/tests/api-tests/teamApiTest.test.js +++ b/frontend/react-app/src/tests/api-tests/teamApiTest.test.js @@ -1,4 +1,4 @@ -import { createTeam, deleteTeam, changeTeamLead, getTeamMembers, getTeamTasks } from '../../api/teamApi'; +import { createTeam, deleteTeam, changeTeamLead, getTeamMembers, getTeamTasks, getTeams } from '../../api/teamApi'; const BASE_URL = "http://localhost:8080/api/teams"; @@ -66,6 +66,21 @@ describe('Team API', () => { expect(result).toEqual(updatedTeam); }); + //test: getting all teams + test('getTeams should return list of team members on success', async () => { + const mockTeams = [ + { teamId: 1, teamName: "Team Alpha", teamLeadId: 3 }, + { teamId: 2, teamName: "Team Beta", teamLeadId: 4 } + ]; + + fetch.mockResponseOnce(JSON.stringify(mockTeams), { status: 200 }); + + const result = await getTeams(); + + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}`, { method: 'GET' }); + expect(result).toEqual(mockTeams); + }); + //test: getting all team members test('getTeamMembers should return team data on success', async () => { fetch.mockResponseOnce(JSON.stringify(true), { status: 200 }); diff --git a/frontend/react-app/src/tests/api-tests/teamMemberAccountApiTest.test.js b/frontend/react-app/src/tests/api-tests/teamMemberAccountApiTest.test.js new file mode 100644 index 00000000..1994de57 --- /dev/null +++ b/frontend/react-app/src/tests/api-tests/teamMemberAccountApiTest.test.js @@ -0,0 +1,107 @@ +import { createTeamMember, modifyTeamMemberEmail, modifyTeamMemberName, getTeamMemberById, deleteTeamMember} from '../../api/teamMemberAccountApi'; + +const BASE_URL = "http://localhost:8080/api/members"; + +beforeEach(() => { + fetch.resetMocks(); +}); + +describe('Team Member Account API', () => { + + //test: creating team member + test('createTeamMember should return team member data on success', async () => { + const mockTeamMember = { + name: "Test TM", + email: "test_tm@example.com", + password: "tm_password" + }; + + fetch.mockResponseOnce(JSON.stringify(mockTeamMember), { status: 200 }); + + const result = await createTeamMember("Test TM", "test_tm@example.com", "tm_password"); + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}`, { + method: 'POST', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + name: "Test TM", + email: "test_tm@example.com", + password: "tm_password" + }) + }); + + expect(result).toEqual(mockTeamMember); + }); + + //test: modify team member name + test('modifyTeamMemberName should return new team member data on success', async () => { + const updatedTeamMember = { + teamMemberId: 1, + newName: "New TMName" + }; + + fetch.mockResponseOnce(JSON.stringify(updatedTeamMember), { status: 200 }); + + const result = await modifyTeamMemberName(1, "New TMName"); + + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1/name`, { + method: 'PUT', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + newName: "New TMName" + }) + }); + + expect(result).toEqual(updatedTeamMember); + }); + + //test: modify team member email + test('modifyTeamMemberEmail should return new team member data on success', async () => { + const updatedTeamMember = { + teamMemberId: 1, + newEmail: "new@example.com" + }; + + fetch.mockResponseOnce(JSON.stringify(updatedTeamMember), { status: 200 }); + + const result = await modifyTeamMemberEmail(1, "new@example.com"); + + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1/email`, { + method: 'PUT', + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + newEmail: "new@example.com" + }) + }); + + expect(result).toEqual(updatedTeamMember); + }); + + //test: deleting a team member + test('deleteTeamMember should return true on success', async () => { + fetch.mockResponseOnce('', { status: 204 }); + + const result = await deleteTeamMember(1); + + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1`, { + method: 'DELETE' + }); + + expect(result).toBe(true); + }); + + //test: retrieving team emember info with ID + test('getTeamMemberById should return team member data on success', async () => { + const mockTeamMember = { + accountId: 2, + userName: "John Doe", + userEmail: "john.doe@example.com" + }; + + fetch.mockResponseOnce(JSON.stringify(mockTeamMember), { status: 200 }); + + const result = await getTeamMemberById(2); + + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/2`, { method: 'GET' }); + expect(result).toEqual(mockTeamMember); + }); +}); \ No newline at end of file diff --git a/frontend/react-app/src/tests/api-tests/teamMemberApiTest.test.js b/frontend/react-app/src/tests/api-tests/teamMemberApiTest.test.js index 77f3f182..9716fc6e 100644 --- a/frontend/react-app/src/tests/api-tests/teamMemberApiTest.test.js +++ b/frontend/react-app/src/tests/api-tests/teamMemberApiTest.test.js @@ -1,90 +1,12 @@ -import { createTask, deleteTask, editTask, assignMemberToTask, changePassword, resetPassword, getTeamsForMember, getAssignedTasks, massAssignMemberToTask } from '../../api/teamMemberApi'; +import { assignMemberToTask, changePassword, getTeamsForMember, getAssignedTasks, massAssignMemberToTask } from '../../api/teamMemberApi'; -const BASE_URL = "http://localhost:8080/api/tasks"; +const BASE_URL = "http://localhost:8080/api/members/actions"; beforeEach(() => { fetch.resetMocks(); }); describe('Team Member API', () => { - //test: creating a task - test('createTask should return task data on sucess', async () => { - const mockTask = { - id: 1, - title: "New Task", - description: "Task description", - isLocked: false, - status: "To-Do", - dueDate: "4-14-2025", - teamId: 2 - }; - - fetch.mockResponseOnce(JSON.stringify(mockTask), {status: 201}); - - const result = await createTask("New Task", "Task description", false, "To-Do", "4-14-2025", 2, "LOW"); - - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}`, { - method: 'POST', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - title: "New Task", - description: "Task description", - isLocked: false, - status: "To-Do", - dueDate: "4-14-2025", - teamId: 2, - priority: "LOW" - }) - }); - - expect(result).toEqual(mockTask); - }); - - //test: deleting a task - test('deleteTask should return true on success', async () => { - fetch.mockResponseOnce('', { status: 204 }); - - const result = await deleteTask(1); - - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1`, { - method: 'DELETE' - }); - - expect(result).toBe(true); - }); - - //test: editing a task - test('editTask should return updated task data on success', async () => { - const updatedTask = { - id: 1, - title: "Updated task", - description: "Updated description", - isLocked: true, - status: "In progress", - dueDate: "2025-03-01", - priority: "HIGH" - }; - - fetch.mockResponseOnce(JSON.stringify(updatedTask), { status: 200 }); - - const result = await editTask(1, "Updated Task", "Updated description", true, "In progress", "2025-03-01", "HIGH"); - - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/1`, { - method: 'PUT', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - title: "Updated Task", - description: "Updated description", - isLocked: true, - status: "In progress", - dueDate: "2025-03-01", - priority: "HIGH" - }) - }); - - expect(result).toEqual(updatedTask); - }); - //test: assigning a memebr to a task test('assignMemberToTask should return task assignment data on sucess', async () => { const mockResponse = { @@ -136,7 +58,7 @@ describe('Team Member API', () => { const result = await changePassword(5, "oldPassword", "newPassword"); - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/team-members/5/change-password`, { + expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/5/change-password`, { method: 'POST', headers: { "Content-Type": "application/json" }, body: JSON.stringify({oldPassword: "oldPassword", newPassword: "newPassword"}) @@ -145,22 +67,7 @@ describe('Team Member API', () => { expect(result).toEqual(mockResponse); }); - //test: resetting a password - test('resetPassword should return success on valid password reset', async () => { - const mockResponse = true; - - fetch.mockResponseOnce(JSON.stringify(mockResponse), { status: 200 }); - - const result = await resetPassword(1, "DefLeppard"); - - expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/team-members/1/reset-password`, { - method: 'POST', - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ newPassword: "DefLeppard" }) - }); - - expect(result).toEqual(mockResponse); - }) + //test: getting all teams for a team member test('getTeamsForMember should return json body on success', async () => {