chore: update
This commit is contained in:
+33
-14
@@ -15,18 +15,40 @@ permissions:
|
||||
checks: write
|
||||
|
||||
jobs:
|
||||
build-and-test:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install dependencies with Proxy
|
||||
env:
|
||||
http_proxy: "http://host.docker.internal:3142"
|
||||
https_proxy: "http://host.docker.internal:3142"
|
||||
- name: Install JDK and Maven
|
||||
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 maven
|
||||
|
||||
- name: Cache Maven packages
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.m2/repository
|
||||
**/target/native-image-cache
|
||||
**/target/reports
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-maven-
|
||||
|
||||
- name: Build native with Maven
|
||||
run: |
|
||||
mvn -B clean install -DskipTests -Pnative \
|
||||
-Dquarkus.container-image.push=false
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Install JDK and Maven
|
||||
run: |
|
||||
# Kiểm tra proxy có hoạt động không
|
||||
echo "Acquire::http::Proxy \"$http_proxy\";" > /etc/apt/apt.conf.d/80proxy
|
||||
@@ -46,16 +68,13 @@ jobs:
|
||||
**/target/native-image-cache
|
||||
**/target/reports
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
restore-keys: ${{ runner.os }}-maven-
|
||||
|
||||
- name: Build and Test all module
|
||||
- name: Run Tests
|
||||
env:
|
||||
TESTCONTAINERS_RYUK_DISABLED: true
|
||||
run: |
|
||||
mvn -B clean install -Pnative \
|
||||
-Dquarkus.container-image.push=false \
|
||||
-Dquarkus.container-image.registry=git.demonkernel.io.vn
|
||||
mvn clean test -Dquarkus.main.run-tests=true
|
||||
|
||||
- name: Publish Test Report
|
||||
uses: dorny/test-reporter@v3
|
||||
|
||||
@@ -43,6 +43,7 @@ public class StaffService extends BaseService<StaffEntity> {
|
||||
|
||||
return Response.status(Response.Status.CREATED)
|
||||
.header(InternalValue.userId, staff.id.toString())
|
||||
.header(InternalValue.managerId, manager.id.toString())
|
||||
.header(InternalValue.role, Role.Staff)
|
||||
.build();
|
||||
}
|
||||
@@ -64,6 +65,7 @@ public class StaffService extends BaseService<StaffEntity> {
|
||||
|
||||
return Response.accepted()
|
||||
.header(InternalValue.userId, staff.id.toString())
|
||||
.header(InternalValue.managerId, staff.serve.id.toString())
|
||||
.header(InternalValue.role, Role.Staff)
|
||||
.entity(staff)
|
||||
.build();
|
||||
|
||||
@@ -3,6 +3,9 @@ package com.drinkool.dtos;
|
||||
import java.time.LocalTime;
|
||||
import org.eclipse.microprofile.graphql.NonNull;
|
||||
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@NoArgsConstructor
|
||||
public class CreateShift {
|
||||
|
||||
@NonNull
|
||||
|
||||
@@ -27,6 +27,13 @@ public class EateryEntity extends BaseEntity {
|
||||
)
|
||||
public List<MenuItemEntity> menuItems = new ArrayList<>();
|
||||
|
||||
@OneToMany(
|
||||
mappedBy = "eatery",
|
||||
cascade = CascadeType.ALL,
|
||||
orphanRemoval = true
|
||||
)
|
||||
public List<ShiftEntity> shifts = new ArrayList<>();
|
||||
|
||||
public EateryEntity() {}
|
||||
|
||||
@Transactional
|
||||
|
||||
@@ -3,13 +3,21 @@ package com.drinkool.entities;
|
||||
import com.drinkool.lib.entities.BaseEntity;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.time.LocalTime;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table
|
||||
public class ShiftEntity extends BaseEntity {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "eatery_id")
|
||||
public EateryEntity eatery;
|
||||
|
||||
@Column(nullable = false)
|
||||
public String name;
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ import com.drinkool.InternalValue;
|
||||
import com.drinkool.Role;
|
||||
import com.drinkool.dtos.CreateShift;
|
||||
import com.drinkool.dtos.RegisterShift;
|
||||
import com.drinkool.entities.EateryEntity;
|
||||
import com.drinkool.entities.ShiftEntity;
|
||||
import com.drinkool.entities.ShiftRegistrationEntity;
|
||||
|
||||
import io.vertx.core.http.HttpServerRequest;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
@@ -58,9 +58,17 @@ public class ShiftService {
|
||||
@Name("registration") RegisterShift registration
|
||||
) throws GraphQLException {
|
||||
String userIdStr = request.getHeader(InternalValue.userId);
|
||||
String managerIdStr = request.getHeader(InternalValue.managerId);
|
||||
UUID staffId = UUID.fromString(userIdStr);
|
||||
|
||||
ShiftEntity shift = ShiftEntity.findById(registration.shiftId);
|
||||
EateryEntity eatery = EateryEntity.findByOwnerId(managerIdStr);
|
||||
if (eatery == null) throw new GraphQLException("NotFoundEatery");
|
||||
|
||||
ShiftEntity shift = ShiftEntity.find(
|
||||
"id = ?1 and eatery.id = ?2",
|
||||
registration.shiftId,
|
||||
eatery.id
|
||||
).firstResult();
|
||||
if (shift == null) throw new GraphQLException("NotFoundShift");
|
||||
|
||||
List<ShiftRegistrationEntity> overlappingShifts =
|
||||
@@ -94,8 +102,13 @@ public class ShiftService {
|
||||
@Transactional
|
||||
public ShiftEntity createShift(@Name("shiftInput") CreateShift input)
|
||||
throws GraphQLException {
|
||||
String ownerId = request.getHeader(InternalValue.userId);
|
||||
|
||||
EateryEntity eatery = EateryEntity.findByOwnerId(ownerId);
|
||||
if (eatery == null) return null;
|
||||
|
||||
ShiftEntity shift = new ShiftEntity();
|
||||
shift.eatery = eatery;
|
||||
shift.name = input.name;
|
||||
shift.startTime = input.startTime;
|
||||
shift.endTime = input.endTime;
|
||||
@@ -120,6 +133,11 @@ public class ShiftService {
|
||||
ShiftEntity shift = ShiftEntity.findById(id);
|
||||
if (shift == null) throw new GraphQLException("NotFoundShift");
|
||||
|
||||
String ownerId = request.getHeader(InternalValue.userId);
|
||||
if (
|
||||
!shift.eatery.ownerId.toString().equals(ownerId)
|
||||
) throw new GraphQLException("InvalidShiftId");
|
||||
|
||||
shift.name = input.name;
|
||||
shift.startTime = input.startTime;
|
||||
shift.endTime = input.endTime;
|
||||
@@ -137,6 +155,22 @@ public class ShiftService {
|
||||
@RolesAllowed(Role.Manager)
|
||||
@Transactional
|
||||
public boolean deleteShift(@Name("id") Long id) throws GraphQLException {
|
||||
String ownerId = request.getHeader(InternalValue.userId);
|
||||
|
||||
EateryEntity eatery = EateryEntity.findByOwnerId(ownerId);
|
||||
if (eatery == null) {
|
||||
throw new GraphQLException("NotFoundEatery");
|
||||
}
|
||||
|
||||
ShiftEntity shift = ShiftEntity.find(
|
||||
"id = ?1 and eatery = ?2",
|
||||
id,
|
||||
eatery
|
||||
).firstResult();
|
||||
if (shift == null) {
|
||||
throw new GraphQLException("NotFoundShiftOrAccessDenied");
|
||||
}
|
||||
|
||||
long count = ShiftRegistrationEntity.count("shift.id", id);
|
||||
if (count > 0) throw new GraphQLException(
|
||||
"CannotDeleteShiftWithRegistrations"
|
||||
|
||||
@@ -4,11 +4,15 @@ import static io.restassured.RestAssured.given;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
import com.drinkool.InternalValue;
|
||||
import com.drinkool.Role;
|
||||
import com.drinkool.entities.EateryEntity;
|
||||
import com.drinkool.entities.ShiftEntity;
|
||||
import com.drinkool.entities.ShiftRegistrationEntity;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import jakarta.transaction.Transactional;
|
||||
import java.time.LocalTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -44,16 +48,28 @@ public class ShiftServiceTest {
|
||||
|
||||
@Test
|
||||
void testCreateShift_AsManager() {
|
||||
String mutation =
|
||||
"mutation { createShift(shiftInput: { " +
|
||||
"name: \"Ca Chiều\", " +
|
||||
"startTime: \"13:00:00\", " +
|
||||
"endTime: \"17:00:00\", " +
|
||||
"maxStaff: 3 }) { id name } }";
|
||||
String query = """
|
||||
mutation Create($input: CreateShiftInput!)
|
||||
{ createShift(shiftInput: $input) { id name } }""";
|
||||
|
||||
Map<String, Object> input = new HashMap<>();
|
||||
input.put("name", "Ca Sáng");
|
||||
input.put("startTime", "08:00:00");
|
||||
input.put("endTime", "12:00:00");
|
||||
input.put("maxStaff", 5);
|
||||
|
||||
Map<String, Object> body = new HashMap<>();
|
||||
body.put("query", query);
|
||||
body.put("variables", Map.of("input", input));
|
||||
|
||||
UUID ownerId = createMockOwner();
|
||||
createMockEatery(ownerId);
|
||||
|
||||
given()
|
||||
.contentType("application/json")
|
||||
.body("{ \"query\": \"" + mutation + "\" }")
|
||||
.header(InternalValue.role, Role.Manager)
|
||||
.header(InternalValue.userId, ownerId)
|
||||
.body(body)
|
||||
.when()
|
||||
.post("/graphql")
|
||||
.then()
|
||||
@@ -136,7 +152,6 @@ public class ShiftServiceTest {
|
||||
@Transactional
|
||||
ShiftEntity createMockShift(String name, String start, String end) {
|
||||
ShiftEntity shift = new ShiftEntity();
|
||||
shift.id = UUID.randomUUID();
|
||||
shift.name = name;
|
||||
shift.startTime = LocalTime.parse(start);
|
||||
shift.endTime = LocalTime.parse(end);
|
||||
@@ -148,9 +163,24 @@ public class ShiftServiceTest {
|
||||
@Transactional
|
||||
void registerStaffToShift(UUID staffId, ShiftEntity shift) {
|
||||
ShiftRegistrationEntity reg = new ShiftRegistrationEntity();
|
||||
reg.id = UUID.randomUUID();
|
||||
reg.staffId = staffId;
|
||||
reg.shift = shift;
|
||||
reg.persist();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public UUID createMockOwner() {
|
||||
return UUID.randomUUID();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public EateryEntity createMockEatery(UUID ownerId) {
|
||||
EateryEntity eatery = new EateryEntity();
|
||||
eatery.name = "Nhà hàng " + ownerId.toString().substring(0, 5);
|
||||
eatery.ownerId = ownerId;
|
||||
eatery.persist();
|
||||
|
||||
EateryEntity.getEntityManager().flush();
|
||||
return eatery;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,4 +6,5 @@ public class InternalValue {
|
||||
public static final String headerId = "X-Internal-";
|
||||
public static final String userId = headerId + "UserId";
|
||||
public static final String role = headerId + "Role";
|
||||
public static final String managerId = headerId + "ManagerId";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user