diff --git a/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/SnackscriptionSubscriptionboxApplication.java b/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/SnackscriptionSubscriptionboxApplication.java index 0e6c4d6..4ecf056 100644 --- a/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/SnackscriptionSubscriptionboxApplication.java +++ b/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/SnackscriptionSubscriptionboxApplication.java @@ -2,6 +2,13 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; + +@EnableAsync @SpringBootApplication public class SnackscriptionSubscriptionboxApplication { @@ -10,4 +17,15 @@ public static void main(String[] args) { SpringApplication.run(SnackscriptionSubscriptionboxApplication.class, args); } + @Bean + public Executor taskExecutor () { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(1); + executor.setMaxPoolSize(1); + executor.setQueueCapacity(500); + executor.setThreadNamePrefix("GithubLookup-"); + executor.initialize(); + return executor; + } + } diff --git a/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/controller/ItemController.java b/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/controller/ItemController.java new file mode 100644 index 0000000..46c1d8b --- /dev/null +++ b/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/controller/ItemController.java @@ -0,0 +1,69 @@ +package id.ac.ui.cs.advprog.snackscription_subscriptionbox.controller; + + +import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.Item; +import lombok.Getter; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@RestController +@RequestMapping("/items") +public class ItemController { + + private final List items = new ArrayList<>(); + + @GetMapping + public ResponseEntity> getAllItems() { + return new ResponseEntity<>(items, HttpStatus.OK); + } + + @GetMapping("/{id}") + public ResponseEntity getItemById(@PathVariable String id) { + for (Item item : items) { + if (item.getId().equals(id)) { + return new ResponseEntity<>(item, HttpStatus.OK); + } + } + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + @PostMapping + public ResponseEntity createItem(@RequestBody Item item) { + items.add(item); + return new ResponseEntity<>(item, HttpStatus.CREATED); + } + + @PutMapping("/{id}") + public ResponseEntity updateItem(@PathVariable String id, @RequestBody Item updatedItem) { + for (Item item : items) { + if (item.getId().equals(id)) { + item.setName(updatedItem.getName()); + item.setQuantity(updatedItem.getQuantity()); + return new ResponseEntity<>(item, HttpStatus.OK); + } + } + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteItem(@PathVariable String id) { + for (Item item : items) { + if (item.getId().equals(id)) { + items.remove(item); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + } + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + public void setItems(List items) { + this.items.clear(); + this.items.addAll(items); + } + +} \ No newline at end of file diff --git a/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/factory/Factory.java b/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/factory/Factory.java index 42ddf56..2cf91df 100644 --- a/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/factory/Factory.java +++ b/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/factory/Factory.java @@ -6,6 +6,6 @@ public interface Factory { T create(); - - T create(String id, String name, String type, int price, List items , String description); + T create(String id, String name, int quantity); + T create(String id, String name, String type, int price, List items ); } \ No newline at end of file diff --git a/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/factory/ItemFactory.java b/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/factory/ItemFactory.java new file mode 100644 index 0000000..bea016e --- /dev/null +++ b/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/factory/ItemFactory.java @@ -0,0 +1,23 @@ +package id.ac.ui.cs.advprog.snackscription_subscriptionbox.factory; +import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.Item; + +import java.util.List; + +public class ItemFactory implements Factory { + @Override + public Item create(){ + return new Item(); + } + + public Item create(String id, String name, int quantity){ + return new Item(id, name, quantity); + } + + @Override + public Item create(String id, String name, String type, int price, List items) { + return null; + } +} + + + diff --git a/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/model/Item.java b/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/model/Item.java index b83498d..bf105eb 100644 --- a/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/model/Item.java +++ b/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/model/Item.java @@ -1,6 +1,5 @@ package id.ac.ui.cs.advprog.snackscription_subscriptionbox.model; -import com.fasterxml.jackson.annotation.JsonBackReference; import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; @@ -20,15 +19,13 @@ public class Item { private int quantity; @ManyToMany(mappedBy = "items") - @JsonBackReference private List subscriptionBoxes; + public Item() {} + public Item(String id, String name, int quantity) { this.id = id; this.name = name; this.quantity = quantity; } - - public Item() { - } } \ No newline at end of file diff --git a/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/repository/ItemRepository.java b/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/repository/ItemRepository.java index 1ee048c..184aae5 100644 --- a/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/repository/ItemRepository.java +++ b/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/repository/ItemRepository.java @@ -36,6 +36,11 @@ public Item editItem(Item item) { } return null; } + + public List getAllItems() { + return new ArrayList<>(items); + } + } diff --git a/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/service/ItemService.java b/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/service/ItemService.java new file mode 100644 index 0000000..ed8eda3 --- /dev/null +++ b/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/service/ItemService.java @@ -0,0 +1,13 @@ +package id.ac.ui.cs.advprog.snackscription_subscriptionbox.service; + +import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.Item; +import java.util.List; + +public interface ItemService { + Item createItem(String id, String name, int quantity); + Item getItemById(String id); + Item deleteItem(String id); + Item editItem(String id, String name, int quantity); + List getAllItems(); + +} diff --git a/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/service/ItemServiceImpl.java b/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/service/ItemServiceImpl.java new file mode 100644 index 0000000..f0dc520 --- /dev/null +++ b/src/main/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/service/ItemServiceImpl.java @@ -0,0 +1,56 @@ +package id.ac.ui.cs.advprog.snackscription_subscriptionbox.service; + +import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.Item; +import id.ac.ui.cs.advprog.snackscription_subscriptionbox.repository.ItemRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class ItemServiceImpl implements ItemService { + + private final ItemRepository itemRepository; + + @Autowired + public ItemServiceImpl(ItemRepository itemRepository) { + this.itemRepository = itemRepository; + } + + @Override + public Item createItem(String id, String name, int quantity) { + Item item = new Item(id, name, quantity); + return itemRepository.createItem(item); + } + + @Override + public Item getItemById(String id) { + return itemRepository.getItemById(id); + } + + @Override + public Item deleteItem(String id) { + Item item = itemRepository.getItemById(id); + if (item != null) { + return itemRepository.deleteItem(item); + } + return null; + } + + @Override + public Item editItem(String id, String name, int quantity) { + Item existingItem = itemRepository.getItemById(id); + if (existingItem != null) { + existingItem.setName(name); + existingItem.setQuantity(quantity); + return itemRepository.editItem(existingItem); + } + return null; + } + + @Override + public List getAllItems() { + return itemRepository.getAllItems(); + } +} + diff --git a/src/test/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/controller/ItemControllerTest.java b/src/test/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/controller/ItemControllerTest.java new file mode 100644 index 0000000..76f69af --- /dev/null +++ b/src/test/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/controller/ItemControllerTest.java @@ -0,0 +1,86 @@ +package id.ac.ui.cs.advprog.snackscription_subscriptionbox.controller; + + +import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.Item; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ItemControllerTest { + + private ItemController itemController; + private List items; + + @BeforeEach + public void setUp() { + itemController = new ItemController(); + items = new ArrayList<>(); + items.add(new Item("1", "Snack A", 5)); + items.add(new Item("2", "Snack B", 10)); + itemController.setItems(items); + } + + @Test + public void testGetAllItems() { + ResponseEntity> responseEntity = itemController.getAllItems(); + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + assertEquals(items, responseEntity.getBody()); + } + + @Test + public void testGetItemById() { + ResponseEntity responseEntity = itemController.getItemById("1"); + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + assertEquals("Snack A", Objects.requireNonNull(responseEntity.getBody()).getName()); + } + + @Test + public void testGetItemById_NotFound() { + ResponseEntity responseEntity = itemController.getItemById("100"); + assertEquals(HttpStatus.NOT_FOUND, responseEntity.getStatusCode()); + } + + @Test + public void testCreateItem() { + Item newItem = new Item("3", "Snack C", 8); + ResponseEntity responseEntity = itemController.createItem(newItem); + assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); + assertEquals(newItem, responseEntity.getBody()); + } + + @Test + public void testUpdateItem() { + Item updatedItem = new Item("1", "New Snack A", 7); + ResponseEntity responseEntity = itemController.updateItem("1", updatedItem); + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + assertEquals(updatedItem, responseEntity.getBody()); + } + + @Test + public void testUpdateItem_NotFound() { + Item updatedItem = new Item("100", "New Snack A", 7); + ResponseEntity responseEntity = itemController.updateItem("100", updatedItem); + assertEquals(HttpStatus.NOT_FOUND, responseEntity.getStatusCode()); + } + + @Test + public void testDeleteItem() { + ResponseEntity responseEntity = itemController.deleteItem("1"); + assertEquals(HttpStatus.NO_CONTENT, responseEntity.getStatusCode()); + assertEquals(1, itemController.getItems().size()); + } + + @Test + public void testDeleteItem_NotFound() { + ResponseEntity responseEntity = itemController.deleteItem("100"); + assertEquals(HttpStatus.NOT_FOUND, responseEntity.getStatusCode()); + } + +} diff --git a/src/test/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/factory/ItemFactoryTest.java b/src/test/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/factory/ItemFactoryTest.java new file mode 100644 index 0000000..515a99f --- /dev/null +++ b/src/test/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/factory/ItemFactoryTest.java @@ -0,0 +1,45 @@ +package id.ac.ui.cs.advprog.snackscription_subscriptionbox.factory; + +import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.Item; +import org.junit.jupiter.api.Test; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.*; + +public class ItemFactoryTest { + + @Test + public void testCreateDefaultItem() { + ItemFactory itemFactory = new ItemFactory(); + Item item = itemFactory.create(); + + assertTrue(isValidUUID(item.getId())); + assertNull(item.getName()); + assertEquals(0, item.getQuantity()); + } + + @Test + public void testCreateItemWithParameters() { + ItemFactory itemFactory = new ItemFactory(); + String id = UUID.randomUUID().toString(); + String name = "Snack A"; + int quantity = 5; + + Item item = itemFactory.create(id, name, quantity); + + // Memeriksa apakah nilai parameter sesuai dengan nilai yang diatur di item + assertEquals(id, item.getId()); + assertEquals(name, item.getName()); + assertEquals(quantity, item.getQuantity()); + } + + private boolean isValidUUID(String uuidString) { + try { + UUID.fromString(uuidString); + return true; + } catch (IllegalArgumentException e) { + return false; + } + } +} + diff --git a/src/test/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/model/ItemTest.java b/src/test/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/model/ItemTest.java new file mode 100644 index 0000000..4343909 --- /dev/null +++ b/src/test/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/model/ItemTest.java @@ -0,0 +1,40 @@ +package id.ac.ui.cs.advprog.snackscription_subscriptionbox.model; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +public class ItemTest { + + @Test + public void testDefaultConstructor() { + Item item = new Item(); + assertNull(item.getId()); + assertNull(item.getName()); + assertEquals(0, item.getQuantity()); + } + + @Test + public void testParameterizedConstructor() { + String id = "123"; + String name = "Snack A"; + int quantity = 5; + + Item item = new Item(id, name, quantity); + assertEquals(id, item.getId()); + assertEquals(name, item.getName()); + assertEquals(quantity, item.getQuantity()); + } + + @Test + public void testSettersAndGetters() { + Item item = new Item(); + item.setId("456"); + item.setName("Snack B"); + item.setQuantity(10); + + assertEquals("456", item.getId()); + assertEquals("Snack B", item.getName()); + assertEquals(10, item.getQuantity()); + } +} diff --git a/src/test/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/repository/ItemRepositoryTest.java b/src/test/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/repository/ItemRepositoryTest.java new file mode 100644 index 0000000..b65e3a7 --- /dev/null +++ b/src/test/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/repository/ItemRepositoryTest.java @@ -0,0 +1,56 @@ +package id.ac.ui.cs.advprog.snackscription_subscriptionbox.repository; + +import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.Item; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +public class ItemRepositoryTest { + + private ItemRepository itemRepository; + + @BeforeEach + public void setUp() { + itemRepository = new ItemRepository(); + } + + @Test + public void testCreateItem() { + Item item = new Item("1", "Snack A", 5); + Item createdItem = itemRepository.createItem(item); + assertEquals(item, createdItem); + } + + @Test + public void testGetItemById() { + Item item = new Item("1", "Snack A", 5); + itemRepository.createItem(item); + Item retrievedItem = itemRepository.getItemById("1"); + assertEquals(item, retrievedItem); + } + + @Test + public void testDeleteItem() { + Item item = new Item("1", "Snack A", 5); + itemRepository.createItem(item); + Item deletedItem = itemRepository.deleteItem(item); + assertEquals(item, deletedItem); + assertNull(itemRepository.getItemById("1")); + } + + @Test + public void testEditItem() { + Item item = new Item("1", "Snack A", 5); + itemRepository.createItem(item); + + Item updatedItem = new Item("1", "Snack B", 10); + Item editedItem = itemRepository.editItem(updatedItem); + assertEquals(updatedItem, editedItem); + + Item retrievedItem = itemRepository.getItemById("1"); + assertEquals("Snack B", retrievedItem.getName()); + assertEquals(10, retrievedItem.getQuantity()); + } +} + diff --git a/src/test/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/service/ItemServiceImplTest.java b/src/test/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/service/ItemServiceImplTest.java new file mode 100644 index 0000000..cda7497 --- /dev/null +++ b/src/test/java/id/ac/ui/cs/advprog/snackscription_subscriptionbox/service/ItemServiceImplTest.java @@ -0,0 +1,88 @@ +package id.ac.ui.cs.advprog.snackscription_subscriptionbox.service; + + +import id.ac.ui.cs.advprog.snackscription_subscriptionbox.model.Item; +import id.ac.ui.cs.advprog.snackscription_subscriptionbox.repository.ItemRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class ItemServiceImplTest { + + private ItemServiceImpl itemService; + + @BeforeEach + void setUp() { + ItemRepository itemRepository = new ItemRepository(); + itemService = new ItemServiceImpl(itemRepository); + } + + @Test + void testCreateItem() { + Item createdItem = itemService.createItem("1", "Item 1", 10); + + assertNotNull(createdItem); + assertEquals("1", createdItem.getId()); + assertEquals("Item 1", createdItem.getName()); + assertEquals(10, createdItem.getQuantity()); + } + + @Test + void testGetItemById() { + itemService.createItem("1", "Item 1", 10); + Item fetchedItem = itemService.getItemById("1"); + + assertNotNull(fetchedItem); + assertEquals("1", fetchedItem.getId()); + assertEquals("Item 1", fetchedItem.getName()); + assertEquals(10, fetchedItem.getQuantity()); + } + + @Test + void testDeleteItem() { + itemService.createItem("1", "Item 1", 10); + Item deletedItem = itemService.deleteItem("1"); + + assertNotNull(deletedItem); + assertEquals("1", deletedItem.getId()); + assertEquals("Item 1", deletedItem.getName()); + assertEquals(10, deletedItem.getQuantity()); + + assertNull(itemService.getItemById("1")); + } + + @Test + void testEditItem() { + itemService.createItem("1", "Item 1", 10); + Item editedItem = itemService.editItem("1", "Item 1 Edited", 20); + + assertNotNull(editedItem); + assertEquals("1", editedItem.getId()); + assertEquals("Item 1 Edited", editedItem.getName()); + assertEquals(20, editedItem.getQuantity()); + } + + @Test + void testGetAllItems() { + itemService.createItem("1", "Item 1", 10); + itemService.createItem("2", "Item 2", 20); + + List allItems = itemService.getAllItems(); + + assertNotNull(allItems); + assertEquals(2, allItems.size()); + + Item firstItem = allItems.getFirst(); + assertEquals("1", firstItem.getId()); + assertEquals("Item 1", firstItem.getName()); + assertEquals(10, firstItem.getQuantity()); + + Item secondItem = allItems.get(1); + assertEquals("2", secondItem.getId()); + assertEquals("Item 2", secondItem.getName()); + assertEquals(20, secondItem.getQuantity()); + } +}