Compare commits

...

25 Commits

Author SHA1 Message Date
TakahashiNguyen 4ae4fa6f2e fix: better ci (#10)
Release package / release (push) Failing after 8m28s
Co-authored-by: TakahashiNg <83152264+TakahashiNguyen@users.noreply.github.com>
Reviewed-on: #10
2026-03-30 09:29:43 +00:00
TakahashiNguyen d9646ab9d1 feat(eatery-service): init menu item (#9)
Release package / release (push) Failing after 3m24s
Co-authored-by: TakahashiNg <83152264+TakahashiNguyen@users.noreply.github.com>
Reviewed-on: #9
2026-03-30 08:46:44 +00:00
TakahashiNguyen 0fa8e37c88 chore(test): update test user model (#7)
Java CI with Maven / build-and-test (push) Successful in 7m2s
Release package / release (push) Failing after 12m15s
Co-authored-by: TranHuuDanh <tranhuudanh@demonkernel.io.vn>
Co-authored-by: gitea-actions <actions-user@noreply.git.demonkernel.io.vn>
Co-authored-by: TakahashiNg <83152264+TakahashiNguyen@users.noreply.github.com>
Reviewed-on: #7
2026-03-25 07:45:49 +00:00
TakahashiNg bfd12e32f9 Merge branch 'main' of https://git.demonkernel.io.vn/FoodSurf/backend
Release package / release (push) Successful in 3m14s
Java CI with Maven / build-and-test (push) Successful in 3m29s
2026-03-25 07:24:31 +00:00
TakahashiNg 3fe3540e7f Mergh origin main branch 'dev-better-ci' 2026-03-25 07:23:59 +00:00
gitea-actions 6931ef71bc chore: release [ci skip] 2026-03-25 07:17:58 +00:00
TakahashiNg afda64befb ci: update
Release package / release (push) Successful in 3m26s
Java CI with Maven / build-and-test (push) Successful in 3m46s
2026-03-25 07:15:11 +00:00
TakahashiNg 7faca4e681 ci: update
Release package / release (push) Failing after 3m37s
Java CI with Maven / build-and-test (push) Successful in 3m55s
2026-03-25 07:09:37 +00:00
TakahashiNg 2bfd7a1364 ci: test
Release package / release (push) Failing after 1m10s
Java CI with Maven / build-and-test (push) Successful in 3m10s
2026-03-25 07:05:44 +00:00
TakahashiNg 1c5bc62d11 ci: update
Release package / release (push) Failing after 2m1s
Java CI with Maven / build-and-test (push) Successful in 3m42s
2026-03-25 07:00:06 +00:00
TakahashiNg dd51dd5f5a ci: update
Release package / release (push) Failing after 3m47s
Java CI with Maven / build-and-test (push) Successful in 3m51s
2026-03-25 06:54:12 +00:00
TakahashiNg 76e4df8384 ci: update
Release package / release (push) Failing after 3m33s
Java CI with Maven / build-and-test (push) Successful in 3m49s
2026-03-25 06:44:20 +00:00
TakahashiNguyen 7db7e6de1e fix: deploy using deploy key (#5)
Release package / release (push) Successful in 3m1s
Java CI with Maven / build-and-test (push) Successful in 3m19s
Co-authored-by: TakahashiNg <83152264+TakahashiNguyen@users.noreply.github.com>
Reviewed-on: #5
2026-03-25 04:41:50 +00:00
TakahashiNg 910ef30c12 chore: update
Release package / release (push) Has been cancelled
Java CI with Maven / build-and-test (push) Has been cancelled
2026-03-25 04:35:20 +00:00
TakahashiNg 3af40b3725 ci: update 2026-03-25 04:31:52 +00:00
TakahashiNg 0eaf52b727 ci: update
Release package / release (push) Failing after 1m20s
Java CI with Maven / build-and-test (push) Successful in 3m9s
2026-03-25 04:22:33 +00:00
TakahashiNg 11aab29fe7 ci: update
Release package / release (push) Failing after 56s
Java CI with Maven / build-and-test (push) Successful in 2m48s
2026-03-25 04:15:58 +00:00
TakahashiNg 44457d0510 ci: test
Java CI with Maven / build-and-test (push) Successful in 4m14s
Release package / release (push) Failing after 4m25s
2026-03-25 04:09:41 +00:00
TakahashiNg 7736761a11 ci: better ssh setup
Java CI with Maven / build-and-test (push) Successful in 2m27s
Release package / release (push) Failing after 58s
2026-03-25 04:01:38 +00:00
TakahashiNg 0793e1ceab Merge branch 'dev-better-ci' of https://git.demonkernel.io.vn/FoodSurf/backend into dev-better-ci
Release package / release (push) Failing after 1m3s
Java CI with Maven / build-and-test (push) Successful in 2m44s
2026-03-25 03:57:11 +00:00
TakahashiNg 20f669f3bc ci: better variable 2026-03-25 03:57:07 +00:00
TakahashiNguyen 232faa6897 Merge branch 'main' into dev-better-ci
Release package / release (push) Failing after 23s
Java CI with Maven / build-and-test (push) Successful in 2m15s
2026-03-25 03:53:24 +00:00
TakahashiNg 689a153d7f chore: update to deploy using deploy key
Release package / release (push) Failing after 32s
Java CI with Maven / build-and-test (push) Has been cancelled
2026-03-25 03:49:41 +00:00
TakahashiNguyen b375feb538 fix: better publish script (#4)
Release package / release (push) Failing after 4m16s
Java CI with Maven / build-and-test (push) Successful in 2m53s
Co-authored-by: TakahashiNg <83152264+TakahashiNguyen@users.noreply.github.com>
Reviewed-on: #4
2026-03-25 03:33:56 +00:00
TakahashiNg 2af438c308 ci: better publish script
Release package / release (push) Has started running
Java CI with Maven / build-and-test (push) Has been cancelled
2026-03-25 03:26:42 +00:00
17 changed files with 378 additions and 48 deletions
+25 -7
View File
@@ -4,7 +4,6 @@ on:
push:
branches:
- main
- dev-*
jobs:
release:
@@ -12,6 +11,24 @@ jobs:
permissions:
contents: write
steps:
- name: Calculate and Export Target IP
run: |
# 1. Lấy IP hiện tại và tính toán IP đích (đổi octet cuối thành .1)
RUNNER_IP=$(hostname -I | awk '{print $1}')
CALCULATED_IP=$(echo $RUNNER_IP | cut -d'.' -f1-3).1
# 2. Đưa vào biến môi trường toàn cục của Job
echo "TARGET_IP=${CALCULATED_IP}" >> $GITHUB_ENV
- name: Setup SSH Key
run: |
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan -p 222 -t ed25519 $TARGET_IP >> ~/.ssh/known_hosts
- uses: actions/checkout@v6
with:
fetch-depth: 0
@@ -65,21 +82,22 @@ jobs:
GITEA_TOKEN: ${{ secrets.ACCESS_TOKEN }}
run: |
pnpm i
pnpm format
pnpm release
pnpm format
- name: Commit & Push Changes
env:
MY_PAT_TOKEN: ${{ secrets.ACCESS_TOKEN }}
run: |
if [ -n "$(git status --porcelain)" ]; then
if [ -n "$(git status --porcelain)" ]&& [ "${{ github.ref_name }}" = "main" ]; then
git config --global user.name "gitea-actions"
git config --global user.email "actions-user@noreply.git.demonkernel.io.vn"
git remote set-url origin https://x-access-token:${MY_PAT_TOKEN}@git.demonkernel.io.vn/${{ github.repository }}.git
REPO_NAME="${{ gitea.repository }}"
git remote set-url origin ssh://git@$TARGET_IP:222/${REPO_NAME}.git
git rm -r --cached .
git add .
git commit -m "chore: release [ci skip]"
git push origin HEAD:${{ github.ref_name }}
git push
fi
+3 -1
View File
@@ -1,7 +1,9 @@
name: Java CI with Maven
on:
push:
pull_request:
branches:
- main
jobs:
build-and-test:
+9 -2
View File
@@ -1,5 +1,12 @@
{
"branches": ["main", { "name": "dev-*", "prerelease": "dev" }],
"branches": [
"main",
{
"name": "dev-*",
"prerelease": "${name.replace('dev-', '')}",
"channel": "${name.replace('dev-', '')}"
}
],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
@@ -8,7 +15,7 @@
"@semantic-release/exec",
{
"prepareCmd": "./mvnw versions:set -DnewVersion=${nextRelease.version}",
"publishCmd": "if [ \"${branch.name}\" = \"main\" ]; then ./mvnw package -Dquarkus.container-image.tag=${nextRelease.version} -DskipTests; fi"
"publishCmd": "if [ \"${branch.name}\" = \"main\" ]; then ./mvnw clean package -Dquarkus.container-image.tag=${nextRelease.version} -DskipTests; fi"
}
],
[
@@ -2,9 +2,12 @@ package com.drinkool.models;
import static org.junit.jupiter.api.Assertions.*;
import com.drinkool.entities.CustomerEntity;
import io.quarkus.test.TestTransaction;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.persistence.*;
import jakarta.transaction.Transactional;
import jakarta.ws.rs.BadRequestException;
import java.util.*;
import org.junit.jupiter.api.Test;
@@ -28,7 +31,7 @@ public class UserModelTest {
assertNotNull(user.id, "ID not null after persist");
assertEquals("Tran Huu Danh", user.name);
assertEquals(phone, user.phone);
assertNotNull(user.hashedPassword, "password phai hash");
// assertNotNull(user.hashedPassword, "password phai hash");
TestUserEntity savedUser = TestUserEntity.find(
"phone",
@@ -36,6 +39,42 @@ public class UserModelTest {
).firstResult();
assertNotNull(savedUser);
}
// 2. Test case: Đăng ký thất bại do số điện thoại đã tồn tại
@Test
@Transactional
public void testSignupFailExistedUser() {
TestUserEntity existUser = new TestUserEntity();
String phone =
"+8477" + String.format("%07d", (new Random()).nextInt(10000000));
String password = "tungtungtungshahua";
existUser.signup("Nguyen Thanh Quy", phone, password);
CustomerEntity newCustomer = new CustomerEntity();
BadRequestException exception = assertThrows(
BadRequestException.class,
() -> {
newCustomer.signup("Nguyen Viet Anh", phone, "02092006Anh");
}
);
assertEquals("ExistedUser", exception.getMessage());
}
// 3. Test case: Đăng ký thất bại do số điện thoại sai định dạng
@Test
@TestTransaction
public void testSignupFailInvalidPhoneNumber() {
TestUserEntity customer = new TestUserEntity();
String invalidPhone = "12345";
BadRequestException exception = assertThrows(
BadRequestException.class,
() -> {
customer.signup("Lam Vi Hoang", invalidPhone, "Pass123");
}
);
assertEquals("InvalidPhoneNumber", exception.getMessage());
}
}
@@ -0,0 +1,50 @@
package com.drinkool.entities;
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;
}
}
@@ -9,21 +9,25 @@ import jakarta.transaction.Transactional;
public class InventoryItemEntity extends BaseEntity {
public String name;
public int quantity;
public String unit;
private InventoryItemEntity() {}
// Create
@Transactional
public void add(String name, int quantity, String unit) {
this.name = name;
this.quantity = quantity;
this.unit = unit;
public static InventoryItemEntity create(String name, String unit) {
InventoryItemEntity item = new InventoryItemEntity();
this.persist();
item.name = name;
item.unit = unit;
item.persist();
return item;
}
@Transactional
public void add(String name, int quantity) {
add(name, quantity, "unit");
public static InventoryItemEntity create(String name) {
return InventoryItemEntity.create(name, "unit");
}
}
@@ -0,0 +1,57 @@
package com.drinkool.entities;
import jakarta.persistence.*;
import jakarta.transaction.Transactional;
import java.util.*;
@Entity
@Table
public class MenuItemEntity extends BaseEntity {
public String name;
public double price;
// 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<MenuItemIngredientEntity> ingredients = new ArrayList<>();
private MenuItemEntity() {}
/**
* 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();
menu.name = name;
menu.price = price;
menu.persist();
return menu;
}
}
@@ -0,0 +1,36 @@
package com.drinkool.entities;
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;
}
}
@@ -13,16 +13,23 @@ public class ReviewEntity extends ReviewModel {
public UUID eateryId;
private ReviewEntity(ReviewModel input) {
super(input);
}
@Transactional
public void receive(UUID reviewerId, UUID eateryId, ReviewModel review) {
this.reviewerId = reviewerId;
public static ReviewEntity create(
UUID reviewerId,
UUID eateryId,
ReviewModel reviewInput
) {
ReviewEntity review = new ReviewEntity(reviewInput);
this.eateryId = eateryId;
review.reviewerId = reviewerId;
review.eateryId = eateryId;
this.rating = review.rating;
review.persist();
this.comment = review.comment;
this.persist();
return review;
}
}
@@ -10,12 +10,10 @@ import jakarta.ws.rs.core.Response;
public class InventoryService {
@POST
@Path("/add")
@Path("/create")
@Transactional
public Response add(AddInventory input) {
InventoryItemEntity newItem = new InventoryItemEntity();
newItem.add(input.name, input.quantity, input.unit);
public Response create(AddInventory input) {
InventoryItemEntity.create(input.name, input.unit);
return Response.ok().build();
}
@@ -6,16 +6,14 @@ import jakarta.transaction.Transactional;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.Response;
@Path("/api")
@Path("/api/review")
public class ReviewService {
@POST
@Path("/leaveReview")
@Path("/create")
@Transactional
public Response leaveReview(SendReview input) {
ReviewEntity newReview = new ReviewEntity();
newReview.receive(input.reviewerId, input.orderId, input.review);
public Response create(SendReview input) {
ReviewEntity.create(input.reviewerId, input.orderId, input.review);
return Response.status(201).build();
}
@@ -0,0 +1,52 @@
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);
}
}
@@ -0,0 +1,58 @@
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";
double inventoryItemQuantity = 10;
String inventoryItemUnit = "l";
EateryInventoryItemEntity inventoryItem = EateryInventoryItemEntity.create(
inventoryItemName,
inventoryItemQuantity,
inventoryItemUnit
);
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);
}
}
@@ -7,7 +7,6 @@ import com.drinkool.dtos.AddInventory;
import com.drinkool.entities.InventoryItemEntity;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
import java.util.Random;
import java.util.UUID;
import org.junit.jupiter.api.Test;
@@ -16,19 +15,16 @@ public class InventoryServiceTest {
@Test
void add() {
Random random = new Random();
String name = UUID.randomUUID().toString();
AddInventory input = new AddInventory();
input.name = name;
input.quantity = random.nextInt(100);
given()
.contentType(ContentType.JSON)
.body(input)
.when()
.post("/api/inventory/add")
.post("/api/inventory/create")
.then();
assertEquals(1, InventoryItemEntity.find("name", name).count());
@@ -27,16 +27,14 @@ public class ReviewServiceTest {
SendReview input = new SendReview();
input.reviewerId = reviewerId;
input.orderId = orderId;
ReviewModel reviewModel = new ReviewModel();
reviewModel.comment = comment;
reviewModel.rating = rating;
ReviewModel reviewModel = new ReviewModel(rating, comment);
input.review = reviewModel;
given()
.contentType(ContentType.JSON)
.body(input)
.when()
.post("/api/leaveReview")
.post("/api/review/create")
.then();
assertEquals(1, ReviewEntity.find("reviewerId", reviewerId).count());
@@ -3,6 +3,5 @@ package com.drinkool.dtos;
public class AddInventory {
public String name;
public int quantity;
public String unit;
}
@@ -13,7 +13,18 @@ public class ReviewModel extends BaseEntity {
@Column
public String comment;
public ReviewModel() {}
public ReviewModel(int rating, String comment) {
this.rating = rating;
this.comment = comment;
}
public ReviewModel(ReviewModel input) {
this(input.rating, input.comment);
}
@org.hibernate.annotations.CreationTimestamp
@Column(name = "review_date", updatable = false)
protected LocalDateTime reviewDate;
public LocalDateTime reviewDate;
}