From ed0e4e357d3c8b96d5eedc72ab3c13e5746a0a75 Mon Sep 17 00:00:00 2001
From: Anders Austlid <andemau@ntnu.no>
Date: Fri, 28 Apr 2023 10:26:29 +0200
Subject: [PATCH] GroupController POST group and POST connection endpoints have
 been fixed

---
 .../v233/SmartMat/config/CorsConfig.java      |  2 +-
 .../controller/group/GroupController.java     | 95 ++++++++++++++-----
 .../group/UserGroupAssoRepository.java        |  5 +
 .../SmartMat/service/group/GroupService.java  | 19 ++++
 4 files changed, 96 insertions(+), 25 deletions(-)

diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/config/CorsConfig.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/config/CorsConfig.java
index 89269aec..8c238f9a 100644
--- a/src/main/java/ntnu/idatt2016/v233/SmartMat/config/CorsConfig.java
+++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/config/CorsConfig.java
@@ -35,7 +35,7 @@ public class CorsConfig {
             public void addCorsMappings(CorsRegistry registry) {
                 registry.addMapping("/**")
                         .allowedOrigins(Arrays.asList("https://localhost",
-                                "https://10.24.21.135",
+                                "https://10.24.38.136",
                                 domainProperty.domain()
                         ).toArray(String[]::new))
                         .allowedMethods(Arrays.asList(
diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/controller/group/GroupController.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/controller/group/GroupController.java
index d895eb6f..356e8000 100644
--- a/src/main/java/ntnu/idatt2016/v233/SmartMat/controller/group/GroupController.java
+++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/controller/group/GroupController.java
@@ -6,12 +6,16 @@ import ntnu.idatt2016.v233.SmartMat.dto.request.group.GroupRequest;
 import ntnu.idatt2016.v233.SmartMat.dto.response.group.GroupResponse;
 import ntnu.idatt2016.v233.SmartMat.entity.group.Group;
 import ntnu.idatt2016.v233.SmartMat.entity.group.UserGroupAsso;
+import ntnu.idatt2016.v233.SmartMat.entity.group.UserGroupId;
+import ntnu.idatt2016.v233.SmartMat.entity.user.User;
 import ntnu.idatt2016.v233.SmartMat.service.group.GroupService;
 import ntnu.idatt2016.v233.SmartMat.service.user.UserService;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 
 /**
@@ -57,25 +61,41 @@ public class GroupController {
      * Creates a new group
      *
      * @param groupRequest the group to create
-     * @return a ResponseEntity containing the created group if it was created successfully, or a 400 if it wasn't
+     * @return a ResponseEntity containing the created group if it was created successfully,
+     * or a 400 if the group name is invalid or already exists, or if the username is invalid
      */
     @PostMapping("/group")
-    public ResponseEntity<GroupResponse> createGroup(@RequestBody GroupRequest groupRequest) {
+    public ResponseEntity<?> createGroup(@RequestBody GroupRequest groupRequest) {
+        if (groupRequest.groupName() == null || groupRequest.groupName().trim().length() < 3) {
+            return ResponseEntity.badRequest().body("Group name must be at least 3 characters long.");
+        }
+
+        if (groupService.getGroupByName(groupRequest.groupName()).isPresent()) {
+            return ResponseEntity.badRequest().body("Group name already exists.");
+        }
 
-        if(groupRequest.groupName().equals("") ||
-                userService.getUserFromUsername(groupRequest.username()).isEmpty() ||
-                groupService.getGroupByName(groupRequest.groupName()).isPresent()) {
-            return ResponseEntity.badRequest().build();
+        Optional<User> optionalUser = userService.getUserFromUsername(groupRequest.username());
+        if (optionalUser.isEmpty()) {
+            return ResponseEntity.badRequest().body("Invalid username.");
         }
 
         Group group = new Group();
         group.setGroupName(groupRequest.groupName());
-
         Group createdGroup = groupService.createGroup(group);
+
+        User user = optionalUser.get();
+
+        UserGroupId userGroupId = UserGroupId.builder()
+                .username(user.getUsername())
+                .groupId(createdGroup.getGroupId())
+                .build();
+
         createdGroup.addUser(UserGroupAsso.builder()
-                        .groupAuthority("ADMIN")
-                        .group(createdGroup)
-                        .user(userService.getUserFromUsername(groupRequest.username()).get())
+                .id(userGroupId)
+                .primaryGroup(false)
+                .groupAuthority("ADMIN")
+                .group(createdGroup)
+                .user(user)
                 .build());
 
         GroupResponse groupResponse = new GroupResponse(createdGroup.getGroupId(), createdGroup.getLinkCode());
@@ -85,6 +105,7 @@ public class GroupController {
         return ResponseEntity.ok(groupResponse);
     }
 
+
     /**
      * Gets the level of a group
      *
@@ -189,22 +210,48 @@ public class GroupController {
      *         or a ResponseEntity object with an HTTP status code indicating that the request was not successful
      */
     @PostMapping("/connection")
-    public ResponseEntity<?> addConnection(@RequestBody GroupConnectionRequest groupConnectionRequest){
-        return groupService.getGroupByLinkCode(groupConnectionRequest.linkCode())
-                .flatMap(group -> userService.getUserFromUsername(groupConnectionRequest.username())
-                        .flatMap(user -> {
-                            UserGroupAsso userGroupAsso = UserGroupAsso.builder()
-                                    .group(group)
-                                    .user(user)
-                                    .build();
-                            user.addGroup(userGroupAsso);
-                            userService.updateUser(user);
-                            return Optional.of(userGroupAsso);
-                        }))
-                .map(ResponseEntity::ok)
-                .orElseGet(() -> ResponseEntity.notFound().build());
+    public ResponseEntity<?> addConnection(@RequestBody GroupConnectionRequest groupConnectionRequest) {
+        Optional<Group> optionalGroup = groupService.getGroupByLinkCode(groupConnectionRequest.linkCode());
+
+        if (optionalGroup.isEmpty()) {
+            return ResponseEntity.badRequest().body("Invalid link code.");
+        }
+
+        Optional<User> optionalUser = userService.getUserFromUsername(groupConnectionRequest.username());
+
+        if (optionalUser.isEmpty()) {
+            return ResponseEntity.badRequest().body("Invalid username.");
+        }
+
+        Group group = optionalGroup.get();
+        User user = optionalUser.get();
+
+        if (groupService.isUserAssociatedWithGroup(user.getUsername(), group.getGroupId())) {
+            return ResponseEntity.badRequest().body("User is already associated with the group.");
+        }
+
+        UserGroupId userGroupId = UserGroupId.builder()
+                .username(user.getUsername())
+                .groupId(group.getGroupId())
+                .build();
+
+        UserGroupAsso userGroupAsso = UserGroupAsso.builder()
+                .id(userGroupId)
+                .group(group)
+                .user(user)
+                .build();
+
+        user.addGroup(userGroupAsso);
+        userService.updateUser(user);
+
+        Map<String, Object> responseBody = new HashMap<>();
+        responseBody.put("groupId", group.getGroupId());
+        responseBody.put("username", user.getUsername());
+
+        return ResponseEntity.ok(responseBody);
     }
 
+
     /**
      * Changes the authority level of a user in a group.
      *
diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/repository/group/UserGroupAssoRepository.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/repository/group/UserGroupAssoRepository.java
index 12cbc628..1580965a 100644
--- a/src/main/java/ntnu/idatt2016/v233/SmartMat/repository/group/UserGroupAssoRepository.java
+++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/repository/group/UserGroupAssoRepository.java
@@ -50,4 +50,9 @@ public interface UserGroupAssoRepository extends JpaRepository<UserGroupAsso, Us
      *         or an empty optional if no such user-group associations exist in the database
      */
     Optional<UserGroupAsso> findFirstByUserAndPrimaryGroup(User user, boolean primaryGroup);
+
+    /**
+     * Finds UserGroupAsso by UserGroupId
+     */
+    Optional<UserGroupAsso> findByUserGroupId(UserGroupId userGroupId);
 }
diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/GroupService.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/GroupService.java
index 83428ebe..5091a870 100644
--- a/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/GroupService.java
+++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/service/group/GroupService.java
@@ -4,9 +4,11 @@ import lombok.AllArgsConstructor;
 import ntnu.idatt2016.v233.SmartMat.entity.ShoppingList;
 import ntnu.idatt2016.v233.SmartMat.entity.group.Fridge;
 import ntnu.idatt2016.v233.SmartMat.entity.group.Group;
+import ntnu.idatt2016.v233.SmartMat.entity.group.UserGroupId;
 import ntnu.idatt2016.v233.SmartMat.repository.ShoppingListRepository;
 import ntnu.idatt2016.v233.SmartMat.repository.group.FridgeRepository;
 import ntnu.idatt2016.v233.SmartMat.repository.group.GroupRepository;
+import ntnu.idatt2016.v233.SmartMat.repository.group.UserGroupAssoRepository;
 import ntnu.idatt2016.v233.SmartMat.util.GroupUtil;
 import org.springframework.stereotype.Service;
 
@@ -26,6 +28,8 @@ public class GroupService {
 
     private final GroupRepository groupRepository;
 
+    private final UserGroupAssoRepository userGroupAssoRepository;
+
     private final FridgeRepository fridgeRepository;
     private ShoppingListRepository shoppingListRepository;
 
@@ -160,4 +164,19 @@ public class GroupService {
     public Optional<Group> getGroupByLinkCode(String linkCode) {
         return groupRepository.findByLinkCode(linkCode);
     }
+
+    /**
+     * Checks if a user is associated with a group
+     * @param username the username of the user
+     * @param groupId the id of the group
+     * @return true if the user is associated with the group, false otherwise
+     */
+    public boolean isUserAssociatedWithGroup(String username, Long groupId) {
+        UserGroupId userGroupId = UserGroupId.builder()
+                .username(username)
+                .groupId(groupId)
+                .build();
+
+        return userGroupAssoRepository.findById(userGroupId).isPresent();
+    }
 }
-- 
GitLab