Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public class DepartmentEntity extends BaseTimeEntity {
@JoinColumn(name = "admin_id")
private MemberEntity admin;

@Column(nullable = false)
private String code;

@Column(nullable = false)
private String name;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@
public interface DepartmentPersistenceMapper extends PersistenceMapper<DepartmentEntity, Department> {

@Mapping(source = "admin.memberId", target = "adminId")
@Mapping(source = "name", target = "code")
Department toDomain(DepartmentEntity entity);

@Mapping(source = "code", target = "name")
@Mapping(source = "adminId", target = "admin.memberId")
DepartmentEntity toEntity(Department domain);
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public static ApprovalTaskResponse toApprovalTaskResponse(Task approvedTask) {
approvedTask.getProcessor().getNickname(),
approvedTask.getReviewer().getNickname(),
approvedTask.getDueDate(),
approvedTask.getLabel().getLabelName(),
approvedTask.getLabel() != null ? approvedTask.getLabel().getLabelName() : "",
approvedTask.getTaskStatus()
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ public ApprovalTaskResponse approvalTaskByReviewer(Long reviewerId, Long taskId,
Task task = taskService.findById(taskId);
Member processor = memberService.findById(approvalTaskRequest.processorId());
Category category = categoryService.findById(approvalTaskRequest.categoryId());
Label label = labelService.findById(approvalTaskRequest.labelId());
Label label = null;
if (approvalTaskRequest.labelId() != null) {
label = labelService.findById(approvalTaskRequest.labelId());
}

requestedTaskUpdatePolicy.validateTaskRequested(task);
task.approveTask(reviewer, processor, approvalTaskRequest.dueDate(), category, label);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import java.time.LocalDateTime;

@Getter
@SuperBuilder(toBuilder = true)
@SuperBuilder
@MappedSuperclass
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class BaseTime {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/clap/server/domain/model/member/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import lombok.experimental.SuperBuilder;

@Getter
@SuperBuilder(toBuilder = true)
@SuperBuilder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class Member extends BaseTime {
Expand Down
107 changes: 107 additions & 0 deletions src/test/java/clap/server/TestDataFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package clap.server;

import clap.server.adapter.inbound.web.dto.task.request.FilterTaskListRequest;
import clap.server.adapter.outbound.persistense.entity.member.constant.MemberRole;
import clap.server.adapter.outbound.persistense.entity.member.constant.MemberStatus;
import clap.server.adapter.outbound.persistense.entity.task.constant.LabelColor;
import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus;
import clap.server.domain.model.member.Member;
import clap.server.domain.model.member.MemberInfo;
import clap.server.domain.model.task.Category;
import clap.server.domain.model.task.Label;
import clap.server.domain.model.task.Task;
import org.springframework.data.domain.PageImpl;

import java.time.LocalDateTime;
import java.util.List;

public class TestDataFactory {

public static Member createAdmin() {
return new Member(1L, createAdminInfo(), null,
true, true, true,
null, MemberStatus.ACTIVE, "1111");
}
public static Member createManagerWithReviewer() {
return new Member(2L, createManagerWithReviewerInfo(), createAdmin(),
true, true, true,
null, MemberStatus.ACTIVE, "1111");
}
public static Member createManager() {
return new Member(3L, createManagerInfo(), createAdmin(),
true, true, true,
null, MemberStatus.ACTIVE, "1111");
}
public static Member createUser() {
return new Member(4L, createUserInfo(), createAdmin(),
true, true, true,
null, MemberStatus.ACTIVE, "1111");
}

public static MemberInfo createAdminInfo(){
return new MemberInfo("홍길동(관리자)", "atom8426@naver.com", "atom.admin", false, null, MemberRole.ROLE_ADMIN, "인프라");
}
public static MemberInfo createManagerWithReviewerInfo(){
return new MemberInfo("홍길동(리뷰어)", "atom8426@naver.com", "atom.manager", true, null, MemberRole.ROLE_MANAGER, "인프라");
}
public static MemberInfo createManagerInfo(){
return new MemberInfo("홍길동(매니저)", "atom8426@naver.com", "atom.manager", false, null, MemberRole.ROLE_MANAGER, "인프라");
}
public static MemberInfo createUserInfo(){
return new MemberInfo("홍길동(사용자)", "atom8426@naver.com", "atom.user", false, null, MemberRole.ROLE_USER, "인프라");
}

public static Category createMainCategory() {
return Category.builder()
.categoryId(1L)
.name("1차 카테고리")
.code("VM")
.isDeleted(false)
.descriptionExample("메인 카테고리 입니다.")
.createdAt(LocalDateTime.now())
.updatedAt(LocalDateTime.now())
.build();
}

public static Category createCategory(Category mainCategory) {
return Category.builder()
.categoryId(2L)
.name("2차 카테고리")
.code("CR")
.isDeleted(false)
.descriptionExample("서브 카테고리 입니다.")
.mainCategory(mainCategory)
.createdAt(LocalDateTime.now())
.updatedAt(LocalDateTime.now())
.build();
}

public static Task createTask(Long id, String taskCode, String title, TaskStatus taskStatus, Category category, LocalDateTime finishedAt, Member processor) {
return Task.builder()
.taskId(id)
.taskCode(taskCode)
.title(title)
.description(null)
.category(category)
.taskStatus(taskStatus)
.finishedAt(finishedAt)
.processor(processor)
.label(createLabel())
.build();
}

public static Label createLabel() {
return Label.builder()
.labelId(1L)
.admin(null)
.labelName("레이블")
.labelColor(LabelColor.BLUE)
.isDeleted(false)
.build();
}


public static PageImpl<Task> createTaskPage(List<Task> tasks) {
return new PageImpl<>(tasks);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package clap.server.application.service.task;

import clap.server.adapter.inbound.web.dto.task.request.ApprovalTaskRequest;
import clap.server.adapter.inbound.web.dto.task.response.ApprovalTaskResponse;
import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus;
import clap.server.TestDataFactory;
import clap.server.application.port.inbound.domain.CategoryService;
import clap.server.application.port.inbound.domain.LabelService;
import clap.server.application.port.inbound.domain.MemberService;
import clap.server.application.port.inbound.domain.TaskService;
import clap.server.application.port.outbound.taskhistory.CommandTaskHistoryPort;
import clap.server.application.service.webhook.SendNotificationService;
import clap.server.domain.model.member.Member;
import clap.server.domain.model.task.Category;
import clap.server.domain.model.task.Label;
import clap.server.domain.model.task.Task;
import clap.server.domain.model.task.TaskHistory;
import clap.server.domain.policy.task.RequestedTaskUpdatePolicy;
import clap.server.exception.DomainException;
import clap.server.exception.code.TaskErrorCode;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.*;


@ExtendWith(MockitoExtension.class)
class ApprovalTaskServiceTest {

@InjectMocks
private ApprovalTaskService approvalTaskService;

@Mock
private MemberService memberService;

@Mock
private TaskService taskService;

@Mock
private CategoryService categoryService;

@Mock
private LabelService labelService;
@Mock
private RequestedTaskUpdatePolicy requestedTaskUpdatePolicy;

@Mock
private CommandTaskHistoryPort commandTaskHistoryPort;

@Mock
private SendNotificationService sendNotificationService;


private Member reviewer, processor;
private Task task;
private Category category, mainCategory;

@BeforeEach
void setUp() {
reviewer = TestDataFactory.createManagerWithReviewer();
processor = TestDataFactory.createManager();
mainCategory = TestDataFactory.createMainCategory();
category = TestDataFactory.createCategory(mainCategory);
task = TestDataFactory.createTask(1L, "TC001", "제목1", TaskStatus.REQUESTED, category, null, processor);
}

@Test
@DisplayName("작업 승인 처리")
void approvalTask() {
//given
Long reviewerId = 2L;
Long taskId = 1L;
ApprovalTaskRequest approvalTaskRequest = new ApprovalTaskRequest(2L, 2L, null, null);

when(memberService.findReviewer(reviewerId)).thenReturn(reviewer);
when(taskService.findById(taskId)).thenReturn(task);
when(memberService.findById(approvalTaskRequest.processorId())).thenReturn(processor);
when(categoryService.findById(approvalTaskRequest.categoryId())).thenReturn(category);
when(taskService.upsert(task)).thenReturn(task);

//when
ApprovalTaskResponse response = approvalTaskService.approvalTaskByReviewer(reviewerId, taskId, approvalTaskRequest);

//then
assertThat(response).isNotNull();
assertThat(response.taskId()).isEqualTo(task.getTaskId());
assertThat(response.taskStatus()).isEqualTo(TaskStatus.IN_PROGRESS);
verify(requestedTaskUpdatePolicy).validateTaskRequested(task);
}

@Test
@DisplayName("작업 승인 처리 중 예외 - 상태 불일치")
void approvalTask_throwsDomainException_whenTaskStatusIsNotRequested() {
//given
Long reviewerId = 2L;
Long taskId = 1L;
ApprovalTaskRequest approvalTaskRequest = new ApprovalTaskRequest(2L, 2L, null, null);
task = TestDataFactory.createTask(1L, "TC001", "제목1", TaskStatus.COMPLETED, category, null, processor);
when(taskService.findById(taskId)).thenReturn(task);

//when
doThrow(new DomainException(TaskErrorCode.TASK_STATUS_MISMATCH))
.when(requestedTaskUpdatePolicy).validateTaskRequested(task);
//then
assertThatThrownBy(() -> approvalTaskService.approvalTaskByReviewer(reviewerId, taskId, approvalTaskRequest))
.isInstanceOf(DomainException.class)
.hasMessage(TaskErrorCode.TASK_STATUS_MISMATCH.getMessage());
}
}
Loading