From b8e154d4b85975c687fbec8a5ad5d290f935fa81 Mon Sep 17 00:00:00 2001
From: Filip Filchev <filip.filchev@paysafe.com>
Date: Tue, 18 Jul 2023 12:37:22 +0300
Subject: [PATCH] Add Post and Put Requests

Add Response Entity
---
 .../Product/InMemoryProductDatabase.java      |  2 +
 .../Database/User/InMemoryUserDatabase.java   |  2 +
 .../ShoppingBasketApplication.java            | 89 ++++++++++++-------
 .../User/DefaultUserService.java              |  6 +-
 .../java/ShoppingBasket/User/Response.java    |  6 ++
 src/main/java/ShoppingBasket/User/User.java   | 13 +--
 .../java/ShoppingBasket/User/UserService.java |  2 +-
 7 files changed, 79 insertions(+), 41 deletions(-)
 create mode 100644 src/main/java/ShoppingBasket/User/Response.java

diff --git a/src/main/java/ShoppingBasket/Database/Product/InMemoryProductDatabase.java b/src/main/java/ShoppingBasket/Database/Product/InMemoryProductDatabase.java
index 7077ea0..c39e54b 100644
--- a/src/main/java/ShoppingBasket/Database/Product/InMemoryProductDatabase.java
+++ b/src/main/java/ShoppingBasket/Database/Product/InMemoryProductDatabase.java
@@ -7,6 +7,7 @@ import ShoppingBasket.Database.Exceptions.ProductNotFoundException;
 import ShoppingBasket.User.Exceptions.NoOrdersByUserException;
 import ShoppingBasket.User.Exceptions.UserNotFoundException;
 import ShoppingBasket.User.User;
+import org.springframework.stereotype.Repository;
 
 import java.io.IOException;
 import java.nio.file.Files;
@@ -17,6 +18,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Stream;
 
+@Repository
 public class InMemoryProductDatabase implements ProductDatabase {
     private static final int AMOUNT = 2;
     private static final String DUMMY_PASSWORD = "alabala";
diff --git a/src/main/java/ShoppingBasket/Database/User/InMemoryUserDatabase.java b/src/main/java/ShoppingBasket/Database/User/InMemoryUserDatabase.java
index e7b7d81..a3eef21 100644
--- a/src/main/java/ShoppingBasket/Database/User/InMemoryUserDatabase.java
+++ b/src/main/java/ShoppingBasket/Database/User/InMemoryUserDatabase.java
@@ -3,6 +3,7 @@ package ShoppingBasket.Database.User;
 import ShoppingBasket.User.Exceptions.UserAlreadyRegisteredException;
 import ShoppingBasket.User.Exceptions.UserNotFoundException;
 import ShoppingBasket.User.User;
+import org.springframework.stereotype.Repository;
 
 import java.io.IOException;
 import java.nio.file.Files;
@@ -14,6 +15,7 @@ import java.util.stream.Stream;
 /*
    Mimics a DataBase
  */
+@Repository
 public class InMemoryUserDatabase implements UserDatabase {
     private static final String USERS_FILE_NAME = "users.csv";
     private final Set<User> users;
diff --git a/src/main/java/ShoppingBasket/ShoppingBasketApplication.java b/src/main/java/ShoppingBasket/ShoppingBasketApplication.java
index 8ee83b9..a25e4b7 100644
--- a/src/main/java/ShoppingBasket/ShoppingBasketApplication.java
+++ b/src/main/java/ShoppingBasket/ShoppingBasketApplication.java
@@ -2,36 +2,46 @@ package ShoppingBasket;
 
 import ShoppingBasket.Basket.Basket;
 import ShoppingBasket.Basket.Product;
-import ShoppingBasket.Database.Product.InMemoryProductDatabase;
 import ShoppingBasket.Database.Product.ProductDatabase;
-import ShoppingBasket.Database.User.InMemoryUserDatabase;
 import ShoppingBasket.Database.User.UserDatabase;
-import ShoppingBasket.User.DefaultUserService;
 import ShoppingBasket.User.Exceptions.InvalidRequestException;
 import ShoppingBasket.User.Exceptions.UserNotFoundException;
 import ShoppingBasket.User.Exceptions.UserNotLoggedInException;
 import ShoppingBasket.User.Exceptions.UserNotRegisteredException;
+import ShoppingBasket.User.Response;
 import ShoppingBasket.User.User;
 import ShoppingBasket.User.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.List;
 import java.util.Map;
 
-
 @SpringBootApplication
 public class ShoppingBasketApplication {
     private static final String DUMMY_PASSWORD = "alabala";
     private static ConfigurableApplicationContext cac;
-    private final UserDatabase userDatabase = new InMemoryUserDatabase();
-    private final ProductDatabase productDatabase = new InMemoryProductDatabase();
 
-    private final UserService userService = new DefaultUserService();
+    private final UserDatabase userDatabase;
+    private final ProductDatabase productDatabase;
+    private final UserService userService;
+
+    @Autowired
+    public ShoppingBasketApplication(UserDatabase userDatabase, ProductDatabase productDatabase,
+                                     UserService userService) {
+        this.userDatabase = userDatabase;
+        this.productDatabase = productDatabase;
+        this.userService = userService;
+    }
 
     public static void main(String[] args) {
         cac = SpringApplication.run(ShoppingBasketApplication.class, args);
@@ -69,65 +79,71 @@ public class ShoppingBasketApplication {
 
     @RestController
     public class UserController {
-        @GetMapping("/register")
-        public String register(@RequestParam(value = "username", defaultValue = "unknown") String username, @RequestParam(value = "password", defaultValue = "unknown") String password) {
+        @PostMapping("/register")
+        public ResponseEntity<Response<User>> register(
+            @RequestParam(value = "username", defaultValue = "unknown") String username,
+            @RequestParam(value = "password", defaultValue = "unknown") String password) {
             System.out.println(username + " requested register");
 
+            User user;
             try {
                 validateRequestUsername(username);
                 validateRequestPassword(password);
 
                 userDatabase.registerUser(username, password);
 
-                User user = new User(username, password);
+                user = new User(username, password);
                 productDatabase.addNewUser(user);
 
-                userService.logIn(user, password);
+                userService.logIn(user);
             } catch (Exception e) {
-                return e.getMessage();
+                return ResponseEntity.badRequest().body(new Response<>(e.getMessage(), null));
             }
 
-            return "Registered and Logged in Successfully";
+            return ResponseEntity.ok().body(new Response<>("User registered successfully", user));
         }
 
-        @GetMapping("/login")
-        public String login(@RequestParam(value = "username", defaultValue = "unknown") String username, @RequestParam(value = "password", defaultValue = "unknown") String password) {
-            System.out.println(username + " requested login");
+        @PutMapping("/login")
+        public ResponseEntity<Response<User>> login(@RequestBody User user) {
+            System.out.println(user.getUsername() + " requested login");
 
             try {
-                validateRequestUsername(username);
-                validateRequestPassword(password);
-
-                User user = userDatabase.getUser(username);
-
+                if (!userDatabase.isRegistered(user)) {
+                    return ResponseEntity.badRequest().body(new Response<>("User not registered", user));
+                }
                 productDatabase.addNewUser(user);
 
                 validateRegistered(user);
 
-                userService.logIn(user, password);
+                userService.logIn(user);
             } catch (Exception e) {
-                return e.getMessage();
+                return ResponseEntity.badRequest().body(new Response<>(e.getMessage(), user));
+
             }
 
-            return "Logged In Successfully";
+            return ResponseEntity.ok().body(new Response<>("User logged in successfully", user));
+
         }
 
         @GetMapping("/logout")
-        public String logout(@RequestParam(value = "username", defaultValue = "unknown") String username) {
+        public ResponseEntity<Response<User>> logout(
+            @RequestParam(value = "username", defaultValue = "unknown") String username) {
             System.out.println(username + " requested logout");
 
+            User user;
             try {
                 validateRequestUsername(username);
 
-                User user = new User(username, DUMMY_PASSWORD);
+                user = new User(username, DUMMY_PASSWORD);
 
                 validateLoggedIn(user);
                 userService.logOut(user);
             } catch (Exception e) {
-                return e.getMessage();
+                return ResponseEntity.badRequest().body(new Response<>(e.getMessage(), null));
+
             }
 
-            return "Logged Out Successfully";
+            return ResponseEntity.ok().body(new Response<>("User logged out successfully", user));
         }
     }
 
@@ -135,7 +151,8 @@ public class ShoppingBasketApplication {
     public class RequestsController {
 
         @GetMapping("/deposit")
-        public String deposit(@RequestParam(value = "username", defaultValue = "unknown") String username, @RequestParam(value = "amount", defaultValue = "unknown") String amount) {
+        public String deposit(@RequestParam(value = "username", defaultValue = "unknown") String username,
+                              @RequestParam(value = "amount", defaultValue = "unknown") String amount) {
             System.out.println(username + " requested deposit: " + amount);
 
             User user;
@@ -220,7 +237,8 @@ public class ShoppingBasketApplication {
         }
 
         @GetMapping("/search")
-        public String search(@RequestParam(value = "username", defaultValue = "unknown") String username, @RequestParam(value = "keyword", defaultValue = "unknown") String keyword) {
+        public String search(@RequestParam(value = "username", defaultValue = "unknown") String username,
+                             @RequestParam(value = "keyword", defaultValue = "unknown") String keyword) {
             System.out.println(username + " requested search");
 
             User user;
@@ -239,7 +257,9 @@ public class ShoppingBasketApplication {
         }
 
         @GetMapping("/add")
-        public String add(@RequestParam(value = "username", defaultValue = "unknown") String username, @RequestParam(value = "product", defaultValue = "unknown") String product, @RequestParam(value = "amount", defaultValue = "unknown") String amount) {
+        public String add(@RequestParam(value = "username", defaultValue = "unknown") String username,
+                          @RequestParam(value = "product", defaultValue = "unknown") String product,
+                          @RequestParam(value = "amount", defaultValue = "unknown") String amount) {
             System.out.println(username + " requested add");
 
             User user;
@@ -271,7 +291,9 @@ public class ShoppingBasketApplication {
         }
 
         @GetMapping("/remove")
-        public String remove(@RequestParam(value = "username", defaultValue = "unknown") String username, @RequestParam(value = "product", defaultValue = "unknown") String product, @RequestParam(value = "amount", defaultValue = "unknown") String amount) {
+        public String remove(@RequestParam(value = "username", defaultValue = "unknown") String username,
+                             @RequestParam(value = "product", defaultValue = "unknown") String product,
+                             @RequestParam(value = "amount", defaultValue = "unknown") String amount) {
             System.out.println(username + " requested remove");
 
             User user;
@@ -410,7 +432,8 @@ public class ShoppingBasketApplication {
                 return e.getMessage();
             }
 
-            StringBuilder builder = new StringBuilder("product,price,amount...:total price").append(System.lineSeparator());
+            StringBuilder builder =
+                new StringBuilder("product,price,amount...:total price").append(System.lineSeparator());
 
             for (String order : orders) {
                 builder.append(order).append(System.lineSeparator());
diff --git a/src/main/java/ShoppingBasket/User/DefaultUserService.java b/src/main/java/ShoppingBasket/User/DefaultUserService.java
index b793441..99cbbaf 100644
--- a/src/main/java/ShoppingBasket/User/DefaultUserService.java
+++ b/src/main/java/ShoppingBasket/User/DefaultUserService.java
@@ -3,10 +3,12 @@ package ShoppingBasket.User;
 import ShoppingBasket.User.Exceptions.InvalidPasswordException;
 import ShoppingBasket.User.Exceptions.UserAlreadyLoggedInException;
 import ShoppingBasket.User.Exceptions.UserNotLoggedInException;
+import org.springframework.stereotype.Service;
 
 import java.util.HashSet;
 import java.util.Set;
 
+@Service
 public class DefaultUserService implements UserService {
     private final Set<User> loggedInUsers;
 
@@ -15,12 +17,12 @@ public class DefaultUserService implements UserService {
     }
 
     @Override
-    public void logIn(User user, String password) throws UserAlreadyLoggedInException, InvalidPasswordException {
+    public void logIn(User user) throws UserAlreadyLoggedInException, InvalidPasswordException {
         if (loggedInUsers.contains(user)) {
             throw new UserAlreadyLoggedInException("User with username: " + user.getUsername() + " is already logged in");
         }
 
-        if (!user.comparePassword(password)) {
+        if (!user.comparePassword(user)) {
             throw new InvalidPasswordException("Incorrect password for User with Username: " + user.getUsername());
         }
 
diff --git a/src/main/java/ShoppingBasket/User/Response.java b/src/main/java/ShoppingBasket/User/Response.java
new file mode 100644
index 0000000..a848750
--- /dev/null
+++ b/src/main/java/ShoppingBasket/User/Response.java
@@ -0,0 +1,6 @@
+package ShoppingBasket.User;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public record Response<T>(@JsonProperty("ResponseMessage") String message, T object) {
+}
diff --git a/src/main/java/ShoppingBasket/User/User.java b/src/main/java/ShoppingBasket/User/User.java
index 18d87cf..a7280d2 100644
--- a/src/main/java/ShoppingBasket/User/User.java
+++ b/src/main/java/ShoppingBasket/User/User.java
@@ -1,6 +1,7 @@
 package ShoppingBasket.User;
 
 import ShoppingBasket.User.Exceptions.NotEnoughBalanceException;
+import org.springframework.stereotype.Component;
 
 import java.util.Objects;
 
@@ -41,7 +42,7 @@ public class User {
     }
 
     public double withdraw(double sum) throws NotEnoughBalanceException {
-        if(balance < sum) {
+        if (balance < sum) {
             throw new NotEnoughBalanceException("Not enough balance for the transaction");
         }
 
@@ -58,14 +59,16 @@ public class User {
         return balance;
     }
 
-    public boolean comparePassword(String password) {
-        return this.password.equals(password);
+    public boolean comparePassword(User user) {
+        return this.password.equals(user.password);
     }
 
     @Override
     public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
         User user = (User) o;
         return Objects.equals(username, user.username);
     }
diff --git a/src/main/java/ShoppingBasket/User/UserService.java b/src/main/java/ShoppingBasket/User/UserService.java
index db0889f..4630850 100644
--- a/src/main/java/ShoppingBasket/User/UserService.java
+++ b/src/main/java/ShoppingBasket/User/UserService.java
@@ -6,7 +6,7 @@ import ShoppingBasket.User.Exceptions.UserNotLoggedInException;
 
 public interface UserService {
 
-    void logIn(User user, String password) throws UserAlreadyLoggedInException, InvalidPasswordException;
+    void logIn(User user) throws UserAlreadyLoggedInException, InvalidPasswordException;
 
     void logOut(User user) throws UserNotLoggedInException;
 
-- 
GitLab