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()));
|
||||||
|
if (recipe.getMainImage() != null) {
|
||||||
view.setMainImage(this.imageService.toImageView(recipe.getMainImage()));
|
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));
|
||||||
|
if (entity.getMainImage() != null) {
|
||||||
view.setMainImage(this.imageService.toImageView(entity.getMainImage()));
|
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