From 43600fc8cfa2cd93e1d33ee855a2934a49f8d663 Mon Sep 17 00:00:00 2001 From: TakahashiNguyen Date: Wed, 6 May 2026 15:10:31 +0000 Subject: [PATCH] fix: menu items CRUD (#44) Co-authored-by: TakahashiNg <83152264+TakahashiNguyen@users.noreply.github.com> Reviewed-on: https://git.demonkernel.io.vn/FoodSurf/backend/pulls/44 --- .gitea/workflows/test.yaml | 22 +-- .gitignore | 1 - .vscode/launch.json | 15 ++ .vscode/settings.json | 13 ++ .../com/drinkool/services/AccountService.java | 2 +- .../drinkool/services/CustomerService.java | 3 +- .../com/drinkool/services/ManagerService.java | 5 +- .../drinkool/services/AccountServiceTest.java | 3 +- .../drinkool/services/BaseServiceTest.java | 3 +- .../services/CustomerServiceTest.java | 3 +- .../drinkool/services/ManagerServiceTest.java | 3 +- eatery-service/pom.xml | 30 ++++ .../java/com/drinkool/dtos/AddMenuItem.java | 25 +++ .../java/com/drinkool/dtos/DtoMapper.java | 18 +++ .../com/drinkool/dtos/UpdateMenuItem.java | 28 ++++ .../com/drinkool/entities/EateryEntity.java | 2 +- .../com/drinkool/entities/MenuItemEntity.java | 27 ++-- .../com/drinkool/services/EateryService.java | 55 ++++++- .../com/drinkool/services/ReviewService.java | 3 +- .../src/main/resources/application.properties | 3 +- .../drinkool/services/EateryServiceTest.java | 145 ++++++++++++++---- .../drinkool/services/ReviewServiceTest.java | 2 +- .../controller/CustomerController.java | 2 +- .../drinkool/controller/EateryController.java | 3 +- .../drinkool/controller/IndexController.java | 2 +- .../drinkool/controller/MainController.java | 2 +- .../controller/ManagerController.java | 2 +- .../com/drinkool/services/BaseService.java | 3 +- .../drinkool/services/CustomerService.java | 3 +- .../com/drinkool/services/ManagerService.java | 3 +- lib/pom.xml | 6 +- .../drinkool/interfaces/EateryInterface.java | 12 ++ .../drinkool/interfaces/EntityInterface.java | 8 + .../interfaces/MenuItemInterface.java | 8 + .../drinkool/{ => lib}/dtos/AddInventory.java | 2 +- .../drinkool/{ => lib}/dtos/GraphqlDto.java | 2 +- .../com/drinkool/{ => lib}/dtos/Login.java | 2 +- .../{ => lib}/dtos/ManagerSignup.java | 2 +- .../drinkool/{ => lib}/dtos/QuickLogin.java | 2 +- .../drinkool/{ => lib}/dtos/QuickSignup.java | 2 +- .../drinkool/{ => lib}/dtos/SendReview.java | 2 +- .../com/drinkool/{ => lib}/dtos/Signup.java | 2 +- .../com/drinkool/{ => lib}/dtos/SmsOtp.java | 2 +- .../{ => lib}/dtos/event/ManagerCreate.java | 2 +- .../com/drinkool/lib/entities/BaseEntity.java | 6 +- scripts/test.sh | 34 +++- 46 files changed, 429 insertions(+), 96 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 eatery-service/src/main/java/com/drinkool/dtos/AddMenuItem.java create mode 100644 eatery-service/src/main/java/com/drinkool/dtos/DtoMapper.java create mode 100644 eatery-service/src/main/java/com/drinkool/dtos/UpdateMenuItem.java create mode 100644 lib/src/main/java/com/drinkool/interfaces/EateryInterface.java create mode 100644 lib/src/main/java/com/drinkool/interfaces/EntityInterface.java create mode 100644 lib/src/main/java/com/drinkool/interfaces/MenuItemInterface.java rename lib/src/main/java/com/drinkool/{ => lib}/dtos/AddInventory.java (70%) rename lib/src/main/java/com/drinkool/{ => lib}/dtos/GraphqlDto.java (76%) rename lib/src/main/java/com/drinkool/{ => lib}/dtos/Login.java (69%) rename lib/src/main/java/com/drinkool/{ => lib}/dtos/ManagerSignup.java (70%) rename lib/src/main/java/com/drinkool/{ => lib}/dtos/QuickLogin.java (69%) rename lib/src/main/java/com/drinkool/{ => lib}/dtos/QuickSignup.java (63%) rename lib/src/main/java/com/drinkool/{ => lib}/dtos/SendReview.java (84%) rename lib/src/main/java/com/drinkool/{ => lib}/dtos/Signup.java (75%) rename lib/src/main/java/com/drinkool/{ => lib}/dtos/SmsOtp.java (60%) rename lib/src/main/java/com/drinkool/{ => lib}/dtos/event/ManagerCreate.java (88%) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 4397345..6135fd9 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -23,6 +23,17 @@ jobs: with: fetch-depth: 0 + - name: Install dependencies with Proxy + env: + http_proxy: "http://host.docker.internal:3142" + https_proxy: "http://host.docker.internal:3142" + run: | + # Kiểm tra proxy có hoạt động không + echo "Acquire::http::Proxy \"$http_proxy\";" > /etc/apt/apt.conf.d/80proxy + apt-get update + apt-get install -y --no-install-recommends --no-install-suggests \ + openjdk-25-jdk-headless docker-cli docker-buildx zstd + - uses: shogo82148/actions-setup-redis@v1 with: redis-version: "7.x" @@ -38,17 +49,6 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - - name: Install dependencies with Proxy - env: - http_proxy: "http://host.docker.internal:3142" - https_proxy: "http://host.docker.internal:3142" - run: | - # Kiểm tra proxy có hoạt động không - echo "Acquire::http::Proxy \"$http_proxy\";" > /etc/apt/apt.conf.d/80proxy - apt-get update - apt-get install -y --no-install-recommends --no-install-suggests \ - openjdk-25-jdk-headless docker-cli docker-buildx - - name: Build and Test all module env: TESTCONTAINERS_RYUK_DISABLED: true diff --git a/.gitignore b/.gitignore index 68c9671..51f3fba 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,6 @@ bin/ nb-configuration.xml # Visual Studio Code -.vscode .factorypath *.rdb diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..f37ad13 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "java", + "name": "Attach to Quarkus", + "request": "attach", + "hostName": "localhost", + "port": 5005 + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..11c8332 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,13 @@ +{ + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/.DS_Store": true, + "**/Thumbs.db": true, + "**/target": true, + "**/docker": true, + "node_modules": true + }, + "explorerExclude.backup": {} +} \ No newline at end of file diff --git a/account-service/src/main/java/com/drinkool/services/AccountService.java b/account-service/src/main/java/com/drinkool/services/AccountService.java index 01a8c8a..caf12fd 100644 --- a/account-service/src/main/java/com/drinkool/services/AccountService.java +++ b/account-service/src/main/java/com/drinkool/services/AccountService.java @@ -2,8 +2,8 @@ package com.drinkool.services; import com.drinkool.Role; import com.drinkool.Url; -import com.drinkool.dtos.SmsOtp; import com.drinkool.entities.ManagerEntity; +import com.drinkool.lib.dtos.SmsOtp; import com.drinkool.models.UserModel; import jakarta.inject.Inject; import jakarta.ws.rs.*; diff --git a/account-service/src/main/java/com/drinkool/services/CustomerService.java b/account-service/src/main/java/com/drinkool/services/CustomerService.java index ea00033..816925f 100644 --- a/account-service/src/main/java/com/drinkool/services/CustomerService.java +++ b/account-service/src/main/java/com/drinkool/services/CustomerService.java @@ -1,8 +1,9 @@ package com.drinkool.services; import com.drinkool.*; -import com.drinkool.dtos.*; import com.drinkool.entities.CustomerEntity; +import com.drinkool.lib.dtos.*; + import jakarta.inject.Inject; import jakarta.transaction.Transactional; import jakarta.ws.rs.*; diff --git a/account-service/src/main/java/com/drinkool/services/ManagerService.java b/account-service/src/main/java/com/drinkool/services/ManagerService.java index ce2d9b6..f78552e 100644 --- a/account-service/src/main/java/com/drinkool/services/ManagerService.java +++ b/account-service/src/main/java/com/drinkool/services/ManagerService.java @@ -1,9 +1,10 @@ package com.drinkool.services; import com.drinkool.*; -import com.drinkool.dtos.*; -import com.drinkool.dtos.event.ManagerCreate; import com.drinkool.entities.ManagerEntity; +import com.drinkool.lib.dtos.*; +import com.drinkool.lib.dtos.event.ManagerCreate; + import jakarta.enterprise.context.ApplicationScoped; import jakarta.transaction.Transactional; import jakarta.ws.rs.*; diff --git a/account-service/src/test/java/com/drinkool/services/AccountServiceTest.java b/account-service/src/test/java/com/drinkool/services/AccountServiceTest.java index c8880af..0688cd2 100644 --- a/account-service/src/test/java/com/drinkool/services/AccountServiceTest.java +++ b/account-service/src/test/java/com/drinkool/services/AccountServiceTest.java @@ -3,7 +3,8 @@ package com.drinkool.services; import static io.restassured.RestAssured.*; import com.drinkool.*; -import com.drinkool.dtos.*; +import com.drinkool.lib.dtos.*; + import io.quarkus.test.junit.QuarkusTest; import io.restassured.http.ContentType; import org.junit.jupiter.api.Test; diff --git a/account-service/src/test/java/com/drinkool/services/BaseServiceTest.java b/account-service/src/test/java/com/drinkool/services/BaseServiceTest.java index 2838545..c925bd4 100644 --- a/account-service/src/test/java/com/drinkool/services/BaseServiceTest.java +++ b/account-service/src/test/java/com/drinkool/services/BaseServiceTest.java @@ -4,7 +4,8 @@ import static io.restassured.RestAssured.*; import static org.hamcrest.CoreMatchers.*; import com.drinkool.*; -import com.drinkool.dtos.*; +import com.drinkool.lib.dtos.*; + import io.quarkus.test.junit.QuarkusTest; import io.restassured.http.ContentType; import org.junit.jupiter.api.Test; diff --git a/account-service/src/test/java/com/drinkool/services/CustomerServiceTest.java b/account-service/src/test/java/com/drinkool/services/CustomerServiceTest.java index 359bff5..5a429f6 100644 --- a/account-service/src/test/java/com/drinkool/services/CustomerServiceTest.java +++ b/account-service/src/test/java/com/drinkool/services/CustomerServiceTest.java @@ -4,8 +4,9 @@ import static io.restassured.RestAssured.*; import static org.junit.jupiter.api.Assertions.*; import com.drinkool.*; -import com.drinkool.dtos.*; import com.drinkool.entities.CustomerEntity; +import com.drinkool.lib.dtos.*; + import io.quarkus.test.junit.QuarkusTest; import io.restassured.http.ContentType; import jakarta.inject.Inject; diff --git a/account-service/src/test/java/com/drinkool/services/ManagerServiceTest.java b/account-service/src/test/java/com/drinkool/services/ManagerServiceTest.java index c2343a0..4d72a95 100644 --- a/account-service/src/test/java/com/drinkool/services/ManagerServiceTest.java +++ b/account-service/src/test/java/com/drinkool/services/ManagerServiceTest.java @@ -4,7 +4,8 @@ import static io.restassured.RestAssured.*; import static org.junit.jupiter.api.Assertions.*; import com.drinkool.*; -import com.drinkool.dtos.*; +import com.drinkool.lib.dtos.*; + import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.kafka.*; diff --git a/eatery-service/pom.xml b/eatery-service/pom.xml index 96f4659..334b2e6 100644 --- a/eatery-service/pom.xml +++ b/eatery-service/pom.xml @@ -28,6 +28,8 @@ 3.32.4 true 3.5.4 + 1.6.3 + 1.18.46 @@ -53,6 +55,22 @@ quarkus-security provided + + org.projectlombok + lombok + ${org.projectlombok.version} + provided + + + io.quarkiverse.mapstruct + quarkus-mapstruct + 1.1.0 + + + org.mapstruct + mapstruct + ${org.mapstruct.version} + net.datafaker datafaker @@ -135,6 +153,18 @@ ${compiler-plugin.version} true + + + org.mapstruct + mapstruct-processor + ${org.mapstruct.version} + + + org.projectlombok + lombok + ${org.projectlombok.version} + + diff --git a/eatery-service/src/main/java/com/drinkool/dtos/AddMenuItem.java b/eatery-service/src/main/java/com/drinkool/dtos/AddMenuItem.java new file mode 100644 index 0000000..fab4aed --- /dev/null +++ b/eatery-service/src/main/java/com/drinkool/dtos/AddMenuItem.java @@ -0,0 +1,25 @@ +package com.drinkool.dtos; + +import com.drinkool.interfaces.MenuItemInterface; +import io.quarkus.runtime.annotations.RegisterForReflection; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.eclipse.microprofile.graphql.Input; +import org.eclipse.microprofile.graphql.NonNull; + +@Input +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@RegisterForReflection +public class AddMenuItem implements MenuItemInterface { + + @NonNull + private String name; + + @NonNull + private Double price; +} diff --git a/eatery-service/src/main/java/com/drinkool/dtos/DtoMapper.java b/eatery-service/src/main/java/com/drinkool/dtos/DtoMapper.java new file mode 100644 index 0000000..ea734ed --- /dev/null +++ b/eatery-service/src/main/java/com/drinkool/dtos/DtoMapper.java @@ -0,0 +1,18 @@ +package com.drinkool.dtos; + +import com.drinkool.entities.MenuItemEntity; +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; + +@Mapper(componentModel = "cdi") +public interface DtoMapper { + @BeanMapping( + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE + ) + void updateMenuItemToEntity( + UpdateMenuItem input, + @MappingTarget MenuItemEntity entity + ); +} diff --git a/eatery-service/src/main/java/com/drinkool/dtos/UpdateMenuItem.java b/eatery-service/src/main/java/com/drinkool/dtos/UpdateMenuItem.java new file mode 100644 index 0000000..f25e2ff --- /dev/null +++ b/eatery-service/src/main/java/com/drinkool/dtos/UpdateMenuItem.java @@ -0,0 +1,28 @@ +package com.drinkool.dtos; + +import com.drinkool.interfaces.EntityInterface; +import com.drinkool.interfaces.MenuItemInterface; +import io.quarkus.runtime.annotations.RegisterForReflection; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.eclipse.microprofile.graphql.Input; +import org.eclipse.microprofile.graphql.NonNull; + +@Input +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@RegisterForReflection +public class UpdateMenuItem implements EntityInterface, MenuItemInterface { + + @NonNull + UUID id; + + String name; + + Double price; +} 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 1a1426c..f60ff5f 100644 --- a/eatery-service/src/main/java/com/drinkool/entities/EateryEntity.java +++ b/eatery-service/src/main/java/com/drinkool/entities/EateryEntity.java @@ -25,7 +25,7 @@ public class EateryEntity extends BaseEntity { cascade = CascadeType.ALL, orphanRemoval = true ) - public List menus = new ArrayList<>(); + public List menuItems = new ArrayList<>(); public EateryEntity() {} 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 fbf8e74..93d57e4 100644 --- a/eatery-service/src/main/java/com/drinkool/entities/MenuItemEntity.java +++ b/eatery-service/src/main/java/com/drinkool/entities/MenuItemEntity.java @@ -1,36 +1,43 @@ package com.drinkool.entities; +import com.drinkool.dtos.AddMenuItem; +import com.drinkool.interfaces.MenuItemInterface; import com.drinkool.lib.entities.BaseEntity; import jakarta.persistence.*; import jakarta.transaction.Transactional; +import lombok.Getter; +import lombok.Setter; @Entity @Table -public class MenuItemEntity extends BaseEntity { +@Getter +@Setter +public class MenuItemEntity extends BaseEntity implements MenuItemInterface { @Column(nullable = false) public String name; @Column(nullable = false) - public double price; + public Double price; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "eatery_id") public EateryEntity eatery; + MenuItemEntity() {} + + MenuItemEntity(MenuItemInterface input) { + this.setName(input.getName()); + this.setPrice(input.getPrice()); + } + /** * Phương thức tiện ích để tạo nhanh Menu Item từ tên */ @Transactional - public static MenuItemEntity create( - EateryEntity eatery, - String name, - double price - ) { - MenuItemEntity menuItem = new MenuItemEntity(); + public static MenuItemEntity create(EateryEntity eatery, AddMenuItem input) { + MenuItemEntity menuItem = new MenuItemEntity(input); - menuItem.name = name; - menuItem.price = price; menuItem.eatery = eatery; menuItem.persist(); 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 15fb483..719b0e4 100644 --- a/eatery-service/src/main/java/com/drinkool/services/EateryService.java +++ b/eatery-service/src/main/java/com/drinkool/services/EateryService.java @@ -2,9 +2,12 @@ package com.drinkool.services; import com.drinkool.InternalValue; import com.drinkool.Role; -import com.drinkool.dtos.event.ManagerCreate; +import com.drinkool.dtos.AddMenuItem; +import com.drinkool.dtos.DtoMapper; +import com.drinkool.dtos.UpdateMenuItem; import com.drinkool.entities.EateryEntity; import com.drinkool.entities.MenuItemEntity; +import com.drinkool.lib.dtos.event.ManagerCreate; import io.vertx.core.http.HttpServerRequest; import jakarta.annotation.security.RolesAllowed; import jakarta.enterprise.context.ApplicationScoped; @@ -22,6 +25,9 @@ import org.eclipse.microprofile.reactive.messaging.Incoming; @GraphQLApi public class EateryService { + @Inject + DtoMapper dtoMapper; + @Inject HttpServerRequest request; @@ -46,20 +52,57 @@ public class EateryService { @Mutation("addMenuItem") @RolesAllowed(Role.Manager) @Transactional - public MenuItemEntity addMenuItem( - @Name("name") String name, - @Name("price") double price - ) { + public MenuItemEntity addMenuItem(@Name("menuItem") AddMenuItem menuItem) { String ownerId = request.getHeader(InternalValue.userId); EateryEntity eatery = EateryEntity.findByOwnerId(ownerId); if (eatery == null) return null; - MenuItemEntity item = MenuItemEntity.create(eatery, name, price); + MenuItemEntity item = MenuItemEntity.create(eatery, menuItem); return item; } + @Mutation("updateMenuItem") + @RolesAllowed(Role.Manager) + @Transactional + public MenuItemEntity updateMenuItem(UpdateMenuItem menuItem) { + UUID ownerId = UUID.fromString(request.getHeader(InternalValue.userId)); + + MenuItemEntity item = MenuItemEntity.find( + "id = ?1 and eatery.ownerId = ?2", + menuItem.getId(), + ownerId + ).firstResult(); + + if (item == null) return null; + + dtoMapper.updateMenuItemToEntity(menuItem, item); + + item.persist(); + + return item; + } + + @Mutation("deleteMenuItem") + @RolesAllowed(Role.Manager) + @Transactional + public boolean deleteMenuItem(@Name("menuItemId") UUID menuItemId) { + UUID ownerId = UUID.fromString(request.getHeader(InternalValue.userId)); + + MenuItemEntity item = MenuItemEntity.find( + "id = ?1 and eatery.ownerId = ?2", + menuItemId, + ownerId + ).firstResult(); + + if (item == null) return false; + + item.delete(); + + return true; + } + @Query("menuItemsByEatery") public List getMenuItemsByEatery( @Name("eateryId") UUID eateryId diff --git a/eatery-service/src/main/java/com/drinkool/services/ReviewService.java b/eatery-service/src/main/java/com/drinkool/services/ReviewService.java index 426fc09..0b9a5ca 100644 --- a/eatery-service/src/main/java/com/drinkool/services/ReviewService.java +++ b/eatery-service/src/main/java/com/drinkool/services/ReviewService.java @@ -1,7 +1,8 @@ package com.drinkool.services; -import com.drinkool.dtos.SendReview; import com.drinkool.entities.ReviewEntity; +import com.drinkool.lib.dtos.SendReview; + import jakarta.transaction.Transactional; import jakarta.ws.rs.*; import jakarta.ws.rs.core.Response; diff --git a/eatery-service/src/main/resources/application.properties b/eatery-service/src/main/resources/application.properties index 6652b84..f499263 100644 --- a/eatery-service/src/main/resources/application.properties +++ b/eatery-service/src/main/resources/application.properties @@ -27,7 +27,8 @@ quarkus.native.remote-container-build=true quarkus.native.additional-build-args=--future-defaults=all # Kafka -mp.messaging.connector.smallrye-kafka.bootstrap.servers=${KAFKA_SERVICE_SERVICE_HOST:host.docker.internal}:9092 +%prod.mp.messaging.connector.smallrye-kafka.bootstrap.servers=${KAFKA_SERVICE_SERVICE_HOST:host.docker.internal}:9092 +mp.messaging.incoming.manager-in.connector=smallrye-in-memory ## Create restaurant topic mp.messaging.incoming.manager-in.connector=smallrye-kafka 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 8cb7d49..50a6a4d 100644 --- a/eatery-service/src/test/java/com/drinkool/services/EateryServiceTest.java +++ b/eatery-service/src/test/java/com/drinkool/services/EateryServiceTest.java @@ -9,9 +9,10 @@ import static org.hamcrest.Matchers.hasSize; import com.drinkool.InternalValue; import com.drinkool.Role; -import com.drinkool.dtos.event.ManagerCreate; +import com.drinkool.dtos.AddMenuItem; import com.drinkool.entities.EateryEntity; import com.drinkool.entities.MenuItemEntity; +import com.drinkool.lib.dtos.event.ManagerCreate; import io.quarkus.test.junit.QuarkusTest; import io.restassured.http.ContentType; import io.smallrye.reactive.messaging.memory.InMemoryConnector; @@ -19,6 +20,8 @@ import jakarta.enterprise.context.control.ActivateRequestContext; import jakarta.enterprise.inject.Any; import jakarta.inject.Inject; import jakarta.transaction.Transactional; +import java.util.HashMap; +import java.util.Map; import java.util.UUID; import net.datafaker.Faker; import org.junit.jupiter.api.Assertions; @@ -57,9 +60,10 @@ public class EateryServiceTest { Assertions.assertEquals("Quan Bun Cha Test", eatery.name); } - private UUID lastSavedId; - private String lastSavedName; - private UUID lastOwnerId = UUID.randomUUID(); + private UUID savedEateryId; + private String savedEateryName; + private UUID savedOwnerId = UUID.randomUUID(); + private UUID savedMenuItemId; @BeforeEach @Transactional @@ -67,11 +71,11 @@ public class EateryServiceTest { MenuItemEntity.deleteAll(); EateryEntity.deleteAll(); - lastSavedName = faker.restaurant().name(); + savedEateryName = faker.restaurant().name(); EateryEntity eatery = new EateryEntity(); - eatery = eatery.create(lastOwnerId, lastSavedName); - lastSavedId = eatery.id; + eatery = eatery.create(savedOwnerId, savedEateryName); + savedEateryId = eatery.id; for (int i = 0; i < 2; i++) { EateryEntity e = new EateryEntity(); @@ -79,11 +83,13 @@ public class EateryServiceTest { } for (int i = 0; i < 3; i++) { - MenuItemEntity.create( + savedMenuItemId = MenuItemEntity.create( eatery, - faker.food().dish(), - faker.number().randomDouble(2, 10, 100) - ); + new AddMenuItem( + faker.food().dish(), + faker.number().randomDouble(2, 10, 100) + ) + ).id; } } @@ -101,7 +107,7 @@ public class EateryServiceTest { .statusCode(200) // GraphQL trả về dữ liệu bọc trong object "data" .body("data.allEateries", notNullValue()) - .body("data.allEateries.name", hasItems(lastSavedName)); + .body("data.allEateries.name", hasItems(savedEateryName)); } @Test @@ -110,7 +116,7 @@ public class EateryServiceTest { // Lưu ý: Trong GraphQL, String/UUID phải nằm trong dấu ngoặc kép String query = String.format( "{ \"query\": \"{ eateryById(id: \\\"%s\\\") { ownerId name } }\" }", - lastSavedId + savedEateryId ); given() @@ -120,32 +126,35 @@ public class EateryServiceTest { .post("/graphql") .then() .statusCode(200) - .body("data.eateryById.name", is(lastSavedName)); + .body("data.eateryById.name", is(savedEateryName)); } @Test public void testAddMenuItemSuccess() { String mutation = - "mutation addMenuItem($name: String!, $price: Float!) {" + - " addMenuItem(name: $name, price: $price) {" + + "mutation addMenuItem($menuItem: AddMenuItemInput!) {" + + " addMenuItem(menuItem: $menuItem) {" + " id" + " name" + " price" + " }" + "}"; - java.util.Map variables = new java.util.HashMap<>(); - variables.put("name", "Trà Sữa"); - variables.put("price", 30000.0); + Map menuItemData = new HashMap<>(); + menuItemData.put("name", "Trà Sữa"); + menuItemData.put("price", 30000.0); - java.util.Map requestBody = new java.util.HashMap<>(); + Map variables = new HashMap<>(); + variables.put("menuItem", menuItemData); + + Map requestBody = new 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 + .header(InternalValue.userId, savedOwnerId) // Thay "x-user-id" bằng InternalValue.userId của bạn .body(requestBody) .when() .post("/graphql") @@ -158,26 +167,29 @@ public class EateryServiceTest { @Test public void testAddMenuItemFailInvalidRole() { String mutation = - "mutation addMenuItem($name: String!, $price: Float!) {" + - " addMenuItem(name: $name, price: $price) {" + + "mutation addMenuItem($menuItem: AddMenuItemInput!) {" + + " addMenuItem(menuItem: $menuItem) {" + " id" + " name" + " price" + " }" + "}"; - java.util.Map variables = new java.util.HashMap<>(); - variables.put("name", "Trà Sữa"); - variables.put("price", 30000.0); + Map menuItemData = new HashMap<>(); + menuItemData.put("name", "Trà Sữa"); + menuItemData.put("price", 30000.0); - java.util.Map requestBody = new java.util.HashMap<>(); + Map variables = new HashMap<>(); + variables.put("menuItem", menuItemData); + + Map requestBody = new HashMap<>(); requestBody.put("query", mutation); requestBody.put("variables", variables); given() .contentType(ContentType.JSON) .header(InternalValue.role, Role.Customer) - .header(InternalValue.userId, lastOwnerId) + .header(InternalValue.userId, savedOwnerId) .body(requestBody) .when() .post("/graphql") @@ -190,7 +202,7 @@ public class EateryServiceTest { String mutation = "mutation { addMenuItem(name: \"Coffee\", price: 20000.0) { id } }"; - java.util.Map requestBody = new java.util.HashMap<>(); + Map requestBody = new HashMap<>(); requestBody.put("query", mutation); given() @@ -216,10 +228,10 @@ public class EateryServiceTest { " }" + "}"; - java.util.Map variables = new java.util.HashMap<>(); - variables.put("id", lastSavedId.toString()); + Map variables = new HashMap<>(); + variables.put("id", savedEateryId.toString()); - java.util.Map requestBody = new java.util.HashMap<>(); + Map requestBody = new HashMap<>(); requestBody.put("query", query); requestBody.put("variables", variables); @@ -244,10 +256,10 @@ public class EateryServiceTest { " }" + "}"; - java.util.Map variables = new java.util.HashMap<>(); + Map variables = new HashMap<>(); variables.put("id", randomId); - java.util.Map requestBody = new java.util.HashMap<>(); + Map requestBody = new HashMap<>(); requestBody.put("query", query); requestBody.put("variables", variables); @@ -260,4 +272,69 @@ public class EateryServiceTest { .statusCode(200) .body("data.menuItemsByEatery", hasSize(0)); // Phải trả về List rỗng như code bạn viết } + + @Test + public void testUpdateMenuItem_Success() { + String mutation = """ + mutation updateMenuItem($menuItem: UpdateMenuItemInput!) { + updateMenuItem(menuItem: $menuItem) { + id + name + price + } + } + """; + + String newValue = "Phở Bò"; + + Map menuItemData = new HashMap<>(); + menuItemData.put("id", savedMenuItemId); + menuItemData.put("name", newValue); + + Map variables = new HashMap<>(); + variables.put("menuItem", menuItemData); + + Map requestBody = new HashMap<>(); + requestBody.put("query", mutation); + requestBody.put("variables", variables); + + given() + .contentType(ContentType.JSON) + .header(InternalValue.role, Role.Manager) + .header(InternalValue.userId, savedOwnerId) + .body(requestBody) + .when() + .post("/graphql") + .then() + .body("data.updateMenuItem.name", is(newValue)) + .body("data.updateMenuItem.id", is(savedMenuItemId.toString())) + .statusCode(200); + } + + @Test + public void testDeleteMenuItem_Success() { + String mutation = """ + mutation deleteItem($input: String!) { + deleteMenuItem(menuItemId: $input) + } + """; + + Map variables = new HashMap<>(); + variables.put("input", savedMenuItemId.toString()); + + Map requestBody = new HashMap<>(); + requestBody.put("query", mutation); + requestBody.put("variables", variables); + + given() + .contentType(ContentType.JSON) + .header(InternalValue.role, Role.Manager) + .header(InternalValue.userId, savedOwnerId) + .body(requestBody) + .when() + .post("/graphql") + .then() + .statusCode(200) + .body("data.deleteMenuItem", is(true)); + } } diff --git a/eatery-service/src/test/java/com/drinkool/services/ReviewServiceTest.java b/eatery-service/src/test/java/com/drinkool/services/ReviewServiceTest.java index 5ed751e..bdab888 100644 --- a/eatery-service/src/test/java/com/drinkool/services/ReviewServiceTest.java +++ b/eatery-service/src/test/java/com/drinkool/services/ReviewServiceTest.java @@ -3,8 +3,8 @@ package com.drinkool.services; import static io.restassured.RestAssured.given; import static org.junit.jupiter.api.Assertions.*; -import com.drinkool.dtos.SendReview; import com.drinkool.entities.ReviewEntity; +import com.drinkool.lib.dtos.SendReview; import com.drinkool.lib.models.ReviewModel; import io.quarkus.test.junit.QuarkusTest; import io.restassured.http.ContentType; diff --git a/gateway-service/src/main/java/com/drinkool/controller/CustomerController.java b/gateway-service/src/main/java/com/drinkool/controller/CustomerController.java index 36efce8..1cb2e87 100644 --- a/gateway-service/src/main/java/com/drinkool/controller/CustomerController.java +++ b/gateway-service/src/main/java/com/drinkool/controller/CustomerController.java @@ -1,7 +1,7 @@ package com.drinkool.controller; import com.drinkool.*; -import com.drinkool.dtos.*; +import com.drinkool.lib.dtos.*; import com.drinkool.services.CustomerService; import io.smallrye.mutiny.Uni; import jakarta.inject.Inject; 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 d54173e..2da0157 100644 --- a/gateway-service/src/main/java/com/drinkool/controller/EateryController.java +++ b/gateway-service/src/main/java/com/drinkool/controller/EateryController.java @@ -1,7 +1,8 @@ package com.drinkool.controller; import com.drinkool.InternalValue; -import com.drinkool.dtos.GraphqlDto; +import com.drinkool.lib.dtos.GraphqlDto; + import io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClient; import io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClientBuilder; import jakarta.inject.Inject; diff --git a/gateway-service/src/main/java/com/drinkool/controller/IndexController.java b/gateway-service/src/main/java/com/drinkool/controller/IndexController.java index a212dfd..7e3d1b9 100644 --- a/gateway-service/src/main/java/com/drinkool/controller/IndexController.java +++ b/gateway-service/src/main/java/com/drinkool/controller/IndexController.java @@ -1,7 +1,7 @@ package com.drinkool.controller; import com.drinkool.Url; -import com.drinkool.dtos.SmsOtp; +import com.drinkool.lib.dtos.SmsOtp; import com.drinkool.services.BaseService; import io.smallrye.mutiny.Uni; import jakarta.inject.Inject; diff --git a/gateway-service/src/main/java/com/drinkool/controller/MainController.java b/gateway-service/src/main/java/com/drinkool/controller/MainController.java index f739339..7f378df 100644 --- a/gateway-service/src/main/java/com/drinkool/controller/MainController.java +++ b/gateway-service/src/main/java/com/drinkool/controller/MainController.java @@ -1,7 +1,7 @@ package com.drinkool.controller; import com.drinkool.Url; -import com.drinkool.dtos.Login; +import com.drinkool.lib.dtos.Login; import com.drinkool.services.CustomerService; import com.drinkool.services.ManagerService; import io.smallrye.mutiny.Uni; diff --git a/gateway-service/src/main/java/com/drinkool/controller/ManagerController.java b/gateway-service/src/main/java/com/drinkool/controller/ManagerController.java index 8b126f2..c95b504 100644 --- a/gateway-service/src/main/java/com/drinkool/controller/ManagerController.java +++ b/gateway-service/src/main/java/com/drinkool/controller/ManagerController.java @@ -1,7 +1,7 @@ package com.drinkool.controller; import com.drinkool.*; -import com.drinkool.dtos.*; +import com.drinkool.lib.dtos.*; import com.drinkool.services.ManagerService; import io.smallrye.mutiny.Uni; import jakarta.inject.Inject; diff --git a/gateway-service/src/main/java/com/drinkool/services/BaseService.java b/gateway-service/src/main/java/com/drinkool/services/BaseService.java index 48a87a5..a07bc1d 100644 --- a/gateway-service/src/main/java/com/drinkool/services/BaseService.java +++ b/gateway-service/src/main/java/com/drinkool/services/BaseService.java @@ -1,7 +1,8 @@ package com.drinkool.services; import com.drinkool.Url; -import com.drinkool.dtos.SmsOtp; +import com.drinkool.lib.dtos.SmsOtp; + import io.smallrye.mutiny.Uni; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; diff --git a/gateway-service/src/main/java/com/drinkool/services/CustomerService.java b/gateway-service/src/main/java/com/drinkool/services/CustomerService.java index 5660e19..f6799a7 100644 --- a/gateway-service/src/main/java/com/drinkool/services/CustomerService.java +++ b/gateway-service/src/main/java/com/drinkool/services/CustomerService.java @@ -3,7 +3,8 @@ package com.drinkool.services; import com.drinkool.InternalValue; import com.drinkool.Role; import com.drinkool.Url; -import com.drinkool.dtos.*; +import com.drinkool.lib.dtos.*; + import io.smallrye.mutiny.Uni; import jakarta.ws.rs.*; import jakarta.ws.rs.core.Response; diff --git a/gateway-service/src/main/java/com/drinkool/services/ManagerService.java b/gateway-service/src/main/java/com/drinkool/services/ManagerService.java index bae3afd..e0edfb3 100644 --- a/gateway-service/src/main/java/com/drinkool/services/ManagerService.java +++ b/gateway-service/src/main/java/com/drinkool/services/ManagerService.java @@ -3,7 +3,8 @@ package com.drinkool.services; import com.drinkool.InternalValue; import com.drinkool.Role; import com.drinkool.Url; -import com.drinkool.dtos.*; +import com.drinkool.lib.dtos.*; + import io.smallrye.mutiny.Uni; import jakarta.ws.rs.*; import jakarta.ws.rs.core.Response; diff --git a/lib/pom.xml b/lib/pom.xml index a92793a..26901c6 100644 --- a/lib/pom.xml +++ b/lib/pom.xml @@ -41,7 +41,7 @@ org.projectlombok lombok - 1.18.30 + 1.18.46 provided @@ -62,5 +62,9 @@ 5.10.0 test + + io.quarkus + quarkus-smallrye-graphql + diff --git a/lib/src/main/java/com/drinkool/interfaces/EateryInterface.java b/lib/src/main/java/com/drinkool/interfaces/EateryInterface.java new file mode 100644 index 0000000..2afd36a --- /dev/null +++ b/lib/src/main/java/com/drinkool/interfaces/EateryInterface.java @@ -0,0 +1,12 @@ +package com.drinkool.interfaces; + +import java.util.UUID; + +public interface EateryInterface { + UUID getOwnerId(); + void setOwnerId(UUID x); + String getName(); + void setName(String x); + boolean getIsVerified(); + void setIsVerified(boolean x); +} diff --git a/lib/src/main/java/com/drinkool/interfaces/EntityInterface.java b/lib/src/main/java/com/drinkool/interfaces/EntityInterface.java new file mode 100644 index 0000000..89f517f --- /dev/null +++ b/lib/src/main/java/com/drinkool/interfaces/EntityInterface.java @@ -0,0 +1,8 @@ +package com.drinkool.interfaces; + +import java.util.UUID; + +public interface EntityInterface { + UUID getId(); + void setId(UUID x); +} diff --git a/lib/src/main/java/com/drinkool/interfaces/MenuItemInterface.java b/lib/src/main/java/com/drinkool/interfaces/MenuItemInterface.java new file mode 100644 index 0000000..74aaabd --- /dev/null +++ b/lib/src/main/java/com/drinkool/interfaces/MenuItemInterface.java @@ -0,0 +1,8 @@ +package com.drinkool.interfaces; + +public interface MenuItemInterface { + String getName(); + void setName(String x); + Double getPrice(); + void setPrice(Double x); +} diff --git a/lib/src/main/java/com/drinkool/dtos/AddInventory.java b/lib/src/main/java/com/drinkool/lib/dtos/AddInventory.java similarity index 70% rename from lib/src/main/java/com/drinkool/dtos/AddInventory.java rename to lib/src/main/java/com/drinkool/lib/dtos/AddInventory.java index 7c2a1f8..374742a 100644 --- a/lib/src/main/java/com/drinkool/dtos/AddInventory.java +++ b/lib/src/main/java/com/drinkool/lib/dtos/AddInventory.java @@ -1,4 +1,4 @@ -package com.drinkool.dtos; +package com.drinkool.lib.dtos; public class AddInventory { diff --git a/lib/src/main/java/com/drinkool/dtos/GraphqlDto.java b/lib/src/main/java/com/drinkool/lib/dtos/GraphqlDto.java similarity index 76% rename from lib/src/main/java/com/drinkool/dtos/GraphqlDto.java rename to lib/src/main/java/com/drinkool/lib/dtos/GraphqlDto.java index a358ed0..309d3f2 100644 --- a/lib/src/main/java/com/drinkool/dtos/GraphqlDto.java +++ b/lib/src/main/java/com/drinkool/lib/dtos/GraphqlDto.java @@ -1,4 +1,4 @@ -package com.drinkool.dtos; +package com.drinkool.lib.dtos; public class GraphqlDto { diff --git a/lib/src/main/java/com/drinkool/dtos/Login.java b/lib/src/main/java/com/drinkool/lib/dtos/Login.java similarity index 69% rename from lib/src/main/java/com/drinkool/dtos/Login.java rename to lib/src/main/java/com/drinkool/lib/dtos/Login.java index af5ca86..e87f3d8 100644 --- a/lib/src/main/java/com/drinkool/dtos/Login.java +++ b/lib/src/main/java/com/drinkool/lib/dtos/Login.java @@ -1,4 +1,4 @@ -package com.drinkool.dtos; +package com.drinkool.lib.dtos; public class Login { diff --git a/lib/src/main/java/com/drinkool/dtos/ManagerSignup.java b/lib/src/main/java/com/drinkool/lib/dtos/ManagerSignup.java similarity index 70% rename from lib/src/main/java/com/drinkool/dtos/ManagerSignup.java rename to lib/src/main/java/com/drinkool/lib/dtos/ManagerSignup.java index 8857f0e..89db905 100644 --- a/lib/src/main/java/com/drinkool/dtos/ManagerSignup.java +++ b/lib/src/main/java/com/drinkool/lib/dtos/ManagerSignup.java @@ -1,4 +1,4 @@ -package com.drinkool.dtos; +package com.drinkool.lib.dtos; public class ManagerSignup extends Signup { diff --git a/lib/src/main/java/com/drinkool/dtos/QuickLogin.java b/lib/src/main/java/com/drinkool/lib/dtos/QuickLogin.java similarity index 69% rename from lib/src/main/java/com/drinkool/dtos/QuickLogin.java rename to lib/src/main/java/com/drinkool/lib/dtos/QuickLogin.java index 6e4c3f8..adbb06b 100644 --- a/lib/src/main/java/com/drinkool/dtos/QuickLogin.java +++ b/lib/src/main/java/com/drinkool/lib/dtos/QuickLogin.java @@ -1,4 +1,4 @@ -package com.drinkool.dtos; +package com.drinkool.lib.dtos; public class QuickLogin { diff --git a/lib/src/main/java/com/drinkool/dtos/QuickSignup.java b/lib/src/main/java/com/drinkool/lib/dtos/QuickSignup.java similarity index 63% rename from lib/src/main/java/com/drinkool/dtos/QuickSignup.java rename to lib/src/main/java/com/drinkool/lib/dtos/QuickSignup.java index aedb13d..3844736 100644 --- a/lib/src/main/java/com/drinkool/dtos/QuickSignup.java +++ b/lib/src/main/java/com/drinkool/lib/dtos/QuickSignup.java @@ -1,4 +1,4 @@ -package com.drinkool.dtos; +package com.drinkool.lib.dtos; public class QuickSignup { diff --git a/lib/src/main/java/com/drinkool/dtos/SendReview.java b/lib/src/main/java/com/drinkool/lib/dtos/SendReview.java similarity index 84% rename from lib/src/main/java/com/drinkool/dtos/SendReview.java rename to lib/src/main/java/com/drinkool/lib/dtos/SendReview.java index c0fb899..2793753 100644 --- a/lib/src/main/java/com/drinkool/dtos/SendReview.java +++ b/lib/src/main/java/com/drinkool/lib/dtos/SendReview.java @@ -1,4 +1,4 @@ -package com.drinkool.dtos; +package com.drinkool.lib.dtos; import com.drinkool.lib.models.ReviewModel; import java.util.UUID; diff --git a/lib/src/main/java/com/drinkool/dtos/Signup.java b/lib/src/main/java/com/drinkool/lib/dtos/Signup.java similarity index 75% rename from lib/src/main/java/com/drinkool/dtos/Signup.java rename to lib/src/main/java/com/drinkool/lib/dtos/Signup.java index d63b990..0db754a 100644 --- a/lib/src/main/java/com/drinkool/dtos/Signup.java +++ b/lib/src/main/java/com/drinkool/lib/dtos/Signup.java @@ -1,4 +1,4 @@ -package com.drinkool.dtos; +package com.drinkool.lib.dtos; public class Signup { diff --git a/lib/src/main/java/com/drinkool/dtos/SmsOtp.java b/lib/src/main/java/com/drinkool/lib/dtos/SmsOtp.java similarity index 60% rename from lib/src/main/java/com/drinkool/dtos/SmsOtp.java rename to lib/src/main/java/com/drinkool/lib/dtos/SmsOtp.java index a7ff340..482733e 100644 --- a/lib/src/main/java/com/drinkool/dtos/SmsOtp.java +++ b/lib/src/main/java/com/drinkool/lib/dtos/SmsOtp.java @@ -1,4 +1,4 @@ -package com.drinkool.dtos; +package com.drinkool.lib.dtos; public class SmsOtp { diff --git a/lib/src/main/java/com/drinkool/dtos/event/ManagerCreate.java b/lib/src/main/java/com/drinkool/lib/dtos/event/ManagerCreate.java similarity index 88% rename from lib/src/main/java/com/drinkool/dtos/event/ManagerCreate.java rename to lib/src/main/java/com/drinkool/lib/dtos/event/ManagerCreate.java index e337a6f..ef06c68 100644 --- a/lib/src/main/java/com/drinkool/dtos/event/ManagerCreate.java +++ b/lib/src/main/java/com/drinkool/lib/dtos/event/ManagerCreate.java @@ -1,4 +1,4 @@ -package com.drinkool.dtos.event; +package com.drinkool.lib.dtos.event; import io.quarkus.runtime.annotations.RegisterForReflection; import java.util.UUID; diff --git a/lib/src/main/java/com/drinkool/lib/entities/BaseEntity.java b/lib/src/main/java/com/drinkool/lib/entities/BaseEntity.java index 0ee8e50..0a33368 100644 --- a/lib/src/main/java/com/drinkool/lib/entities/BaseEntity.java +++ b/lib/src/main/java/com/drinkool/lib/entities/BaseEntity.java @@ -1,13 +1,15 @@ package com.drinkool.lib.entities; import io.quarkus.hibernate.orm.panache.PanacheEntityBase; -import jakarta.persistence.*; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.MappedSuperclass; import java.util.UUID; @MappedSuperclass public class BaseEntity extends PanacheEntityBase { - @Id + @jakarta.persistence.Id @GeneratedValue(strategy = GenerationType.UUID) public UUID id; } diff --git a/scripts/test.sh b/scripts/test.sh index 3b7a38f..f7040bf 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -1 +1,33 @@ -mvn clean package -Dquarkus.container-image.push=false -Dquarkus.container-image.build=false \ No newline at end of file +#!/bin/bash + +# Khởi tạo giá trị mặc định +DEBUG_FLAG="" +TEST_FLAG="" + +# Duyệt qua các tham số đầu vào +for arg in "$@"; do + case $arg in + --debug) + DEBUG_FLAG="-Dmaven.surefire.debug" + shift # Bỏ qua flag này + ;; + --test=*) + # Lấy giá trị sau dấu = + TEST_NAME="${arg#*=}" + TEST_FLAG="-Dtest=$TEST_NAME" + shift + ;; + *) + # Các tham số không xác định (nếu cần xử lý thêm) + ;; + esac +done + +echo "Running: mvn clean package $DEBUG_FLAG $TEST_FLAG" + +# Chạy lệnh Maven +mvn clean package \ + -Dquarkus.container-image.push=false \ + -Dquarkus.container-image.build=false \ + $DEBUG_FLAG \ + $TEST_FLAG \ No newline at end of file