From aabc0bff5a20ebbe70fc4a048ae8b2e5680e0212 Mon Sep 17 00:00:00 2001
From: sasmitmati <sasmitmati98@gmail.com>
Date: Tue, 19 Nov 2024 22:39:13 +0530
Subject: [PATCH 1/2] Chain of Responsibility design pattern implementation

---
 pom.xml                                       |   4 +
 .../iss/shopsmart_backend/chains/Chain.java   |  10 +
 .../chains/GenerateOtpForLoginChain.java      |  77 ++
 .../chains/GenerateOtpForRegisterChain.java   |  75 ++
 .../chains/ValidateOtpAndLoginChain.java      |  69 ++
 .../chains/ValidateOtpAndRegisterChain.java   |  72 ++
 .../controller/ProfileController.java         |  27 +-
 .../handlers/CheckProfileExistsHandler.java   |  77 ++
 .../handlers/CreateProfileHandler.java        |  59 ++
 .../handlers/FetchUserIdForEmailHandler.java  |  67 ++
 .../handlers/GenerateOtpHandler.java          |  68 ++
 .../shopsmart_backend/handlers/Handler.java   |  12 +
 .../handlers/ValidateOtpHandler.java          |  70 ++
 .../model/ApiRequestResolver.java             |  16 +
 .../service/ProfileService.java               | 431 ++++-----
 .../utils/ApplicationConstants.java           |   1 +
 .../controller/ProfileControllerTest.java     |  23 +-
 .../CheckProfileExistsHandlerTest.java        | 125 +++
 .../handlers/CreateProfileHandlerTest.java    |  78 ++
 .../FetchUserIdForEmailHandlerTest.java       |  96 ++
 .../handlers/GenerateOtpHandlerTest.java      |  98 ++
 .../handlers/ValidateOtpHandlerTest.java      | 103 ++
 .../service/ProfileServiceTest.java           | 903 +++++++++++-------
 23 files changed, 1967 insertions(+), 594 deletions(-)
 create mode 100644 src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/Chain.java
 create mode 100644 src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/GenerateOtpForLoginChain.java
 create mode 100644 src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/GenerateOtpForRegisterChain.java
 create mode 100644 src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/ValidateOtpAndLoginChain.java
 create mode 100644 src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/ValidateOtpAndRegisterChain.java
 create mode 100644 src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/CheckProfileExistsHandler.java
 create mode 100644 src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/CreateProfileHandler.java
 create mode 100644 src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/FetchUserIdForEmailHandler.java
 create mode 100644 src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/GenerateOtpHandler.java
 create mode 100644 src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/Handler.java
 create mode 100644 src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/ValidateOtpHandler.java
 create mode 100644 src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/CheckProfileExistsHandlerTest.java
 create mode 100644 src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/CreateProfileHandlerTest.java
 create mode 100644 src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/FetchUserIdForEmailHandlerTest.java
 create mode 100644 src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/GenerateOtpHandlerTest.java
 create mode 100644 src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/ValidateOtpHandlerTest.java

diff --git a/pom.xml b/pom.xml
index 6ecd988..940db9a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,8 +29,10 @@
 	<properties>
 		<java.version>21</java.version>
 		<sonar.coverage.exclusions>**/sg/edu/nus/iss/shopsmart_backend/ShopsmartBackendApplication.java,
+			**/sg/edu/nus/iss/shopsmart_backend/chains/**,
 			**/sg/edu/nus/iss/shopsmart_backend/config/**,
 			**/sg/edu/nus/iss/shopsmart_backend/exception/**,
+			**/sg/edu/nus/iss/shopsmart_backend/handlers/Handler.java,
 			**/sg/edu/nus/iss/shopsmart_backend/model/**,
 			**/sg/edu/nus/iss/shopsmart_backend/service/CommonService.java,
 			**/sg/edu/nus/iss/shopsmart_backend/utils/**</sonar.coverage.exclusions>
@@ -134,8 +136,10 @@
 						<exclude>sg/edu/nus/iss/shopsmart_backend/HomeController.class</exclude>
 						<exclude>sg/edu/nus/iss/shopsmart_backend/ShopsmartBackendApplication.class</exclude>
 						<!-- Exclude all classes in the model package from code coverage -->
+						<exclude>sg/edu/nus/iss/shopsmart_backend/chains/**</exclude>
 						<exclude>sg/edu/nus/iss/shopsmart_backend/config/**</exclude>
 						<exclude>sg/edu/nus/iss/shopsmart_backend/exception/**</exclude>
+						<exclude>sg/edu/nus/iss/shopsmart_backend/handlers/Handler.class</exclude>
 						<exclude>sg/edu/nus/iss/shopsmart_backend/model/**</exclude>
 						<exclude>sg/edu/nus/iss/shopsmart_backend/service/CommonService.class</exclude>
 						<exclude>sg/edu/nus/iss/shopsmart_backend/utils/**</exclude>
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/Chain.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/Chain.java
new file mode 100644
index 0000000..c914a54
--- /dev/null
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/Chain.java
@@ -0,0 +1,10 @@
+package sg.edu.nus.iss.shopsmart_backend.chains;
+
+import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
+
+import java.util.concurrent.CompletableFuture;
+
+public interface Chain {
+    CompletableFuture<ApiResponseResolver> handleRequest(ApiRequestResolver request, String profileType);
+}
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/GenerateOtpForLoginChain.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/GenerateOtpForLoginChain.java
new file mode 100644
index 0000000..cd9b246
--- /dev/null
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/GenerateOtpForLoginChain.java
@@ -0,0 +1,77 @@
+package sg.edu.nus.iss.shopsmart_backend.chains;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import io.swagger.v3.core.util.Json;
+import lombok.Getter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Service;
+import sg.edu.nus.iss.shopsmart_backend.handlers.FetchUserIdForEmailHandler;
+import sg.edu.nus.iss.shopsmart_backend.handlers.GenerateOtpHandler;
+import sg.edu.nus.iss.shopsmart_backend.handlers.Handler;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
+import sg.edu.nus.iss.shopsmart_backend.service.ProfileService;
+import sg.edu.nus.iss.shopsmart_backend.utils.Constants;
+
+import java.util.concurrent.CompletableFuture;
+
+@Service
+public class GenerateOtpForLoginChain extends Constants implements Chain{
+    private static final Logger log = LoggerFactory.getLogger(GenerateOtpForLoginChain.class);
+    private final ObjectMapper mapper = Json.mapper();
+
+    @Getter
+    private final Handler handlerChain;
+    private final ProfileService profileService;
+
+    @Autowired
+    public GenerateOtpForLoginChain(ProfileService profileService) {
+        this.profileService = profileService;
+        Handler fetchUserIdForEmailHandler = new FetchUserIdForEmailHandler(profileService);
+        Handler generateOtpHandler = new GenerateOtpHandler(profileService);
+
+        generateOtpHandler.setNext(null);
+        fetchUserIdForEmailHandler.setNext(generateOtpHandler);
+
+        this.handlerChain = fetchUserIdForEmailHandler;
+    }
+
+    @Override
+    public CompletableFuture<ApiResponseResolver> handleRequest(ApiRequestResolver apiRequestResolver, String profileType) {
+        log.info("Starting GenerateOtpForLoginChain, for apiRequestResolver : {}, and profileType {}", apiRequestResolver, profileType);
+        log.info("{} Generating OTP for profile login with requestObt : {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
+        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
+        ObjectNode data = mapper.createObjectNode();
+        JsonNode payload = apiRequestResolver.getRequestBody();
+        if(payload.isNull() || payload.isEmpty()){
+            log.info("{} No request body found for opt generation for login", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
+            data.put(MESSAGE, "No request body found for otp generation for email");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        }
+        if(!payload.hasNonNull(EMAIL)){
+            log.info("{} No Email provided for generating OTP for login", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
+            data.put(MESSAGE, "Email is required for generating OTP for login");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        }
+        String email = payload.get(EMAIL).asText();
+        if(ADMIN.equalsIgnoreCase(profileType) && !profileService.checkIfValidAdminEmailId(email)){
+            log.info("{} Email {} is not valid for admin, not authorized", apiRequestResolver.getLoggerString(), email);
+            apiResponseResolver.setStatusCode(HttpStatus.UNAUTHORIZED); // 401 unauthorized
+            data.put(MESSAGE, "Email is not authorized for admin OTP generation");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        }
+        apiRequestResolver.addParamValue(EMAIL, email);
+        apiRequestResolver.addParamValue(NEEDS_USER_PROF, "true");
+        return handlerChain.handle(apiRequestResolver, profileType);
+    }
+}
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/GenerateOtpForRegisterChain.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/GenerateOtpForRegisterChain.java
new file mode 100644
index 0000000..0e6a0ac
--- /dev/null
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/GenerateOtpForRegisterChain.java
@@ -0,0 +1,75 @@
+package sg.edu.nus.iss.shopsmart_backend.chains;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import io.swagger.v3.core.util.Json;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Service;
+import sg.edu.nus.iss.shopsmart_backend.handlers.CheckProfileExistsHandler;
+import sg.edu.nus.iss.shopsmart_backend.handlers.GenerateOtpHandler;
+import sg.edu.nus.iss.shopsmart_backend.handlers.Handler;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
+import sg.edu.nus.iss.shopsmart_backend.service.ProfileService;
+import sg.edu.nus.iss.shopsmart_backend.utils.Constants;
+
+import java.util.concurrent.CompletableFuture;
+
+@Service
+public class GenerateOtpForRegisterChain extends Constants implements Chain {
+    private static final Logger log = LoggerFactory.getLogger(GenerateOtpForRegisterChain.class);
+    private final ObjectMapper mapper = Json.mapper();
+
+    private final Handler handlerChain;
+    private final ProfileService profileService;
+
+    @Autowired
+    public GenerateOtpForRegisterChain(ProfileService profileService) {
+        this.profileService = profileService;
+        Handler checkProfileExistsHandler = new CheckProfileExistsHandler(profileService);
+        Handler generateOtpHandler = new GenerateOtpHandler(profileService);
+
+        generateOtpHandler.setNext(null);
+        checkProfileExistsHandler.setNext(generateOtpHandler);
+
+        this.handlerChain = checkProfileExistsHandler;
+    }
+
+    @Override
+    public CompletableFuture<ApiResponseResolver> handleRequest(ApiRequestResolver apiRequestResolver, String profileType) {
+        log.info("Starting GenerateOtpForRegisterChain, for apiRequestResolver : {}, and profileType {}", apiRequestResolver, profileType);
+        log.info("{} Generating OTP for profile registration with requestObt : {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
+        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
+        ObjectNode data = mapper.createObjectNode();
+        JsonNode payload = apiRequestResolver.getRequestBody();
+        if(payload.isNull() || payload.isEmpty()){
+            log.info("{} No request body found for fetching user id for email", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
+            data.put(MESSAGE, "No request body found for otp generation for email");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        }
+        if(!payload.hasNonNull(EMAIL)){
+            log.info("{} No Email provided for generating OTP for registration", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
+            data.put(MESSAGE, "Email is required for generating OTP for registration");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        }
+        String email = payload.get(EMAIL).asText();
+        if(ADMIN.equalsIgnoreCase(profileType) && !profileService.checkIfValidAdminEmailId(email)){
+            log.info("{} Email {} is not valid for admin, not authorized", apiRequestResolver.getLoggerString(), email);
+            apiResponseResolver.setStatusCode(HttpStatus.UNAUTHORIZED); // 401 unauthorized
+            data.put(MESSAGE, "Email is not authorized for admin OTP generation");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        }
+        apiRequestResolver.addParamValue(EMAIL, email);
+        apiRequestResolver.addParamValue(NEEDS_USER_PROF, "false");
+        return handlerChain.handle(apiRequestResolver, profileType);
+    }
+}
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/ValidateOtpAndLoginChain.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/ValidateOtpAndLoginChain.java
new file mode 100644
index 0000000..5a7d0ca
--- /dev/null
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/ValidateOtpAndLoginChain.java
@@ -0,0 +1,69 @@
+package sg.edu.nus.iss.shopsmart_backend.chains;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import io.swagger.v3.core.util.Json;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Service;
+import sg.edu.nus.iss.shopsmart_backend.handlers.FetchUserIdForEmailHandler;
+import sg.edu.nus.iss.shopsmart_backend.handlers.Handler;
+import sg.edu.nus.iss.shopsmart_backend.handlers.ValidateOtpHandler;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
+import sg.edu.nus.iss.shopsmart_backend.service.ProfileService;
+import sg.edu.nus.iss.shopsmart_backend.utils.Constants;
+
+import java.util.concurrent.CompletableFuture;
+
+@Service
+public class ValidateOtpAndLoginChain extends Constants implements Chain{
+    private static final Logger log = LoggerFactory.getLogger(ValidateOtpAndLoginChain.class);
+    private final ObjectMapper mapper = Json.mapper();
+
+    private final Handler handlerChain;
+    private final ProfileService profileService;
+
+    @Autowired
+    public ValidateOtpAndLoginChain(ProfileService profileService) {
+        this.profileService = profileService;
+        Handler validateOtpHandler = new ValidateOtpHandler(profileService);
+        Handler fetchUserIdForEmailHandler = new FetchUserIdForEmailHandler(profileService);
+
+        validateOtpHandler.setNext(fetchUserIdForEmailHandler);
+        fetchUserIdForEmailHandler.setNext(null);
+
+        this.handlerChain = validateOtpHandler;
+    }
+
+    @Override
+    public CompletableFuture<ApiResponseResolver> handleRequest(ApiRequestResolver apiRequestResolver, String profileType){
+        log.info("Starting ValidateOtpAndLoginChain, for apiRequestResolver : {}, and profileType {}", apiRequestResolver, profileType);
+        log.info("{} validating OTP for profile login with requestObt : {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
+        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
+        ObjectNode data = mapper.createObjectNode();
+        JsonNode payload = apiRequestResolver.getRequestBody();
+        if(payload.isNull() || payload.isEmpty()){
+            log.info("{} No request body found for OTP validation for login", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
+            data.put(MESSAGE, "No request body found for otp validation of email");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        }
+        if(!payload.hasNonNull(EMAIL) || !payload.hasNonNull(OTP)){
+            log.info("{} No Email or OTP provided for validating OTP for login", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
+            data.put(MESSAGE, "Email and OTP are required for validating OTP for login");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        }
+        String email = payload.get(EMAIL).asText();
+        String otp = payload.get(OTP).asText();
+        apiRequestResolver.addParamValue(EMAIL, email);
+        apiRequestResolver.addParamValue(OTP, otp);
+        return handlerChain.handle(apiRequestResolver, profileType);
+    }
+}
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/ValidateOtpAndRegisterChain.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/ValidateOtpAndRegisterChain.java
new file mode 100644
index 0000000..080eeec
--- /dev/null
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/ValidateOtpAndRegisterChain.java
@@ -0,0 +1,72 @@
+package sg.edu.nus.iss.shopsmart_backend.chains;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import io.swagger.v3.core.util.Json;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Service;
+import sg.edu.nus.iss.shopsmart_backend.handlers.CreateProfileHandler;
+import sg.edu.nus.iss.shopsmart_backend.handlers.FetchUserIdForEmailHandler;
+import sg.edu.nus.iss.shopsmart_backend.handlers.Handler;
+import sg.edu.nus.iss.shopsmart_backend.handlers.ValidateOtpHandler;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
+import sg.edu.nus.iss.shopsmart_backend.service.ProfileService;
+import sg.edu.nus.iss.shopsmart_backend.utils.Constants;
+
+import java.util.concurrent.CompletableFuture;
+
+@Service
+public class ValidateOtpAndRegisterChain extends Constants implements Chain{
+    private static final Logger log = LoggerFactory.getLogger(ValidateOtpAndRegisterChain.class);
+    private final ObjectMapper mapper = Json.mapper();
+
+    private final Handler handlerChain;
+    private final ProfileService profileService;
+
+    @Autowired
+    public ValidateOtpAndRegisterChain(ProfileService profileService) {
+        this.profileService = profileService;
+        Handler validateOtpHandler = new ValidateOtpHandler(profileService);
+        Handler createProfileHandler = new CreateProfileHandler(profileService);
+        Handler fetchUserIdForEmailHandler = new FetchUserIdForEmailHandler(profileService);
+
+        validateOtpHandler.setNext(createProfileHandler);
+        createProfileHandler.setNext(fetchUserIdForEmailHandler);
+        fetchUserIdForEmailHandler.setNext(null);
+
+        this.handlerChain = validateOtpHandler;
+    }
+
+    @Override
+    public CompletableFuture<ApiResponseResolver> handleRequest(ApiRequestResolver apiRequestResolver, String profileType){
+        log.info("Starting ValidateOtpAndRegisterChain, for apiRequestResolver : {}, and profileType {}", apiRequestResolver, profileType);
+        log.info("{} validating OTP for profile register with requestObt : {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
+        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
+        ObjectNode data = mapper.createObjectNode();
+        JsonNode payload = apiRequestResolver.getRequestBody();
+        if(payload.isNull() || payload.isEmpty()){
+            log.info("{} No request body found for OTP validation for registration", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
+            data.put(MESSAGE, "No request body found for otp validation of email");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        }
+        if(!payload.hasNonNull(EMAIL) || !payload.hasNonNull(OTP)){
+            log.info("{} No Email or OTP provided for validating OTP for registration", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
+            data.put(MESSAGE, "Email and OTP are required for validating OTP for registration");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        }
+        String email = payload.get(EMAIL).asText();
+        String otp = payload.get(OTP).asText();
+        apiRequestResolver.addParamValue(EMAIL, email);
+        apiRequestResolver.addParamValue(OTP, otp);
+        return handlerChain.handle(apiRequestResolver, profileType);
+    }
+}
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/controller/ProfileController.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/controller/ProfileController.java
index 60b7aaa..5f4ea73 100644
--- a/src/main/java/sg/edu/nus/iss/shopsmart_backend/controller/ProfileController.java
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/controller/ProfileController.java
@@ -10,6 +10,7 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
+import sg.edu.nus.iss.shopsmart_backend.chains.*;
 import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
 import sg.edu.nus.iss.shopsmart_backend.service.CommonService;
 import sg.edu.nus.iss.shopsmart_backend.service.ProfileService;
@@ -24,15 +25,23 @@
 @Tag(name = "Profile Login flows", description = "Handle login for customers and merchants profiles via APIs")
 public class ProfileController extends Constants {
     private static final Logger log = LoggerFactory.getLogger(ProfileController.class);
-    private final ProfileService profileService;
     private final CommonService commonService;
     private final Utils utils;
+    private final Chain generateOtpForRegisterChain;
+    private final Chain generateOtpForLoginChain;
+    private final Chain validateOtpAndRegisterChain;
+    private final Chain validateOtpAndLoginChain;
 
     @Autowired
-    public ProfileController(ProfileService profileService, CommonService commonService, Utils utils) {
-        this.profileService = profileService;
+    public ProfileController(CommonService commonService, Utils utils, GenerateOtpForRegisterChain generateOtpForRegisterChain,
+                             GenerateOtpForLoginChain generateOtpForLoginChain, ValidateOtpAndRegisterChain validateOtpAndRegisterChain,
+                             ValidateOtpAndLoginChain validateOtpAndLoginChain) {
         this.commonService = commonService;
         this.utils = utils;
+        this.generateOtpForRegisterChain = generateOtpForRegisterChain;
+        this.generateOtpForLoginChain = generateOtpForLoginChain;
+        this.validateOtpAndRegisterChain = validateOtpAndRegisterChain;
+        this.validateOtpAndLoginChain = validateOtpAndLoginChain;
     }
 
     @PostMapping("/register/generateOtp/{profileType}")
@@ -41,7 +50,8 @@ public CompletableFuture<ResponseEntity<JsonNode>> generateOtpForRegister(@PathV
         log.info("Starting flow for generate OTP for registration for profileType: {}", profileType);
         ApiRequestResolver apiRequestResolver = commonService.createApiResolverRequest(request, GENERATE_OTP, requestBody);
         long startTime = System.currentTimeMillis();
-        return profileService.generateOtpForRegister(apiRequestResolver, profileType).thenApplyAsync(resp ->{
+//        return profileService.generateOtpForRegister(apiRequestResolver, profileType).thenApplyAsync(resp ->{
+        return generateOtpForRegisterChain.handleRequest(apiRequestResolver, profileType).thenApplyAsync(resp ->{
             log.info("{} Time taken to complete otp generation for registration is {} ms", apiRequestResolver.getLoggerString(),
                     (System.currentTimeMillis() - startTime));
             setRequiredCookies(apiRequestResolver, request, response);
@@ -57,7 +67,8 @@ public CompletableFuture<ResponseEntity<JsonNode>> verifyOtpForRegister(@PathVar
         log.info("Starting flow for validate OTP and createProfile for registration for profileType: {}", profileType);
         ApiRequestResolver apiRequestResolver = commonService.createApiResolverRequest(request, VALIDATE_OTP, requestBody);
         long startTime = System.currentTimeMillis();
-        return profileService.validateOtpAndRegister(apiRequestResolver, profileType).thenApplyAsync(resp ->{
+//        return profileService.validateOtpAndRegister(apiRequestResolver, profileType).thenApplyAsync(resp ->{
+        return validateOtpAndRegisterChain.handleRequest(apiRequestResolver, profileType).thenApplyAsync(resp ->{
                 log.info("{} Time taken to complete validate otp and create profile is {} ms", apiRequestResolver.getLoggerString(),
                         (System.currentTimeMillis() - startTime));
             String userId = JsonUtils.getText(resp.getRespData(), USER_ID);
@@ -80,7 +91,8 @@ public CompletableFuture<ResponseEntity<JsonNode>> generateOtpForLogin(@PathVari
         log.info("Starting flow for generate OTP for login for profileType: {}", profileType);
         ApiRequestResolver apiRequestResolver = commonService.createApiResolverRequest(request, GENERATE_OTP, requestBody);
         long startTime = System.currentTimeMillis();
-        return profileService.generateOtpForLogin(apiRequestResolver, profileType).thenApplyAsync(resp ->{
+//        return profileService.generateOtpForLogin(apiRequestResolver, profileType).thenApplyAsync(resp ->{
+        return generateOtpForLoginChain.handleRequest(apiRequestResolver, profileType).thenApplyAsync(resp ->{
             log.info("{} Time taken to complete otp generation for login is {} ms", apiRequestResolver.getLoggerString(),
                     (System.currentTimeMillis() - startTime));
             setRequiredCookies(apiRequestResolver, request, response);
@@ -96,7 +108,8 @@ public CompletableFuture<ResponseEntity<JsonNode>> verifyOtpForLogin(@PathVariab
         log.info("Starting flow for validate OTP and createProfile for login for profileType: {}", profileType);
         ApiRequestResolver apiRequestResolver = commonService.createApiResolverRequest(request, VALIDATE_OTP, requestBody);
         long startTime = System.currentTimeMillis();
-        return profileService.validateOtpAndLogin(apiRequestResolver, profileType).thenApplyAsync(resp ->{
+//        return profileService.validateOtpAndLogin(apiRequestResolver, profileType).thenApplyAsync(resp ->{
+        return validateOtpAndLoginChain.handleRequest(apiRequestResolver, profileType).thenApplyAsync(resp ->{
             log.info("{} Time taken to complete validate otp and fetch userId is {} ms", apiRequestResolver.getLoggerString(),
                     (System.currentTimeMillis() - startTime));
             String userId = JsonUtils.getText(resp.getRespData(), USER_ID);
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/CheckProfileExistsHandler.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/CheckProfileExistsHandler.java
new file mode 100644
index 0000000..22e723d
--- /dev/null
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/CheckProfileExistsHandler.java
@@ -0,0 +1,77 @@
+package sg.edu.nus.iss.shopsmart_backend.handlers;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import io.swagger.v3.core.util.Json;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
+import sg.edu.nus.iss.shopsmart_backend.service.ProfileService;
+import sg.edu.nus.iss.shopsmart_backend.utils.Constants;
+
+import java.util.concurrent.CompletableFuture;
+
+public class CheckProfileExistsHandler extends Constants implements Handler{
+    private static final Logger log = LoggerFactory.getLogger(CheckProfileExistsHandler.class);
+    private final ObjectMapper mapper = Json.mapper();
+
+    private Handler nextHandler; // Next handler in the chain
+    private final ProfileService profileService;
+
+    public CheckProfileExistsHandler(ProfileService profileService) {
+        this.profileService = profileService;
+    }
+
+    @Override
+    public void setNext(Handler nextHandler) {
+        this.nextHandler = nextHandler;
+    }
+
+    @Override
+    public CompletableFuture<ApiResponseResolver> handle(ApiRequestResolver apiRequestResolver, String profileType) {
+        log.info("{} starting checkProfileExistsHandler", apiRequestResolver.getLoggerString());
+        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
+        ObjectNode data = mapper.createObjectNode();
+        String email = apiRequestResolver.getParamValue(EMAIL);
+        if(StringUtils.isEmpty(email)){
+            log.error("{} Email is empty in params", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
+            data.put(MESSAGE, "Email is empty or not found in request for fetching user id");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        }
+        return profileService.fetchUserIdForEmail(apiRequestResolver, email, profileType).thenComposeAsync(userId -> {
+            String needsProfVal = apiRequestResolver.getParamValue(NEEDS_USER_PROF);
+            boolean needsProfForReq = true;
+            if(StringUtils.isNotEmpty(needsProfVal)){
+                needsProfForReq = Boolean.parseBoolean(needsProfVal);
+            }
+            log.info("{} checkProfileExistsHandler for email {} completed with userId {} and needsProfForReq {}", apiRequestResolver.getLoggerString(), email, userId, needsProfForReq);
+            if(StringUtils.isEmpty(userId)){
+                if(!needsProfForReq && nextHandler!=null){
+                    log.info("{} No userId found for email {} and needsProfForReq is false and found next link in chain so passing to next handler",
+                            apiRequestResolver.getLoggerString(), email);
+                    return nextHandler.handle(apiRequestResolver, profileType);
+                }
+                log.error("{} Error occurred while fetching userId for email: {} after profile creation", apiRequestResolver.getLoggerString(), email);
+                apiResponseResolver.setStatusCode(HttpStatus.NOT_FOUND);
+                data.put(MESSAGE, "No existing profile found for the email");
+                apiResponseResolver.setRespData(data);
+                return CompletableFuture.completedFuture(apiResponseResolver);
+            }
+            if(needsProfForReq && nextHandler!=null){
+                log.info("{} User id found and needsProfForReq is true and found next link in chain so passing to next handler",
+                        apiRequestResolver.getLoggerString());
+                return nextHandler.handle(apiRequestResolver, profileType);
+            }
+            log.info("{} User id found and no next link in chain so returning response", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.OK); // 200 ok
+            data.put(USER_ID, userId);
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        });
+    }
+}
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/CreateProfileHandler.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/CreateProfileHandler.java
new file mode 100644
index 0000000..12b28c6
--- /dev/null
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/CreateProfileHandler.java
@@ -0,0 +1,59 @@
+package sg.edu.nus.iss.shopsmart_backend.handlers;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import io.swagger.v3.core.util.Json;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
+import sg.edu.nus.iss.shopsmart_backend.service.ProfileService;
+import sg.edu.nus.iss.shopsmart_backend.utils.Constants;
+
+import java.util.concurrent.CompletableFuture;
+
+public class CreateProfileHandler extends Constants implements Handler {
+    private static final Logger log = LoggerFactory.getLogger(CreateProfileHandler.class);
+    private final ObjectMapper mapper = Json.mapper();
+
+    private Handler nextHandler; // Next handler in the chain
+    private final ProfileService profileService;
+
+    public CreateProfileHandler(ProfileService profileService) {
+        this.profileService = profileService;
+    }
+
+    @Override
+    public void setNext(Handler nextHandler) {
+        this.nextHandler = nextHandler;
+    }
+
+    @Override
+    public CompletableFuture<ApiResponseResolver> handle(ApiRequestResolver apiRequestResolver, String profileType) {
+        log.info("{} starting createProfileHandler", apiRequestResolver.getLoggerString());
+        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
+        ObjectNode data = mapper.createObjectNode();
+
+        return profileService.createProfile(apiRequestResolver, profileType).thenComposeAsync(profileCreateResp -> {
+            log.info("{} createProfile call completed with resp : {}", apiRequestResolver.getLoggerString(), profileCreateResp);
+            if(!profileCreateResp){
+                log.error("{} Profile creation failed for provided request", apiRequestResolver.getLoggerString());
+                apiResponseResolver.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
+                data.put(MESSAGE, "Unable to create profile for the provided request");
+                apiResponseResolver.setRespData(data);
+                return CompletableFuture.completedFuture(apiResponseResolver);
+            }
+            if(nextHandler!=null){
+                log.info("{} Profile creation completed CreateProfileHandler and found next link in chain so passing to next handler",
+                        apiRequestResolver.getLoggerString());
+                return nextHandler.handle(apiRequestResolver, profileType);
+            }
+            log.info("{} profile creation completed and no next link in chain so returning response", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.OK); // 200 ok
+            data.put(MESSAGE, "Profile created successfully for user");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        });
+    }
+}
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/FetchUserIdForEmailHandler.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/FetchUserIdForEmailHandler.java
new file mode 100644
index 0000000..2a9c989
--- /dev/null
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/FetchUserIdForEmailHandler.java
@@ -0,0 +1,67 @@
+package sg.edu.nus.iss.shopsmart_backend.handlers;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import io.swagger.v3.core.util.Json;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
+import sg.edu.nus.iss.shopsmart_backend.service.ProfileService;
+import sg.edu.nus.iss.shopsmart_backend.utils.Constants;
+
+import java.util.concurrent.CompletableFuture;
+
+public class FetchUserIdForEmailHandler extends Constants implements Handler{
+    private static final Logger log = LoggerFactory.getLogger(FetchUserIdForEmailHandler.class);
+    private final ObjectMapper mapper = Json.mapper();
+
+    private Handler nextHandler; // Next handler in the chain
+    private final ProfileService profileService;
+
+    public FetchUserIdForEmailHandler(ProfileService profileService) {
+        this.profileService = profileService;
+    }
+
+    @Override
+    public void setNext(Handler nextHandler) {
+        this.nextHandler = nextHandler;
+    }
+
+    @Override
+    public CompletableFuture<ApiResponseResolver> handle(ApiRequestResolver apiRequestResolver, String profileType) {
+        log.info("{} starting fetchUserIdForEmailHandler", apiRequestResolver.getLoggerString());
+        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
+        ObjectNode data = mapper.createObjectNode();
+        String email = apiRequestResolver.getParamValue(EMAIL);
+        if(StringUtils.isEmpty(email)){
+            log.error("{} Email is empty in params", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
+            data.put(MESSAGE, "Email is empty or not found in request for fetching user id");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        }
+        return profileService.fetchUserIdForEmail(apiRequestResolver, email, profileType).thenComposeAsync(userId -> {
+            log.info("{} fetchUserIdForEmailHandler for email {} completed with userId {}", apiRequestResolver.getLoggerString(), email, userId);
+            if(StringUtils.isEmpty(userId)){
+                log.error("{} Error occurred while fetching userId for email: {} after profile creation", apiRequestResolver.getLoggerString(), email);
+                apiResponseResolver.setStatusCode(HttpStatus.NOT_FOUND);
+                data.put(MESSAGE, "No existing profile found for the email");
+                apiResponseResolver.setRespData(data);
+                return CompletableFuture.completedFuture(apiResponseResolver);
+            }
+            if(nextHandler!=null){
+                log.info("{} User id found and found next link in chain so passing to next handler",
+                        apiRequestResolver.getLoggerString());
+                return nextHandler.handle(apiRequestResolver, profileType);
+            }
+            log.info("{} User id found and no next link in chain so returning response", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.OK); // 200 ok
+            data.put(USER_ID, userId);
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        });
+    }
+}
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/GenerateOtpHandler.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/GenerateOtpHandler.java
new file mode 100644
index 0000000..28731ca
--- /dev/null
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/GenerateOtpHandler.java
@@ -0,0 +1,68 @@
+package sg.edu.nus.iss.shopsmart_backend.handlers;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import io.swagger.v3.core.util.Json;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
+import sg.edu.nus.iss.shopsmart_backend.service.ProfileService;
+import sg.edu.nus.iss.shopsmart_backend.utils.Constants;
+
+import java.util.concurrent.CompletableFuture;
+
+public class GenerateOtpHandler extends Constants implements Handler{
+    private static final Logger log = LoggerFactory.getLogger(GenerateOtpHandler.class);
+    private final ObjectMapper mapper = Json.mapper();
+
+    private Handler nextHandler; // Next handler in the chain
+    private final ProfileService profileService;
+
+    public GenerateOtpHandler(ProfileService profileService) {
+        this.profileService = profileService;
+    }
+
+    @Override
+    public void setNext(Handler nextHandler) {
+        this.nextHandler = nextHandler;
+    }
+
+    @Override
+    public CompletableFuture<ApiResponseResolver> handle(ApiRequestResolver apiRequestResolver, String profileType) {
+        log.info("{} starting GenerateOtpHandler", apiRequestResolver.getLoggerString());
+        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
+        ObjectNode data = mapper.createObjectNode();
+
+        String email = apiRequestResolver.getParamValue(EMAIL);
+        if(StringUtils.isEmpty(email)){
+            log.error("{} Email is empty in params", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
+            data.put(MESSAGE, "Email is empty or not found in request for otp generation");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        }
+        return profileService.generateOtp(apiRequestResolver, email).thenComposeAsync(otpGenerationResp->{
+            log.info("{} otpGeneration call completed with resp {}", apiRequestResolver.getLoggerString(), otpGenerationResp);
+            if(!otpGenerationResp){
+                log.error("{} otp generation failed for provided email {}", apiRequestResolver.getLoggerString(), email);
+                apiResponseResolver.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
+                data.put(MESSAGE, "Failure occurred in generation of otp for provided email");
+                apiResponseResolver.setRespData(data);
+                return CompletableFuture.completedFuture(apiResponseResolver);
+            }
+            if(nextHandler!=null){
+                log.info("{} Otp generation completed GenerateOtpHandler and found next link in chain so passing to next handler",
+                        apiRequestResolver.getLoggerString());
+                return nextHandler.handle(apiRequestResolver, profileType);
+            }
+            log.info("{} otp generation completed and no next link in chain so returning response", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.OK); // 200 ok
+            data.put(MESSAGE, "Otp generation completed as expected");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        });
+    }
+}
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/Handler.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/Handler.java
new file mode 100644
index 0000000..63a7ddd
--- /dev/null
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/Handler.java
@@ -0,0 +1,12 @@
+package sg.edu.nus.iss.shopsmart_backend.handlers;
+
+import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
+
+import java.util.concurrent.CompletableFuture;
+
+public interface Handler {
+    void setNext(Handler nextHandler);
+    CompletableFuture<ApiResponseResolver> handle(ApiRequestResolver request, String profileType);
+}
+
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/ValidateOtpHandler.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/ValidateOtpHandler.java
new file mode 100644
index 0000000..b7dbe8b
--- /dev/null
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/handlers/ValidateOtpHandler.java
@@ -0,0 +1,70 @@
+package sg.edu.nus.iss.shopsmart_backend.handlers;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import io.swagger.v3.core.util.Json;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
+import sg.edu.nus.iss.shopsmart_backend.service.ProfileService;
+import sg.edu.nus.iss.shopsmart_backend.utils.Constants;
+
+import java.util.concurrent.CompletableFuture;
+
+public class ValidateOtpHandler extends Constants implements Handler{
+    private static final Logger log = LoggerFactory.getLogger(ValidateOtpHandler.class);
+    private final ObjectMapper mapper = Json.mapper();
+
+    private Handler nextHandler; // Next handler in the chain
+    private final ProfileService profileService;
+
+    public ValidateOtpHandler(ProfileService profileService) {
+        this.profileService = profileService;
+    }
+
+    @Override
+    public void setNext(Handler nextHandler) {
+        this.nextHandler = nextHandler;
+    }
+
+    @Override
+    public CompletableFuture<ApiResponseResolver> handle(ApiRequestResolver apiRequestResolver, String profileType) {
+        log.info("{} starting ValidateOtpHandler", apiRequestResolver.getLoggerString());
+        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
+        ObjectNode data = mapper.createObjectNode();
+
+        String email = apiRequestResolver.getParamValue(EMAIL);
+        String otp = apiRequestResolver.getParamValue(OTP);
+        if(StringUtils.isEmpty(email) || StringUtils.isEmpty(otp)){
+            log.error("{} Email or otp is empty in params", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.NOT_FOUND);
+            data.put(MESSAGE, "Email or otp is empty or not found in request for otp validation");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        }
+
+        return profileService.validateOtp(apiRequestResolver, email, otp).thenComposeAsync(otpValidationResp -> {
+            log.info("{} validateOtp call completed with resp : {}", apiRequestResolver.getLoggerString(), otpValidationResp);
+            if(!otpValidationResp){
+                log.error("{} otp validation failed for provided email {} and otp {}", apiRequestResolver.getLoggerString(), email, otp);
+                apiResponseResolver.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
+                data.put(MESSAGE, "Failure occurred in validation of otp for provided request");
+                apiResponseResolver.setRespData(data);
+                return CompletableFuture.completedFuture(apiResponseResolver);
+            }
+            if(nextHandler!=null){
+                log.info("{} Otp validation completed ValidateOtpHandler and found next link in chain so passing to next handler",
+                        apiRequestResolver.getLoggerString());
+                return nextHandler.handle(apiRequestResolver, profileType);
+            }
+            log.info("{} otp validation completed and no next link in chain so returning response", apiRequestResolver.getLoggerString());
+            apiResponseResolver.setStatusCode(HttpStatus.OK); // 200 ok
+            data.put(MESSAGE, "Otp validation completed as expected");
+            apiResponseResolver.setRespData(data);
+            return CompletableFuture.completedFuture(apiResponseResolver);
+        });
+    }
+}
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/model/ApiRequestResolver.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/model/ApiRequestResolver.java
index ed9c060..da7c52d 100644
--- a/src/main/java/sg/edu/nus/iss/shopsmart_backend/model/ApiRequestResolver.java
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/model/ApiRequestResolver.java
@@ -3,6 +3,7 @@
 import com.fasterxml.jackson.databind.JsonNode;
 import lombok.Data;
 
+import java.util.HashMap;
 import java.util.Map;
 
 @Data
@@ -23,4 +24,19 @@ public class ApiRequestResolver {
     private String userId;
     private String jwtToken;
     private boolean isLoggedIn;
+    private Map<String, String> params;
+
+    public void addParamValue(String key, String value) {
+        if(params == null){
+            params=new HashMap<>();
+        }
+        params.put(key, value);
+    }
+
+    public String getParamValue(String key) {
+        if(params.containsKey(key)){
+            return params.get(key);
+        }
+        return "";
+    }
 }
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/service/ProfileService.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/service/ProfileService.java
index 0177176..e3046fe 100644
--- a/src/main/java/sg/edu/nus/iss/shopsmart_backend/service/ProfileService.java
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/service/ProfileService.java
@@ -34,164 +34,162 @@ public ProfileService(RedisManager redisManager, WSUtils wsUtils){
         this.wsUtils = wsUtils;
     }
 
-    public CompletableFuture<ApiResponseResolver> generateOtpForRegister(ApiRequestResolver apiRequestResolver, String profileType){
-        log.info("{} Generating OTP for profile registration with requestObt : {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
-        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
-        ObjectNode data = mapper.createObjectNode();
-        JsonNode payload = apiRequestResolver.getRequestBody();
-        if(payload.isNull() || payload.isEmpty()){
-            log.info("{} No request body found for fetching user id for email", apiRequestResolver.getLoggerString());
-            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
-            data.put(MESSAGE, "No request body found for otp generation for email");
-            apiResponseResolver.setRespData(data);
-            return CompletableFuture.completedFuture(apiResponseResolver);
-        }
-        if(!payload.hasNonNull(EMAIL)){
-            log.info("{} No Email provided for generating OTP for registration", apiRequestResolver.getLoggerString());
-            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
-            data.put(MESSAGE, "Email is required for generating OTP for registration");
-            apiResponseResolver.setRespData(data);
-            return CompletableFuture.completedFuture(apiResponseResolver);
-        }
-        String email = payload.get(EMAIL).asText();
-        if(ADMIN.equalsIgnoreCase(profileType) && !checkIfValidAdminEmailId(email)){
-            log.info("{} Email {} is not valid for admin, not authorized", apiRequestResolver.getLoggerString(), email);
-            apiResponseResolver.setStatusCode(HttpStatus.UNAUTHORIZED); // 401 unauthorized
-            data.put(MESSAGE, "Email is not authorized for admin OTP generation");
-            apiResponseResolver.setRespData(data);
-            return CompletableFuture.completedFuture(apiResponseResolver);
-        }
-        return fetchUserIdForEmail(apiRequestResolver, email, profileType).thenComposeAsync(userId -> {
-            if(StringUtils.isNotEmpty(userId)){
-                log.info("{} User id {} found for email, so not generating OTP for registration, user needs to login",
-                        apiRequestResolver.getLoggerString(), userId);
-                apiResponseResolver.setStatusCode(HttpStatus.CONFLICT); // 409 conflict
-                data.put(MESSAGE, "User already exists with email, please login");
-                apiResponseResolver.setRespData(data);
-                return CompletableFuture.completedFuture(apiResponseResolver);
-            }
-            return generateOtp(apiRequestResolver, email);
-        });
-    }
-    public CompletableFuture<ApiResponseResolver> generateOtpForLogin(ApiRequestResolver apiRequestResolver, String profileType){
-        log.info("{} Generating OTP for profile login with requestObt : {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
-        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
-        ObjectNode data = mapper.createObjectNode();
-        JsonNode payload = apiRequestResolver.getRequestBody();
-        if(payload.isNull() || payload.isEmpty()){
-            log.info("{} No request body found for opt generation for login", apiRequestResolver.getLoggerString());
-            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
-            data.put(MESSAGE, "No request body found for otp generation for email");
-            apiResponseResolver.setRespData(data);
-            return CompletableFuture.completedFuture(apiResponseResolver);
-        }
-        if(!payload.hasNonNull(EMAIL)){
-            log.info("{} No Email provided for generating OTP for login", apiRequestResolver.getLoggerString());
-            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
-            data.put(MESSAGE, "Email is required for generating OTP for login");
-            apiResponseResolver.setRespData(data);
-            return CompletableFuture.completedFuture(apiResponseResolver);
-        }
-        String email = payload.get(EMAIL).asText();
-        return fetchUserIdForEmail(apiRequestResolver, email, profileType).thenComposeAsync(userId -> {
-            if(userId==null || StringUtils.isEmpty(userId)){
-                log.info("{} No userId found for email, so not generating OTP for login, user accounts needs to be present to login",
-                        apiRequestResolver.getLoggerString());
-                apiResponseResolver.setStatusCode(HttpStatus.NOT_FOUND); // 404 not found
-                data.put(MESSAGE, "User does not exists with email, please register");
-                apiResponseResolver.setRespData(data);
-                return CompletableFuture.completedFuture(apiResponseResolver);
-            }
-            return generateOtp(apiRequestResolver, email);
-        });
-    }
-    public CompletableFuture<ApiResponseResolver> validateOtpAndRegister(ApiRequestResolver apiRequestResolver, String profileType){
-        log.info("{} validating OTP for profile register with requestObt : {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
-        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
-        ObjectNode data = mapper.createObjectNode();
-        JsonNode payload = apiRequestResolver.getRequestBody();
-        if(payload.isNull() || payload.isEmpty()){
-            log.info("{} No request body found for OTP validation for registration", apiRequestResolver.getLoggerString());
-            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
-            data.put(MESSAGE, "No request body found for otp validation of email");
-            apiResponseResolver.setRespData(data);
-            return CompletableFuture.completedFuture(apiResponseResolver);
-        }
-        if(!payload.hasNonNull(EMAIL) || !payload.hasNonNull(OTP)){
-            log.info("{} No Email or OTP provided for validating OTP for registration", apiRequestResolver.getLoggerString());
-            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
-            data.put(MESSAGE, "Email and OTP are required for validating OTP for registration");
-            apiResponseResolver.setRespData(data);
-            return CompletableFuture.completedFuture(apiResponseResolver);
-        }
-        String email = payload.get(EMAIL).asText();
-        String otp = payload.get(OTP).asText();
-        return validateOtp(apiRequestResolver, email, otp).thenComposeAsync(isValid -> {
-            log.info("{} OTP validation status for email for registration: {} is : {}", apiRequestResolver.getLoggerString(), email, isValid);
-            if(isValid){
-                log.info("{} as otp is valid, so registering user for email: {}", apiRequestResolver.getLoggerString(), email);
-                return createProfileAndRetrieveId(apiRequestResolver, email, profileType);
-            }else{
-                log.error("{} OTP validation failed for email during registration: {}", apiRequestResolver.getLoggerString(), email);
-                apiResponseResolver.setStatusCode(HttpStatus.UNAUTHORIZED); // 401 unauthorized
-                data.put(MESSAGE, "OTP validation failed, please try again");
-                apiResponseResolver.setRespData(data);
-                return CompletableFuture.completedFuture(apiResponseResolver);
-            }
-        });
-    }
-    public CompletableFuture<ApiResponseResolver> validateOtpAndLogin(ApiRequestResolver apiRequestResolver, String profileType){
-        log.info("{} validating OTP for profile login with requestObt : {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
-        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
-        ObjectNode data = mapper.createObjectNode();
-        JsonNode payload = apiRequestResolver.getRequestBody();
-        if(payload.isNull() || payload.isEmpty()){
-            log.info("{} No request body found for OTP validation for login", apiRequestResolver.getLoggerString());
-            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
-            data.put(MESSAGE, "No request body found for otp validation of email");
-            apiResponseResolver.setRespData(data);
-            return CompletableFuture.completedFuture(apiResponseResolver);
-        }
-        if(!payload.hasNonNull(EMAIL) || !payload.hasNonNull(OTP)){
-            log.info("{} No Email or OTP provided for validating OTP for login", apiRequestResolver.getLoggerString());
-            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
-            data.put(MESSAGE, "Email and OTP are required for validating OTP for login");
-            apiResponseResolver.setRespData(data);
-            return CompletableFuture.completedFuture(apiResponseResolver);
-        }
-        String email = payload.get(EMAIL).asText();
-        String otp = payload.get(OTP).asText();
-        return validateOtp(apiRequestResolver, email, otp).thenComposeAsync(isValid -> {
-            log.info("{} OTP validation status for email: {} is : {}", apiRequestResolver.getLoggerString(), email, isValid);
-            if(isValid){
-                log.info("{} as otp is valid, so retrieving userId for email: {}", apiRequestResolver.getLoggerString(), email);
-                return fetchUserIdForEmail(apiRequestResolver, email, profileType).thenComposeAsync(userId -> {
-                    if(StringUtils.isEmpty(userId)){
-                        log.error("{} No userId found for email: {} after OTP validation", apiRequestResolver.getLoggerString(), email);
-                        apiResponseResolver.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR); // 500 internal server error
-                        data.put(MESSAGE, "Some error occurred while fetching userId, please try again.");
-                        apiResponseResolver.setRespData(data);
-                        return CompletableFuture.completedFuture(apiResponseResolver);
-                    }
-                    log.info("{} User id found for email: {} after OTP validation, so returning userId", apiRequestResolver.getLoggerString(), email);
-                    apiResponseResolver.setStatusCode(HttpStatus.OK); // 200 ok
-                    data.put(USER_ID, userId);
-                    apiResponseResolver.setRespData(data);
-                    return CompletableFuture.completedFuture(apiResponseResolver);
-                });
-            }else{
-                log.error("{} OTP validation failed for email during login: {}", apiRequestResolver.getLoggerString(), email);
-                apiResponseResolver.setStatusCode(HttpStatus.UNAUTHORIZED); // 401 unauthorized
-                data.put(MESSAGE, "OTP validation failed, please try again");
-                apiResponseResolver.setRespData(data);
-                return CompletableFuture.completedFuture(apiResponseResolver);
-            }
-        });
-    }
-    private CompletableFuture<ApiResponseResolver> generateOtp(ApiRequestResolver apiRequestResolver, String email){
+//    public CompletableFuture<ApiResponseResolver> generateOtpForRegister(ApiRequestResolver apiRequestResolver, String profileType){
+//        log.info("{} Generating OTP for profile registration with requestObt : {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
+//        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
+//        ObjectNode data = mapper.createObjectNode();
+//        JsonNode payload = apiRequestResolver.getRequestBody();
+//        if(payload.isNull() || payload.isEmpty()){
+//            log.info("{} No request body found for fetching user id for email", apiRequestResolver.getLoggerString());
+//            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
+//            data.put(MESSAGE, "No request body found for otp generation for email");
+//            apiResponseResolver.setRespData(data);
+//            return CompletableFuture.completedFuture(apiResponseResolver);
+//        }
+//        if(!payload.hasNonNull(EMAIL)){
+//            log.info("{} No Email provided for generating OTP for registration", apiRequestResolver.getLoggerString());
+//            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
+//            data.put(MESSAGE, "Email is required for generating OTP for registration");
+//            apiResponseResolver.setRespData(data);
+//            return CompletableFuture.completedFuture(apiResponseResolver);
+//        }
+//        String email = payload.get(EMAIL).asText();
+//        if(ADMIN.equalsIgnoreCase(profileType) && !checkIfValidAdminEmailId(email)){
+//            log.info("{} Email {} is not valid for admin, not authorized", apiRequestResolver.getLoggerString(), email);
+//            apiResponseResolver.setStatusCode(HttpStatus.UNAUTHORIZED); // 401 unauthorized
+//            data.put(MESSAGE, "Email is not authorized for admin OTP generation");
+//            apiResponseResolver.setRespData(data);
+//            return CompletableFuture.completedFuture(apiResponseResolver);
+//        }
+//        return fetchUserIdForEmail(apiRequestResolver, email, profileType).thenComposeAsync(userId -> {
+//            if(StringUtils.isNotEmpty(userId)){
+//                log.info("{} User id {} found for email, so not generating OTP for registration, user needs to login",
+//                        apiRequestResolver.getLoggerString(), userId);
+//                apiResponseResolver.setStatusCode(HttpStatus.CONFLICT); // 409 conflict
+//                data.put(MESSAGE, "User already exists with email, please login");
+//                apiResponseResolver.setRespData(data);
+//                return CompletableFuture.completedFuture(apiResponseResolver);
+//            }
+//            return generateOtp(apiRequestResolver, email);
+//        });
+//    }
+//    public CompletableFuture<ApiResponseResolver> generateOtpForLogin(ApiRequestResolver apiRequestResolver, String profileType){
+//        log.info("{} Generating OTP for profile login with requestObt : {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
+//        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
+//        ObjectNode data = mapper.createObjectNode();
+//        JsonNode payload = apiRequestResolver.getRequestBody();
+//        if(payload.isNull() || payload.isEmpty()){
+//            log.info("{} No request body found for opt generation for login", apiRequestResolver.getLoggerString());
+//            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
+//            data.put(MESSAGE, "No request body found for otp generation for email");
+//            apiResponseResolver.setRespData(data);
+//            return CompletableFuture.completedFuture(apiResponseResolver);
+//        }
+//        if(!payload.hasNonNull(EMAIL)){
+//            log.info("{} No Email provided for generating OTP for login", apiRequestResolver.getLoggerString());
+//            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
+//            data.put(MESSAGE, "Email is required for generating OTP for login");
+//            apiResponseResolver.setRespData(data);
+//            return CompletableFuture.completedFuture(apiResponseResolver);
+//        }
+//        String email = payload.get(EMAIL).asText();
+//        return fetchUserIdForEmail(apiRequestResolver, email, profileType).thenComposeAsync(userId -> {
+//            if(userId==null || StringUtils.isEmpty(userId)){
+//                log.info("{} No userId found for email, so not generating OTP for login, user accounts needs to be present to login",
+//                        apiRequestResolver.getLoggerString());
+//                apiResponseResolver.setStatusCode(HttpStatus.NOT_FOUND); // 404 not found
+//                data.put(MESSAGE, "User does not exists with email, please register");
+//                apiResponseResolver.setRespData(data);
+//                return CompletableFuture.completedFuture(apiResponseResolver);
+//            }
+//            return generateOtp(apiRequestResolver, email);
+//        });
+//    }
+//    public CompletableFuture<ApiResponseResolver> validateOtpAndRegister(ApiRequestResolver apiRequestResolver, String profileType){
+//        log.info("{} validating OTP for profile register with requestObt : {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
+//        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
+//        ObjectNode data = mapper.createObjectNode();
+//        JsonNode payload = apiRequestResolver.getRequestBody();
+//        if(payload.isNull() || payload.isEmpty()){
+//            log.info("{} No request body found for OTP validation for registration", apiRequestResolver.getLoggerString());
+//            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
+//            data.put(MESSAGE, "No request body found for otp validation of email");
+//            apiResponseResolver.setRespData(data);
+//            return CompletableFuture.completedFuture(apiResponseResolver);
+//        }
+//        if(!payload.hasNonNull(EMAIL) || !payload.hasNonNull(OTP)){
+//            log.info("{} No Email or OTP provided for validating OTP for registration", apiRequestResolver.getLoggerString());
+//            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
+//            data.put(MESSAGE, "Email and OTP are required for validating OTP for registration");
+//            apiResponseResolver.setRespData(data);
+//            return CompletableFuture.completedFuture(apiResponseResolver);
+//        }
+//        String email = payload.get(EMAIL).asText();
+//        String otp = payload.get(OTP).asText();
+//        return validateOtp(apiRequestResolver, email, otp).thenComposeAsync(isValid -> {
+//            log.info("{} OTP validation status for email for registration: {} is : {}", apiRequestResolver.getLoggerString(), email, isValid);
+//            if(isValid){
+//                log.info("{} as otp is valid, so registering user for email: {}", apiRequestResolver.getLoggerString(), email);
+//                return createProfileAndRetrieveId(apiRequestResolver, email, profileType);
+//            }else{
+//                log.error("{} OTP validation failed for email during registration: {}", apiRequestResolver.getLoggerString(), email);
+//                apiResponseResolver.setStatusCode(HttpStatus.UNAUTHORIZED); // 401 unauthorized
+//                data.put(MESSAGE, "OTP validation failed, please try again");
+//                apiResponseResolver.setRespData(data);
+//                return CompletableFuture.completedFuture(apiResponseResolver);
+//            }
+//        });
+//    }
+//    public CompletableFuture<ApiResponseResolver> validateOtpAndLogin(ApiRequestResolver apiRequestResolver, String profileType){
+//        log.info("{} validating OTP for profile login with requestObt : {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
+//        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
+//        ObjectNode data = mapper.createObjectNode();
+//        JsonNode payload = apiRequestResolver.getRequestBody();
+//        if(payload.isNull() || payload.isEmpty()){
+//            log.info("{} No request body found for OTP validation for login", apiRequestResolver.getLoggerString());
+//            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
+//            data.put(MESSAGE, "No request body found for otp validation of email");
+//            apiResponseResolver.setRespData(data);
+//            return CompletableFuture.completedFuture(apiResponseResolver);
+//        }
+//        if(!payload.hasNonNull(EMAIL) || !payload.hasNonNull(OTP)){
+//            log.info("{} No Email or OTP provided for validating OTP for login", apiRequestResolver.getLoggerString());
+//            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
+//            data.put(MESSAGE, "Email and OTP are required for validating OTP for login");
+//            apiResponseResolver.setRespData(data);
+//            return CompletableFuture.completedFuture(apiResponseResolver);
+//        }
+//        String email = payload.get(EMAIL).asText();
+//        String otp = payload.get(OTP).asText();
+//        return validateOtp(apiRequestResolver, email, otp).thenComposeAsync(isValid -> {
+//            log.info("{} OTP validation status for email: {} is : {}", apiRequestResolver.getLoggerString(), email, isValid);
+//            if(isValid){
+//                log.info("{} as otp is valid, so retrieving userId for email: {}", apiRequestResolver.getLoggerString(), email);
+//                return fetchUserIdForEmail(apiRequestResolver, email, profileType).thenComposeAsync(userId -> {
+//                    if(StringUtils.isEmpty(userId)){
+//                        log.error("{} No userId found for email: {} after OTP validation", apiRequestResolver.getLoggerString(), email);
+//                        apiResponseResolver.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR); // 500 internal server error
+//                        data.put(MESSAGE, "Some error occurred while fetching userId, please try again.");
+//                        apiResponseResolver.setRespData(data);
+//                        return CompletableFuture.completedFuture(apiResponseResolver);
+//                    }
+//                    log.info("{} User id found for email: {} after OTP validation, so returning userId", apiRequestResolver.getLoggerString(), email);
+//                    apiResponseResolver.setStatusCode(HttpStatus.OK); // 200 ok
+//                    data.put(USER_ID, userId);
+//                    apiResponseResolver.setRespData(data);
+//                    return CompletableFuture.completedFuture(apiResponseResolver);
+//                });
+//            }else{
+//                log.error("{} OTP validation failed for email during login: {}", apiRequestResolver.getLoggerString(), email);
+//                apiResponseResolver.setStatusCode(HttpStatus.UNAUTHORIZED); // 401 unauthorized
+//                data.put(MESSAGE, "OTP validation failed, please try again");
+//                apiResponseResolver.setRespData(data);
+//                return CompletableFuture.completedFuture(apiResponseResolver);
+//            }
+//        });
+//    }
+    public CompletableFuture<Boolean> generateOtp(ApiRequestResolver apiRequestResolver, String email){
         log.info("{} starting OTP generation for email: {}", apiRequestResolver.getLoggerString(), email);
-        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
-        ObjectNode data = mapper.createObjectNode();
         DataDynamicObject ddo = redisManager.getDdoData(GENERATE_OTP);
         String serviceUrl = redisManager.getServiceEndpoint(ddo.getService());
         String apiEndpoint = serviceUrl.concat(ddo.getApi());
@@ -201,21 +199,18 @@ private CompletableFuture<ApiResponseResolver> generateOtp(ApiRequestResolver ap
         HttpMethod method = Utils.getHttpMethod(ddo.getMethod());
         return wsUtils.makeWSCall(uriBuilder.toUriString(), null, new HashMap<>(), method,
                 ddo.getConnectTimeout(), ddo.getReadTimeout(), ddo.getReturnClass()).thenApplyAsync(response -> {
-            apiResponseResolver.setStatusCode(response.getHttpStatusCode());
             if(SUCCESS.equalsIgnoreCase(response.getStatus())){
                 log.info("{} OTP generated for email: {}", apiRequestResolver.getLoggerString(), email);
-                data.put(MESSAGE, "OTP generated successfully");
+                return true;
             } else {
                 log.error("{} Error generating OTP for email: {}", apiRequestResolver.getLoggerString(), email);
-                data.put(MESSAGE, "Error generating OTP");
+                return false;
             }
-            apiResponseResolver.setRespData(data);
-            return apiResponseResolver;
         });
     }
-    private CompletableFuture<Boolean> validateOtp(ApiRequestResolver apiRequestResolver, String email, String otp){
+
+    public CompletableFuture<Boolean> validateOtp(ApiRequestResolver apiRequestResolver, String email, String otp){
         log.info("{} starting OTP validation for email: {}", apiRequestResolver.getLoggerString(), email);
-        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
         DataDynamicObject ddo = redisManager.getDdoData(VALIDATE_OTP);
         String serviceUrl = redisManager.getServiceEndpoint(ddo.getService());
         String apiEndpoint = serviceUrl.concat(ddo.getApi());
@@ -226,7 +221,6 @@ private CompletableFuture<Boolean> validateOtp(ApiRequestResolver apiRequestReso
         HttpMethod method = Utils.getHttpMethod(ddo.getMethod());
         return wsUtils.makeWSCall(uriBuilder.toUriString(), null, new HashMap<>(), method,
                 ddo.getConnectTimeout(), ddo.getReadTimeout(), ddo.getReturnClass()).thenApplyAsync(response -> {
-            apiResponseResolver.setStatusCode(response.getHttpStatusCode());
             if(SUCCESS.equalsIgnoreCase(response.getStatus())){
                 log.info("{} OTP validated for email: {}", apiRequestResolver.getLoggerString(), email);
                 return true;
@@ -236,8 +230,14 @@ private CompletableFuture<Boolean> validateOtp(ApiRequestResolver apiRequestReso
             }
         });
     }
-    private CompletableFuture<Boolean> createProfile(ApiRequestResolver apiRequestResolver, String profileType){
+
+    public CompletableFuture<Boolean> createProfile(ApiRequestResolver apiRequestResolver, String profileType){
         log.info("{} Starting to create profile for request {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
+        if(ADMIN.equalsIgnoreCase(profileType)){
+            log.info("{} Admin profile type has a hard coded userId, hence no need to create profile, skipping to fetch profile",
+                    apiRequestResolver.getLoggerString());
+            return CompletableFuture.completedFuture(true);
+        }
         String ddoToGetProfileId = Utils.ddoCreateProfileByType(profileType);
         if(ddoToGetProfileId == null){
             log.error("{} Unsupported profile type for creating profile", apiRequestResolver.getLoggerString());
@@ -260,53 +260,58 @@ private CompletableFuture<Boolean> createProfile(ApiRequestResolver apiRequestRe
             }
         });
     }
-    private CompletableFuture<ApiResponseResolver> createProfileAndRetrieveId(ApiRequestResolver apiRequestResolver, String email, String profileType){
-        log.info("Starting profile create flow for email: {} and profileType: {}", email, profileType);
-        if(ADMIN.equalsIgnoreCase(profileType)){
-            String adminUserId = redisManager.getHashValue(REDIS_FEATURE_FLAGS, ADMIN_USER_ID);
-            log.info("{} Admin profile type has a hard coded userId : {}, hence no need to create profile",
-                    apiRequestResolver.getLoggerString(), adminUserId);
-            ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
-            ObjectNode data = mapper.createObjectNode();
-            apiResponseResolver.setStatusCode(HttpStatus.OK); // 200 ok
-            data.put(USER_ID, adminUserId);
-            apiResponseResolver.setRespData(data);
-            return CompletableFuture.completedFuture(apiResponseResolver);
-        }
-        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
-        ObjectNode data = mapper.createObjectNode();
-        return createProfile(apiRequestResolver, profileType).thenComposeAsync(profCreationResult -> {
-            if(!profCreationResult){
-                log.error("{} failure occurred in profile creation", apiRequestResolver.getLoggerString());
-                apiResponseResolver.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR); // 500 internal server error
-                data.put(MESSAGE, "Some error occurred while creating profile, please try again.");
-                apiResponseResolver.setRespData(data);
-                return CompletableFuture.completedFuture(apiResponseResolver);
-            } else {
-                log.info("{} profile created successfully for email: {}", apiRequestResolver.getLoggerString(), email);
-                return fetchUserIdForEmail(apiRequestResolver, email, profileType).thenApplyAsync(userId -> {
-                    if(StringUtils.isEmpty(userId)){
-                        log.error("{} Error occurred while fetching userId for email: {} after profile creation", apiRequestResolver.getLoggerString(), email);
-                        apiResponseResolver.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR); // 500 internal server error
-                        data.put(MESSAGE, "Some error occurred while creating profile, please try again.");
-                        apiResponseResolver.setRespData(data);
-                        return apiResponseResolver;
-                    }
-                    log.info("{} retrieved user id email: {} after profile creation, so returning userId {}", apiRequestResolver.getLoggerString(), email, userId);
-                    apiResponseResolver.setStatusCode(HttpStatus.OK); // 200 ok
-                    data.put(USER_ID, userId);
-                    apiResponseResolver.setRespData(data);
-                    return apiResponseResolver;
-                });
-            }
-        });
-    }
-    private CompletableFuture<String> fetchUserIdForEmail(ApiRequestResolver apiRequestResolver, String email, String profileType){
+//    private CompletableFuture<ApiResponseResolver> createProfileAndRetrieveId(ApiRequestResolver apiRequestResolver, String email, String profileType){
+//        log.info("Starting profile create flow for email: {} and profileType: {}", email, profileType);
+//        if(ADMIN.equalsIgnoreCase(profileType)){
+//            String adminUserId = redisManager.getHashValue(REDIS_FEATURE_FLAGS, ADMIN_USER_ID);
+//            log.info("{} Admin profile type has a hard coded userId : {}, hence no need to create profile",
+//                    apiRequestResolver.getLoggerString(), adminUserId);
+//            ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
+//            ObjectNode data = mapper.createObjectNode();
+//            apiResponseResolver.setStatusCode(HttpStatus.OK); // 200 ok
+//            data.put(USER_ID, adminUserId);
+//            apiResponseResolver.setRespData(data);
+//            return CompletableFuture.completedFuture(apiResponseResolver);
+//        }
+//        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
+//        ObjectNode data = mapper.createObjectNode();
+//        return createProfile(apiRequestResolver, profileType).thenComposeAsync(profCreationResult -> {
+//            if(!profCreationResult){
+//                log.error("{} failure occurred in profile creation", apiRequestResolver.getLoggerString());
+//                apiResponseResolver.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR); // 500 internal server error
+//                data.put(MESSAGE, "Some error occurred while creating profile, please try again.");
+//                apiResponseResolver.setRespData(data);
+//                return CompletableFuture.completedFuture(apiResponseResolver);
+//            } else {
+//                log.info("{} profile created successfully for email: {}", apiRequestResolver.getLoggerString(), email);
+//                return fetchUserIdForEmail(apiRequestResolver, email, profileType).thenApplyAsync(userId -> {
+//                    if(StringUtils.isEmpty(userId)){
+//                        log.error("{} Error occurred while fetching userId for email: {} after profile creation", apiRequestResolver.getLoggerString(), email);
+//                        apiResponseResolver.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR); // 500 internal server error
+//                        data.put(MESSAGE, "Some error occurred while creating profile, please try again.");
+//                        apiResponseResolver.setRespData(data);
+//                        return apiResponseResolver;
+//                    }
+//                    log.info("{} retrieved user id email: {} after profile creation, so returning userId {}", apiRequestResolver.getLoggerString(), email, userId);
+//                    apiResponseResolver.setStatusCode(HttpStatus.OK); // 200 ok
+//                    data.put(USER_ID, userId);
+//                    apiResponseResolver.setRespData(data);
+//                    return apiResponseResolver;
+//                });
+//            }
+//        });
+//    }
+    public CompletableFuture<String> fetchUserIdForEmail(ApiRequestResolver apiRequestResolver, String email, String profileType){
         log.info("{} fetching user id for email {} for profileType {}", apiRequestResolver.getLoggerString(), email, profileType);
-        if(ADMIN.equalsIgnoreCase(profileType)){
-            String adminUserId = redisManager.getHashValue(REDIS_FEATURE_FLAGS, ADMIN_USER_ID);
-            log.info("{} Admin profile type has a hard coded userId : {}", apiRequestResolver.getLoggerString(), adminUserId);
-            return CompletableFuture.completedFuture(adminUserId);
+        if(ADMIN.equalsIgnoreCase(profileType) ){
+            if(checkIfValidAdminEmailId(email)){
+                String adminUserId = redisManager.getHashValue(REDIS_FEATURE_FLAGS, ADMIN_USER_ID);
+                log.info("{} Admin profile type has a hard coded userId : {}", apiRequestResolver.getLoggerString(), adminUserId);
+                return CompletableFuture.completedFuture(adminUserId);
+            } else{
+                log.error("{} Email {} is not valid for admin, not authorized", apiRequestResolver.getLoggerString(), email);
+                return CompletableFuture.completedFuture("");
+            }
         }
         String ddoToGetProfileId = Utils.getDdoForFetchProfileIdByType(profileType);
         if(ddoToGetProfileId == null){
@@ -336,7 +341,7 @@ private CompletableFuture<String> fetchUserIdForEmail(ApiRequestResolver apiRequ
         });
     }
 
-    private boolean checkIfValidAdminEmailId(String emailId){
+    public boolean checkIfValidAdminEmailId(String emailId){
         String adminEmailId = redisManager.getHashValue(REDIS_FEATURE_FLAGS, ADMIN_EMAIL_ID);
         if(adminEmailId==null || StringUtils.isEmpty(adminEmailId)){
             return false;
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/utils/ApplicationConstants.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/utils/ApplicationConstants.java
index a030e13..4569dbc 100644
--- a/src/main/java/sg/edu/nus/iss/shopsmart_backend/utils/ApplicationConstants.java
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/utils/ApplicationConstants.java
@@ -20,6 +20,7 @@ public interface ApplicationConstants {
     String ADDITIONAL_URI_DATA = "additionalUriData";
     String EMAIL = "email";
     String OTP = "otp";
+    String NEEDS_USER_PROF = "needsUserProf";
     String CREATED_AT = "createdAt";
     String VALID_TILL = "validTill";
     String SESSION_ID = "sessionId";
diff --git a/src/test/java/sg/edu/nus/iss/shopsmart_backend/controller/ProfileControllerTest.java b/src/test/java/sg/edu/nus/iss/shopsmart_backend/controller/ProfileControllerTest.java
index 8989b81..6fffeba 100644
--- a/src/test/java/sg/edu/nus/iss/shopsmart_backend/controller/ProfileControllerTest.java
+++ b/src/test/java/sg/edu/nus/iss/shopsmart_backend/controller/ProfileControllerTest.java
@@ -13,6 +13,7 @@
 import org.mockito.MockitoAnnotations;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
+import sg.edu.nus.iss.shopsmart_backend.chains.*;
 import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
 import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
 import sg.edu.nus.iss.shopsmart_backend.service.CommonService;
@@ -31,8 +32,6 @@
 class ProfileControllerTest extends Constants {
     private final ObjectMapper objectMapper = Json.mapper();
 
-    @Mock
-    private ProfileService profileService;
     @Mock
     private CommonService commonService;
     @Mock
@@ -41,6 +40,14 @@ class ProfileControllerTest extends Constants {
     private HttpServletResponse httpServletResponse;
     @Mock
     private HttpServletRequest httpServletRequest;
+    @Mock
+    private GenerateOtpForRegisterChain generateOtpForRegisterChain;
+    @Mock
+    private GenerateOtpForLoginChain generateOtpForLoginChain;
+    @Mock
+    private ValidateOtpAndRegisterChain validateOtpAndRegisterChain;
+    @Mock
+    private ValidateOtpAndLoginChain validateOtpAndLoginChain;
 
     @InjectMocks
     private ProfileController profileController;
@@ -58,7 +65,8 @@ public void testGenerateOtpForRegister() throws Exception {
 
         commonMocking();
 
-        when(profileService.generateOtpForRegister(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
+//        when(profileService.generateOtpForRegister(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
+        when(generateOtpForRegisterChain.handleRequest(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
         ResponseEntity<JsonNode> response = profileController.generateOtpForRegister(CUSTOMER, objectMapper.createObjectNode(),
                 httpServletRequest, httpServletResponse).get();
         assertEquals(HttpStatus.OK, response.getStatusCode());
@@ -76,7 +84,8 @@ public void testVerifyOtpForRegister() throws Exception {
         commonMocking();
         doNothing().when(commonService).updateUserIdInRedisInSessionData(any());
 
-        when(profileService.validateOtpAndRegister(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
+//        when(profileService.validateOtpAndRegister(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
+        when(validateOtpAndRegisterChain.handleRequest(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
         ResponseEntity<JsonNode> response = profileController.verifyOtpForRegister(CUSTOMER, objectMapper.createObjectNode(),
                 httpServletRequest, httpServletResponse).get();
         assertEquals(HttpStatus.OK, response.getStatusCode());
@@ -91,7 +100,8 @@ public void testGenerateOtpForLogin() throws Exception {
 
         commonMocking();
 
-        when(profileService.generateOtpForLogin(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
+//        when(profileService.generateOtpForLogin(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
+        when(generateOtpForLoginChain.handleRequest(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
         ResponseEntity<JsonNode> response = profileController.generateOtpForLogin(CUSTOMER, objectMapper.createObjectNode(),
                 httpServletRequest, httpServletResponse).get();
         assertEquals(HttpStatus.OK, response.getStatusCode());
@@ -109,7 +119,8 @@ public void testVerifyOtpForLogin() throws Exception {
         commonMocking();
         doNothing().when(commonService).updateUserIdInRedisInSessionData(any());
 
-        when(profileService.validateOtpAndLogin(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
+//        when(profileService.validateOtpAndLogin(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
+        when(validateOtpAndLoginChain.handleRequest(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
         ResponseEntity<JsonNode> response = profileController.verifyOtpForLogin(CUSTOMER, objectMapper.createObjectNode(),
                 httpServletRequest, httpServletResponse).get();
         assertEquals(HttpStatus.OK, response.getStatusCode());
diff --git a/src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/CheckProfileExistsHandlerTest.java b/src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/CheckProfileExistsHandlerTest.java
new file mode 100644
index 0000000..c2d0b83
--- /dev/null
+++ b/src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/CheckProfileExistsHandlerTest.java
@@ -0,0 +1,125 @@
+package sg.edu.nus.iss.shopsmart_backend.handlers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.springframework.http.HttpStatus;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
+import sg.edu.nus.iss.shopsmart_backend.service.ProfileService;
+
+import java.util.concurrent.CompletableFuture;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+class CheckProfileExistsHandlerTest {
+
+    @Mock
+    private ProfileService profileService;
+
+    @InjectMocks
+    private CheckProfileExistsHandler handler;
+
+    @Mock
+    private Handler nextHandler;
+
+    @BeforeEach
+    void setUp() {
+        profileService = mock(ProfileService.class);
+        nextHandler = mock(Handler.class);
+        handler = new CheckProfileExistsHandler(profileService);
+        handler.setNext(nextHandler);
+    }
+
+    @Test
+    void testHandle_EmailIsEmpty() {
+        ApiRequestResolver request = new ApiRequestResolver();
+        request.addParamValue("email", ""); // Simulate empty email
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, result.getStatusCode());
+        assertEquals("Email is empty or not found in request for fetching user id", result.getRespData().get("message").asText());
+    }
+
+    @Test
+    void testHandle_NoUserId_NeedsProfileFalse_WithNextHandler() {
+        ApiRequestResolver request = new ApiRequestResolver();
+        request.addParamValue("email", "user@domain.com");
+        request.addParamValue("needsUserProf", "false");
+
+        when(profileService.fetchUserIdForEmail(any(ApiRequestResolver.class), eq("user@domain.com"), eq("admin")))
+                .thenReturn(CompletableFuture.completedFuture(null));
+
+        ApiResponseResolver mockResponse = new ApiResponseResolver();
+        mockResponse.setStatusCode(HttpStatus.OK);
+        when(nextHandler.handle(any(ApiRequestResolver.class), eq("admin")))
+                .thenReturn(CompletableFuture.completedFuture(mockResponse));
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.OK, result.getStatusCode());
+        verify(nextHandler, times(1)).handle(any(ApiRequestResolver.class), eq("admin"));
+    }
+
+    @Test
+    void testHandle_NoUserId_NeedsProfileTrue() {
+        ApiRequestResolver request = new ApiRequestResolver();
+        request.addParamValue("email", "user@domain.com");
+        request.addParamValue("needsUserProf", "true");
+
+        when(profileService.fetchUserIdForEmail(any(ApiRequestResolver.class), eq("user@domain.com"), eq("admin")))
+                .thenReturn(CompletableFuture.completedFuture(null));
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.NOT_FOUND, result.getStatusCode());
+        assertEquals("No existing profile found for the email", result.getRespData().get("message").asText());
+        verify(nextHandler, never()).handle(any(ApiRequestResolver.class), anyString());
+    }
+
+    @Test
+    void testHandle_UserIdFound_WithNextHandler() {
+        ApiRequestResolver request = new ApiRequestResolver();
+        request.addParamValue("email", "user@domain.com");
+        request.addParamValue("needsUserProf", "true");
+
+        when(profileService.fetchUserIdForEmail(any(ApiRequestResolver.class), eq("user@domain.com"), eq("admin")))
+                .thenReturn(CompletableFuture.completedFuture("user123"));
+
+        ApiResponseResolver mockResponse = new ApiResponseResolver();
+        mockResponse.setStatusCode(HttpStatus.OK);
+        when(nextHandler.handle(any(ApiRequestResolver.class), eq("admin")))
+                .thenReturn(CompletableFuture.completedFuture(mockResponse));
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.OK, result.getStatusCode());
+        verify(nextHandler, times(1)).handle(any(ApiRequestResolver.class), eq("admin"));
+    }
+
+    @Test
+    void testHandle_UserIdFound_NoNextHandler() {
+        ApiRequestResolver request = new ApiRequestResolver();
+        request.addParamValue("email", "user@domain.com");
+        request.addParamValue("needsUserProf", "false");
+
+        handler.setNext(null); // Simulate no next handler
+
+        when(profileService.fetchUserIdForEmail(any(ApiRequestResolver.class), eq("user@domain.com"), eq("admin")))
+                .thenReturn(CompletableFuture.completedFuture("user123"));
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.OK, result.getStatusCode());
+        assertEquals("user123", result.getRespData().get("userId").asText());
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/CreateProfileHandlerTest.java b/src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/CreateProfileHandlerTest.java
new file mode 100644
index 0000000..ebfb5c8
--- /dev/null
+++ b/src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/CreateProfileHandlerTest.java
@@ -0,0 +1,78 @@
+package sg.edu.nus.iss.shopsmart_backend.handlers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.http.HttpStatus;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
+import sg.edu.nus.iss.shopsmart_backend.service.ProfileService;
+
+import java.util.concurrent.CompletableFuture;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+class CreateProfileHandlerTest {
+    private ProfileService profileService;
+    private CreateProfileHandler handler;
+    private Handler nextHandler;
+
+    @BeforeEach
+    void setUp() {
+        profileService = mock(ProfileService.class);
+        nextHandler = mock(Handler.class);
+        handler = new CreateProfileHandler(profileService);
+        handler.setNext(nextHandler);
+    }
+
+    @Test
+    void testHandle_ProfileCreationFails() {
+        ApiRequestResolver request = new ApiRequestResolver();
+
+        when(profileService.createProfile(any(ApiRequestResolver.class), anyString()))
+                .thenReturn(CompletableFuture.completedFuture(false)); // Simulate profile creation failure
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, result.getStatusCode());
+        assertEquals("Unable to create profile for the provided request", result.getRespData().get("message").asText());
+        verify(nextHandler, never()).handle(any(ApiRequestResolver.class), anyString());
+    }
+
+    @Test
+    void testHandle_ProfileCreationSuccess_WithNextHandler() {
+        ApiRequestResolver request = new ApiRequestResolver();
+
+        when(profileService.createProfile(any(ApiRequestResolver.class), anyString()))
+                .thenReturn(CompletableFuture.completedFuture(true)); // Simulate profile creation success
+
+        ApiResponseResolver mockResponse = new ApiResponseResolver();
+        mockResponse.setStatusCode(HttpStatus.OK);
+        when(nextHandler.handle(any(ApiRequestResolver.class), anyString()))
+                .thenReturn(CompletableFuture.completedFuture(mockResponse));
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.OK, result.getStatusCode());
+        verify(nextHandler, times(1)).handle(any(ApiRequestResolver.class), eq("admin"));
+    }
+
+    @Test
+    void testHandle_ProfileCreationSuccess_NoNextHandler() {
+        ApiRequestResolver request = new ApiRequestResolver();
+
+        handler.setNext(null); // Simulate no next handler
+
+        when(profileService.createProfile(any(ApiRequestResolver.class), anyString()))
+                .thenReturn(CompletableFuture.completedFuture(true)); // Simulate profile creation success
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.OK, result.getStatusCode());
+        assertEquals("Profile created successfully for user", result.getRespData().get("message").asText());
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/FetchUserIdForEmailHandlerTest.java b/src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/FetchUserIdForEmailHandlerTest.java
new file mode 100644
index 0000000..a4a0fbc
--- /dev/null
+++ b/src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/FetchUserIdForEmailHandlerTest.java
@@ -0,0 +1,96 @@
+package sg.edu.nus.iss.shopsmart_backend.handlers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.http.HttpStatus;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
+import sg.edu.nus.iss.shopsmart_backend.service.ProfileService;
+import sg.edu.nus.iss.shopsmart_backend.utils.Constants;
+
+import java.util.concurrent.CompletableFuture;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+class FetchUserIdForEmailHandlerTest extends Constants {
+    private ProfileService profileService;
+    private FetchUserIdForEmailHandler handler;
+    private Handler nextHandler;
+
+    @BeforeEach
+    void setUp() {
+        profileService = mock(ProfileService.class);
+        nextHandler = mock(Handler.class);
+        handler = new FetchUserIdForEmailHandler(profileService);
+        handler.setNext(nextHandler);
+    }
+
+    @Test
+    void testHandle_EmailIsEmpty() {
+        ApiRequestResolver request = new ApiRequestResolver();
+        request.addParamValue(EMAIL, ""); // Simulate empty email
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, result.getStatusCode());
+        assertEquals("Email is empty or not found in request for fetching user id", result.getRespData().get("message").asText());
+        verify(profileService, never()).fetchUserIdForEmail(any(), anyString(), anyString());
+        verify(nextHandler, never()).handle(any(), anyString());
+    }
+
+    @Test
+    void testHandle_UserIdNotFound() {
+        ApiRequestResolver request = new ApiRequestResolver();
+        request.addParamValue(EMAIL, "test@example.com");
+
+        when(profileService.fetchUserIdForEmail(any(), eq("test@example.com"), anyString()))
+                .thenReturn(CompletableFuture.completedFuture("")); // Simulate no userId found
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.NOT_FOUND, result.getStatusCode());
+        assertEquals("No existing profile found for the email", result.getRespData().get("message").asText());
+        verify(nextHandler, never()).handle(any(), anyString());
+    }
+
+    @Test
+    void testHandle_UserIdFound_WithNextHandler() {
+        ApiRequestResolver request = new ApiRequestResolver();
+        request.addParamValue(EMAIL, "test@example.com");
+
+        when(profileService.fetchUserIdForEmail(any(), eq("test@example.com"), anyString()))
+                .thenReturn(CompletableFuture.completedFuture("user123")); // Simulate userId found
+
+        ApiResponseResolver nextHandlerResponse = new ApiResponseResolver();
+        nextHandlerResponse.setStatusCode(HttpStatus.OK);
+        when(nextHandler.handle(any(), anyString()))
+                .thenReturn(CompletableFuture.completedFuture(nextHandlerResponse));
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.OK, result.getStatusCode());
+        verify(nextHandler, times(1)).handle(any(), eq("admin"));
+    }
+
+    @Test
+    void testHandle_UserIdFound_NoNextHandler() {
+        ApiRequestResolver request = new ApiRequestResolver();
+        request.addParamValue(EMAIL, "test@example.com");
+
+        handler.setNext(null); // No next handler
+
+        when(profileService.fetchUserIdForEmail(any(), eq("test@example.com"), anyString()))
+                .thenReturn(CompletableFuture.completedFuture("user123")); // Simulate userId found
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.OK, result.getStatusCode());
+        assertEquals("user123", result.getRespData().get(Constants.USER_ID).asText());
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/GenerateOtpHandlerTest.java b/src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/GenerateOtpHandlerTest.java
new file mode 100644
index 0000000..5ac8df1
--- /dev/null
+++ b/src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/GenerateOtpHandlerTest.java
@@ -0,0 +1,98 @@
+package sg.edu.nus.iss.shopsmart_backend.handlers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.http.HttpStatus;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
+import sg.edu.nus.iss.shopsmart_backend.service.ProfileService;
+import sg.edu.nus.iss.shopsmart_backend.utils.Constants;
+
+import java.util.concurrent.CompletableFuture;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+class GenerateOtpHandlerTest extends Constants {
+
+    private ProfileService profileService;
+    private GenerateOtpHandler handler;
+    private Handler nextHandler;
+
+    @BeforeEach
+    void setUp() {
+        profileService = mock(ProfileService.class);
+        nextHandler = mock(Handler.class);
+        handler = new GenerateOtpHandler(profileService);
+        handler.setNext(nextHandler);
+    }
+
+    @Test
+    void testHandle_EmailIsEmpty() {
+        ApiRequestResolver request = mock(ApiRequestResolver.class);
+        request.addParamValue(EMAIL, ""); // Simulate empty email
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, result.getStatusCode());
+        assertEquals("Email is empty or not found in request for otp generation", result.getRespData().get(MESSAGE).asText());
+        verify(profileService, never()).generateOtp(any(), anyString());
+        verify(nextHandler, never()).handle(any(), anyString());
+    }
+
+    @Test
+    void testHandle_OtpGenerationFailed() {
+        ApiRequestResolver request = new ApiRequestResolver();
+        request.addParamValue(EMAIL, "test@example.com");
+
+        when(profileService.generateOtp(any(), eq("test@example.com")))
+                .thenReturn(CompletableFuture.completedFuture(false)); // Simulate OTP generation failure
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, result.getStatusCode());
+        assertEquals("Failure occurred in generation of otp for provided email", result.getRespData().get(MESSAGE).asText());
+        verify(nextHandler, never()).handle(any(), anyString());
+    }
+
+    @Test
+    void testHandle_OtpGenerated_WithNextHandler() {
+        ApiRequestResolver request = new ApiRequestResolver();
+        request.addParamValue(EMAIL, "test@example.com");
+
+        when(profileService.generateOtp(any(), eq("test@example.com")))
+                .thenReturn(CompletableFuture.completedFuture(true)); // Simulate successful OTP generation
+
+        ApiResponseResolver nextHandlerResponse = new ApiResponseResolver();
+        nextHandlerResponse.setStatusCode(HttpStatus.OK);
+        when(nextHandler.handle(any(), anyString()))
+                .thenReturn(CompletableFuture.completedFuture(nextHandlerResponse));
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.OK, result.getStatusCode());
+        verify(nextHandler, times(1)).handle(any(), eq("admin"));
+    }
+
+    @Test
+    void testHandle_OtpGenerated_NoNextHandler() {
+        ApiRequestResolver request = new ApiRequestResolver();
+        request.addParamValue(EMAIL, "test@example.com");
+
+        handler.setNext(null); // No next handler in the chain
+
+        when(profileService.generateOtp(any(), eq("test@example.com")))
+                .thenReturn(CompletableFuture.completedFuture(true)); // Simulate successful OTP generation
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.OK, result.getStatusCode());
+        assertEquals("Otp generation completed as expected", result.getRespData().get(MESSAGE).asText());
+        verify(nextHandler, never()).handle(any(), anyString());
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/ValidateOtpHandlerTest.java b/src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/ValidateOtpHandlerTest.java
new file mode 100644
index 0000000..5311e9f
--- /dev/null
+++ b/src/test/java/sg/edu/nus/iss/shopsmart_backend/handlers/ValidateOtpHandlerTest.java
@@ -0,0 +1,103 @@
+package sg.edu.nus.iss.shopsmart_backend.handlers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.http.HttpStatus;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
+import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
+import sg.edu.nus.iss.shopsmart_backend.service.ProfileService;
+import sg.edu.nus.iss.shopsmart_backend.utils.Constants;
+
+import java.util.concurrent.CompletableFuture;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+class ValidateOtpHandlerTest extends Constants {
+    private ProfileService profileService;
+    private ValidateOtpHandler handler;
+    private Handler nextHandler;
+
+    @BeforeEach
+    void setUp() {
+        profileService = mock(ProfileService.class);
+        nextHandler = mock(Handler.class);
+        handler = new ValidateOtpHandler(profileService);
+        handler.setNext(nextHandler);
+    }
+
+    @Test
+    void testHandle_EmailOrOtpIsEmpty() {
+        ApiRequestResolver request = new ApiRequestResolver();
+        request.addParamValue(EMAIL, "");
+        request.addParamValue(OTP, "123456");
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.NOT_FOUND, result.getStatusCode());
+        assertEquals("Email or otp is empty or not found in request for otp validation",
+                result.getRespData().get(Constants.MESSAGE).asText());
+        verify(profileService, never()).validateOtp(any(), anyString(), anyString());
+        verify(nextHandler, never()).handle(any(), anyString());
+    }
+
+    @Test
+    void testHandle_OtpValidationFailed() {
+        ApiRequestResolver request = new ApiRequestResolver();
+        request.addParamValue(EMAIL, "test@example.com");
+        request.addParamValue(OTP, "123456");
+
+        when(profileService.validateOtp(any(), eq("test@example.com"), eq("123456")))
+                .thenReturn(CompletableFuture.completedFuture(false)); // OTP validation failed
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, result.getStatusCode());
+        assertEquals("Failure occurred in validation of otp for provided request",
+                result.getRespData().get(Constants.MESSAGE).asText());
+        verify(nextHandler, never()).handle(any(), anyString());
+    }
+
+    @Test
+    void testHandle_OtpValidationSuccess_WithNextHandler() {
+        ApiRequestResolver request = new ApiRequestResolver();
+        request.addParamValue(EMAIL, "test@example.com");
+        request.addParamValue(OTP, "123456");
+
+        when(profileService.validateOtp(any(), eq("test@example.com"), eq("123456")))
+                .thenReturn(CompletableFuture.completedFuture(true)); // OTP validation success
+
+        ApiResponseResolver nextHandlerResponse = new ApiResponseResolver();
+        nextHandlerResponse.setStatusCode(HttpStatus.OK);
+        when(nextHandler.handle(any(), anyString()))
+                .thenReturn(CompletableFuture.completedFuture(nextHandlerResponse));
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.OK, result.getStatusCode());
+        verify(nextHandler, times(1)).handle(any(), eq("admin"));
+    }
+
+    @Test
+    void testHandle_OtpValidationSuccess_NoNextHandler() {
+        ApiRequestResolver request = new ApiRequestResolver();
+        request.addParamValue(EMAIL, "test@example.com");
+        request.addParamValue(OTP, "123456");
+
+        handler.setNext(null); // No next handler in the chain
+
+        when(profileService.validateOtp(any(), eq("test@example.com"), eq("123456")))
+                .thenReturn(CompletableFuture.completedFuture(true)); // OTP validation success
+
+        CompletableFuture<ApiResponseResolver> response = handler.handle(request, "admin");
+
+        ApiResponseResolver result = response.join();
+        assertEquals(HttpStatus.OK, result.getStatusCode());
+        assertEquals("Otp validation completed as expected", result.getRespData().get(Constants.MESSAGE).asText());
+        verify(nextHandler, never()).handle(any(), anyString());
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/sg/edu/nus/iss/shopsmart_backend/service/ProfileServiceTest.java b/src/test/java/sg/edu/nus/iss/shopsmart_backend/service/ProfileServiceTest.java
index c738286..b76713e 100644
--- a/src/test/java/sg/edu/nus/iss/shopsmart_backend/service/ProfileServiceTest.java
+++ b/src/test/java/sg/edu/nus/iss/shopsmart_backend/service/ProfileServiceTest.java
@@ -13,6 +13,7 @@
 import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
 import sg.edu.nus.iss.shopsmart_backend.model.DataDynamicObject;
 import sg.edu.nus.iss.shopsmart_backend.model.Response;
+import sg.edu.nus.iss.shopsmart_backend.utils.ApplicationConstants;
 import sg.edu.nus.iss.shopsmart_backend.utils.Constants;
 import sg.edu.nus.iss.shopsmart_backend.utils.RedisManager;
 import sg.edu.nus.iss.shopsmart_backend.utils.WSUtils;
@@ -40,455 +41,621 @@ public void setup() {
     }
 
     @Test
-    public void testGenerateOtpForRegister_NoPayload() throws Exception {
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(objectMapper.nullNode());
+    public void testGenerateOtp_Success() throws Exception{
+        DataDynamicObject ddo = getDdo("service", "GET", "api", 1000, 30000);
+        Response resp = new Response();
+        resp.setStatus(SUCCESS);
 
-        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
-        assertEquals("No request body found for otp generation for email", responseResolver.getRespData().get("message").asText());
-    }
+        when(redisManager.getDdoData(anyString())).thenReturn(ddo);
+        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
+        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(resp));
 
-    @Test
-    public void testGenerateOtpForRegister_NoEmail() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put("otp", "123456");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
-        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
-        assertEquals("Email is required for generating OTP for registration", responseResolver.getRespData().get("message").asText());
+        Boolean otpResp = profileService.generateOtp(new ApiRequestResolver(), "abc@mail.com").get();
+        assertTrue(otpResp);
     }
 
     @Test
-    public void testGenerateOtpForRegister_UnAuthAdmin() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put(EMAIL, "admin1223@mail.com");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
-        when(redisManager.getHashValue(anyString(), anyString())).thenReturn("admin@mail.com");
+    public void testGenerateOtp_Failure() throws Exception{
+        DataDynamicObject ddo = getDdo("service", "GET", "api", 1000, 30000);
+        Response resp = new Response();
+        resp.setStatus(FAILURE);
 
-        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, ADMIN).get();
-        assertEquals(HttpStatus.UNAUTHORIZED, responseResolver.getStatusCode());
-        assertEquals("Email is not authorized for admin OTP generation", responseResolver.getRespData().get("message").asText());
-    }
+        when(redisManager.getDdoData(anyString())).thenReturn(ddo);
+        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
+        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(resp));
 
-    @Test
-    public void testGenerateOtpForRegister_AdminUser() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put(EMAIL, "admin@mail.com");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
-        when(redisManager.getHashValue(anyString(), eq(ADMIN_EMAIL_ID))).thenReturn("admin@mail.com");
-        when(redisManager.getHashValue(anyString(), eq(ADMIN_USER_ID))).thenReturn("admin123");
-
-        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, ADMIN).get();
-        assertEquals(HttpStatus.CONFLICT, responseResolver.getStatusCode());
-        assertEquals("User already exists with email, please login", responseResolver.getRespData().get("message").asText());
+        Boolean otpResp = profileService.generateOtp(new ApiRequestResolver(), "abc@mail.com").get();
+        assertFalse(otpResp);
     }
 
     @Test
-    public void testGenerateOtpForRegister_ExistingProfileUser() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put(EMAIL, "user@mail.com");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
+    public void testValidateOtp_Success() throws Exception{
         DataDynamicObject ddo = getDdo("service", "GET", "api", 1000, 30000);
-
-        ObjectNode data = objectMapper.createObjectNode();
-        data.put(MESSAGE, "\"804jt408\"");
         Response resp = new Response();
         resp.setStatus(SUCCESS);
-        resp.setData(data);
 
         when(redisManager.getDdoData(anyString())).thenReturn(ddo);
         when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
         when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(resp));
 
-        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.CONFLICT, responseResolver.getStatusCode());
-        assertEquals("User already exists with email, please login", responseResolver.getRespData().get("message").asText());
+        Boolean otpResp = profileService.validateOtp(new ApiRequestResolver(), "abc@mail.com", "123456").get();
+        assertTrue(otpResp);
     }
 
-    //dont need to write success as it will get covered in success for generateOtpForLogin
     @Test
-    public void testGenerateOtpForRegister_Failure() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put(EMAIL, "user@mail.com");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
-        DataDynamicObject fetchCustId = getDdo("service", "GET", "api", 1000, 30000);
-        DataDynamicObject genOtp = getDdo("service", "POST", "gen-otp", 1000, 30000);
-
+    public void testValidateOtp_Failure() throws Exception{
+        DataDynamicObject ddo = getDdo("service", "GET", "api", 1000, 30000);
         Response resp = new Response();
         resp.setStatus(FAILURE);
-        resp.setHttpStatusCode(HttpStatus.NOT_FOUND);
 
-        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchCustId);
-        when(redisManager.getDdoData(GENERATE_OTP)).thenReturn(genOtp);
+        when(redisManager.getDdoData(anyString())).thenReturn(ddo);
         when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
-        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString()))
-                .thenReturn(CompletableFuture.completedFuture(resp));
-
-        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.NOT_FOUND, responseResolver.getStatusCode());
-        assertEquals("Error generating OTP", responseResolver.getRespData().get("message").asText());
-    }
-
-    @Test
-    public void testGenerateOtpForLogin_NoPayload() throws Exception {
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(objectMapper.nullNode());
-
-        ApiResponseResolver responseResolver = profileService.generateOtpForLogin(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
-        assertEquals("No request body found for otp generation for email", responseResolver.getRespData().get("message").asText());
-    }
+        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(resp));
 
-    @Test
-    public void testGenerateOtpForLogin_NoEmail() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put("otp", "123456");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
-        ApiResponseResolver responseResolver = profileService.generateOtpForLogin(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
-        assertEquals("Email is required for generating OTP for login", responseResolver.getRespData().get("message").asText());
+        Boolean otpResp = profileService.validateOtp(new ApiRequestResolver(), "abc@mail.com", "123456").get();
+        assertFalse(otpResp);
     }
 
     @Test
-    public void testGenerateOtpForLogin_NoExistingProfile() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put(EMAIL, "user@mail.com");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
+    public void testCreateProfile_Admin() throws Exception{
         DataDynamicObject ddo = getDdo("service", "GET", "api", 1000, 30000);
-
         Response resp = new Response();
-        resp.setStatus(FAILURE);
+        resp.setStatus(SUCCESS);
 
         when(redisManager.getDdoData(anyString())).thenReturn(ddo);
         when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
         when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(resp));
 
-        ApiResponseResolver responseResolver = profileService.generateOtpForLogin(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.NOT_FOUND, responseResolver.getStatusCode());
-        assertEquals("User does not exists with email, please register", responseResolver.getRespData().get("message").asText());
+        Boolean otpResp = profileService.createProfile(new ApiRequestResolver(), ApplicationConstants.ADMIN).get();
+        assertTrue(otpResp);
     }
 
-    //dont need to write failure case as it will get covered in failure for generateOtpForRegister
     @Test
-    public void testGenerateOtpForLogin_Success() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put(EMAIL, "user@mail.com");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
-        DataDynamicObject fetchCustId = getDdo("service", "GET", "api", 1000, 30000);
-        DataDynamicObject genOtp = getDdo("service", "POST", "gen-otp", 1000, 30000);
-
-        ObjectNode data = objectMapper.createObjectNode();
-        data.put(MESSAGE, "\"804jt408\"");
+    public void testCreateProfile_Success() throws Exception{
+        DataDynamicObject ddo = getDdo("service", "GET", "api", 1000, 30000);
         Response resp = new Response();
         resp.setStatus(SUCCESS);
-        resp.setHttpStatusCode(HttpStatus.OK);
-        resp.setData(data);
 
-        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchCustId);
-        when(redisManager.getDdoData(GENERATE_OTP)).thenReturn(genOtp);
+        when(redisManager.getDdoData(anyString())).thenReturn(ddo);
         when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
-        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString()))
-                .thenReturn(CompletableFuture.completedFuture(resp));
+        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(resp));
 
-        ApiResponseResolver responseResolver = profileService.generateOtpForLogin(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.OK, responseResolver.getStatusCode());
-        assertEquals("OTP generated successfully", responseResolver.getRespData().get("message").asText());
+        Boolean otpResp = profileService.createProfile(new ApiRequestResolver(), ApplicationConstants.CUSTOMER).get();
+        assertTrue(otpResp);
     }
 
     @Test
-    public void testValidateOtpAndRegister_NoPayload() throws Exception {
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(objectMapper.nullNode());
+    public void testCreateProfile_Failure() throws Exception{
+        DataDynamicObject ddo = getDdo("service", "GET", "api", 1000, 30000);
+        Response resp = new Response();
+        resp.setStatus(FAILURE);
 
-        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
-        assertEquals("No request body found for otp validation of email", responseResolver.getRespData().get("message").asText());
+        when(redisManager.getDdoData(anyString())).thenReturn(ddo);
+        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
+        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(resp));
+
+        Boolean otpResp = profileService.createProfile(new ApiRequestResolver(), ApplicationConstants.CUSTOMER).get();
+        assertFalse(otpResp);
     }
 
     @Test
-    public void testValidateOtpAndRegister_NoEmailOrOtp() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put("pass", "123456");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
-        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
-        assertEquals("Email and OTP are required for validating OTP for registration", responseResolver.getRespData().get("message").asText());
+    public void testCreateProfile_Invalid_Prof_Type() throws Exception{
+        Boolean otpResp = profileService.createProfile(new ApiRequestResolver(), "invalid").get();
+        assertFalse(otpResp);
     }
 
     @Test
-    public void testValidateOtpAndRegister_OtpVerifyFailed() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put(EMAIL, "user@mail.com");
-        reqBody.put(OTP, "123456");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
+    public void testFetchUserIdForEmail_Admin_Success() throws Exception{
+        when(redisManager.getHashValue(anyString(), eq(ADMIN_EMAIL_ID))).thenReturn("abc@mail.com");
+        when(redisManager.getHashValue(anyString(), eq(ADMIN_USER_ID))).thenReturn("123456");
 
-        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
-
-        Response resp = new Response();
-        resp.setStatus(FAILURE);
-        when(redisManager.getDdoData(anyString())).thenReturn(valOtp);
-        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
-        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString()))
-                .thenReturn(CompletableFuture.completedFuture(resp));
-
-        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.UNAUTHORIZED, responseResolver.getStatusCode());
-        assertEquals("OTP validation failed, please try again", responseResolver.getRespData().get("message").asText());
+        String otpResp = profileService.fetchUserIdForEmail(new ApiRequestResolver(), "abc@mail.com", ADMIN).get();
+        assertEquals("123456", otpResp);
     }
 
     @Test
-    public void testValidateOtpAndRegister_AdminProfCreate() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put(EMAIL, "user@mail.com");
-        reqBody.put(OTP, "123456");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
-        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
-
-        Response resp = new Response();
-        resp.setStatus(SUCCESS);
-        when(redisManager.getDdoData(anyString())).thenReturn(valOtp);
-        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
-        when(redisManager.getHashValue(anyString(), anyString())).thenReturn("admin1234");
-        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString()))
-                .thenReturn(CompletableFuture.completedFuture(resp));
-
-        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, ADMIN).get();
-        assertEquals(HttpStatus.OK, responseResolver.getStatusCode());
-        assertEquals("admin1234", responseResolver.getRespData().get(USER_ID).asText());
+    public void testFetchUserIdForEmail_Admin_Failure() throws Exception{
+        when(redisManager.getHashValue(anyString(), anyString())).thenReturn("def@mail.com");
 
+        String otpResp = profileService.fetchUserIdForEmail(new ApiRequestResolver(), "abc@mail.com", ADMIN).get();
+        assertEquals("", otpResp);
     }
 
     @Test
-    public void testValidateOtpAndRegister_CreateProfileFailed() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put(EMAIL, "user@mail.com");
-        reqBody.put(OTP, "123456");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
-        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
-        Response valOtpResp = new Response();
-        valOtpResp.setStatus(SUCCESS);
-
-        DataDynamicObject createProf = getDdo("service", "POST", "create-prof", 1000, 30000);
-        Response createProfResp = new Response();
-        createProfResp.setStatus(FAILURE);
-
-        when(redisManager.getDdoData(VALIDATE_OTP)).thenReturn(valOtp);
-        when(redisManager.getDdoData(CREATE_CUSTOMER_PROFILE)).thenReturn(createProf);
-        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
-        when(wsUtils.makeWSCall(eq("http://localhost:8080/val-otp?email=user@mail.com&otp=123456"), any(), any(),
-                any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(valOtpResp));
-        when(wsUtils.makeWSCall(eq("http://localhost:8080/create-prof"), any(), any(), any(), anyLong(), anyLong(), anyString()))
-                .thenReturn(CompletableFuture.completedFuture(createProfResp));
-
-        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseResolver.getStatusCode());
-        assertEquals("Some error occurred while creating profile, please try again.", responseResolver.getRespData().get(MESSAGE).asText());
-    }
+    public void testFetchUserIdForEmail_Admin_Failure2() throws Exception{
+        when(redisManager.getHashValue(anyString(), anyString())).thenReturn(null);
 
-    @Test
-    public void testValidateOtpAndRegister_CreateProfileSuccess_FetchUserFailed() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put(EMAIL, "user@mail.com");
-        reqBody.put(OTP, "123456");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
-        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
-        Response valOtpResp = new Response();
-        valOtpResp.setStatus(SUCCESS);
-
-        DataDynamicObject createProf = getDdo("service", "POST", "create-prof", 1000, 30000);
-        Response createProfResp = new Response();
-        createProfResp.setStatus(SUCCESS);
-
-        DataDynamicObject fetchProfId = getDdo("service", "GET", "prof-id", 1000, 30000);
-        Response fetchProfIdResp = new Response();
-        fetchProfIdResp.setStatus(FAILURE);
-
-        when(redisManager.getDdoData(VALIDATE_OTP)).thenReturn(valOtp);
-        when(redisManager.getDdoData(CREATE_CUSTOMER_PROFILE)).thenReturn(createProf);
-        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchProfId);
-        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
-        when(wsUtils.makeWSCall(eq("http://localhost:8080/val-otp?email=user@mail.com&otp=123456"), any(), any(),
-                any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(valOtpResp));
-        when(wsUtils.makeWSCall(eq("http://localhost:8080/create-prof"), any(), any(), any(), anyLong(), anyLong(), anyString()))
-                .thenReturn(CompletableFuture.completedFuture(createProfResp));
-        when(wsUtils.makeWSCall(eq("http://localhost:8080/prof-id/user@mail.com"), any(), any(), any(), anyLong(), anyLong(), anyString()))
-                .thenReturn(CompletableFuture.completedFuture(fetchProfIdResp));
-
-        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseResolver.getStatusCode());
-        assertEquals("Some error occurred while creating profile, please try again.", responseResolver.getRespData().get(MESSAGE).asText());
+        String otpResp = profileService.fetchUserIdForEmail(new ApiRequestResolver(), "abc@mail.com", ADMIN).get();
+        assertEquals("", otpResp);
     }
 
     @Test
-    public void testValidateOtpAndRegister_Success() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put(EMAIL, "user@mail.com");
-        reqBody.put(OTP, "123456");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
-        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
-        Response valOtpResp = new Response();
-        valOtpResp.setStatus(SUCCESS);
-
-        DataDynamicObject createProf = getDdo("service", "POST", "create-prof", 1000, 30000);
-        Response createProfResp = new Response();
-        createProfResp.setStatus(SUCCESS);
-
-        DataDynamicObject fetchProfId = getDdo("service", "GET", "prof-id", 1000, 30000);
+    public void testFetchUserIdForEmail_Success() throws Exception{
+        DataDynamicObject ddo = getDdo("service", "GET", "api", 1000, 30000);
         ObjectNode data = objectMapper.createObjectNode();
         data.put(MESSAGE, "\"804jt408\"");
-        Response fetchProfIdResp = new Response();
-        fetchProfIdResp.setStatus(SUCCESS);
-        fetchProfIdResp.setData(data);
-
-        when(redisManager.getDdoData(VALIDATE_OTP)).thenReturn(valOtp);
-        when(redisManager.getDdoData(CREATE_CUSTOMER_PROFILE)).thenReturn(createProf);
-        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchProfId);
-        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
-        when(wsUtils.makeWSCall(eq("http://localhost:8080/val-otp?email=user@mail.com&otp=123456"), any(), any(),
-                any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(valOtpResp));
-        when(wsUtils.makeWSCall(eq("http://localhost:8080/create-prof"), any(), any(), any(), anyLong(), anyLong(), anyString()))
-                .thenReturn(CompletableFuture.completedFuture(createProfResp));
-        when(wsUtils.makeWSCall(eq("http://localhost:8080/prof-id/user@mail.com"), any(), any(), any(), anyLong(), anyLong(), anyString()))
-                .thenReturn(CompletableFuture.completedFuture(fetchProfIdResp));
-
-        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.OK, responseResolver.getStatusCode());
-        assertEquals("804jt408", responseResolver.getRespData().get(USER_ID).asText());
-    }
-
-    @Test
-    public void testValidateOtpAndLogin_NoPayload() throws Exception {
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(objectMapper.nullNode());
+        Response resp = new Response();
+        resp.setStatus(SUCCESS);
+        resp.setData(data);
 
-        ApiResponseResolver responseResolver = profileService.validateOtpAndLogin(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
-        assertEquals("No request body found for otp validation of email", responseResolver.getRespData().get("message").asText());
-    }
+        when(redisManager.getDdoData(anyString())).thenReturn(ddo);
+        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
+        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(resp));
 
-    @Test
-    public void testValidateOtpAndLogin_NoEmailOrOtp() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put("pass", "123456");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
-        ApiResponseResolver responseResolver = profileService.validateOtpAndLogin(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
-        assertEquals("Email and OTP are required for validating OTP for login", responseResolver.getRespData().get("message").asText());
+        String otpResp = profileService.fetchUserIdForEmail(new ApiRequestResolver(), "abc@mail.com", CUSTOMER).get();
+        assertEquals("804jt408", otpResp);
     }
 
     @Test
-    public void testValidateOtpAndLogin_OtpVerifyFailed() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put(EMAIL, "user@mail.com");
-        reqBody.put(OTP, "123456");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
-        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
-
+    public void testFetchUserIdForEmail_Failure() throws Exception{
+        DataDynamicObject ddo = getDdo("service", "GET", "api", 1000, 30000);
         Response resp = new Response();
         resp.setStatus(FAILURE);
-        when(redisManager.getDdoData(anyString())).thenReturn(valOtp);
-        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
-        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString()))
-                .thenReturn(CompletableFuture.completedFuture(resp));
-
-        ApiResponseResolver responseResolver = profileService.validateOtpAndLogin(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.UNAUTHORIZED, responseResolver.getStatusCode());
-        assertEquals("OTP validation failed, please try again", responseResolver.getRespData().get("message").asText());
-    }
 
-    @Test
-    public void testValidateOtpAndLogin_FetchUserFailed() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put(EMAIL, "user@mail.com");
-        reqBody.put(OTP, "123456");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
-        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
-        Response valOtpResp = new Response();
-        valOtpResp.setStatus(SUCCESS);
-
-        DataDynamicObject fetchProfId = getDdo("service", "GET", "prof-id", 1000, 30000);
-        Response fetchProfIdResp = new Response();
-        fetchProfIdResp.setStatus(FAILURE);
-
-        when(redisManager.getDdoData(VALIDATE_OTP)).thenReturn(valOtp);
-        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchProfId);
-        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
-        when(wsUtils.makeWSCall(eq("http://localhost:8080/val-otp?email=user@mail.com&otp=123456"), any(), any(),
-                any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(valOtpResp));
-        when(wsUtils.makeWSCall(eq("http://localhost:8080/prof-id/user@mail.com"), any(), any(), any(), anyLong(), anyLong(), anyString()))
-                .thenReturn(CompletableFuture.completedFuture(fetchProfIdResp));
-
-        ApiResponseResolver responseResolver = profileService.validateOtpAndLogin(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseResolver.getStatusCode());
-        assertEquals("Some error occurred while fetching userId, please try again.", responseResolver.getRespData().get(MESSAGE).asText());
+        when(redisManager.getDdoData(anyString())).thenReturn(ddo);
+        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
+        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(resp));
+
+        String otpResp = profileService.fetchUserIdForEmail(new ApiRequestResolver(), "abc@mail.com", CUSTOMER).get();
+        assertEquals("", otpResp);
     }
 
     @Test
-    public void testValidateOtpAndLogin_Success() throws Exception {
-        ObjectNode reqBody = objectMapper.createObjectNode();
-        reqBody.put(EMAIL, "user@mail.com");
-        reqBody.put(OTP, "123456");
-        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-        apiRequestResolver.setRequestBody(reqBody);
-
-        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
-        Response valOtpResp = new Response();
-        valOtpResp.setStatus(SUCCESS);
-
-        DataDynamicObject fetchProfId = getDdo("service", "GET", "prof-id", 1000, 30000);
-        ObjectNode data = objectMapper.createObjectNode();
-        data.put(MESSAGE, "\"804jt408\"");
-        Response fetchProfIdResp = new Response();
-        fetchProfIdResp.setStatus(SUCCESS);
-        fetchProfIdResp.setData(data);
-
-        when(redisManager.getDdoData(VALIDATE_OTP)).thenReturn(valOtp);
-        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchProfId);
-        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
-        when(wsUtils.makeWSCall(eq("http://localhost:8080/val-otp?email=user@mail.com&otp=123456"), any(), any(),
-                any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(valOtpResp));
-        when(wsUtils.makeWSCall(eq("http://localhost:8080/prof-id/user@mail.com"), any(), any(), any(), anyLong(), anyLong(), anyString()))
-                .thenReturn(CompletableFuture.completedFuture(fetchProfIdResp));
-
-        ApiResponseResolver responseResolver = profileService.validateOtpAndLogin(apiRequestResolver, CUSTOMER).get();
-        assertEquals(HttpStatus.OK, responseResolver.getStatusCode());
-        assertEquals("804jt408", responseResolver.getRespData().get(USER_ID).asText());
+    public void testFetchUserIdForEmail_Invalid_Prof_Type() throws Exception{
+        String otpResp = profileService.fetchUserIdForEmail(new ApiRequestResolver(), "abc@mail.com", "invalid").get();
+        assertEquals("", otpResp);
     }
 
+//    @Test
+//    public void testGenerateOtpForRegister_NoPayload() throws Exception {
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(objectMapper.nullNode());
+//
+//        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
+//        assertEquals("No request body found for otp generation for email", responseResolver.getRespData().get("message").asText());
+//    }
+//
+//    @Test
+//    public void testGenerateOtpForRegister_NoEmail() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put("otp", "123456");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
+//        assertEquals("Email is required for generating OTP for registration", responseResolver.getRespData().get("message").asText());
+//    }
+//
+//    @Test
+//    public void testGenerateOtpForRegister_UnAuthAdmin() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put(EMAIL, "admin1223@mail.com");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        when(redisManager.getHashValue(anyString(), anyString())).thenReturn("admin@mail.com");
+//
+//        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, ADMIN).get();
+//        assertEquals(HttpStatus.UNAUTHORIZED, responseResolver.getStatusCode());
+//        assertEquals("Email is not authorized for admin OTP generation", responseResolver.getRespData().get("message").asText());
+//    }
+//
+//    @Test
+//    public void testGenerateOtpForRegister_AdminUser() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put(EMAIL, "admin@mail.com");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        when(redisManager.getHashValue(anyString(), eq(ADMIN_EMAIL_ID))).thenReturn("admin@mail.com");
+//        when(redisManager.getHashValue(anyString(), eq(ADMIN_USER_ID))).thenReturn("admin123");
+//
+//        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, ADMIN).get();
+//        assertEquals(HttpStatus.CONFLICT, responseResolver.getStatusCode());
+//        assertEquals("User already exists with email, please login", responseResolver.getRespData().get("message").asText());
+//    }
+//
+//    @Test
+//    public void testGenerateOtpForRegister_ExistingProfileUser() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put(EMAIL, "user@mail.com");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        DataDynamicObject ddo = getDdo("service", "GET", "api", 1000, 30000);
+//
+//        ObjectNode data = objectMapper.createObjectNode();
+//        data.put(MESSAGE, "\"804jt408\"");
+//        Response resp = new Response();
+//        resp.setStatus(SUCCESS);
+//        resp.setData(data);
+//
+//        when(redisManager.getDdoData(anyString())).thenReturn(ddo);
+//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
+//        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(resp));
+//
+//        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.CONFLICT, responseResolver.getStatusCode());
+//        assertEquals("User already exists with email, please login", responseResolver.getRespData().get("message").asText());
+//    }
+//
+//    //dont need to write success as it will get covered in success for generateOtpForLogin
+//    @Test
+//    public void testGenerateOtpForRegister_Failure() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put(EMAIL, "user@mail.com");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        DataDynamicObject fetchCustId = getDdo("service", "GET", "api", 1000, 30000);
+//        DataDynamicObject genOtp = getDdo("service", "POST", "gen-otp", 1000, 30000);
+//
+//        Response resp = new Response();
+//        resp.setStatus(FAILURE);
+//        resp.setHttpStatusCode(HttpStatus.NOT_FOUND);
+//
+//        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchCustId);
+//        when(redisManager.getDdoData(GENERATE_OTP)).thenReturn(genOtp);
+//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
+//        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString()))
+//                .thenReturn(CompletableFuture.completedFuture(resp));
+//
+//        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.NOT_FOUND, responseResolver.getStatusCode());
+//        assertEquals("Error generating OTP", responseResolver.getRespData().get("message").asText());
+//    }
+//
+//    @Test
+//    public void testGenerateOtpForLogin_NoPayload() throws Exception {
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(objectMapper.nullNode());
+//
+//        ApiResponseResolver responseResolver = profileService.generateOtpForLogin(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
+//        assertEquals("No request body found for otp generation for email", responseResolver.getRespData().get("message").asText());
+//    }
+//
+//    @Test
+//    public void testGenerateOtpForLogin_NoEmail() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put("otp", "123456");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        ApiResponseResolver responseResolver = profileService.generateOtpForLogin(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
+//        assertEquals("Email is required for generating OTP for login", responseResolver.getRespData().get("message").asText());
+//    }
+//
+//    @Test
+//    public void testGenerateOtpForLogin_NoExistingProfile() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put(EMAIL, "user@mail.com");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        DataDynamicObject ddo = getDdo("service", "GET", "api", 1000, 30000);
+//
+//        Response resp = new Response();
+//        resp.setStatus(FAILURE);
+//
+//        when(redisManager.getDdoData(anyString())).thenReturn(ddo);
+//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
+//        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(resp));
+//
+//        ApiResponseResolver responseResolver = profileService.generateOtpForLogin(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.NOT_FOUND, responseResolver.getStatusCode());
+//        assertEquals("User does not exists with email, please register", responseResolver.getRespData().get("message").asText());
+//    }
+//
+//    //dont need to write failure case as it will get covered in failure for generateOtpForRegister
+//    @Test
+//    public void testGenerateOtpForLogin_Success() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put(EMAIL, "user@mail.com");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        DataDynamicObject fetchCustId = getDdo("service", "GET", "api", 1000, 30000);
+//        DataDynamicObject genOtp = getDdo("service", "POST", "gen-otp", 1000, 30000);
+//
+//        ObjectNode data = objectMapper.createObjectNode();
+//        data.put(MESSAGE, "\"804jt408\"");
+//        Response resp = new Response();
+//        resp.setStatus(SUCCESS);
+//        resp.setHttpStatusCode(HttpStatus.OK);
+//        resp.setData(data);
+//
+//        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchCustId);
+//        when(redisManager.getDdoData(GENERATE_OTP)).thenReturn(genOtp);
+//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
+//        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString()))
+//                .thenReturn(CompletableFuture.completedFuture(resp));
+//
+//        ApiResponseResolver responseResolver = profileService.generateOtpForLogin(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.OK, responseResolver.getStatusCode());
+//        assertEquals("OTP generated successfully", responseResolver.getRespData().get("message").asText());
+//    }
+//
+//    @Test
+//    public void testValidateOtpAndRegister_NoPayload() throws Exception {
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(objectMapper.nullNode());
+//
+//        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
+//        assertEquals("No request body found for otp validation of email", responseResolver.getRespData().get("message").asText());
+//    }
+//
+//    @Test
+//    public void testValidateOtpAndRegister_NoEmailOrOtp() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put("pass", "123456");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
+//        assertEquals("Email and OTP are required for validating OTP for registration", responseResolver.getRespData().get("message").asText());
+//    }
+//
+//    @Test
+//    public void testValidateOtpAndRegister_OtpVerifyFailed() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put(EMAIL, "user@mail.com");
+//        reqBody.put(OTP, "123456");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
+//
+//        Response resp = new Response();
+//        resp.setStatus(FAILURE);
+//        when(redisManager.getDdoData(anyString())).thenReturn(valOtp);
+//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
+//        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString()))
+//                .thenReturn(CompletableFuture.completedFuture(resp));
+//
+//        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.UNAUTHORIZED, responseResolver.getStatusCode());
+//        assertEquals("OTP validation failed, please try again", responseResolver.getRespData().get("message").asText());
+//    }
+//
+//    @Test
+//    public void testValidateOtpAndRegister_AdminProfCreate() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put(EMAIL, "user@mail.com");
+//        reqBody.put(OTP, "123456");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
+//
+//        Response resp = new Response();
+//        resp.setStatus(SUCCESS);
+//        when(redisManager.getDdoData(anyString())).thenReturn(valOtp);
+//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
+//        when(redisManager.getHashValue(anyString(), anyString())).thenReturn("admin1234");
+//        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString()))
+//                .thenReturn(CompletableFuture.completedFuture(resp));
+//
+//        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, ADMIN).get();
+//        assertEquals(HttpStatus.OK, responseResolver.getStatusCode());
+//        assertEquals("admin1234", responseResolver.getRespData().get(USER_ID).asText());
+//
+//    }
+//
+//    @Test
+//    public void testValidateOtpAndRegister_CreateProfileFailed() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put(EMAIL, "user@mail.com");
+//        reqBody.put(OTP, "123456");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
+//        Response valOtpResp = new Response();
+//        valOtpResp.setStatus(SUCCESS);
+//
+//        DataDynamicObject createProf = getDdo("service", "POST", "create-prof", 1000, 30000);
+//        Response createProfResp = new Response();
+//        createProfResp.setStatus(FAILURE);
+//
+//        when(redisManager.getDdoData(VALIDATE_OTP)).thenReturn(valOtp);
+//        when(redisManager.getDdoData(CREATE_CUSTOMER_PROFILE)).thenReturn(createProf);
+//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
+//        when(wsUtils.makeWSCall(eq("http://localhost:8080/val-otp?email=user@mail.com&otp=123456"), any(), any(),
+//                any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(valOtpResp));
+//        when(wsUtils.makeWSCall(eq("http://localhost:8080/create-prof"), any(), any(), any(), anyLong(), anyLong(), anyString()))
+//                .thenReturn(CompletableFuture.completedFuture(createProfResp));
+//
+//        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseResolver.getStatusCode());
+//        assertEquals("Some error occurred while creating profile, please try again.", responseResolver.getRespData().get(MESSAGE).asText());
+//    }
+//
+//    @Test
+//    public void testValidateOtpAndRegister_CreateProfileSuccess_FetchUserFailed() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put(EMAIL, "user@mail.com");
+//        reqBody.put(OTP, "123456");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
+//        Response valOtpResp = new Response();
+//        valOtpResp.setStatus(SUCCESS);
+//
+//        DataDynamicObject createProf = getDdo("service", "POST", "create-prof", 1000, 30000);
+//        Response createProfResp = new Response();
+//        createProfResp.setStatus(SUCCESS);
+//
+//        DataDynamicObject fetchProfId = getDdo("service", "GET", "prof-id", 1000, 30000);
+//        Response fetchProfIdResp = new Response();
+//        fetchProfIdResp.setStatus(FAILURE);
+//
+//        when(redisManager.getDdoData(VALIDATE_OTP)).thenReturn(valOtp);
+//        when(redisManager.getDdoData(CREATE_CUSTOMER_PROFILE)).thenReturn(createProf);
+//        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchProfId);
+//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
+//        when(wsUtils.makeWSCall(eq("http://localhost:8080/val-otp?email=user@mail.com&otp=123456"), any(), any(),
+//                any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(valOtpResp));
+//        when(wsUtils.makeWSCall(eq("http://localhost:8080/create-prof"), any(), any(), any(), anyLong(), anyLong(), anyString()))
+//                .thenReturn(CompletableFuture.completedFuture(createProfResp));
+//        when(wsUtils.makeWSCall(eq("http://localhost:8080/prof-id/user@mail.com"), any(), any(), any(), anyLong(), anyLong(), anyString()))
+//                .thenReturn(CompletableFuture.completedFuture(fetchProfIdResp));
+//
+//        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseResolver.getStatusCode());
+//        assertEquals("Some error occurred while creating profile, please try again.", responseResolver.getRespData().get(MESSAGE).asText());
+//    }
+//
+//    @Test
+//    public void testValidateOtpAndRegister_Success() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put(EMAIL, "user@mail.com");
+//        reqBody.put(OTP, "123456");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
+//        Response valOtpResp = new Response();
+//        valOtpResp.setStatus(SUCCESS);
+//
+//        DataDynamicObject createProf = getDdo("service", "POST", "create-prof", 1000, 30000);
+//        Response createProfResp = new Response();
+//        createProfResp.setStatus(SUCCESS);
+//
+//        DataDynamicObject fetchProfId = getDdo("service", "GET", "prof-id", 1000, 30000);
+//        ObjectNode data = objectMapper.createObjectNode();
+//        data.put(MESSAGE, "\"804jt408\"");
+//        Response fetchProfIdResp = new Response();
+//        fetchProfIdResp.setStatus(SUCCESS);
+//        fetchProfIdResp.setData(data);
+//
+//        when(redisManager.getDdoData(VALIDATE_OTP)).thenReturn(valOtp);
+//        when(redisManager.getDdoData(CREATE_CUSTOMER_PROFILE)).thenReturn(createProf);
+//        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchProfId);
+//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
+//        when(wsUtils.makeWSCall(eq("http://localhost:8080/val-otp?email=user@mail.com&otp=123456"), any(), any(),
+//                any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(valOtpResp));
+//        when(wsUtils.makeWSCall(eq("http://localhost:8080/create-prof"), any(), any(), any(), anyLong(), anyLong(), anyString()))
+//                .thenReturn(CompletableFuture.completedFuture(createProfResp));
+//        when(wsUtils.makeWSCall(eq("http://localhost:8080/prof-id/user@mail.com"), any(), any(), any(), anyLong(), anyLong(), anyString()))
+//                .thenReturn(CompletableFuture.completedFuture(fetchProfIdResp));
+//
+//        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.OK, responseResolver.getStatusCode());
+//        assertEquals("804jt408", responseResolver.getRespData().get(USER_ID).asText());
+//    }
+//
+//    @Test
+//    public void testValidateOtpAndLogin_NoPayload() throws Exception {
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(objectMapper.nullNode());
+//
+//        ApiResponseResolver responseResolver = profileService.validateOtpAndLogin(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
+//        assertEquals("No request body found for otp validation of email", responseResolver.getRespData().get("message").asText());
+//    }
+//
+//    @Test
+//    public void testValidateOtpAndLogin_NoEmailOrOtp() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put("pass", "123456");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        ApiResponseResolver responseResolver = profileService.validateOtpAndLogin(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
+//        assertEquals("Email and OTP are required for validating OTP for login", responseResolver.getRespData().get("message").asText());
+//    }
+//
+//    @Test
+//    public void testValidateOtpAndLogin_OtpVerifyFailed() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put(EMAIL, "user@mail.com");
+//        reqBody.put(OTP, "123456");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
+//
+//        Response resp = new Response();
+//        resp.setStatus(FAILURE);
+//        when(redisManager.getDdoData(anyString())).thenReturn(valOtp);
+//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
+//        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString()))
+//                .thenReturn(CompletableFuture.completedFuture(resp));
+//
+//        ApiResponseResolver responseResolver = profileService.validateOtpAndLogin(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.UNAUTHORIZED, responseResolver.getStatusCode());
+//        assertEquals("OTP validation failed, please try again", responseResolver.getRespData().get("message").asText());
+//    }
+//
+//    @Test
+//    public void testValidateOtpAndLogin_FetchUserFailed() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put(EMAIL, "user@mail.com");
+//        reqBody.put(OTP, "123456");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
+//        Response valOtpResp = new Response();
+//        valOtpResp.setStatus(SUCCESS);
+//
+//        DataDynamicObject fetchProfId = getDdo("service", "GET", "prof-id", 1000, 30000);
+//        Response fetchProfIdResp = new Response();
+//        fetchProfIdResp.setStatus(FAILURE);
+//
+//        when(redisManager.getDdoData(VALIDATE_OTP)).thenReturn(valOtp);
+//        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchProfId);
+//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
+//        when(wsUtils.makeWSCall(eq("http://localhost:8080/val-otp?email=user@mail.com&otp=123456"), any(), any(),
+//                any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(valOtpResp));
+//        when(wsUtils.makeWSCall(eq("http://localhost:8080/prof-id/user@mail.com"), any(), any(), any(), anyLong(), anyLong(), anyString()))
+//                .thenReturn(CompletableFuture.completedFuture(fetchProfIdResp));
+//
+//        ApiResponseResolver responseResolver = profileService.validateOtpAndLogin(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseResolver.getStatusCode());
+//        assertEquals("Some error occurred while fetching userId, please try again.", responseResolver.getRespData().get(MESSAGE).asText());
+//    }
+//
+//    @Test
+//    public void testValidateOtpAndLogin_Success() throws Exception {
+//        ObjectNode reqBody = objectMapper.createObjectNode();
+//        reqBody.put(EMAIL, "user@mail.com");
+//        reqBody.put(OTP, "123456");
+//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
+//        apiRequestResolver.setRequestBody(reqBody);
+//
+//        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
+//        Response valOtpResp = new Response();
+//        valOtpResp.setStatus(SUCCESS);
+//
+//        DataDynamicObject fetchProfId = getDdo("service", "GET", "prof-id", 1000, 30000);
+//        ObjectNode data = objectMapper.createObjectNode();
+//        data.put(MESSAGE, "\"804jt408\"");
+//        Response fetchProfIdResp = new Response();
+//        fetchProfIdResp.setStatus(SUCCESS);
+//        fetchProfIdResp.setData(data);
+//
+//        when(redisManager.getDdoData(VALIDATE_OTP)).thenReturn(valOtp);
+//        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchProfId);
+//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
+//        when(wsUtils.makeWSCall(eq("http://localhost:8080/val-otp?email=user@mail.com&otp=123456"), any(), any(),
+//                any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(valOtpResp));
+//        when(wsUtils.makeWSCall(eq("http://localhost:8080/prof-id/user@mail.com"), any(), any(), any(), anyLong(), anyLong(), anyString()))
+//                .thenReturn(CompletableFuture.completedFuture(fetchProfIdResp));
+//
+//        ApiResponseResolver responseResolver = profileService.validateOtpAndLogin(apiRequestResolver, CUSTOMER).get();
+//        assertEquals(HttpStatus.OK, responseResolver.getStatusCode());
+//        assertEquals("804jt408", responseResolver.getRespData().get(USER_ID).asText());
+//    }
+
     private DataDynamicObject getDdo(String service, String method, String api, int connectTimeout, int readTimeout) {
         DataDynamicObject ddo = new DataDynamicObject();
         ddo.setService(service);

From 5ec265272ca1be76ba9b415637a7464f48e223d6 Mon Sep 17 00:00:00 2001
From: sasmitmati <sasmitmati98@gmail.com>
Date: Wed, 20 Nov 2024 21:37:17 +0530
Subject: [PATCH 2/2] Removed comments and minor fix.

---
 .../chains/GenerateOtpForLoginChain.java      |   8 +-
 .../controller/ProfileController.java         |   4 -
 .../service/ProfileService.java               | 200 +-------
 .../controller/ProfileControllerTest.java     |   4 -
 .../service/ProfileServiceTest.java           | 450 ------------------
 5 files changed, 5 insertions(+), 661 deletions(-)

diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/GenerateOtpForLoginChain.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/GenerateOtpForLoginChain.java
index cd9b246..c0811fa 100644
--- a/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/GenerateOtpForLoginChain.java
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/chains/GenerateOtpForLoginChain.java
@@ -10,7 +10,7 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
-import sg.edu.nus.iss.shopsmart_backend.handlers.FetchUserIdForEmailHandler;
+import sg.edu.nus.iss.shopsmart_backend.handlers.CheckProfileExistsHandler;
 import sg.edu.nus.iss.shopsmart_backend.handlers.GenerateOtpHandler;
 import sg.edu.nus.iss.shopsmart_backend.handlers.Handler;
 import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
@@ -32,13 +32,13 @@ public class GenerateOtpForLoginChain extends Constants implements Chain{
     @Autowired
     public GenerateOtpForLoginChain(ProfileService profileService) {
         this.profileService = profileService;
-        Handler fetchUserIdForEmailHandler = new FetchUserIdForEmailHandler(profileService);
+        Handler checkProfileExistsHandler = new CheckProfileExistsHandler(profileService);
         Handler generateOtpHandler = new GenerateOtpHandler(profileService);
 
         generateOtpHandler.setNext(null);
-        fetchUserIdForEmailHandler.setNext(generateOtpHandler);
+        checkProfileExistsHandler.setNext(generateOtpHandler);
 
-        this.handlerChain = fetchUserIdForEmailHandler;
+        this.handlerChain = checkProfileExistsHandler;
     }
 
     @Override
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/controller/ProfileController.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/controller/ProfileController.java
index 5f4ea73..d892a66 100644
--- a/src/main/java/sg/edu/nus/iss/shopsmart_backend/controller/ProfileController.java
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/controller/ProfileController.java
@@ -50,7 +50,6 @@ public CompletableFuture<ResponseEntity<JsonNode>> generateOtpForRegister(@PathV
         log.info("Starting flow for generate OTP for registration for profileType: {}", profileType);
         ApiRequestResolver apiRequestResolver = commonService.createApiResolverRequest(request, GENERATE_OTP, requestBody);
         long startTime = System.currentTimeMillis();
-//        return profileService.generateOtpForRegister(apiRequestResolver, profileType).thenApplyAsync(resp ->{
         return generateOtpForRegisterChain.handleRequest(apiRequestResolver, profileType).thenApplyAsync(resp ->{
             log.info("{} Time taken to complete otp generation for registration is {} ms", apiRequestResolver.getLoggerString(),
                     (System.currentTimeMillis() - startTime));
@@ -67,7 +66,6 @@ public CompletableFuture<ResponseEntity<JsonNode>> verifyOtpForRegister(@PathVar
         log.info("Starting flow for validate OTP and createProfile for registration for profileType: {}", profileType);
         ApiRequestResolver apiRequestResolver = commonService.createApiResolverRequest(request, VALIDATE_OTP, requestBody);
         long startTime = System.currentTimeMillis();
-//        return profileService.validateOtpAndRegister(apiRequestResolver, profileType).thenApplyAsync(resp ->{
         return validateOtpAndRegisterChain.handleRequest(apiRequestResolver, profileType).thenApplyAsync(resp ->{
                 log.info("{} Time taken to complete validate otp and create profile is {} ms", apiRequestResolver.getLoggerString(),
                         (System.currentTimeMillis() - startTime));
@@ -91,7 +89,6 @@ public CompletableFuture<ResponseEntity<JsonNode>> generateOtpForLogin(@PathVari
         log.info("Starting flow for generate OTP for login for profileType: {}", profileType);
         ApiRequestResolver apiRequestResolver = commonService.createApiResolverRequest(request, GENERATE_OTP, requestBody);
         long startTime = System.currentTimeMillis();
-//        return profileService.generateOtpForLogin(apiRequestResolver, profileType).thenApplyAsync(resp ->{
         return generateOtpForLoginChain.handleRequest(apiRequestResolver, profileType).thenApplyAsync(resp ->{
             log.info("{} Time taken to complete otp generation for login is {} ms", apiRequestResolver.getLoggerString(),
                     (System.currentTimeMillis() - startTime));
@@ -108,7 +105,6 @@ public CompletableFuture<ResponseEntity<JsonNode>> verifyOtpForLogin(@PathVariab
         log.info("Starting flow for validate OTP and createProfile for login for profileType: {}", profileType);
         ApiRequestResolver apiRequestResolver = commonService.createApiResolverRequest(request, VALIDATE_OTP, requestBody);
         long startTime = System.currentTimeMillis();
-//        return profileService.validateOtpAndLogin(apiRequestResolver, profileType).thenApplyAsync(resp ->{
         return validateOtpAndLoginChain.handleRequest(apiRequestResolver, profileType).thenApplyAsync(resp ->{
             log.info("{} Time taken to complete validate otp and fetch userId is {} ms", apiRequestResolver.getLoggerString(),
                     (System.currentTimeMillis() - startTime));
diff --git a/src/main/java/sg/edu/nus/iss/shopsmart_backend/service/ProfileService.java b/src/main/java/sg/edu/nus/iss/shopsmart_backend/service/ProfileService.java
index e3046fe..05a26ca 100644
--- a/src/main/java/sg/edu/nus/iss/shopsmart_backend/service/ProfileService.java
+++ b/src/main/java/sg/edu/nus/iss/shopsmart_backend/service/ProfileService.java
@@ -1,19 +1,15 @@
 package sg.edu.nus.iss.shopsmart_backend.service;
 
-import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
 import io.swagger.v3.core.util.Json;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpMethod;
-import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
 import org.springframework.web.util.UriComponentsBuilder;
 import sg.edu.nus.iss.shopsmart_backend.model.ApiRequestResolver;
-import sg.edu.nus.iss.shopsmart_backend.model.ApiResponseResolver;
 import sg.edu.nus.iss.shopsmart_backend.model.DataDynamicObject;
 import sg.edu.nus.iss.shopsmart_backend.utils.*;
 
@@ -34,160 +30,6 @@ public ProfileService(RedisManager redisManager, WSUtils wsUtils){
         this.wsUtils = wsUtils;
     }
 
-//    public CompletableFuture<ApiResponseResolver> generateOtpForRegister(ApiRequestResolver apiRequestResolver, String profileType){
-//        log.info("{} Generating OTP for profile registration with requestObt : {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
-//        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
-//        ObjectNode data = mapper.createObjectNode();
-//        JsonNode payload = apiRequestResolver.getRequestBody();
-//        if(payload.isNull() || payload.isEmpty()){
-//            log.info("{} No request body found for fetching user id for email", apiRequestResolver.getLoggerString());
-//            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
-//            data.put(MESSAGE, "No request body found for otp generation for email");
-//            apiResponseResolver.setRespData(data);
-//            return CompletableFuture.completedFuture(apiResponseResolver);
-//        }
-//        if(!payload.hasNonNull(EMAIL)){
-//            log.info("{} No Email provided for generating OTP for registration", apiRequestResolver.getLoggerString());
-//            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
-//            data.put(MESSAGE, "Email is required for generating OTP for registration");
-//            apiResponseResolver.setRespData(data);
-//            return CompletableFuture.completedFuture(apiResponseResolver);
-//        }
-//        String email = payload.get(EMAIL).asText();
-//        if(ADMIN.equalsIgnoreCase(profileType) && !checkIfValidAdminEmailId(email)){
-//            log.info("{} Email {} is not valid for admin, not authorized", apiRequestResolver.getLoggerString(), email);
-//            apiResponseResolver.setStatusCode(HttpStatus.UNAUTHORIZED); // 401 unauthorized
-//            data.put(MESSAGE, "Email is not authorized for admin OTP generation");
-//            apiResponseResolver.setRespData(data);
-//            return CompletableFuture.completedFuture(apiResponseResolver);
-//        }
-//        return fetchUserIdForEmail(apiRequestResolver, email, profileType).thenComposeAsync(userId -> {
-//            if(StringUtils.isNotEmpty(userId)){
-//                log.info("{} User id {} found for email, so not generating OTP for registration, user needs to login",
-//                        apiRequestResolver.getLoggerString(), userId);
-//                apiResponseResolver.setStatusCode(HttpStatus.CONFLICT); // 409 conflict
-//                data.put(MESSAGE, "User already exists with email, please login");
-//                apiResponseResolver.setRespData(data);
-//                return CompletableFuture.completedFuture(apiResponseResolver);
-//            }
-//            return generateOtp(apiRequestResolver, email);
-//        });
-//    }
-//    public CompletableFuture<ApiResponseResolver> generateOtpForLogin(ApiRequestResolver apiRequestResolver, String profileType){
-//        log.info("{} Generating OTP for profile login with requestObt : {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
-//        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
-//        ObjectNode data = mapper.createObjectNode();
-//        JsonNode payload = apiRequestResolver.getRequestBody();
-//        if(payload.isNull() || payload.isEmpty()){
-//            log.info("{} No request body found for opt generation for login", apiRequestResolver.getLoggerString());
-//            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
-//            data.put(MESSAGE, "No request body found for otp generation for email");
-//            apiResponseResolver.setRespData(data);
-//            return CompletableFuture.completedFuture(apiResponseResolver);
-//        }
-//        if(!payload.hasNonNull(EMAIL)){
-//            log.info("{} No Email provided for generating OTP for login", apiRequestResolver.getLoggerString());
-//            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
-//            data.put(MESSAGE, "Email is required for generating OTP for login");
-//            apiResponseResolver.setRespData(data);
-//            return CompletableFuture.completedFuture(apiResponseResolver);
-//        }
-//        String email = payload.get(EMAIL).asText();
-//        return fetchUserIdForEmail(apiRequestResolver, email, profileType).thenComposeAsync(userId -> {
-//            if(userId==null || StringUtils.isEmpty(userId)){
-//                log.info("{} No userId found for email, so not generating OTP for login, user accounts needs to be present to login",
-//                        apiRequestResolver.getLoggerString());
-//                apiResponseResolver.setStatusCode(HttpStatus.NOT_FOUND); // 404 not found
-//                data.put(MESSAGE, "User does not exists with email, please register");
-//                apiResponseResolver.setRespData(data);
-//                return CompletableFuture.completedFuture(apiResponseResolver);
-//            }
-//            return generateOtp(apiRequestResolver, email);
-//        });
-//    }
-//    public CompletableFuture<ApiResponseResolver> validateOtpAndRegister(ApiRequestResolver apiRequestResolver, String profileType){
-//        log.info("{} validating OTP for profile register with requestObt : {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
-//        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
-//        ObjectNode data = mapper.createObjectNode();
-//        JsonNode payload = apiRequestResolver.getRequestBody();
-//        if(payload.isNull() || payload.isEmpty()){
-//            log.info("{} No request body found for OTP validation for registration", apiRequestResolver.getLoggerString());
-//            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
-//            data.put(MESSAGE, "No request body found for otp validation of email");
-//            apiResponseResolver.setRespData(data);
-//            return CompletableFuture.completedFuture(apiResponseResolver);
-//        }
-//        if(!payload.hasNonNull(EMAIL) || !payload.hasNonNull(OTP)){
-//            log.info("{} No Email or OTP provided for validating OTP for registration", apiRequestResolver.getLoggerString());
-//            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
-//            data.put(MESSAGE, "Email and OTP are required for validating OTP for registration");
-//            apiResponseResolver.setRespData(data);
-//            return CompletableFuture.completedFuture(apiResponseResolver);
-//        }
-//        String email = payload.get(EMAIL).asText();
-//        String otp = payload.get(OTP).asText();
-//        return validateOtp(apiRequestResolver, email, otp).thenComposeAsync(isValid -> {
-//            log.info("{} OTP validation status for email for registration: {} is : {}", apiRequestResolver.getLoggerString(), email, isValid);
-//            if(isValid){
-//                log.info("{} as otp is valid, so registering user for email: {}", apiRequestResolver.getLoggerString(), email);
-//                return createProfileAndRetrieveId(apiRequestResolver, email, profileType);
-//            }else{
-//                log.error("{} OTP validation failed for email during registration: {}", apiRequestResolver.getLoggerString(), email);
-//                apiResponseResolver.setStatusCode(HttpStatus.UNAUTHORIZED); // 401 unauthorized
-//                data.put(MESSAGE, "OTP validation failed, please try again");
-//                apiResponseResolver.setRespData(data);
-//                return CompletableFuture.completedFuture(apiResponseResolver);
-//            }
-//        });
-//    }
-//    public CompletableFuture<ApiResponseResolver> validateOtpAndLogin(ApiRequestResolver apiRequestResolver, String profileType){
-//        log.info("{} validating OTP for profile login with requestObt : {}", apiRequestResolver.getLoggerString(), apiRequestResolver.getRequestBody());
-//        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
-//        ObjectNode data = mapper.createObjectNode();
-//        JsonNode payload = apiRequestResolver.getRequestBody();
-//        if(payload.isNull() || payload.isEmpty()){
-//            log.info("{} No request body found for OTP validation for login", apiRequestResolver.getLoggerString());
-//            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
-//            data.put(MESSAGE, "No request body found for otp validation of email");
-//            apiResponseResolver.setRespData(data);
-//            return CompletableFuture.completedFuture(apiResponseResolver);
-//        }
-//        if(!payload.hasNonNull(EMAIL) || !payload.hasNonNull(OTP)){
-//            log.info("{} No Email or OTP provided for validating OTP for login", apiRequestResolver.getLoggerString());
-//            apiResponseResolver.setStatusCode(HttpStatus.BAD_REQUEST); // 400 bad request
-//            data.put(MESSAGE, "Email and OTP are required for validating OTP for login");
-//            apiResponseResolver.setRespData(data);
-//            return CompletableFuture.completedFuture(apiResponseResolver);
-//        }
-//        String email = payload.get(EMAIL).asText();
-//        String otp = payload.get(OTP).asText();
-//        return validateOtp(apiRequestResolver, email, otp).thenComposeAsync(isValid -> {
-//            log.info("{} OTP validation status for email: {} is : {}", apiRequestResolver.getLoggerString(), email, isValid);
-//            if(isValid){
-//                log.info("{} as otp is valid, so retrieving userId for email: {}", apiRequestResolver.getLoggerString(), email);
-//                return fetchUserIdForEmail(apiRequestResolver, email, profileType).thenComposeAsync(userId -> {
-//                    if(StringUtils.isEmpty(userId)){
-//                        log.error("{} No userId found for email: {} after OTP validation", apiRequestResolver.getLoggerString(), email);
-//                        apiResponseResolver.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR); // 500 internal server error
-//                        data.put(MESSAGE, "Some error occurred while fetching userId, please try again.");
-//                        apiResponseResolver.setRespData(data);
-//                        return CompletableFuture.completedFuture(apiResponseResolver);
-//                    }
-//                    log.info("{} User id found for email: {} after OTP validation, so returning userId", apiRequestResolver.getLoggerString(), email);
-//                    apiResponseResolver.setStatusCode(HttpStatus.OK); // 200 ok
-//                    data.put(USER_ID, userId);
-//                    apiResponseResolver.setRespData(data);
-//                    return CompletableFuture.completedFuture(apiResponseResolver);
-//                });
-//            }else{
-//                log.error("{} OTP validation failed for email during login: {}", apiRequestResolver.getLoggerString(), email);
-//                apiResponseResolver.setStatusCode(HttpStatus.UNAUTHORIZED); // 401 unauthorized
-//                data.put(MESSAGE, "OTP validation failed, please try again");
-//                apiResponseResolver.setRespData(data);
-//                return CompletableFuture.completedFuture(apiResponseResolver);
-//            }
-//        });
-//    }
     public CompletableFuture<Boolean> generateOtp(ApiRequestResolver apiRequestResolver, String email){
         log.info("{} starting OTP generation for email: {}", apiRequestResolver.getLoggerString(), email);
         DataDynamicObject ddo = redisManager.getDdoData(GENERATE_OTP);
@@ -260,47 +102,7 @@ public CompletableFuture<Boolean> createProfile(ApiRequestResolver apiRequestRes
             }
         });
     }
-//    private CompletableFuture<ApiResponseResolver> createProfileAndRetrieveId(ApiRequestResolver apiRequestResolver, String email, String profileType){
-//        log.info("Starting profile create flow for email: {} and profileType: {}", email, profileType);
-//        if(ADMIN.equalsIgnoreCase(profileType)){
-//            String adminUserId = redisManager.getHashValue(REDIS_FEATURE_FLAGS, ADMIN_USER_ID);
-//            log.info("{} Admin profile type has a hard coded userId : {}, hence no need to create profile",
-//                    apiRequestResolver.getLoggerString(), adminUserId);
-//            ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
-//            ObjectNode data = mapper.createObjectNode();
-//            apiResponseResolver.setStatusCode(HttpStatus.OK); // 200 ok
-//            data.put(USER_ID, adminUserId);
-//            apiResponseResolver.setRespData(data);
-//            return CompletableFuture.completedFuture(apiResponseResolver);
-//        }
-//        ApiResponseResolver apiResponseResolver = new ApiResponseResolver();
-//        ObjectNode data = mapper.createObjectNode();
-//        return createProfile(apiRequestResolver, profileType).thenComposeAsync(profCreationResult -> {
-//            if(!profCreationResult){
-//                log.error("{} failure occurred in profile creation", apiRequestResolver.getLoggerString());
-//                apiResponseResolver.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR); // 500 internal server error
-//                data.put(MESSAGE, "Some error occurred while creating profile, please try again.");
-//                apiResponseResolver.setRespData(data);
-//                return CompletableFuture.completedFuture(apiResponseResolver);
-//            } else {
-//                log.info("{} profile created successfully for email: {}", apiRequestResolver.getLoggerString(), email);
-//                return fetchUserIdForEmail(apiRequestResolver, email, profileType).thenApplyAsync(userId -> {
-//                    if(StringUtils.isEmpty(userId)){
-//                        log.error("{} Error occurred while fetching userId for email: {} after profile creation", apiRequestResolver.getLoggerString(), email);
-//                        apiResponseResolver.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR); // 500 internal server error
-//                        data.put(MESSAGE, "Some error occurred while creating profile, please try again.");
-//                        apiResponseResolver.setRespData(data);
-//                        return apiResponseResolver;
-//                    }
-//                    log.info("{} retrieved user id email: {} after profile creation, so returning userId {}", apiRequestResolver.getLoggerString(), email, userId);
-//                    apiResponseResolver.setStatusCode(HttpStatus.OK); // 200 ok
-//                    data.put(USER_ID, userId);
-//                    apiResponseResolver.setRespData(data);
-//                    return apiResponseResolver;
-//                });
-//            }
-//        });
-//    }
+
     public CompletableFuture<String> fetchUserIdForEmail(ApiRequestResolver apiRequestResolver, String email, String profileType){
         log.info("{} fetching user id for email {} for profileType {}", apiRequestResolver.getLoggerString(), email, profileType);
         if(ADMIN.equalsIgnoreCase(profileType) ){
diff --git a/src/test/java/sg/edu/nus/iss/shopsmart_backend/controller/ProfileControllerTest.java b/src/test/java/sg/edu/nus/iss/shopsmart_backend/controller/ProfileControllerTest.java
index 6fffeba..ae0f2f4 100644
--- a/src/test/java/sg/edu/nus/iss/shopsmart_backend/controller/ProfileControllerTest.java
+++ b/src/test/java/sg/edu/nus/iss/shopsmart_backend/controller/ProfileControllerTest.java
@@ -65,7 +65,6 @@ public void testGenerateOtpForRegister() throws Exception {
 
         commonMocking();
 
-//        when(profileService.generateOtpForRegister(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
         when(generateOtpForRegisterChain.handleRequest(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
         ResponseEntity<JsonNode> response = profileController.generateOtpForRegister(CUSTOMER, objectMapper.createObjectNode(),
                 httpServletRequest, httpServletResponse).get();
@@ -84,7 +83,6 @@ public void testVerifyOtpForRegister() throws Exception {
         commonMocking();
         doNothing().when(commonService).updateUserIdInRedisInSessionData(any());
 
-//        when(profileService.validateOtpAndRegister(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
         when(validateOtpAndRegisterChain.handleRequest(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
         ResponseEntity<JsonNode> response = profileController.verifyOtpForRegister(CUSTOMER, objectMapper.createObjectNode(),
                 httpServletRequest, httpServletResponse).get();
@@ -100,7 +98,6 @@ public void testGenerateOtpForLogin() throws Exception {
 
         commonMocking();
 
-//        when(profileService.generateOtpForLogin(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
         when(generateOtpForLoginChain.handleRequest(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
         ResponseEntity<JsonNode> response = profileController.generateOtpForLogin(CUSTOMER, objectMapper.createObjectNode(),
                 httpServletRequest, httpServletResponse).get();
@@ -119,7 +116,6 @@ public void testVerifyOtpForLogin() throws Exception {
         commonMocking();
         doNothing().when(commonService).updateUserIdInRedisInSessionData(any());
 
-//        when(profileService.validateOtpAndLogin(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
         when(validateOtpAndLoginChain.handleRequest(any(), anyString())).thenReturn(CompletableFuture.completedFuture(apiResponseResolver));
         ResponseEntity<JsonNode> response = profileController.verifyOtpForLogin(CUSTOMER, objectMapper.createObjectNode(),
                 httpServletRequest, httpServletResponse).get();
diff --git a/src/test/java/sg/edu/nus/iss/shopsmart_backend/service/ProfileServiceTest.java b/src/test/java/sg/edu/nus/iss/shopsmart_backend/service/ProfileServiceTest.java
index b76713e..d9a8182 100644
--- a/src/test/java/sg/edu/nus/iss/shopsmart_backend/service/ProfileServiceTest.java
+++ b/src/test/java/sg/edu/nus/iss/shopsmart_backend/service/ProfileServiceTest.java
@@ -206,456 +206,6 @@ public void testFetchUserIdForEmail_Invalid_Prof_Type() throws Exception{
         assertEquals("", otpResp);
     }
 
-//    @Test
-//    public void testGenerateOtpForRegister_NoPayload() throws Exception {
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(objectMapper.nullNode());
-//
-//        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
-//        assertEquals("No request body found for otp generation for email", responseResolver.getRespData().get("message").asText());
-//    }
-//
-//    @Test
-//    public void testGenerateOtpForRegister_NoEmail() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put("otp", "123456");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
-//        assertEquals("Email is required for generating OTP for registration", responseResolver.getRespData().get("message").asText());
-//    }
-//
-//    @Test
-//    public void testGenerateOtpForRegister_UnAuthAdmin() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put(EMAIL, "admin1223@mail.com");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        when(redisManager.getHashValue(anyString(), anyString())).thenReturn("admin@mail.com");
-//
-//        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, ADMIN).get();
-//        assertEquals(HttpStatus.UNAUTHORIZED, responseResolver.getStatusCode());
-//        assertEquals("Email is not authorized for admin OTP generation", responseResolver.getRespData().get("message").asText());
-//    }
-//
-//    @Test
-//    public void testGenerateOtpForRegister_AdminUser() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put(EMAIL, "admin@mail.com");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        when(redisManager.getHashValue(anyString(), eq(ADMIN_EMAIL_ID))).thenReturn("admin@mail.com");
-//        when(redisManager.getHashValue(anyString(), eq(ADMIN_USER_ID))).thenReturn("admin123");
-//
-//        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, ADMIN).get();
-//        assertEquals(HttpStatus.CONFLICT, responseResolver.getStatusCode());
-//        assertEquals("User already exists with email, please login", responseResolver.getRespData().get("message").asText());
-//    }
-//
-//    @Test
-//    public void testGenerateOtpForRegister_ExistingProfileUser() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put(EMAIL, "user@mail.com");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        DataDynamicObject ddo = getDdo("service", "GET", "api", 1000, 30000);
-//
-//        ObjectNode data = objectMapper.createObjectNode();
-//        data.put(MESSAGE, "\"804jt408\"");
-//        Response resp = new Response();
-//        resp.setStatus(SUCCESS);
-//        resp.setData(data);
-//
-//        when(redisManager.getDdoData(anyString())).thenReturn(ddo);
-//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
-//        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(resp));
-//
-//        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.CONFLICT, responseResolver.getStatusCode());
-//        assertEquals("User already exists with email, please login", responseResolver.getRespData().get("message").asText());
-//    }
-//
-//    //dont need to write success as it will get covered in success for generateOtpForLogin
-//    @Test
-//    public void testGenerateOtpForRegister_Failure() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put(EMAIL, "user@mail.com");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        DataDynamicObject fetchCustId = getDdo("service", "GET", "api", 1000, 30000);
-//        DataDynamicObject genOtp = getDdo("service", "POST", "gen-otp", 1000, 30000);
-//
-//        Response resp = new Response();
-//        resp.setStatus(FAILURE);
-//        resp.setHttpStatusCode(HttpStatus.NOT_FOUND);
-//
-//        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchCustId);
-//        when(redisManager.getDdoData(GENERATE_OTP)).thenReturn(genOtp);
-//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
-//        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString()))
-//                .thenReturn(CompletableFuture.completedFuture(resp));
-//
-//        ApiResponseResolver responseResolver = profileService.generateOtpForRegister(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.NOT_FOUND, responseResolver.getStatusCode());
-//        assertEquals("Error generating OTP", responseResolver.getRespData().get("message").asText());
-//    }
-//
-//    @Test
-//    public void testGenerateOtpForLogin_NoPayload() throws Exception {
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(objectMapper.nullNode());
-//
-//        ApiResponseResolver responseResolver = profileService.generateOtpForLogin(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
-//        assertEquals("No request body found for otp generation for email", responseResolver.getRespData().get("message").asText());
-//    }
-//
-//    @Test
-//    public void testGenerateOtpForLogin_NoEmail() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put("otp", "123456");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        ApiResponseResolver responseResolver = profileService.generateOtpForLogin(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
-//        assertEquals("Email is required for generating OTP for login", responseResolver.getRespData().get("message").asText());
-//    }
-//
-//    @Test
-//    public void testGenerateOtpForLogin_NoExistingProfile() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put(EMAIL, "user@mail.com");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        DataDynamicObject ddo = getDdo("service", "GET", "api", 1000, 30000);
-//
-//        Response resp = new Response();
-//        resp.setStatus(FAILURE);
-//
-//        when(redisManager.getDdoData(anyString())).thenReturn(ddo);
-//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
-//        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(resp));
-//
-//        ApiResponseResolver responseResolver = profileService.generateOtpForLogin(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.NOT_FOUND, responseResolver.getStatusCode());
-//        assertEquals("User does not exists with email, please register", responseResolver.getRespData().get("message").asText());
-//    }
-//
-//    //dont need to write failure case as it will get covered in failure for generateOtpForRegister
-//    @Test
-//    public void testGenerateOtpForLogin_Success() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put(EMAIL, "user@mail.com");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        DataDynamicObject fetchCustId = getDdo("service", "GET", "api", 1000, 30000);
-//        DataDynamicObject genOtp = getDdo("service", "POST", "gen-otp", 1000, 30000);
-//
-//        ObjectNode data = objectMapper.createObjectNode();
-//        data.put(MESSAGE, "\"804jt408\"");
-//        Response resp = new Response();
-//        resp.setStatus(SUCCESS);
-//        resp.setHttpStatusCode(HttpStatus.OK);
-//        resp.setData(data);
-//
-//        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchCustId);
-//        when(redisManager.getDdoData(GENERATE_OTP)).thenReturn(genOtp);
-//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
-//        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString()))
-//                .thenReturn(CompletableFuture.completedFuture(resp));
-//
-//        ApiResponseResolver responseResolver = profileService.generateOtpForLogin(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.OK, responseResolver.getStatusCode());
-//        assertEquals("OTP generated successfully", responseResolver.getRespData().get("message").asText());
-//    }
-//
-//    @Test
-//    public void testValidateOtpAndRegister_NoPayload() throws Exception {
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(objectMapper.nullNode());
-//
-//        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
-//        assertEquals("No request body found for otp validation of email", responseResolver.getRespData().get("message").asText());
-//    }
-//
-//    @Test
-//    public void testValidateOtpAndRegister_NoEmailOrOtp() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put("pass", "123456");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
-//        assertEquals("Email and OTP are required for validating OTP for registration", responseResolver.getRespData().get("message").asText());
-//    }
-//
-//    @Test
-//    public void testValidateOtpAndRegister_OtpVerifyFailed() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put(EMAIL, "user@mail.com");
-//        reqBody.put(OTP, "123456");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
-//
-//        Response resp = new Response();
-//        resp.setStatus(FAILURE);
-//        when(redisManager.getDdoData(anyString())).thenReturn(valOtp);
-//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
-//        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString()))
-//                .thenReturn(CompletableFuture.completedFuture(resp));
-//
-//        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.UNAUTHORIZED, responseResolver.getStatusCode());
-//        assertEquals("OTP validation failed, please try again", responseResolver.getRespData().get("message").asText());
-//    }
-//
-//    @Test
-//    public void testValidateOtpAndRegister_AdminProfCreate() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put(EMAIL, "user@mail.com");
-//        reqBody.put(OTP, "123456");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
-//
-//        Response resp = new Response();
-//        resp.setStatus(SUCCESS);
-//        when(redisManager.getDdoData(anyString())).thenReturn(valOtp);
-//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080");
-//        when(redisManager.getHashValue(anyString(), anyString())).thenReturn("admin1234");
-//        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString()))
-//                .thenReturn(CompletableFuture.completedFuture(resp));
-//
-//        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, ADMIN).get();
-//        assertEquals(HttpStatus.OK, responseResolver.getStatusCode());
-//        assertEquals("admin1234", responseResolver.getRespData().get(USER_ID).asText());
-//
-//    }
-//
-//    @Test
-//    public void testValidateOtpAndRegister_CreateProfileFailed() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put(EMAIL, "user@mail.com");
-//        reqBody.put(OTP, "123456");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
-//        Response valOtpResp = new Response();
-//        valOtpResp.setStatus(SUCCESS);
-//
-//        DataDynamicObject createProf = getDdo("service", "POST", "create-prof", 1000, 30000);
-//        Response createProfResp = new Response();
-//        createProfResp.setStatus(FAILURE);
-//
-//        when(redisManager.getDdoData(VALIDATE_OTP)).thenReturn(valOtp);
-//        when(redisManager.getDdoData(CREATE_CUSTOMER_PROFILE)).thenReturn(createProf);
-//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
-//        when(wsUtils.makeWSCall(eq("http://localhost:8080/val-otp?email=user@mail.com&otp=123456"), any(), any(),
-//                any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(valOtpResp));
-//        when(wsUtils.makeWSCall(eq("http://localhost:8080/create-prof"), any(), any(), any(), anyLong(), anyLong(), anyString()))
-//                .thenReturn(CompletableFuture.completedFuture(createProfResp));
-//
-//        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseResolver.getStatusCode());
-//        assertEquals("Some error occurred while creating profile, please try again.", responseResolver.getRespData().get(MESSAGE).asText());
-//    }
-//
-//    @Test
-//    public void testValidateOtpAndRegister_CreateProfileSuccess_FetchUserFailed() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put(EMAIL, "user@mail.com");
-//        reqBody.put(OTP, "123456");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
-//        Response valOtpResp = new Response();
-//        valOtpResp.setStatus(SUCCESS);
-//
-//        DataDynamicObject createProf = getDdo("service", "POST", "create-prof", 1000, 30000);
-//        Response createProfResp = new Response();
-//        createProfResp.setStatus(SUCCESS);
-//
-//        DataDynamicObject fetchProfId = getDdo("service", "GET", "prof-id", 1000, 30000);
-//        Response fetchProfIdResp = new Response();
-//        fetchProfIdResp.setStatus(FAILURE);
-//
-//        when(redisManager.getDdoData(VALIDATE_OTP)).thenReturn(valOtp);
-//        when(redisManager.getDdoData(CREATE_CUSTOMER_PROFILE)).thenReturn(createProf);
-//        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchProfId);
-//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
-//        when(wsUtils.makeWSCall(eq("http://localhost:8080/val-otp?email=user@mail.com&otp=123456"), any(), any(),
-//                any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(valOtpResp));
-//        when(wsUtils.makeWSCall(eq("http://localhost:8080/create-prof"), any(), any(), any(), anyLong(), anyLong(), anyString()))
-//                .thenReturn(CompletableFuture.completedFuture(createProfResp));
-//        when(wsUtils.makeWSCall(eq("http://localhost:8080/prof-id/user@mail.com"), any(), any(), any(), anyLong(), anyLong(), anyString()))
-//                .thenReturn(CompletableFuture.completedFuture(fetchProfIdResp));
-//
-//        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseResolver.getStatusCode());
-//        assertEquals("Some error occurred while creating profile, please try again.", responseResolver.getRespData().get(MESSAGE).asText());
-//    }
-//
-//    @Test
-//    public void testValidateOtpAndRegister_Success() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put(EMAIL, "user@mail.com");
-//        reqBody.put(OTP, "123456");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
-//        Response valOtpResp = new Response();
-//        valOtpResp.setStatus(SUCCESS);
-//
-//        DataDynamicObject createProf = getDdo("service", "POST", "create-prof", 1000, 30000);
-//        Response createProfResp = new Response();
-//        createProfResp.setStatus(SUCCESS);
-//
-//        DataDynamicObject fetchProfId = getDdo("service", "GET", "prof-id", 1000, 30000);
-//        ObjectNode data = objectMapper.createObjectNode();
-//        data.put(MESSAGE, "\"804jt408\"");
-//        Response fetchProfIdResp = new Response();
-//        fetchProfIdResp.setStatus(SUCCESS);
-//        fetchProfIdResp.setData(data);
-//
-//        when(redisManager.getDdoData(VALIDATE_OTP)).thenReturn(valOtp);
-//        when(redisManager.getDdoData(CREATE_CUSTOMER_PROFILE)).thenReturn(createProf);
-//        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchProfId);
-//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
-//        when(wsUtils.makeWSCall(eq("http://localhost:8080/val-otp?email=user@mail.com&otp=123456"), any(), any(),
-//                any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(valOtpResp));
-//        when(wsUtils.makeWSCall(eq("http://localhost:8080/create-prof"), any(), any(), any(), anyLong(), anyLong(), anyString()))
-//                .thenReturn(CompletableFuture.completedFuture(createProfResp));
-//        when(wsUtils.makeWSCall(eq("http://localhost:8080/prof-id/user@mail.com"), any(), any(), any(), anyLong(), anyLong(), anyString()))
-//                .thenReturn(CompletableFuture.completedFuture(fetchProfIdResp));
-//
-//        ApiResponseResolver responseResolver = profileService.validateOtpAndRegister(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.OK, responseResolver.getStatusCode());
-//        assertEquals("804jt408", responseResolver.getRespData().get(USER_ID).asText());
-//    }
-//
-//    @Test
-//    public void testValidateOtpAndLogin_NoPayload() throws Exception {
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(objectMapper.nullNode());
-//
-//        ApiResponseResolver responseResolver = profileService.validateOtpAndLogin(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
-//        assertEquals("No request body found for otp validation of email", responseResolver.getRespData().get("message").asText());
-//    }
-//
-//    @Test
-//    public void testValidateOtpAndLogin_NoEmailOrOtp() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put("pass", "123456");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        ApiResponseResolver responseResolver = profileService.validateOtpAndLogin(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.BAD_REQUEST, responseResolver.getStatusCode());
-//        assertEquals("Email and OTP are required for validating OTP for login", responseResolver.getRespData().get("message").asText());
-//    }
-//
-//    @Test
-//    public void testValidateOtpAndLogin_OtpVerifyFailed() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put(EMAIL, "user@mail.com");
-//        reqBody.put(OTP, "123456");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
-//
-//        Response resp = new Response();
-//        resp.setStatus(FAILURE);
-//        when(redisManager.getDdoData(anyString())).thenReturn(valOtp);
-//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
-//        when(wsUtils.makeWSCall(anyString(), any(), any(), any(), anyLong(), anyLong(), anyString()))
-//                .thenReturn(CompletableFuture.completedFuture(resp));
-//
-//        ApiResponseResolver responseResolver = profileService.validateOtpAndLogin(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.UNAUTHORIZED, responseResolver.getStatusCode());
-//        assertEquals("OTP validation failed, please try again", responseResolver.getRespData().get("message").asText());
-//    }
-//
-//    @Test
-//    public void testValidateOtpAndLogin_FetchUserFailed() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put(EMAIL, "user@mail.com");
-//        reqBody.put(OTP, "123456");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
-//        Response valOtpResp = new Response();
-//        valOtpResp.setStatus(SUCCESS);
-//
-//        DataDynamicObject fetchProfId = getDdo("service", "GET", "prof-id", 1000, 30000);
-//        Response fetchProfIdResp = new Response();
-//        fetchProfIdResp.setStatus(FAILURE);
-//
-//        when(redisManager.getDdoData(VALIDATE_OTP)).thenReturn(valOtp);
-//        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchProfId);
-//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
-//        when(wsUtils.makeWSCall(eq("http://localhost:8080/val-otp?email=user@mail.com&otp=123456"), any(), any(),
-//                any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(valOtpResp));
-//        when(wsUtils.makeWSCall(eq("http://localhost:8080/prof-id/user@mail.com"), any(), any(), any(), anyLong(), anyLong(), anyString()))
-//                .thenReturn(CompletableFuture.completedFuture(fetchProfIdResp));
-//
-//        ApiResponseResolver responseResolver = profileService.validateOtpAndLogin(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseResolver.getStatusCode());
-//        assertEquals("Some error occurred while fetching userId, please try again.", responseResolver.getRespData().get(MESSAGE).asText());
-//    }
-//
-//    @Test
-//    public void testValidateOtpAndLogin_Success() throws Exception {
-//        ObjectNode reqBody = objectMapper.createObjectNode();
-//        reqBody.put(EMAIL, "user@mail.com");
-//        reqBody.put(OTP, "123456");
-//        ApiRequestResolver apiRequestResolver = new ApiRequestResolver();
-//        apiRequestResolver.setRequestBody(reqBody);
-//
-//        DataDynamicObject valOtp = getDdo("service", "POST", "val-otp", 1000, 30000);
-//        Response valOtpResp = new Response();
-//        valOtpResp.setStatus(SUCCESS);
-//
-//        DataDynamicObject fetchProfId = getDdo("service", "GET", "prof-id", 1000, 30000);
-//        ObjectNode data = objectMapper.createObjectNode();
-//        data.put(MESSAGE, "\"804jt408\"");
-//        Response fetchProfIdResp = new Response();
-//        fetchProfIdResp.setStatus(SUCCESS);
-//        fetchProfIdResp.setData(data);
-//
-//        when(redisManager.getDdoData(VALIDATE_OTP)).thenReturn(valOtp);
-//        when(redisManager.getDdoData(FETCH_CUSTOMER_ID_BY_EMAIL)).thenReturn(fetchProfId);
-//        when(redisManager.getServiceEndpoint(anyString())).thenReturn("http://localhost:8080/");
-//        when(wsUtils.makeWSCall(eq("http://localhost:8080/val-otp?email=user@mail.com&otp=123456"), any(), any(),
-//                any(), anyLong(), anyLong(), anyString())).thenReturn(CompletableFuture.completedFuture(valOtpResp));
-//        when(wsUtils.makeWSCall(eq("http://localhost:8080/prof-id/user@mail.com"), any(), any(), any(), anyLong(), anyLong(), anyString()))
-//                .thenReturn(CompletableFuture.completedFuture(fetchProfIdResp));
-//
-//        ApiResponseResolver responseResolver = profileService.validateOtpAndLogin(apiRequestResolver, CUSTOMER).get();
-//        assertEquals(HttpStatus.OK, responseResolver.getStatusCode());
-//        assertEquals("804jt408", responseResolver.getRespData().get(USER_ID).asText());
-//    }
-
     private DataDynamicObject getDdo(String service, String method, String api, int connectTimeout, int readTimeout) {
         DataDynamicObject ddo = new DataDynamicObject();
         ddo.setService(service);