diff --git a/eatery-service/src/main/java/com/drinkool/entities/EateryEntity.java b/eatery-service/src/main/java/com/drinkool/entities/EateryEntity.java index d8e16d9..1a1426c 100644 --- a/eatery-service/src/main/java/com/drinkool/entities/EateryEntity.java +++ b/eatery-service/src/main/java/com/drinkool/entities/EateryEntity.java @@ -45,4 +45,16 @@ public class EateryEntity extends BaseEntity { return this; } + + @Transactional + public static EateryEntity findByOwnerId(String ownerId) { + UUID ownerUUID = UUID.fromString(ownerId); + + return EateryEntity.find("ownerId", ownerUUID).firstResult(); + } + + @Transactional + public static EateryEntity findByOwnerId(UUID ownerId) { + return EateryEntity.find("ownerId", ownerId).firstResult(); + } } diff --git a/eatery-service/src/main/java/com/drinkool/entities/EateryInventoryItemEntity.java b/eatery-service/src/main/java/com/drinkool/entities/EateryInventoryItemEntity.java deleted file mode 100644 index e428384..0000000 --- a/eatery-service/src/main/java/com/drinkool/entities/EateryInventoryItemEntity.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.drinkool.entities; - -import com.drinkool.lib.entities.BaseEntity; -import jakarta.persistence.*; -import jakarta.transaction.Transactional; - -@Entity -@Table -public class EateryInventoryItemEntity extends BaseEntity { - - public double quantity; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "inventory_item_id") - public InventoryItemEntity inventoryItem; - - private EateryInventoryItemEntity() {} - - // Create - @Transactional - public static EateryInventoryItemEntity create( - String name, - double quantity, - String unit - ) { - String itemName = name.toLowerCase(); - - InventoryItemEntity item = InventoryItemEntity.find( - "name", - itemName - ).firstResult(); - - if (item == null || item.unit != unit) { - if (unit != null || unit == "") { - item = InventoryItemEntity.create(itemName, unit); - } else { - item = InventoryItemEntity.create(itemName); - } - } - - EateryInventoryItemEntity eateryInventoryItem = - new EateryInventoryItemEntity(); - - eateryInventoryItem.quantity = quantity; - eateryInventoryItem.inventoryItem = item; - - eateryInventoryItem.persist(); - - return eateryInventoryItem; - } -} diff --git a/eatery-service/src/main/java/com/drinkool/entities/InventoryItemEntity.java b/eatery-service/src/main/java/com/drinkool/entities/InventoryItemEntity.java deleted file mode 100644 index e85a8e1..0000000 --- a/eatery-service/src/main/java/com/drinkool/entities/InventoryItemEntity.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.drinkool.entities; - -import com.drinkool.lib.entities.BaseEntity; -import jakarta.persistence.Entity; -import jakarta.persistence.Table; -import jakarta.transaction.Transactional; - -@Entity -@Table(name = "inventory_items") -public class InventoryItemEntity extends BaseEntity { - - public String name; - public String unit; - - private InventoryItemEntity() {} - - // Create - @Transactional - public static InventoryItemEntity create(String name, String unit) { - InventoryItemEntity item = new InventoryItemEntity(); - - item.name = name; - item.unit = unit; - - item.persist(); - - return item; - } - - @Transactional - public static InventoryItemEntity create(String name) { - return InventoryItemEntity.create(name, "unit"); - } -} diff --git a/eatery-service/src/main/java/com/drinkool/entities/MenuItemEntity.java b/eatery-service/src/main/java/com/drinkool/entities/MenuItemEntity.java index 39ddb09..8254931 100644 --- a/eatery-service/src/main/java/com/drinkool/entities/MenuItemEntity.java +++ b/eatery-service/src/main/java/com/drinkool/entities/MenuItemEntity.java @@ -3,7 +3,6 @@ package com.drinkool.entities; import com.drinkool.lib.entities.BaseEntity; import jakarta.persistence.*; import jakarta.transaction.Transactional; -import java.util.*; @Entity @Table @@ -19,45 +18,19 @@ public class MenuItemEntity extends BaseEntity { @JoinColumn(name = "eatery_id") public EateryEntity eatery; - // Danh sách các nguyên liệu cấu thành món ăn này - @OneToMany( - mappedBy = "menuItem", - cascade = CascadeType.ALL, - orphanRemoval = true - ) - public List ingredients = new ArrayList<>(); - - /** - * Thêm nguyên liệu vào món ăn với định lượng cụ thể - */ - @Transactional - public void addIngredient( - EateryInventoryItemEntity inventoryItem, - double requiredQty - ) { - MenuItemIngredientEntity ingredient = MenuItemIngredientEntity.create( - this, - inventoryItem, - requiredQty - ); - - this.ingredients.add(ingredient); - - this.persist(); - } - /** * Phương thức tiện ích để tạo nhanh Menu Item từ tên */ @Transactional - public static MenuItemEntity create(String name, double price) { - MenuItemEntity menu = new MenuItemEntity(); + public static MenuItemEntity create(EateryEntity eatery, String name, double price) { + MenuItemEntity menuItem = new MenuItemEntity(); - menu.name = name; - menu.price = price; + menuItem.name = name; + menuItem.price = price; + menuItem.eatery = eatery; - menu.persist(); + menuItem.persist(); - return menu; + return menuItem; } } diff --git a/eatery-service/src/main/java/com/drinkool/entities/MenuItemIngredientEntity.java b/eatery-service/src/main/java/com/drinkool/entities/MenuItemIngredientEntity.java deleted file mode 100644 index 17f7cd8..0000000 --- a/eatery-service/src/main/java/com/drinkool/entities/MenuItemIngredientEntity.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.drinkool.entities; - -import com.drinkool.lib.entities.BaseEntity; -import jakarta.persistence.*; - -@Entity -@Table(name = "menu_item_ingredients") -public class MenuItemIngredientEntity extends BaseEntity { - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "menu_item_id") - public MenuItemEntity menuItem; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "inventory_item_id") - public EateryInventoryItemEntity inventoryItem; - - public double requiredQuantity; - - private MenuItemIngredientEntity() {} - - public static MenuItemIngredientEntity create( - MenuItemEntity menuItem, - EateryInventoryItemEntity inventoryItem, - double requiredQuantity - ) { - MenuItemIngredientEntity ingredient = new MenuItemIngredientEntity(); - - ingredient.menuItem = menuItem; - ingredient.inventoryItem = inventoryItem; - ingredient.requiredQuantity = requiredQuantity; - - ingredient.persist(); - - return ingredient; - } -} diff --git a/eatery-service/src/main/java/com/drinkool/services/EateryService.java b/eatery-service/src/main/java/com/drinkool/services/EateryService.java index 50a26af..15fb483 100644 --- a/eatery-service/src/main/java/com/drinkool/services/EateryService.java +++ b/eatery-service/src/main/java/com/drinkool/services/EateryService.java @@ -1,12 +1,19 @@ package com.drinkool.services; +import com.drinkool.InternalValue; +import com.drinkool.Role; import com.drinkool.dtos.event.ManagerCreate; import com.drinkool.entities.EateryEntity; +import com.drinkool.entities.MenuItemEntity; +import io.vertx.core.http.HttpServerRequest; +import jakarta.annotation.security.RolesAllowed; import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; import jakarta.transaction.Transactional; import java.util.List; import java.util.UUID; import org.eclipse.microprofile.graphql.GraphQLApi; +import org.eclipse.microprofile.graphql.Mutation; import org.eclipse.microprofile.graphql.Name; import org.eclipse.microprofile.graphql.Query; import org.eclipse.microprofile.reactive.messaging.Incoming; @@ -15,6 +22,9 @@ import org.eclipse.microprofile.reactive.messaging.Incoming; @GraphQLApi public class EateryService { + @Inject + HttpServerRequest request; + @Incoming("manager-in") @Transactional public void consumeManagerSignup(ManagerCreate input) { @@ -32,4 +42,32 @@ public class EateryService { public EateryEntity getEatery(@Name("id") UUID id) { return EateryEntity.findById(id); } + + @Mutation("addMenuItem") + @RolesAllowed(Role.Manager) + @Transactional + public MenuItemEntity addMenuItem( + @Name("name") String name, + @Name("price") double price + ) { + String ownerId = request.getHeader(InternalValue.userId); + + EateryEntity eatery = EateryEntity.findByOwnerId(ownerId); + if (eatery == null) return null; + + MenuItemEntity item = MenuItemEntity.create(eatery, name, price); + + return item; + } + + @Query("menuItemsByEatery") + public List getMenuItemsByEatery( + @Name("eateryId") UUID eateryId + ) { + EateryEntity eatery = EateryEntity.findById(eateryId); + + if (eatery == null) return List.of(); + + return MenuItemEntity.list("eatery", eatery); + } } diff --git a/eatery-service/src/main/java/com/drinkool/services/InventoryService.java b/eatery-service/src/main/java/com/drinkool/services/InventoryService.java deleted file mode 100644 index c051aa4..0000000 --- a/eatery-service/src/main/java/com/drinkool/services/InventoryService.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.drinkool.services; - -import com.drinkool.dtos.AddInventory; -import com.drinkool.entities.InventoryItemEntity; -import jakarta.transaction.Transactional; -import jakarta.ws.rs.*; -import jakarta.ws.rs.core.Response; - -@Path("/api/inventory") -public class InventoryService { - - @POST - @Path("/create") - @Transactional - public Response create(AddInventory input) { - InventoryItemEntity.create(input.name, input.unit); - - return Response.ok().build(); - } -} diff --git a/eatery-service/src/test/java/com/drinkool/entities/EateryInventoryItemEntityTest.java b/eatery-service/src/test/java/com/drinkool/entities/EateryInventoryItemEntityTest.java deleted file mode 100644 index ca2717c..0000000 --- a/eatery-service/src/test/java/com/drinkool/entities/EateryInventoryItemEntityTest.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.drinkool.entities; - -import static org.junit.jupiter.api.Assertions.*; - -import io.quarkus.test.junit.QuarkusTest; -import jakarta.transaction.Transactional; -import org.junit.jupiter.api.Test; - -@QuarkusTest -public class EateryInventoryItemEntityTest { - - @Test - @Transactional - void testAdd_WhenItemExists_ShouldUseExistingItem() { - String itemName = "Coca Cola"; - int quantity = 10; - - InventoryItemEntity.create(itemName); - - EateryInventoryItemEntity eateryItem = EateryInventoryItemEntity.create( - itemName, - quantity, - "" - ); - - EateryInventoryItemEntity savedEntity = EateryInventoryItemEntity.find( - "id", - eateryItem.id - ).firstResult(); - assertNotNull(savedEntity); - } - - @Test - @Transactional - void testAdd_WhenItemDoesNotExist_ShouldCreateNewItem() { - String itemName = "Pepsi"; - int quantity = 5; - String unit = "Bottle"; - - EateryInventoryItemEntity eateryItem = EateryInventoryItemEntity.create( - itemName, - quantity, - unit - ); - - EateryInventoryItemEntity savedEntity = EateryInventoryItemEntity.find( - "id", - eateryItem.id - ).firstResult(); - assertNotNull(savedEntity); - } -} diff --git a/eatery-service/src/test/java/com/drinkool/entities/InventoryItemEntityTest.java b/eatery-service/src/test/java/com/drinkool/entities/InventoryItemEntityTest.java deleted file mode 100644 index 4aecfc0..0000000 --- a/eatery-service/src/test/java/com/drinkool/entities/InventoryItemEntityTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.drinkool.entities; - -import io.quarkus.test.junit.QuarkusTest; -import jakarta.transaction.Transactional; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -@QuarkusTest -public class InventoryItemEntityTest { - - @Test - @Transactional - public void testCreateInventoryItem() { - // 1. Chuẩn bị dữ liệu (Lưu ý: Không còn biến quantity nữa) - String name = "Trà sữa truyền thống"; - String unit = "Ly"; - - // 2. Gọi hàm static create (Không dùng new hay hàm add nữa) - // Hàm này vừa tạo object, vừa gán data, vừa gọi persist() luôn - InventoryItemEntity item = InventoryItemEntity.create(name, unit); - - // 3. Kiểm chứng - Assertions.assertNotNull(item, "Entity tạo ra không được null"); - Assertions.assertEquals(name, item.name, "Tên không khớp"); - Assertions.assertEquals(unit, item.unit, "Đơn vị không khớp"); - Assertions.assertNotNull( - item.id, - "ID phải được sinh ra tự động sau khi persist" - ); - } - - @Test - @Transactional - public void testCreateWithDefaultUnit() { - // 1. Chuẩn bị dữ liệu - String name = "Trân châu đen"; - - // 2. Gọi hàm static create rút gọn (chỉ truyền name, unit sẽ tự là "unit") - InventoryItemEntity item = InventoryItemEntity.create(name); - - // 3. Kiểm chứng - Assertions.assertNotNull(item, "Entity tạo ra không được null"); - Assertions.assertEquals(name, item.name, "Tên không khớp"); - Assertions.assertEquals("unit", item.unit, "Unit mặc định phải là 'unit'"); - Assertions.assertNotNull( - item.id, - "ID phải được sinh ra tự động sau khi persist" - ); - } -} diff --git a/eatery-service/src/test/java/com/drinkool/entities/MenuItemEntityTest.java b/eatery-service/src/test/java/com/drinkool/entities/MenuItemEntityTest.java deleted file mode 100644 index e6b62ac..0000000 --- a/eatery-service/src/test/java/com/drinkool/entities/MenuItemEntityTest.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.drinkool.entities; - -import static org.junit.jupiter.api.Assertions.*; - -import io.quarkus.test.junit.QuarkusTest; -import jakarta.transaction.Transactional; -import org.junit.jupiter.api.Test; - -@QuarkusTest -public class MenuItemEntityTest { - - @Test - @Transactional - public void testCreateMenuItemSuccessfully() { - // 1. Chuẩn bị dữ liệu (Arrange) - String name = "Cà phê sữa đá"; - double price = 29000.0; - - // 2. Thực thi (Act) - Gọi hàm tĩnh create - MenuItemEntity menuItem = MenuItemEntity.create(name, price); - - // 3. Kiểm chứng (Assert) - assertNotNull(menuItem, "Thực thể MenuItem không được null"); - assertEquals(name, menuItem.name, "Tên món ăn không khớp"); - assertEquals(price, menuItem.price, "Giá món ăn không khớp"); - assertNotNull(menuItem.id, "ID phải được tự động sinh ra sau khi persist"); - assertTrue( - menuItem.ingredients.isEmpty(), - "Danh sách nguyên liệu ban đầu phải rỗng" - ); - } - - @Test - @Transactional - public void testAddIngredientSuccessfully() { - // 1. Chuẩn bị dữ liệu (Arrange) - // Tạo món ăn - MenuItemEntity menuItem = MenuItemEntity.create( - "Trà sữa trân châu", - 45000.0 - ); - - // Tạo nguyên liệu trong kho (Dùng đúng hàm add() của EateryInventoryItemEntity như đã fix) - EateryInventoryItemEntity inventoryItem = EateryInventoryItemEntity.create( - "Trân châu đen", - 50, - "kg" - ); - - double requiredQty = 0.2; // Cần 0.2 kg trân châu cho 1 ly - - // 2. Thực thi (Act) - Thêm nguyên liệu vào món ăn - menuItem.addIngredient(inventoryItem, requiredQty); - - // 3. Kiểm chứng (Assert) - // Kiểm tra danh sách nguyên liệu của món ăn - assertFalse( - menuItem.ingredients.isEmpty(), - "Danh sách nguyên liệu không được rỗng sau khi thêm" - ); - assertEquals( - 1, - menuItem.ingredients.size(), - "Phải có đúng 1 nguyên liệu trong danh sách" - ); - - // Lấy phần tử nguyên liệu đầu tiên ra để kiểm tra chi tiết các liên kết - MenuItemIngredientEntity addedIngredient = menuItem.ingredients.get(0); - - assertNotNull( - addedIngredient.id, - "ID của Entity trung gian phải được sinh ra" - ); - assertEquals( - menuItem.id, - addedIngredient.menuItem.id, - "Khóa ngoại MenuItem bị sai" - ); - assertEquals( - inventoryItem.id, - addedIngredient.inventoryItem.id, - "Khóa ngoại InventoryItem bị sai" - ); - assertEquals( - requiredQty, - addedIngredient.requiredQuantity, - "Định lượng (requiredQty) không khớp" - ); - } -} diff --git a/eatery-service/src/test/java/com/drinkool/entities/MenuItemIngredientEntityTest.java b/eatery-service/src/test/java/com/drinkool/entities/MenuItemIngredientEntityTest.java deleted file mode 100644 index f9f84f8..0000000 --- a/eatery-service/src/test/java/com/drinkool/entities/MenuItemIngredientEntityTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.drinkool.entities; - -import static org.junit.jupiter.api.Assertions.*; - -import io.quarkus.test.junit.QuarkusTest; -import jakarta.transaction.Transactional; -import org.junit.jupiter.api.Test; - -@QuarkusTest -public class MenuItemIngredientEntityTest { - - @Test - @Transactional - void testCreate_ShouldPersistIngredientSuccessfully() { - // 1. Chuẩn bị dữ liệu giả định - - String menuItemName = "Milk Tea"; - double menuItemPrice = 40; - - MenuItemEntity menuItem = MenuItemEntity.create( - menuItemName, - menuItemPrice - ); - - String inventoryItemName = "Water"; - int inventoryItemQuantity = 10; // Đổi thành int cho khớp với kiểu của EateryInventoryItemEntity - String inventoryItemUnit = "l"; - - // SỬA Ở ĐÂY: Khởi tạo bằng new và dùng hàm add() đúng như cấu trúc class của bạn - EateryInventoryItemEntity inventoryItem = EateryInventoryItemEntity.create( - inventoryItemName, - inventoryItemQuantity, - inventoryItemUnit - ); - // Lưu ý: Hàm add() của bạn đã có sẵn lệnh this.persist() bên trong nên không cần gọi lại nữa! - - double requiredQuantity = 0.5; - - // 2. Gọi hàm static create cần test - MenuItemIngredientEntity createdIngredient = - MenuItemIngredientEntity.create( - menuItem, - inventoryItem, - requiredQuantity - ); - - // 3. Kiểm tra kết quả - assertNotNull(createdIngredient.id, "ID không được null sau khi persist"); - - // Truy vấn lại từ Database để đảm bảo dữ liệu đã được lưu đúng - MenuItemIngredientEntity savedEntity = MenuItemIngredientEntity.findById( - createdIngredient.id - ); - - assertNotNull(savedEntity); - assertEquals(menuItem.id, savedEntity.menuItem.id); - assertEquals(inventoryItem.id, savedEntity.inventoryItem.id); - assertEquals(requiredQuantity, savedEntity.requiredQuantity); - } -} diff --git a/eatery-service/src/test/java/com/drinkool/services/EateryServiceTest.java b/eatery-service/src/test/java/com/drinkool/services/EateryServiceTest.java index 16bde3e..b28fd3f 100644 --- a/eatery-service/src/test/java/com/drinkool/services/EateryServiceTest.java +++ b/eatery-service/src/test/java/com/drinkool/services/EateryServiceTest.java @@ -2,11 +2,16 @@ package com.drinkool.services; import static io.restassured.RestAssured.given; import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.Matchers.hasSize; +import com.drinkool.InternalValue; +import com.drinkool.Role; import com.drinkool.dtos.event.ManagerCreate; import com.drinkool.entities.EateryEntity; +import com.drinkool.entities.MenuItemEntity; import io.quarkus.test.junit.QuarkusTest; import io.restassured.http.ContentType; import io.smallrye.reactive.messaging.memory.InMemoryConnector; @@ -54,21 +59,32 @@ public class EateryServiceTest { private UUID lastSavedId; private String lastSavedName; + private UUID lastOwnerId = UUID.randomUUID(); @BeforeEach @Transactional void setup() { + MenuItemEntity.deleteAll(); EateryEntity.deleteAll(); lastSavedName = faker.restaurant().name(); EateryEntity eatery = new EateryEntity(); - lastSavedId = eatery.create(UUID.randomUUID(), lastSavedName).id; + eatery = eatery.create(lastOwnerId, lastSavedName); + lastSavedId = eatery.id; for (int i = 0; i < 2; i++) { EateryEntity e = new EateryEntity(); e.create(UUID.randomUUID(), faker.restaurant().name()); } + + for (int i = 0; i < 3; i++) { + MenuItemEntity.create( + eatery, + faker.food().dish(), + faker.number().randomDouble(2, 10, 100) + ); + } } @Test @@ -106,4 +122,144 @@ public class EateryServiceTest { .statusCode(200) .body("data.eateryById.name", is(lastSavedName)); } + + @Test + public void testAddMenuItemSuccess() { + String mutation = + "mutation addMenuItem($name: String!, $price: Float!) {" + + " addMenuItem(name: $name, price: $price) {" + + " id" + + " name" + + " price" + + " }" + + "}"; + + java.util.Map variables = new java.util.HashMap<>(); + variables.put("name", "Trà Sữa"); + variables.put("price", 30000.0); + + java.util.Map requestBody = new java.util.HashMap<>(); + requestBody.put("query", mutation); + requestBody.put("variables", variables); + + given() + .contentType(ContentType.JSON) + .header(InternalValue.role, Role.Manager) + .header(InternalValue.userId, lastOwnerId) // Thay "x-user-id" bằng InternalValue.userId của bạn + .body(requestBody) + .when() + .post("/graphql") + .then() + .statusCode(200) + .body("data.addMenuItem.name", is("Trà Sữa")) + .body("data.addMenuItem.id", notNullValue()); + } + + @Test + public void testAddMenuItemFailInvalidRole() { + String mutation = + "mutation addMenuItem($name: String!, $price: Float!) {" + + " addMenuItem(name: $name, price: $price) {" + + " id" + + " name" + + " price" + + " }" + + "}"; + + java.util.Map variables = new java.util.HashMap<>(); + variables.put("name", "Trà Sữa"); + variables.put("price", 30000.0); + + java.util.Map requestBody = new java.util.HashMap<>(); + requestBody.put("query", mutation); + requestBody.put("variables", variables); + + given() + .contentType(ContentType.JSON) + .header(InternalValue.role, Role.Customer) + .header(InternalValue.userId, lastOwnerId) + .body(requestBody) + .when() + .post("/graphql") + .then() + .statusCode(200) + .body("data.addMenuItem.name", is("Trà Sữa")) + .body("data.addMenuItem.id", notNullValue()); + } + + @Test + public void testAddMenuItemFailInvalidOwner() { + String mutation = + "mutation { addMenuItem(name: \"Coffee\", price: 20000.0) { id } }"; + + java.util.Map requestBody = new java.util.HashMap<>(); + requestBody.put("query", mutation); + + given() + .contentType(ContentType.JSON) + .header(InternalValue.role, Role.Manager) + .header(InternalValue.userId, UUID.randomUUID()) + .body(requestBody) + .when() + .post("/graphql") + .then() + .statusCode(200) + .body("data.addMenuItem", is((Object) null)); + } + + @Test + public void testGetMenuItemsByEatery_Success() { + String query = + "query getItems($id: String!) {" + + " menuItemsByEatery(eateryId: $id) {" + + " id" + + " name" + + " price" + + " }" + + "}"; + + java.util.Map variables = new java.util.HashMap<>(); + variables.put("id", lastSavedId.toString()); + + java.util.Map requestBody = new java.util.HashMap<>(); + requestBody.put("query", query); + requestBody.put("variables", variables); + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/graphql") + .then() + .statusCode(200) + .body("data.menuItemsByEatery", hasSize(not(0))); + } + + @Test + public void testGetMenuItemsByEatery_NotFound() { + String randomId = UUID.randomUUID().toString(); + + String query = + "query getItems($id: String!) {" + + " menuItemsByEatery(eateryId: $id) {" + + " id" + + " }" + + "}"; + + java.util.Map variables = new java.util.HashMap<>(); + variables.put("id", randomId); + + java.util.Map requestBody = new java.util.HashMap<>(); + requestBody.put("query", query); + requestBody.put("variables", variables); + + given() + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/graphql") + .then() + .statusCode(200) + .body("data.menuItemsByEatery", hasSize(0)); // Phải trả về List rỗng như code bạn viết + } } diff --git a/eatery-service/src/test/java/com/drinkool/services/InventoryServiceTest.java b/eatery-service/src/test/java/com/drinkool/services/InventoryServiceTest.java deleted file mode 100644 index e6e2ca8..0000000 --- a/eatery-service/src/test/java/com/drinkool/services/InventoryServiceTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.drinkool.services; - -import static io.restassured.RestAssured.given; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import com.drinkool.dtos.AddInventory; -import com.drinkool.entities.InventoryItemEntity; -import io.quarkus.test.junit.QuarkusTest; -import io.restassured.http.ContentType; -import java.util.UUID; -import org.junit.jupiter.api.Test; - -@QuarkusTest -public class InventoryServiceTest { - - @Test - void add() { - String name = UUID.randomUUID().toString(); - - AddInventory input = new AddInventory(); - input.name = name; - - given() - .contentType(ContentType.JSON) - .body(input) - .when() - .post("/api/inventory/create") - .then(); - - assertEquals(1, InventoryItemEntity.find("name", name).count()); - } -} diff --git a/gateway-service/src/main/java/com/drinkool/controller/EateryController.java b/gateway-service/src/main/java/com/drinkool/controller/EateryController.java index 3e98288..6073717 100644 --- a/gateway-service/src/main/java/com/drinkool/controller/EateryController.java +++ b/gateway-service/src/main/java/com/drinkool/controller/EateryController.java @@ -1,5 +1,6 @@ package com.drinkool.controller; +import com.drinkool.dtos.GraphqlDto; import io.smallrye.graphql.client.GraphQLClient; import io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClient; import jakarta.ws.rs.POST; @@ -15,10 +16,11 @@ public class EateryController { @POST @Path("/graphql") - public Response forward(String query) + public Response forward(GraphqlDto gqlRequest) throws ExecutionException, InterruptedException { io.smallrye.graphql.client.Response response = dynamicClient.executeSync( - query + gqlRequest.query, + gqlRequest.variables ); if (response.hasError()) { diff --git a/lib/pom.xml b/lib/pom.xml index 05bf8ce..6c2c7ef 100644 --- a/lib/pom.xml +++ b/lib/pom.xml @@ -1,8 +1,8 @@ - + 4.0.0 @@ -21,20 +21,25 @@ + + io.quarkus + quarkus-security + provided + com.fasterxml.jackson.core jackson-annotations 2.15.2 - io.quarkus - quarkus-kafka-client + io.quarkus + quarkus-kafka-client - org.projectlombok - lombok - 1.18.30 - provided + org.projectlombok + lombok + 1.18.30 + provided jakarta.persistence @@ -55,4 +60,4 @@ test - + \ No newline at end of file diff --git a/lib/src/main/java/com/drinkool/dtos/GraphqlDto.java b/lib/src/main/java/com/drinkool/dtos/GraphqlDto.java new file mode 100644 index 0000000..a358ed0 --- /dev/null +++ b/lib/src/main/java/com/drinkool/dtos/GraphqlDto.java @@ -0,0 +1,7 @@ +package com.drinkool.dtos; + +public class GraphqlDto { + + public String query; + public java.util.Map variables; +} diff --git a/lib/src/main/java/com/drinkool/lib/utils/HeaderIdentityProvider.java b/lib/src/main/java/com/drinkool/lib/utils/HeaderIdentityProvider.java new file mode 100644 index 0000000..aee7b63 --- /dev/null +++ b/lib/src/main/java/com/drinkool/lib/utils/HeaderIdentityProvider.java @@ -0,0 +1,38 @@ +package com.drinkool.lib.utils; + +import com.drinkool.InternalValue; +import io.quarkus.security.identity.AuthenticationRequestContext; +import io.quarkus.security.identity.IdentityProvider; +import io.quarkus.security.identity.SecurityIdentity; +import io.quarkus.security.identity.request.TrustedAuthenticationRequest; +import io.quarkus.security.runtime.QuarkusSecurityIdentity; +import io.smallrye.mutiny.Uni; +import io.vertx.core.http.HttpServerRequest; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +@ApplicationScoped +public class HeaderIdentityProvider + implements IdentityProvider +{ + + @Inject + HttpServerRequest httpServerRequest; + + @Override + public Class getRequestType() { + return TrustedAuthenticationRequest.class; + } + + @Override + public Uni authenticate( + TrustedAuthenticationRequest request, + AuthenticationRequestContext context + ) { + String role = httpServerRequest.getHeader(InternalValue.role); + + return Uni.createFrom().item( + QuarkusSecurityIdentity.builder().addRole(role).build() + ); + } +}