ImageView.viewers only non-empty when principal is owner. Added preparation, cook, and total time to Recipe.
This commit is contained in:
parent
22fac36e4b
commit
ccae29b202
@ -46,6 +46,9 @@ public class RecipeControllerTests {
|
|||||||
final RecipeCreateSpec spec = new RecipeCreateSpec();
|
final RecipeCreateSpec spec = new RecipeCreateSpec();
|
||||||
spec.setSlug(slug);
|
spec.setSlug(slug);
|
||||||
spec.setTitle("Test Recipe");
|
spec.setTitle("Test Recipe");
|
||||||
|
spec.setPreparationTime(10);
|
||||||
|
spec.setCookingTime(20);
|
||||||
|
spec.setTotalTime(30);
|
||||||
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);
|
||||||
@ -63,8 +66,13 @@ public class RecipeControllerTests {
|
|||||||
this.mockMvc.perform(get("/recipes/{username}/{slug}", recipe.getOwner().getUsername(), recipe.getSlug()))
|
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("$.created").exists()) // TODO: better matching of exact LocalDateTime
|
||||||
|
.andExpect(jsonPath("$.modified").doesNotExist())
|
||||||
.andExpect(jsonPath("$.slug").value(recipe.getSlug()))
|
.andExpect(jsonPath("$.slug").value(recipe.getSlug()))
|
||||||
.andExpect(jsonPath("$.title").value("Test Recipe"))
|
.andExpect(jsonPath("$.title").value("Test Recipe"))
|
||||||
|
.andExpect(jsonPath("$.preparationTime").value(recipe.getPreparationTime()))
|
||||||
|
.andExpect(jsonPath("$.cookingTime").value(recipe.getCookingTime()))
|
||||||
|
.andExpect(jsonPath("$.totalTime").value(recipe.getTotalTime()))
|
||||||
.andExpect(jsonPath("$.text").value("<h1>Hello, World!</h1>"))
|
.andExpect(jsonPath("$.text").value("<h1>Hello, World!</h1>"))
|
||||||
.andExpect(jsonPath("$.owner.id").value(owner.getId()))
|
.andExpect(jsonPath("$.owner.id").value(owner.getId()))
|
||||||
.andExpect(jsonPath("$.owner.username").value(owner.getUsername()))
|
.andExpect(jsonPath("$.owner.username").value(owner.getUsername()))
|
||||||
@ -85,9 +93,13 @@ public class RecipeControllerTests {
|
|||||||
.andExpect(jsonPath("$.content").isArray())
|
.andExpect(jsonPath("$.content").isArray())
|
||||||
.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].created").exists()) // TODO: better matching of exact LocalDateTime
|
||||||
|
.andExpect(jsonPath("$.content[0].modified").doesNotExist())
|
||||||
.andExpect(jsonPath("$.content[0].slug").value(recipe.getSlug()))
|
.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].preparationTime").value(recipe.getPreparationTime()))
|
||||||
|
.andExpect(jsonPath("$.content[0].cookingTime").value(recipe.getCookingTime()))
|
||||||
|
.andExpect(jsonPath("$.content[0].totalTime").value(recipe.getTotalTime()))
|
||||||
.andExpect(jsonPath("$.content[0].owner.id").value(owner.getId()))
|
.andExpect(jsonPath("$.content[0].owner.id").value(owner.getId()))
|
||||||
.andExpect(jsonPath("$.content[0].owner.username").value(owner.getUsername()))
|
.andExpect(jsonPath("$.content[0].owner.username").value(owner.getUsername()))
|
||||||
.andExpect(jsonPath("$.content[0].isPublic").value(true))
|
.andExpect(jsonPath("$.content[0].isPublic").value(true))
|
||||||
|
@ -7,6 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.test.annotation.DirtiesContext;
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -42,6 +43,7 @@ public class RecipeRepositoryTests {
|
|||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void findsAllPublicRecipes() {
|
public void findsAllPublicRecipes() {
|
||||||
final RecipeEntity publicRecipe = new RecipeEntity();
|
final RecipeEntity publicRecipe = new RecipeEntity();
|
||||||
|
publicRecipe.setCreated(LocalDateTime.now());
|
||||||
publicRecipe.setSlug("public-recipe");
|
publicRecipe.setSlug("public-recipe");
|
||||||
publicRecipe.setPublic(true);
|
publicRecipe.setPublic(true);
|
||||||
publicRecipe.setOwner(this.getOwnerUser());
|
publicRecipe.setOwner(this.getOwnerUser());
|
||||||
@ -57,6 +59,7 @@ public class RecipeRepositoryTests {
|
|||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void doesNotFindNonPublicRecipe() {
|
public void doesNotFindNonPublicRecipe() {
|
||||||
final RecipeEntity nonPublicRecipe = new RecipeEntity();
|
final RecipeEntity nonPublicRecipe = new RecipeEntity();
|
||||||
|
nonPublicRecipe.setCreated(LocalDateTime.now());
|
||||||
nonPublicRecipe.setSlug("non-public-recipe");
|
nonPublicRecipe.setSlug("non-public-recipe");
|
||||||
nonPublicRecipe.setOwner(this.getOwnerUser());
|
nonPublicRecipe.setOwner(this.getOwnerUser());
|
||||||
nonPublicRecipe.setTitle("Non-Public Recipe");
|
nonPublicRecipe.setTitle("Non-Public Recipe");
|
||||||
@ -71,6 +74,7 @@ public class RecipeRepositoryTests {
|
|||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void findsAllForViewer() {
|
public void findsAllForViewer() {
|
||||||
final RecipeEntity recipe = new RecipeEntity();
|
final RecipeEntity recipe = new RecipeEntity();
|
||||||
|
recipe.setCreated(LocalDateTime.now());
|
||||||
recipe.setSlug("test-recipe");
|
recipe.setSlug("test-recipe");
|
||||||
recipe.setOwner(this.getOwnerUser());
|
recipe.setOwner(this.getOwnerUser());
|
||||||
recipe.setTitle("Test Recipe");
|
recipe.setTitle("Test Recipe");
|
||||||
@ -92,6 +96,7 @@ public class RecipeRepositoryTests {
|
|||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void doesNotIncludeNonViewable() {
|
public void doesNotIncludeNonViewable() {
|
||||||
final RecipeEntity recipe = new RecipeEntity();
|
final RecipeEntity recipe = new RecipeEntity();
|
||||||
|
recipe.setCreated(LocalDateTime.now());
|
||||||
recipe.setSlug("test-recipe");
|
recipe.setSlug("test-recipe");
|
||||||
recipe.setOwner(this.getOwnerUser());
|
recipe.setOwner(this.getOwnerUser());
|
||||||
recipe.setTitle("Test Recipe");
|
recipe.setTitle("Test Recipe");
|
||||||
|
@ -27,6 +27,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
|||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
// TODO: test mainImage included
|
// TODO: test mainImage included
|
||||||
|
// TODO: test prep/cooking/total times included
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
public class RecipeServiceTests {
|
public class RecipeServiceTests {
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ public class ImageController {
|
|||||||
image.getSize(),
|
image.getSize(),
|
||||||
createSpec
|
createSpec
|
||||||
);
|
);
|
||||||
return ResponseEntity.status(201).body(this.imageService.toImageView(saved));
|
return ResponseEntity.status(201).body(this.imageService.toImageView(saved, principal));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/{username}/{filename}")
|
@PostMapping("/{username}/{filename}")
|
||||||
@ -127,7 +127,7 @@ public class ImageController {
|
|||||||
final User owner = this.userService.getUser(username);
|
final User owner = this.userService.getUser(username);
|
||||||
final Image image = this.imageService.getByOwnerAndFilename(owner, filename, principal);
|
final Image image = this.imageService.getByOwnerAndFilename(owner, filename, principal);
|
||||||
final Image updated = this.imageService.update(image, principal, this.getImageUpdateSpec(body));
|
final Image updated = this.imageService.update(image, principal, this.getImageUpdateSpec(body));
|
||||||
return ResponseEntity.ok(this.imageService.toImageView(updated));
|
return ResponseEntity.ok(this.imageService.toImageView(updated, principal));
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("/{username}/{filename}")
|
@DeleteMapping("/{username}/{filename}")
|
||||||
|
@ -25,6 +25,6 @@ public interface ImageService {
|
|||||||
|
|
||||||
void deleteImage(Image image, User modifier) throws IOException;
|
void deleteImage(Image image, User modifier) throws IOException;
|
||||||
|
|
||||||
ImageView toImageView(Image image);
|
ImageView toImageView(Image image, @Nullable User viewer);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import app.mealsmadeeasy.api.image.view.ImageView;
|
|||||||
import app.mealsmadeeasy.api.s3.S3Manager;
|
import app.mealsmadeeasy.api.s3.S3Manager;
|
||||||
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.view.UserInfoView;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.security.access.prepost.PostAuthorize;
|
import org.springframework.security.access.prepost.PostAuthorize;
|
||||||
@ -21,7 +20,6 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
/* TODO: update modified LocalDateTime when updating */
|
|
||||||
public class S3ImageService implements ImageService {
|
public class S3ImageService implements ImageService {
|
||||||
|
|
||||||
private static final Pattern extensionPattern = Pattern.compile(".+\\.(.+)$");
|
private static final Pattern extensionPattern = Pattern.compile(".+\\.(.+)$");
|
||||||
@ -186,34 +184,17 @@ public class S3ImageService implements ImageService {
|
|||||||
this.s3Manager.delete("images", imageEntity.getObjectName());
|
this.s3Manager.delete("images", imageEntity.getObjectName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getImageUrl(Image image) {
|
||||||
|
return this.baseUrl + "/images/" + image.getOwner().getUsername() + "/" + image.getUserFilename();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImageView toImageView(Image image) {
|
public ImageView toImageView(Image image, @Nullable User viewer) {
|
||||||
final ImageView imageView = new ImageView();
|
if (viewer != null && image.getOwner().getUsername().equals(viewer.getUsername())) {
|
||||||
imageView.setUrl(this.baseUrl + "/images/" + image.getOwner().getUsername() + "/" + image.getUserFilename());
|
return ImageView.from(image, this.getImageUrl(image), true);
|
||||||
imageView.setCreated(image.getCreated());
|
} else {
|
||||||
imageView.setModified(image.getModified());
|
return ImageView.from(image, this.getImageUrl(image), false);
|
||||||
imageView.setFilename(image.getUserFilename());
|
|
||||||
imageView.setMimeType(image.getMimeType());
|
|
||||||
imageView.setAlt(image.getAlt());
|
|
||||||
imageView.setCaption(image.getCaption());
|
|
||||||
imageView.setIsPublic(image.isPublic());
|
|
||||||
|
|
||||||
final User owner = image.getOwner();
|
|
||||||
final UserInfoView userInfoView = new UserInfoView();
|
|
||||||
userInfoView.setId(owner.getId());
|
|
||||||
userInfoView.setUsername(owner.getUsername());
|
|
||||||
imageView.setOwner(userInfoView);
|
|
||||||
|
|
||||||
final Set<UserInfoView> viewers = new HashSet<>();
|
|
||||||
for (final User viewer : image.getViewers()) {
|
|
||||||
final UserInfoView viewerView = new UserInfoView();
|
|
||||||
viewerView.setId(viewer.getId());
|
|
||||||
viewerView.setUsername(viewer.getUsername());
|
|
||||||
viewers.add(viewerView);
|
|
||||||
}
|
}
|
||||||
imageView.setViewers(viewers);
|
|
||||||
|
|
||||||
return imageView;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,35 @@
|
|||||||
package app.mealsmadeeasy.api.image.view;
|
package app.mealsmadeeasy.api.image.view;
|
||||||
|
|
||||||
|
import app.mealsmadeeasy.api.image.Image;
|
||||||
import app.mealsmadeeasy.api.user.view.UserInfoView;
|
import app.mealsmadeeasy.api.user.view.UserInfoView;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
// TODO: get rid of viewers, keep it only for owner view!
|
|
||||||
public class ImageView {
|
public class ImageView {
|
||||||
|
|
||||||
|
public static ImageView from(Image image, String url, boolean includeViewers) {
|
||||||
|
final ImageView view = new ImageView();
|
||||||
|
view.setUrl(url);
|
||||||
|
view.setCreated(image.getCreated());
|
||||||
|
view.setModified(image.getModified());
|
||||||
|
view.setFilename(image.getUserFilename());
|
||||||
|
view.setMimeType(image.getMimeType());
|
||||||
|
view.setAlt(image.getAlt());
|
||||||
|
view.setCaption(image.getCaption());
|
||||||
|
view.setOwner(UserInfoView.from(image.getOwner()));
|
||||||
|
view.setIsPublic(image.isPublic());
|
||||||
|
if (includeViewers) {
|
||||||
|
view.setViewers(image.getViewers().stream()
|
||||||
|
.map(UserInfoView::from)
|
||||||
|
.collect(Collectors.toSet())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
private String url;
|
private String url;
|
||||||
private LocalDateTime created;
|
private LocalDateTime created;
|
||||||
private @Nullable LocalDateTime modified;
|
private @Nullable LocalDateTime modified;
|
||||||
@ -18,7 +39,7 @@ public class ImageView {
|
|||||||
private @Nullable String caption;
|
private @Nullable String caption;
|
||||||
private UserInfoView owner;
|
private UserInfoView owner;
|
||||||
private boolean isPublic;
|
private boolean isPublic;
|
||||||
private Set<UserInfoView> viewers;
|
private @Nullable Set<UserInfoView> viewers;
|
||||||
|
|
||||||
public String getUrl() {
|
public String getUrl() {
|
||||||
return this.url;
|
return this.url;
|
||||||
@ -60,19 +81,19 @@ public class ImageView {
|
|||||||
this.mimeType = mimeType;
|
this.mimeType = mimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAlt() {
|
public @Nullable String getAlt() {
|
||||||
return this.alt;
|
return this.alt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAlt(String alt) {
|
public void setAlt(@Nullable String alt) {
|
||||||
this.alt = alt;
|
this.alt = alt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCaption() {
|
public @Nullable String getCaption() {
|
||||||
return this.caption;
|
return this.caption;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCaption(String caption) {
|
public void setCaption(@Nullable String caption) {
|
||||||
this.caption = caption;
|
this.caption = caption;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,11 +113,11 @@ public class ImageView {
|
|||||||
this.isPublic = isPublic;
|
this.isPublic = isPublic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<UserInfoView> getViewers() {
|
public @Nullable Set<UserInfoView> getViewers() {
|
||||||
return this.viewers;
|
return this.viewers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setViewers(Set<UserInfoView> viewers) {
|
public void setViewers(@Nullable Set<UserInfoView> viewers) {
|
||||||
this.viewers = viewers;
|
this.viewers = viewers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,9 @@ public interface Recipe {
|
|||||||
@Nullable LocalDateTime getModified();
|
@Nullable LocalDateTime getModified();
|
||||||
String getSlug();
|
String getSlug();
|
||||||
String getTitle();
|
String getTitle();
|
||||||
|
@Nullable Integer getPreparationTime();
|
||||||
|
@Nullable Integer getCookingTime();
|
||||||
|
@Nullable Integer getTotalTime();
|
||||||
String getRawText();
|
String getRawText();
|
||||||
User getOwner();
|
User getOwner();
|
||||||
Set<RecipeStar> getStars();
|
Set<RecipeStar> getStars();
|
||||||
|
@ -23,7 +23,7 @@ public final class RecipeEntity implements Recipe {
|
|||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private LocalDateTime created = LocalDateTime.now();
|
private LocalDateTime created;
|
||||||
|
|
||||||
private LocalDateTime modified;
|
private LocalDateTime modified;
|
||||||
|
|
||||||
@ -33,6 +33,15 @@ public final class RecipeEntity implements Recipe {
|
|||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Integer preparationTime;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Integer cookingTime;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Integer totalTime;
|
||||||
|
|
||||||
@Lob
|
@Lob
|
||||||
@Column(name = "raw_text", columnDefinition = "TEXT", nullable = false)
|
@Column(name = "raw_text", columnDefinition = "TEXT", nullable = false)
|
||||||
@Basic(fetch = FetchType.LAZY)
|
@Basic(fetch = FetchType.LAZY)
|
||||||
@ -108,6 +117,33 @@ public final class RecipeEntity implements Recipe {
|
|||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Integer getPreparationTime() {
|
||||||
|
return this.preparationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreparationTime(@Nullable Integer preparationTime) {
|
||||||
|
this.preparationTime = preparationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Integer getCookingTime() {
|
||||||
|
return this.cookingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCookingTime(@Nullable Integer cookingTime) {
|
||||||
|
this.cookingTime = cookingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Integer getTotalTime() {
|
||||||
|
return this.totalTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalTime(@Nullable Integer totalTime) {
|
||||||
|
this.totalTime = totalTime;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getRawText() {
|
public String getRawText() {
|
||||||
return this.rawText;
|
return this.rawText;
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
package app.mealsmadeeasy.api.recipe;
|
package app.mealsmadeeasy.api.recipe;
|
||||||
|
|
||||||
|
import app.mealsmadeeasy.api.image.Image;
|
||||||
import app.mealsmadeeasy.api.image.ImageService;
|
import app.mealsmadeeasy.api.image.ImageService;
|
||||||
import app.mealsmadeeasy.api.image.S3ImageEntity;
|
import app.mealsmadeeasy.api.image.S3ImageEntity;
|
||||||
|
import app.mealsmadeeasy.api.image.view.ImageView;
|
||||||
import app.mealsmadeeasy.api.recipe.spec.RecipeCreateSpec;
|
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.view.FullRecipeView;
|
import app.mealsmadeeasy.api.recipe.view.FullRecipeView;
|
||||||
import app.mealsmadeeasy.api.recipe.view.RecipeInfoView;
|
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.view.UserInfoView;
|
|
||||||
import org.commonmark.parser.Parser;
|
import org.commonmark.parser.Parser;
|
||||||
import org.commonmark.renderer.html.HtmlRenderer;
|
import org.commonmark.renderer.html.HtmlRenderer;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jsoup.Jsoup;
|
import org.jsoup.Jsoup;
|
||||||
import org.jsoup.safety.Safelist;
|
import org.jsoup.safety.Safelist;
|
||||||
@ -99,22 +101,31 @@ public class RecipeServiceImpl implements RecipeService {
|
|||||||
return this.recipeRepository.getViewerCount(recipeId);
|
return this.recipeRepository.getViewerCount(recipeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FullRecipeView getFullView(RecipeEntity recipe) {
|
@Contract("null, _ -> null")
|
||||||
final FullRecipeView view = new FullRecipeView();
|
private @Nullable ImageView getImageView(@Nullable Image image, @Nullable User viewer) {
|
||||||
view.setId(recipe.getId());
|
if (image != null) {
|
||||||
view.setCreated(recipe.getCreated());
|
return this.imageService.toImageView(image, viewer);
|
||||||
view.setModified(recipe.getModified());
|
} else {
|
||||||
view.setSlug(recipe.getSlug());
|
return null;
|
||||||
view.setTitle(recipe.getTitle());
|
|
||||||
view.setText(this.getRenderedMarkdown(recipe));
|
|
||||||
view.setOwner(UserInfoView.from(recipe.getOwner()));
|
|
||||||
view.setStarCount(this.getStarCount(recipe));
|
|
||||||
view.setViewerCount(this.getViewerCount(recipe.getId()));
|
|
||||||
if (recipe.getMainImage() != null) {
|
|
||||||
view.setMainImage(this.imageService.toImageView(recipe.getMainImage()));
|
|
||||||
}
|
}
|
||||||
view.setIsPublic(recipe.isPublic());
|
}
|
||||||
return view;
|
|
||||||
|
private FullRecipeView getFullView(RecipeEntity recipe, @Nullable User viewer) {
|
||||||
|
return FullRecipeView.from(
|
||||||
|
recipe,
|
||||||
|
this.getRenderedMarkdown(recipe),
|
||||||
|
this.getStarCount(recipe),
|
||||||
|
this.getViewerCount(recipe.getId()),
|
||||||
|
this.getImageView(recipe.getMainImage(), viewer)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RecipeInfoView getInfoView(RecipeEntity recipe, @Nullable User viewer) {
|
||||||
|
return RecipeInfoView.from(
|
||||||
|
recipe,
|
||||||
|
this.getStarCount(recipe),
|
||||||
|
this.getImageView(recipe.getMainImage(), viewer)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -123,7 +134,7 @@ public class RecipeServiceImpl implements RecipeService {
|
|||||||
final RecipeEntity recipe = this.recipeRepository.findById(id).orElseThrow(() -> new RecipeException(
|
final RecipeEntity recipe = this.recipeRepository.findById(id).orElseThrow(() -> new RecipeException(
|
||||||
RecipeException.Type.INVALID_ID, "No such Recipe for id: " + id
|
RecipeException.Type.INVALID_ID, "No such Recipe for id: " + id
|
||||||
));
|
));
|
||||||
return this.getFullView(recipe);
|
return this.getFullView(recipe, viewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -134,29 +145,14 @@ public class RecipeServiceImpl implements RecipeService {
|
|||||||
RecipeException.Type.INVALID_USERNAME_OR_SLUG,
|
RecipeException.Type.INVALID_USERNAME_OR_SLUG,
|
||||||
"No such Recipe for username " + username + " and slug: " + slug
|
"No such Recipe for username " + username + " and slug: " + slug
|
||||||
));
|
));
|
||||||
return this.getFullView(recipe);
|
return this.getFullView(recipe, viewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@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(recipe ->
|
||||||
final RecipeInfoView view = new RecipeInfoView();
|
this.getInfoView(recipe, viewer)
|
||||||
view.setId(entity.getId());
|
);
|
||||||
if (entity.getModified() != null) {
|
|
||||||
view.setUpdated(entity.getModified());
|
|
||||||
} else {
|
|
||||||
view.setUpdated(entity.getCreated());
|
|
||||||
}
|
|
||||||
view.setSlug(entity.getSlug());
|
|
||||||
view.setTitle(entity.getTitle());
|
|
||||||
view.setOwner(UserInfoView.from(entity.getOwner()));
|
|
||||||
view.setIsPublic(entity.isPublic());
|
|
||||||
view.setStarCount(this.getStarCount(entity));
|
|
||||||
if (entity.getMainImage() != null) {
|
|
||||||
view.setMainImage(this.imageService.toImageView(entity.getMainImage()));
|
|
||||||
}
|
|
||||||
return view;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -194,6 +190,18 @@ public class RecipeServiceImpl implements RecipeService {
|
|||||||
entity.setTitle(spec.getTitle());
|
entity.setTitle(spec.getTitle());
|
||||||
didModify = true;
|
didModify = true;
|
||||||
}
|
}
|
||||||
|
if (spec.getPreparationTime() != null) {
|
||||||
|
entity.setPreparationTime(spec.getPreparationTime());
|
||||||
|
didModify = true;
|
||||||
|
}
|
||||||
|
if (spec.getCookingTime() != null) {
|
||||||
|
entity.setCookingTime(spec.getCookingTime());
|
||||||
|
didModify = true;
|
||||||
|
}
|
||||||
|
if (spec.getTotalTime() != null) {
|
||||||
|
entity.setTotalTime(spec.getTotalTime());
|
||||||
|
didModify = true;
|
||||||
|
}
|
||||||
if (spec.getRawText() != null) {
|
if (spec.getRawText() != null) {
|
||||||
entity.setRawText(spec.getRawText());
|
entity.setRawText(spec.getRawText());
|
||||||
didModify = true;
|
didModify = true;
|
||||||
|
@ -7,6 +7,9 @@ public class RecipeCreateSpec {
|
|||||||
|
|
||||||
private String slug;
|
private String slug;
|
||||||
private String title;
|
private String title;
|
||||||
|
private @Nullable Integer preparationTime;
|
||||||
|
private @Nullable Integer cookingTime;
|
||||||
|
private @Nullable Integer totalTime;
|
||||||
private String rawText;
|
private String rawText;
|
||||||
private boolean isPublic;
|
private boolean isPublic;
|
||||||
private @Nullable Image mainImage;
|
private @Nullable Image mainImage;
|
||||||
@ -27,6 +30,30 @@ public class RecipeCreateSpec {
|
|||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer getPreparationTime() {
|
||||||
|
return this.preparationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreparationTime(@Nullable Integer preparationTime) {
|
||||||
|
this.preparationTime = preparationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer getCookingTime() {
|
||||||
|
return this.cookingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCookingTime(@Nullable Integer cookingTime) {
|
||||||
|
this.cookingTime = cookingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer getTotalTime() {
|
||||||
|
return this.totalTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalTime(@Nullable Integer totalTime) {
|
||||||
|
this.totalTime = totalTime;
|
||||||
|
}
|
||||||
|
|
||||||
public String getRawText() {
|
public String getRawText() {
|
||||||
return this.rawText;
|
return this.rawText;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,9 @@ public class RecipeUpdateSpec {
|
|||||||
|
|
||||||
private @Nullable String slug;
|
private @Nullable String slug;
|
||||||
private @Nullable String title;
|
private @Nullable String title;
|
||||||
|
private @Nullable Integer preparationTime;
|
||||||
|
private @Nullable Integer cookingTime;
|
||||||
|
private @Nullable Integer totalTime;
|
||||||
private @Nullable String rawText;
|
private @Nullable String rawText;
|
||||||
private @Nullable Boolean isPublic;
|
private @Nullable Boolean isPublic;
|
||||||
private @Nullable Image mainImage;
|
private @Nullable Image mainImage;
|
||||||
@ -27,6 +30,30 @@ public class RecipeUpdateSpec {
|
|||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer getPreparationTime() {
|
||||||
|
return this.preparationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreparationTime(@Nullable Integer preparationTime) {
|
||||||
|
this.preparationTime = preparationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer getCookingTime() {
|
||||||
|
return this.cookingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCookingTime(@Nullable Integer cookingTime) {
|
||||||
|
this.cookingTime = cookingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer getTotalTime() {
|
||||||
|
return this.totalTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalTime(@Nullable Integer totalTime) {
|
||||||
|
this.totalTime = totalTime;
|
||||||
|
}
|
||||||
|
|
||||||
public @Nullable String getRawText() {
|
public @Nullable String getRawText() {
|
||||||
return this.rawText;
|
return this.rawText;
|
||||||
}
|
}
|
||||||
|
@ -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 app.mealsmadeeasy.api.recipe.Recipe;
|
||||||
import app.mealsmadeeasy.api.user.view.UserInfoView;
|
import app.mealsmadeeasy.api.user.view.UserInfoView;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@ -8,11 +9,39 @@ import java.time.LocalDateTime;
|
|||||||
|
|
||||||
public class FullRecipeView {
|
public class FullRecipeView {
|
||||||
|
|
||||||
|
public static FullRecipeView from(
|
||||||
|
Recipe recipe,
|
||||||
|
String renderedText,
|
||||||
|
int starCount,
|
||||||
|
int viewerCount,
|
||||||
|
ImageView mainImage
|
||||||
|
) {
|
||||||
|
final FullRecipeView view = new FullRecipeView();
|
||||||
|
view.setId(recipe.getId());
|
||||||
|
view.setCreated(recipe.getCreated());
|
||||||
|
view.setModified(recipe.getModified());
|
||||||
|
view.setSlug(recipe.getSlug());
|
||||||
|
view.setTitle(recipe.getTitle());
|
||||||
|
view.setPreparationTime(recipe.getPreparationTime());
|
||||||
|
view.setCookingTime(recipe.getCookingTime());
|
||||||
|
view.setTotalTime(recipe.getTotalTime());
|
||||||
|
view.setText(renderedText);
|
||||||
|
view.setOwner(UserInfoView.from(recipe.getOwner()));
|
||||||
|
view.setStarCount(starCount);
|
||||||
|
view.setViewerCount(viewerCount);
|
||||||
|
view.setMainImage(mainImage);
|
||||||
|
view.setIsPublic(recipe.isPublic());
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
private long id;
|
private long id;
|
||||||
private LocalDateTime created;
|
private LocalDateTime created;
|
||||||
private @Nullable LocalDateTime modified;
|
private @Nullable LocalDateTime modified;
|
||||||
private String slug;
|
private String slug;
|
||||||
private String title;
|
private String title;
|
||||||
|
private @Nullable Integer preparationTime;
|
||||||
|
private @Nullable Integer cookingTime;
|
||||||
|
private @Nullable Integer totalTime;
|
||||||
private String text;
|
private String text;
|
||||||
private UserInfoView owner;
|
private UserInfoView owner;
|
||||||
private int starCount;
|
private int starCount;
|
||||||
@ -60,6 +89,30 @@ public class FullRecipeView {
|
|||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer getPreparationTime() {
|
||||||
|
return this.preparationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreparationTime(@Nullable Integer preparationTime) {
|
||||||
|
this.preparationTime = preparationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer getCookingTime() {
|
||||||
|
return this.cookingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCookingTime(@Nullable Integer cookingTime) {
|
||||||
|
this.cookingTime = cookingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer getTotalTime() {
|
||||||
|
return this.totalTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalTime(@Nullable Integer totalTime) {
|
||||||
|
this.totalTime = totalTime;
|
||||||
|
}
|
||||||
|
|
||||||
public @Nullable String getText() {
|
public @Nullable String getText() {
|
||||||
return this.text;
|
return this.text;
|
||||||
}
|
}
|
||||||
|
@ -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 app.mealsmadeeasy.api.recipe.Recipe;
|
||||||
import app.mealsmadeeasy.api.user.view.UserInfoView;
|
import app.mealsmadeeasy.api.user.view.UserInfoView;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@ -8,10 +9,31 @@ import java.time.LocalDateTime;
|
|||||||
|
|
||||||
public final class RecipeInfoView {
|
public final class RecipeInfoView {
|
||||||
|
|
||||||
|
public static RecipeInfoView from(Recipe recipe, int starCount, @Nullable ImageView mainImage) {
|
||||||
|
final RecipeInfoView view = new RecipeInfoView();
|
||||||
|
view.setId(recipe.getId());
|
||||||
|
view.setCreated(recipe.getCreated());
|
||||||
|
view.setModified(recipe.getModified());
|
||||||
|
view.setSlug(recipe.getSlug());
|
||||||
|
view.setTitle(recipe.getTitle());
|
||||||
|
view.setPreparationTime(recipe.getPreparationTime());
|
||||||
|
view.setCookingTime(recipe.getCookingTime());
|
||||||
|
view.setTotalTime(recipe.getTotalTime());
|
||||||
|
view.setOwner(UserInfoView.from(recipe.getOwner()));
|
||||||
|
view.setIsPublic(recipe.isPublic());
|
||||||
|
view.setStarCount(starCount);
|
||||||
|
view.setMainImage(mainImage);
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
private long id;
|
private long id;
|
||||||
private LocalDateTime updated;
|
private LocalDateTime created;
|
||||||
|
private LocalDateTime modified;
|
||||||
private String slug;
|
private String slug;
|
||||||
private String title;
|
private String title;
|
||||||
|
private @Nullable Integer preparationTime;
|
||||||
|
private @Nullable Integer cookingTime;
|
||||||
|
private @Nullable Integer totalTime;
|
||||||
private UserInfoView owner;
|
private UserInfoView owner;
|
||||||
private boolean isPublic;
|
private boolean isPublic;
|
||||||
private int starCount;
|
private int starCount;
|
||||||
@ -25,12 +47,20 @@ public final class RecipeInfoView {
|
|||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDateTime getUpdated() {
|
public LocalDateTime getCreated() {
|
||||||
return this.updated;
|
return this.created;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUpdated(LocalDateTime updated) {
|
public void setCreated(LocalDateTime created) {
|
||||||
this.updated = updated;
|
this.created = created;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getModified() {
|
||||||
|
return this.modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModified(LocalDateTime modified) {
|
||||||
|
this.modified = modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSlug() {
|
public String getSlug() {
|
||||||
@ -49,6 +79,30 @@ public final class RecipeInfoView {
|
|||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer getPreparationTime() {
|
||||||
|
return this.preparationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreparationTime(@Nullable Integer preparationTime) {
|
||||||
|
this.preparationTime = preparationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer getCookingTime() {
|
||||||
|
return this.cookingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCookingTime(@Nullable Integer cookingTime) {
|
||||||
|
this.cookingTime = cookingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Integer getTotalTime() {
|
||||||
|
return this.totalTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalTime(@Nullable Integer totalTime) {
|
||||||
|
this.totalTime = totalTime;
|
||||||
|
}
|
||||||
|
|
||||||
public UserInfoView getOwner() {
|
public UserInfoView getOwner() {
|
||||||
return this.owner;
|
return this.owner;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user