diff --git a/pom.xml b/pom.xml index 6ecd988..940db9a 100644 --- a/pom.xml +++ b/pom.xml @@ -29,8 +29,10 @@ 21 **/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/** @@ -134,8 +136,10 @@ sg/edu/nus/iss/shopsmart_backend/HomeController.class sg/edu/nus/iss/shopsmart_backend/ShopsmartBackendApplication.class + 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.class sg/edu/nus/iss/shopsmart_backend/model/** sg/edu/nus/iss/shopsmart_backend/service/CommonService.class sg/edu/nus/iss/shopsmart_backend/utils/** 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 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..c0811fa --- /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.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 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 checkProfileExistsHandler = new CheckProfileExistsHandler(profileService); + Handler generateOtpHandler = new GenerateOtpHandler(profileService); + + generateOtpHandler.setNext(null); + checkProfileExistsHandler.setNext(generateOtpHandler); + + this.handlerChain = checkProfileExistsHandler; + } + + @Override + public CompletableFuture 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 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 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 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..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 @@ -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,7 @@ public CompletableFuture> 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)); setRequiredCookies(apiRequestResolver, request, response); @@ -57,7 +66,7 @@ public CompletableFuture> 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)); String userId = JsonUtils.getText(resp.getRespData(), USER_ID); @@ -80,7 +89,7 @@ public CompletableFuture> 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)); setRequiredCookies(apiRequestResolver, request, response); @@ -96,7 +105,7 @@ public CompletableFuture> 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)); 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 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 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 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 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 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 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 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..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,164 +30,8 @@ public ProfileService(RedisManager redisManager, WSUtils wsUtils){ this.wsUtils = wsUtils; } - public CompletableFuture 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 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 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 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 generateOtp(ApiRequestResolver apiRequestResolver, String email){ + public CompletableFuture 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 +41,18 @@ private CompletableFuture 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 validateOtp(ApiRequestResolver apiRequestResolver, String email, String otp){ + + public CompletableFuture 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 +63,6 @@ private CompletableFuture 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 +72,14 @@ private CompletableFuture validateOtp(ApiRequestResolver apiRequestReso } }); } - private CompletableFuture createProfile(ApiRequestResolver apiRequestResolver, String profileType){ + + public CompletableFuture 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 +102,18 @@ private CompletableFuture createProfile(ApiRequestResolver apiRequestRe } }); } - private CompletableFuture 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 fetchUserIdForEmail(ApiRequestResolver apiRequestResolver, String email, String profileType){ + + public CompletableFuture 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 +143,7 @@ private CompletableFuture 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..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 @@ -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,7 @@ 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 response = profileController.generateOtpForRegister(CUSTOMER, objectMapper.createObjectNode(), httpServletRequest, httpServletResponse).get(); assertEquals(HttpStatus.OK, response.getStatusCode()); @@ -76,7 +83,7 @@ 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 response = profileController.verifyOtpForRegister(CUSTOMER, objectMapper.createObjectNode(), httpServletRequest, httpServletResponse).get(); assertEquals(HttpStatus.OK, response.getStatusCode()); @@ -91,7 +98,7 @@ 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 response = profileController.generateOtpForLogin(CUSTOMER, objectMapper.createObjectNode(), httpServletRequest, httpServletResponse).get(); assertEquals(HttpStatus.OK, response.getStatusCode()); @@ -109,7 +116,7 @@ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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..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 @@ -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,453 +41,169 @@ 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); } private DataDynamicObject getDdo(String service, String method, String api, int connectTimeout, int readTimeout) {