diff --git a/src/main/java/idatt2106/systemutvikling/sparesti/controller/ChallengeController.java b/src/main/java/idatt2106/systemutvikling/sparesti/controller/ChallengeController.java
index 09e9f58eb1b36eee3c4e6723aace411a40e43626..d7291a29bbf10f4a8d1e9564f843658c1fe6d6a5 100644
--- a/src/main/java/idatt2106/systemutvikling/sparesti/controller/ChallengeController.java
+++ b/src/main/java/idatt2106/systemutvikling/sparesti/controller/ChallengeController.java
@@ -12,6 +12,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import io.swagger.v3.oas.annotations.responses.ApiResponse;
 import io.swagger.v3.oas.annotations.responses.ApiResponses;
 import lombok.AllArgsConstructor;
+import lombok.NonNull;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.http.HttpStatus;
@@ -200,20 +201,16 @@ public class ChallengeController {
   )
   @PostMapping("/activate/{challengeId}")
   @ResponseBody
-  public ResponseEntity<ChallengeDTO> activateChallenge(@PathVariable Long challengeId) {
+  public ResponseEntity<ChallengeDTO> activateChallenge(@PathVariable @NonNull Long challengeId) {
 
-    if (challengeId == null) {
-      return ResponseEntity.badRequest().build();
-    }
-
-    if (challengeService.getChallenge(challengeId).isActive()) {
+    // Verify that the challenge is inactive
+    if (challengeService.getChallenge(challengeId).isActive())
       return ResponseEntity.badRequest().body(challengeService.getChallenge(challengeId));
-    }
 
+    //
     if (!challengeService.getChallenge(challengeId).getUsername()
-            .equals(CurrentUserService.getCurrentUsername())) {
+        .equals(CurrentUserService.getCurrentUsername()))
       return ResponseEntity.badRequest().body(challengeService.getChallenge(challengeId));
-    }
 
     return ResponseEntity.ok()
             .body(ChallengeMapper.toDTO(challengeService.activateChallenge(challengeId)));
@@ -250,40 +247,22 @@ public class ChallengeController {
   )
   @PostMapping("/complete")
   @ResponseBody
-  public ResponseEntity<String> completeChallenge(@RequestParam("challengeId") Long challengeId,
-                                                  @RequestParam("milestoneId") Long milestoneId) {
-    if (challengeId == null) {
-      return ResponseEntity.badRequest().build();
-    }
+  public ResponseEntity<String> completeChallenge(@RequestParam("challengeId") @NonNull Long challengeId,
+                                                  @RequestParam("milestoneId") @NonNull Long milestoneId) {
 
+    // Verify ownership of the requested challenge
     if (!challengeService.getChallenge(challengeId).getUsername()
-            .equals(CurrentUserService.getCurrentUsername())) {
+        .equals(CurrentUserService.getCurrentUsername()))
       return ResponseEntity.badRequest().body("You are not the owner of this challenge");
-    }
-
-    if (milestoneId == null) {
-      return ResponseEntity.badRequest().build();
-    }
 
+    // Verify ownership of the requested milestone
     if (!milestoneService.getMilestoneDTOById(milestoneId).getUsername()
-            .equals(CurrentUserService.getCurrentUsername())) {
+        .equals(CurrentUserService.getCurrentUsername()))
       return ResponseEntity.badRequest().body("You are not the owner of this milestone");
-    }
-
-    Long achievedSum = challengeService.getChallenge(challengeId).getGoalSum();
-    Long milestoneCurrentSum = milestoneService.getMilestoneDTOById(milestoneId)
-            .getMilestoneCurrentSum();
-    long targetSum = achievedSum + milestoneCurrentSum;
-
-    milestoneService.increaseMilestonesCurrentSum(milestoneId, achievedSum);
-
-    if (targetSum > milestoneService.getMilestoneDTOById(milestoneId)
-            .getMilestoneCurrentSum()) {
-      return ResponseEntity.badRequest().body("Could not transfer money to milestone");
-    }
-
-    challengeService.completeChallenge(challengeId);
+    // Perform requested operation
+    challengeService.completeChallengeForCurrentUser(challengeId, milestoneId);
 
+    // Return 200 OK
     return ResponseEntity.ok().body("Challenge completed");
   }
 
@@ -315,16 +294,12 @@ public class ChallengeController {
                   )})
   @DeleteMapping("/delete/{challengeId}")
   @ResponseBody
-  public ResponseEntity<String> moveChallengeToLog(@PathVariable Long challengeId) {
-    if (challengeId == null) {
-      return ResponseEntity.badRequest().build();
-    }
-
-    if (!challengeService.getChallenge(challengeId).getUsername()
-            .equals(CurrentUserService.getCurrentUsername())) {
+  public ResponseEntity<String> moveChallengeToLog(@PathVariable @NonNull Long challengeId) {
+    // Verify ownership of the challenge
+    if (!challengeService.getChallenge(challengeId).getUsername().equals(CurrentUserService.getCurrentUsername()))
       return ResponseEntity.badRequest().body("You are not the owner of this challenge");
-    }
 
+    // Perform the service layer function
     challengeService.moveChallengeToLog(challengeId);
 
     return ResponseEntity.ok().body("Challenge deleted");
diff --git a/src/main/java/idatt2106/systemutvikling/sparesti/dto/MilestoneDTO.java b/src/main/java/idatt2106/systemutvikling/sparesti/dto/MilestoneDTO.java
index b9883c740e03ff27f0c4a7961fe8703fc00c8f91..574cbf32caae027d7122dad6a12dc498af763a74 100644
--- a/src/main/java/idatt2106/systemutvikling/sparesti/dto/MilestoneDTO.java
+++ b/src/main/java/idatt2106/systemutvikling/sparesti/dto/MilestoneDTO.java
@@ -2,8 +2,8 @@ package idatt2106.systemutvikling.sparesti.dto;
 
 import jakarta.validation.constraints.NotNull;
 import java.time.LocalDateTime;
-import lombok.Getter;
-import lombok.Setter;
+
+import lombok.*;
 
 /**
  * Data transfer object for Milestone
@@ -11,6 +11,9 @@ import lombok.Setter;
  */
 @Getter
 @Setter
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder(toBuilder=true)
 public class MilestoneDTO {
   @NotNull
 private Long milestoneId;
diff --git a/src/main/java/idatt2106/systemutvikling/sparesti/repository/ChallengeRepository.java b/src/main/java/idatt2106/systemutvikling/sparesti/repository/ChallengeRepository.java
index 772b1e9dc5ad1190fc6550f6f228d79db33e5dd1..4246123350b3b3aed3bb1964ba59b4e51dd3ede3 100644
--- a/src/main/java/idatt2106/systemutvikling/sparesti/repository/ChallengeRepository.java
+++ b/src/main/java/idatt2106/systemutvikling/sparesti/repository/ChallengeRepository.java
@@ -118,4 +118,8 @@ public interface ChallengeRepository extends JpaRepository<ChallengeDAO, Long> {
 
 
   void deleteAllByUserDAO_Username(String username);
+
+
+
+  ChallengeDAO findByChallengeIdAndUserDAO_Username(Long id, String username);
 }
diff --git a/src/main/java/idatt2106/systemutvikling/sparesti/service/ChallengeService.java b/src/main/java/idatt2106/systemutvikling/sparesti/service/ChallengeService.java
index ecac3fd3c7b566a3ddfe86c914497c5d41afc97e..01275088e55f07d6443153814b139cb49b3ecb17 100644
--- a/src/main/java/idatt2106/systemutvikling/sparesti/service/ChallengeService.java
+++ b/src/main/java/idatt2106/systemutvikling/sparesti/service/ChallengeService.java
@@ -2,13 +2,18 @@ package idatt2106.systemutvikling.sparesti.service;
 
 import idatt2106.systemutvikling.sparesti.dao.ChallengeDAO;
 import idatt2106.systemutvikling.sparesti.dao.ChallengeLogDAO;
+import idatt2106.systemutvikling.sparesti.dao.MilestoneDAO;
 import idatt2106.systemutvikling.sparesti.dto.ChallengeDTO;
+import idatt2106.systemutvikling.sparesti.exceptions.BankConnectionErrorException;
+import idatt2106.systemutvikling.sparesti.exceptions.NotFoundInDatabaseException;
 import idatt2106.systemutvikling.sparesti.mapper.ChallengeMapper;
 import idatt2106.systemutvikling.sparesti.repository.ChallengeLogRepository;
 import idatt2106.systemutvikling.sparesti.repository.ChallengeRepository;
 
 import java.util.logging.Logger;
 
+import idatt2106.systemutvikling.sparesti.repository.MilestoneRepository;
+import jakarta.transaction.Transactional;
 import lombok.AllArgsConstructor;
 import org.springframework.data.domain.*;
 import org.springframework.stereotype.Service;
@@ -25,8 +30,11 @@ import java.util.List;
 public class ChallengeService {
 
   private final Logger logger = Logger.getLogger(ChallengeService.class.getName());
-  private ChallengeRepository challengeRepository;
-  private ChallengeLogRepository challengeLogRepository;
+  private final TransactionService transactionService;
+  private final ChallengeRepository challengeRepository;
+  private final ChallengeLogRepository challengeLogRepository;
+  private final MilestoneService milestoneService;
+  private final MilestoneRepository dbMilestone;
 
   /**
    * Method to get a challenge by its id from the database and return it as a ChallengeDTO object to
@@ -208,20 +216,74 @@ public class ChallengeService {
     return challengeRepository.save(challengeDAO);
   }
 
+  @Transactional
+  public void completeChallengeForCurrentUser(long challengeId, long milestoneId) {
+    // Fetch username from security context
+    final String username = CurrentUserService.getCurrentUsername();
+
+    // Fetch data
+    ChallengeDAO challenge = challengeRepository.findByChallengeIdAndUserDAO_Username(challengeId, username);
+    MilestoneDAO milestone = dbMilestone.findMilestoneDAOByMilestoneIdAndUserDAO_Username(milestoneId, username);
+
+    // Verify existence of the requested challenge
+    if (challenge == null)
+      throw new NotFoundInDatabaseException("No challenge found with the requested ID for the user");
+
+    // Verify existence of the requested milestone
+    if (milestone == null)
+      throw new NotFoundInDatabaseException("No milestone found with the requested ID for the user");
+
+
+
+    // Define transfer amount as the difference between the goal and the current sum
+    long transferAmount = challenge.getGoalSum() - challenge.getCurrentSum();
+
+    // Perform savings transaction
+    boolean success = transactionService.createSavingsTransferForCurrentUser(transferAmount);
+
+    // Verify transaction success
+    if (success)
+      throw new BankConnectionErrorException("Failed to transfer funds to savings");
+
+
+    // Transfer achieved currency to milestone
+    MilestoneDAO savedEntry = milestoneService.increaseMilestonesCurrentSum(milestoneId, challenge.getGoalSum());
+
+
+    // Archive challenge
+    archiveActiveChallenge(challenge.getChallengeId());
+  }
+
   /**
-   * Method to complete a challenge. The method returns a ChallengeLogDAO object. The challenge is
-   * completed with the current date and time. The challenge is completed with the same information
-   * as the challenge. The challenge is deleted from the database and saved as a challenge log.
+   * Performs the changes - local to the challenge repository - needed for a challenge to be considered as 'completed'.
+   * This function creates a log entry from the selected challenge (specified by the id-parameter)
+   * and stores it in the database. The challenge is deleted from the table of active challenges,
+   * but the log entry persists.
    *
    * @param challengeId the id of the challenge to complete
-   * @return the completed challenge
+   * @return The log entry that is persisted by this function.
    */
-  public ChallengeLogDAO completeChallenge(Long challengeId) {
+  public ChallengeLogDAO archiveActiveChallenge(Long challengeId) {
+    // Fetch active challenge from database
     ChallengeDAO challengeDAO = challengeRepository.findChallengeDAOByChallengeId(challengeId);
+
+    // Verify existence of the active challenge
+    if (challengeDAO == null)
+      return null;
+
+    // Create log entry from the active challenge
     ChallengeLogDAO challengeLogDAO = createChallengeLog(challengeDAO);
+
+    // Set the archived currency equal to the goal of the active challenge
     challengeLogDAO.setChallengeAchievedSum(challengeLogDAO.getGoalSum());
+
+    // Save challenge log entry to database
+    challengeLogDAO = challengeLogRepository.save(challengeLogDAO);
+
+    // Remove active challenge from database
     challengeRepository.delete(challengeDAO);
-    challengeLogRepository.save(challengeLogDAO);
+
+    // Return the archived entry
     return challengeLogDAO;
   }
 
diff --git a/src/test/java/idatt2106/systemutvikling/sparesti/controller/ChallengeControllerTests.java b/src/test/java/idatt2106/systemutvikling/sparesti/controller/ChallengeControllerTests.java
index 8bb216a43d9be2e515e45efd1839b0a71094df9a..dc119e5510eef34c57230c0f08ea673c1f5569c9 100644
--- a/src/test/java/idatt2106/systemutvikling/sparesti/controller/ChallengeControllerTests.java
+++ b/src/test/java/idatt2106/systemutvikling/sparesti/controller/ChallengeControllerTests.java
@@ -1,11 +1,12 @@
 package idatt2106.systemutvikling.sparesti.controller;
 
 import idatt2106.systemutvikling.sparesti.dto.ChallengeDTO;
+import idatt2106.systemutvikling.sparesti.dto.MilestoneDTO;
+import idatt2106.systemutvikling.sparesti.repository.ChallengeLogRepository;
+import idatt2106.systemutvikling.sparesti.repository.ChallengeRepository;
 import idatt2106.systemutvikling.sparesti.service.ChallengeService;
 import idatt2106.systemutvikling.sparesti.service.CurrentUserService;
 import idatt2106.systemutvikling.sparesti.service.MilestoneService;
-import idatt2106.systemutvikling.sparesti.service.TransactionService;
-import org.hibernate.grammars.hql.HqlParser;
 import org.junit.jupiter.api.Test;
 import org.mockito.MockedStatic;
 import org.mockito.Mockito;
@@ -15,15 +16,13 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.test.context.TestPropertySource;
 import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
 
 import java.time.LocalDateTime;
-import java.util.Date;
 
 import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.*;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
 
 
@@ -32,40 +31,178 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
 @TestPropertySource(locations = "classpath:application-integrationtest.properties")
 public class ChallengeControllerTests {
 
-  private static final ChallengeDTO TEST_CHALLENGE = new ChallengeDTO(
-      99L,
-      "Darth",
-      "Test",
-      "This is a test challenge",
-      100L,
-      0L,
-      LocalDateTime.now(),
-      LocalDateTime.now().plusDays(3),
-      0,
-      true
-  );
-
-  @Autowired
-  private MockMvc mvc;
-
-  @MockBean
-  private ChallengeService challengeService;
-
-  @MockBean
-  private MilestoneService milestoneService;
-
-  @Test
-  public void deleteChallenge_ReturnOkWhenAllIsWell() throws Exception {
-    final ChallengeDTO challenge = TEST_CHALLENGE.toBuilder().build();
-
-    given(challengeService.getChallenge(challenge.getChallengeId())).willReturn(challenge);
-    doNothing().when(challengeService).moveChallengeToLog(challenge.getChallengeId());
-
-    try (MockedStatic<CurrentUserService> utilities = Mockito.mockStatic(
-        CurrentUserService.class)) {
-      utilities.when(CurrentUserService::getCurrentUsername).thenReturn(challenge.getUsername());
-      mvc.perform(delete("/user/challenge/delete/" + challenge.getChallengeId()))
-          .andExpect(status().isOk());
+    public static final String TEST_USERNAME = "Test user";
+    public static final String TEST_USERNAME_OTHER = "Not " + TEST_USERNAME;
+
+    private static final ChallengeDTO TEST_CHALLENGE = new ChallengeDTO(
+        99L,
+            TEST_USERNAME,
+        "Test",
+        "This is a test challenge",
+        100L,
+        0L,
+        LocalDateTime.now(),
+        LocalDateTime.now().plusDays(3),
+        0,
+        true
+    );
+
+    private static final MilestoneDTO TEST_MILESTONE = new MilestoneDTO(
+            1L,
+            TEST_USERNAME,
+            "Test milestone",
+            "A milestone for testing",
+            100L,
+            0L,
+            "image.jpg",
+            LocalDateTime.now(),
+            LocalDateTime.now().plusDays(3)
+            );
+
+    @Autowired
+    private MockMvc mvc;
+
+    @MockBean
+    private ChallengeService challengeService;
+
+    @MockBean
+    private MilestoneService milestoneService;
+
+
+    @Test
+    public void moveChallengeToLog_okWhenUserOwnsChallenge() throws Exception {
+        try (MockedStatic<CurrentUserService> utilities = Mockito.mockStatic(CurrentUserService.class)) {
+            // Copy the default values used for testing
+            final ChallengeDTO challenge = TEST_CHALLENGE.toBuilder().build();
+            final Long challengeId = challenge.getChallengeId();
+
+            // Set the currently logged-in user to the owner of the challenge and milestone
+            utilities.when(CurrentUserService::getCurrentUsername).thenReturn(TEST_USERNAME);
+
+            // Stub the service call
+            doNothing().when(challengeService).moveChallengeToLog(challengeId);
+
+            // Set return values of service layer functions
+            given(challengeService.getChallenge(challengeId)).willReturn(challenge);
+
+            // Http request path
+            final String URI = "/user/challenge/delete/" + challengeId;
+
+            // Perform http request
+            mvc.perform(delete(URI)).andExpect(status().is2xxSuccessful());
+        }
+    }
+
+
+    @Test
+    public void completeChallenge_okWhenUserOwnsBothMilestoneAndChallenge() throws Exception {
+        try (MockedStatic<CurrentUserService> utilities = Mockito.mockStatic(CurrentUserService.class)) {
+            // Copy the default values used for testing
+            final ChallengeDTO challenge = TEST_CHALLENGE.toBuilder().build();
+            final MilestoneDTO milestone = TEST_MILESTONE.toBuilder().build();
+            final Long challengeId = challenge.getChallengeId();
+            final Long milestoneId = milestone.getMilestoneId();
+
+            // Set the currently logged-in user to the owner of the challenge and milestone
+            utilities.when(CurrentUserService::getCurrentUsername).thenReturn(TEST_USERNAME);
+
+            // Stub the service call
+            doNothing().when(challengeService).completeChallengeForCurrentUser(challengeId, milestoneId);
+
+            // Set return values of service layer functions
+            given(challengeService.getChallenge(challengeId)).willReturn(challenge);
+            given(milestoneService.getMilestoneDTOById(milestoneId)).willReturn(milestone);
+
+            // Http request path
+            final String URI = String.format("/user/challenge/complete?challengeId=%d&milestoneId=%d",
+                    challengeId,
+                    milestoneId);
+
+            // Perform http request
+            mvc.perform(post(URI)).andExpect(status().isOk());
+        }
+    }
+
+    @Test
+    public void completeChallenge_badRequestWhenUserDoesNotOwnChallenge() throws Exception {
+        try (MockedStatic<CurrentUserService> utilities = Mockito.mockStatic(CurrentUserService.class)) {
+            // Copy the default values used for testing
+            final ChallengeDTO challenge = TEST_CHALLENGE.toBuilder().username("Other user").build();
+            final MilestoneDTO milestone = TEST_MILESTONE.toBuilder().build();
+            final Long challengeId = challenge.getChallengeId();
+            final Long milestoneId = milestone.getMilestoneId();
+
+            // Set the currently logged-in user to the owner of the challenge and milestone
+            utilities.when(CurrentUserService::getCurrentUsername).thenReturn(TEST_USERNAME);
+
+            // Stub the service call
+            doNothing().when(challengeService).completeChallengeForCurrentUser(challengeId, milestoneId);
+
+            // Set return values of service layer functions
+            given(challengeService.getChallenge(challengeId)).willReturn(challenge);
+            given(milestoneService.getMilestoneDTOById(milestoneId)).willReturn(milestone);
+
+            // Http request path
+            final String URI = String.format("/user/challenge/complete?challengeId=%d&milestoneId=%d",
+                    challengeId,
+                    milestoneId);
+
+            // Perform http request
+            mvc.perform(post(URI)).andExpect(status().isBadRequest());
+        }
     }
-  }
+
+    @Test
+    public void completeChallenge_badRequestWhenUserDoesNotOwnMilestone() throws Exception {
+        try (MockedStatic<CurrentUserService> utilities = Mockito.mockStatic(CurrentUserService.class)) {
+            // Copy the default values used for testing
+            final ChallengeDTO challenge = TEST_CHALLENGE.toBuilder().build();
+            final MilestoneDTO milestone = TEST_MILESTONE.toBuilder().username(TEST_USERNAME_OTHER).build();
+            final Long challengeId = challenge.getChallengeId();
+            final Long milestoneId = milestone.getMilestoneId();
+
+            // Set the currently logged-in user to the owner of the challenge and milestone
+            utilities.when(CurrentUserService::getCurrentUsername).thenReturn(TEST_USERNAME);
+
+            // Stub the service call
+            doNothing().when(challengeService).completeChallengeForCurrentUser(challengeId, milestoneId);
+
+            // Set return values of service layer functions
+            given(challengeService.getChallenge(challengeId)).willReturn(challenge);
+            given(milestoneService.getMilestoneDTOById(milestoneId)).willReturn(milestone);
+
+            // Http request path
+            final String URI = String.format("/user/challenge/complete?challengeId=%d&milestoneId=%d",
+                    challengeId,
+                    milestoneId);
+
+            // Perform http request
+            mvc.perform(post(URI)).andExpect(status().isBadRequest());
+        }
+    }
+
+    @Test
+    public void moveChallengeToLog_badRequestWhenUserDoesNotOwnChallenge() throws Exception {
+        try (MockedStatic<CurrentUserService> utilities = Mockito.mockStatic(CurrentUserService.class)) {
+            // Copy the default values used for testing
+            final ChallengeDTO challenge = TEST_CHALLENGE.toBuilder().username(TEST_USERNAME_OTHER).build();
+            final Long challengeId = challenge.getChallengeId();
+
+            // Set the currently logged-in user to the owner of the challenge and milestone
+            utilities.when(CurrentUserService::getCurrentUsername).thenReturn(TEST_USERNAME);
+
+            // Stub the service call
+            doNothing().when(challengeService).moveChallengeToLog(challengeId);
+
+            // Set return values of service layer functions
+            given(challengeService.getChallenge(challengeId)).willReturn(challenge);
+
+            // Http request path
+            final String URI = "/user/challenge/delete/" + challengeId;
+
+            // Perform http request
+            mvc.perform(delete(URI)).andExpect(status().is4xxClientError());
+        }
+    }
+
 }
diff --git a/src/test/java/idatt2106/systemutvikling/sparesti/service/ChallengeServiceTest.java b/src/test/java/idatt2106/systemutvikling/sparesti/service/ChallengeServiceTest.java
index 54f5ea1296680a2997b76ab5504e3fd28aa90e76..982f9b1d63c3c128bd89056fb0e75960975dc711 100644
--- a/src/test/java/idatt2106/systemutvikling/sparesti/service/ChallengeServiceTest.java
+++ b/src/test/java/idatt2106/systemutvikling/sparesti/service/ChallengeServiceTest.java
@@ -1,7 +1,9 @@
 package idatt2106.systemutvikling.sparesti.service;
 
 import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.BDDMockito.given;
 import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
 
 import idatt2106.systemutvikling.sparesti.dao.ChallengeDAO;
 import idatt2106.systemutvikling.sparesti.dao.ChallengeLogDAO;
@@ -16,23 +18,29 @@ import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.List;
 
+import org.aspectj.lang.annotation.Before;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Test;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
+import org.mockito.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.data.domain.*;
+import org.springframework.test.context.TestPropertySource;
 import org.springframework.test.util.ReflectionTestUtils;
 
 
+@AutoConfigureMockMvc(addFilters = false)
+@TestPropertySource(locations = "classpath:application-integrationtest.properties")
+@DataJpaTest
 public class ChallengeServiceTest {
 
-  @Mock
+  @MockBean
   private ChallengeRepository challengeRepository;
 
-  @Mock
+  @MockBean
   private ChallengeLogRepository challengeLogRepository;
 
   @InjectMocks
@@ -40,10 +48,40 @@ public class ChallengeServiceTest {
 
   @BeforeEach
   public void setup() {
-    MockitoAnnotations.openMocks(this);
-    challengeRepository = Mockito.mock(ChallengeRepository.class);
-    challengeLogRepository = Mockito.mock(ChallengeLogRepository.class);
     ReflectionTestUtils.setField(challengeService, "challengeRepository", challengeRepository);
+    ReflectionTestUtils.setField(challengeService, "challengeLogRepository", challengeLogRepository);
+  }
+
+  @Test
+  @DisplayName("Verify that ChallengeService::createChallenge cannot register challenges on other users")
+  public void createChallenge_CannotRegisterChallengesOnOtherUsers() {
+    String loggedInUsername = "Original user";
+    String targetUsername = "Other user";
+
+    ChallengeDTO dto = new ChallengeDTO(
+      451L,
+            targetUsername,
+      "Tricked you >:D",
+      "This is a challenge from \"Other user\"",
+      100_000_000L,
+      0L,
+      LocalDateTime.now(),
+      LocalDateTime.now().plusDays(2),
+      0,
+      true
+    );
+
+    try (MockedStatic<CurrentUserService> utilities = mockStatic(CurrentUserService.class)) {
+      utilities.when(CurrentUserService::getCurrentUsername).thenReturn(loggedInUsername);
+      challengeService.createChallenge(dto);
+    }
+
+    ArgumentCaptor<ChallengeDAO> argumentCaptor = ArgumentCaptor.forClass(ChallengeDAO.class);
+    verify(challengeRepository, times(1)).save(argumentCaptor.capture());
+
+    ChallengeDAO argument = argumentCaptor.getValue();
+    assertNotEquals(targetUsername, argument.getUserDAO().getUsername());
+    assertEquals(loggedInUsername, argument.getUserDAO().getUsername());
   }
 
   @Test
@@ -57,7 +95,7 @@ public class ChallengeServiceTest {
     List<ChallengeDAO> challenges = List.of(challenge, challenge2);
 
     when(challengeRepository.findChallengeDAOByActiveAndUserDAO_Username(true,
-        "username")).thenReturn(challenges);
+            "username")).thenReturn(challenges);
 
     assertEquals(challenges, challengeService.getChallengesByActiveAndUsername("username", true));
   }
@@ -222,8 +260,8 @@ public class ChallengeServiceTest {
   }
 
   @Test
-  @DisplayName("Test completeChallenge completes a challenge")
-  void testCompleteChallenge() {
+  @DisplayName("Test archiveActiveChallenge completes a challenge")
+  void testArchiveActiveChallenge() {
     UserDAO user1 = new UserDAO();
     user1.setUsername("JohnSmith12");
 
@@ -242,11 +280,15 @@ public class ChallengeServiceTest {
     challengeLogDAO.setCompletionDate(LocalDateTime.now());
     challengeLogDAO.setUserDAO(user1);
 
-    when(challengeRepository.findChallengeDAOByChallengeId(1L)).thenReturn(challenge1);
-    when(challengeRepository.save(challenge1)).thenReturn(challenge1);
+    given(challengeRepository.findChallengeDAOByChallengeId(challenge1.getChallengeId())).willReturn(challenge1);
+    ArgumentCaptor<ChallengeLogDAO> challengeLogDAOCaptor = ArgumentCaptor.forClass(ChallengeLogDAO.class);
 
-    assertEquals(challengeLogDAO.getChallengeId(),
-        challengeService.completeChallenge(1L).getChallengeId());
+    // Act
+    challengeService.archiveActiveChallenge(challenge1.getChallengeId());
+    verify(challengeLogRepository, times(1)).save(challengeLogDAOCaptor.capture());
+
+    // Assert
+    assertEquals(challenge1.getChallengeId(), challengeLogDAOCaptor.getValue().getChallengeId());
   }
 
   @Test