diff --git a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeControllerTests.java b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeControllerTests.java
index 2a65832..229a8a1 100644
--- a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeControllerTests.java
+++ b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeControllerTests.java
@@ -39,6 +39,7 @@ public class RecipeControllerTests {
private Recipe createTestRecipe(User owner, boolean isPublic) {
final RecipeCreateSpec spec = new RecipeCreateSpec();
+ spec.setSlug("test-recipe");
spec.setTitle("Test Recipe");
spec.setRawText("# Hello, World!");
spec.setPublic(isPublic);
@@ -50,12 +51,12 @@ public class RecipeControllerTests {
public void getRecipePageViewByIdPublicRecipeNoPrincipal() throws Exception {
final User owner = this.createTestUser("owner");
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(jsonPath("$.id").value(1))
+ .andExpect(jsonPath("$.slug").value(recipe.getSlug()))
.andExpect(jsonPath("$.title").value("Test Recipe"))
.andExpect(jsonPath("$.text").value("
Hello, World!
"))
- .andExpect(jsonPath("$.ownerId").value(owner.getId()))
.andExpect(jsonPath("$.ownerUsername").value(owner.getUsername()))
.andExpect(jsonPath("$.starCount").value(0))
.andExpect(jsonPath("$.viewerCount").value(0));
@@ -74,8 +75,8 @@ public class RecipeControllerTests {
.andExpect(jsonPath("$.content", hasSize(1)))
.andExpect(jsonPath("$.content[0].id").value(recipe.getId()))
.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].ownerId").value(owner.getId()))
.andExpect(jsonPath("$.content[0].ownerUsername").value(owner.getUsername()))
.andExpect(jsonPath("$.content[0].public").value(true))
.andExpect(jsonPath("$.content[0].starCount").value(0));
diff --git a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeRepositoryTests.java b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeRepositoryTests.java
index 0be0421..521841f 100644
--- a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeRepositoryTests.java
+++ b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeRepositoryTests.java
@@ -42,6 +42,7 @@ public class RecipeRepositoryTests {
@DirtiesContext
public void findsAllPublicRecipes() {
final RecipeEntity publicRecipe = new RecipeEntity();
+ publicRecipe.setSlug("public-recipe");
publicRecipe.setPublic(true);
publicRecipe.setOwner(this.getOwnerUser());
publicRecipe.setTitle("Public Recipe");
@@ -56,6 +57,7 @@ public class RecipeRepositoryTests {
@DirtiesContext
public void doesNotFindNonPublicRecipe() {
final RecipeEntity nonPublicRecipe = new RecipeEntity();
+ nonPublicRecipe.setSlug("non-public-recipe");
nonPublicRecipe.setOwner(this.getOwnerUser());
nonPublicRecipe.setTitle("Non-Public Recipe");
nonPublicRecipe.setRawText("Hello, World!");
@@ -69,6 +71,7 @@ public class RecipeRepositoryTests {
@DirtiesContext
public void findsAllForViewer() {
final RecipeEntity recipe = new RecipeEntity();
+ recipe.setSlug("test-recipe");
recipe.setOwner(this.getOwnerUser());
recipe.setTitle("Test Recipe");
recipe.setRawText("Hello, World!");
@@ -89,6 +92,7 @@ public class RecipeRepositoryTests {
@DirtiesContext
public void doesNotIncludeNonViewable() {
final RecipeEntity recipe = new RecipeEntity();
+ recipe.setSlug("test-recipe");
recipe.setOwner(this.getOwnerUser());
recipe.setTitle("Test Recipe");
recipe.setRawText("Hello, World!");
diff --git a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeServiceTests.java b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeServiceTests.java
index b188132..406981c 100644
--- a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeServiceTests.java
+++ b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeServiceTests.java
@@ -43,11 +43,16 @@ public class RecipeServiceTests {
}
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) {
+ return this.createTestRecipe(owner, isPublic, null);
+ }
+
+ private Recipe createTestRecipe(@Nullable User owner, boolean isPublic, @Nullable String slug) {
final RecipeCreateSpec spec = new RecipeCreateSpec();
+ spec.setSlug(slug != null ? slug : "my-recipe");
spec.setTitle("My Recipe");
spec.setRawText("Hello!");
spec.setPublic(isPublic);
@@ -88,6 +93,7 @@ public class RecipeServiceTests {
final Recipe recipe = this.createTestRecipe(owner, true);
final Recipe byId = this.recipeService.getById(recipe.getId(), null);
assertThat(byId.getId(), is(recipe.getId()));
+ assertThat(byId.getSlug(), is(recipe.getSlug()));
assertThat(byId.getTitle(), is("My Recipe"));
assertThat(byId.getRawText(), is("Hello!"));
assertThat(byId.isPublic(), is(true));
@@ -167,9 +173,9 @@ public class RecipeServiceTests {
final User u0 = this.createTestUser("u0");
final User u1 = this.createTestUser("u1");
- final Recipe r0 = this.createTestRecipe(owner, true);
- final Recipe r1 = this.createTestRecipe(owner, true);
- final Recipe r2 = this.createTestRecipe(owner, true);
+ final Recipe r0 = this.createTestRecipe(owner, true, "r0");
+ final Recipe r1 = this.createTestRecipe(owner, true, "r1");
+ final Recipe r2 = this.createTestRecipe(owner, true, "r2");
// r0.stars = 0, r1.stars = 1, r2.stars = 2
this.recipeStarService.create(r1.getId(), u0.getUsername());
@@ -197,9 +203,9 @@ public class RecipeServiceTests {
final User u1 = this.createTestUser("u1");
final User viewer = this.createTestUser("recipeViewer");
- Recipe r0 = this.createTestRecipe(owner); // not public
- Recipe r1 = this.createTestRecipe(owner);
- Recipe r2 = this.createTestRecipe(owner);
+ Recipe r0 = this.createTestRecipe(owner, false, "r0"); // not public
+ Recipe r1 = this.createTestRecipe(owner, false, "r1");
+ Recipe r2 = this.createTestRecipe(owner, false, "r2");
for (final User starer : List.of(u0, u1)) {
r0 = this.recipeService.addViewer(r0.getId(), owner, starer);
@@ -243,8 +249,8 @@ public class RecipeServiceTests {
public void getPublicRecipes() {
final User owner = this.createTestUser("recipeOwner");
- Recipe r0 = this.createTestRecipe(owner, true);
- Recipe r1 = this.createTestRecipe(owner, true);
+ Recipe r0 = this.createTestRecipe(owner, true, "r0");
+ Recipe r1 = this.createTestRecipe(owner, true, "r1");
final List publicRecipes = this.recipeService.getPublicRecipes();
assertThat(publicRecipes.size(), is(2));
@@ -279,6 +285,7 @@ public class RecipeServiceTests {
public void updateRawText() throws RecipeException {
final User owner = this.createTestUser("recipeOwner");
final RecipeCreateSpec createSpec = new RecipeCreateSpec();
+ createSpec.setSlug("my-recipe");
createSpec.setTitle("My Recipe");
createSpec.setRawText("# A Heading");
Recipe recipe = this.recipeService.create(owner, createSpec);
diff --git a/src/integrationTest/resources/application.properties b/src/integrationTest/resources/application.properties
index 224bc54..60d3fb7 100644
--- a/src/integrationTest/resources/application.properties
+++ b/src/integrationTest/resources/application.properties
@@ -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.username=sa
spring.datasource.password=sa
+app.mealsmadeeasy.api.baseUrl=http://localhost:8080
app.mealsmadeeasy.api.security.access-token-lifetime=60
app.mealsmadeeasy.api.security.refresh-token-lifetime=120
app.mealsmadeeasy.api.minio.endpoint=http://localhost:9000
diff --git a/src/main/java/app/mealsmadeeasy/api/DevConfiguration.java b/src/main/java/app/mealsmadeeasy/api/DevConfiguration.java
index 576c2bd..d605f94 100644
--- a/src/main/java/app/mealsmadeeasy/api/DevConfiguration.java
+++ b/src/main/java/app/mealsmadeeasy/api/DevConfiguration.java
@@ -61,6 +61,7 @@ public class DevConfiguration {
logger.info("Created {}", obazdaImage);
final RecipeCreateSpec recipeCreateSpec = new RecipeCreateSpec();
+ recipeCreateSpec.setSlug("test-recipe");
recipeCreateSpec.setTitle("Test Recipe");
recipeCreateSpec.setRawText("Hello, World!");
recipeCreateSpec.setPublic(true);
diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/Recipe.java b/src/main/java/app/mealsmadeeasy/api/recipe/Recipe.java
index f171bd8..9dca31f 100644
--- a/src/main/java/app/mealsmadeeasy/api/recipe/Recipe.java
+++ b/src/main/java/app/mealsmadeeasy/api/recipe/Recipe.java
@@ -13,6 +13,7 @@ public interface Recipe {
Long getId();
LocalDateTime getCreated();
@Nullable LocalDateTime getModified();
+ String getSlug();
String getTitle();
String getRawText();
User getOwner();
diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeController.java b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeController.java
index 2699548..1910d5c 100644
--- a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeController.java
+++ b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeController.java
@@ -31,10 +31,14 @@ public class RecipeController {
));
}
- @GetMapping("/{id}")
- public ResponseEntity getById(@PathVariable long id, @AuthenticationPrincipal User user)
+ @GetMapping("/{username}/{slug}")
+ public ResponseEntity getById(
+ @PathVariable String username,
+ @PathVariable String slug,
+ @AuthenticationPrincipal User viewer
+ )
throws RecipeException {
- return ResponseEntity.ok(this.recipeService.getFullViewById(id, user));
+ return ResponseEntity.ok(this.recipeService.getFullViewByUsernameAndSlug(username, slug, viewer));
}
@GetMapping
diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeEntity.java b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeEntity.java
index 34651ee..490515b 100644
--- a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeEntity.java
+++ b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeEntity.java
@@ -27,6 +27,9 @@ public final class RecipeEntity implements Recipe {
private LocalDateTime modified;
+ @Column(nullable = false, unique = true)
+ private String slug;
+
@Column(nullable = false)
private String title;
@@ -86,6 +89,15 @@ public final class RecipeEntity implements Recipe {
this.modified = modified;
}
+ @Override
+ public String getSlug() {
+ return this.slug;
+ }
+
+ public void setSlug(String slug) {
+ this.slug = slug;
+ }
+
@Override
public String getTitle() {
return this.title;
diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeException.java b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeException.java
index 5026bde..c3c5625 100644
--- a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeException.java
+++ b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeException.java
@@ -3,7 +3,7 @@ package app.mealsmadeeasy.api.recipe;
public class RecipeException extends Exception {
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;
diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeRepository.java b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeRepository.java
index cd93267..35830a8 100644
--- a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeRepository.java
+++ b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeRepository.java
@@ -18,6 +18,9 @@ public interface RecipeRepository extends JpaRepository {
List findAllByOwner(UserEntity owner);
+ @Query("SELECT r from Recipe r WHERE r.owner.username = ?1 AND r.slug = ?2")
+ Optional 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)")
List findAllViewableByStarsGreaterThanEqual(long stars, UserEntity viewer);
diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeSecurity.java b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeSecurity.java
index bc7e3c6..5960f64 100644
--- a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeSecurity.java
+++ b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeSecurity.java
@@ -7,5 +7,6 @@ public interface RecipeSecurity {
boolean isOwner(Recipe recipe, User user);
boolean isOwner(long recipeId, 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;
}
diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeSecurityImpl.java b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeSecurityImpl.java
index 435a01c..de87b84 100644
--- a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeSecurityImpl.java
+++ b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeSecurityImpl.java
@@ -56,6 +56,16 @@ public class RecipeSecurityImpl implements RecipeSecurity {
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
public boolean isViewableBy(long recipeId, @Nullable User user) throws RecipeException {
final Recipe recipe = this.recipeRepository.findById(recipeId).orElseThrow(() -> new RecipeException(
diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeService.java b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeService.java
index ac1c63e..19d87e5 100644
--- a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeService.java
+++ b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeService.java
@@ -18,6 +18,7 @@ public interface RecipeService {
Recipe getById(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 getFullViewByUsernameAndSlug(String username, String slug, @Nullable User viewer) throws RecipeException;
Slice getInfoViewsViewableBy(Pageable pageable, @Nullable User viewer);
List getByMinimumStars(long minimumStars, @Nullable User viewer);
diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeServiceImpl.java b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeServiceImpl.java
index 3fc00ad..5154718 100644
--- a/src/main/java/app/mealsmadeeasy/api/recipe/RecipeServiceImpl.java
+++ b/src/main/java/app/mealsmadeeasy/api/recipe/RecipeServiceImpl.java
@@ -53,6 +53,7 @@ public class RecipeServiceImpl implements RecipeService {
final RecipeEntity draft = new RecipeEntity();
draft.setCreated(LocalDateTime.now());
draft.setOwner((UserEntity) owner);
+ draft.setSlug(spec.getSlug());
draft.setTitle(spec.getTitle());
draft.setRawText(spec.getRawText());
draft.setMainImage((S3ImageEntity) spec.getMainImage());
@@ -97,26 +98,44 @@ public class RecipeServiceImpl implements RecipeService {
return this.recipeRepository.getViewerCount(recipeId);
}
- @Override
- @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
- ));
+ private FullRecipeView getFullView(RecipeEntity recipe) {
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.setText(this.getRenderedMarkdown(recipe));
view.setOwnerId(recipe.getOwner().getId());
view.setOwnerUsername(recipe.getOwner().getUsername());
view.setStarCount(this.getStarCount(recipe));
view.setViewerCount(this.getViewerCount(recipe.getId()));
- view.setMainImage(this.imageService.toImageView(recipe.getMainImage()));
+ if (recipe.getMainImage() != null) {
+ view.setMainImage(this.imageService.toImageView(recipe.getMainImage()));
+ }
return view;
}
+ @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
public Slice getInfoViewsViewableBy(Pageable pageable, @Nullable User viewer) {
return this.recipeRepository.findAllViewableBy((UserEntity) viewer, pageable).map(entity -> {
@@ -127,12 +146,14 @@ public class RecipeServiceImpl implements RecipeService {
} else {
view.setUpdated(entity.getCreated());
}
+ view.setSlug(entity.getSlug());
view.setTitle(entity.getTitle());
- view.setOwnerId(entity.getOwner().getId());
view.setOwnerUsername(entity.getOwner().getUsername());
view.setPublic(entity.isPublic());
view.setStarCount(this.getStarCount(entity));
- view.setMainImage(this.imageService.toImageView(entity.getMainImage()));
+ if (entity.getMainImage() != null) {
+ view.setMainImage(this.imageService.toImageView(entity.getMainImage()));
+ }
return view;
});
}
@@ -164,6 +185,10 @@ public class RecipeServiceImpl implements RecipeService {
public Recipe update(long id, RecipeUpdateSpec spec, User modifier) throws RecipeException {
final RecipeEntity entity = this.findRecipeEntity(id);
boolean didModify = false;
+ if (spec.getSlug() != null) {
+ entity.setSlug(spec.getSlug());
+ didModify = true;
+ }
if (spec.getTitle() != null) {
entity.setTitle(spec.getTitle());
didModify = true;
diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/spec/RecipeCreateSpec.java b/src/main/java/app/mealsmadeeasy/api/recipe/spec/RecipeCreateSpec.java
index 149606a..f45b9f8 100644
--- a/src/main/java/app/mealsmadeeasy/api/recipe/spec/RecipeCreateSpec.java
+++ b/src/main/java/app/mealsmadeeasy/api/recipe/spec/RecipeCreateSpec.java
@@ -5,11 +5,20 @@ import org.jetbrains.annotations.Nullable;
public class RecipeCreateSpec {
+ private String slug;
private String title;
private String rawText;
private boolean isPublic;
private @Nullable Image mainImage;
+ public String getSlug() {
+ return this.slug;
+ }
+
+ public void setSlug(String slug) {
+ this.slug = slug;
+ }
+
public String getTitle() {
return this.title;
}
diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/spec/RecipeUpdateSpec.java b/src/main/java/app/mealsmadeeasy/api/recipe/spec/RecipeUpdateSpec.java
index 5af41af..fcdb8e6 100644
--- a/src/main/java/app/mealsmadeeasy/api/recipe/spec/RecipeUpdateSpec.java
+++ b/src/main/java/app/mealsmadeeasy/api/recipe/spec/RecipeUpdateSpec.java
@@ -5,11 +5,20 @@ import org.jetbrains.annotations.Nullable;
public class RecipeUpdateSpec {
+ private @Nullable String slug;
private @Nullable String title;
private @Nullable String rawText;
private @Nullable Boolean isPublic;
private @Nullable Image mainImage;
+ public @Nullable String getSlug() {
+ return this.slug;
+ }
+
+ public void setSlug(@Nullable String slug) {
+ this.slug = slug;
+ }
+
public @Nullable String getTitle() {
return this.title;
}
diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/view/FullRecipeView.java b/src/main/java/app/mealsmadeeasy/api/recipe/view/FullRecipeView.java
index 2f1286b..491c2bc 100644
--- a/src/main/java/app/mealsmadeeasy/api/recipe/view/FullRecipeView.java
+++ b/src/main/java/app/mealsmadeeasy/api/recipe/view/FullRecipeView.java
@@ -10,6 +10,7 @@ public class FullRecipeView {
private long id;
private LocalDateTime created;
private LocalDateTime modified;
+ private String slug;
private String title;
private String text;
private long ownerId;
@@ -42,6 +43,14 @@ public class FullRecipeView {
this.modified = modified;
}
+ public String getSlug() {
+ return this.slug;
+ }
+
+ public void setSlug(String slug) {
+ this.slug = slug;
+ }
+
public String getTitle() {
return this.title;
}
diff --git a/src/main/java/app/mealsmadeeasy/api/recipe/view/RecipeInfoView.java b/src/main/java/app/mealsmadeeasy/api/recipe/view/RecipeInfoView.java
index b2ea158..e9d980e 100644
--- a/src/main/java/app/mealsmadeeasy/api/recipe/view/RecipeInfoView.java
+++ b/src/main/java/app/mealsmadeeasy/api/recipe/view/RecipeInfoView.java
@@ -1,6 +1,7 @@
package app.mealsmadeeasy.api.recipe.view;
import app.mealsmadeeasy.api.image.view.ImageView;
+import org.jetbrains.annotations.Nullable;
import java.time.LocalDateTime;
@@ -8,12 +9,12 @@ public final class RecipeInfoView {
private long id;
private LocalDateTime updated;
+ private String slug;
private String title;
- private long ownerId;
private String ownerUsername;
private boolean isPublic;
private int starCount;
- private ImageView mainImage;
+ private @Nullable ImageView mainImage;
public long getId() {
return this.id;
@@ -31,6 +32,14 @@ public final class RecipeInfoView {
this.updated = updated;
}
+ public String getSlug() {
+ return this.slug;
+ }
+
+ public void setSlug(String slug) {
+ this.slug = slug;
+ }
+
public String getTitle() {
return this.title;
}
@@ -39,14 +48,6 @@ public final class RecipeInfoView {
this.title = title;
}
- public long getOwnerId() {
- return this.ownerId;
- }
-
- public void setOwnerId(long ownerId) {
- this.ownerId = ownerId;
- }
-
public String getOwnerUsername() {
return this.ownerUsername;
}
@@ -71,11 +72,11 @@ public final class RecipeInfoView {
this.starCount = starCount;
}
- public ImageView getMainImage() {
+ public @Nullable ImageView getMainImage() {
return this.mainImage;
}
- public void setMainImage(ImageView mainImage) {
+ public void setMainImage(@Nullable ImageView mainImage) {
this.mainImage = mainImage;
}