diff --git a/backend/pom.xml b/backend/pom.xml
index 470caae3..81791029 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -21,6 +21,18 @@
org.springframework.boot
spring-boot-starter-security
+
+ org.mockito
+ mockito-core
+ 5.2.0
+ test
+
+
+ org.mockito
+ mockito-junit-jupiter
+ 5.2.0
+ test
+
org.apache.jena
apache-jena-libs
diff --git a/backend/src/main/java/com/group1/cuisines/controllers/AuthenticationController.java b/backend/src/main/java/com/group1/cuisines/controllers/AuthenticationController.java
index 0ffe909b..777b70ad 100644
--- a/backend/src/main/java/com/group1/cuisines/controllers/AuthenticationController.java
+++ b/backend/src/main/java/com/group1/cuisines/controllers/AuthenticationController.java
@@ -6,6 +6,7 @@
import com.group1.cuisines.dao.response.AuthenticationTokenResponse;
import com.group1.cuisines.services.AuthenticationService;
import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -23,13 +24,27 @@ public class AuthenticationController {
public ResponseEntity> signup(
@RequestBody SignUpRequest request
) {
- return ResponseEntity.ok(authenticationService.signup(request)); // Return response
+ ApiResponse response = authenticationService.signup(request);
+
+ if (response.getStatus() == 409) {
+ return ResponseEntity.status(HttpStatus.CONFLICT).body(response);
+ } else if (response.getStatus() == 400) {
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
+ } else {
+ return ResponseEntity.status(HttpStatus.CREATED).body(response);
+ }
}
@PostMapping("/login") // Sign in endpoint
public ResponseEntity> signin(
@RequestBody SignInRequest request
) {
- return ResponseEntity.ok(authenticationService.signin(request)); // Return response
+ ApiResponse response = authenticationService.signin(request);
+
+ if (response.getStatus() == 401) {
+ return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
+ } else {
+ return ResponseEntity.ok(response);
+ }
}
}
diff --git a/backend/src/main/java/com/group1/cuisines/controllers/SearchController.java b/backend/src/main/java/com/group1/cuisines/controllers/SearchController.java
index 05799f48..77bb7669 100644
--- a/backend/src/main/java/com/group1/cuisines/controllers/SearchController.java
+++ b/backend/src/main/java/com/group1/cuisines/controllers/SearchController.java
@@ -1,6 +1,7 @@
package com.group1.cuisines.controllers;
import com.group1.cuisines.dao.response.ApiResponse;
+import com.group1.cuisines.dto.DishResponseDto;
import com.group1.cuisines.entities.Dish;
import com.group1.cuisines.entities.User;
import com.group1.cuisines.services.SearchService;
@@ -34,9 +35,9 @@ public ResponseEntity> searchUsers(@RequestParam(required = false) String q) {
}
@GetMapping("/dishes")
- public ApiResponse> searchDishes(@RequestParam(required = false) String q,
- @RequestParam(required = false) String cuisine,
- @RequestParam(required = false) String foodType) {
+ public ApiResponse> searchDishes(@RequestParam(required = false) String q,
+ @RequestParam(required = false) String cuisine,
+ @RequestParam(required = false) String foodType) {
return new ApiResponse<>(
200,
"Search completed",
diff --git a/backend/src/main/java/com/group1/cuisines/dto/DishResponseDto.java b/backend/src/main/java/com/group1/cuisines/dto/DishResponseDto.java
new file mode 100644
index 00000000..6eb4915e
--- /dev/null
+++ b/backend/src/main/java/com/group1/cuisines/dto/DishResponseDto.java
@@ -0,0 +1,19 @@
+package com.group1.cuisines.dto;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class DishResponseDto {
+ private String id;
+ private String name;
+ private String image;
+ private String description;
+ private String countries;
+ private String ingredients;
+ private String foodTypes;
+ private String cuisines;
+}
diff --git a/backend/src/main/java/com/group1/cuisines/exceptions/GlobalExceptionHandler.java b/backend/src/main/java/com/group1/cuisines/exceptions/GlobalExceptionHandler.java
new file mode 100644
index 00000000..bff8d299
--- /dev/null
+++ b/backend/src/main/java/com/group1/cuisines/exceptions/GlobalExceptionHandler.java
@@ -0,0 +1,26 @@
+package com.group1.cuisines.exceptions;
+
+import com.group1.cuisines.dao.response.ApiResponse;
+import org.springframework.boot.context.config.ConfigDataResourceNotFoundException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+
+@ControllerAdvice
+public class GlobalExceptionHandler {
+
+ @ExceptionHandler(Exception.class)
+ public ResponseEntity> handleException(Exception e) {
+ ApiResponse response = new ApiResponse<>(500, "An unexpected error occurred: " + e.getMessage(), null);
+ return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+
+ @ExceptionHandler(ResourceNotFoundException.class)
+ public ResponseEntity> handleResourceNotFoundException(ResourceNotFoundException e) {
+ ApiResponse response = new ApiResponse<>(400, e.getMessage(), null);
+ return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
+ }
+
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/group1/cuisines/exceptions/ResourceNotFoundException.java b/backend/src/main/java/com/group1/cuisines/exceptions/ResourceNotFoundException.java
new file mode 100644
index 00000000..d1ab87bf
--- /dev/null
+++ b/backend/src/main/java/com/group1/cuisines/exceptions/ResourceNotFoundException.java
@@ -0,0 +1,7 @@
+package com.group1.cuisines.exceptions;
+
+public class ResourceNotFoundException extends RuntimeException {
+ public ResourceNotFoundException(String message) {
+ super(message);
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/group1/cuisines/services/AuthenticationService.java b/backend/src/main/java/com/group1/cuisines/services/AuthenticationService.java
index 06bb7823..1221f008 100644
--- a/backend/src/main/java/com/group1/cuisines/services/AuthenticationService.java
+++ b/backend/src/main/java/com/group1/cuisines/services/AuthenticationService.java
@@ -52,7 +52,7 @@ public ApiResponse signup(
String token = jwtService.generateToken(user);
return new ApiResponse<>(
- 200,
+ 201,
"User registered successfully.",
AuthenticationTokenResponse.builder().token(token).build()
);
diff --git a/backend/src/main/java/com/group1/cuisines/services/SearchService.java b/backend/src/main/java/com/group1/cuisines/services/SearchService.java
index ee33a83e..abbe6422 100644
--- a/backend/src/main/java/com/group1/cuisines/services/SearchService.java
+++ b/backend/src/main/java/com/group1/cuisines/services/SearchService.java
@@ -1,6 +1,9 @@
package com.group1.cuisines.services;
+import com.group1.cuisines.dto.DishDto;
+import com.group1.cuisines.dto.DishResponseDto;
import com.group1.cuisines.entities.Dish;
+import com.group1.cuisines.exceptions.ResourceNotFoundException;
import com.group1.cuisines.repositories.DishRepository;
import com.group1.cuisines.repositories.UserRepository;
import lombok.RequiredArgsConstructor;
@@ -16,17 +19,23 @@
public class SearchService {
private final DishRepository dishRepository;
- public List searchDishes(String query, String cuisine, String foodType) {
+ public List searchDishes(String query, String cuisine, String foodType) {
List dishes = dishRepository.findAll();
// Filter by dish name
if (query != null && !query.isEmpty()) {
dishes = dishRepository.findByNameContainingIgnoreCase(query);
+ if (dishes.isEmpty()) {
+ throw new ResourceNotFoundException("No dishes found with the given name query.");
+ }
}
// Filter by cuisine name
if (cuisine != null && !cuisine.isEmpty()) {
List dishesByCuisine = dishRepository.findByCuisinesName(cuisine);
+ if (dishesByCuisine.isEmpty()) {
+ throw new ResourceNotFoundException("No dishes found with the given cuisine.");
+ }
dishes = dishes.stream()
.filter(dishesByCuisine::contains)
.collect(Collectors.toList());
@@ -37,9 +46,25 @@ public List searchDishes(String query, String cuisine, String foodType) {
dishes = dishes.stream()
.filter(d -> d.getFoodTypes() != null && d.getFoodTypes().contains(foodType))
.collect(Collectors.toList());
+
+ if (dishes.isEmpty()) {
+ throw new ResourceNotFoundException("No dishes found with the given food type.");
+ }
}
- return dishes;
+ // Map to DishResponseDto
+ return dishes.stream()
+ .map(d -> new DishResponseDto(
+ d.getId(),
+ d.getName(),
+ d.getImage(),
+ d.getDescription(),
+ d.getCountries(),
+ d.getIngredients(),
+ d.getFoodTypes(),
+ d.getCuisines().isEmpty() ? null : d.getCuisines().get(0).getName()
+ ))
+ .collect(Collectors.toList());
}
diff --git a/backend/src/test/java/com/group1/cuisines/AuthenticationControllerTest.java b/backend/src/test/java/com/group1/cuisines/AuthenticationControllerTest.java
index d3d6218b..4aa77e4c 100644
--- a/backend/src/test/java/com/group1/cuisines/AuthenticationControllerTest.java
+++ b/backend/src/test/java/com/group1/cuisines/AuthenticationControllerTest.java
@@ -14,6 +14,7 @@
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
public class AuthenticationControllerTest {
@@ -31,123 +32,65 @@ public void setUp() {
@Test
public void shouldReturnSuccessOnValidSignin() {
- SignInRequest signInRequest = new SignInRequest(
- "testUser",
- "testPassword"
- );
- ApiResponse apiResponse =
- new ApiResponse<>(
- 200,
- "Success",
- new AuthenticationTokenResponse("token")
- );
- when(authenticationService.signin(signInRequest)).thenReturn(
- apiResponse
- );
- ResponseEntity<
- ApiResponse
- > responseEntity = authenticationController.signin(signInRequest);
- assertEquals(
- 200,
- responseEntity.getBody().getStatus(),
- "Status code does not match expected value on successful signin"
- );
- assertEquals(
- apiResponse,
- responseEntity.getBody(),
- "Response body does not match expected value on successful signin"
- );
+ SignInRequest signInRequest = new SignInRequest("testUser", "testPassword");
+ ApiResponse apiResponse = new ApiResponse<>(200, "Success", new AuthenticationTokenResponse("token"));
+ when(authenticationService.signin(signInRequest)).thenReturn(apiResponse);
+
+ ResponseEntity> responseEntity = authenticationController.signin(signInRequest);
+
+ assertEquals(HttpStatus.OK.value(), responseEntity.getStatusCodeValue(), "Status code does not match expected value on successful signin");
+ assertEquals(apiResponse, responseEntity.getBody(), "Response body does not match expected value on successful signin");
}
@Test
public void shouldReturnFailureOnInvalidSignin() {
- SignInRequest signInRequest = new SignInRequest(
- "testUser",
- "wrongPassword"
- );
- ApiResponse apiResponse =
- new ApiResponse<>(401, "Failure", null);
- when(authenticationService.signin(signInRequest)).thenReturn(
- apiResponse
- );
- ResponseEntity<
- ApiResponse
- > responseEntity = authenticationController.signin(signInRequest);
- assertEquals(
- 401,
- responseEntity.getBody().getStatus(),
- "Status code does not match expected value on failed signin"
- );
- assertEquals(
- apiResponse,
- responseEntity.getBody(),
- "Response body does not match expected value on failed signin"
- );
+ SignInRequest signInRequest = new SignInRequest("testUser", "wrongPassword");
+ ApiResponse apiResponse = new ApiResponse<>(401, "Invalid email/username or password.", null);
+ when(authenticationService.signin(signInRequest)).thenReturn(apiResponse);
+
+ ResponseEntity> responseEntity = authenticationController.signin(signInRequest);
+
+ assertEquals(HttpStatus.UNAUTHORIZED.value(), responseEntity.getStatusCodeValue(), "Status code does not match expected value on failed signin");
+ assertEquals(apiResponse, responseEntity.getBody(), "Response body does not match expected value on failed signin");
}
@Test
public void shouldReturnSuccessOnValidSignup() {
SignUpRequest signUpRequest = SignUpRequest.builder()
- .email("newUser@gmail.com")
- .username("newUser")
- .country("USA")
- .bio("Bio of the new user")
- .password("newPassword")
- .firstName("New")
- .lastName("User")
- .build();
- ApiResponse apiResponse =
- new ApiResponse<>(
- 200,
- "Success",
- new AuthenticationTokenResponse("token")
- );
- when(authenticationService.signup(signUpRequest)).thenReturn(
- apiResponse
- );
- ResponseEntity<
- ApiResponse
- > responseEntity = authenticationController.signup(signUpRequest);
- assertEquals(
- 200,
- responseEntity.getBody().getStatus(),
- "Status code does not match expected value on successful signup"
- );
- assertEquals(
- apiResponse,
- responseEntity.getBody(),
- "Response body does not match expected value on successful signup"
- );
+ .email("newUser@gmail.com")
+ .username("newUser")
+ .country("USA")
+ .bio("Bio of the new user")
+ .password("newPassword")
+ .firstName("New")
+ .lastName("User")
+ .build();
+ ApiResponse apiResponse = new ApiResponse<>(201, "User registered successfully.", new AuthenticationTokenResponse("token"));
+ when(authenticationService.signup(signUpRequest)).thenReturn(apiResponse);
+
+ ResponseEntity> responseEntity = authenticationController.signup(signUpRequest);
+
+ assertEquals(HttpStatus.CREATED.value(), responseEntity.getStatusCodeValue(), "Status code does not match expected value on successful signup");
+ assertEquals(apiResponse, responseEntity.getBody(), "Response body does not match expected value on successful signup");
}
@Test
public void shouldReturnFailureOnInvalidSignup() {
SignUpRequest signUpRequest = SignUpRequest.builder()
- .email("newUser@gmail.com")
- .username("newUser")
- .country("USA")
- .bio("Bio of the new user")
- .password("newPassword")
- .firstName("New")
- .lastName("User")
- .build();
- ApiResponse apiResponse =
- new ApiResponse<>(409, "Failure", null);
- when(authenticationService.signup(signUpRequest)).thenReturn(
- apiResponse
- );
- ResponseEntity<
- ApiResponse
- > responseEntity = authenticationController.signup(signUpRequest);
- assertEquals(
- 409,
- responseEntity.getBody().getStatus(),
- "Status code does not match expected value on failed signup"
- );
- assertEquals(
- apiResponse,
- responseEntity.getBody(),
- "Response body does not match expected value on failed signup"
- );
+ .email("newUser@gmail.com")
+ .username("newUser")
+ .country("USA")
+ .bio("Bio of the new user")
+ .password("newPassword")
+ .firstName("New")
+ .lastName("User")
+ .build();
+ ApiResponse apiResponse = new ApiResponse<>(409, "Email or username already exists.", null);
+ when(authenticationService.signup(signUpRequest)).thenReturn(apiResponse);
+
+ ResponseEntity> responseEntity = authenticationController.signup(signUpRequest);
+
+ assertEquals(HttpStatus.CONFLICT.value(), responseEntity.getStatusCodeValue(), "Status code does not match expected value on failed signup");
+ assertEquals(apiResponse, responseEntity.getBody(), "Response body does not match expected value on failed signup");
}
}