Fix app smokescreen and ImageController integration tests for use with Postgres.
This commit is contained in:
parent
b9e7ccedce
commit
2642f6100e
@ -83,10 +83,10 @@ dependencies {
|
|||||||
runtimeOnly 'org.apache.xmlgraphics:batik-all:1.19'
|
runtimeOnly 'org.apache.xmlgraphics:batik-all:1.19'
|
||||||
|
|
||||||
// Custom testing
|
// Custom testing
|
||||||
testRuntimeOnly 'com.h2database:h2'
|
|
||||||
testImplementation 'org.testcontainers:testcontainers:1.21.4'
|
testImplementation 'org.testcontainers:testcontainers:1.21.4'
|
||||||
testImplementation 'org.testcontainers:junit-jupiter:1.21.4'
|
testImplementation 'org.testcontainers:junit-jupiter:1.21.4'
|
||||||
testImplementation "org.testcontainers:minio:1.21.4"
|
testImplementation 'org.testcontainers:postgresql:1.21.4'
|
||||||
|
testImplementation 'org.testcontainers:minio:1.21.4'
|
||||||
|
|
||||||
testFixturesImplementation 'org.hamcrest:hamcrest:3.0'
|
testFixturesImplementation 'org.hamcrest:hamcrest:3.0'
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,19 @@
|
|||||||
|
package app.mealsmadeeasy.api;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.extension.BeforeAllCallback;
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||||
|
import org.testcontainers.containers.PostgreSQLContainer;
|
||||||
|
|
||||||
|
public class IntegrationTestsExtension implements BeforeAllCallback {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeAll(ExtensionContext context) {
|
||||||
|
final PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("pgvector/pgvector:pg18-trixie")
|
||||||
|
.withDatabaseName("meals_made_easy_api");
|
||||||
|
postgres.start();
|
||||||
|
System.setProperty("spring.datasource.url", postgres.getJdbcUrl());
|
||||||
|
System.setProperty("spring.datasource.username", postgres.getUsername());
|
||||||
|
System.setProperty("spring.datasource.password", postgres.getPassword());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,12 +1,14 @@
|
|||||||
package app.mealsmadeeasy.api;
|
package app.mealsmadeeasy.api;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
class MealsMadeEasyApiApplicationTests {
|
@ExtendWith(IntegrationTestsExtension.class)
|
||||||
|
public class MealsMadeEasyApiApplicationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void contextLoads() {}
|
public void contextLoads() {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package app.mealsmadeeasy.api.image;
|
package app.mealsmadeeasy.api.image;
|
||||||
|
|
||||||
|
import app.mealsmadeeasy.api.IntegrationTestsExtension;
|
||||||
import app.mealsmadeeasy.api.auth.AuthService;
|
import app.mealsmadeeasy.api.auth.AuthService;
|
||||||
import app.mealsmadeeasy.api.auth.LoginException;
|
import app.mealsmadeeasy.api.auth.LoginException;
|
||||||
import app.mealsmadeeasy.api.image.body.ImageUpdateInfoBody;
|
import app.mealsmadeeasy.api.image.body.ImageUpdateInfoBody;
|
||||||
@ -9,12 +10,12 @@ import app.mealsmadeeasy.api.user.User;
|
|||||||
import app.mealsmadeeasy.api.user.UserCreateException;
|
import app.mealsmadeeasy.api.user.UserCreateException;
|
||||||
import app.mealsmadeeasy.api.user.UserService;
|
import app.mealsmadeeasy.api.user.UserService;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
|
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.test.annotation.DirtiesContext;
|
|
||||||
import org.springframework.test.context.DynamicPropertyRegistry;
|
import org.springframework.test.context.DynamicPropertyRegistry;
|
||||||
import org.springframework.test.context.DynamicPropertySource;
|
import org.springframework.test.context.DynamicPropertySource;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
@ -27,7 +28,7 @@ import tools.jackson.databind.ObjectMapper;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.*;
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
@ -38,10 +39,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
@Testcontainers
|
@Testcontainers
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
@AutoConfigureMockMvc
|
@AutoConfigureMockMvc
|
||||||
|
@ExtendWith(IntegrationTestsExtension.class)
|
||||||
public class ImageControllerTests {
|
public class ImageControllerTests {
|
||||||
|
|
||||||
private static final String USER_FILENAME = "HAL9000.svg";
|
|
||||||
|
|
||||||
@Container
|
@Container
|
||||||
private static final MinIOContainer container = new MinIOContainer(
|
private static final MinIOContainer container = new MinIOContainer(
|
||||||
DockerImageName.parse("minio/minio:latest")
|
DockerImageName.parse("minio/minio:latest")
|
||||||
@ -54,7 +54,7 @@ public class ImageControllerTests {
|
|||||||
registry.add("app.mealsmadeeasy.api.minio.secretKey", container::getPassword);
|
registry.add("app.mealsmadeeasy.api.minio.secretKey", container::getPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InputStream getHal9000() {
|
private static InputStream getHal9000InputStream() {
|
||||||
return ImageControllerTests.class.getResourceAsStream("HAL9000.svg");
|
return ImageControllerTests.class.getResourceAsStream("HAL9000.svg");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,65 +73,73 @@ public class ImageControllerTests {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ObjectMapper objectMapper;
|
private ObjectMapper objectMapper;
|
||||||
|
|
||||||
private User createTestUser(String username) {
|
private static final String TEST_PASSWORD = "test";
|
||||||
|
private static final long HAL_SIZE = 27881L;
|
||||||
|
|
||||||
|
private static String makeUserFilename() {
|
||||||
|
return UUID.randomUUID() + ".svg";
|
||||||
|
}
|
||||||
|
|
||||||
|
private User seedUser() {
|
||||||
|
final String uuid = UUID.randomUUID().toString();
|
||||||
try {
|
try {
|
||||||
return this.userService.createUser(username, username + "@test.com", "test");
|
return this.userService.createUser(uuid, uuid + "@test.com", TEST_PASSWORD);
|
||||||
} catch (UserCreateException e) {
|
} catch (UserCreateException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Image createHal9000(User owner) throws ImageException, IOException {
|
private Image seedImage(User owner, ImageCreateInfoSpec spec) {
|
||||||
try (final InputStream hal9000 = getHal9000()) {
|
try {
|
||||||
return this.imageService.create(
|
return this.imageService.create(
|
||||||
owner,
|
owner,
|
||||||
USER_FILENAME,
|
makeUserFilename(),
|
||||||
hal9000,
|
getHal9000InputStream(),
|
||||||
27881L,
|
HAL_SIZE,
|
||||||
new ImageCreateInfoSpec()
|
spec
|
||||||
);
|
);
|
||||||
|
} catch (IOException | ImageException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getAccessToken(String username) {
|
private Image seedImage(User owner) {
|
||||||
|
return this.seedImage(owner, new ImageCreateInfoSpec());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getImageUrl(User owner, Image image) {
|
||||||
|
return "/images/" + owner.getUsername() + "/" + image.getUserFilename();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getAccessToken(User user) {
|
||||||
try {
|
try {
|
||||||
return this.authService.login(username, "test").getAccessToken().getToken();
|
return this.authService.login(user.getUsername(), TEST_PASSWORD).getAccessToken().getToken();
|
||||||
} catch (LoginException e) {
|
} catch (LoginException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Image makePublic(Image image, User modifier) {
|
|
||||||
final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec();
|
|
||||||
spec.setPublic(true);
|
|
||||||
return this.imageService.update(image, modifier, spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Image addViewer(Image image, User modifier, User viewerToAdd) {
|
|
||||||
final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec();
|
|
||||||
spec.setViewersToAdd(Set.of(viewerToAdd));
|
|
||||||
return this.imageService.update(image, modifier, spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
public void getPublicImageNoPrincipal() throws Exception {
|
||||||
public void getImageNoPrincipal() throws Exception {
|
final User owner = this.seedUser();
|
||||||
final User owner = this.createTestUser("imageOwner");
|
final ImageCreateInfoSpec spec = new ImageCreateInfoSpec();
|
||||||
final Image image = this.createHal9000(owner);
|
spec.setPublic(true);
|
||||||
this.makePublic(image, owner);
|
final Image image = this.seedImage(owner, spec);
|
||||||
try (final InputStream hal9000 = getHal9000()) {
|
|
||||||
|
// Assert bytes the same and proper mime type
|
||||||
|
try (final InputStream hal9000 = getHal9000InputStream()) {
|
||||||
final byte[] halBytes = hal9000.readAllBytes();
|
final byte[] halBytes = hal9000.readAllBytes();
|
||||||
this.mockMvc.perform(get("/images/imageOwner/HAL9000.svg"))
|
this.mockMvc.perform(get(getImageUrl(owner, image)))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType("image/svg+xml"))
|
.andExpect(content().contentType("image/svg+xml"))
|
||||||
.andExpect(content().bytes(halBytes));
|
.andExpect(content().bytes(halBytes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doGetImageTestWithViewer(String accessToken) throws Exception {
|
private void doGetImageTestWithAccessToken(User owner, Image image, String accessToken) throws Exception {
|
||||||
try (final InputStream hal9000 = getHal9000()) {
|
try (final InputStream hal9000 = getHal9000InputStream()) {
|
||||||
final byte[] halBytes = hal9000.readAllBytes();
|
final byte[] halBytes = hal9000.readAllBytes();
|
||||||
this.mockMvc.perform(get("/images/imageOwner/HAL9000.svg")
|
this.mockMvc.perform(get(getImageUrl(owner, image))
|
||||||
.header("Authorization", "Bearer " + accessToken))
|
.header("Authorization", "Bearer " + accessToken))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType("image/svg+xml"))
|
.andExpect(content().contentType("image/svg+xml"))
|
||||||
@ -140,88 +148,73 @@ public class ImageControllerTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
public void getImageForOwner() throws Exception {
|
||||||
public void getImageWithOwner() throws Exception {
|
final User owner = this.seedUser();
|
||||||
final User owner = this.createTestUser("imageOwner");
|
final Image image = this.seedImage(owner);
|
||||||
this.createHal9000(owner);
|
this.doGetImageTestWithAccessToken(owner, image, this.getAccessToken(owner));
|
||||||
final String accessToken = this.getAccessToken(owner.getUsername());
|
|
||||||
this.doGetImageTestWithViewer(accessToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
public void getImageForViewer() throws Exception {
|
||||||
public void getImageWithViewer() throws Exception {
|
final User owner = this.seedUser();
|
||||||
final User owner = this.createTestUser("imageOwner");
|
final User viewer = this.seedUser();
|
||||||
final User viewer = this.createTestUser("viewer");
|
final Image image = this.seedImage(owner);
|
||||||
final Image image = this.createHal9000(owner);
|
|
||||||
this.addViewer(image, owner, viewer);
|
// add viewer
|
||||||
final String accessToken = this.getAccessToken(viewer.getUsername());
|
final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec();
|
||||||
this.doGetImageTestWithViewer(accessToken);
|
spec.setViewersToAdd(Set.of(viewer));
|
||||||
|
this.imageService.update(image, owner, spec);
|
||||||
|
|
||||||
|
this.doGetImageTestWithAccessToken(owner, image, this.getAccessToken(viewer));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
|
||||||
public void getNonPublicImageNoPrincipalForbidden() throws Exception {
|
public void getNonPublicImageNoPrincipalForbidden() throws Exception {
|
||||||
final User owner = this.createTestUser("imageOwner");
|
final User owner = this.seedUser();
|
||||||
this.createHal9000(owner);
|
final Image image = this.seedImage(owner);
|
||||||
this.mockMvc.perform(
|
this.mockMvc.perform(get(getImageUrl(owner, image)))
|
||||||
get("/images/imageOwner/HAL9000.svg")
|
.andExpect(status().isForbidden());
|
||||||
).andExpect(status().isForbidden());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
|
||||||
public void getNonPublicImageWithPrincipalForbidden() throws Exception {
|
public void getNonPublicImageWithPrincipalForbidden() throws Exception {
|
||||||
final User owner = this.createTestUser("imageOwner");
|
final User owner = this.seedUser();
|
||||||
final User viewer = this.createTestUser("viewer");
|
final Image image = this.seedImage(owner);
|
||||||
this.createHal9000(owner);
|
final User nonViewer = this.seedUser();
|
||||||
final String accessToken = this.getAccessToken(viewer.getUsername());
|
final String nonViewerToken = this.getAccessToken(nonViewer);
|
||||||
this.mockMvc.perform(
|
this.mockMvc.perform(
|
||||||
get("/images/imageOwner/HAL9000.svg")
|
get(getImageUrl(owner, image))
|
||||||
.header("Authorization", "Bearer " + accessToken)
|
.header("Authorization", "Bearer " + nonViewerToken)
|
||||||
).andExpect(status().isForbidden());
|
).andExpect(status().isForbidden());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
|
||||||
public void getImageWithViewersNoPrincipalForbidden() throws Exception {
|
public void getImageWithViewersNoPrincipalForbidden() throws Exception {
|
||||||
final User owner = this.createTestUser("imageOwner");
|
final User owner = this.seedUser();
|
||||||
final User viewer = this.createTestUser("viewer");
|
final Image image = this.seedImage(owner);
|
||||||
final Image image = this.createHal9000(owner);
|
final User viewer = this.seedUser();
|
||||||
this.addViewer(image, owner, viewer);
|
|
||||||
this.mockMvc.perform(
|
// add viewer
|
||||||
get("/images/imageOwner/HAL9000.svg")
|
final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec();
|
||||||
).andExpect(status().isForbidden());
|
spec.setViewersToAdd(Set.of(viewer));
|
||||||
|
this.imageService.update(image, owner, spec);
|
||||||
|
|
||||||
|
this.mockMvc.perform(get(getImageUrl(owner, image))).andExpect(status().isForbidden());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
|
||||||
public void getImageWithViewersWrongViewerForbidden() throws Exception {
|
|
||||||
final User owner = this.createTestUser("imageOwner");
|
|
||||||
final User viewer = this.createTestUser("viewer");
|
|
||||||
final User wrongViewer = this.createTestUser("wrongViewer");
|
|
||||||
final Image image = this.createHal9000(owner);
|
|
||||||
this.addViewer(image, owner, viewer);
|
|
||||||
final String accessToken = this.getAccessToken(wrongViewer.getUsername());
|
|
||||||
this.mockMvc.perform(
|
|
||||||
get("/images/imageOwner/HAL9000.svg")
|
|
||||||
.header("Authorization", "Bearer " + accessToken)
|
|
||||||
).andExpect(status().isForbidden());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DirtiesContext
|
|
||||||
public void putImage() throws Exception {
|
public void putImage() throws Exception {
|
||||||
final User owner = this.createTestUser("imageOwner");
|
final User owner = this.seedUser();
|
||||||
final String accessToken = this.getAccessToken(owner.getUsername());
|
final String accessToken = this.getAccessToken(owner);
|
||||||
try (final InputStream hal9000 = getHal9000()) {
|
try (final InputStream hal9000 = getHal9000InputStream()) {
|
||||||
|
final String userFilename = makeUserFilename();
|
||||||
final MockMultipartFile mockMultipartFile = new MockMultipartFile(
|
final MockMultipartFile mockMultipartFile = new MockMultipartFile(
|
||||||
"image", "HAL9000.svg", "image/svg+xml", hal9000
|
"image", userFilename, "image/svg+xml", hal9000
|
||||||
);
|
);
|
||||||
this.mockMvc.perform(
|
this.mockMvc.perform(
|
||||||
multipart("/images")
|
multipart("/images")
|
||||||
.file(mockMultipartFile)
|
.file(mockMultipartFile)
|
||||||
.param("filename", "HAL9000.svg")
|
.param("filename", userFilename)
|
||||||
.param("alt", "HAL 9000")
|
.param("alt", "HAL 9000")
|
||||||
.param("caption", "HAL 9000, from 2001: A Space Odyssey")
|
.param("caption", "HAL 9000, from 2001: A Space Odyssey")
|
||||||
.param("isPublic", "true")
|
.param("isPublic", "true")
|
||||||
@ -234,31 +227,26 @@ public class ImageControllerTests {
|
|||||||
.andExpect(status().isCreated())
|
.andExpect(status().isCreated())
|
||||||
.andExpect(jsonPath("$.created").exists())
|
.andExpect(jsonPath("$.created").exists())
|
||||||
.andExpect(jsonPath("$.modified").value(nullValue()))
|
.andExpect(jsonPath("$.modified").value(nullValue()))
|
||||||
.andExpect(jsonPath("$.filename").value(USER_FILENAME))
|
.andExpect(jsonPath("$.filename").value(userFilename))
|
||||||
.andExpect(jsonPath("$.mimeType").value("image/svg+xml"))
|
.andExpect(jsonPath("$.mimeType").value("image/svg+xml"))
|
||||||
.andExpect(jsonPath("$.alt").value("HAL 9000"))
|
.andExpect(jsonPath("$.alt").value("HAL 9000"))
|
||||||
.andExpect(jsonPath("$.caption").value("HAL 9000, from 2001: A Space Odyssey"))
|
.andExpect(jsonPath("$.caption").value("HAL 9000, from 2001: A Space Odyssey"))
|
||||||
.andExpect(jsonPath("$.isPublic").value(true))
|
.andExpect(jsonPath("$.isPublic").value(true))
|
||||||
.andExpect(jsonPath("$.owner.username").value("imageOwner"))
|
.andExpect(jsonPath("$.owner.username").value(owner.getUsername()))
|
||||||
.andExpect(jsonPath("$.owner.id").value(owner.getId()))
|
.andExpect(jsonPath("$.owner.id").value(owner.getId()))
|
||||||
.andExpect(jsonPath("$.viewers").value(empty()));
|
.andExpect(jsonPath("$.viewers").value(empty()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String prepUpdate() throws ImageException, IOException {
|
|
||||||
final User owner = this.createTestUser("imageOwner");
|
|
||||||
this.createHal9000(owner);
|
|
||||||
return this.getAccessToken(owner.getUsername());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
|
||||||
public void updateAlt() throws Exception {
|
public void updateAlt() throws Exception {
|
||||||
final String accessToken = this.prepUpdate();
|
final User owner = this.seedUser();
|
||||||
|
final Image image = this.seedImage(owner);
|
||||||
|
final String accessToken = this.getAccessToken(owner);
|
||||||
final ImageUpdateInfoBody body = new ImageUpdateInfoBody();
|
final ImageUpdateInfoBody body = new ImageUpdateInfoBody();
|
||||||
body.setAlt("HAL 9000");
|
body.setAlt("HAL 9000");
|
||||||
this.mockMvc.perform(
|
this.mockMvc.perform(
|
||||||
post("/images/imageOwner/HAL9000.svg")
|
post(getImageUrl(owner, image))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(this.objectMapper.writeValueAsString(body))
|
.content(this.objectMapper.writeValueAsString(body))
|
||||||
.header("Authorization", "Bearer " + accessToken)
|
.header("Authorization", "Bearer " + accessToken)
|
||||||
@ -269,13 +257,14 @@ public class ImageControllerTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
|
||||||
public void updateCaption() throws Exception {
|
public void updateCaption() throws Exception {
|
||||||
final String accessToken = this.prepUpdate();
|
final User owner = this.seedUser();
|
||||||
|
final Image image = this.seedImage(owner);
|
||||||
|
final String accessToken = this.getAccessToken(owner);
|
||||||
final ImageUpdateInfoBody body = new ImageUpdateInfoBody();
|
final ImageUpdateInfoBody body = new ImageUpdateInfoBody();
|
||||||
body.setCaption("HAL 9000 from 2001: A Space Odyssey");
|
body.setCaption("HAL 9000 from 2001: A Space Odyssey");
|
||||||
this.mockMvc.perform(
|
this.mockMvc.perform(
|
||||||
post("/images/imageOwner/HAL9000.svg")
|
post(getImageUrl(owner, image))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(this.objectMapper.writeValueAsString(body))
|
.content(this.objectMapper.writeValueAsString(body))
|
||||||
.header("Authorization", "Bearer " + accessToken)
|
.header("Authorization", "Bearer " + accessToken)
|
||||||
@ -286,13 +275,14 @@ public class ImageControllerTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
|
||||||
public void updateIsPublic() throws Exception {
|
public void updateIsPublic() throws Exception {
|
||||||
final String accessToken = this.prepUpdate();
|
final User owner = this.seedUser();
|
||||||
|
final Image image = this.seedImage(owner);
|
||||||
|
final String accessToken = this.getAccessToken(owner);
|
||||||
final ImageUpdateInfoBody body = new ImageUpdateInfoBody();
|
final ImageUpdateInfoBody body = new ImageUpdateInfoBody();
|
||||||
body.setPublic(true);
|
body.setPublic(true);
|
||||||
this.mockMvc.perform(
|
this.mockMvc.perform(
|
||||||
post("/images/imageOwner/HAL9000.svg")
|
post(getImageUrl(owner, image))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(this.objectMapper.writeValueAsString(body))
|
.content(this.objectMapper.writeValueAsString(body))
|
||||||
.header("Authorization", "Bearer " + accessToken)
|
.header("Authorization", "Bearer " + accessToken)
|
||||||
@ -303,16 +293,18 @@ public class ImageControllerTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
|
||||||
public void addViewers() throws Exception {
|
public void addViewers() throws Exception {
|
||||||
final String accessToken = this.prepUpdate();
|
final User owner = this.seedUser();
|
||||||
|
final User viewerToAdd = this.seedUser();
|
||||||
|
final Image image = this.seedImage(owner);
|
||||||
|
final String accessToken = this.getAccessToken(owner);
|
||||||
|
|
||||||
final ImageUpdateInfoBody body = new ImageUpdateInfoBody();
|
final ImageUpdateInfoBody body = new ImageUpdateInfoBody();
|
||||||
final Set<String> viewerUsernames = Set.of(this.createTestUser("imageViewer")).stream()
|
final Set<String> viewerUsernames = Set.of(viewerToAdd.getUsername());
|
||||||
.map(User::getUsername)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
body.setViewersToAdd(viewerUsernames);
|
body.setViewersToAdd(viewerUsernames);
|
||||||
|
|
||||||
this.mockMvc.perform(
|
this.mockMvc.perform(
|
||||||
post("/images/imageOwner/HAL9000.svg")
|
post(getImageUrl(owner, image))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(this.objectMapper.writeValueAsString(body))
|
.content(this.objectMapper.writeValueAsString(body))
|
||||||
.header("Authorization", "Bearer " + accessToken)
|
.header("Authorization", "Bearer " + accessToken)
|
||||||
@ -320,15 +312,15 @@ public class ImageControllerTests {
|
|||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.modified").value(notNullValue()))
|
.andExpect(jsonPath("$.modified").value(notNullValue()))
|
||||||
.andExpect(jsonPath("$.viewers").value(not(empty())))
|
.andExpect(jsonPath("$.viewers").value(not(empty())))
|
||||||
.andExpect(jsonPath("$.viewers[0].username").value("imageViewer"));
|
.andExpect(jsonPath("$.viewers[0].username").value(viewerToAdd.getUsername()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private record OwnerViewerImage(User owner, User viewer, Image image) {}
|
private record OwnerViewerImage(User owner, User viewer, Image image) {}
|
||||||
|
|
||||||
private OwnerViewerImage prepOwnerViewerImage() throws ImageException, IOException {
|
private OwnerViewerImage prepOwnerViewerImage() {
|
||||||
final User owner = this.createTestUser("imageOwner");
|
final User owner = this.seedUser();
|
||||||
final User viewer = this.createTestUser("imageViewer");
|
final User viewer = this.seedUser();
|
||||||
final Image image = this.createHal9000(owner);
|
final Image image = this.seedImage(owner);
|
||||||
final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec();
|
final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec();
|
||||||
spec.setViewersToAdd(Set.of(viewer));
|
spec.setViewersToAdd(Set.of(viewer));
|
||||||
this.imageService.update(image, owner, spec);
|
this.imageService.update(image, owner, spec);
|
||||||
@ -336,14 +328,15 @@ public class ImageControllerTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
|
||||||
public void removeViewers() throws Exception {
|
public void removeViewers() throws Exception {
|
||||||
final OwnerViewerImage ownerViewerImage = this.prepOwnerViewerImage();
|
final OwnerViewerImage ownerViewerImage = this.prepOwnerViewerImage();
|
||||||
final String accessToken = this.getAccessToken(ownerViewerImage.owner().getUsername());
|
final String accessToken = this.getAccessToken(ownerViewerImage.owner());
|
||||||
|
|
||||||
final ImageUpdateInfoBody body = new ImageUpdateInfoBody();
|
final ImageUpdateInfoBody body = new ImageUpdateInfoBody();
|
||||||
body.setViewersToRemove(Set.of(ownerViewerImage.viewer().getUsername()));
|
body.setViewersToRemove(Set.of(ownerViewerImage.viewer().getUsername()));
|
||||||
|
|
||||||
this.mockMvc.perform(
|
this.mockMvc.perform(
|
||||||
post("/images/imageOwner/HAL9000.svg")
|
post(getImageUrl(ownerViewerImage.owner(), ownerViewerImage.image()))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(this.objectMapper.writeValueAsString(body))
|
.content(this.objectMapper.writeValueAsString(body))
|
||||||
.header("Authorization", "Bearer " + accessToken)
|
.header("Authorization", "Bearer " + accessToken)
|
||||||
@ -354,14 +347,13 @@ public class ImageControllerTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
|
||||||
public void clearAllViewers() throws Exception {
|
public void clearAllViewers() throws Exception {
|
||||||
final OwnerViewerImage ownerViewerImage = this.prepOwnerViewerImage();
|
final OwnerViewerImage ownerViewerImage = this.prepOwnerViewerImage();
|
||||||
final String accessToken = this.getAccessToken(ownerViewerImage.owner().getUsername());
|
final String accessToken = this.getAccessToken(ownerViewerImage.owner());
|
||||||
final ImageUpdateInfoBody body = new ImageUpdateInfoBody();
|
final ImageUpdateInfoBody body = new ImageUpdateInfoBody();
|
||||||
body.setClearAllViewers(true);
|
body.setClearAllViewers(true);
|
||||||
this.mockMvc.perform(
|
this.mockMvc.perform(
|
||||||
post("/images/imageOwner/HAL9000.svg")
|
post(getImageUrl(ownerViewerImage.owner(), ownerViewerImage.image()))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(this.objectMapper.writeValueAsString(body))
|
.content(this.objectMapper.writeValueAsString(body))
|
||||||
.header("Authorization", "Bearer " + accessToken)
|
.header("Authorization", "Bearer " + accessToken)
|
||||||
@ -372,14 +364,13 @@ public class ImageControllerTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
|
||||||
public void updateInfoByViewerForbidden() throws Exception {
|
public void updateInfoByViewerForbidden() throws Exception {
|
||||||
final OwnerViewerImage ownerViewerImage = this.prepOwnerViewerImage();
|
final OwnerViewerImage ownerViewerImage = this.prepOwnerViewerImage();
|
||||||
final String accessToken = this.getAccessToken(ownerViewerImage.viewer().getUsername()); // viewer
|
final String accessToken = this.getAccessToken(ownerViewerImage.viewer()); // viewer
|
||||||
final ImageUpdateInfoBody body = new ImageUpdateInfoBody();
|
final ImageUpdateInfoBody body = new ImageUpdateInfoBody();
|
||||||
this.mockMvc.perform(
|
this.mockMvc.perform(
|
||||||
post("/images/imageOwner/HAL9000.svg")
|
post(getImageUrl(ownerViewerImage.owner(), ownerViewerImage.image()))
|
||||||
.contentType(MediaType.APPLICATION_JSON )
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(this.objectMapper.writeValueAsString(body))
|
.content(this.objectMapper.writeValueAsString(body))
|
||||||
.header("Authorization", "Bearer " + accessToken)
|
.header("Authorization", "Bearer " + accessToken)
|
||||||
)
|
)
|
||||||
@ -389,13 +380,12 @@ public class ImageControllerTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
|
||||||
public void deleteImageWithOwner() throws Exception {
|
public void deleteImageWithOwner() throws Exception {
|
||||||
final User owner = this.createTestUser("imageOwner");
|
final User owner = this.seedUser();
|
||||||
final Image image = this.createHal9000(owner);
|
final Image image = this.seedImage(owner);
|
||||||
final String accessToken = this.getAccessToken(owner.getUsername());
|
final String accessToken = this.getAccessToken(owner);
|
||||||
this.mockMvc.perform(
|
this.mockMvc.perform(
|
||||||
delete("/images/imageOwner/HAL9000.svg")
|
delete(getImageUrl(owner, image))
|
||||||
.header("Authorization", "Bearer " + accessToken)
|
.header("Authorization", "Bearer " + accessToken)
|
||||||
)
|
)
|
||||||
.andExpect(status().isNoContent());
|
.andExpect(status().isNoContent());
|
||||||
@ -403,12 +393,11 @@ public class ImageControllerTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
|
||||||
public void deleteImageByViewerForbidden() throws Exception {
|
public void deleteImageByViewerForbidden() throws Exception {
|
||||||
final OwnerViewerImage ownerViewerImage = this.prepOwnerViewerImage();
|
final OwnerViewerImage ownerViewerImage = this.prepOwnerViewerImage();
|
||||||
final String accessToken = this.getAccessToken(ownerViewerImage.viewer().getUsername());
|
final String accessToken = this.getAccessToken(ownerViewerImage.viewer());
|
||||||
this.mockMvc.perform(
|
this.mockMvc.perform(
|
||||||
delete("/images/imageOwner/HAL9000.svg")
|
delete(getImageUrl(ownerViewerImage.owner(), ownerViewerImage.image()))
|
||||||
.header("Authorization", "Bearer " + accessToken)
|
.header("Authorization", "Bearer " + accessToken)
|
||||||
)
|
)
|
||||||
.andExpect(status().isForbidden());
|
.andExpect(status().isForbidden());
|
||||||
|
|||||||
@ -1,7 +1,3 @@
|
|||||||
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.baseUrl=http://localhost:8080
|
||||||
app.mealsmadeeasy.api.security.access-token-lifetime=60
|
app.mealsmadeeasy.api.security.access-token-lifetime=60
|
||||||
app.mealsmadeeasy.api.security.refresh-token-lifetime=120
|
app.mealsmadeeasy.api.security.refresh-token-lifetime=120
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
CREATE UNIQUE INDEX image_owner_id_user_filename ON image (owner_id, user_filename);
|
||||||
Loading…
Reference in New Issue
Block a user