MME-34 Add recipe star toggle endpoint, deprecate old star endpoints and service methods.
This commit is contained in:
parent
20865a1b5a
commit
a73dcd1c01
@ -7,18 +7,16 @@ import app.mealsmadeeasy.api.recipe.spec.RecipeCreateSpec;
|
||||
import app.mealsmadeeasy.api.user.User;
|
||||
import app.mealsmadeeasy.api.user.UserCreateException;
|
||||
import app.mealsmadeeasy.api.user.UserService;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@SpringBootTest
|
||||
@ExtendWith(PostgresTestsExtension.class)
|
||||
@ -53,55 +51,39 @@ public class RecipeStarServiceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createViaUsernameAndSlug() {
|
||||
final User owner = this.seedUser();
|
||||
final User starer = this.seedUser();
|
||||
final Recipe recipe = this.seedRecipe(owner);
|
||||
final RecipeStar star = assertDoesNotThrow(() -> this.recipeStarService.create(
|
||||
recipe.getOwner().getUsername(),
|
||||
recipe.getSlug(),
|
||||
starer
|
||||
));
|
||||
assertThat(star.getTimestamp(), is(notNullValue()));
|
||||
public void whenToggleCreates_findReturnsPresent() {
|
||||
final User user = this.seedUser();
|
||||
final Recipe recipe = this.seedRecipe(user);
|
||||
this.recipeStarService.toggle(recipe, user);
|
||||
assertThat(this.recipeStarService.find(recipe, user).isPresent(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createViaId() {
|
||||
final User owner = this.seedUser();
|
||||
final User starer = this.seedUser();
|
||||
final Recipe recipe = this.seedRecipe(owner);
|
||||
final RecipeStar star = assertDoesNotThrow(() -> this.recipeStarService.create(
|
||||
recipe.getId(),
|
||||
starer.getId()
|
||||
));
|
||||
assertThat(star.getTimestamp(), is(notNullValue()));
|
||||
public void whenToggleDeletes_findReturnsEmpty() {
|
||||
final User user = this.seedUser();
|
||||
final Recipe recipe = this.seedRecipe(user);
|
||||
this.recipeStarService.toggle(recipe, user); // create
|
||||
assertThat(this.recipeStarService.find(recipe, user).isPresent(), is(true));
|
||||
this.recipeStarService.toggle(recipe, user); // delete
|
||||
assertThat(this.recipeStarService.find(recipe, user).isEmpty(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void find() {
|
||||
final User owner = this.seedUser();
|
||||
final User starer = this.seedUser();
|
||||
final Recipe recipe = this.seedRecipe(owner);
|
||||
this.recipeStarService.create(recipe.getId(), starer.getId());
|
||||
final @Nullable RecipeStar star = this.recipeStarService.find(
|
||||
recipe.getOwner().getUsername(),
|
||||
recipe.getSlug(),
|
||||
starer
|
||||
).orElse(null);
|
||||
assertThat(star, is(notNullValue()));
|
||||
public void whenNotStarred_toggleReturnsPresent() {
|
||||
final User user = this.seedUser();
|
||||
final Recipe recipe = this.seedRecipe(user);
|
||||
final Optional<RecipeStar> maybeRecipeStar = this.recipeStarService.toggle(recipe, user);
|
||||
assertThat(maybeRecipeStar.isPresent(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteViaUsernameAndSlug() {
|
||||
final User owner = this.seedUser();
|
||||
final User starer = this.seedUser();
|
||||
final Recipe recipe = this.seedRecipe(owner);
|
||||
this.recipeStarService.create(recipe.getId(), starer.getId());
|
||||
assertDoesNotThrow(() -> this.recipeStarService.delete(
|
||||
recipe.getOwner().getUsername(),
|
||||
recipe.getSlug(),
|
||||
starer
|
||||
));
|
||||
public void whenStarred_toggleReturnsEmpty() {
|
||||
final User user = this.seedUser();
|
||||
final Recipe recipe = this.seedRecipe(user);
|
||||
this.recipeStarService.toggle(recipe, user); // create
|
||||
assertThat(this.recipeStarService.find(recipe, user).isPresent(), is(true)); // check that it's there
|
||||
final Optional<RecipeStar> maybeRecipeStar = this.recipeStarService.toggle(recipe, user); // get rid
|
||||
assertThat(maybeRecipeStar.isEmpty(), is(true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/recipes")
|
||||
@ -141,6 +142,7 @@ public class RecipesController {
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@PostMapping("/{username}/{slug}/star")
|
||||
public ResponseEntity<RecipeStar> addStar(
|
||||
@PathVariable String username,
|
||||
@ -150,6 +152,24 @@ public class RecipesController {
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(this.recipeStarService.create(username, slug, principal));
|
||||
}
|
||||
|
||||
@PostMapping("/{username}/{slug}/star/toggle")
|
||||
public ResponseEntity<Object> toggleStar(
|
||||
@PathVariable String username,
|
||||
@PathVariable String slug,
|
||||
@AuthenticationPrincipal User principal
|
||||
) {
|
||||
final Optional<RecipeStar> maybeStar = this.recipeStarService.toggle(
|
||||
this.recipeService.getByUsernameAndSlug(username, slug, principal),
|
||||
principal
|
||||
);
|
||||
if (maybeStar.isPresent()) {
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(maybeStar.get());
|
||||
} else {
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@GetMapping("/{username}/{slug}/star")
|
||||
public ResponseEntity<Map<String, Object>> getStar(
|
||||
@PathVariable String username,
|
||||
@ -164,6 +184,7 @@ public class RecipesController {
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@DeleteMapping("/{username}/{slug}/star")
|
||||
public ResponseEntity<Object> removeStar(
|
||||
@PathVariable String username,
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package app.mealsmadeeasy.api.recipe.star;
|
||||
|
||||
import app.mealsmadeeasy.api.recipe.Recipe;
|
||||
import app.mealsmadeeasy.api.user.User;
|
||||
import jakarta.transaction.Transactional;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
@ -9,6 +11,7 @@ import java.util.Optional;
|
||||
public interface RecipeStarRepository extends JpaRepository<RecipeStar, Long> {
|
||||
|
||||
Optional<RecipeStar> findByRecipeIdAndOwnerId(Integer recipeId, Integer ownerId);
|
||||
Optional<RecipeStar> findByRecipeAndOwner(Recipe recipe, User owner);
|
||||
|
||||
@Query("SELECT count(rs) > 0 FROM RecipeStar rs, Recipe r WHERE r.owner.username = ?1 AND r.slug = ?2 AND r.id = rs.recipe.id AND rs.owner.id = ?3")
|
||||
boolean isStarer(String ownerUsername, String slug, Integer viewerId);
|
||||
|
||||
@ -7,6 +7,7 @@ import app.mealsmadeeasy.api.user.User;
|
||||
import app.mealsmadeeasy.api.user.UserRepository;
|
||||
import app.mealsmadeeasy.api.util.NoSuchEntityWithIdException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Optional;
|
||||
@ -20,6 +21,7 @@ public class RecipeStarService {
|
||||
private final RecipeRepository recipeRepository;
|
||||
private final RecipeService recipeService;
|
||||
|
||||
@Deprecated
|
||||
public RecipeStar create(Recipe recipe, User owner) {
|
||||
final RecipeStar recipeStar = new RecipeStar();
|
||||
recipeStar.setOwner(owner);
|
||||
@ -51,15 +53,35 @@ public class RecipeStarService {
|
||||
return existing.orElseGet(() -> this.create(recipe, starer));
|
||||
}
|
||||
|
||||
@PreAuthorize("@recipeSecurity.isViewableBy(#recipe, #starer)")
|
||||
public Optional<RecipeStar> toggle(Recipe recipe, User starer) {
|
||||
final Optional<RecipeStar> existing = this.find(recipe, starer);
|
||||
if (existing.isPresent()) {
|
||||
this.recipeStarRepository.delete(existing.get());
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return Optional.of(this.create(recipe, starer));
|
||||
}
|
||||
}
|
||||
|
||||
@PreAuthorize("@recipeSecurity.isViewableBy(#recipe, #starer)")
|
||||
public Optional<RecipeStar> find(Recipe recipe, User starer) {
|
||||
return this.recipeStarRepository.findByRecipeAndOwner(recipe, starer);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@PreAuthorize("@recipeSecurity.isViewableBy(#recipeOwnerUsername, #recipeSlug, #starer)")
|
||||
public Optional<RecipeStar> find(String recipeOwnerUsername, String recipeSlug, User starer) {
|
||||
final Recipe recipe = this.recipeService.getByUsernameAndSlug(recipeOwnerUsername, recipeSlug, starer);
|
||||
return this.recipeStarRepository.findByRecipeIdAndOwnerId(recipe.getId(), starer.getId());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void delete(Integer recipeId, Integer ownerId) {
|
||||
this.recipeStarRepository.deleteByRecipeIdAndOwnerId(recipeId, ownerId);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void delete(String recipeOwnerUsername, String recipeSlug, User starer) {
|
||||
final Recipe recipe = this.recipeService.getByUsernameAndSlug(recipeOwnerUsername, recipeSlug, starer);
|
||||
this.delete(recipe.getId(), starer.getId());
|
||||
|
||||
Loading…
Reference in New Issue
Block a user