diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/api/UserFormApi.java b/src/main/java/ddingdong/ddingdongBE/domain/form/api/UserFormApi.java new file mode 100644 index 00000000..2f5c9e96 --- /dev/null +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/api/UserFormApi.java @@ -0,0 +1,27 @@ +package ddingdong.ddingdongBE.domain.form.api; + +import ddingdong.ddingdongBE.domain.form.controller.dto.response.FormSectionResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; + +@Tag(name = "Form - User", description = "User Form API") +@RequestMapping("/server") +public interface UserFormApi { + + @Operation(summary = "폼지 섹션 조회 API") + @ApiResponse(responseCode = "200", description = "폼지 섹션 조회 성공", + content = @Content(schema = @Schema(implementation = FormSectionResponse.class))) + @ResponseStatus(HttpStatus.OK) + @GetMapping("/forms/{formId}/sections") + FormSectionResponse getFormSections( + @PathVariable("formId") Long formId + ); +} diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/controller/UserFormController.java b/src/main/java/ddingdong/ddingdongBE/domain/form/controller/UserFormController.java new file mode 100644 index 00000000..ac461b8b --- /dev/null +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/controller/UserFormController.java @@ -0,0 +1,21 @@ +package ddingdong.ddingdongBE.domain.form.controller; + +import ddingdong.ddingdongBE.domain.form.api.UserFormApi; +import ddingdong.ddingdongBE.domain.form.controller.dto.response.FormSectionResponse; +import ddingdong.ddingdongBE.domain.form.service.FacadeUserFormService; +import ddingdong.ddingdongBE.domain.form.service.dto.query.FormSectionQuery; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +public class UserFormController implements UserFormApi { + + private final FacadeUserFormService facadeUserFormService; + + @Override + public FormSectionResponse getFormSections(Long formId) { + FormSectionQuery query = facadeUserFormService.getFormSection(formId); + return FormSectionResponse.from(query); + } +} diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/controller/dto/response/FormSectionResponse.java b/src/main/java/ddingdong/ddingdongBE/domain/form/controller/dto/response/FormSectionResponse.java new file mode 100644 index 00000000..912ed7b2 --- /dev/null +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/controller/dto/response/FormSectionResponse.java @@ -0,0 +1,24 @@ +package ddingdong.ddingdongBE.domain.form.controller.dto.response; + +import ddingdong.ddingdongBE.domain.form.service.dto.query.FormSectionQuery; +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; +import lombok.Builder; + +@Builder +public record FormSectionResponse ( + @Schema(description = "폼지 제목", example = "카우 1기 폼지") + String title, + @Schema(description = "폼지 설명", example = "폼지 설명입니다") + String description, + @Schema(description = "섹션 리스트", example = "[서버, 웹]") + List sections +) { + public static FormSectionResponse from(FormSectionQuery formSectionQuery) { + return FormSectionResponse.builder() + .title(formSectionQuery.title()) + .description(formSectionQuery.description()) + .sections(formSectionQuery.sections()) + .build(); + } +} diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeUserFormService.java b/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeUserFormService.java new file mode 100644 index 00000000..8070736c --- /dev/null +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeUserFormService.java @@ -0,0 +1,8 @@ +package ddingdong.ddingdongBE.domain.form.service; + +import ddingdong.ddingdongBE.domain.form.service.dto.query.FormSectionQuery; + +public interface FacadeUserFormService { + + FormSectionQuery getFormSection(Long formId); +} diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeUserFormServiceImpl.java b/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeUserFormServiceImpl.java new file mode 100644 index 00000000..78d78506 --- /dev/null +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeUserFormServiceImpl.java @@ -0,0 +1,21 @@ +package ddingdong.ddingdongBE.domain.form.service; + +import ddingdong.ddingdongBE.domain.form.entity.Form; +import ddingdong.ddingdongBE.domain.form.service.dto.query.FormSectionQuery; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class FacadeUserFormServiceImpl implements FacadeUserFormService { + + private final FormService formService; + + @Override + public FormSectionQuery getFormSection(Long formId) { + Form form = formService.getById(formId); + return FormSectionQuery.from(form); + } +} diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/service/dto/query/FormSectionQuery.java b/src/main/java/ddingdong/ddingdongBE/domain/form/service/dto/query/FormSectionQuery.java new file mode 100644 index 00000000..334110b1 --- /dev/null +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/service/dto/query/FormSectionQuery.java @@ -0,0 +1,21 @@ +package ddingdong.ddingdongBE.domain.form.service.dto.query; + +import ddingdong.ddingdongBE.domain.form.entity.Form; +import java.util.List; +import lombok.Builder; + +@Builder +public record FormSectionQuery( + String title, + String description, + List sections +) { + + public static FormSectionQuery from(Form form) { + return FormSectionQuery.builder() + .title(form.getTitle()) + .description(form.getDescription()) + .sections(form.getSections()) + .build(); + } +} diff --git a/src/main/java/ddingdong/ddingdongBE/domain/formapplication/controller/UserFormApplicationController.java b/src/main/java/ddingdong/ddingdongBE/domain/formapplication/controller/UserFormApplicationController.java index 2eb57b49..68e4f37c 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/formapplication/controller/UserFormApplicationController.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/formapplication/controller/UserFormApplicationController.java @@ -2,7 +2,7 @@ import ddingdong.ddingdongBE.domain.formapplication.api.UserFormApplicationApi; import ddingdong.ddingdongBE.domain.formapplication.controller.dto.request.CreateFormApplicationRequest; -import ddingdong.ddingdongBE.domain.formapplication.service.FacadeUserFormService; +import ddingdong.ddingdongBE.domain.formapplication.service.FacadeUserFormApplicationService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.RestController; @@ -10,11 +10,12 @@ @RequiredArgsConstructor public class UserFormApplicationController implements UserFormApplicationApi { - private final FacadeUserFormService facadeUserFormService; + private final FacadeUserFormApplicationService facadeUserFormApplicationService; @Override public void createFormApplication(Long formId, CreateFormApplicationRequest createFormApplicationRequest) { - facadeUserFormService.createFormApplication(createFormApplicationRequest.toCommand(formId)); + facadeUserFormApplicationService.createFormApplication( + createFormApplicationRequest.toCommand(formId)); } } diff --git a/src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormService.java b/src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormApplicationService.java similarity index 83% rename from src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormService.java rename to src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormApplicationService.java index 3a7fbee8..d3d864df 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormService.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormApplicationService.java @@ -2,7 +2,7 @@ import ddingdong.ddingdongBE.domain.formapplication.service.dto.command.CreateFormApplicationCommand; -public interface FacadeUserFormService { +public interface FacadeUserFormApplicationService { void createFormApplication(CreateFormApplicationCommand createFormApplicationCommand); diff --git a/src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormServiceImpl.java b/src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormApplicationServiceImpl.java similarity index 95% rename from src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormServiceImpl.java rename to src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormApplicationServiceImpl.java index 012cd1ce..ba92dba3 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormServiceImpl.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormApplicationServiceImpl.java @@ -15,7 +15,7 @@ @Service @RequiredArgsConstructor @Transactional(readOnly = true) -public class FacadeUserFormServiceImpl implements FacadeUserFormService { +public class FacadeUserFormApplicationServiceImpl implements FacadeUserFormApplicationService { private final FormApplicationService formApplicationService; private final FormAnswerService formAnswerService; diff --git a/src/test/java/ddingdong/ddingdongBE/domain/form/service/FacadeUserFormApplicationServiceImplTest.java b/src/test/java/ddingdong/ddingdongBE/domain/form/service/FacadeUserFormApplicationServiceImplTest.java new file mode 100644 index 00000000..c9560474 --- /dev/null +++ b/src/test/java/ddingdong/ddingdongBE/domain/form/service/FacadeUserFormApplicationServiceImplTest.java @@ -0,0 +1,112 @@ +package ddingdong.ddingdongBE.domain.form.service; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +import com.navercorp.fixturemonkey.FixtureMonkey; +import ddingdong.ddingdongBE.common.support.FixtureMonkeyFactory; +import ddingdong.ddingdongBE.common.support.TestContainerSupport; +import ddingdong.ddingdongBE.domain.club.entity.Club; +import ddingdong.ddingdongBE.domain.club.repository.ClubRepository; +import ddingdong.ddingdongBE.domain.form.entity.FieldType; +import ddingdong.ddingdongBE.domain.form.entity.Form; +import ddingdong.ddingdongBE.domain.form.entity.FormField; +import ddingdong.ddingdongBE.domain.form.repository.FormFieldRepository; +import ddingdong.ddingdongBE.domain.form.repository.FormRepository; +import ddingdong.ddingdongBE.domain.formapplication.entity.FormAnswer; +import ddingdong.ddingdongBE.domain.formapplication.entity.FormApplication; +import ddingdong.ddingdongBE.domain.formapplication.repository.FormAnswerRepository; +import ddingdong.ddingdongBE.domain.formapplication.repository.FormApplicationRepository; +import ddingdong.ddingdongBE.domain.formapplication.service.FacadeUserFormApplicationService; +import ddingdong.ddingdongBE.domain.formapplication.service.dto.command.CreateFormApplicationCommand; +import ddingdong.ddingdongBE.domain.formapplication.service.dto.command.CreateFormApplicationCommand.CreateFormAnswerCommand; +import ddingdong.ddingdongBE.domain.user.entity.Role; +import ddingdong.ddingdongBE.domain.user.entity.User; +import ddingdong.ddingdongBE.domain.user.repository.UserRepository; +import jakarta.persistence.EntityManager; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class FacadeUserFormApplicationServiceImplTest extends TestContainerSupport { + + @Autowired + private FacadeUserFormApplicationService facadeUserFormApplicationService; + + @Autowired + private FormApplicationRepository formApplicationRepository; + + @Autowired + private FormAnswerRepository formAnswerRepository; + + @Autowired + private FormRepository formRepository; + + @Autowired + private ClubRepository clubRepository; + + @Autowired + private UserRepository userRepository; + + @Autowired + private FormFieldRepository formFieldRepository; + + @Autowired + private EntityManager entityManager; + + private static final FixtureMonkey fixtureMonkey = FixtureMonkeyFactory.getNotNullBuilderIntrospectorMonkey(); + + @DisplayName("사용자는 동아리에 지원할 수 있다.") + @Test + void createFormApplication() { + // given + User user = fixtureMonkey.giveMeBuilder(User.class) + .set("id", 1L) + .set("Role", Role.CLUB) + .set("deletedAt", null) + .sample(); + User savedUser = userRepository.save(user); + Club club = fixtureMonkey.giveMeBuilder(Club.class) + .set("id", 1L) + .set("user", savedUser) + .set("score", null) + .set("clubMembers", null) + .set("deletedAt", null) + .sample(); + clubRepository.save(club); + Club savedClub = clubRepository.save(club); + Form form = fixtureMonkey.giveMeBuilder(Form.class) + .set("id", 1L) + .set("title", "띵동 폼") + .set("description", "저희 동아리는 띵동입니다.") + .set("hasInterview", false) + .set("club", savedClub) + .sample(); + Form savedForm = formRepository.save(form); + FormField formField = FormField.builder() + .form(savedForm) + .fieldType(FieldType.CHECK_BOX) + .fieldOrder(1) + .section("서버") + .required(true) + .question("질문") + .build(); + FormField savedFormField = formFieldRepository.save(formField); + CreateFormApplicationCommand createFormApplicationCommand = fixtureMonkey.giveMeBuilder(CreateFormApplicationCommand.class) + .set("formId", savedForm.getId()) + .set("formAnswerCommands", List.of(new CreateFormAnswerCommand(savedFormField.getId(), List.of("답변")))) + .sample(); + // when + facadeUserFormApplicationService.createFormApplication(createFormApplicationCommand); + // then + List formApplications = formApplicationRepository.findAll(); + List formAnswers = formAnswerRepository.findAll(); + + assertThat(formApplications).isNotEmpty(); + assertThat(formApplications.get(0).getForm().getId()).isEqualTo(savedForm.getId()); + assertThat(formAnswers).isNotEmpty(); + assertThat(formAnswers.get(0).getValue()).isEqualTo(List.of("답변")); + } +} diff --git a/src/test/java/ddingdong/ddingdongBE/domain/form/service/FacadeUserFormServiceImplTest.java b/src/test/java/ddingdong/ddingdongBE/domain/form/service/FacadeUserFormServiceImplTest.java index 2b8273f2..9779d03f 100644 --- a/src/test/java/ddingdong/ddingdongBE/domain/form/service/FacadeUserFormServiceImplTest.java +++ b/src/test/java/ddingdong/ddingdongBE/domain/form/service/FacadeUserFormServiceImplTest.java @@ -7,22 +7,13 @@ import ddingdong.ddingdongBE.common.support.TestContainerSupport; import ddingdong.ddingdongBE.domain.club.entity.Club; import ddingdong.ddingdongBE.domain.club.repository.ClubRepository; -import ddingdong.ddingdongBE.domain.form.entity.FieldType; import ddingdong.ddingdongBE.domain.form.entity.Form; -import ddingdong.ddingdongBE.domain.form.entity.FormField; -import ddingdong.ddingdongBE.domain.form.repository.FormFieldRepository; import ddingdong.ddingdongBE.domain.form.repository.FormRepository; -import ddingdong.ddingdongBE.domain.formapplication.entity.FormAnswer; -import ddingdong.ddingdongBE.domain.formapplication.entity.FormApplication; -import ddingdong.ddingdongBE.domain.formapplication.repository.FormAnswerRepository; -import ddingdong.ddingdongBE.domain.formapplication.repository.FormApplicationRepository; -import ddingdong.ddingdongBE.domain.formapplication.service.FacadeUserFormService; -import ddingdong.ddingdongBE.domain.formapplication.service.dto.command.CreateFormApplicationCommand; -import ddingdong.ddingdongBE.domain.formapplication.service.dto.command.CreateFormApplicationCommand.CreateFormAnswerCommand; +import ddingdong.ddingdongBE.domain.form.service.dto.query.FormSectionQuery; import ddingdong.ddingdongBE.domain.user.entity.Role; import ddingdong.ddingdongBE.domain.user.entity.User; import ddingdong.ddingdongBE.domain.user.repository.UserRepository; -import jakarta.persistence.EntityManager; +import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -32,81 +23,56 @@ @SpringBootTest class FacadeUserFormServiceImplTest extends TestContainerSupport { - @Autowired - private FacadeUserFormService facadeUserFormService; + @Autowired + private FacadeUserFormService facadeUserFormService; - @Autowired - private FormApplicationRepository formApplicationRepository; + @Autowired + private FormRepository formRepository; - @Autowired - private FormAnswerRepository formAnswerRepository; + @Autowired + private ClubRepository clubRepository; - @Autowired - private FormRepository formRepository; + @Autowired + private UserRepository userRepository; - @Autowired - private ClubRepository clubRepository; + private static final FixtureMonkey fixtureMonkey = FixtureMonkeyFactory.getNotNullBuilderIntrospectorMonkey(); - @Autowired - private UserRepository userRepository; + @DisplayName("유저는 섹션 목록을 조회할 수 있다.") + @Test + void getFormSection() { + // given + User user = fixtureMonkey.giveMeBuilder(User.class) + .set("id", 1L) + .set("Role", Role.CLUB) + .set("deletedAt", null) + .sample(); + User savedUser = userRepository.save(user); - @Autowired - private FormFieldRepository formFieldRepository; + Club club = fixtureMonkey.giveMeBuilder(Club.class) + .set("id", 1L) + .set("user", savedUser) + .set("score", null) + .set("clubMembers", null) + .set("deletedAt", null) + .sample(); + clubRepository.save(club); - @Autowired - private EntityManager entityManager; + List savedSections = new ArrayList<>(); + savedSections.add("section1"); + savedSections.add("section2"); - private static final FixtureMonkey fixtureMonkey = FixtureMonkeyFactory.getNotNullBuilderIntrospectorMonkey(); + Form form = fixtureMonkey.giveMeBuilder(Form.class) + .set("id", 1L) + .set("title", "띵동 폼") + .set("description", "저희 동아리는 띵동입니다.") + .set("hasInterview", false) + .set("club", club) + .set("sections", savedSections) + .sample(); + Form savedForm = formRepository.save(form); - @DisplayName("사용자는 동아리에 지원할 수 있다.") - @Test - void createFormApplication() { - // given - User user = fixtureMonkey.giveMeBuilder(User.class) - .set("id", 1L) - .set("Role", Role.CLUB) - .set("deletedAt", null) - .sample(); - User savedUser = userRepository.save(user); - Club club = fixtureMonkey.giveMeBuilder(Club.class) - .set("id", 1L) - .set("user", savedUser) - .set("score", null) - .set("clubMembers", null) - .set("deletedAt", null) - .sample(); - clubRepository.save(club); - Club savedClub = clubRepository.save(club); - Form form = fixtureMonkey.giveMeBuilder(Form.class) - .set("id", 1L) - .set("title", "띵동 폼") - .set("description", "저희 동아리는 띵동입니다.") - .set("hasInterview", false) - .set("club", savedClub) - .sample(); - Form savedForm = formRepository.save(form); - FormField formField = FormField.builder() - .form(savedForm) - .fieldType(FieldType.CHECK_BOX) - .fieldOrder(1) - .section("서버") - .required(true) - .question("질문") - .build(); - FormField savedFormField = formFieldRepository.save(formField); - CreateFormApplicationCommand createFormApplicationCommand = fixtureMonkey.giveMeBuilder(CreateFormApplicationCommand.class) - .set("formId", savedForm.getId()) - .set("formAnswerCommands", List.of(new CreateFormAnswerCommand(savedFormField.getId(), List.of("답변")))) - .sample(); - // when - facadeUserFormService.createFormApplication(createFormApplicationCommand); - // then - List formApplications = formApplicationRepository.findAll(); - List formAnswers = formAnswerRepository.findAll(); + FormSectionQuery sectionQuery = facadeUserFormService.getFormSection(savedForm.getId()); - assertThat(formApplications).isNotEmpty(); - assertThat(formApplications.get(0).getForm().getId()).isEqualTo(savedForm.getId()); - assertThat(formAnswers).isNotEmpty(); - assertThat(formAnswers.get(0).getValue()).isEqualTo(List.of("답변")); - } -} + assertThat(sectionQuery.sections()).isEqualTo(savedSections); + } +} \ No newline at end of file