From 67ab8fba8cc9f4d006c6b270c9886dab6e09eb9c Mon Sep 17 00:00:00 2001 From: sdikyarts Date: Wed, 15 May 2024 20:39:39 +0700 Subject: [PATCH 1/2] Modify async --- .../config/AsyncConfiguration.java | 26 +++--- .../controller/AdminController.java | 35 ++++---- .../service/AdminService.java | 13 +-- .../service/AdminServiceImpl.java | 34 ++++---- .../controller/AdminControllerTest.java | 81 +++++++++++++++++-- .../service/AdminServiceImplTest.java | 57 ++++++++++--- 6 files changed, 179 insertions(+), 67 deletions(-) diff --git a/src/main/java/snackscription/subscriptionadmin/config/AsyncConfiguration.java b/src/main/java/snackscription/subscriptionadmin/config/AsyncConfiguration.java index 7237d9a..0ea1381 100644 --- a/src/main/java/snackscription/subscriptionadmin/config/AsyncConfiguration.java +++ b/src/main/java/snackscription/subscriptionadmin/config/AsyncConfiguration.java @@ -1,22 +1,22 @@ package snackscription.subscriptionadmin.config; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.AsyncTaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; -import java.util.concurrent.Executor; - @Configuration @EnableAsync -public class AsyncConfiguration { - @Bean("asyncTaskExecutor") - public Executor asyncTaskExecutor(){ - ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); - taskExecutor.setCorePoolSize(4); - taskExecutor.setQueueCapacity(150); - taskExecutor.setThreadNamePrefix("AsyncTaskThread-"); - taskExecutor.initialize(); - return taskExecutor; +public class AsyncConfiguration implements AsyncConfigurer { + @Override + public AsyncTaskExecutor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(5); + executor.setMaxPoolSize(10); + executor.setQueueCapacity(100); + executor.setThreadNamePrefix("Async-Executor-"); + executor.initialize(); + return executor; } -} +} \ No newline at end of file diff --git a/src/main/java/snackscription/subscriptionadmin/controller/AdminController.java b/src/main/java/snackscription/subscriptionadmin/controller/AdminController.java index 59f55c6..1ab96cf 100644 --- a/src/main/java/snackscription/subscriptionadmin/controller/AdminController.java +++ b/src/main/java/snackscription/subscriptionadmin/controller/AdminController.java @@ -1,6 +1,5 @@ package snackscription.subscriptionadmin.controller; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import snackscription.subscriptionadmin.dto.AdminDTO; @@ -8,6 +7,8 @@ import snackscription.subscriptionadmin.service.AdminService; import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; @RestController @RequestMapping("/admin") @@ -20,32 +21,34 @@ public AdminController(AdminService adminService) { } @PostMapping("/create") - public ResponseEntity create(@RequestBody AdminDTO adminDTO) { - AdminSubscription adminSubscription = adminService.create(adminDTO); - return new ResponseEntity<>(adminSubscription, HttpStatus.CREATED); + public CompletableFuture> create(@RequestBody AdminDTO adminDTO) { + return adminService.create(adminDTO).thenApply(ResponseEntity::ok) + .exceptionally(ex -> ResponseEntity.badRequest().build()); + } @GetMapping("/list") - public ResponseEntity> findAll() { - List adminDTOList = adminService.findAll(); - return new ResponseEntity<>(adminDTOList, HttpStatus.OK); + public CompletableFuture>> findAll() { + return adminService.findAll().thenApply(ResponseEntity::ok) + .exceptionally(ex -> ResponseEntity.badRequest().build()); } @GetMapping("/{subscriptionId}") - public ResponseEntity findById(@PathVariable String subscriptionId) { - AdminDTO adminDTO = adminService.findById(subscriptionId); - return new ResponseEntity<>(adminDTO, HttpStatus.OK); + public CompletableFuture>> findById(@PathVariable String subscriptionId) { + return adminService.findById(subscriptionId).thenApply(ResponseEntity::ok) + .exceptionally(ex -> ResponseEntity.badRequest().build()); } + @PutMapping("/update") - public ResponseEntity update(@RequestBody AdminDTO adminDTO) { - AdminSubscription adminSubscription = adminService.update(adminDTO); - return new ResponseEntity<>(adminSubscription, HttpStatus.OK); + public CompletableFuture> update(@RequestBody AdminDTO adminDTO) { + return adminService.update(adminDTO).thenApply(ResponseEntity::ok) + .exceptionally(ex -> ResponseEntity.badRequest().build()); } @DeleteMapping("/{subscriptionId}") - public ResponseEntity delete(@PathVariable String subscriptionId) { - adminService.delete(subscriptionId); - return new ResponseEntity<>(HttpStatus.NO_CONTENT); + public CompletableFuture> delete(@PathVariable String subscriptionId) { + return adminService.delete(subscriptionId).thenApply(result -> ResponseEntity.ok("DELETE SUCCESS")) + .exceptionally(ex -> ResponseEntity.notFound().build()); } } \ No newline at end of file diff --git a/src/main/java/snackscription/subscriptionadmin/service/AdminService.java b/src/main/java/snackscription/subscriptionadmin/service/AdminService.java index 48774b6..9ef4b0f 100644 --- a/src/main/java/snackscription/subscriptionadmin/service/AdminService.java +++ b/src/main/java/snackscription/subscriptionadmin/service/AdminService.java @@ -3,12 +3,15 @@ import snackscription.subscriptionadmin.dto.AdminDTO; import snackscription.subscriptionadmin.model.AdminSubscription; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; + import java.util.List; public interface AdminService { - AdminSubscription create(AdminDTO adminDTO); - List findAll(); - AdminDTO findById(String subscriptionId); - AdminSubscription update(AdminDTO adminDTO); - void delete(String subscriptionId); + CompletableFuture create(AdminDTO adminDTO); + CompletableFuture> findAll(); + CompletableFuture> findById(String subscriptionId); + CompletableFuture update(AdminDTO adminDTO); + CompletableFuture delete(String subscriptionId); } \ No newline at end of file diff --git a/src/main/java/snackscription/subscriptionadmin/service/AdminServiceImpl.java b/src/main/java/snackscription/subscriptionadmin/service/AdminServiceImpl.java index 6085aaa..319e7dc 100644 --- a/src/main/java/snackscription/subscriptionadmin/service/AdminServiceImpl.java +++ b/src/main/java/snackscription/subscriptionadmin/service/AdminServiceImpl.java @@ -5,8 +5,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import snackscription.subscriptionadmin.dto.AdminDTO; +import org.springframework.scheduling.annotation.Async; import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; import snackscription.subscriptionadmin.dto.DTOMapper; @@ -17,21 +21,24 @@ public class AdminServiceImpl implements AdminService{ private AdminRepository adminRepository; @Override - public AdminSubscription create(AdminDTO adminDTO) { + @Async + public CompletableFuture create(AdminDTO adminDTO) { AdminSubscription adminSubscription = DTOMapper.convertDTOtoModel(adminDTO); - return adminRepository.create(adminSubscription); + return CompletableFuture.completedFuture(adminRepository.create(adminSubscription)); } @Override - public List findAll() { - return adminRepository.findAll() + @Async + public CompletableFuture> findAll() { + return CompletableFuture.completedFuture(adminRepository.findAll() .stream() .map(DTOMapper::convertModelToDto) - .toList(); + .collect(Collectors.toList())); } @Override - public AdminDTO findById(String subscriptionId) { + @Async + public CompletableFuture> findById(String subscriptionId) { if(subscriptionId == null || subscriptionId.isBlank()){ throw new IllegalArgumentException("ID cannot be null or empty"); } @@ -39,11 +46,12 @@ public AdminDTO findById(String subscriptionId) { AdminSubscription adminSubscription = adminRepository.findById(subscriptionId) .orElseThrow(() -> new IllegalArgumentException("Subscription not found")); - return DTOMapper.convertModelToDto(adminSubscription); + return CompletableFuture.completedFuture(Optional.of(DTOMapper.convertModelToDto(adminSubscription))); } @Override - public AdminSubscription update(AdminDTO adminDTO) { + @Async + public CompletableFuture update(AdminDTO adminDTO) { if(adminDTO == null) { throw new IllegalArgumentException("AdminDTO cannot be null"); } @@ -52,19 +60,17 @@ public AdminSubscription update(AdminDTO adminDTO) { .orElseThrow(() -> new IllegalArgumentException("Subscription not found")); DTOMapper.updateAdminSubscription(adminSubscription, adminDTO); - return adminRepository.update(adminSubscription); + return CompletableFuture.completedFuture(adminRepository.update(adminSubscription)); } @Override - public void delete(String subscriptionId) { + @Async + public CompletableFuture delete(String subscriptionId) { if(subscriptionId == null || subscriptionId.isBlank()){ throw new IllegalArgumentException("ID cannot be null or empty"); } - if(adminRepository.findById(subscriptionId).isEmpty()){ - throw new IllegalArgumentException("Subscription not found"); - } - adminRepository.delete(subscriptionId); + return CompletableFuture.completedFuture(null); } } \ No newline at end of file diff --git a/src/test/java/snackscription/subscriptionadmin/controller/AdminControllerTest.java b/src/test/java/snackscription/subscriptionadmin/controller/AdminControllerTest.java index 62b8345..20363c4 100644 --- a/src/test/java/snackscription/subscriptionadmin/controller/AdminControllerTest.java +++ b/src/test/java/snackscription/subscriptionadmin/controller/AdminControllerTest.java @@ -4,7 +4,6 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import snackscription.subscriptionadmin.dto.AdminDTO; import snackscription.subscriptionadmin.model.AdminSubscription; @@ -12,8 +11,10 @@ import java.util.Collections; import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; public class AdminControllerTest { @@ -24,16 +25,82 @@ public class AdminControllerTest { @InjectMocks private AdminController adminController; - public AdminControllerTest() { + private AdminDTO adminDTO; + private AdminSubscription adminSubscription; + + @Test + void setUp(){ MockitoAnnotations.openMocks(this); + + adminDTO = new AdminDTO(); + adminDTO.setSubscriptionId("1"); + adminDTO.setSubscriptionType("MONTHLY"); + adminDTO.setSubscriberName("Stray Kids"); + adminDTO.setSubscriberId("0325"); + adminDTO.setSubscriptionBoxId("143ily"); + adminDTO.setSubscriptionStatus("PENDING"); + + adminSubscription = new AdminSubscription(); + adminSubscription.setSubscriptionId("1"); + adminSubscription.setSubscriptionType("MONTHLY"); + adminSubscription.setSubscriberName("Stray Kids"); + adminSubscription.setSubscriberId("0325"); + adminSubscription.setSubscriptionBoxId("143ily"); + adminSubscription.setSubscriptionStatus("PENDING"); + } + + @Test + void testCreate(){ + when(adminService.create(adminDTO)).thenReturn(CompletableFuture.completedFuture(adminSubscription)); + + CompletableFuture> result = adminController.create(adminDTO); + + assertNotNull(result); + assertTrue(result.isDone()); + assertEquals(ResponseEntity.ok(adminSubscription), result.join()); + } + + @Test + void testFindAll(){ + when(adminService.findAll()).thenReturn(CompletableFuture.completedFuture(Collections.singletonList(adminDTO))); + + CompletableFuture>> result = adminController.findAll(); + + assertNotNull(result); + assertTrue(result.isDone()); + assertEquals(ResponseEntity.ok(Collections.singletonList(adminDTO)), result.join()); + } + + @Test + void testFindById(){ + when(adminService.findById("1")).thenReturn(CompletableFuture.completedFuture(Optional.of(adminDTO))); + + CompletableFuture>> result = adminController.findById("1"); + + assertNotNull(result); + assertTrue(result.isDone()); + assertEquals(ResponseEntity.ok(Optional.of(adminDTO)), result.join()); + } + + @Test + void testUpdate(){ + when(adminService.update(adminDTO)).thenReturn(CompletableFuture.completedFuture(adminSubscription)); + + CompletableFuture> result = adminController.update(adminDTO); + + assertNotNull(result); + assertTrue(result.isDone()); + assertEquals(ResponseEntity.ok(adminSubscription), result.join()); } @Test - void testCreate() { - List adminDTOList = Collections.singletonList(new AdminDTO()); + void testDelete(){ + when(adminService.delete("1")).thenReturn(CompletableFuture.completedFuture(null)); - when(adminService.findAll()).thenReturn(adminDTOList); + CompletableFuture> result = adminController.delete("1"); - ResponseEntity> responseEntity = adminController.findAll(); + assertNotNull(result); + assertTrue(result.isDone()); + assertEquals(ResponseEntity.ok("DELETE SUCCESS"), result.join()); } } diff --git a/src/test/java/snackscription/subscriptionadmin/service/AdminServiceImplTest.java b/src/test/java/snackscription/subscriptionadmin/service/AdminServiceImplTest.java index cd95a40..406b58f 100644 --- a/src/test/java/snackscription/subscriptionadmin/service/AdminServiceImplTest.java +++ b/src/test/java/snackscription/subscriptionadmin/service/AdminServiceImplTest.java @@ -8,13 +8,16 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.springframework.http.ResponseEntity; +import snackscription.subscriptionadmin.controller.AdminController; import snackscription.subscriptionadmin.dto.AdminDTO; import snackscription.subscriptionadmin.factory.AdminSubscriptionFactory; import snackscription.subscriptionadmin.model.AdminSubscription; import snackscription.subscriptionadmin.repository.AdminRepository; -import java.util.Collections; import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; public class AdminServiceImplTest { @@ -26,6 +29,7 @@ public class AdminServiceImplTest { @InjectMocks private AdminServiceImpl adminService; + private AdminController adminController; private AdminSubscription adminSubscription; private AdminDTO adminDTO; @@ -55,33 +59,62 @@ void setUp() { @Test void testCreate() { - when(adminRepository.create(any(AdminSubscription.class))).thenReturn(adminSubscription); + when(adminRepository.create(adminSubscription)).thenReturn(adminSubscription); - AdminSubscription result = adminService.create(adminDTO); + CompletableFuture result = adminService.create(adminDTO); assertNotNull(result); - assertEquals(adminSubscription, result); + assertTrue(result.isDone()); + assertEquals(adminSubscription, result.join()); } @Test void testFindAll() { - when(adminRepository.findAll()).thenReturn(Collections.singletonList(adminSubscription)); + List adminDTOList = List.of(adminDTO); - List result = adminService.findAll(); + when(adminService.findAll()).thenReturn(CompletableFuture.completedFuture(adminDTOList)); - assertEquals(1, result.size()); - assertEquals(adminSubscription.getSubscriptionId(), result.get(0).getSubscriptionId()); + CompletableFuture>> result = adminController.findAll(); + + assertNotNull(result); + assertTrue(result.isDone()); + assertEquals(ResponseEntity.ok(adminDTOList), result.join()); } @Test void testFindById() { - String subscriptionId = "1"; + Optional adminDTOOptional = Optional.of(adminDTO); + + when(adminRepository.findById(anyString())).thenReturn(Optional.of(adminSubscription)); + when(adminService.findById(anyString())).thenReturn(CompletableFuture.completedFuture(adminDTOOptional)); + + CompletableFuture>> result = adminController.findById("1"); + + assertNotNull(result); + assertTrue(result.isDone()); + assertEquals(ResponseEntity.ok(adminDTOOptional), result.join()); + } - when(adminRepository.findById(subscriptionId)).thenReturn(java.util.Optional.of(adminSubscription)); + @Test + void testUpdate() { + when(adminService.findById(adminDTO.getSubscriptionId())).thenReturn(CompletableFuture.completedFuture(Optional.of(adminDTO))); + when(adminService.update(adminDTO)).thenReturn(CompletableFuture.completedFuture(adminSubscription)); + + CompletableFuture> result = adminController.update(adminDTO); + + assertNotNull(result); + assertTrue(result.isDone()); + assertEquals(ResponseEntity.ok(adminSubscription), result.join()); + } + + @Test + void testDelete() { + when(adminService.delete(anyString())).thenReturn(CompletableFuture.completedFuture(null)); - AdminDTO result = adminService.findById(subscriptionId); + CompletableFuture> result = adminController.delete("1"); assertNotNull(result); - assertEquals(adminSubscription.getSubscriptionId(), result.getSubscriptionId()); + assertTrue(result.isDone()); + assertEquals(ResponseEntity.ok("DELETE SUCCESS"), result.join()); } } From 37fe08e2c6b0d399f2be909b08b1df34d93cf839 Mon Sep 17 00:00:00 2001 From: sdikyarts Date: Sat, 25 May 2024 22:49:37 +0700 Subject: [PATCH 2/2] Fix async implementation --- .../controller/AdminController.java | 27 +++++++--- .../subscriptionadmin/dto/DTOMapper.java | 17 ++++--- .../service/AdminService.java | 2 +- .../service/AdminServiceImpl.java | 30 ++++++----- src/main/resources/application-dev.properties | 2 +- .../resources/application-prod.properties | 2 +- .../resources/application-test.properties | 2 +- .../controller/AdminControllerTest.java | 51 +++++++++---------- .../service/AdminServiceImplTest.java | 42 +++++++-------- 9 files changed, 95 insertions(+), 80 deletions(-) diff --git a/src/main/java/snackscription/subscriptionadmin/controller/AdminController.java b/src/main/java/snackscription/subscriptionadmin/controller/AdminController.java index 1ab96cf..de7d02e 100644 --- a/src/main/java/snackscription/subscriptionadmin/controller/AdminController.java +++ b/src/main/java/snackscription/subscriptionadmin/controller/AdminController.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Optional; +import java.util.UUID; import java.util.concurrent.CompletableFuture; @RestController @@ -29,26 +30,38 @@ public CompletableFuture> create(@RequestBody @GetMapping("/list") public CompletableFuture>> findAll() { - return adminService.findAll().thenApply(ResponseEntity::ok) - .exceptionally(ex -> ResponseEntity.badRequest().build()); + return adminService.findAll().thenApply(ResponseEntity::ok); } @GetMapping("/{subscriptionId}") - public CompletableFuture>> findById(@PathVariable String subscriptionId) { + public CompletableFuture> findById(@PathVariable String subscriptionId) { + try { + UUID.fromString(subscriptionId); + } catch (IllegalArgumentException e) { + return CompletableFuture.completedFuture(ResponseEntity.badRequest().build()); + } return adminService.findById(subscriptionId).thenApply(ResponseEntity::ok) - .exceptionally(ex -> ResponseEntity.badRequest().build()); + .exceptionally(ex -> ResponseEntity.notFound().build()); } - @PutMapping("/update") public CompletableFuture> update(@RequestBody AdminDTO adminDTO) { + if (adminDTO.getSubscriptionId() == null) { + return CompletableFuture.completedFuture(ResponseEntity.badRequest().build()); + } + return adminService.update(adminDTO).thenApply(ResponseEntity::ok) - .exceptionally(ex -> ResponseEntity.badRequest().build()); + .exceptionally(ex -> ResponseEntity.notFound().build()); } @DeleteMapping("/{subscriptionId}") public CompletableFuture> delete(@PathVariable String subscriptionId) { - return adminService.delete(subscriptionId).thenApply(result -> ResponseEntity.ok("DELETE SUCCESS")) + try { + UUID.fromString(subscriptionId); + } catch (IllegalArgumentException e) { + return CompletableFuture.completedFuture(ResponseEntity.badRequest().build()); + } + return adminService.delete(subscriptionId).thenApply(deleted -> ResponseEntity.ok("DELETE SUCCESS")) .exceptionally(ex -> ResponseEntity.notFound().build()); } } \ No newline at end of file diff --git a/src/main/java/snackscription/subscriptionadmin/dto/DTOMapper.java b/src/main/java/snackscription/subscriptionadmin/dto/DTOMapper.java index e73a195..b81c1db 100644 --- a/src/main/java/snackscription/subscriptionadmin/dto/DTOMapper.java +++ b/src/main/java/snackscription/subscriptionadmin/dto/DTOMapper.java @@ -10,14 +10,15 @@ public class DTOMapper { public static AdminDTO convertModelToDto(AdminSubscription adminSubscription) { - return new AdminDTO( - adminSubscription.getSubscriptionId(), - adminSubscription.getUniqueCode(), - adminSubscription.getSubscriberName(), - adminSubscription.getSubscriberId(), - adminSubscription.getSubscriptionBoxId(), - adminSubscription.getSubscriptionStatus() - ); + AdminDTO adminDTO = new AdminDTO(); + adminDTO.setSubscriptionId(adminSubscription.getSubscriptionId()); + adminDTO.setSubscriptionType(adminSubscription.getSubscriptionType()); + adminDTO.setSubscriberName(adminSubscription.getSubscriberName()); + adminDTO.setSubscriberId(adminSubscription.getSubscriberId()); + adminDTO.setSubscriptionBoxId(adminSubscription.getSubscriptionBoxId()); + adminDTO.setSubscriptionStatus(adminSubscription.getSubscriptionStatus()); + adminDTO.setUniqueCode(adminSubscription.getUniqueCode()); + return adminDTO; } public static AdminSubscription convertDTOtoModel(AdminDTO adminDTO) { diff --git a/src/main/java/snackscription/subscriptionadmin/service/AdminService.java b/src/main/java/snackscription/subscriptionadmin/service/AdminService.java index 9ef4b0f..57641e7 100644 --- a/src/main/java/snackscription/subscriptionadmin/service/AdminService.java +++ b/src/main/java/snackscription/subscriptionadmin/service/AdminService.java @@ -11,7 +11,7 @@ public interface AdminService { CompletableFuture create(AdminDTO adminDTO); CompletableFuture> findAll(); - CompletableFuture> findById(String subscriptionId); + CompletableFuture findById(String subscriptionId); CompletableFuture update(AdminDTO adminDTO); CompletableFuture delete(String subscriptionId); } \ No newline at end of file diff --git a/src/main/java/snackscription/subscriptionadmin/service/AdminServiceImpl.java b/src/main/java/snackscription/subscriptionadmin/service/AdminServiceImpl.java index 319e7dc..8e4d0eb 100644 --- a/src/main/java/snackscription/subscriptionadmin/service/AdminServiceImpl.java +++ b/src/main/java/snackscription/subscriptionadmin/service/AdminServiceImpl.java @@ -8,12 +8,12 @@ import org.springframework.scheduling.annotation.Async; import java.util.List; -import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import snackscription.subscriptionadmin.dto.DTOMapper; + @Service public class AdminServiceImpl implements AdminService{ @@ -30,23 +30,24 @@ public CompletableFuture create(AdminDTO adminDTO) { @Override @Async public CompletableFuture> findAll() { - return CompletableFuture.completedFuture(adminRepository.findAll() - .stream() + List adminSubscriptions = adminRepository.findAll(); + List adminDtos = adminSubscriptions.stream() .map(DTOMapper::convertModelToDto) - .collect(Collectors.toList())); + .collect(Collectors.toList()); + return CompletableFuture.completedFuture(adminDtos); } @Override @Async - public CompletableFuture> findById(String subscriptionId) { + public CompletableFuture findById(String subscriptionId) { if(subscriptionId == null || subscriptionId.isBlank()){ throw new IllegalArgumentException("ID cannot be null or empty"); } - AdminSubscription adminSubscription = adminRepository.findById(subscriptionId) + return adminRepository.findById(subscriptionId) + .map(DTOMapper::convertModelToDto) + .map(CompletableFuture::completedFuture) .orElseThrow(() -> new IllegalArgumentException("Subscription not found")); - - return CompletableFuture.completedFuture(Optional.of(DTOMapper.convertModelToDto(adminSubscription))); } @Override @@ -56,11 +57,11 @@ public CompletableFuture update(AdminDTO adminDTO) { throw new IllegalArgumentException("AdminDTO cannot be null"); } - AdminSubscription adminSubscription = adminRepository.findById(adminDTO.getSubscriptionId()) - .orElseThrow(() -> new IllegalArgumentException("Subscription not found")); - - DTOMapper.updateAdminSubscription(adminSubscription, adminDTO); - return CompletableFuture.completedFuture(adminRepository.update(adminSubscription)); + return adminRepository.findById(adminDTO.getSubscriptionId()). + map(adminSubscription -> { + DTOMapper.updateAdminSubscription(adminSubscription, adminDTO); + return CompletableFuture.completedFuture(adminRepository.update(adminSubscription)); + }).orElseThrow(() -> new IllegalArgumentException("Subscription not found")); } @Override @@ -70,6 +71,9 @@ public CompletableFuture delete(String subscriptionId) { throw new IllegalArgumentException("ID cannot be null or empty"); } + if (adminRepository.findById(subscriptionId).isEmpty()) { + throw new IllegalArgumentException("Subscription not found"); + } adminRepository.delete(subscriptionId); return CompletableFuture.completedFuture(null); } diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index ffe5daf..137369d 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -1,4 +1,4 @@ -spring.datasource.url=jdbc:postgresql://localhost:5432/subscription-admin/ +spring.datasource.url=jdbc:postgresql://postgres:5432/subscription-admin/ spring.datasource.username=postgres spring.datasource.password=postgres spring.jpa.hibernate.ddl-auto=create-drop diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties index 52b03e0..209fd70 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-prod.properties @@ -1,4 +1,4 @@ -spring.datasource.url=jdbc:postgresql://aws-0-ap-southeast-1.pooler.supabase.com:5432/postgres?user=postgres.thnfvhxtvcbfxndlxdze&password=YouMakeStrayKidsStay +spring.datasource.url=jdbc:postgresql://aws-0-ap-southeast-1.pooler.supabase.com:5432/postgres spring.datasource.username=postgres.thnfvhxtvcbfxndlxdze spring.datasource.password=YouMakeStrayKidsStay spring.jpa.hibernate.ddl-auto=update diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties index 0a5230d..207a451 100644 --- a/src/main/resources/application-test.properties +++ b/src/main/resources/application-test.properties @@ -1,4 +1,4 @@ -spring.datasource.url=jdbc:postgresql://postgres:5432/subscription-admin +spring.datasource.url=jdbc:postgresql://postgres:5432/subscription-admin/ spring.datasource.username=postgres spring.datasource.password=postgres spring.jpa.hibernate.ddl-auto=create diff --git a/src/test/java/snackscription/subscriptionadmin/controller/AdminControllerTest.java b/src/test/java/snackscription/subscriptionadmin/controller/AdminControllerTest.java index 20363c4..1468c42 100644 --- a/src/test/java/snackscription/subscriptionadmin/controller/AdminControllerTest.java +++ b/src/test/java/snackscription/subscriptionadmin/controller/AdminControllerTest.java @@ -1,6 +1,6 @@ package snackscription.subscriptionadmin.controller; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.*; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -28,7 +28,7 @@ public class AdminControllerTest { private AdminDTO adminDTO; private AdminSubscription adminSubscription; - @Test + @BeforeEach void setUp(){ MockitoAnnotations.openMocks(this); @@ -53,54 +53,51 @@ void setUp(){ void testCreate(){ when(adminService.create(adminDTO)).thenReturn(CompletableFuture.completedFuture(adminSubscription)); - CompletableFuture> result = adminController.create(adminDTO); - - assertNotNull(result); - assertTrue(result.isDone()); - assertEquals(ResponseEntity.ok(adminSubscription), result.join()); + CompletableFuture> response = adminController.create(adminDTO); + assertNotNull(response); + assertEquals(ResponseEntity.ok(adminSubscription), response.join()); } @Test void testFindAll(){ - when(adminService.findAll()).thenReturn(CompletableFuture.completedFuture(Collections.singletonList(adminDTO))); + List adminDTOList = Collections.singletonList(adminDTO); + when(adminService.findAll()).thenReturn(CompletableFuture.completedFuture(adminDTOList)); - CompletableFuture>> result = adminController.findAll(); - - assertNotNull(result); - assertTrue(result.isDone()); - assertEquals(ResponseEntity.ok(Collections.singletonList(adminDTO)), result.join()); + CompletableFuture>> response = adminController.findAll(); + assertNotNull(response); + assertEquals(ResponseEntity.ok(adminDTOList), response.join()); } @Test void testFindById(){ - when(adminService.findById("1")).thenReturn(CompletableFuture.completedFuture(Optional.of(adminDTO))); + String validUUID = "8a56e04b-d0c8-4e43-b2e0-fdf43e304d9e"; + adminDTO.setSubscriptionId(validUUID); + adminSubscription.setSubscriptionId(validUUID); + when(adminService.findById(validUUID)).thenReturn(CompletableFuture.completedFuture(adminDTO)); - CompletableFuture>> result = adminController.findById("1"); + CompletableFuture> result = adminController.findById(validUUID); assertNotNull(result); assertTrue(result.isDone()); - assertEquals(ResponseEntity.ok(Optional.of(adminDTO)), result.join()); + assertEquals(ResponseEntity.ok(adminDTO), result.join()); } @Test void testUpdate(){ when(adminService.update(adminDTO)).thenReturn(CompletableFuture.completedFuture(adminSubscription)); - CompletableFuture> result = adminController.update(adminDTO); - - assertNotNull(result); - assertTrue(result.isDone()); - assertEquals(ResponseEntity.ok(adminSubscription), result.join()); + CompletableFuture> response = adminController.update(adminDTO); + assertNotNull(response); + assertEquals(ResponseEntity.ok(adminSubscription), response.join()); } @Test void testDelete(){ - when(adminService.delete("1")).thenReturn(CompletableFuture.completedFuture(null)); + String validUUID = "8a56e04b-d0c8-4e43-b2e0-fdf43e304d9e"; + when(adminService.delete(validUUID)).thenReturn(CompletableFuture.completedFuture(null)); - CompletableFuture> result = adminController.delete("1"); - - assertNotNull(result); - assertTrue(result.isDone()); - assertEquals(ResponseEntity.ok("DELETE SUCCESS"), result.join()); + CompletableFuture> response = adminController.delete(validUUID); + assertNotNull(response); + assertEquals(ResponseEntity.ok("DELETE SUCCESS"), response.join()); } } diff --git a/src/test/java/snackscription/subscriptionadmin/service/AdminServiceImplTest.java b/src/test/java/snackscription/subscriptionadmin/service/AdminServiceImplTest.java index 406b58f..e96829f 100644 --- a/src/test/java/snackscription/subscriptionadmin/service/AdminServiceImplTest.java +++ b/src/test/java/snackscription/subscriptionadmin/service/AdminServiceImplTest.java @@ -5,9 +5,11 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.http.ResponseEntity; import snackscription.subscriptionadmin.controller.AdminController; import snackscription.subscriptionadmin.dto.AdminDTO; @@ -19,6 +21,7 @@ import java.util.Optional; import java.util.concurrent.CompletableFuture; +@ExtendWith(MockitoExtension.class) public class AdminServiceImplTest { @Mock @@ -53,13 +56,12 @@ void setUp() { adminSubscription.setSubscriberId("0325"); adminSubscription.setSubscriptionBoxId("143ily"); adminSubscription.setSubscriptionStatus("PENDING"); - - when(adminSubscriptionFactory.create(anyString(), anyString(), anyString(), anyString())).thenReturn(adminSubscription); } + @Test void testCreate() { - when(adminRepository.create(adminSubscription)).thenReturn(adminSubscription); + when(adminRepository.create(any(AdminSubscription.class))).thenReturn(adminSubscription); CompletableFuture result = adminService.create(adminDTO); @@ -70,51 +72,49 @@ void testCreate() { @Test void testFindAll() { - List adminDTOList = List.of(adminDTO); - - when(adminService.findAll()).thenReturn(CompletableFuture.completedFuture(adminDTOList)); + List adminSubscriptions = List.of(adminSubscription); + when(adminRepository.findAll()).thenReturn(adminSubscriptions); - CompletableFuture>> result = adminController.findAll(); + CompletableFuture> result = adminService.findAll(); assertNotNull(result); assertTrue(result.isDone()); - assertEquals(ResponseEntity.ok(adminDTOList), result.join()); + assertEquals(List.of(adminDTO), result.join()); } @Test void testFindById() { - Optional adminDTOOptional = Optional.of(adminDTO); + String id = "1"; + when(adminRepository.findById(id)).thenReturn(Optional.of(adminSubscription)); - when(adminRepository.findById(anyString())).thenReturn(Optional.of(adminSubscription)); - when(adminService.findById(anyString())).thenReturn(CompletableFuture.completedFuture(adminDTOOptional)); - - CompletableFuture>> result = adminController.findById("1"); + CompletableFuture result = adminService.findById(id); assertNotNull(result); assertTrue(result.isDone()); - assertEquals(ResponseEntity.ok(adminDTOOptional), result.join()); + assertEquals(adminDTO, result.join()); } @Test void testUpdate() { - when(adminService.findById(adminDTO.getSubscriptionId())).thenReturn(CompletableFuture.completedFuture(Optional.of(adminDTO))); - when(adminService.update(adminDTO)).thenReturn(CompletableFuture.completedFuture(adminSubscription)); + when(adminRepository.findById(adminDTO.getSubscriptionId())).thenReturn(Optional.of(adminSubscription)); + when(adminRepository.update(adminSubscription)).thenReturn(adminSubscription); - CompletableFuture> result = adminController.update(adminDTO); + CompletableFuture result = adminService.update(adminDTO); assertNotNull(result); assertTrue(result.isDone()); - assertEquals(ResponseEntity.ok(adminSubscription), result.join()); + assertEquals(adminSubscription, result.join()); } @Test void testDelete() { - when(adminService.delete(anyString())).thenReturn(CompletableFuture.completedFuture(null)); + String id = "1"; + when(adminRepository.findById(id)).thenReturn(Optional.of(adminSubscription)); - CompletableFuture> result = adminController.delete("1"); + CompletableFuture result = adminService.delete(id); assertNotNull(result); assertTrue(result.isDone()); - assertEquals(ResponseEntity.ok("DELETE SUCCESS"), result.join()); + assertNull(result.join()); } }