From fd8c7a620a9799d29641e7425f644c354d7bc976 Mon Sep 17 00:00:00 2001
From: Andreas Svanberg <andreass@dsv.su.se>
Date: Mon, 17 Feb 2025 14:17:39 +0100
Subject: [PATCH] Added tests for deletion logic

---
 .../BasicForumServiceIntegrationTest.java     | 83 +++++++++++++++++++
 .../se/su/dsv/scipro/test/SpringTest.java     | 27 +++++-
 2 files changed, 109 insertions(+), 1 deletion(-)
 create mode 100644 core/src/test/java/se/su/dsv/scipro/forum/BasicForumServiceIntegrationTest.java

diff --git a/core/src/test/java/se/su/dsv/scipro/forum/BasicForumServiceIntegrationTest.java b/core/src/test/java/se/su/dsv/scipro/forum/BasicForumServiceIntegrationTest.java
new file mode 100644
index 0000000000..ec5d815af7
--- /dev/null
+++ b/core/src/test/java/se/su/dsv/scipro/forum/BasicForumServiceIntegrationTest.java
@@ -0,0 +1,83 @@
+package se.su.dsv.scipro.forum;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import jakarta.inject.Inject;
+import java.util.Set;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import se.su.dsv.scipro.forum.dataobjects.ForumPost;
+import se.su.dsv.scipro.forum.dataobjects.ForumThread;
+import se.su.dsv.scipro.system.User;
+import se.su.dsv.scipro.test.IntegrationTest;
+
+public class BasicForumServiceIntegrationTest extends IntegrationTest {
+
+    @Inject
+    BasicForumService basicForumService;
+
+    private User op;
+    private User commenter;
+
+    @BeforeEach
+    public void setUp() {
+        User op = User.builder().firstName("Bill").lastName("Gates").emailAddress("bill@example.com").build();
+        this.op = save(op);
+
+        User commenter = User.builder().firstName("Steve").lastName("Jobs").emailAddress("steve@example.com").build();
+        this.commenter = save(commenter);
+    }
+
+    @Test
+    public void can_not_delete_original_post() {
+        ForumThread thread = basicForumService.createThread("Test thread");
+        ForumPost originalPost = basicForumService.createReply(thread, op, "Test post", Set.of());
+
+        setLoggedInAs(op);
+
+        assertFalse(basicForumService.canDelete(originalPost));
+        assertThrows(IllegalArgumentException.class, () -> basicForumService.deletePost(originalPost));
+    }
+
+    @Test
+    public void can_delete_reply_to_original_post() {
+        ForumThread thread = basicForumService.createThread("Test thread");
+        ForumPost originalPost = basicForumService.createReply(thread, op, "Test post", Set.of());
+        ForumPost reply = basicForumService.createReply(thread, commenter, "Test reply", Set.of());
+
+        setLoggedInAs(commenter);
+
+        assertTrue(basicForumService.canDelete(reply));
+        assertDoesNotThrow(() -> basicForumService.deletePost(reply));
+    }
+
+    @Test
+    public void can_not_delete_someone_elses_reply() {
+        ForumThread thread = basicForumService.createThread("Test thread");
+        ForumPost originalPost = basicForumService.createReply(thread, op, "Test post", Set.of());
+        ForumPost reply = basicForumService.createReply(thread, commenter, "Test reply", Set.of());
+
+        setLoggedInAs(op);
+
+        assertFalse(basicForumService.canDelete(reply));
+        assertThrows(IllegalArgumentException.class, () -> basicForumService.deletePost(reply));
+    }
+
+    @Test
+    public void system_can_delete_all_replies() {
+        ForumThread thread = basicForumService.createThread("Test thread");
+        ForumPost originalPost = basicForumService.createReply(thread, op, "Test post", Set.of());
+        ForumPost reply = basicForumService.createReply(thread, commenter, "Test reply", Set.of());
+        ForumPost secondReply = basicForumService.createReply(thread, op, "Test post", Set.of());
+
+        setLoggedInAs(null);
+
+        assertTrue(basicForumService.canDelete(reply));
+        assertDoesNotThrow(() -> basicForumService.deletePost(reply));
+        assertTrue(basicForumService.canDelete(secondReply));
+        assertDoesNotThrow(() -> basicForumService.deletePost(secondReply));
+    }
+}
diff --git a/core/src/test/java/se/su/dsv/scipro/test/SpringTest.java b/core/src/test/java/se/su/dsv/scipro/test/SpringTest.java
index 04d0f70da7..287e49e710 100644
--- a/core/src/test/java/se/su/dsv/scipro/test/SpringTest.java
+++ b/core/src/test/java/se/su/dsv/scipro/test/SpringTest.java
@@ -1,5 +1,6 @@
 package se.su.dsv.scipro.test;
 
+import jakarta.inject.Inject;
 import jakarta.persistence.EntityManager;
 import jakarta.persistence.EntityManagerFactory;
 import jakarta.persistence.EntityTransaction;
@@ -25,6 +26,7 @@ import se.su.dsv.scipro.RepositoryConfiguration;
 import se.su.dsv.scipro.profiles.CurrentProfile;
 import se.su.dsv.scipro.sukat.Sukat;
 import se.su.dsv.scipro.system.CurrentUser;
+import se.su.dsv.scipro.system.User;
 
 @Testcontainers
 public abstract class SpringTest {
@@ -35,6 +37,9 @@ public abstract class SpringTest {
     @Container
     static MariaDBContainer<?> mariaDBContainer = new MariaDBContainer<>("mariadb:10.11");
 
+    @Inject
+    private TestUser testUser;
+
     @BeforeEach
     public final void prepareSpring() throws SQLException {
         MariaDbDataSource dataSource = new MariaDbDataSource(mariaDBContainer.getJdbcUrl());
@@ -56,6 +61,8 @@ public abstract class SpringTest {
         annotationConfigApplicationContext.getBeanFactory().registerSingleton("entityManager", this.entityManager);
         annotationConfigApplicationContext.refresh();
         annotationConfigApplicationContext.getAutowireCapableBeanFactory().autowireBean(this);
+
+        testUser.setUser(null); // default to system
     }
 
     @AfterEach
@@ -75,6 +82,10 @@ public abstract class SpringTest {
         }
     }
 
+    protected void setLoggedInAs(User user) {
+        this.testUser.setUser(user);
+    }
+
     @Configuration(proxyBeanMethods = false)
     @Import({ CoreConfig.class, RepositoryConfiguration.class })
     public static class TestContext {
@@ -96,7 +107,7 @@ public abstract class SpringTest {
 
         @Bean
         public CurrentUser currentUser() {
-            return () -> null;
+            return new TestUser();
         }
 
         @Bean
@@ -106,4 +117,18 @@ public abstract class SpringTest {
             return currentProfile;
         }
     }
+
+    private static class TestUser implements CurrentUser {
+
+        private User user;
+
+        @Override
+        public User get() {
+            return user;
+        }
+
+        private void setUser(User user) {
+            this.user = user;
+        }
+    }
 }