diff --git a/src/main/java/com/factoreal/backend/controller/SensorController.java b/src/main/java/com/factoreal/backend/controller/SensorController.java index 30cf0088..30594731 100644 --- a/src/main/java/com/factoreal/backend/controller/SensorController.java +++ b/src/main/java/com/factoreal/backend/controller/SensorController.java @@ -51,6 +51,6 @@ public ResponseEntity update( @PathVariable("sensorId") String sensorId, @RequestBody SensorUpdateDto dto) { service.updateSensor(sensorId, dto); - return ResponseEntity.noContent().build(); + return ResponseEntity.noContent().build(); // 204 응답 반환 } } \ No newline at end of file diff --git a/src/main/java/com/factoreal/backend/controller/WorkerController.java b/src/main/java/com/factoreal/backend/controller/WorkerController.java index e4efd46f..656ba840 100644 --- a/src/main/java/com/factoreal/backend/controller/WorkerController.java +++ b/src/main/java/com/factoreal/backend/controller/WorkerController.java @@ -1,5 +1,6 @@ package com.factoreal.backend.controller; +import com.factoreal.backend.dto.CreateWorkerRequest; import com.factoreal.backend.dto.WorkerDto; import com.factoreal.backend.dto.ZoneManagerResponseDto; import com.factoreal.backend.service.WorkerService; @@ -17,10 +18,18 @@ @RequestMapping("/api/workers") @RequiredArgsConstructor @Slf4j -@Tag(name = "작업자 API", description = "작업자 조회 API") +@Tag(name = "작업자 API", description = "작업자 조회 및 생성 API") public class WorkerController { private final WorkerService workerService; + @Operation(summary = "작업자 생성", description = "새로운 작업자를 생성하고 접근 가능한 공간들을 선택합니다.") + @PostMapping + public ResponseEntity createWorker(@RequestBody CreateWorkerRequest request) { + log.info("작업자 생성 요청: {}", request); + workerService.createWorker(request); + return ResponseEntity.ok().build(); // 작업자 생성 성공 시 200 응답 + } + @Operation(summary = "전체 작업자 목록 조회", description = "전체 작업자 목록을 조회합니다.") @GetMapping public ResponseEntity> getAllWorkers() { diff --git a/src/main/java/com/factoreal/backend/controller/WorkerManagerController.java b/src/main/java/com/factoreal/backend/controller/WorkerManagerController.java new file mode 100644 index 00000000..80a3206a --- /dev/null +++ b/src/main/java/com/factoreal/backend/controller/WorkerManagerController.java @@ -0,0 +1,55 @@ +package com.factoreal.backend.controller; + +import com.factoreal.backend.dto.WorkerManagerResponse; +import com.factoreal.backend.service.WorkerManagerService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@Tag(name = "공간 담당자 API", description = "공간별 담당자 관리 API") +@Slf4j +@RestController +@RequestMapping("/api/zone-managers") +@RequiredArgsConstructor +public class WorkerManagerController { + + private final WorkerManagerService workerManagerService; + + @Operation(summary = "공간 담당자 후보 목록 조회", description = "특정 공간의 담당자로 지정 가능한 작업자 목록을 조회합니다.") + @GetMapping("/candidates/{zoneId}") + public ResponseEntity> getManagerCandidates( + @Parameter(description = "공간 ID", required = true) + @PathVariable String zoneId) { + log.info("공간 ID: {}의 담당자 후보 목록 조회 요청", zoneId); + return ResponseEntity.ok(workerManagerService.getManagerCandidates(zoneId)); + } + + @Operation(summary = "공간 담당자 지정", description = "특정 공간의 담당자를 지정합니다.") + @PostMapping("/{zoneId}/assign/{workerId}") + public ResponseEntity assignManager( + @Parameter(description = "공간 ID", required = true) + @PathVariable String zoneId, + @Parameter(description = "작업자 ID", required = true) + @PathVariable String workerId) { + log.info("공간 ID: {}의 담당자를 작업자 ID: {}로 지정 요청", zoneId, workerId); + workerManagerService.assignManager(zoneId, workerId); + return ResponseEntity.ok().build(); + } + + @Operation(summary = "현재 공간 담당자 조회", description = "특정 공간의 현재 담당자 정보를 조회합니다.") + @GetMapping("/{zoneId}") + public ResponseEntity getCurrentManager( + @Parameter(description = "공간 ID", required = true) + @PathVariable String zoneId) { + log.info("공간 ID: {}의 현재 담당자 조회 요청", zoneId); + WorkerManagerResponse manager = workerManagerService.getCurrentManager(zoneId); + return manager != null ? ResponseEntity.ok(manager) : ResponseEntity.noContent().build(); + // 담당자가 있으면 담당자 정보 반환, 없으면 빈 응답 + } +} \ No newline at end of file diff --git a/src/main/java/com/factoreal/backend/dto/CreateWorkerRequest.java b/src/main/java/com/factoreal/backend/dto/CreateWorkerRequest.java new file mode 100644 index 00000000..879b592a --- /dev/null +++ b/src/main/java/com/factoreal/backend/dto/CreateWorkerRequest.java @@ -0,0 +1,21 @@ +package com.factoreal.backend.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +// 작업자 생성 요청 DTO (FE -> BE) +public class CreateWorkerRequest { + private String workerId; // 작업자 ID (사원 번호) + private String name; // 작업자 이름 + private String phoneNumber; // 연락처 + private String email; // 이메일 + private List zoneNames; // 출입 가능한 공간명 리스트 +} \ No newline at end of file diff --git a/src/main/java/com/factoreal/backend/dto/WorkerLocationRequest.java b/src/main/java/com/factoreal/backend/dto/WorkerLocationRequest.java index 7530a47e..0f3a394d 100644 --- a/src/main/java/com/factoreal/backend/dto/WorkerLocationRequest.java +++ b/src/main/java/com/factoreal/backend/dto/WorkerLocationRequest.java @@ -9,7 +9,7 @@ @Getter @Setter @ToString -// Wearable 장치에서 받아오는 데이터 by 우영. 추후 논의 예정 +// Wearable 장치에서 받아오는 데이터 by 우영 public class WorkerLocationRequest { private String workerId; private String zoneId; diff --git a/src/main/java/com/factoreal/backend/dto/WorkerManagerResponse.java b/src/main/java/com/factoreal/backend/dto/WorkerManagerResponse.java new file mode 100644 index 00000000..0abd11f6 --- /dev/null +++ b/src/main/java/com/factoreal/backend/dto/WorkerManagerResponse.java @@ -0,0 +1,26 @@ +package com.factoreal.backend.dto; + +import com.factoreal.backend.entity.Worker; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +// 공간 담당자 후보 목록 응답 DTO (BE -> FE) +public class WorkerManagerResponse { + private String workerId; // 직원 아이디 + private String name; // 직원 이름 + private Boolean isManager; // 공간담당자 여부 + + public static WorkerManagerResponse fromEntity(Worker worker, Boolean isManager) { + return WorkerManagerResponse.builder() + .workerId(worker.getWorkerId()) + .name(worker.getName()) + .isManager(isManager) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/factoreal/backend/repository/WorkerZoneRepository.java b/src/main/java/com/factoreal/backend/repository/WorkerZoneRepository.java index ab3dd503..bcc1255c 100644 --- a/src/main/java/com/factoreal/backend/repository/WorkerZoneRepository.java +++ b/src/main/java/com/factoreal/backend/repository/WorkerZoneRepository.java @@ -14,4 +14,10 @@ public interface WorkerZoneRepository extends JpaRepository findByZoneZoneIdAndManageYnIsTrue(String zoneId); + + // 특정 공간을 제외한 다른 공간의 담당자 목록 조회 + List findByZoneZoneIdNotAndManageYnIsTrue(String zoneId); + + // 특정 작업자가 담당자로 있는 공간 조회 + Optional findByWorkerWorkerIdAndManageYnIsTrue(String workerId); } \ No newline at end of file diff --git a/src/main/java/com/factoreal/backend/service/WorkerManagerService.java b/src/main/java/com/factoreal/backend/service/WorkerManagerService.java new file mode 100644 index 00000000..df6a864b --- /dev/null +++ b/src/main/java/com/factoreal/backend/service/WorkerManagerService.java @@ -0,0 +1,106 @@ +package com.factoreal.backend.service; + +import com.factoreal.backend.dto.WorkerManagerResponse; +import com.factoreal.backend.entity.Worker; +import com.factoreal.backend.entity.WorkerZone; +import com.factoreal.backend.entity.WorkerZoneId; +import com.factoreal.backend.entity.Zone; +import com.factoreal.backend.repository.WorkerRepository; +import com.factoreal.backend.repository.WorkerZoneRepository; +import com.factoreal.backend.repository.ZoneRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +@Slf4j +@Service +@RequiredArgsConstructor +// 공간 담당자 지정 서비스 +public class WorkerManagerService { + + private final WorkerRepository workerRepository; + private final WorkerZoneRepository workerZoneRepository; + private final ZoneRepository zoneRepository; + + /** + * 특정 공간의 담당자 후보 목록 조회 + * - 이미 담당자가 있는 경우: 현재 담당자를 제외한 해당 공간 접근 권한이 있는 작업자 목록 + * - 담당자가 없는 경우: 해당 공간 접근 권한이 있는 작업자 목록 + * - 다른 공간의 담당자인 작업자는 후보 목록에서 제외 + */ + @Transactional(readOnly = true) + public List getManagerCandidates(String zoneId) { + log.info("공간 ID: {}의 담당자 후보 목록 조회", zoneId); + + // 1. 현재 해당 공간의 담당자 조회 + Optional currentManager = workerZoneRepository.findByZoneZoneIdAndManageYnIsTrue(zoneId); + + // 2. 현재 공간을 제외한 다른 공간의 담당자 목록 조회 (workerId를 Set으로 묶어서 중복 제거) + Set otherManagerIds = workerZoneRepository.findByZoneZoneIdNotAndManageYnIsTrue(zoneId).stream() + .map(wz -> wz.getWorker().getWorkerId()) + .collect(Collectors.toSet()); + + // 3. 해당 공간에 접근 권한이 있는 작업자 목록 조회 + List zoneWorkers = workerZoneRepository.findByZoneZoneId(zoneId); + + // 4. 현재 담당자와 다른 공간의 담당자를 제외한 후보 목록 생성 + List candidates = currentManager + .map(manager -> zoneWorkers.stream() + .filter(wz -> !wz.getWorker().getWorkerId().equals(manager.getWorker().getWorkerId())) // 현재 담당자를 제외 + .filter(wz -> !otherManagerIds.contains(wz.getWorker().getWorkerId())) // 다른 공간의 담당자인 작업자는 후보 목록에서 제외 + .map(WorkerZone::getWorker) // 후보 목록에 포함된 작업자 객체 생성 + .collect(Collectors.toList())) + .orElse(zoneWorkers.stream() // 담당자가 없는 경우, 해당 공간 접근 권한이 있는 작업자 목록 + .filter(wz -> !otherManagerIds.contains(wz.getWorker().getWorkerId())) // 다른 공간의 담당자인 작업자는 후보 목록에서 제외 + .map(WorkerZone::getWorker) // 후보 목록에 포함된 작업자 객체 생성 + .collect(Collectors.toList())); + + // 4. DTO 변환 (후보 목록의 작업자들은 현재 이 공간의 담당자가 아니므로 isManager = false) + return candidates.stream() + .map(worker -> WorkerManagerResponse.fromEntity(worker, false)) + .collect(Collectors.toList()); + } + + /** + * 특정 공간의 담당자 지정 + */ + @Transactional + public void assignManager(String zoneId, String workerId) { + log.info("공간 ID: {}의 담당자를 작업자 ID: {}로 지정", zoneId, workerId); + + // 1. 작업자-공간 관계 확인 + WorkerZoneId workerZoneId = new WorkerZoneId(workerId, zoneId); + WorkerZone workerZone = workerZoneRepository.findById(workerZoneId) + .orElseThrow(() -> new IllegalArgumentException( + String.format("작업자 ID: %s는 공간 ID: %s에 대한 접근 권한이 없습니다.", workerId, zoneId))); + + // 2. 기존 담당자가 있다면 담당자 해제 + Optional currentManager = workerZoneRepository.findByZoneZoneIdAndManageYnIsTrue(zoneId); + currentManager.ifPresent(manager -> { + manager.setManageYn(false); + workerZoneRepository.save(manager); + }); + + // 3. 새로운 담당자 지정 + workerZone.setManageYn(true); + workerZoneRepository.save(workerZone); + } + + /** + * 특정 공간의 현재 담당자 조회 + */ + @Transactional(readOnly = true) + public WorkerManagerResponse getCurrentManager(String zoneId) { + log.info("공간 ID: {}의 현재 담당자 조회", zoneId); + + return workerZoneRepository.findByZoneZoneIdAndManageYnIsTrue(zoneId) + .map(workerZone -> WorkerManagerResponse.fromEntity(workerZone.getWorker(), true)) + .orElse(null); + } +} \ No newline at end of file diff --git a/src/main/java/com/factoreal/backend/service/WorkerService.java b/src/main/java/com/factoreal/backend/service/WorkerService.java index 27b49682..7f77b38d 100644 --- a/src/main/java/com/factoreal/backend/service/WorkerService.java +++ b/src/main/java/com/factoreal/backend/service/WorkerService.java @@ -1,13 +1,16 @@ package com.factoreal.backend.service; +import com.factoreal.backend.dto.CreateWorkerRequest; import com.factoreal.backend.dto.WorkerDto; import com.factoreal.backend.dto.ZoneManagerResponseDto; import com.factoreal.backend.entity.Worker; import com.factoreal.backend.entity.WorkerZone; +import com.factoreal.backend.entity.WorkerZoneId; import com.factoreal.backend.entity.Zone; import com.factoreal.backend.entity.ZoneHist; import com.factoreal.backend.repository.WorkerRepository; import com.factoreal.backend.repository.WorkerZoneRepository; +import com.factoreal.backend.repository.ZoneRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -23,13 +26,18 @@ public class WorkerService { private final WorkerRepository workerRepository; private final WorkerLocationService workerLocationService; private final WorkerZoneRepository workerZoneRepository; + private final ZoneRepository zoneRepository; @Transactional(readOnly = true) public List getAllWorkers() { log.info("전체 작업자 목록 조회"); List workers = workerRepository.findAll(); return workers.stream() - .map(worker -> WorkerDto.fromEntity(worker, false)) + .map(worker -> { + // 해당 작업자가 어떤 공간의 담당자인지 확인 + boolean isManager = workerZoneRepository.findByWorkerWorkerIdAndManageYnIsTrue(worker.getWorkerId()).isPresent(); + return WorkerDto.fromEntity(worker, isManager); + }) .collect(Collectors.toList()); } @@ -71,19 +79,40 @@ public ZoneManagerResponseDto getZoneManagerWithLocation(String zoneId) { // 4. DTO 변환 및 반환 return ZoneManagerResponseDto.fromEntity(manager, currentZone); } -} -// TODO. 수정되어야 할 로직. 현재는 WorkerZone 테이블에서 공간id로 필터링 되는 모든 작업자를 끌고왔는데, -// 사실 현재 그 공간에서 실제로 작업하고 있는, 즉 들어 -// public List getWorkersByZoneId(String zoneId) { -// log.info("공간 ID: {}의 작업자 목록 조회", zoneId); -// List workerZones = workerZoneRepository.findByZoneZoneId(zoneId); - -// return workerZones.stream() -// .map(workerZone -> { -// Worker worker = workerZone.getWorker(); -// Boolean isManager = workerZone.getManageYn(); -// return WorkerDto.fromEntity(worker, isManager); -// }) -// .collect(Collectors.toList()); -// } \ No newline at end of file + /** + * 작업자 생성 및 출입 가능 공간 설정 + */ + @Transactional + public void createWorker(CreateWorkerRequest request) { + log.info("작업자 생성 요청: {}", request); + + // 1. 작업자 정보 저장 + Worker worker = Worker.builder() + .workerId(request.getWorkerId()) + .name(request.getName()) + .phoneNumber(request.getPhoneNumber()) + .email(request.getEmail()) + .build(); + + workerRepository.save(worker); // 작업자 정보 저장 + + // 2. 각 공간명으로 Zone 조회 및 WorkerZone 생성 + for (String zoneName : request.getZoneNames()) { + Zone zone = zoneRepository.findByZoneName(zoneName) + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 공간명입니다: " + zoneName)); + + // WorkerZone 생성 (기본적으로 관리자 권한은 없음) + WorkerZone workerZone = WorkerZone.builder() + .id(new WorkerZoneId(worker.getWorkerId(), zone.getZoneId())) // 복합키 생성 + .worker(worker) + .zone(zone) + .manageYn(false) // 담당자 권한은 없음이 default + .build(); + + workerZoneRepository.save(workerZone); // WorkerZone 저장 + } + + log.info("작업자 생성 완료 - workerId: {}", worker.getWorkerId()); + } +} \ No newline at end of file diff --git a/src/test/java/com/factoreal/backend/service/WorkerManagerServiceTest.java b/src/test/java/com/factoreal/backend/service/WorkerManagerServiceTest.java new file mode 100644 index 00000000..43ccfc6c --- /dev/null +++ b/src/test/java/com/factoreal/backend/service/WorkerManagerServiceTest.java @@ -0,0 +1,213 @@ +package com.factoreal.backend.service; + +import com.factoreal.backend.dto.WorkerManagerResponse; +import com.factoreal.backend.entity.Worker; +import com.factoreal.backend.entity.WorkerZone; +import com.factoreal.backend.entity.WorkerZoneId; +import com.factoreal.backend.entity.Zone; +import com.factoreal.backend.repository.WorkerZoneRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +class WorkerManagerServiceTest { + + @Mock + private WorkerZoneRepository workerZoneRepository; + + @InjectMocks + private WorkerManagerService workerManagerService; + + private Worker worker1, worker2, worker3, worker4; + private Zone zone1, zone2; + private WorkerZone workerZone1, workerZone2, workerZone3, workerZone4, workerZone5; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + + // 테스트용 Zone 데이터 생성 + zone1 = Zone.builder() + .zoneId("zone1") + .zoneName("공간1") + .build(); + + zone2 = Zone.builder() + .zoneId("zone2") + .zoneName("공간2") + .build(); + + // 테스트용 Worker 데이터 생성 + worker1 = Worker.builder() + .workerId("worker1") + .name("작업자1") + .phoneNumber("010-1111-1111") + .email("worker1@test.com") + .build(); + + worker2 = Worker.builder() + .workerId("worker2") + .name("작업자2") + .phoneNumber("010-2222-2222") + .email("worker2@test.com") + .build(); + + worker3 = Worker.builder() + .workerId("worker3") + .name("작업자3") + .phoneNumber("010-3333-3333") + .email("worker3@test.com") + .build(); + + worker4 = Worker.builder() + .workerId("worker4") + .name("작업자4") + .phoneNumber("010-4444-4444") + .email("worker4@test.com") + .build(); + + // 테스트용 WorkerZone 데이터 생성 + workerZone1 = WorkerZone.builder() + .id(new WorkerZoneId("worker1", "zone1")) + .worker(worker1) + .zone(zone1) + .manageYn(true) // worker1은 zone1의 담당자 + .build(); + + workerZone2 = WorkerZone.builder() + .id(new WorkerZoneId("worker2", "zone1")) + .worker(worker2) + .zone(zone1) + .manageYn(false) // worker2는 zone1에 접근 가능 + .build(); + + workerZone3 = WorkerZone.builder() + .id(new WorkerZoneId("worker2", "zone2")) + .worker(worker2) + .zone(zone2) + .manageYn(true) // worker2는 zone2의 담당자 + .build(); + + workerZone4 = WorkerZone.builder() + .id(new WorkerZoneId("worker3", "zone1")) + .worker(worker3) + .zone(zone1) + .manageYn(false) // worker3는 zone1에 접근 가능 + .build(); + + workerZone5 = WorkerZone.builder() + .id(new WorkerZoneId("worker4", "zone1")) + .worker(worker4) + .zone(zone1) + .manageYn(false) // worker4는 zone1에 접근 가능 + .build(); + } + + // 특정 공간의 담당자 후보 목록 조회 + @Test + void getManagerCandidates_WhenZoneHasManager() { + // given + String zoneId = "zone1"; + + // 현재 담당자 설정 + when(workerZoneRepository.findByZoneZoneIdAndManageYnIsTrue(zoneId)) + .thenReturn(Optional.of(workerZone1)); + + // 다른 공간의 담당자 설정 + when(workerZoneRepository.findByZoneZoneIdNotAndManageYnIsTrue(zoneId)) + .thenReturn(Arrays.asList(workerZone3)); // worker2는 zone2의 담당자 + + // 해당 공간의 모든 작업자 설정 + when(workerZoneRepository.findByZoneZoneId(zoneId)) + .thenReturn(Arrays.asList(workerZone1, workerZone2, workerZone4, workerZone5)); + + // when + List candidates = workerManagerService.getManagerCandidates(zoneId); + + // then + assertNotNull(candidates); + assertEquals(2, candidates.size()); // worker3, worker4만 후보가 되어야 함 (현재 담당자와 다른 공간 담당자 제외) + + // worker2(다른 공간 담당자)가 후보 목록에 없는지 확인 + assertTrue(candidates.stream() + .noneMatch(c -> c.getWorkerId().equals("worker2"))); + + // worker1(현재 담당자)가 후보 목록에 없는지 확인 + assertTrue(candidates.stream() + .noneMatch(c -> c.getWorkerId().equals("worker1"))); + } + + // 공간 담당자 지정 + @Test + void assignManager_Success() { + // given + String zoneId = "zone1"; + String newManagerId = "worker3"; + + // 현재 담당자 설정 + when(workerZoneRepository.findByZoneZoneIdAndManageYnIsTrue(zoneId)) + .thenReturn(Optional.of(workerZone1)); + + // 새로운 담당자의 WorkerZone 설정 + WorkerZoneId newManagerZoneId = new WorkerZoneId(newManagerId, zoneId); + when(workerZoneRepository.findById(newManagerZoneId)) + .thenReturn(Optional.of(workerZone4)); + + // when + workerManagerService.assignManager(zoneId, newManagerId); + + // then + // 기존 담당자의 manageYn이 false로 변경되었는지 확인 + verify(workerZoneRepository, times(1)).save(argThat(wz -> + wz.getWorker().getWorkerId().equals("worker1") && !wz.getManageYn() + )); + + // 새로운 담당자의 manageYn이 true로 변경되었는지 확인 + verify(workerZoneRepository, times(1)).save(argThat(wz -> + wz.getWorker().getWorkerId().equals(newManagerId) && wz.getManageYn() + )); + } + + // 현재 공간 담당자 조회 (담당자가 있는 경우) + @Test + void getCurrentManager_WhenManagerExists() { + // given + String zoneId = "zone1"; + when(workerZoneRepository.findByZoneZoneIdAndManageYnIsTrue(zoneId)) + .thenReturn(Optional.of(workerZone1)); + + // when + WorkerManagerResponse manager = workerManagerService.getCurrentManager(zoneId); + + // then + assertNotNull(manager); + assertEquals("worker1", manager.getWorkerId()); + assertEquals("작업자1", manager.getName()); + assertTrue(manager.getIsManager()); + } + + // 현재 공간 담당자 조회 (담당자가 없는 경우) + @Test + void getCurrentManager_WhenNoManagerExists() { + // given + String zoneId = "zone1"; + when(workerZoneRepository.findByZoneZoneIdAndManageYnIsTrue(zoneId)) + .thenReturn(Optional.empty()); + + // when + WorkerManagerResponse manager = workerManagerService.getCurrentManager(zoneId); + + // then + assertNull(manager); + } +} \ No newline at end of file diff --git a/src/test/java/com/factoreal/backend/service/WorkerServiceTest.java b/src/test/java/com/factoreal/backend/service/WorkerServiceTest.java index 5e527e98..a078a990 100644 --- a/src/test/java/com/factoreal/backend/service/WorkerServiceTest.java +++ b/src/test/java/com/factoreal/backend/service/WorkerServiceTest.java @@ -5,6 +5,7 @@ import com.factoreal.backend.entity.Zone; import com.factoreal.backend.entity.ZoneHist; import com.factoreal.backend.repository.WorkerRepository; +import com.factoreal.backend.repository.WorkerZoneRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -14,10 +15,12 @@ import java.time.LocalDateTime; import java.util.Arrays; import java.util.List; +import java.util.Optional; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.anyString; public class WorkerServiceTest { @@ -27,6 +30,9 @@ public class WorkerServiceTest { @Mock private WorkerLocationService workerLocationService; + @Mock + private WorkerZoneRepository workerZoneRepository; + @InjectMocks private WorkerService workerService; @@ -76,6 +82,10 @@ public void testGetAllWorkers() { // Mock 설정 when(workerRepository.findAll()).thenReturn(Arrays.asList(worker1, worker2)); + // WorkerZoneRepository mock 설정 추가 + when(workerZoneRepository.findByWorkerWorkerIdAndManageYnIsTrue(anyString())) + .thenReturn(Optional.empty()); // 모든 작업자가 관리자가 아닌 것으로 설정 + // 서비스 메소드 호출 List result = workerService.getAllWorkers();