Fixed bug where Recipe owner was not being seen as a 'viewer' by the RecipeRepository.

This commit is contained in:
Jesse Brault 2024-08-07 17:33:24 -05:00
parent 1804b1556f
commit 733899fee8
3 changed files with 61 additions and 12 deletions

View File

@ -1,5 +1,7 @@
package app.mealsmadeeasy.api.recipe; package app.mealsmadeeasy.api.recipe;
import app.mealsmadeeasy.api.auth.AuthService;
import app.mealsmadeeasy.api.auth.LoginDetails;
import app.mealsmadeeasy.api.recipe.spec.RecipeCreateSpec; import app.mealsmadeeasy.api.recipe.spec.RecipeCreateSpec;
import app.mealsmadeeasy.api.user.User; import app.mealsmadeeasy.api.user.User;
import app.mealsmadeeasy.api.user.UserCreateException; import app.mealsmadeeasy.api.user.UserCreateException;
@ -29,6 +31,9 @@ public class RecipeControllerTests {
@Autowired @Autowired
private UserService userService; private UserService userService;
@Autowired
private AuthService authService;
private User createTestUser(String username) { private User createTestUser(String username) {
try { try {
return this.userService.createUser(username, username + "@test.com", "test"); return this.userService.createUser(username, username + "@test.com", "test");
@ -37,15 +42,19 @@ public class RecipeControllerTests {
} }
} }
private Recipe createTestRecipe(User owner, boolean isPublic) { private Recipe createTestRecipe(User owner, boolean isPublic, String slug) {
final RecipeCreateSpec spec = new RecipeCreateSpec(); final RecipeCreateSpec spec = new RecipeCreateSpec();
spec.setSlug("test-recipe"); spec.setSlug(slug);
spec.setTitle("Test Recipe"); spec.setTitle("Test Recipe");
spec.setRawText("# Hello, World!"); spec.setRawText("# Hello, World!");
spec.setPublic(isPublic); spec.setPublic(isPublic);
return this.recipeService.create(owner, spec); return this.recipeService.create(owner, spec);
} }
private Recipe createTestRecipe(User owner, boolean isPublic) {
return this.createTestRecipe(owner, isPublic, "test-recipe");
}
@Test @Test
@DirtiesContext @DirtiesContext
public void getRecipePageViewByIdPublicRecipeNoPrincipal() throws Exception { public void getRecipePageViewByIdPublicRecipeNoPrincipal() throws Exception {
@ -83,4 +92,23 @@ public class RecipeControllerTests {
.andExpect(jsonPath("$.content[0].starCount").value(0)); .andExpect(jsonPath("$.content[0].starCount").value(0));
} }
@Test
@DirtiesContext
public void getRecipeInfoViewsWithPrincipalIncludesPrivate() throws Exception {
final User owner = this.createTestUser("owner");
final Recipe r0 = this.createTestRecipe(owner, true, "r0");
final Recipe r1 = this.createTestRecipe(owner, true, "r1");
final Recipe r2 = this.createTestRecipe(owner, false, "r2");
final LoginDetails loginDetails = this.authService.login(owner.getUsername(), "test");
this.mockMvc.perform(
get("/recipes")
.header("Authorization", "Bearer " + loginDetails.getAccessToken().getToken())
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.slice.number").value(0))
.andExpect(jsonPath("$.slice.size").value(20))
.andExpect(jsonPath("$.content").isArray())
.andExpect(jsonPath("$.content", hasSize(3)));
}
} }

View File

@ -4,6 +4,7 @@ import app.mealsmadeeasy.api.recipe.spec.RecipeCreateSpec;
import app.mealsmadeeasy.api.recipe.spec.RecipeUpdateSpec; import app.mealsmadeeasy.api.recipe.spec.RecipeUpdateSpec;
import app.mealsmadeeasy.api.recipe.star.RecipeStar; import app.mealsmadeeasy.api.recipe.star.RecipeStar;
import app.mealsmadeeasy.api.recipe.star.RecipeStarService; import app.mealsmadeeasy.api.recipe.star.RecipeStarService;
import app.mealsmadeeasy.api.recipe.view.RecipeInfoView;
import app.mealsmadeeasy.api.user.User; import app.mealsmadeeasy.api.user.User;
import app.mealsmadeeasy.api.user.UserEntity; import app.mealsmadeeasy.api.user.UserEntity;
import app.mealsmadeeasy.api.user.UserRepository; import app.mealsmadeeasy.api.user.UserRepository;
@ -11,11 +12,15 @@ import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.AccessDeniedException;
import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext;
import java.util.List; import java.util.List;
import static app.mealsmadeeasy.api.recipe.ContainsRecipeInfoViewsForRecipesMatcher.containsRecipeInfoViewsForRecipes;
import static app.mealsmadeeasy.api.recipe.ContainsRecipesMatcher.containsRecipes;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
@ -190,9 +195,9 @@ public class RecipeServiceTests {
assertThat(oneStar.size(), is(2)); assertThat(oneStar.size(), is(2));
assertThat(twoStars.size(), is(1)); assertThat(twoStars.size(), is(1));
assertThat(zeroStars, ContainsRecipesMatcher.containsRecipes(r0, r1, r2)); assertThat(zeroStars, containsRecipes(r0, r1, r2));
assertThat(oneStar, ContainsRecipesMatcher.containsRecipes(r1, r2)); assertThat(oneStar, containsRecipes(r1, r2));
assertThat(twoStars, ContainsRecipesMatcher.containsRecipes(r2)); assertThat(twoStars, containsRecipes(r2));
} }
@Test @Test
@ -239,9 +244,9 @@ public class RecipeServiceTests {
assertThat(oneStarViewable.size(), is(2)); assertThat(oneStarViewable.size(), is(2));
assertThat(twoStarsViewable.size(), is (1)); assertThat(twoStarsViewable.size(), is (1));
assertThat(zeroStarsViewable, ContainsRecipesMatcher.containsRecipes(r0, r1, r2)); assertThat(zeroStarsViewable, containsRecipes(r0, r1, r2));
assertThat(oneStarViewable, ContainsRecipesMatcher.containsRecipes(r1, r2)); assertThat(oneStarViewable, containsRecipes(r1, r2));
assertThat(twoStarsViewable, ContainsRecipesMatcher.containsRecipes(r2)); assertThat(twoStarsViewable, containsRecipes(r2));
} }
@Test @Test
@ -254,7 +259,23 @@ public class RecipeServiceTests {
final List<Recipe> publicRecipes = this.recipeService.getPublicRecipes(); final List<Recipe> publicRecipes = this.recipeService.getPublicRecipes();
assertThat(publicRecipes.size(), is(2)); assertThat(publicRecipes.size(), is(2));
assertThat(publicRecipes, ContainsRecipesMatcher.containsRecipes(r0, r1)); assertThat(publicRecipes, containsRecipes(r0, r1));
}
@Test
@DirtiesContext
public void getRecipeInfoViewsViewableByOwnerWhenPublicAndPrivate() {
final User owner = this.createTestUser("recipeOwner");
Recipe r0 = this.createTestRecipe(owner, true, "r0");
Recipe r1 = this.createTestRecipe(owner, false, "r1");
final Slice<RecipeInfoView> viewableInfoViewsSlice = this.recipeService.getInfoViewsViewableBy(
Pageable.ofSize(20),
owner
);
final List<RecipeInfoView> viewableInfos = viewableInfoViewsSlice.getContent();
assertThat(viewableInfos.size(), is(2));
assertThat(viewableInfos, containsRecipeInfoViewsForRecipes(r0, r1));
} }
@Test @Test
@ -267,7 +288,7 @@ public class RecipeServiceTests {
r0 = this.recipeService.addViewer(r0.getId(), owner, viewer); r0 = this.recipeService.addViewer(r0.getId(), owner, viewer);
final List<Recipe> viewableRecipes = this.recipeService.getRecipesViewableBy(viewer); final List<Recipe> viewableRecipes = this.recipeService.getRecipesViewableBy(viewer);
assertThat(viewableRecipes.size(), is(1)); assertThat(viewableRecipes.size(), is(1));
assertThat(viewableRecipes, ContainsRecipesMatcher.containsRecipes(r0)); assertThat(viewableRecipes, containsRecipes(r0));
} }
@Test @Test
@ -277,7 +298,7 @@ public class RecipeServiceTests {
final Recipe r0 = this.createTestRecipe(owner); final Recipe r0 = this.createTestRecipe(owner);
final List<Recipe> ownedRecipes = this.recipeService.getRecipesOwnedBy(owner); final List<Recipe> ownedRecipes = this.recipeService.getRecipesOwnedBy(owner);
assertThat(ownedRecipes.size(), is(1)); assertThat(ownedRecipes.size(), is(1));
assertThat(ownedRecipes, ContainsRecipesMatcher.containsRecipes(r0)); assertThat(ownedRecipes, containsRecipes(r0));
} }
@Test @Test

View File

@ -38,7 +38,7 @@ public interface RecipeRepository extends JpaRepository<RecipeEntity, Long> {
@Query("SELECT size(r.viewers) FROM Recipe r WHERE r.id = ?1") @Query("SELECT size(r.viewers) FROM Recipe r WHERE r.id = ?1")
int getViewerCount(long recipeId); int getViewerCount(long recipeId);
@Query("SELECT r FROM Recipe r WHERE r.isPublic OR ?1 MEMBER OF r.viewers") @Query("SELECT r FROM Recipe r WHERE r.isPublic OR r.owner = ?1 OR ?1 MEMBER OF r.viewers")
Slice<RecipeEntity> findAllViewableBy(UserEntity viewer, Pageable pageable); Slice<RecipeEntity> findAllViewableBy(UserEntity viewer, Pageable pageable);
} }