Added removeStar to RecipeController and related.

This commit is contained in:
Jesse Brault 2024-08-13 11:29:41 -05:00
parent e23526dbcc
commit c467bd75b3
6 changed files with 62 additions and 6 deletions

View File

@ -2,7 +2,9 @@ package app.mealsmadeeasy.api.recipe;
import app.mealsmadeeasy.api.auth.AuthService; import app.mealsmadeeasy.api.auth.AuthService;
import app.mealsmadeeasy.api.auth.LoginDetails; import app.mealsmadeeasy.api.auth.LoginDetails;
import app.mealsmadeeasy.api.auth.LoginException;
import app.mealsmadeeasy.api.recipe.spec.RecipeCreateSpec; import app.mealsmadeeasy.api.recipe.spec.RecipeCreateSpec;
import app.mealsmadeeasy.api.recipe.star.RecipeStarService;
import app.mealsmadeeasy.api.user.User; import app.mealsmadeeasy.api.user.User;
import app.mealsmadeeasy.api.user.UserCreateException; import app.mealsmadeeasy.api.user.UserCreateException;
import app.mealsmadeeasy.api.user.UserService; import app.mealsmadeeasy.api.user.UserService;
@ -14,8 +16,7 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.hasSize;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -29,6 +30,9 @@ public class RecipeControllerTests {
@Autowired @Autowired
private RecipeService recipeService; private RecipeService recipeService;
@Autowired
private RecipeStarService recipeStarService;
@Autowired @Autowired
private UserService userService; private UserService userService;
@ -59,6 +63,12 @@ public class RecipeControllerTests {
return this.createTestRecipe(owner, isPublic, "test-recipe"); return this.createTestRecipe(owner, isPublic, "test-recipe");
} }
private String getAccessToken(User user) throws LoginException {
return this.authService.login(user.getUsername(), "test")
.getAccessToken()
.getToken();
}
@Test @Test
@DirtiesContext @DirtiesContext
public void getRecipePageViewByIdPublicRecipeNoPrincipal() throws Exception { public void getRecipePageViewByIdPublicRecipeNoPrincipal() throws Exception {
@ -132,15 +142,26 @@ public class RecipeControllerTests {
final User owner = this.createTestUser("recipe-owner"); final User owner = this.createTestUser("recipe-owner");
final User starer = this.createTestUser("recipe-starer"); final User starer = this.createTestUser("recipe-starer");
final Recipe recipe = this.createTestRecipe(owner, true); final Recipe recipe = this.createTestRecipe(owner, true);
final String accessToken = this.authService.login(starer.getUsername(), "test")
.getAccessToken()
.getToken();
this.mockMvc.perform( this.mockMvc.perform(
post("/recipes/{username}/{slug}/stars", recipe.getOwner().getUsername(), recipe.getSlug()) post("/recipes/{username}/{slug}/stars", recipe.getOwner().getUsername(), recipe.getSlug())
.header("Authorization", "Bearer " + accessToken) .header("Authorization", "Bearer " + this.getAccessToken(starer))
) )
.andExpect(status().isCreated()) .andExpect(status().isCreated())
.andExpect(jsonPath("$.date").exists()); .andExpect(jsonPath("$.date").exists());
} }
@Test
@DirtiesContext
public void deleteStarFromRecipe() throws Exception {
final User owner = this.createTestUser("recipe-owner");
final User starer = this.createTestUser("recipe-starer");
final Recipe recipe = this.createTestRecipe(owner, true);
this.recipeStarService.create(recipe.getId(), starer.getUsername());
this.mockMvc.perform(
delete("/recipes/{username}/{slug}/stars", recipe.getOwner().getUsername(), recipe.getSlug())
.header("Authorization", "Bearer " + this.getAccessToken(starer))
)
.andExpect(status().isNoContent());
}
} }

View File

@ -72,4 +72,18 @@ public class RecipeStarServiceTests {
assertThat(star.getDate(), is(notNullValue())); assertThat(star.getDate(), is(notNullValue()));
} }
@Test
@DirtiesContext
public void deleteViaUsernameAndSlug() {
final User owner = this.getTestUser("recipe-owner");
final User starer = this.getTestUser("recipe-starer");
final Recipe recipe = this.getTestRecipe(owner, "test-recipe", true);
this.recipeStarService.create(recipe.getId(), starer.getUsername());
assertDoesNotThrow(() -> this.recipeStarService.delete(
recipe.getOwner().getUsername(),
recipe.getSlug(),
starer
));
}
} }

View File

@ -74,4 +74,14 @@ public class RecipeController {
return ResponseEntity.status(HttpStatus.CREATED).body(this.recipeStarService.create(username, slug, principal)); return ResponseEntity.status(HttpStatus.CREATED).body(this.recipeStarService.create(username, slug, principal));
} }
@DeleteMapping("/{username}/{slug}/stars")
public ResponseEntity<Object> removeStar(
@PathVariable String username,
@PathVariable String slug,
@AuthenticationPrincipal User principal
) throws RecipeException {
this.recipeStarService.delete(username, slug, principal);
return ResponseEntity.noContent().build();
}
} }

View File

@ -1,6 +1,8 @@
package app.mealsmadeeasy.api.recipe.star; package app.mealsmadeeasy.api.recipe.star;
import jakarta.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import java.util.Optional; import java.util.Optional;
@ -10,6 +12,8 @@ public interface RecipeStarRepository extends JpaRepository<RecipeStarEntity, Lo
@Query("SELECT star FROM RecipeStar star WHERE star.id.recipeId = ?1 AND star.id.ownerUsername = ?2") @Query("SELECT star FROM RecipeStar star WHERE star.id.recipeId = ?1 AND star.id.ownerUsername = ?2")
Optional<RecipeStarEntity> findByRecipeIdAndOwnerUsername(Long recipeId, String username); Optional<RecipeStarEntity> findByRecipeIdAndOwnerUsername(Long recipeId, String username);
@Modifying
@Transactional
@Query("DELETE FROM RecipeStar star WHERE star.id.recipeId = ?1 AND star.id.ownerUsername = ?2") @Query("DELETE FROM RecipeStar star WHERE star.id.recipeId = ?1 AND star.id.ownerUsername = ?2")
void deleteByRecipeIdAndOwnerUsername(Long recipeId, String username); void deleteByRecipeIdAndOwnerUsername(Long recipeId, String username);

View File

@ -8,4 +8,5 @@ public interface RecipeStarService {
RecipeStar create(String recipeOwnerUsername, String recipeSlug, User starer) throws RecipeException; RecipeStar create(String recipeOwnerUsername, String recipeSlug, User starer) throws RecipeException;
RecipeStar get(long recipeId, String ownerUsername) throws RecipeException; RecipeStar get(long recipeId, String ownerUsername) throws RecipeException;
void delete(long recipeId, String ownerUsername); void delete(long recipeId, String ownerUsername);
void delete(String recipeOwnerUsername, String recipeSlug, User starer) throws RecipeException;
} }

View File

@ -59,4 +59,10 @@ public class RecipeStarServiceImpl implements RecipeStarService {
this.recipeStarRepository.deleteByRecipeIdAndOwnerUsername(recipeId, ownerUsername); this.recipeStarRepository.deleteByRecipeIdAndOwnerUsername(recipeId, ownerUsername);
} }
@Override
public void delete(String recipeOwnerUsername, String recipeSlug, User starer) throws RecipeException {
final Recipe recipe = this.recipeService.getByUsernameAndSlug(recipeOwnerUsername, recipeSlug, starer);
this.delete(recipe.getId(), starer.getUsername());
}
} }