diff --git a/src/main/java/clap/server/adapter/outbound/persistense/entity/member/MemberEntity.java b/src/main/java/clap/server/adapter/outbound/persistense/entity/member/MemberEntity.java index c2e28dca..40e294a8 100644 --- a/src/main/java/clap/server/adapter/outbound/persistense/entity/member/MemberEntity.java +++ b/src/main/java/clap/server/adapter/outbound/persistense/entity/member/MemberEntity.java @@ -46,6 +46,7 @@ public class MemberEntity extends BaseTimeEntity { @Column(nullable = false) private MemberStatus status; + @Column private String password; @Column diff --git a/src/main/java/clap/server/application/service/admin/CsvParseService.java b/src/main/java/clap/server/application/service/admin/CsvParseService.java index aeaed78c..547b99c0 100644 --- a/src/main/java/clap/server/application/service/admin/CsvParseService.java +++ b/src/main/java/clap/server/application/service/admin/CsvParseService.java @@ -65,12 +65,14 @@ private Member mapToMember(String[] fields, List departments) { fields[0].trim(), // name fields[4].trim(), // email fields[1].trim(), // nickname - Boolean.parseBoolean(fields[6].trim()), // isReviewer + Boolean.parseBoolean(fields[6].trim().toLowerCase()), // isReviewer department, // department MemberRole.valueOf(fields[5].trim()), // role fields[3].trim() // departmentRole ); - return toMember(memberInfo); + return Member.builder() + .memberInfo(memberInfo) + .build(); } } diff --git a/src/main/java/clap/server/application/service/admin/RegisterMemberCSVService.java b/src/main/java/clap/server/application/service/admin/RegisterMemberCSVService.java index 76261543..0723c7dd 100644 --- a/src/main/java/clap/server/application/service/admin/RegisterMemberCSVService.java +++ b/src/main/java/clap/server/application/service/admin/RegisterMemberCSVService.java @@ -23,9 +23,12 @@ public class RegisterMemberCSVService implements RegisterMemberCSVUsecase { public int registerMembersFromCsv(Long adminId, MultipartFile file) { List members = csvParser.parseDataAndMapToMember(file); Member admin = memberService.findActiveMember(adminId); - members.forEach(member -> {member.register(admin);}); - commandMemberPort.saveAll(members); + List newMembers = members.stream() + .map(memberData -> Member.createMember(admin, memberData.getMemberInfo())) + .toList(); + + commandMemberPort.saveAll(newMembers); return members.size(); } } \ No newline at end of file diff --git a/src/test/java/clap/server/application/service/admin/RegisterMemberCSVServiceTest.java b/src/test/java/clap/server/application/service/admin/RegisterMemberCSVServiceTest.java deleted file mode 100644 index 3c974e35..00000000 --- a/src/test/java/clap/server/application/service/admin/RegisterMemberCSVServiceTest.java +++ /dev/null @@ -1,132 +0,0 @@ -package clap.server.application.service.admin; - -import clap.server.application.port.inbound.domain.MemberService; -import clap.server.application.port.outbound.member.CommandMemberPort; -import clap.server.domain.model.member.Member; -import clap.server.exception.ApplicationException; -import clap.server.exception.code.MemberErrorCode; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.springframework.mock.web.MockMultipartFile; -import org.springframework.web.multipart.MultipartFile; - -import java.io.IOException; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; - -class RegisterMemberCSVServiceTest { - - private RegisterMemberCSVService registerMemberCSVService; - private MemberService memberService; - private CommandMemberPort commandMemberPort; - private CsvParseService csvParseService; - - - @BeforeEach - void setup() { - memberService = Mockito.mock(MemberService.class); - commandMemberPort = Mockito.mock(CommandMemberPort.class); - csvParseService = Mockito.mock(CsvParseService.class); - registerMemberCSVService = new RegisterMemberCSVService(memberService, commandMemberPort, csvParseService); - } - - /** - * 정상적인 회원 등록 테스트 - * - 주어진 CSV 파일을 정상적으로 파싱하여 회원이 등록되는지 검증 - */ - @Test - @DisplayName("CSV 파일에서 회원 정보를 성공적으로 파싱하고 등록하는지 검증한다.") - void testRegisterMembersFromCsvSuccess() { - Long adminId = 1L; - MultipartFile file = new MockMultipartFile("file", "members.csv", "text/csv", "dummy-content".getBytes()); - - Member admin = Mockito.mock(Member.class); - List parsedMembers = List.of(Mockito.mock(Member.class), Mockito.mock(Member.class)); - - when(memberService.findActiveMember(adminId)).thenReturn(admin); - when(csvParseService.parseDataAndMapToMember(file)).thenReturn(parsedMembers); - - int addedCount = registerMemberCSVService.registerMembersFromCsv(adminId, file); - - assertEquals(2, addedCount); - verify(commandMemberPort).saveAll(parsedMembers); - verify(parsedMembers.get(0)).register(admin); - verify(parsedMembers.get(1)).register(admin); - } - - - /** - * ❌ 관리자 찾기 실패 (MEMBER_NOT_FOUND) - */ - @Test - @DisplayName("관리자가 존재하지 않을 때 CSV 회원 등록 시 예외가 발생한다.") - void testRegisterMembersFromCsvThrowsWhenAdminNotFound() { - Long adminId = 99L; - MultipartFile file = new MockMultipartFile("file", "members.csv", "text/csv", "dummy-content".getBytes()); - - when(memberService.findActiveMember(adminId)).thenThrow(new ApplicationException(MemberErrorCode.MEMBER_NOT_FOUND)); - - ApplicationException exception = assertThrows(ApplicationException.class, () -> { - registerMemberCSVService.registerMembersFromCsv(adminId, file); - }); - - // 검증: 발생한 예외가 `MEMBER_NOT_FOUND`인지 확인 - assertEquals(MemberErrorCode.MEMBER_NOT_FOUND.getCustomCode(), exception.getCode().getCustomCode()); - verifyNoInteractions(commandMemberPort); // 회원 저장 로직이 실행안됨 - } - - /** - * ❌ CSV 파싱 실패 (CSV_PARSING_ERROR) - */ - @Test - @DisplayName("CSV 파싱 실패 시 예외 발생 및 회원 등록이 실패한다.") - void testRegisterMembersFromCsvThrowsWhenCsvParsingFails() { - Long adminId = 1L; - MultipartFile file = new MockMultipartFile("file", "members.csv", "text/csv", "dummy-content".getBytes()); - - // ✅ Mock 객체 설정: CSV 파싱 과정에서 예외 발생하도록 설정 - when(csvParseService.parseDataAndMapToMember(file)).thenThrow(new ApplicationException(MemberErrorCode.CSV_PARSING_ERROR)); - - // 🔹 유스케이스 실행 및 예외 검증 - ApplicationException exception = assertThrows(ApplicationException.class, () -> { - registerMemberCSVService.registerMembersFromCsv(adminId, file); - }); - - // ✅ 검증: 발생한 예외가 `CSV_PARSING_ERROR`인지 확인 - assertEquals(MemberErrorCode.CSV_PARSING_ERROR.getCustomCode(), exception.getCode().getCustomCode()); - verifyNoInteractions(commandMemberPort); // ❗ 회원 저장 로직이 실행되지 않아야 함 - } - - /** - * ❌ 회원 등록 실패 (MEMBER_REGISTRATION_FAILED) - * - */ -// @Test -// @DisplayName("회원 등록 과정 중 실패 시 예외 발생 및 부분 저장 된다.") -// void testRegisterMembersFromCsvThrowsWhenSavingMemberFails() { -// Long adminId = 1L; -// MultipartFile file = new MockMultipartFile("file", "members.csv", "text/csv", "dummy-content".getBytes()); -// -// Member admin = Mockito.mock(Member.class); -// Member failingMember = Mockito.mock(Member.class); -// List parsedMembers = List.of(failingMember, Mockito.mock(Member.class)); -// -// // 특정 회원 등록 중 예외 발생 -// when(memberService.findActiveMember(adminId)).thenReturn(admin); -// when(csvParseService.parseDataAndMapToMember(file)).thenReturn(parsedMembers); -// doThrow(new ApplicationException(MemberErrorCode.MEMBER_REGISTRATION_FAILED)) -// .when(commandMemberPort).save(failingMember); -// -// // Usecase 실행 -// ApplicationException exception = assertThrows(ApplicationException.class, () -> { -// registerMemberCSVService.registerMembersFromCsv(adminId, file); -// }); -// -// assertEquals(MemberErrorCode.MEMBER_REGISTRATION_FAILED.getCustomCode(), exception.getCode().getCustomCode()); -// verify(commandMemberPort, times(1)).save(failingMember); // ❗ 실패한 회원만 저장 시도해야 함 -// } -}