ImageView.viewers only non-empty when principal is owner. Added preparation, cook, and total time to Recipe.

This commit is contained in:
Jesse Brault 2024-08-12 20:05:24 -05:00
parent 22fac36e4b
commit ccae29b202
14 changed files with 310 additions and 82 deletions

View File

@ -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))

View File

@ -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");

View File

@ -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 {

View File

@ -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}")

View File

@ -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);
} }

View File

@ -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;
} }
} }

View File

@ -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;
} }

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }