Skip to content

Commit

Permalink
GETP-188 fix: 같은 프로젝트에 중복으로 지원이 가능한 오류 수정 (#122)
Browse files Browse the repository at this point in the history
  • Loading branch information
scv1702 authored Aug 14, 2024
1 parent 0804d48 commit 8210633
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 6 deletions.
6 changes: 6 additions & 0 deletions src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ include::{docdir}/project/unlike-project.adoc[]

include::{docdir}/project/commission-project.adoc[]

=== [피플] 프로젝트 지원

피플은 프로젝트에 지원할 수 있습니다.

include::{docdir}/project/apply-for-project.adoc[]

== 프로젝트 관리

=== [의뢰자] 의뢰한 프로젝트 목록 조회
Expand Down
1 change: 1 addition & 0 deletions src/docs/asciidoc/project/apply-for-project.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
operation::/apply-for-project/apply-for-project[snippets="http-request,request-headers,path-parameters,request-fields,http-response,response-fields-data"]
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import es.princip.getp.domain.people.command.domain.PeopleRepository;
import es.princip.getp.domain.people.exception.NotFoundPeopleException;
import es.princip.getp.domain.project.command.application.command.ApplyProjectCommand;
import es.princip.getp.domain.project.command.domain.*;
import es.princip.getp.domain.project.command.domain.Project;
import es.princip.getp.domain.project.command.domain.ProjectApplication;
import es.princip.getp.domain.project.command.domain.ProjectApplier;
import es.princip.getp.domain.project.command.domain.ProjectRepository;
import es.princip.getp.domain.project.exception.NotFoundProjectException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -17,7 +20,6 @@ public class ProjectApplicationService {

private final ProjectRepository projectRepository;
private final PeopleRepository peopleRepository;
private final ProjectApplicationRepository projectApplicationRepository;
private final ProjectApplier projectApplier;

/**
Expand All @@ -39,7 +41,6 @@ public Long applyForProject(final ApplyProjectCommand command) {
command.description(),
command.attachmentFiles()
);
projectApplicationRepository.save(application);
return application.getApplicationId();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import es.princip.getp.domain.common.domain.Duration;
import es.princip.getp.domain.people.command.domain.People;
import es.princip.getp.domain.people.exception.NotRegisteredPeopleProfileException;
import es.princip.getp.domain.project.exception.AlreadyAppliedProjectException;
import es.princip.getp.domain.project.exception.ClosedProjectApplicationException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
Expand All @@ -17,6 +18,7 @@
@RequiredArgsConstructor
public class ProjectApplier {

private final ProjectApplicationRepository projectApplicationRepository;
private final ClockHolder clockHolder;

/**
Expand All @@ -36,20 +38,27 @@ public ProjectApplication applyForProject(
final String description,
final List<AttachmentFile> attachmentFiles
) {
final Long peopleId = people.getPeopleId();
final Long projectId = project.getProjectId();
if (projectApplicationRepository.existsByApplicantIdAndProjectId(peopleId, projectId)) {
throw new AlreadyAppliedProjectException();
}
final Clock clock = clockHolder.getClock();
if (project.isApplicationClosed(clock)) {
throw new ClosedProjectApplicationException();
}
if (people.isProfileRegistered()) {
if (!people.isProfileRegistered()) {
throw new NotRegisteredPeopleProfileException();
}
return ProjectApplication.builder()
final ProjectApplication application = ProjectApplication.builder()
.applicantId(people.getPeopleId())
.projectId(project.getProjectId())
.expectedDuration(expectedDuration)
.description(description)
.attachmentFiles(attachmentFiles)
.applicationStatus(APPLICATION_COMPLETED)
.build();
projectApplicationRepository.save(application);
return application;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package es.princip.getp.domain.project.exception;

import es.princip.getp.infra.exception.BusinessLogicException;
import es.princip.getp.infra.exception.ErrorDescription;

public class AlreadyAppliedProjectException extends BusinessLogicException {

private static final String code = "ALREADY_APPLIED_PROJECT";
private static final String message = "이미 지원한 프로젝트입니다.";

public AlreadyAppliedProjectException() {
super(ErrorDescription.of(code, message));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import es.princip.getp.domain.member.command.domain.model.MemberType;
import es.princip.getp.domain.project.command.application.ProjectApplicationService;
import es.princip.getp.domain.project.command.application.command.ApplyProjectCommand;
import es.princip.getp.domain.project.command.presentation.description.ApplyProjectRequestDescription;
import es.princip.getp.domain.project.command.presentation.description.ApplyProjectResponseDescription;
import es.princip.getp.domain.project.command.presentation.dto.request.ApplyProjectRequest;
import es.princip.getp.infra.annotation.WithCustomMockUser;
import es.princip.getp.infra.support.AbstractControllerTest;
Expand All @@ -14,10 +16,17 @@
import org.springframework.boot.test.mock.mockito.MockBean;

import static es.princip.getp.domain.project.fixture.ApplyProjectRequestFixture.applyProjectRequest;
import static es.princip.getp.infra.util.HeaderDescriptorHelper.authorizationHeaderDescriptor;
import static es.princip.getp.infra.util.PayloadDocumentationHelper.responseFields;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest(ProjectApplicationController.class)
Expand Down Expand Up @@ -51,8 +60,18 @@ void applyForProject() throws Exception {
.willReturn(applicationId);

mockMvc.perform(post("/projects/{projectId}/applications", projectId)
.header("Authorization", "Bearer ${ACCESS_TOKEN}")
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isCreated());
.andExpect(status().isCreated())
.andDo(
restDocs.document(
requestHeaders(authorizationHeaderDescriptor()),
pathParameters(parameterWithName("projectId").description("프로젝트 ID")),
requestFields(ApplyProjectRequestDescription.description()),
responseFields(ApplyProjectResponseDescription.description())
)
)
.andDo(print());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package es.princip.getp.domain.project.command.presentation.description;

import es.princip.getp.domain.project.command.presentation.dto.request.ApplyProjectRequest;
import org.springframework.restdocs.payload.FieldDescriptor;

import static es.princip.getp.infra.util.FieldDescriptorHelper.getDescriptor;

public class ApplyProjectRequestDescription {

public static FieldDescriptor[] description() {
final Class<?> clazz = ApplyProjectRequest.class;
return new FieldDescriptor[] {
getDescriptor("expectedDuration.startDate", "예상 작업 시작 기간", clazz),
getDescriptor("expectedDuration.endDate", "예상 작업 종료 기간", clazz),
getDescriptor("description", "프로젝트 지원 설명", clazz),
getDescriptor("attachmentFiles", "첨부 파일", clazz)
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package es.princip.getp.domain.project.command.presentation.description;

import org.springframework.restdocs.payload.FieldDescriptor;

import static es.princip.getp.infra.util.FieldDescriptorHelper.getDescriptor;

public class ApplyProjectResponseDescription {

public static FieldDescriptor[] description() {
return new FieldDescriptor[] {
getDescriptor("applicationId", "프로젝트 지원 ID")
};
}
}

0 comments on commit 8210633

Please sign in to comment.