Recipe GET now working by ownerUsername and slug.
This commit is contained in:
		
							parent
							
								
									3d7d5d00f1
								
							
						
					
					
						commit
						57d2451be9
					
				| @ -39,6 +39,7 @@ public class RecipeControllerTests { | |||||||
| 
 | 
 | ||||||
|     private Recipe createTestRecipe(User owner, boolean isPublic) { |     private Recipe createTestRecipe(User owner, boolean isPublic) { | ||||||
|         final RecipeCreateSpec spec = new RecipeCreateSpec(); |         final RecipeCreateSpec spec = new RecipeCreateSpec(); | ||||||
|  |         spec.setSlug("test-recipe"); | ||||||
|         spec.setTitle("Test Recipe"); |         spec.setTitle("Test Recipe"); | ||||||
|         spec.setRawText("# Hello, World!"); |         spec.setRawText("# Hello, World!"); | ||||||
|         spec.setPublic(isPublic); |         spec.setPublic(isPublic); | ||||||
| @ -50,12 +51,12 @@ public class RecipeControllerTests { | |||||||
|     public void getRecipePageViewByIdPublicRecipeNoPrincipal() throws Exception { |     public void getRecipePageViewByIdPublicRecipeNoPrincipal() throws Exception { | ||||||
|         final User owner = this.createTestUser("owner"); |         final User owner = this.createTestUser("owner"); | ||||||
|         final Recipe recipe = this.createTestRecipe(owner, true); |         final Recipe recipe = this.createTestRecipe(owner, true); | ||||||
|         this.mockMvc.perform(get("/recipes/{id}", recipe.getId())) |         this.mockMvc.perform(get("/recipes/{username}/{slug}", recipe.getOwner().getUsername(), recipe.getSlug())) | ||||||
|                 .andExpect(status().isOk()) |                 .andExpect(status().isOk()) | ||||||
|                 .andExpect(jsonPath("$.id").value(1)) |                 .andExpect(jsonPath("$.id").value(1)) | ||||||
|  |                 .andExpect(jsonPath("$.slug").value(recipe.getSlug())) | ||||||
|                 .andExpect(jsonPath("$.title").value("Test Recipe")) |                 .andExpect(jsonPath("$.title").value("Test Recipe")) | ||||||
|                 .andExpect(jsonPath("$.text").value("<h1>Hello, World!</h1>")) |                 .andExpect(jsonPath("$.text").value("<h1>Hello, World!</h1>")) | ||||||
|                 .andExpect(jsonPath("$.ownerId").value(owner.getId())) |  | ||||||
|                 .andExpect(jsonPath("$.ownerUsername").value(owner.getUsername())) |                 .andExpect(jsonPath("$.ownerUsername").value(owner.getUsername())) | ||||||
|                 .andExpect(jsonPath("$.starCount").value(0)) |                 .andExpect(jsonPath("$.starCount").value(0)) | ||||||
|                 .andExpect(jsonPath("$.viewerCount").value(0)); |                 .andExpect(jsonPath("$.viewerCount").value(0)); | ||||||
| @ -74,8 +75,8 @@ public class RecipeControllerTests { | |||||||
|                 .andExpect(jsonPath("$.content", hasSize(1))) |                 .andExpect(jsonPath("$.content", hasSize(1))) | ||||||
|                 .andExpect(jsonPath("$.content[0].id").value(recipe.getId())) |                 .andExpect(jsonPath("$.content[0].id").value(recipe.getId())) | ||||||
|                 .andExpect(jsonPath("$.content[0].updated").exists()) |                 .andExpect(jsonPath("$.content[0].updated").exists()) | ||||||
|  |                 .andExpect(jsonPath("$.content[0].slug").value(recipe.getSlug())) | ||||||
|                 .andExpect(jsonPath("$.content[0].title").value(recipe.getTitle())) |                 .andExpect(jsonPath("$.content[0].title").value(recipe.getTitle())) | ||||||
|                 .andExpect(jsonPath("$.content[0].ownerId").value(owner.getId())) |  | ||||||
|                 .andExpect(jsonPath("$.content[0].ownerUsername").value(owner.getUsername())) |                 .andExpect(jsonPath("$.content[0].ownerUsername").value(owner.getUsername())) | ||||||
|                 .andExpect(jsonPath("$.content[0].public").value(true)) |                 .andExpect(jsonPath("$.content[0].public").value(true)) | ||||||
|                 .andExpect(jsonPath("$.content[0].starCount").value(0)); |                 .andExpect(jsonPath("$.content[0].starCount").value(0)); | ||||||
|  | |||||||
| @ -42,6 +42,7 @@ public class RecipeRepositoryTests { | |||||||
|     @DirtiesContext |     @DirtiesContext | ||||||
|     public void findsAllPublicRecipes() { |     public void findsAllPublicRecipes() { | ||||||
|         final RecipeEntity publicRecipe = new RecipeEntity(); |         final RecipeEntity publicRecipe = new RecipeEntity(); | ||||||
|  |         publicRecipe.setSlug("public-recipe"); | ||||||
|         publicRecipe.setPublic(true); |         publicRecipe.setPublic(true); | ||||||
|         publicRecipe.setOwner(this.getOwnerUser()); |         publicRecipe.setOwner(this.getOwnerUser()); | ||||||
|         publicRecipe.setTitle("Public Recipe"); |         publicRecipe.setTitle("Public Recipe"); | ||||||
| @ -56,6 +57,7 @@ public class RecipeRepositoryTests { | |||||||
|     @DirtiesContext |     @DirtiesContext | ||||||
|     public void doesNotFindNonPublicRecipe() { |     public void doesNotFindNonPublicRecipe() { | ||||||
|         final RecipeEntity nonPublicRecipe = new RecipeEntity(); |         final RecipeEntity nonPublicRecipe = new RecipeEntity(); | ||||||
|  |         nonPublicRecipe.setSlug("non-public-recipe"); | ||||||
|         nonPublicRecipe.setOwner(this.getOwnerUser()); |         nonPublicRecipe.setOwner(this.getOwnerUser()); | ||||||
|         nonPublicRecipe.setTitle("Non-Public Recipe"); |         nonPublicRecipe.setTitle("Non-Public Recipe"); | ||||||
|         nonPublicRecipe.setRawText("Hello, World!"); |         nonPublicRecipe.setRawText("Hello, World!"); | ||||||
| @ -69,6 +71,7 @@ public class RecipeRepositoryTests { | |||||||
|     @DirtiesContext |     @DirtiesContext | ||||||
|     public void findsAllForViewer() { |     public void findsAllForViewer() { | ||||||
|         final RecipeEntity recipe = new RecipeEntity(); |         final RecipeEntity recipe = new RecipeEntity(); | ||||||
|  |         recipe.setSlug("test-recipe"); | ||||||
|         recipe.setOwner(this.getOwnerUser()); |         recipe.setOwner(this.getOwnerUser()); | ||||||
|         recipe.setTitle("Test Recipe"); |         recipe.setTitle("Test Recipe"); | ||||||
|         recipe.setRawText("Hello, World!"); |         recipe.setRawText("Hello, World!"); | ||||||
| @ -89,6 +92,7 @@ public class RecipeRepositoryTests { | |||||||
|     @DirtiesContext |     @DirtiesContext | ||||||
|     public void doesNotIncludeNonViewable() { |     public void doesNotIncludeNonViewable() { | ||||||
|         final RecipeEntity recipe = new RecipeEntity(); |         final RecipeEntity recipe = new RecipeEntity(); | ||||||
|  |         recipe.setSlug("test-recipe"); | ||||||
|         recipe.setOwner(this.getOwnerUser()); |         recipe.setOwner(this.getOwnerUser()); | ||||||
|         recipe.setTitle("Test Recipe"); |         recipe.setTitle("Test Recipe"); | ||||||
|         recipe.setRawText("Hello, World!"); |         recipe.setRawText("Hello, World!"); | ||||||
|  | |||||||
| @ -43,11 +43,16 @@ public class RecipeServiceTests { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private Recipe createTestRecipe(@Nullable User owner) { |     private Recipe createTestRecipe(@Nullable User owner) { | ||||||
|         return this.createTestRecipe(owner, false); |         return this.createTestRecipe(owner, false, null); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private Recipe createTestRecipe(@Nullable User owner, boolean isPublic) { |     private Recipe createTestRecipe(@Nullable User owner, boolean isPublic) { | ||||||
|  |         return this.createTestRecipe(owner, isPublic, null); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private Recipe createTestRecipe(@Nullable User owner, boolean isPublic, @Nullable String slug) { | ||||||
|         final RecipeCreateSpec spec = new RecipeCreateSpec(); |         final RecipeCreateSpec spec = new RecipeCreateSpec(); | ||||||
|  |         spec.setSlug(slug != null ? slug : "my-recipe"); | ||||||
|         spec.setTitle("My Recipe"); |         spec.setTitle("My Recipe"); | ||||||
|         spec.setRawText("Hello!"); |         spec.setRawText("Hello!"); | ||||||
|         spec.setPublic(isPublic); |         spec.setPublic(isPublic); | ||||||
| @ -88,6 +93,7 @@ public class RecipeServiceTests { | |||||||
|         final Recipe recipe = this.createTestRecipe(owner, true); |         final Recipe recipe = this.createTestRecipe(owner, true); | ||||||
|         final Recipe byId = this.recipeService.getById(recipe.getId(), null); |         final Recipe byId = this.recipeService.getById(recipe.getId(), null); | ||||||
|         assertThat(byId.getId(), is(recipe.getId())); |         assertThat(byId.getId(), is(recipe.getId())); | ||||||
|  |         assertThat(byId.getSlug(), is(recipe.getSlug())); | ||||||
|         assertThat(byId.getTitle(), is("My Recipe")); |         assertThat(byId.getTitle(), is("My Recipe")); | ||||||
|         assertThat(byId.getRawText(), is("Hello!")); |         assertThat(byId.getRawText(), is("Hello!")); | ||||||
|         assertThat(byId.isPublic(), is(true)); |         assertThat(byId.isPublic(), is(true)); | ||||||
| @ -167,9 +173,9 @@ public class RecipeServiceTests { | |||||||
|         final User u0 = this.createTestUser("u0"); |         final User u0 = this.createTestUser("u0"); | ||||||
|         final User u1 = this.createTestUser("u1"); |         final User u1 = this.createTestUser("u1"); | ||||||
| 
 | 
 | ||||||
|         final Recipe r0 = this.createTestRecipe(owner, true); |         final Recipe r0 = this.createTestRecipe(owner, true, "r0"); | ||||||
|         final Recipe r1 = this.createTestRecipe(owner, true); |         final Recipe r1 = this.createTestRecipe(owner, true, "r1"); | ||||||
|         final Recipe r2 = this.createTestRecipe(owner, true); |         final Recipe r2 = this.createTestRecipe(owner, true, "r2"); | ||||||
| 
 | 
 | ||||||
|         // r0.stars = 0, r1.stars = 1, r2.stars = 2 |         // r0.stars = 0, r1.stars = 1, r2.stars = 2 | ||||||
|         this.recipeStarService.create(r1.getId(), u0.getUsername()); |         this.recipeStarService.create(r1.getId(), u0.getUsername()); | ||||||
| @ -197,9 +203,9 @@ public class RecipeServiceTests { | |||||||
|         final User u1 = this.createTestUser("u1"); |         final User u1 = this.createTestUser("u1"); | ||||||
|         final User viewer = this.createTestUser("recipeViewer"); |         final User viewer = this.createTestUser("recipeViewer"); | ||||||
| 
 | 
 | ||||||
|         Recipe r0 = this.createTestRecipe(owner); // not public |         Recipe r0 = this.createTestRecipe(owner, false, "r0"); // not public | ||||||
|         Recipe r1 = this.createTestRecipe(owner); |         Recipe r1 = this.createTestRecipe(owner, false, "r1"); | ||||||
|         Recipe r2 = this.createTestRecipe(owner); |         Recipe r2 = this.createTestRecipe(owner, false, "r2"); | ||||||
| 
 | 
 | ||||||
|         for (final User starer : List.of(u0, u1)) { |         for (final User starer : List.of(u0, u1)) { | ||||||
|             r0 = this.recipeService.addViewer(r0.getId(), owner, starer); |             r0 = this.recipeService.addViewer(r0.getId(), owner, starer); | ||||||
| @ -243,8 +249,8 @@ public class RecipeServiceTests { | |||||||
|     public void getPublicRecipes() { |     public void getPublicRecipes() { | ||||||
|         final User owner = this.createTestUser("recipeOwner"); |         final User owner = this.createTestUser("recipeOwner"); | ||||||
| 
 | 
 | ||||||
|         Recipe r0 = this.createTestRecipe(owner, true); |         Recipe r0 = this.createTestRecipe(owner, true, "r0"); | ||||||
|         Recipe r1 = this.createTestRecipe(owner, true); |         Recipe r1 = this.createTestRecipe(owner, true, "r1"); | ||||||
| 
 | 
 | ||||||
|         final List<Recipe> publicRecipes = this.recipeService.getPublicRecipes(); |         final List<Recipe> publicRecipes = this.recipeService.getPublicRecipes(); | ||||||
|         assertThat(publicRecipes.size(), is(2)); |         assertThat(publicRecipes.size(), is(2)); | ||||||
| @ -279,6 +285,7 @@ public class RecipeServiceTests { | |||||||
|     public void updateRawText() throws RecipeException { |     public void updateRawText() throws RecipeException { | ||||||
|         final User owner = this.createTestUser("recipeOwner"); |         final User owner = this.createTestUser("recipeOwner"); | ||||||
|         final RecipeCreateSpec createSpec = new RecipeCreateSpec(); |         final RecipeCreateSpec createSpec = new RecipeCreateSpec(); | ||||||
|  |         createSpec.setSlug("my-recipe"); | ||||||
|         createSpec.setTitle("My Recipe"); |         createSpec.setTitle("My Recipe"); | ||||||
|         createSpec.setRawText("# A Heading"); |         createSpec.setRawText("# A Heading"); | ||||||
|         Recipe recipe = this.recipeService.create(owner, createSpec); |         Recipe recipe = this.recipeService.create(owner, createSpec); | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ spring.datasource.driver-class-name=org.h2.Driver | |||||||
| spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 | spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 | ||||||
| spring.datasource.username=sa | spring.datasource.username=sa | ||||||
| spring.datasource.password=sa | spring.datasource.password=sa | ||||||
|  | app.mealsmadeeasy.api.baseUrl=http://localhost:8080 | ||||||
| app.mealsmadeeasy.api.security.access-token-lifetime=60 | app.mealsmadeeasy.api.security.access-token-lifetime=60 | ||||||
| app.mealsmadeeasy.api.security.refresh-token-lifetime=120 | app.mealsmadeeasy.api.security.refresh-token-lifetime=120 | ||||||
| app.mealsmadeeasy.api.minio.endpoint=http://localhost:9000 | app.mealsmadeeasy.api.minio.endpoint=http://localhost:9000 | ||||||
|  | |||||||
| @ -61,6 +61,7 @@ public class DevConfiguration { | |||||||
|             logger.info("Created {}", obazdaImage); |             logger.info("Created {}", obazdaImage); | ||||||
| 
 | 
 | ||||||
|             final RecipeCreateSpec recipeCreateSpec = new RecipeCreateSpec(); |             final RecipeCreateSpec recipeCreateSpec = new RecipeCreateSpec(); | ||||||
|  |             recipeCreateSpec.setSlug("test-recipe"); | ||||||
|             recipeCreateSpec.setTitle("Test Recipe"); |             recipeCreateSpec.setTitle("Test Recipe"); | ||||||
|             recipeCreateSpec.setRawText("Hello, World!"); |             recipeCreateSpec.setRawText("Hello, World!"); | ||||||
|             recipeCreateSpec.setPublic(true); |             recipeCreateSpec.setPublic(true); | ||||||
|  | |||||||
| @ -13,6 +13,7 @@ public interface Recipe { | |||||||
|     Long getId(); |     Long getId(); | ||||||
|     LocalDateTime getCreated(); |     LocalDateTime getCreated(); | ||||||
|     @Nullable LocalDateTime getModified(); |     @Nullable LocalDateTime getModified(); | ||||||
|  |     String getSlug(); | ||||||
|     String getTitle(); |     String getTitle(); | ||||||
|     String getRawText(); |     String getRawText(); | ||||||
|     User getOwner(); |     User getOwner(); | ||||||
|  | |||||||
| @ -31,10 +31,14 @@ public class RecipeController { | |||||||
|         )); |         )); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @GetMapping("/{id}") |     @GetMapping("/{username}/{slug}") | ||||||
|     public ResponseEntity<FullRecipeView> getById(@PathVariable long id, @AuthenticationPrincipal User user) |     public ResponseEntity<FullRecipeView> getById( | ||||||
|  |             @PathVariable String username, | ||||||
|  |             @PathVariable String slug, | ||||||
|  |             @AuthenticationPrincipal User viewer | ||||||
|  |     ) | ||||||
|             throws RecipeException { |             throws RecipeException { | ||||||
|         return ResponseEntity.ok(this.recipeService.getFullViewById(id, user)); |         return ResponseEntity.ok(this.recipeService.getFullViewByUsernameAndSlug(username, slug, viewer)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @GetMapping |     @GetMapping | ||||||
|  | |||||||
| @ -27,6 +27,9 @@ public final class RecipeEntity implements Recipe { | |||||||
| 
 | 
 | ||||||
|     private LocalDateTime modified; |     private LocalDateTime modified; | ||||||
| 
 | 
 | ||||||
|  |     @Column(nullable = false, unique = true) | ||||||
|  |     private String slug; | ||||||
|  | 
 | ||||||
|     @Column(nullable = false) |     @Column(nullable = false) | ||||||
|     private String title; |     private String title; | ||||||
| 
 | 
 | ||||||
| @ -86,6 +89,15 @@ public final class RecipeEntity implements Recipe { | |||||||
|         this.modified = modified; |         this.modified = modified; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @Override | ||||||
|  |     public String getSlug() { | ||||||
|  |         return this.slug; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setSlug(String slug) { | ||||||
|  |         this.slug = slug; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @Override |     @Override | ||||||
|     public String getTitle() { |     public String getTitle() { | ||||||
|         return this.title; |         return this.title; | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ package app.mealsmadeeasy.api.recipe; | |||||||
| public class RecipeException extends Exception { | public class RecipeException extends Exception { | ||||||
| 
 | 
 | ||||||
|     public enum Type { |     public enum Type { | ||||||
|         INVALID_OWNER_USERNAME, INVALID_STAR, NOT_VIEWABLE, INVALID_COMMENT_ID, INVALID_ID |         INVALID_OWNER_USERNAME, INVALID_STAR, NOT_VIEWABLE, INVALID_COMMENT_ID, INVALID_USERNAME_OR_SLUG, INVALID_ID | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private final Type type; |     private final Type type; | ||||||
|  | |||||||
| @ -18,6 +18,9 @@ public interface RecipeRepository extends JpaRepository<RecipeEntity, Long> { | |||||||
| 
 | 
 | ||||||
|     List<RecipeEntity> findAllByOwner(UserEntity owner); |     List<RecipeEntity> findAllByOwner(UserEntity owner); | ||||||
| 
 | 
 | ||||||
|  |     @Query("SELECT r from Recipe r WHERE r.owner.username = ?1 AND r.slug = ?2") | ||||||
|  |     Optional<RecipeEntity> findByOwnerUsernameAndSlug(String ownerUsername, String slug); | ||||||
|  | 
 | ||||||
|     @Query("SELECT r FROM Recipe r WHERE size(r.stars) >= ?1 AND (r.isPublic OR ?2 MEMBER OF r.viewers)") |     @Query("SELECT r FROM Recipe r WHERE size(r.stars) >= ?1 AND (r.isPublic OR ?2 MEMBER OF r.viewers)") | ||||||
|     List<RecipeEntity> findAllViewableByStarsGreaterThanEqual(long stars, UserEntity viewer); |     List<RecipeEntity> findAllViewableByStarsGreaterThanEqual(long stars, UserEntity viewer); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -7,5 +7,6 @@ public interface RecipeSecurity { | |||||||
|     boolean isOwner(Recipe recipe, User user); |     boolean isOwner(Recipe recipe, User user); | ||||||
|     boolean isOwner(long recipeId, User user) throws RecipeException; |     boolean isOwner(long recipeId, User user) throws RecipeException; | ||||||
|     boolean isViewableBy(Recipe recipe, @Nullable User user) throws RecipeException; |     boolean isViewableBy(Recipe recipe, @Nullable User user) throws RecipeException; | ||||||
|  |     boolean isViewableBy(String ownerUsername, String slug, @Nullable User user) throws RecipeException; | ||||||
|     boolean isViewableBy(long recipeId, @Nullable User user) throws RecipeException; |     boolean isViewableBy(long recipeId, @Nullable User user) throws RecipeException; | ||||||
| } | } | ||||||
|  | |||||||
| @ -56,6 +56,16 @@ public class RecipeSecurityImpl implements RecipeSecurity { | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean isViewableBy(String ownerUsername, String slug, @Nullable User user) throws RecipeException { | ||||||
|  |         final Recipe recipe = this.recipeRepository.findByOwnerUsernameAndSlug(ownerUsername, slug) | ||||||
|  |                 .orElseThrow(() -> new RecipeException( | ||||||
|  |                         RecipeException.Type.INVALID_USERNAME_OR_SLUG, | ||||||
|  |                         "No such Recipe for username " + ownerUsername + " and slug: " + slug | ||||||
|  |                 )); | ||||||
|  |         return this.isViewableBy(recipe, user); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @Override |     @Override | ||||||
|     public boolean isViewableBy(long recipeId, @Nullable User user) throws RecipeException { |     public boolean isViewableBy(long recipeId, @Nullable User user) throws RecipeException { | ||||||
|         final Recipe recipe = this.recipeRepository.findById(recipeId).orElseThrow(() -> new RecipeException( |         final Recipe recipe = this.recipeRepository.findById(recipeId).orElseThrow(() -> new RecipeException( | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ public interface RecipeService { | |||||||
|     Recipe getById(long id, @Nullable User viewer) throws RecipeException; |     Recipe getById(long id, @Nullable User viewer) throws RecipeException; | ||||||
|     Recipe getByIdWithStars(long id, @Nullable User viewer) throws RecipeException; |     Recipe getByIdWithStars(long id, @Nullable User viewer) throws RecipeException; | ||||||
|     FullRecipeView getFullViewById(long id, @Nullable User viewer) throws RecipeException; |     FullRecipeView getFullViewById(long id, @Nullable User viewer) throws RecipeException; | ||||||
|  |     FullRecipeView getFullViewByUsernameAndSlug(String username, String slug, @Nullable User viewer) throws RecipeException; | ||||||
| 
 | 
 | ||||||
|     Slice<RecipeInfoView> getInfoViewsViewableBy(Pageable pageable, @Nullable User viewer); |     Slice<RecipeInfoView> getInfoViewsViewableBy(Pageable pageable, @Nullable User viewer); | ||||||
|     List<Recipe> getByMinimumStars(long minimumStars, @Nullable User viewer); |     List<Recipe> getByMinimumStars(long minimumStars, @Nullable User viewer); | ||||||
|  | |||||||
| @ -53,6 +53,7 @@ public class RecipeServiceImpl implements RecipeService { | |||||||
|         final RecipeEntity draft = new RecipeEntity(); |         final RecipeEntity draft = new RecipeEntity(); | ||||||
|         draft.setCreated(LocalDateTime.now()); |         draft.setCreated(LocalDateTime.now()); | ||||||
|         draft.setOwner((UserEntity) owner); |         draft.setOwner((UserEntity) owner); | ||||||
|  |         draft.setSlug(spec.getSlug()); | ||||||
|         draft.setTitle(spec.getTitle()); |         draft.setTitle(spec.getTitle()); | ||||||
|         draft.setRawText(spec.getRawText()); |         draft.setRawText(spec.getRawText()); | ||||||
|         draft.setMainImage((S3ImageEntity) spec.getMainImage()); |         draft.setMainImage((S3ImageEntity) spec.getMainImage()); | ||||||
| @ -97,26 +98,44 @@ public class RecipeServiceImpl implements RecipeService { | |||||||
|         return this.recipeRepository.getViewerCount(recipeId); |         return this.recipeRepository.getViewerCount(recipeId); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     private FullRecipeView getFullView(RecipeEntity recipe) { | ||||||
|     @PostAuthorize("@recipeSecurity.isViewableBy(#id, #viewer)") |  | ||||||
|     public FullRecipeView getFullViewById(long id, @Nullable User viewer) throws RecipeException { |  | ||||||
|         final RecipeEntity recipe = this.recipeRepository.findById(id).orElseThrow(() -> new RecipeException( |  | ||||||
|                 RecipeException.Type.INVALID_ID, "No such Recipe for id: " + id |  | ||||||
|         )); |  | ||||||
|         final FullRecipeView view = new FullRecipeView(); |         final FullRecipeView view = new FullRecipeView(); | ||||||
|         view.setId(recipe.getId()); |         view.setId(recipe.getId()); | ||||||
|         view.setCreated(recipe.getCreated()); |         view.setCreated(recipe.getCreated()); | ||||||
|         view.setModified(recipe.getModified()); |         view.setModified(recipe.getModified()); | ||||||
|  |         view.setSlug(recipe.getSlug()); | ||||||
|         view.setTitle(recipe.getTitle()); |         view.setTitle(recipe.getTitle()); | ||||||
|         view.setText(this.getRenderedMarkdown(recipe)); |         view.setText(this.getRenderedMarkdown(recipe)); | ||||||
|         view.setOwnerId(recipe.getOwner().getId()); |         view.setOwnerId(recipe.getOwner().getId()); | ||||||
|         view.setOwnerUsername(recipe.getOwner().getUsername()); |         view.setOwnerUsername(recipe.getOwner().getUsername()); | ||||||
|         view.setStarCount(this.getStarCount(recipe)); |         view.setStarCount(this.getStarCount(recipe)); | ||||||
|         view.setViewerCount(this.getViewerCount(recipe.getId())); |         view.setViewerCount(this.getViewerCount(recipe.getId())); | ||||||
|         view.setMainImage(this.imageService.toImageView(recipe.getMainImage())); |         if (recipe.getMainImage() != null) { | ||||||
|  |             view.setMainImage(this.imageService.toImageView(recipe.getMainImage())); | ||||||
|  |         } | ||||||
|         return view; |         return view; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @Override | ||||||
|  |     @PreAuthorize("@recipeSecurity.isViewableBy(#id, #viewer)") | ||||||
|  |     public FullRecipeView getFullViewById(long id, @Nullable User viewer) throws RecipeException { | ||||||
|  |         final RecipeEntity recipe = this.recipeRepository.findById(id).orElseThrow(() -> new RecipeException( | ||||||
|  |                 RecipeException.Type.INVALID_ID, "No such Recipe for id: " + id | ||||||
|  |         )); | ||||||
|  |         return this.getFullView(recipe); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     @PreAuthorize("@recipeSecurity.isViewableBy(#username, #slug, #viewer)") | ||||||
|  |     public FullRecipeView getFullViewByUsernameAndSlug(String username, String slug, @Nullable User viewer) throws RecipeException { | ||||||
|  |         final RecipeEntity recipe = this.recipeRepository.findByOwnerUsernameAndSlug(username, slug) | ||||||
|  |                 .orElseThrow(() -> new RecipeException( | ||||||
|  |                         RecipeException.Type.INVALID_USERNAME_OR_SLUG, | ||||||
|  |                         "No such Recipe for username " + username + " and slug: " + slug | ||||||
|  |                 )); | ||||||
|  |         return this.getFullView(recipe); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @Override |     @Override | ||||||
|     public Slice<RecipeInfoView> getInfoViewsViewableBy(Pageable pageable, @Nullable User viewer) { |     public Slice<RecipeInfoView> getInfoViewsViewableBy(Pageable pageable, @Nullable User viewer) { | ||||||
|         return this.recipeRepository.findAllViewableBy((UserEntity) viewer, pageable).map(entity -> { |         return this.recipeRepository.findAllViewableBy((UserEntity) viewer, pageable).map(entity -> { | ||||||
| @ -127,12 +146,14 @@ public class RecipeServiceImpl implements RecipeService { | |||||||
|             } else { |             } else { | ||||||
|                 view.setUpdated(entity.getCreated()); |                 view.setUpdated(entity.getCreated()); | ||||||
|             } |             } | ||||||
|  |             view.setSlug(entity.getSlug()); | ||||||
|             view.setTitle(entity.getTitle()); |             view.setTitle(entity.getTitle()); | ||||||
|             view.setOwnerId(entity.getOwner().getId()); |  | ||||||
|             view.setOwnerUsername(entity.getOwner().getUsername()); |             view.setOwnerUsername(entity.getOwner().getUsername()); | ||||||
|             view.setPublic(entity.isPublic()); |             view.setPublic(entity.isPublic()); | ||||||
|             view.setStarCount(this.getStarCount(entity)); |             view.setStarCount(this.getStarCount(entity)); | ||||||
|             view.setMainImage(this.imageService.toImageView(entity.getMainImage())); |             if (entity.getMainImage() != null) { | ||||||
|  |                 view.setMainImage(this.imageService.toImageView(entity.getMainImage())); | ||||||
|  |             } | ||||||
|             return view; |             return view; | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| @ -164,6 +185,10 @@ public class RecipeServiceImpl implements RecipeService { | |||||||
|     public Recipe update(long id, RecipeUpdateSpec spec, User modifier) throws RecipeException { |     public Recipe update(long id, RecipeUpdateSpec spec, User modifier) throws RecipeException { | ||||||
|         final RecipeEntity entity = this.findRecipeEntity(id); |         final RecipeEntity entity = this.findRecipeEntity(id); | ||||||
|         boolean didModify = false; |         boolean didModify = false; | ||||||
|  |         if (spec.getSlug() != null) { | ||||||
|  |             entity.setSlug(spec.getSlug()); | ||||||
|  |             didModify = true; | ||||||
|  |         } | ||||||
|         if (spec.getTitle() != null) { |         if (spec.getTitle() != null) { | ||||||
|             entity.setTitle(spec.getTitle()); |             entity.setTitle(spec.getTitle()); | ||||||
|             didModify = true; |             didModify = true; | ||||||
|  | |||||||
| @ -5,11 +5,20 @@ import org.jetbrains.annotations.Nullable; | |||||||
| 
 | 
 | ||||||
| public class RecipeCreateSpec { | public class RecipeCreateSpec { | ||||||
| 
 | 
 | ||||||
|  |     private String slug; | ||||||
|     private String title; |     private String title; | ||||||
|     private String rawText; |     private String rawText; | ||||||
|     private boolean isPublic; |     private boolean isPublic; | ||||||
|     private @Nullable Image mainImage; |     private @Nullable Image mainImage; | ||||||
| 
 | 
 | ||||||
|  |     public String getSlug() { | ||||||
|  |         return this.slug; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setSlug(String slug) { | ||||||
|  |         this.slug = slug; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public String getTitle() { |     public String getTitle() { | ||||||
|         return this.title; |         return this.title; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -5,11 +5,20 @@ import org.jetbrains.annotations.Nullable; | |||||||
| 
 | 
 | ||||||
| public class RecipeUpdateSpec { | public class RecipeUpdateSpec { | ||||||
| 
 | 
 | ||||||
|  |     private @Nullable String slug; | ||||||
|     private @Nullable String title; |     private @Nullable String title; | ||||||
|     private @Nullable String rawText; |     private @Nullable String rawText; | ||||||
|     private @Nullable Boolean isPublic; |     private @Nullable Boolean isPublic; | ||||||
|     private @Nullable Image mainImage; |     private @Nullable Image mainImage; | ||||||
| 
 | 
 | ||||||
|  |     public @Nullable String getSlug() { | ||||||
|  |         return this.slug; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setSlug(@Nullable String slug) { | ||||||
|  |         this.slug = slug; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public @Nullable String getTitle() { |     public @Nullable String getTitle() { | ||||||
|         return this.title; |         return this.title; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ public class FullRecipeView { | |||||||
|     private long id; |     private long id; | ||||||
|     private LocalDateTime created; |     private LocalDateTime created; | ||||||
|     private LocalDateTime modified; |     private LocalDateTime modified; | ||||||
|  |     private String slug; | ||||||
|     private String title; |     private String title; | ||||||
|     private String text; |     private String text; | ||||||
|     private long ownerId; |     private long ownerId; | ||||||
| @ -42,6 +43,14 @@ public class FullRecipeView { | |||||||
|         this.modified = modified; |         this.modified = modified; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public String getSlug() { | ||||||
|  |         return this.slug; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setSlug(String slug) { | ||||||
|  |         this.slug = slug; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public String getTitle() { |     public String getTitle() { | ||||||
|         return this.title; |         return this.title; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package app.mealsmadeeasy.api.recipe.view; | package app.mealsmadeeasy.api.recipe.view; | ||||||
| 
 | 
 | ||||||
| import app.mealsmadeeasy.api.image.view.ImageView; | import app.mealsmadeeasy.api.image.view.ImageView; | ||||||
|  | import org.jetbrains.annotations.Nullable; | ||||||
| 
 | 
 | ||||||
| import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||||
| 
 | 
 | ||||||
| @ -8,12 +9,12 @@ public final class RecipeInfoView { | |||||||
| 
 | 
 | ||||||
|     private long id; |     private long id; | ||||||
|     private LocalDateTime updated; |     private LocalDateTime updated; | ||||||
|  |     private String slug; | ||||||
|     private String title; |     private String title; | ||||||
|     private long ownerId; |  | ||||||
|     private String ownerUsername; |     private String ownerUsername; | ||||||
|     private boolean isPublic; |     private boolean isPublic; | ||||||
|     private int starCount; |     private int starCount; | ||||||
|     private ImageView mainImage; |     private @Nullable ImageView mainImage; | ||||||
| 
 | 
 | ||||||
|     public long getId() { |     public long getId() { | ||||||
|         return this.id; |         return this.id; | ||||||
| @ -31,6 +32,14 @@ public final class RecipeInfoView { | |||||||
|         this.updated = updated; |         this.updated = updated; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public String getSlug() { | ||||||
|  |         return this.slug; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setSlug(String slug) { | ||||||
|  |         this.slug = slug; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public String getTitle() { |     public String getTitle() { | ||||||
|         return this.title; |         return this.title; | ||||||
|     } |     } | ||||||
| @ -39,14 +48,6 @@ public final class RecipeInfoView { | |||||||
|         this.title = title; |         this.title = title; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public long getOwnerId() { |  | ||||||
|         return this.ownerId; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setOwnerId(long ownerId) { |  | ||||||
|         this.ownerId = ownerId; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public String getOwnerUsername() { |     public String getOwnerUsername() { | ||||||
|         return this.ownerUsername; |         return this.ownerUsername; | ||||||
|     } |     } | ||||||
| @ -71,11 +72,11 @@ public final class RecipeInfoView { | |||||||
|         this.starCount = starCount; |         this.starCount = starCount; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public ImageView getMainImage() { |     public @Nullable ImageView getMainImage() { | ||||||
|         return this.mainImage; |         return this.mainImage; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void setMainImage(ImageView mainImage) { |     public void setMainImage(@Nullable ImageView mainImage) { | ||||||
|         this.mainImage = mainImage; |         this.mainImage = mainImage; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Jesse Brault
						Jesse Brault