S3ImageServiceTests all passing.

This commit is contained in:
Jesse Brault 2024-07-26 10:38:11 -05:00
parent a5c0add82b
commit 6e29ec7d58
6 changed files with 102 additions and 20 deletions

View File

@ -22,13 +22,14 @@ import java.util.List;
import java.util.Set;
import static app.mealsmadeeasy.api.image.ContainsImagesMatcher.containsImages;
import static app.mealsmadeeasy.api.user.ContainsUsersMatcher.containsUsers;
import static app.mealsmadeeasy.api.user.IsUserMatcher.isUser;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.Assert.assertThrows;
@Testcontainers
@SpringBootTest
@ -165,43 +166,89 @@ public class S3ImageServiceTests {
@Test
@DirtiesContext
public void updateAlt() throws Exception {
fail("TODO");
final User owner = this.createTestUser("imageOwner");
Image image = this.createHal9000(owner);
final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec();
spec.setAlt("HAL 9000");
image = this.imageService.update(image, owner, spec);
assertThat(image.getAlt(), is("HAL 9000"));
}
@Test
@DirtiesContext
public void updateCaption() throws Exception {
fail("TODO");
final User owner = this.createTestUser("imageOwner");
Image image = this.createHal9000(owner);
final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec();
spec.setCaption("HAL 9000 from 2001: A Space Odyssey");
image = this.imageService.update(image, owner, spec);
assertThat(image.getCaption(), is("HAL 9000 from 2001: A Space Odyssey"));
}
@Test
@DirtiesContext
public void updateIsPublic() throws Exception {
fail("TODO");
final User owner = this.createTestUser("imageOwner");
Image image = this.createHal9000(owner);
final ImageUpdateInfoSpec spec = new ImageUpdateInfoSpec();
spec.setPublic(true);
image = this.imageService.update(image, owner, spec);
assertThat(image.isPublic(), is(true));
}
private Image addViewer(Image image, User owner, User viewer) {
final ImageUpdateInfoSpec spec0 = new ImageUpdateInfoSpec();
spec0.setViewersToAdd(Set.of(viewer));
return this.imageService.update(image, owner, spec0);
}
@Test
@DirtiesContext
public void addViewers() throws Exception {
fail("TODO");
final User owner = this.createTestUser("imageOwner");
final User viewer = this.createTestUser("imageViewer");
Image image = this.createHal9000(owner);
image = this.addViewer(image, owner, viewer);
assertThat(image.getViewers(), containsUsers(viewer));
}
@Test
@DirtiesContext
public void removeViewers() throws Exception {
fail("TODO");
final User owner = this.createTestUser("imageOwner");
final User viewer = this.createTestUser("imageViewer");
Image image = this.createHal9000(owner);
image = this.addViewer(image, owner, viewer);
assertThat(image.getViewers(), containsUsers(viewer));
final ImageUpdateInfoSpec spec1 = new ImageUpdateInfoSpec();
spec1.setViewersToRemove(Set.of(viewer));
image = this.imageService.update(image, owner, spec1);
assertThat(image.getViewers(), empty());
}
@Test
@DirtiesContext
public void clearAllViewers() throws Exception {
fail("TODO");
final User owner = this.createTestUser("imageOwner");
final User viewer = this.createTestUser("imageViewer");
Image image = this.createHal9000(owner);
image = this.addViewer(image, owner, viewer);
assertThat(image.getViewers(), containsUsers(viewer));
final ImageUpdateInfoSpec spec1 = new ImageUpdateInfoSpec();
spec1.setClearAllViewers(true);
image = this.imageService.update(image, owner, spec1);
assertThat(image.getViewers(), empty());
}
@Test
@DirtiesContext
public void deleteImage() throws Exception {
fail("TODO");
final User owner = this.createTestUser("imageOwner");
final Image image = this.createHal9000(owner);
this.imageService.deleteImage(image, owner);
assertThrows(ImageException.class, () -> this.imageService.getById(image.getId(), owner));
}
}

View File

@ -1,7 +1,6 @@
package app.mealsmadeeasy.api.image;
import app.mealsmadeeasy.api.user.User;
import app.mealsmadeeasy.api.user.UserEntity;
import org.jetbrains.annotations.Nullable;
import java.time.LocalDateTime;
@ -17,5 +16,5 @@ public interface Image {
@Nullable String getCaption();
User getOwner();
boolean isPublic();
Set<UserEntity> getViewers();
Set<User> getViewers();
}

View File

@ -14,7 +14,9 @@ public interface ImageService {
Image create(User owner, String userFilename, InputStream inputStream, long objectSize, ImageCreateInfoSpec infoSpec)
throws IOException, ImageException;
Image getById(long id, @Nullable User viewer) throws ImageException;
Image getByOwnerAndFilename(User owner, String filename, User viewer) throws ImageException;
InputStream getImageContent(Image image, @Nullable User viewer) throws IOException;
List<Image> getImagesOwnedBy(User user);

View File

@ -135,7 +135,11 @@ public class S3ImageEntity implements Image {
}
@Override
public Set<UserEntity> getViewers() {
public Set<User> getViewers() {
return Set.copyOf(this.viewers);
}
public Set<UserEntity> getViewerEntities() {
return this.viewers;
}

View File

@ -5,6 +5,7 @@ import app.mealsmadeeasy.api.image.spec.ImageUpdateInfoSpec;
import app.mealsmadeeasy.api.s3.S3Manager;
import app.mealsmadeeasy.api.user.User;
import app.mealsmadeeasy.api.user.UserEntity;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
@ -12,9 +13,7 @@ import org.springframework.stereotype.Service;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -75,9 +74,11 @@ public class S3ImageService implements ImageService {
if (spec.getPublic() != null) {
entity.setPublic(spec.getPublic());
}
final Set<UserEntity> viewers = new HashSet<>(entity.getViewerEntities());
for (final User viewerToAdd : spec.getViewersToAdd()) {
entity.getViewers().add((UserEntity) viewerToAdd);
viewers.add((UserEntity) viewerToAdd);
}
entity.setViewers(viewers);
}
@Override
@ -105,6 +106,14 @@ public class S3ImageService implements ImageService {
return this.imageRepository.save(draft);
}
@Override
@PostAuthorize("@imageSecurity.isViewableBy(returnObject, #viewer)")
public Image getById(long id, @Nullable User viewer) throws ImageException {
return this.imageRepository.findById(id).orElseThrow(() -> new ImageException(
ImageException.Type.INVALID_ID, "No Image with id: " + id
));
}
@Override
@PostAuthorize("@imageSecurity.isViewableBy(returnObject, #viewer)")
public Image getByOwnerAndFilename(User owner, String filename, User viewer) throws ImageException {
@ -131,11 +140,15 @@ public class S3ImageService implements ImageService {
public Image update(final Image image, User modifier, ImageUpdateInfoSpec updateSpec) {
S3ImageEntity entity = (S3ImageEntity) image;
this.transferFromSpec(entity, updateSpec);
final @Nullable Boolean clearAllViewers = updateSpec.getClearAllViewers();
if (clearAllViewers != null && clearAllViewers) {
entity.setViewers(Set.of());
} else {
final Set<UserEntity> viewers = new HashSet<>(entity.getViewerEntities());
for (final User toRemove : updateSpec.getViewersToRemove()) {
entity.getViewers().remove((UserEntity) toRemove);
viewers.remove((UserEntity) toRemove);
}
if (updateSpec.getClearAllViewers() != null) {
entity.getViewers().clear();
entity.setViewers(viewers);
}
return this.imageRepository.save(entity);
}

View File

@ -0,0 +1,17 @@
package app.mealsmadeeasy.api.user;
import app.mealsmadeeasy.api.matchers.ContainsItemsMatcher;
import java.util.List;
public class ContainsUsersMatcher extends ContainsItemsMatcher<User, Long> {
public static ContainsUsersMatcher containsUsers(User... allExpected) {
return new ContainsUsersMatcher(allExpected);
}
private ContainsUsersMatcher(User... allExpected) {
super(List.of(allExpected), o -> o instanceof User, User::getId);
}
}