Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Formatting responses for /search (dishes) #207

Merged
merged 2 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>apache-jena-libs</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -23,13 +24,27 @@ public class AuthenticationController {
public ResponseEntity<ApiResponse<AuthenticationTokenResponse>> signup(
@RequestBody SignUpRequest request
) {
return ResponseEntity.ok(authenticationService.signup(request)); // Return response
ApiResponse<AuthenticationTokenResponse> 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<ApiResponse<AuthenticationTokenResponse>> signin(
@RequestBody SignInRequest request
) {
return ResponseEntity.ok(authenticationService.signin(request)); // Return response
ApiResponse<AuthenticationTokenResponse> response = authenticationService.signin(request);

if (response.getStatus() == 401) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
} else {
return ResponseEntity.ok(response);
}
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -34,9 +35,9 @@ public ResponseEntity<?> searchUsers(@RequestParam(required = false) String q) {
}

@GetMapping("/dishes")
public ApiResponse<List<Dish>> searchDishes(@RequestParam(required = false) String q,
@RequestParam(required = false) String cuisine,
@RequestParam(required = false) String foodType) {
public ApiResponse<List<DishResponseDto>> searchDishes(@RequestParam(required = false) String q,
@RequestParam(required = false) String cuisine,
@RequestParam(required = false) String foodType) {
return new ApiResponse<>(
200,
"Search completed",
Expand Down
19 changes: 19 additions & 0 deletions backend/src/main/java/com/group1/cuisines/dto/DishResponseDto.java
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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<ApiResponse<String>> handleException(Exception e) {
ApiResponse<String> response = new ApiResponse<>(500, "An unexpected error occurred: " + e.getMessage(), null);
return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
}

@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ApiResponse<String>> handleResourceNotFoundException(ResourceNotFoundException e) {
ApiResponse<String> response = new ApiResponse<>(400, e.getMessage(), null);
return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.group1.cuisines.exceptions;

public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public ApiResponse<AuthenticationTokenResponse> signup(
String token = jwtService.generateToken(user);

return new ApiResponse<>(
200,
201,
"User registered successfully.",
AuthenticationTokenResponse.builder().token(token).build()
);
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -16,17 +19,23 @@
public class SearchService {

private final DishRepository dishRepository;
public List<Dish> searchDishes(String query, String cuisine, String foodType) {
public List<DishResponseDto> searchDishes(String query, String cuisine, String foodType) {
List<Dish> 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<Dish> 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());
Expand All @@ -37,9 +46,25 @@ public List<Dish> 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());
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -31,123 +32,65 @@ public void setUp() {

@Test
public void shouldReturnSuccessOnValidSignin() {
SignInRequest signInRequest = new SignInRequest(
"testUser",
"testPassword"
);
ApiResponse<AuthenticationTokenResponse> apiResponse =
new ApiResponse<>(
200,
"Success",
new AuthenticationTokenResponse("token")
);
when(authenticationService.signin(signInRequest)).thenReturn(
apiResponse
);
ResponseEntity<
ApiResponse<AuthenticationTokenResponse>
> 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<AuthenticationTokenResponse> apiResponse = new ApiResponse<>(200, "Success", new AuthenticationTokenResponse("token"));
when(authenticationService.signin(signInRequest)).thenReturn(apiResponse);

ResponseEntity<ApiResponse<AuthenticationTokenResponse>> 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<AuthenticationTokenResponse> apiResponse =
new ApiResponse<>(401, "Failure", null);
when(authenticationService.signin(signInRequest)).thenReturn(
apiResponse
);
ResponseEntity<
ApiResponse<AuthenticationTokenResponse>
> 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<AuthenticationTokenResponse> apiResponse = new ApiResponse<>(401, "Invalid email/username or password.", null);
when(authenticationService.signin(signInRequest)).thenReturn(apiResponse);

ResponseEntity<ApiResponse<AuthenticationTokenResponse>> 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("[email protected]")
.username("newUser")
.country("USA")
.bio("Bio of the new user")
.password("newPassword")
.firstName("New")
.lastName("User")
.build();
ApiResponse<AuthenticationTokenResponse> apiResponse =
new ApiResponse<>(
200,
"Success",
new AuthenticationTokenResponse("token")
);
when(authenticationService.signup(signUpRequest)).thenReturn(
apiResponse
);
ResponseEntity<
ApiResponse<AuthenticationTokenResponse>
> 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("[email protected]")
.username("newUser")
.country("USA")
.bio("Bio of the new user")
.password("newPassword")
.firstName("New")
.lastName("User")
.build();
ApiResponse<AuthenticationTokenResponse> apiResponse = new ApiResponse<>(201, "User registered successfully.", new AuthenticationTokenResponse("token"));
when(authenticationService.signup(signUpRequest)).thenReturn(apiResponse);

ResponseEntity<ApiResponse<AuthenticationTokenResponse>> 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("[email protected]")
.username("newUser")
.country("USA")
.bio("Bio of the new user")
.password("newPassword")
.firstName("New")
.lastName("User")
.build();
ApiResponse<AuthenticationTokenResponse> apiResponse =
new ApiResponse<>(409, "Failure", null);
when(authenticationService.signup(signUpRequest)).thenReturn(
apiResponse
);
ResponseEntity<
ApiResponse<AuthenticationTokenResponse>
> 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("[email protected]")
.username("newUser")
.country("USA")
.bio("Bio of the new user")
.password("newPassword")
.firstName("New")
.lastName("User")
.build();
ApiResponse<AuthenticationTokenResponse> apiResponse = new ApiResponse<>(409, "Email or username already exists.", null);
when(authenticationService.signup(signUpRequest)).thenReturn(apiResponse);

ResponseEntity<ApiResponse<AuthenticationTokenResponse>> 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");
}
}
Loading