diff --git a/src/integrationTest/java/app/mealsmadeeasy/api/image/S3ImageServiceTests.java b/src/integrationTest/java/app/mealsmadeeasy/api/image/S3ImageServiceTests.java index 400dbfb..963fa12 100644 --- a/src/integrationTest/java/app/mealsmadeeasy/api/image/S3ImageServiceTests.java +++ b/src/integrationTest/java/app/mealsmadeeasy/api/image/S3ImageServiceTests.java @@ -1,14 +1,15 @@ package app.mealsmadeeasy.api.image; +import app.mealsmadeeasy.api.IntegrationTestsExtension; import app.mealsmadeeasy.api.image.spec.ImageCreateInfoSpec; import app.mealsmadeeasy.api.image.spec.ImageUpdateInfoSpec; import app.mealsmadeeasy.api.user.User; import app.mealsmadeeasy.api.user.UserCreateException; import app.mealsmadeeasy.api.user.UserService; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; import org.testcontainers.containers.MinIOContainer; @@ -20,6 +21,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Set; +import java.util.UUID; import static app.mealsmadeeasy.api.image.ContainsImagesMatcher.containsImages; import static app.mealsmadeeasy.api.user.ContainsUsersMatcher.containsUsers; @@ -30,13 +32,13 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertThrows; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; @Testcontainers @SpringBootTest +@ExtendWith(IntegrationTestsExtension.class) public class S3ImageServiceTests { - private static final String USER_FILENAME = "HAL9000.svg"; - @Container private static final MinIOContainer container = new MinIOContainer( DockerImageName.parse("minio/minio:latest") @@ -49,7 +51,7 @@ public class S3ImageServiceTests { registry.add("app.mealsmadeeasy.api.minio.secretKey", container::getPassword); } - private static InputStream getHal9000() { + private static InputStream getHal9000InputStream() { return S3ImageServiceTests.class.getResourceAsStream("HAL9000.svg"); } @@ -59,26 +61,40 @@ public class S3ImageServiceTests { @Autowired private ImageService imageService; - private User createTestUser(String username) { + private static final String TEST_PASSWORD = "test"; + private static final long HAL_LENGTH = 27881L; + + private User seedUser() { + final String uuid = UUID.randomUUID().toString(); try { - return this.userService.createUser(username, username + "@test.com", "test"); + return this.userService.createUser(uuid, uuid + "@test.com", TEST_PASSWORD); } catch (UserCreateException e) { throw new RuntimeException(e); } } - private Image createHal9000(User owner) throws ImageException, IOException { - try (final InputStream hal9000 = getHal9000()) { + private static String makeUserFilename() { + return UUID.randomUUID() + ".svg"; + } + + private Image seedImage(User owner, ImageCreateInfoSpec spec) { + try (final InputStream hal9000 = getHal9000InputStream()) { return this.imageService.create( owner, - USER_FILENAME, + makeUserFilename(), hal9000, - 27881L, - new ImageCreateInfoSpec() + HAL_LENGTH, + spec ); + } catch (ImageException | IOException e) { + throw new RuntimeException(e); } } + private Image seedImage(User owner) { + return this.seedImage(owner, new ImageCreateInfoSpec()); + } + private Image makePublic(Image image, User modifier) { final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec(); spec.setPublic(true); @@ -89,14 +105,13 @@ public class S3ImageServiceTests { public void smokeScreen() {} @Test - @DirtiesContext - public void simpleCreate() throws ImageException, IOException { - final User owner = this.createTestUser("imageOwner"); - final Image image = this.createHal9000(owner); + public void simpleCreate() { + final User owner = this.seedUser(); + final Image image = this.seedImage(owner); assertThat(image.getOwner(), isUser(owner)); assertThat(image.getCreated(), is(notNullValue())); assertThat(image.getModified(), is(nullValue())); - assertThat(image.getUserFilename(), is("HAL9000.svg")); + assertThat(image.getUserFilename(), is(notNullValue())); assertThat(image.getMimeType(), is("image/svg+xml")); assertThat(image.getAlt(), is(nullValue())); assertThat(image.getCaption(), is(nullValue())); @@ -105,54 +120,55 @@ public class S3ImageServiceTests { } @Test - @DirtiesContext - public void loadImageWithOwnerAsViewer() throws ImageException, IOException { - final User owner = this.createTestUser("imageOwner"); - final Image image = this.createHal9000(owner); - try (final InputStream stored = - this.imageService.getImageContent(image, owner)) { - final byte[] storedBytes = stored.readAllBytes(); - assertThat(storedBytes.length, is(27881)); - } + public void properlyLoadsContent() throws IOException { + final User owner = this.seedUser(); + final Image image = this.seedImage(owner); + final InputStream content = assertDoesNotThrow(() -> this.imageService.getImageContent(image, owner)); + //noinspection DataFlowIssue + final byte[] contentBytes = content.readAllBytes(); + assertThat(contentBytes.length, is((int) HAL_LENGTH)); + content.close(); } @Test - @DirtiesContext - public void loadPublicImage() throws ImageException, IOException { - final User owner = this.createTestUser("imageOwner"); - Image image = this.createHal9000(owner); - image = this.makePublic(image, owner); - try (final InputStream stored = - this.imageService.getImageContent(image, null)) { - final byte[] storedBytes = stored.readAllBytes(); - assertThat(storedBytes.length, is(27881)); - } + public void loadImageWithOwnerAsViewer() throws IOException { + final User owner = this.seedUser(); + final Image image = this.seedImage(owner); + final InputStream content = assertDoesNotThrow(() -> this.imageService.getImageContent(image, owner)); + //noinspection DataFlowIssue + content.close(); } @Test - @DirtiesContext - public void loadImageWithViewer() throws ImageException, IOException { - final User owner = this.createTestUser("imageOwner"); - final User viewer = this.createTestUser("imageViewer"); - Image image = this.createHal9000(owner); + public void loadPublicImage() throws IOException { + final User owner = this.seedUser(); + final Image seedImage = this.seedImage(owner); + final Image publicImage = this.makePublic(seedImage, owner); + final InputStream content = assertDoesNotThrow(() -> this.imageService.getImageContent(publicImage, null)); + //noinspection DataFlowIssue + content.close(); + } + + @Test + public void loadImageWithViewer() throws IOException { + final User owner = this.seedUser(); + final User viewer = this.seedUser(); + Image seedImage = this.seedImage(owner); final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec(); spec.setViewersToAdd(Set.of(viewer)); - image = this.imageService.update(image, owner, spec); - try (final InputStream stored = - this.imageService.getImageContent(image, viewer)) { - final byte[] storedBytes = stored.readAllBytes(); - assertThat(storedBytes.length, is(27881)); - } + final Image imageWithViewer = this.imageService.update(seedImage, owner, spec); + final InputStream content = assertDoesNotThrow(() -> this.imageService.getImageContent(imageWithViewer, viewer)); + //noinspection DataFlowIssue + content.close(); } @Test - @DirtiesContext - public void getImagesOwnedBy() throws ImageException, IOException { - final User owner = this.createTestUser("imageOwner"); - final User otherOwner = this.createTestUser("otherImageOwner"); - final Image image0 = this.createHal9000(owner); - final Image image1 = this.createHal9000(owner); - final Image image2 = this.createHal9000(otherOwner); + public void getImagesOwnedBy() { + final User owner = this.seedUser(); + final User otherOwner = this.seedUser(); + final Image image0 = this.seedImage(owner); + final Image image1 = this.seedImage(owner); + final Image image2 = this.seedImage(otherOwner); final List ownedImages = this.imageService.getImagesOwnedBy(owner); assertThat(ownedImages.size(), is(2)); @@ -164,10 +180,9 @@ public class S3ImageServiceTests { } @Test - @DirtiesContext - public void updateAlt() throws Exception { - final User owner = this.createTestUser("imageOwner"); - Image image = this.createHal9000(owner); + public void updateAlt() { + final User owner = this.seedUser(); + Image image = this.seedImage(owner); final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec(); spec.setAlt("HAL 9000"); image = this.imageService.update(image, owner, spec); @@ -175,10 +190,9 @@ public class S3ImageServiceTests { } @Test - @DirtiesContext - public void updateCaption() throws Exception { - final User owner = this.createTestUser("imageOwner"); - Image image = this.createHal9000(owner); + public void updateCaption() { + final User owner = this.seedUser(); + Image image = this.seedImage(owner); final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec(); spec.setCaption("HAL 9000 from 2001: A Space Odyssey"); image = this.imageService.update(image, owner, spec); @@ -186,10 +200,9 @@ public class S3ImageServiceTests { } @Test - @DirtiesContext - public void updateIsPublic() throws Exception { - final User owner = this.createTestUser("imageOwner"); - Image image = this.createHal9000(owner); + public void updateIsPublic() { + final User owner = this.seedUser(); + Image image = this.seedImage(owner); final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec(); spec.setPublic(true); image = this.imageService.update(image, owner, spec); @@ -203,21 +216,19 @@ public class S3ImageServiceTests { } @Test - @DirtiesContext - public void addViewers() throws Exception { - final User owner = this.createTestUser("imageOwner"); - final User viewer = this.createTestUser("imageViewer"); - Image image = this.createHal9000(owner); + public void addViewers() { + final User owner = this.seedUser(); + final User viewer = this.seedUser(); + Image image = this.seedImage(owner); image = this.addViewer(image, owner, viewer); assertThat(image.getViewers(), containsUsers(viewer)); } @Test - @DirtiesContext - public void removeViewers() throws Exception { - final User owner = this.createTestUser("imageOwner"); - final User viewer = this.createTestUser("imageViewer"); - Image image = this.createHal9000(owner); + public void removeViewers() { + final User owner = this.seedUser(); + final User viewer = this.seedUser(); + Image image = this.seedImage(owner); image = this.addViewer(image, owner, viewer); assertThat(image.getViewers(), containsUsers(viewer)); @@ -228,11 +239,10 @@ public class S3ImageServiceTests { } @Test - @DirtiesContext - public void clearAllViewers() throws Exception { - final User owner = this.createTestUser("imageOwner"); - final User viewer = this.createTestUser("imageViewer"); - Image image = this.createHal9000(owner); + public void clearAllViewers() { + final User owner = this.seedUser(); + final User viewer = this.seedUser(); + Image image = this.seedImage(owner); image = this.addViewer(image, owner, viewer); assertThat(image.getViewers(), containsUsers(viewer)); @@ -243,10 +253,9 @@ public class S3ImageServiceTests { } @Test - @DirtiesContext public void deleteImage() throws Exception { - final User owner = this.createTestUser("imageOwner"); - final Image image = this.createHal9000(owner); + final User owner = this.seedUser(); + final Image image = this.seedImage(owner); this.imageService.deleteImage(image, owner); assertThrows(ImageException.class, () -> this.imageService.getById(image.getId(), owner)); } diff --git a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeControllerTests.java b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeControllerTests.java index d87aa63..d247fc0 100644 --- a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeControllerTests.java +++ b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeControllerTests.java @@ -1,5 +1,6 @@ package app.mealsmadeeasy.api.recipe; +import app.mealsmadeeasy.api.IntegrationTestsExtension; import app.mealsmadeeasy.api.auth.AuthService; import app.mealsmadeeasy.api.auth.LoginDetails; import app.mealsmadeeasy.api.auth.LoginException; @@ -14,11 +15,11 @@ import app.mealsmadeeasy.api.user.User; import app.mealsmadeeasy.api.user.UserCreateException; import app.mealsmadeeasy.api.user.UserService; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.http.MediaType; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.web.servlet.MockMvc; @@ -29,9 +30,9 @@ import org.testcontainers.utility.DockerImageName; import tools.jackson.databind.ObjectMapper; import java.io.InputStream; +import java.util.UUID; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.Matchers.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -39,6 +40,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @Testcontainers @SpringBootTest @AutoConfigureMockMvc +@ExtendWith(IntegrationTestsExtension.class) public class RecipeControllerTests { @Container @@ -78,17 +80,20 @@ public class RecipeControllerTests { @Autowired private ObjectMapper objectMapper; - private User createTestUser(String username) { + private static final String TEST_PASSWORD = "test"; + + private User seedUser() { + final String uuid = UUID.randomUUID().toString(); try { - return this.userService.createUser(username, username + "@test.com", "test"); + return this.userService.createUser(uuid, uuid + "@test.com", TEST_PASSWORD); } catch (UserCreateException e) { throw new RuntimeException(e); } } - private Recipe createTestRecipe(User owner, boolean isPublic, String slug) { + private Recipe createTestRecipe(User owner, boolean isPublic) { final RecipeCreateSpec spec = new RecipeCreateSpec(); - spec.setSlug(slug); + spec.setSlug(UUID.randomUUID().toString()); spec.setTitle("Test Recipe"); spec.setPreparationTime(10); spec.setCookingTime(20); @@ -98,12 +103,8 @@ public class RecipeControllerTests { return this.recipeService.create(owner, spec); } - private Recipe createTestRecipe(User owner, boolean isPublic) { - return this.createTestRecipe(owner, isPublic, "test-recipe"); - } - private String getAccessToken(User user) throws LoginException { - return this.authService.login(user.getUsername(), "test") + return this.authService.login(user.getUsername(), TEST_PASSWORD) .getAccessToken() .getToken(); } @@ -112,7 +113,7 @@ public class RecipeControllerTests { try (final InputStream hal9000 = getHal9000()) { return this.imageService.create( owner, - "HAL9000.svg", + UUID.randomUUID() + ".svg", hal9000, 27881L, new ImageCreateInfoSpec() @@ -123,15 +124,14 @@ public class RecipeControllerTests { } @Test - @DirtiesContext public void getRecipePageViewByIdPublicRecipeNoPrincipal() throws Exception { - final User owner = this.createTestUser("owner"); + final User owner = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner, true); this.mockMvc.perform( get("/recipes/{username}/{slug}", recipe.getOwner().getUsername(), recipe.getSlug()) ) .andExpect(status().isOk()) - .andExpect(jsonPath("$.recipe.id").value(1)) + .andExpect(jsonPath("$.recipe.id").value(recipe.getId())) .andExpect(jsonPath("$.recipe.created").exists()) // TODO: better matching of exact LocalDateTime .andExpect(jsonPath("$.recipe.modified").doesNotExist()) .andExpect(jsonPath("$.recipe.slug").value(recipe.getSlug())) @@ -152,9 +152,8 @@ public class RecipeControllerTests { } @Test - @DirtiesContext public void getFullRecipeViewIncludeRawText() throws Exception { - final User owner = this.createTestUser("owner"); + final User owner = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner, true); this.mockMvc.perform( get( @@ -168,9 +167,8 @@ public class RecipeControllerTests { } @Test - @DirtiesContext public void getFullRecipeViewPrincipalIsStarer() throws Exception { - final User owner = this.createTestUser("owner"); + final User owner = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner, false); this.recipeStarService.create(recipe.getId(), owner.getId()); final String accessToken = this.getAccessToken(owner); @@ -183,9 +181,8 @@ public class RecipeControllerTests { } @Test - @DirtiesContext public void getFullRecipeViewPrincipalIsNotStarer() throws Exception { - final User owner = this.createTestUser("owner"); + final User owner = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner, false); final String accessToken = this.getAccessToken(owner); this.mockMvc.perform( @@ -197,38 +194,23 @@ public class RecipeControllerTests { } @Test - @DirtiesContext public void getRecipeInfoViewsNoPrincipal() throws Exception { - final User owner = this.createTestUser("owner"); + final User owner = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner, true); this.mockMvc.perform(get("/recipes")) .andExpect(status().isOk()) .andExpect(jsonPath("$.slice.number").value(0)) .andExpect(jsonPath("$.slice.size").value(20)) .andExpect(jsonPath("$.content").isArray()) - .andExpect(jsonPath("$.content", hasSize(1))) - .andExpect(jsonPath("$.content[0].id").value(recipe.getId())) - .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].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.username").value(owner.getUsername())) - .andExpect(jsonPath("$.content[0].isPublic").value(true)) - .andExpect(jsonPath("$.content[0].starCount").value(0)) - .andExpect(jsonPath("$.content[0].mainImage").value(nullValue())); + .andExpect(jsonPath("$.content[*].id").value(hasItem(recipe.getId()))); } @Test - @DirtiesContext public void getRecipeInfoViewsWithPrincipalIncludesPrivate() throws Exception { - final User owner = this.createTestUser("owner"); - final Recipe r0 = this.createTestRecipe(owner, true, "r0"); - final Recipe r1 = this.createTestRecipe(owner, true, "r1"); - final Recipe r2 = this.createTestRecipe(owner, false, "r2"); + final User owner = this.seedUser(); + final Recipe r0 = this.createTestRecipe(owner, true); + final Recipe r1 = this.createTestRecipe(owner, true); + final Recipe r2 = this.createTestRecipe(owner, false); final LoginDetails loginDetails = this.authService.login(owner.getUsername(), "test"); this.mockMvc.perform( get("/recipes") @@ -238,7 +220,7 @@ public class RecipeControllerTests { .andExpect(jsonPath("$.slice.number").value(0)) .andExpect(jsonPath("$.slice.size").value(20)) .andExpect(jsonPath("$.content").isArray()) - .andExpect(jsonPath("$.content", hasSize(3))); + .andExpect(jsonPath("$.content[*].id").value(hasItems(r0.getId(), r1.getId(), r2.getId()))); } private String getUpdateBody() { @@ -253,9 +235,8 @@ public class RecipeControllerTests { } @Test - @DirtiesContext public void updateRecipe() throws Exception { - final User owner = this.createTestUser("owner"); + final User owner = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner, false); final String accessToken = this.getAccessToken(owner); final String body = this.getUpdateBody(); @@ -284,9 +265,8 @@ public class RecipeControllerTests { } @Test - @DirtiesContext public void updateRecipeReturnsViewWithMainImage() throws Exception { - final User owner = this.createTestUser("owner"); + final User owner = this.seedUser(); final Image hal9000 = this.createHal9000(owner); @@ -319,24 +299,22 @@ public class RecipeControllerTests { } @Test - @DirtiesContext public void addStarToRecipe() throws Exception { - final User owner = this.createTestUser("recipe-owner"); - final User starer = this.createTestUser("recipe-starer"); + final User owner = this.seedUser(); + final User starer = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner, true); this.mockMvc.perform( post("/recipes/{username}/{slug}/star", recipe.getOwner().getUsername(), recipe.getSlug()) .header("Authorization", "Bearer " + this.getAccessToken(starer)) ) .andExpect(status().isCreated()) - .andExpect(jsonPath("$.date").exists()); + .andExpect(jsonPath("$.timestamp").exists()); } @Test - @DirtiesContext public void getStarForRecipe() throws Exception { - final User owner = this.createTestUser("recipe-owner"); - final User starer = this.createTestUser("recipe-starer"); + final User owner = this.seedUser(); + final User starer = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner, true); this.recipeStarService.create(recipe.getId(), starer.getId()); this.mockMvc.perform( @@ -346,14 +324,13 @@ public class RecipeControllerTests { .andExpect(status().isOk()) .andExpect(jsonPath("$.isStarred").value(true)) .andExpect(jsonPath("$.star").isMap()) - .andExpect(jsonPath("$.star.date").exists()); + .andExpect(jsonPath("$.star.timestamp").exists()); } @Test - @DirtiesContext public void deleteStarFromRecipe() throws Exception { - final User owner = this.createTestUser("recipe-owner"); - final User starer = this.createTestUser("recipe-starer"); + final User owner = this.seedUser(); + final User starer = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner, true); this.recipeStarService.create(recipe.getId(), starer.getId()); this.mockMvc.perform( diff --git a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeRepositoryTests.java b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeRepositoryTests.java index b771eb2..00a6ee9 100644 --- a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeRepositoryTests.java +++ b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeRepositoryTests.java @@ -1,20 +1,23 @@ package app.mealsmadeeasy.api.recipe; +import app.mealsmadeeasy.api.IntegrationTestsExtension; import app.mealsmadeeasy.api.user.UserEntity; import app.mealsmadeeasy.api.user.UserRepository; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.DirtiesContext; import java.time.OffsetDateTime; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest +@ExtendWith(IntegrationTestsExtension.class) public class RecipeRepositoryTests { @Autowired @@ -23,65 +26,55 @@ public class RecipeRepositoryTests { @Autowired private UserRepository userRepository; - private UserEntity getOwnerUser() { - final UserEntity recipeUser = UserEntity.getDefaultDraft(); - recipeUser.setUsername("recipeUser"); - recipeUser.setEmail("recipe@user.com"); - recipeUser.setPassword("test"); - return this.userRepository.save(recipeUser); - } - - private UserEntity getViewerUser() { - final UserEntity viewerUser = UserEntity.getDefaultDraft(); - viewerUser.setUsername("recipeViewerUser"); - viewerUser.setEmail("recipe-viewer@user.com"); - viewerUser.setPassword("test"); - return this.userRepository.save(viewerUser); + private UserEntity seedUser() { + final String uuid = UUID.randomUUID().toString(); + final UserEntity draft = UserEntity.getDefaultDraft(); + draft.setUsername(uuid); + draft.setEmail(uuid + "@test.com"); + draft.setPassword("test"); + return this.userRepository.save(draft); } @Test - @DirtiesContext public void findsAllPublicRecipes() { final RecipeEntity publicRecipe = new RecipeEntity(); publicRecipe.setCreated(OffsetDateTime.now()); - publicRecipe.setSlug("public-recipe"); + publicRecipe.setSlug(UUID.randomUUID().toString()); publicRecipe.setPublic(true); - publicRecipe.setOwner(this.getOwnerUser()); + publicRecipe.setOwner(this.seedUser()); publicRecipe.setTitle("Public Recipe"); publicRecipe.setRawText("Hello, World!"); - this.recipeRepository.save(publicRecipe); + final RecipeEntity savedRecipe = this.recipeRepository.save(publicRecipe); final List publicRecipes = this.recipeRepository.findAllByIsPublicIsTrue(); - assertThat(publicRecipes.size()).isEqualTo(1); + assertThat(publicRecipes).anyMatch(recipeEntity -> recipeEntity.getId().equals(savedRecipe.getId())); } @Test - @DirtiesContext public void doesNotFindNonPublicRecipe() { final RecipeEntity nonPublicRecipe = new RecipeEntity(); nonPublicRecipe.setCreated(OffsetDateTime.now()); - nonPublicRecipe.setSlug("non-public-recipe"); - nonPublicRecipe.setOwner(this.getOwnerUser()); + nonPublicRecipe.setSlug(UUID.randomUUID().toString()); + nonPublicRecipe.setOwner(this.seedUser()); nonPublicRecipe.setTitle("Non-Public Recipe"); nonPublicRecipe.setRawText("Hello, World!"); - this.recipeRepository.save(nonPublicRecipe); + final RecipeEntity savedRecipe = this.recipeRepository.save(nonPublicRecipe); final List publicRecipes = this.recipeRepository.findAllByIsPublicIsTrue(); - assertThat(publicRecipes.size()).isEqualTo(0); + assertThat(publicRecipes).noneMatch(recipeEntity -> recipeEntity.getId().equals(savedRecipe.getId())); } @Test - @DirtiesContext public void findsAllForViewer() { final RecipeEntity recipe = new RecipeEntity(); recipe.setCreated(OffsetDateTime.now()); - recipe.setSlug("test-recipe"); - recipe.setOwner(this.getOwnerUser()); + recipe.setSlug(UUID.randomUUID().toString()); + recipe.setOwner(this.seedUser()); recipe.setTitle("Test Recipe"); recipe.setRawText("Hello, World!"); final RecipeEntity saved = this.recipeRepository.save(recipe); - final UserEntity viewer = this.getViewerUser(); + final UserEntity viewer = this.seedUser(); final Set viewers = new HashSet<>(recipe.getViewerEntities()); viewers.add(viewer); saved.setViewers(viewers); @@ -93,17 +86,16 @@ public class RecipeRepositoryTests { } @Test - @DirtiesContext public void doesNotIncludeNonViewable() { final RecipeEntity recipe = new RecipeEntity(); recipe.setCreated(OffsetDateTime.now()); - recipe.setSlug("test-recipe"); - recipe.setOwner(this.getOwnerUser()); + recipe.setSlug(UUID.randomUUID().toString()); + recipe.setOwner(this.seedUser()); recipe.setTitle("Test Recipe"); recipe.setRawText("Hello, World!"); this.recipeRepository.save(recipe); - final UserEntity viewer = this.getViewerUser(); + final UserEntity viewer = this.seedUser(); final List viewable = this.recipeRepository.findAllByViewersContaining(viewer); assertThat(viewable.size()).isEqualTo(0); } diff --git a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeServiceTests.java b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeServiceTests.java index ceb5f8b..d761d09 100644 --- a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeServiceTests.java +++ b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/RecipeServiceTests.java @@ -1,5 +1,6 @@ package app.mealsmadeeasy.api.recipe; +import app.mealsmadeeasy.api.IntegrationTestsExtension; import app.mealsmadeeasy.api.image.ImageException; import app.mealsmadeeasy.api.recipe.spec.RecipeCreateSpec; import app.mealsmadeeasy.api.recipe.spec.RecipeUpdateSpec; @@ -11,25 +12,28 @@ import app.mealsmadeeasy.api.user.UserEntity; import app.mealsmadeeasy.api.user.UserRepository; import org.jetbrains.annotations.Nullable; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.security.access.AccessDeniedException; -import org.springframework.test.annotation.DirtiesContext; import java.util.List; +import java.util.UUID; import static app.mealsmadeeasy.api.recipe.ContainsRecipeInfoViewsForRecipesMatcher.containsRecipeInfoViewsForRecipes; import static app.mealsmadeeasy.api.recipe.ContainsRecipesMatcher.containsRecipes; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; // TODO: test mainImage included // TODO: test prep/cooking/total times included @SpringBootTest +@ExtendWith(IntegrationTestsExtension.class) public class RecipeServiceTests { @Autowired @@ -41,25 +45,22 @@ public class RecipeServiceTests { @Autowired private UserRepository userRepository; - private UserEntity createTestUser(String username) { + private UserEntity seedUser() { + final String uuid = UUID.randomUUID().toString(); final UserEntity draft = UserEntity.getDefaultDraft(); - draft.setUsername(username); - draft.setEmail(username + "@test.com"); + draft.setUsername(uuid); + draft.setEmail(uuid + "@test.com"); draft.setPassword("test"); return this.userRepository.save(draft); } private Recipe createTestRecipe(@Nullable User owner) { - return this.createTestRecipe(owner, false, null); + return this.createTestRecipe(owner, false); } 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.setSlug(UUID.randomUUID().toString()); spec.setTitle("My Recipe"); spec.setRawText("Hello!"); spec.setPublic(isPublic); @@ -70,9 +71,8 @@ public class RecipeServiceTests { public void smokeScreen() {} @Test - @DirtiesContext public void create() { - final User user = this.createTestUser("recipeOwner"); + final User user = this.seedUser(); final Recipe recipe = this.createTestRecipe(user); assertThat(recipe.getOwner().getUsername(), is(user.getUsername())); assertThat(recipe.getTitle(), is("My Recipe")); @@ -80,23 +80,20 @@ public class RecipeServiceTests { } @Test - @DirtiesContext public void createWithoutOwnerThrowsAccessDenied() { assertThrows(AccessDeniedException.class, () -> this.recipeService.create(null, new RecipeCreateSpec())); } @Test - @DirtiesContext public void getByIdPublicNoViewerDoesNotThrow() { - final User owner = this.createTestUser("recipeOwner"); + final User owner = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner, true); assertDoesNotThrow(() -> this.recipeService.getById(recipe.getId(), null)); } @Test - @DirtiesContext public void getByIdHasCorrectProperties() throws RecipeException { - final User owner = this.createTestUser("recipeOwner"); + final User owner = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner, true); final Recipe byId = this.recipeService.getById(recipe.getId(), null); assertThat(byId.getId(), is(recipe.getId())); @@ -107,43 +104,38 @@ public class RecipeServiceTests { } @Test - @DirtiesContext public void getByIdThrowsWhenNotPublicAndNoViewer() { - final User owner = this.createTestUser("recipeOwner"); + final User owner = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner, false); // not public assertThrows(AccessDeniedException.class, () -> this.recipeService.getById(recipe.getId(), null)); } @Test - @DirtiesContext public void getByIdThrowsWhenNotViewer() { - final User owner = this.createTestUser("recipeOwner"); - final User notViewer = this.createTestUser("notViewer"); + final User owner = this.seedUser(); + final User notViewer = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner); assertThrows(AccessDeniedException.class, () -> this.recipeService.getById(recipe.getId(), notViewer)); } @Test - @DirtiesContext public void getByIdOkayWhenPublicAndNoViewer() { - final User owner = this.createTestUser("recipeOwner"); + final User owner = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner, true); assertDoesNotThrow(() -> this.recipeService.getById(recipe.getId(), null)); } @Test - @DirtiesContext public void getByIdOkayWhenPublicRecipeWithViewer() { - final User owner = this.createTestUser("recipeOwner"); - final User viewer = this.createTestUser("viewer"); + final User owner = this.seedUser(); + final User viewer = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner, true); assertDoesNotThrow(() -> this.recipeService.getById(recipe.getId(), viewer)); } @Test - @DirtiesContext public void getByIdOkayWithStarsPublicAndNoViewer() { - final User owner = this.createTestUser("recipeOwner"); + final User owner = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner, true); final RecipeStar star = this.recipeStarService.create(recipe.getId(), owner.getId()); final Recipe byIdWithStars = assertDoesNotThrow(() -> this.recipeService.getByIdWithStars( @@ -153,19 +145,17 @@ public class RecipeServiceTests { } @Test - @DirtiesContext public void getByIdOkayWithStarsThrowsWhenNotViewer() { - final User owner = this.createTestUser("recipeOwner"); - final User notViewer = this.createTestUser("notViewer"); + final User owner = this.seedUser(); + final User notViewer = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner); assertThrows(AccessDeniedException.class, () -> this.recipeService.getByIdWithStars(recipe.getId(), notViewer)); } @Test - @DirtiesContext public void getByIdWithStarsOkayWhenPublicRecipeWithViewer() throws RecipeException, ImageException { - final User owner = this.createTestUser("recipeOwner"); - final User viewer = this.createTestUser("viewer"); + final User owner = this.seedUser(); + final User viewer = this.seedUser(); final Recipe notYetPublicRecipe = this.createTestRecipe(owner); final RecipeUpdateSpec updateSpec = new RecipeUpdateSpec(notYetPublicRecipe); updateSpec.setIsPublic(true); @@ -179,15 +169,14 @@ public class RecipeServiceTests { } @Test - @DirtiesContext public void getByMinimumStarsAllPublic() { - final User owner = this.createTestUser("recipeOwner"); - final User u0 = this.createTestUser("u0"); - final User u1 = this.createTestUser("u1"); + final User owner = this.seedUser(); + final User u0 = this.seedUser(); + final User u1 = this.seedUser(); - final Recipe r0 = this.createTestRecipe(owner, true, "r0"); - final Recipe r1 = this.createTestRecipe(owner, true, "r1"); - final Recipe r2 = this.createTestRecipe(owner, true, "r2"); + final Recipe r0 = this.createTestRecipe(owner, true); + final Recipe r1 = this.createTestRecipe(owner, true); + final Recipe r2 = this.createTestRecipe(owner, true); // r0.stars = 0, r1.stars = 1, r2.stars = 2 this.recipeStarService.create(r1.getId(), u0.getId()); @@ -198,26 +187,21 @@ public class RecipeServiceTests { final List oneStar = this.recipeService.getByMinimumStars(1, null); final List twoStars = this.recipeService.getByMinimumStars(2, null); - assertThat(zeroStars.size(), is(3)); - assertThat(oneStar.size(), is(2)); - assertThat(twoStars.size(), is(1)); - assertThat(zeroStars, containsRecipes(r0, r1, r2)); assertThat(oneStar, containsRecipes(r1, r2)); assertThat(twoStars, containsRecipes(r2)); } @Test - @DirtiesContext public void getByMinimumStarsOnlySomeViewable() throws RecipeException { - final User owner = this.createTestUser("recipeOwner"); - final User u0 = this.createTestUser("u0"); - final User u1 = this.createTestUser("u1"); - final User viewer = this.createTestUser("recipeViewer"); + final User owner = this.seedUser(); + final User u0 = this.seedUser(); + final User u1 = this.seedUser(); + final User viewer = this.seedUser(); - Recipe r0 = this.createTestRecipe(owner, false, "r0"); // not public - Recipe r1 = this.createTestRecipe(owner, false, "r1"); - Recipe r2 = this.createTestRecipe(owner, false, "r2"); + Recipe r0 = this.createTestRecipe(owner, false); // not public + Recipe r1 = this.createTestRecipe(owner, false); + Recipe r2 = this.createTestRecipe(owner, false); for (final User starer : List.of(u0, u1)) { r0 = this.recipeService.addViewer(r0.getId(), owner, starer); @@ -234,9 +218,9 @@ public class RecipeServiceTests { final List oneStarNoneViewable = this.recipeService.getByMinimumStars(1, viewer); final List twoStarsNoneViewable = this.recipeService.getByMinimumStars(2, viewer); - assertThat(zeroStarsNoneViewable.size(), is(0)); - assertThat(oneStarNoneViewable.size(), is(0)); - assertThat(twoStarsNoneViewable.size(), is(0)); + assertThat(zeroStarsNoneViewable, not(containsRecipes(r0, r1, r2))); + assertThat(oneStarNoneViewable, not(containsRecipes(r1, r2))); + assertThat(twoStarsNoneViewable, not(containsRecipes(r2))); // Now make them viewable r0 = this.recipeService.addViewer(r0.getId(), owner, viewer); @@ -247,49 +231,40 @@ public class RecipeServiceTests { final List oneStarViewable = this.recipeService.getByMinimumStars(1, viewer); final List twoStarsViewable = this.recipeService.getByMinimumStars(2, viewer); - assertThat(zeroStarsViewable.size(), is(3)); - assertThat(oneStarViewable.size(), is(2)); - assertThat(twoStarsViewable.size(), is (1)); - assertThat(zeroStarsViewable, containsRecipes(r0, r1, r2)); assertThat(oneStarViewable, containsRecipes(r1, r2)); assertThat(twoStarsViewable, containsRecipes(r2)); } @Test - @DirtiesContext public void getPublicRecipes() { - final User owner = this.createTestUser("recipeOwner"); + final User owner = this.seedUser(); - Recipe r0 = this.createTestRecipe(owner, true, "r0"); - Recipe r1 = this.createTestRecipe(owner, true, "r1"); + Recipe r0 = this.createTestRecipe(owner, true); + Recipe r1 = this.createTestRecipe(owner, true); final List publicRecipes = this.recipeService.getPublicRecipes(); - assertThat(publicRecipes.size(), is(2)); assertThat(publicRecipes, containsRecipes(r0, r1)); } @Test - @DirtiesContext public void getRecipeInfoViewsViewableByOwnerWhenPublicAndPrivate() { - final User owner = this.createTestUser("recipeOwner"); - Recipe r0 = this.createTestRecipe(owner, true, "r0"); - Recipe r1 = this.createTestRecipe(owner, false, "r1"); + final User owner = this.seedUser(); + Recipe r0 = this.createTestRecipe(owner, true); + Recipe r1 = this.createTestRecipe(owner, false); final Slice viewableInfoViewsSlice = this.recipeService.getInfoViewsViewableBy( Pageable.ofSize(20), owner ); final List viewableInfos = viewableInfoViewsSlice.getContent(); - assertThat(viewableInfos.size(), is(2)); assertThat(viewableInfos, containsRecipeInfoViewsForRecipes(r0, r1)); } @Test - @DirtiesContext public void getRecipesViewableByUser() throws RecipeException { - final User owner = this.createTestUser("recipeOwner"); - final User viewer = this.createTestUser("recipeViewer"); + final User owner = this.seedUser(); + final User viewer = this.seedUser(); Recipe r0 = this.createTestRecipe(owner); r0 = this.recipeService.addViewer(r0.getId(), owner, viewer); @@ -299,9 +274,8 @@ public class RecipeServiceTests { } @Test - @DirtiesContext public void getRecipesOwnedByUser() { - final User owner = this.createTestUser("recipeOwner"); + final User owner = this.seedUser(); final Recipe r0 = this.createTestRecipe(owner); final List ownedRecipes = this.recipeService.getRecipesOwnedBy(owner); assertThat(ownedRecipes.size(), is(1)); @@ -309,9 +283,8 @@ public class RecipeServiceTests { } @Test - @DirtiesContext public void updateRawText() throws RecipeException, ImageException { - final User owner = this.createTestUser("recipeOwner"); + final User owner = this.seedUser(); final RecipeCreateSpec createSpec = new RecipeCreateSpec(); createSpec.setSlug("my-recipe"); createSpec.setTitle("My Recipe"); @@ -330,10 +303,9 @@ public class RecipeServiceTests { } @Test - @DirtiesContext public void updateRawTextThrowsIfNotOwner() { - final User owner = this.createTestUser("recipeOwner"); - final User notOwner = this.createTestUser("notOwner"); + final User owner = this.seedUser(); + final User notOwner = this.seedUser(); final Recipe recipe = this.createTestRecipe(owner); final RecipeUpdateSpec updateSpec = new RecipeUpdateSpec(); updateSpec.setRawText("should fail"); @@ -349,19 +321,17 @@ public class RecipeServiceTests { } @Test - @DirtiesContext public void deleteRecipe() { - final User owner = this.createTestUser("recipeOwner"); + final User owner = this.seedUser(); final Recipe toDelete = this.createTestRecipe(owner); this.recipeService.deleteRecipe(toDelete.getId(), owner); assertThrows(RecipeException.class, () -> this.recipeService.getById(toDelete.getId(), owner)); } @Test - @DirtiesContext public void deleteRecipeThrowsIfNotOwner() { - final User owner = this.createTestUser("recipeOwner"); - final User notOwner = this.createTestUser("notOwner"); + final User owner = this.seedUser(); + final User notOwner = this.seedUser(); final Recipe toDelete = this.createTestRecipe(owner); assertThrows(AccessDeniedException.class, () -> this.recipeService.deleteRecipe(toDelete.getId(), notOwner)); } diff --git a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/star/RecipeStarRepositoryTests.java b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/star/RecipeStarRepositoryTests.java index 938c5df..3ea19bf 100644 --- a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/star/RecipeStarRepositoryTests.java +++ b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/star/RecipeStarRepositoryTests.java @@ -1,20 +1,23 @@ package app.mealsmadeeasy.api.recipe.star; +import app.mealsmadeeasy.api.IntegrationTestsExtension; import app.mealsmadeeasy.api.recipe.RecipeEntity; import app.mealsmadeeasy.api.recipe.RecipeRepository; import app.mealsmadeeasy.api.user.UserEntity; import app.mealsmadeeasy.api.user.UserRepository; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.DirtiesContext; import java.time.OffsetDateTime; +import java.util.UUID; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @SpringBootTest +@ExtendWith(IntegrationTestsExtension.class) public class RecipeStarRepositoryTests { @Autowired @@ -26,10 +29,11 @@ public class RecipeStarRepositoryTests { @Autowired private UserRepository userRepository; - private UserEntity getOwnerUser() { + private UserEntity seedUser() { final UserEntity draft = UserEntity.getDefaultDraft(); - draft.setUsername("test-user"); - draft.setEmail("test-user@test.com"); + final String uuid = UUID.randomUUID().toString(); + draft.setUsername(uuid); + draft.setEmail(uuid + "@test.com"); draft.setPassword("test"); return this.userRepository.save(draft); } @@ -37,7 +41,7 @@ public class RecipeStarRepositoryTests { private RecipeEntity getTestRecipe(UserEntity owner) { final RecipeEntity recipeDraft = new RecipeEntity(); recipeDraft.setCreated(OffsetDateTime.now()); - recipeDraft.setSlug("test-recipe"); + recipeDraft.setSlug(UUID.randomUUID().toString()); recipeDraft.setOwner(owner); recipeDraft.setTitle("Test Recipe"); recipeDraft.setRawText("Hello, World!"); @@ -45,9 +49,8 @@ public class RecipeStarRepositoryTests { } @Test - @DirtiesContext public void returnsTrueIfStarer() { - final UserEntity owner = this.getOwnerUser(); + final UserEntity owner = this.seedUser(); final RecipeEntity recipe = this.getTestRecipe(owner); final RecipeStarEntity starDraft = new RecipeStarEntity(); @@ -68,9 +71,8 @@ public class RecipeStarRepositoryTests { } @Test - @DirtiesContext public void returnsFalseIfNotStarer() { - final UserEntity owner = this.getOwnerUser(); + final UserEntity owner = this.seedUser(); final RecipeEntity recipe = this.getTestRecipe(owner); assertThat( this.recipeStarRepository.isStarer( diff --git a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/star/RecipeStarServiceTests.java b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/star/RecipeStarServiceTests.java index 26b4d2f..e6f67f5 100644 --- a/src/integrationTest/java/app/mealsmadeeasy/api/recipe/star/RecipeStarServiceTests.java +++ b/src/integrationTest/java/app/mealsmadeeasy/api/recipe/star/RecipeStarServiceTests.java @@ -1,5 +1,6 @@ package app.mealsmadeeasy.api.recipe.star; +import app.mealsmadeeasy.api.IntegrationTestsExtension; import app.mealsmadeeasy.api.recipe.Recipe; import app.mealsmadeeasy.api.recipe.RecipeException; import app.mealsmadeeasy.api.recipe.RecipeService; @@ -9,9 +10,11 @@ import app.mealsmadeeasy.api.user.UserCreateException; import app.mealsmadeeasy.api.user.UserService; import org.jetbrains.annotations.Nullable; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.DirtiesContext; + +import java.util.UUID; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; @@ -19,6 +22,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; @SpringBootTest +@ExtendWith(IntegrationTestsExtension.class) public class RecipeStarServiceTests { @Autowired @@ -30,56 +34,56 @@ public class RecipeStarServiceTests { @Autowired private RecipeService recipeService; - private User getTestUser(String username) { + private User seedUser() { + final String uuid = UUID.randomUUID().toString(); try { - return this.userService.createUser(username, username + "@test.com", "test"); + return this.userService.createUser(uuid, uuid + "@test.com", "test"); } catch (UserCreateException e) { throw new RuntimeException(e); } } - private Recipe getTestRecipe(User owner, String slug, boolean isPublic) { + private Recipe seedRecipe(User owner) { final RecipeCreateSpec spec = new RecipeCreateSpec(); - spec.setSlug(slug); + spec.setSlug(UUID.randomUUID().toString()); spec.setTitle("Test Recipe"); spec.setRawText("My great recipe has five ingredients."); - spec.setPublic(isPublic); + spec.setPublic(true); return this.recipeService.create(owner, spec); } @Test - @DirtiesContext public void createViaUsernameAndSlug() { - final User owner = this.getTestUser("recipe-owner"); - final User starer = this.getTestUser("recipe-starer"); - final Recipe recipe = this.getTestRecipe(owner, "test-recipe", true); + final User owner = this.seedUser(); + final User starer = this.seedUser(); + final Recipe recipe = this.seedRecipe(owner); final RecipeStar star = assertDoesNotThrow(() -> this.recipeStarService.create( recipe.getOwner().getUsername(), recipe.getSlug(), starer )); + //noinspection DataFlowIssue assertThat(star.getTimestamp(), is(notNullValue())); } @Test - @DirtiesContext public void createViaId() { - final User owner = this.getTestUser("recipe-owner"); - final User starer = this.getTestUser("recipe-starer"); - final Recipe recipe = this.getTestRecipe(owner, "test-recipe", true); + final User owner = this.seedUser(); + final User starer = this.seedUser(); + final Recipe recipe = this.seedRecipe(owner); final RecipeStar star = assertDoesNotThrow(() -> this.recipeStarService.create( recipe.getId(), starer.getId() )); + //noinspection DataFlowIssue assertThat(star.getTimestamp(), is(notNullValue())); } @Test - @DirtiesContext public void find() throws RecipeException { - final User owner = this.getTestUser("recipe-owner"); - final User starer = this.getTestUser("recipe-starer"); - final Recipe recipe = this.getTestRecipe(owner, "test-recipe", true); + final User owner = this.seedUser(); + final User starer = this.seedUser(); + final Recipe recipe = this.seedRecipe(owner); this.recipeStarService.create(recipe.getId(), starer.getId()); final @Nullable RecipeStar star = this.recipeStarService.find( recipe.getOwner().getUsername(), @@ -90,11 +94,10 @@ public class RecipeStarServiceTests { } @Test - @DirtiesContext public void deleteViaUsernameAndSlug() { - final User owner = this.getTestUser("recipe-owner"); - final User starer = this.getTestUser("recipe-starer"); - final Recipe recipe = this.getTestRecipe(owner, "test-recipe", true); + final User owner = this.seedUser(); + final User starer = this.seedUser(); + final Recipe recipe = this.seedRecipe(owner); this.recipeStarService.create(recipe.getId(), starer.getId()); assertDoesNotThrow(() -> this.recipeStarService.delete( recipe.getOwner().getUsername(), diff --git a/src/integrationTest/java/app/mealsmadeeasy/api/signup/SignUpControllerTests.java b/src/integrationTest/java/app/mealsmadeeasy/api/signup/SignUpControllerTests.java index 8a52a84..65c9a1f 100644 --- a/src/integrationTest/java/app/mealsmadeeasy/api/signup/SignUpControllerTests.java +++ b/src/integrationTest/java/app/mealsmadeeasy/api/signup/SignUpControllerTests.java @@ -1,19 +1,21 @@ package app.mealsmadeeasy.api.signup; +import app.mealsmadeeasy.api.IntegrationTestsExtension; import app.mealsmadeeasy.api.user.UserCreateException.Type; import app.mealsmadeeasy.api.user.UserService; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.http.MediaType; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import tools.jackson.databind.ObjectMapper; import java.util.Map; +import java.util.UUID; import static org.hamcrest.Matchers.containsString; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -22,6 +24,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @SpringBootTest @AutoConfigureMockMvc +@ExtendWith(IntegrationTestsExtension.class) public class SignUpControllerTests { @Autowired @@ -41,18 +44,18 @@ public class SignUpControllerTests { } @Test - @DirtiesContext public void checkUsernameExpectAvailable() throws Exception { - this.mockMvc.perform(this.getCheckUsernameRequest("isAvailable")) + final String username = UUID.randomUUID().toString(); + this.mockMvc.perform(this.getCheckUsernameRequest(username)) .andExpect(status().isOk()) .andExpect(jsonPath("$.isAvailable").value(true)); } @Test - @DirtiesContext public void checkUsernameExpectNotAvailable() throws Exception { - this.userService.createUser("notAvailable", "not-available@notavailable.com", "test"); - this.mockMvc.perform(this.getCheckUsernameRequest("notAvailable")) + final String username = UUID.randomUUID().toString(); + this.userService.createUser(username, username + "@notavailable.com", "test"); + this.mockMvc.perform(this.getCheckUsernameRequest(username)) .andExpect(status().isOk()) .andExpect(jsonPath("$.isAvailable").value(false)); } @@ -66,44 +69,43 @@ public class SignUpControllerTests { } @Test - @DirtiesContext public void checkEmailExpectAvailable() throws Exception { - this.mockMvc.perform(this.getCheckEmailRequest("available@available.com")) + this.mockMvc.perform(this.getCheckEmailRequest(UUID.randomUUID() + "@available.com")) .andExpect(status().isOk()) .andExpect(jsonPath("$.isAvailable").value(true)); } @Test - @DirtiesContext public void checkEmailExpectNotAvailable() throws Exception { - this.userService.createUser("notAvailable", "not-available@notavailable.com", "test"); - this.mockMvc.perform(this.getCheckEmailRequest("not-available@notavailable.com")) + final String notAvailable = UUID.randomUUID().toString(); + this.userService.createUser(notAvailable, notAvailable + "@notavailable.com", "test"); + this.mockMvc.perform(this.getCheckEmailRequest(notAvailable + "@notavailable.com")) .andExpect(status().isOk()) .andExpect(jsonPath("$.isAvailable").value(false)); } @Test - @DirtiesContext public void simpleSignUp() throws Exception { final SignUpBody body = new SignUpBody(); - body.setUsername("newUser"); - body.setEmail("new@user.com"); + final String username = UUID.randomUUID().toString(); + body.setUsername(username); + body.setEmail(username + "@user.com"); body.setPassword("test"); final MockHttpServletRequestBuilder req = post("/sign-up") .content(this.objectMapper.writeValueAsString(body)) .contentType(MediaType.APPLICATION_JSON); this.mockMvc.perform(req) .andExpect(status().isCreated()) - .andExpect(jsonPath("$.username").value("newUser")); + .andExpect(jsonPath("$.username").value(username)); } @Test - @DirtiesContext public void signUpBadRequestWhenUsernameTaken() throws Exception { - this.userService.createUser("taken", "taken@taken.com", "test"); + final String takenUsername = UUID.randomUUID().toString(); + this.userService.createUser(takenUsername, takenUsername + "@taken.com", "test"); final SignUpBody body = new SignUpBody(); - body.setUsername("taken"); - body.setEmail("not-taken@taken.com"); // n.b. + body.setUsername(takenUsername); + body.setEmail(UUID.randomUUID() + "@taken.com"); // n.b.: not taken email body.setPassword("test"); final MockHttpServletRequestBuilder req = post("/sign-up") .content(this.objectMapper.writeValueAsString(body)) @@ -111,16 +113,16 @@ public class SignUpControllerTests { this.mockMvc.perform(req) .andExpect(status().isBadRequest()) .andExpect(jsonPath("$.error.type").value(Type.USERNAME_TAKEN.toString())) - .andExpect(jsonPath("$.error.message").value(containsString("taken"))); + .andExpect(jsonPath("$.error.message").value(containsString(takenUsername))); } @Test - @DirtiesContext public void signUpBadRequestWhenEmailTaken() throws Exception { - this.userService.createUser("taken", "taken@taken.com", "test"); + final String takenEmail = UUID.randomUUID() + "@taken.com"; + this.userService.createUser(UUID.randomUUID().toString(), takenEmail, "test"); final SignUpBody body = new SignUpBody(); - body.setUsername("notTaken"); // n.b. - body.setEmail("taken@taken.com"); + body.setUsername(UUID.randomUUID().toString()); // n.b.: random username + body.setEmail(takenEmail); body.setPassword("test"); final MockHttpServletRequestBuilder req = post("/sign-up") .content(this.objectMapper.writeValueAsString(body)) @@ -128,7 +130,7 @@ public class SignUpControllerTests { this.mockMvc.perform(req) .andExpect(status().isBadRequest()) .andExpect(jsonPath("$.error.type").value(Type.EMAIL_TAKEN.toString())) - .andExpect(jsonPath("$.error.message").value(containsString("taken@taken.com"))); + .andExpect(jsonPath("$.error.message").value(containsString(takenEmail))); } } diff --git a/src/integrationTest/resources/application.properties b/src/integrationTest/resources/application.properties index e26398a..64e0fc8 100644 --- a/src/integrationTest/resources/application.properties +++ b/src/integrationTest/resources/application.properties @@ -4,4 +4,9 @@ app.mealsmadeeasy.api.security.refresh-token-lifetime=120 app.mealsmadeeasy.api.minio.endpoint=http://localhost:9000 app.mealsmadeeasy.api.minio.accessKey=minio-root app.mealsmadeeasy.api.minio.secretKey=test0123 -app.mealsmadeeasy.api.images.bucketName=images \ No newline at end of file +app.mealsmadeeasy.api.images.bucketName=images + +# Source - https://stackoverflow.com/questions/3164072/large-objects-may-not-be-used-in-auto-commit-mode +# Posted by Iogui, modified by community. See post 'Timeline' for change history +# Retrieved 2025-12-25, License - CC BY-SA 4.0 +spring.datasource.hikari.auto-commit=false