diff --git a/backend/.gitignore b/backend/.gitignore index fea34685..9f039158 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -8,6 +8,9 @@ build/ ### Generated ### **/src/main/generated/ +### initDB ### +**/src/main/java/moim_today/global/init/** + ### Properties ### application.yml application-dev.yml diff --git a/backend/src/main/java/moim_today/application/auth/AuthService.java b/backend/src/main/java/moim_today/application/auth/AuthService.java index 1ccf618b..da2e4400 100644 --- a/backend/src/main/java/moim_today/application/auth/AuthService.java +++ b/backend/src/main/java/moim_today/application/auth/AuthService.java @@ -8,7 +8,7 @@ public interface AuthService { void login(final MemberLoginRequest memberLoginRequest, final HttpServletRequest request); - void register(final MemberRegisterRequest memberRegisterRequest, final HttpServletRequest request); + void signUp(final MemberRegisterRequest memberRegisterRequest, final HttpServletRequest request); void logout(final HttpServletRequest request); } diff --git a/backend/src/main/java/moim_today/application/auth/AuthServiceImpl.java b/backend/src/main/java/moim_today/application/auth/AuthServiceImpl.java index 24e74a0f..0a0198e2 100644 --- a/backend/src/main/java/moim_today/application/auth/AuthServiceImpl.java +++ b/backend/src/main/java/moim_today/application/auth/AuthServiceImpl.java @@ -39,11 +39,11 @@ public void logout(final HttpServletRequest request) { } @Override - public void register(final MemberRegisterRequest memberRegisterRequest, - final HttpServletRequest request) { + public void signUp(final MemberRegisterRequest memberRegisterRequest, + final HttpServletRequest request) { universityFinder.checkUniversityIdIsPresent(memberRegisterRequest.universityId()); departmentFinder.isDepartmentAssociatedWithUniversity(memberRegisterRequest.universityId(), memberRegisterRequest.departmentId()); memberFinder.validateEmailNotExists(memberRegisterRequest.email()); - authManager.register(memberRegisterRequest, request); + authManager.signUp(memberRegisterRequest, request); } } diff --git a/backend/src/main/java/moim_today/application/file/AmazonS3Service.java b/backend/src/main/java/moim_today/application/file/AmazonS3Service.java index 691e4265..12bb20ef 100644 --- a/backend/src/main/java/moim_today/application/file/AmazonS3Service.java +++ b/backend/src/main/java/moim_today/application/file/AmazonS3Service.java @@ -8,6 +8,8 @@ import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import java.io.File; + @Service public class AmazonS3Service implements FileService{ @@ -21,7 +23,8 @@ public AmazonS3Service(final FileUploader fileUploader, final FileRemover fileRe } public FileInfoResponse uploadFile(final String fileType, final MultipartFile multipartFile){ - return fileUploader.uploadFile(fileType, multipartFile); + String imageUrl = fileUploader.uploadFile(fileType, multipartFile); + return new FileInfoResponse(imageUrl); } public void deleteFile(final MemberSession memberSession, final FileDeleteRequest fileDeleteRequest){ diff --git a/backend/src/main/java/moim_today/application/member/MemberServiceImpl.java b/backend/src/main/java/moim_today/application/member/MemberServiceImpl.java index ba773a61..ad8c4d16 100644 --- a/backend/src/main/java/moim_today/application/member/MemberServiceImpl.java +++ b/backend/src/main/java/moim_today/application/member/MemberServiceImpl.java @@ -61,7 +61,7 @@ public void updateProfile(final long memberId, @Override public void updateProfileImage(final long memberId, final MultipartFile file) { - FileInfoResponse fileInfoResponse = fileUploader.uploadFile(PROFILE_IMAGE.value(), file); - memberUpdater.updateProfileImageUrl(memberId, fileInfoResponse.uploadFileUrl()); + String imageUrl = fileUploader.uploadFile(PROFILE_IMAGE.value(), file); + memberUpdater.updateProfileImageUrl(memberId, imageUrl); } } diff --git a/backend/src/main/java/moim_today/application/moim/MoimService.java b/backend/src/main/java/moim_today/application/moim/MoimService.java new file mode 100644 index 00000000..8f1fa17d --- /dev/null +++ b/backend/src/main/java/moim_today/application/moim/MoimService.java @@ -0,0 +1,19 @@ +package moim_today.application.moim; + +import moim_today.dto.moim.*; +import org.springframework.web.multipart.MultipartFile; + +public interface MoimService { + + void createPublicMoim(final long memberId, final long universityId, + final PublicMoimAppendRequest publicMoimAppendRequest); + + void createPrivateMoim(final long memberId, final long universityId, + final PrivateMoimAppendRequest privateMoimAppendRequest); + + UploadMoimImageResponse uploadMoimImage(final MultipartFile file); + + MoimDetailResponse getMoimDetail(final long moimId); + + void updateMoim(final long memberId, final MoimUpdateRequest moimUpdateRequest); +} diff --git a/backend/src/main/java/moim_today/application/moim/MoimServiceImpl.java b/backend/src/main/java/moim_today/application/moim/MoimServiceImpl.java new file mode 100644 index 00000000..fc584b2d --- /dev/null +++ b/backend/src/main/java/moim_today/application/moim/MoimServiceImpl.java @@ -0,0 +1,60 @@ +package moim_today.application.moim; + +import moim_today.dto.moim.*; +import moim_today.implement.file.FileUploader; +import moim_today.implement.moim.MoimAppender; +import moim_today.implement.moim.MoimFinder; +import moim_today.implement.moim.MoimUpdater; +import moim_today.persistence.entity.moim.moim.MoimJpaEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import static moim_today.global.constant.FileTypeConstant.MOIM_IMAGE; + +@Service +public class MoimServiceImpl implements MoimService{ + + private final MoimAppender moimAppender; + private final FileUploader fileUploader; + private final MoimFinder moimFinder; + private final MoimUpdater moimUpdater; + + public MoimServiceImpl(final MoimAppender moimAppender, + final FileUploader fileUploader, + final MoimFinder moimFinder, + final MoimUpdater moimUpdater) { + this.moimAppender = moimAppender; + this.fileUploader = fileUploader; + this.moimFinder = moimFinder; + this.moimUpdater = moimUpdater; + } + + @Override + public void createPublicMoim(final long memberId, final long universityId, + final PublicMoimAppendRequest publicMoimAppendRequest) { + moimAppender.createPublicMoim(memberId, universityId, publicMoimAppendRequest); + } + + @Override + public void createPrivateMoim(final long memberId, final long universityId, + final PrivateMoimAppendRequest privateMoimAppendRequest) { + moimAppender.createPrivateMoim(memberId, universityId, privateMoimAppendRequest); + } + + @Override + public UploadMoimImageResponse uploadMoimImage(final MultipartFile file) { + String imageUrl = fileUploader.uploadFile(MOIM_IMAGE.value(), file); + return UploadMoimImageResponse.from(imageUrl); + } + + @Override + public MoimDetailResponse getMoimDetail(final long moimId) { + MoimJpaEntity moimJpaEntity = moimFinder.getById(moimId); + return MoimDetailResponse.from(moimJpaEntity); + } + + @Override + public void updateMoim(final long memberId, final MoimUpdateRequest moimUpdateRequest) { + moimUpdater.updateMoim(memberId, moimUpdateRequest); + } +} diff --git a/backend/src/main/java/moim_today/application/schedule/ScheduleService.java b/backend/src/main/java/moim_today/application/schedule/ScheduleService.java index 94171835..219d10c8 100644 --- a/backend/src/main/java/moim_today/application/schedule/ScheduleService.java +++ b/backend/src/main/java/moim_today/application/schedule/ScheduleService.java @@ -1,9 +1,17 @@ package moim_today.application.schedule; +import moim_today.dto.schedule.ScheduleCreateRequest; +import moim_today.dto.schedule.ScheduleUpdateRequest; import moim_today.dto.schedule.TimeTableRequest; public interface ScheduleService { void fetchTimeTable(final long memberId, final TimeTableRequest timeTableRequest); + + void createSchedule(final long memberId, final ScheduleCreateRequest scheduleCreateRequest); + + void updateSchedule(final long memberId, final ScheduleUpdateRequest scheduleUpdateRequest); + + void deleteSchedule(final long memberId, final long scheduleId); } diff --git a/backend/src/main/java/moim_today/application/schedule/ScheduleServiceImpl.java b/backend/src/main/java/moim_today/application/schedule/ScheduleServiceImpl.java index af20fd22..ca02c0f0 100644 --- a/backend/src/main/java/moim_today/application/schedule/ScheduleServiceImpl.java +++ b/backend/src/main/java/moim_today/application/schedule/ScheduleServiceImpl.java @@ -1,9 +1,14 @@ package moim_today.application.schedule; import moim_today.domain.schedule.Schedule; +import moim_today.dto.schedule.ScheduleCreateRequest; +import moim_today.dto.schedule.ScheduleUpdateRequest; import moim_today.dto.schedule.TimeTableRequest; import moim_today.implement.schedule.ScheduleAppender; +import moim_today.implement.schedule.ScheduleDeleter; import moim_today.implement.schedule.ScheduleManager; +import moim_today.implement.schedule.ScheduleUpdater; +import moim_today.persistence.entity.schedule.ScheduleJpaEntity; import org.springframework.stereotype.Service; import java.util.List; @@ -13,10 +18,15 @@ public class ScheduleServiceImpl implements ScheduleService { private final ScheduleManager scheduleManager; private final ScheduleAppender scheduleAppender; + private final ScheduleUpdater scheduleUpdater; + private final ScheduleDeleter scheduleDeleter; - public ScheduleServiceImpl(final ScheduleManager scheduleManager, final ScheduleAppender scheduleAppender) { + public ScheduleServiceImpl(final ScheduleManager scheduleManager, final ScheduleAppender scheduleAppender, + final ScheduleUpdater scheduleUpdater, final ScheduleDeleter scheduleDeleter) { this.scheduleManager = scheduleManager; this.scheduleAppender = scheduleAppender; + this.scheduleUpdater = scheduleUpdater; + this.scheduleDeleter = scheduleDeleter; } @Override @@ -25,4 +35,20 @@ public void fetchTimeTable(final long memberId, final TimeTableRequest timeTable List schedules = scheduleManager.processTimetable(timeTableXML, timeTableRequest); scheduleAppender.batchUpdateSchedules(schedules, memberId); } + + @Override + public void createSchedule(final long memberId, final ScheduleCreateRequest scheduleCreateRequest) { + ScheduleJpaEntity scheduleJpaEntity = scheduleCreateRequest.toEntity(memberId); + scheduleAppender.createSchedule(scheduleJpaEntity); + } + + @Override + public void updateSchedule(final long memberId, final ScheduleUpdateRequest scheduleUpdateRequest) { + scheduleUpdater.updateSchedule(memberId, scheduleUpdateRequest); + } + + @Override + public void deleteSchedule(final long memberId, final long scheduleId) { + scheduleDeleter.deleteSchedule(memberId, scheduleId); + } } \ No newline at end of file diff --git a/backend/src/main/java/moim_today/application/university/UniversityServiceImpl.java b/backend/src/main/java/moim_today/application/university/UniversityServiceImpl.java index ab3c3827..ebfd3710 100644 --- a/backend/src/main/java/moim_today/application/university/UniversityServiceImpl.java +++ b/backend/src/main/java/moim_today/application/university/UniversityServiceImpl.java @@ -1,7 +1,7 @@ package moim_today.application.university; import moim_today.dto.university.UniversityInfoResponse; -import moim_today.implement.university.UniversityAppender; +import moim_today.implement.university.UniversityUpdater; import moim_today.implement.university.UniversityFinder; import org.springframework.stereotype.Service; @@ -10,17 +10,17 @@ @Service public class UniversityServiceImpl implements UniversityService{ - private final UniversityAppender universityAppender; + private final UniversityUpdater universityUpdater; private final UniversityFinder universityFinder; - public UniversityServiceImpl(final UniversityAppender universityAppender, final UniversityFinder universityFinder) { - this.universityAppender = universityAppender; + public UniversityServiceImpl(final UniversityUpdater universityUpdater, final UniversityFinder universityFinder) { + this.universityUpdater = universityUpdater; this.universityFinder = universityFinder; } @Override public void putAllUniversity() { - universityAppender.fetchAllUniversity(); + universityUpdater.fetchAllUniversity(); } @Override diff --git a/backend/src/main/java/moim_today/domain/department/Department.java b/backend/src/main/java/moim_today/domain/department/Department.java new file mode 100644 index 00000000..98ed1968 --- /dev/null +++ b/backend/src/main/java/moim_today/domain/department/Department.java @@ -0,0 +1,38 @@ +package moim_today.domain.department; + +import moim_today.persistence.entity.department.DepartmentJpaEntity; +import moim_today.persistence.entity.university.UniversityJpaEntity; + +import java.util.*; + +public record Department( + long universityId, + String departmentName +) { + + public static List toEntities(Map> universityAndDepartments) { + List departmentJpaEntities = new ArrayList<>(); + + for (Map.Entry> entrySet : universityAndDepartments.entrySet()) { + for (String departmentName : entrySet.getValue()) { + departmentJpaEntities.add(DepartmentJpaEntity.builder() + .universityId(entrySet.getKey()) + .departmentName(departmentName) + .build()); + } + } + return departmentJpaEntities; + } + + public static Map> convertToUnivIdAndDepartments(final Map> universityAndDepartments, + final List universityJpaEntities) { + Map> existingUniversities = new HashMap<>(); + + universityJpaEntities.stream() + .forEach(universityJpaEntity -> { + existingUniversities.put(universityJpaEntity.getId(), universityAndDepartments.get(universityJpaEntity.getUniversityName())); + }); + + return existingUniversities; + } +} diff --git a/backend/src/main/java/moim_today/domain/moim/DisplayStatus.java b/backend/src/main/java/moim_today/domain/moim/DisplayStatus.java new file mode 100644 index 00000000..1ed31ba1 --- /dev/null +++ b/backend/src/main/java/moim_today/domain/moim/DisplayStatus.java @@ -0,0 +1,6 @@ +package moim_today.domain.moim; + +public enum DisplayStatus { + + PUBLIC, PRIVATE +} diff --git a/backend/src/main/java/moim_today/domain/moim/enums/MoimCategory.java b/backend/src/main/java/moim_today/domain/moim/enums/MoimCategory.java index ab08b5e9..b3d25e55 100644 --- a/backend/src/main/java/moim_today/domain/moim/enums/MoimCategory.java +++ b/backend/src/main/java/moim_today/domain/moim/enums/MoimCategory.java @@ -2,4 +2,6 @@ // todo 정기 모임 카테고리 세부사항 추가 public enum MoimCategory { + + STUDY, TEAM_PROJECT } diff --git a/backend/src/main/java/moim_today/dto/moim/MoimDetailResponse.java b/backend/src/main/java/moim_today/dto/moim/MoimDetailResponse.java new file mode 100644 index 00000000..419b506a --- /dev/null +++ b/backend/src/main/java/moim_today/dto/moim/MoimDetailResponse.java @@ -0,0 +1,42 @@ +package moim_today.dto.moim; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Builder; +import moim_today.domain.moim.DisplayStatus; +import moim_today.domain.moim.enums.MoimCategory; +import moim_today.persistence.entity.moim.moim.MoimJpaEntity; + +import java.time.LocalDate; + +@Builder +public record MoimDetailResponse( + String title, + String contents, + int capacity, + int currentCount, + String imageUrl, + MoimCategory moimCategory, + DisplayStatus displayStatus, + int views, + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "Asia/Seoul") + LocalDate startDate, + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "Asia/Seoul") + LocalDate endDate + +) { + + public static MoimDetailResponse from(final MoimJpaEntity moimJpaEntity) { + return MoimDetailResponse.builder() + .title(moimJpaEntity.getTitle()) + .contents(moimJpaEntity.getContents()) + .capacity(moimJpaEntity.getCapacity()) + .currentCount(moimJpaEntity.getCurrentCount()) + .imageUrl(moimJpaEntity.getImageUrl()) + .moimCategory(moimJpaEntity.getMoimCategory()) + .displayStatus(moimJpaEntity.getDisplayStatus()) + .views(moimJpaEntity.getViews()) + .startDate(moimJpaEntity.getStartDate()) + .endDate(moimJpaEntity.getEndDate()) + .build(); + } +} diff --git a/backend/src/main/java/moim_today/dto/moim/MoimUpdateRequest.java b/backend/src/main/java/moim_today/dto/moim/MoimUpdateRequest.java new file mode 100644 index 00000000..53550973 --- /dev/null +++ b/backend/src/main/java/moim_today/dto/moim/MoimUpdateRequest.java @@ -0,0 +1,27 @@ +package moim_today.dto.moim; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Builder; +import moim_today.domain.moim.DisplayStatus; +import moim_today.domain.moim.enums.MoimCategory; + +import java.time.LocalDate; + +@Builder +public record MoimUpdateRequest( + long moimId, + String title, + String contents, + int capacity, + //imageUrl null 허용 + String imageUrl, + //비밀번호 null 허용 + String password, + MoimCategory moimCategory, + DisplayStatus displayStatus, + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "Asia/Seoul") + LocalDate startDate, + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "Asia/Seoul") + LocalDate endDate +) { +} diff --git a/backend/src/main/java/moim_today/dto/moim/PrivateMoimAppendRequest.java b/backend/src/main/java/moim_today/dto/moim/PrivateMoimAppendRequest.java new file mode 100644 index 00000000..29a0e075 --- /dev/null +++ b/backend/src/main/java/moim_today/dto/moim/PrivateMoimAppendRequest.java @@ -0,0 +1,56 @@ +package moim_today.dto.moim; + +import lombok.Builder; +import moim_today.domain.moim.DisplayStatus; +import moim_today.domain.moim.enums.MoimCategory; +import moim_today.persistence.entity.moim.moim.MoimJpaEntity; +import moim_today.persistence.entity.moim.moim.MoimJpaEntity.MoimJpaEntityBuilder; + +import java.time.LocalDate; + +import static moim_today.global.constant.MoimConstant.DEFAULT_MOIM_IMAGE_URL; +import static moim_today.global.constant.NumberConstant.DEFAULT_MOIM_CURRENT_COUNT; +import static moim_today.global.constant.NumberConstant.DEFAULT_MOIM_VIEWS; + +@Builder +public record PrivateMoimAppendRequest( + String title, + String contents, + int capacity, + String password, + String imageUrl, + MoimCategory moimCategory, + LocalDate startDate, + LocalDate endDate +) { + + public MoimJpaEntity toEntity(final long memberId, final long universityId) { + + MoimJpaEntityBuilder moimJpaEntityBuilder = MoimJpaEntity.builder() + .universityId(universityId) + .memberId(memberId) + .title(title) + .contents(contents) + .capacity(capacity) + .currentCount(DEFAULT_MOIM_CURRENT_COUNT.value()) + .password(password) + .moimCategory(moimCategory) + .displayStatus(DisplayStatus.PRIVATE) + .views(DEFAULT_MOIM_VIEWS.value()) + .startDate(startDate) + .endDate(endDate); + + if (imageUrl == null) { + return buildMoimByImageUrl(moimJpaEntityBuilder, DEFAULT_MOIM_IMAGE_URL.value()); + } else{ + return buildMoimByImageUrl(moimJpaEntityBuilder, imageUrl); + } + } + + private MoimJpaEntity buildMoimByImageUrl(final MoimJpaEntityBuilder moimJpaEntityBuilder, + final String imageUrl) { + return moimJpaEntityBuilder + .imageUrl(imageUrl) + .build(); + } +} diff --git a/backend/src/main/java/moim_today/dto/moim/PublicMoimAppendRequest.java b/backend/src/main/java/moim_today/dto/moim/PublicMoimAppendRequest.java new file mode 100644 index 00000000..a54c3161 --- /dev/null +++ b/backend/src/main/java/moim_today/dto/moim/PublicMoimAppendRequest.java @@ -0,0 +1,56 @@ +package moim_today.dto.moim; + +import lombok.Builder; +import moim_today.domain.moim.DisplayStatus; +import moim_today.domain.moim.enums.MoimCategory; +import moim_today.persistence.entity.moim.moim.MoimJpaEntity; +import moim_today.persistence.entity.moim.moim.MoimJpaEntity.MoimJpaEntityBuilder; + +import java.time.LocalDate; + +import static moim_today.global.constant.MoimConstant.DEFAULT_MOIM_IMAGE_URL; +import static moim_today.global.constant.MoimConstant.DEFAULT_MOIM_PASSWORD; +import static moim_today.global.constant.NumberConstant.DEFAULT_MOIM_CURRENT_COUNT; +import static moim_today.global.constant.NumberConstant.DEFAULT_MOIM_VIEWS; + +@Builder +public record PublicMoimAppendRequest( + String title, + String contents, + int capacity, + String imageUrl, + MoimCategory moimCategory, + LocalDate startDate, + LocalDate endDate +) { + + public MoimJpaEntity toEntity(final long memberId, final long universityId) { + + MoimJpaEntityBuilder moimJpaEntityBuilder = MoimJpaEntity.builder() + .universityId(universityId) + .memberId(memberId) + .title(title) + .contents(contents) + .capacity(capacity) + .currentCount(DEFAULT_MOIM_CURRENT_COUNT.value()) + .password(DEFAULT_MOIM_PASSWORD.value()) + .moimCategory(moimCategory) + .displayStatus(DisplayStatus.PUBLIC) + .views(DEFAULT_MOIM_VIEWS.value()) + .startDate(startDate) + .endDate(endDate); + + if (imageUrl == null) { + return buildMoimByImageUrl(moimJpaEntityBuilder, DEFAULT_MOIM_IMAGE_URL.value()); + } else { + return buildMoimByImageUrl(moimJpaEntityBuilder, imageUrl); + } + } + + private MoimJpaEntity buildMoimByImageUrl(final MoimJpaEntityBuilder moimJpaEntityBuilder, + final String imageUrl) { + return moimJpaEntityBuilder + .imageUrl(imageUrl) + .build(); + } +} diff --git a/backend/src/main/java/moim_today/dto/moim/UploadMoimImageResponse.java b/backend/src/main/java/moim_today/dto/moim/UploadMoimImageResponse.java new file mode 100644 index 00000000..f5332421 --- /dev/null +++ b/backend/src/main/java/moim_today/dto/moim/UploadMoimImageResponse.java @@ -0,0 +1,10 @@ +package moim_today.dto.moim; + +public record UploadMoimImageResponse( + String imageUrl +) { + + public static UploadMoimImageResponse from(String imageUrl) { + return new UploadMoimImageResponse(imageUrl); + } +} diff --git a/backend/src/main/java/moim_today/dto/schedule/ScheduleCreateRequest.java b/backend/src/main/java/moim_today/dto/schedule/ScheduleCreateRequest.java new file mode 100644 index 00000000..9b8b1867 --- /dev/null +++ b/backend/src/main/java/moim_today/dto/schedule/ScheduleCreateRequest.java @@ -0,0 +1,33 @@ +package moim_today.dto.schedule; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Builder; +import moim_today.persistence.entity.schedule.ScheduleJpaEntity; + +import java.time.DayOfWeek; +import java.time.LocalDateTime; + +import static moim_today.global.constant.NumberConstant.SCHEDULE_MEETING_ID; + +@Builder +public record ScheduleCreateRequest( + String scheduleName, + DayOfWeek dayOfWeek, + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul") + LocalDateTime startDateTime, + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul") + LocalDateTime endDateTime +) { + + public ScheduleJpaEntity toEntity(final long memberId) { + return ScheduleJpaEntity.builder() + .memberId(memberId) + .meetingId(SCHEDULE_MEETING_ID.value()) + .scheduleName(scheduleName) + .dayOfWeek(dayOfWeek) + .startDateTime(startDateTime) + .endDateTime(endDateTime) + .build(); + } +} diff --git a/backend/src/main/java/moim_today/dto/schedule/ScheduleDeleteRequest.java b/backend/src/main/java/moim_today/dto/schedule/ScheduleDeleteRequest.java new file mode 100644 index 00000000..7a313b5b --- /dev/null +++ b/backend/src/main/java/moim_today/dto/schedule/ScheduleDeleteRequest.java @@ -0,0 +1,6 @@ +package moim_today.dto.schedule; + +public record ScheduleDeleteRequest( + long scheduleId +) { +} diff --git a/backend/src/main/java/moim_today/dto/schedule/ScheduleUpdateRequest.java b/backend/src/main/java/moim_today/dto/schedule/ScheduleUpdateRequest.java new file mode 100644 index 00000000..fd3f8834 --- /dev/null +++ b/backend/src/main/java/moim_today/dto/schedule/ScheduleUpdateRequest.java @@ -0,0 +1,21 @@ +package moim_today.dto.schedule; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Builder; + +import java.time.DayOfWeek; +import java.time.LocalDateTime; + + +@Builder +public record ScheduleUpdateRequest( + long scheduleId, + String scheduleName, + DayOfWeek dayOfWeek, + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul") + LocalDateTime startDateTime, + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul") + LocalDateTime endDateTime +) { +} diff --git a/backend/src/main/java/moim_today/global/config/WebConfig.java b/backend/src/main/java/moim_today/global/config/WebConfig.java index d3b7d50a..851ecd53 100644 --- a/backend/src/main/java/moim_today/global/config/WebConfig.java +++ b/backend/src/main/java/moim_today/global/config/WebConfig.java @@ -24,7 +24,14 @@ public void addInterceptors(final InterceptorRegistry registry) { registry.addInterceptor(new MemberLoginInterceptor()) .order(1) .addPathPatterns("/api/**") - .excludePathPatterns("/api/login", "/api/certification/**"); + .excludePathPatterns( + "/api/login", + "/api/certification/**", + "/api/moims/detail", + "/api/sign-up", + "/api/universities", + "/api/universities/departments/**" + ); } @Override diff --git a/backend/src/main/java/moim_today/global/constant/DepartmentConstant.java b/backend/src/main/java/moim_today/global/constant/DepartmentConstant.java new file mode 100644 index 00000000..bf413482 --- /dev/null +++ b/backend/src/main/java/moim_today/global/constant/DepartmentConstant.java @@ -0,0 +1,19 @@ +package moim_today.global.constant; + +public enum DepartmentConstant { + DEPARTMENT_UPDATE_BATCH_SIZE("1000"); + + private final String value; + + DepartmentConstant(final String value) { + this.value = value; + } + + public String value(){ + return value; + } + + public int intValue(){ + return Integer.parseInt(value); + } +} diff --git a/backend/src/main/java/moim_today/global/constant/MoimConstant.java b/backend/src/main/java/moim_today/global/constant/MoimConstant.java new file mode 100644 index 00000000..2cc4947e --- /dev/null +++ b/backend/src/main/java/moim_today/global/constant/MoimConstant.java @@ -0,0 +1,17 @@ +package moim_today.global.constant; + +public enum MoimConstant { + + DEFAULT_MOIM_IMAGE_URL("https://anak2.s3.ap-northeast-2.amazonaws.com/moim/default-moim.jpg"), + DEFAULT_MOIM_PASSWORD("NONE"); + + private final String value; + + MoimConstant(final String value) { + this.value = value; + } + + public String value() { + return value; + } +} diff --git a/backend/src/main/java/moim_today/global/constant/NumberConstant.java b/backend/src/main/java/moim_today/global/constant/NumberConstant.java index 66d2e535..16933000 100644 --- a/backend/src/main/java/moim_today/global/constant/NumberConstant.java +++ b/backend/src/main/java/moim_today/global/constant/NumberConstant.java @@ -8,6 +8,9 @@ public enum NumberConstant { SLASH_CNT_START(0), MAX_SLASH_CNT(2), + DEFAULT_MOIM_CURRENT_COUNT(1), + DEFAULT_MOIM_VIEWS(0), + SCHEDULE_MEETING_ID(0), TIME_TABLE_SCHEDULING_COUNT(10), diff --git a/backend/src/main/java/moim_today/global/constant/UniversityConstant.java b/backend/src/main/java/moim_today/global/constant/UniversityConstant.java index 9ba5b442..5ce8d70a 100644 --- a/backend/src/main/java/moim_today/global/constant/UniversityConstant.java +++ b/backend/src/main/java/moim_today/global/constant/UniversityConstant.java @@ -2,6 +2,10 @@ public enum UniversityConstant { + UNIVERSITY_NAME("university_name"), + UNIVERSITY_EMAIL("university_email"), + UNIVERSITY_ID("university_id"), + ASSOCIATE_DEGREE("전문대학"), GRADUATE_DEGREE("대학교"), DATA_SEARCH("dataSearch"), diff --git a/backend/src/main/java/moim_today/global/constant/exception/MoimExceptionConstant.java b/backend/src/main/java/moim_today/global/constant/exception/MoimExceptionConstant.java new file mode 100644 index 00000000..b3054bec --- /dev/null +++ b/backend/src/main/java/moim_today/global/constant/exception/MoimExceptionConstant.java @@ -0,0 +1,17 @@ +package moim_today.global.constant.exception; + +public enum MoimExceptionConstant { + + MOIM_NOT_FOUND_ERROR("존재하지 않거나 삭제된 모임입니다."), + MOIM_FORBIDDEN("해당 모임에 대한 접근 권한이 없습니다."); + + private final String message; + + MoimExceptionConstant(final String message) { + this.message = message; + } + + public String message() { + return message; + } +} diff --git a/backend/src/main/java/moim_today/global/constant/exception/ScheduleExceptionConstant.java b/backend/src/main/java/moim_today/global/constant/exception/ScheduleExceptionConstant.java new file mode 100644 index 00000000..f3b0d8b5 --- /dev/null +++ b/backend/src/main/java/moim_today/global/constant/exception/ScheduleExceptionConstant.java @@ -0,0 +1,18 @@ +package moim_today.global.constant.exception; + +public enum ScheduleExceptionConstant { + + SCHEDULE_ALREADY_EXIST("해당 시간에 이미 스케줄이 존재합니다."), + SCHEDULE_FORBIDDEN("해당 스케줄에 대한 접근 권한이 없습니다."), + SCHEDULE_NOT_FOUND("해당 스케줄을 찾을 수 없습니다."); + + private final String message; + + ScheduleExceptionConstant(final String message) { + this.message = message; + } + + public String message() { + return message; + } +} diff --git a/backend/src/main/java/moim_today/implement/department/DepartmentAppender.java b/backend/src/main/java/moim_today/implement/department/DepartmentAppender.java index 3a9f4702..c5c0e075 100644 --- a/backend/src/main/java/moim_today/implement/department/DepartmentAppender.java +++ b/backend/src/main/java/moim_today/implement/department/DepartmentAppender.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import moim_today.domain.department.Department; import moim_today.global.annotation.Implement; import moim_today.global.error.InternalServerException; import moim_today.implement.university.UniversityFinder; @@ -13,10 +14,9 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.client.RestTemplate; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; +import java.util.*; +import static moim_today.global.constant.DepartmentConstant.DEPARTMENT_UPDATE_BATCH_SIZE; import static moim_today.global.constant.UniversityConstant.*; import static moim_today.global.constant.exception.CrawlingExceptionConstant.CRAWLING_PARSE_ERROR; @@ -39,40 +39,81 @@ public DepartmentAppender(final RestTemplate restTemplate, final ObjectMapper ob @Value("${university.api.key}") private String apiKey; - @Transactional - public void putAllDepartment(){ - List allDepartment = fetchAllDepartment(); - for(String eachDepartment : allDepartment){ - fetchUniversitiesByDepartment(eachDepartment); + public void putAllDepartment() { + List allMajor = findAllMajor(); + Map> departmentUpdateQueue = new HashMap<>(); + + for (String eachMajor : allMajor) { + patchMapAll(departmentUpdateQueue, getDepartments(eachMajor)); + updateDepartmentsIfSizeOver(departmentUpdateQueue, DEPARTMENT_UPDATE_BATCH_SIZE.intValue()); } + batchUpdate(getDepartmentJpaEntities(departmentUpdateQueue)); } @Transactional - public List fetchAllDepartment(){ - String url = UNIVERSITY_API_URL.value()+apiKey+FETCH_ALL_DEPARTMENT_URL.value(); + public void batchUpdate(final List departmentJpaEntities) { + departmentRepository.batchUpdate(departmentJpaEntities); + } + + public void updateDepartmentsIfSizeOver(final Map> universityAndDepartments, final int size){ + if(getTotalMapSize(universityAndDepartments) > size){ + batchUpdate(getDepartmentJpaEntities(universityAndDepartments)); + universityAndDepartments.clear(); + } + } + + private int getTotalMapSize(final Map> mapWithSet){ + int totalSize = 0; + for(Map.Entry> entry : mapWithSet.entrySet()){ + totalSize += entry.getValue().size(); + } + return totalSize; + } + + private List getDepartmentJpaEntities(final Map> universityAndDepartments) { + Map> universityIdAndDepartments = filterExistingUniversity(universityAndDepartments); + List departmentJpaEntities = Department.toEntities(universityIdAndDepartments); + return departmentJpaEntities; + } + + private Map> getDepartments(final String eachMajor) { + Map> universityAndDepartments = getDepartmentsOfUniversity(eachMajor); + return universityAndDepartments; + } + + private Map> filterExistingUniversity(final Map> universityAndDepartments) { + List universityJpaEntities = universityFinder + .findUniversitiesByName(universityAndDepartments.keySet().stream().toList()); + + return Department.convertToUnivIdAndDepartments(universityAndDepartments, universityJpaEntities); + } + + private List findAllMajor() { + String url = UNIVERSITY_API_URL.value() + apiKey + FETCH_ALL_DEPARTMENT_URL.value(); String response = restTemplate.getForObject(url, String.class); List allMajor = new ArrayList<>(); - try{ + try { JsonNode root = objectMapper.readTree(response); JsonNode content = root.path(DATA_SEARCH.value()).path(CONTENT.value()); - for(JsonNode item : content){ + for (JsonNode item : content) { String majorSeq = item.get(MAJOR_SEQ.value()).asText(); allMajor.add(majorSeq); } return allMajor; - }catch(JsonProcessingException e){ + } catch (JsonProcessingException e) { throw new InternalServerException(CRAWLING_PARSE_ERROR.message()); } } - @Transactional - public void fetchUniversitiesByDepartment(final String majorSeq){ - String url = UNIVERSITY_API_URL.value()+apiKey+FETCH_ALL_UNIVERSITY_BY_DEPARTMENT_URL.value()+majorSeq; + private Map> getDepartmentsOfUniversity(final String majorSeq) { + String url = UNIVERSITY_API_URL.value() + apiKey + FETCH_ALL_UNIVERSITY_BY_DEPARTMENT_URL.value() + majorSeq; String response = restTemplate.getForObject(url, String.class); + Map> universityAndDepartments = new HashMap<>(); + try { JsonNode root = objectMapper.readTree(response); JsonNode content = root.path(DATA_SEARCH.value()).path(CONTENT.value()); @@ -81,25 +122,28 @@ public void fetchUniversitiesByDepartment(final String majorSeq){ JsonNode universities = item.path(UNIVERSITY.value()); for (JsonNode university : universities) { String departmentName = university.path(MAJOR_NAME.value()).asText(); - String schoolName = university.path(SCHOOL_NAME.value()).asText(); + String universityName = university.path(SCHOOL_NAME.value()).asText(); - Optional universityJpaEntity = universityFinder.findByName(schoolName); - if(universityJpaEntity.isPresent()){ - saveDepartment(universityJpaEntity.get(), departmentName); - } + patchMap(universityAndDepartments, universityName, departmentName); } } - }catch (JsonProcessingException e){ + } catch (JsonProcessingException e) { throw new InternalServerException(CRAWLING_PARSE_ERROR.message()); } + + return universityAndDepartments; } - @Transactional - public void saveDepartment(UniversityJpaEntity universityJpaEntity, String departmentName){ - DepartmentJpaEntity saveDepartment = DepartmentJpaEntity.builder() - .universityId(universityJpaEntity.getId()) - .departmentName(departmentName) - .build(); - departmentRepository.save(saveDepartment); + private void patchMap(final Map> universityAndDepartments, final String universityName, final String departmentName) { + Set departments = universityAndDepartments + .computeIfAbsent(universityName, k -> new HashSet<>()); + departments.add(departmentName); + } + + private void patchMapAll(final Map> baseMap, + final Map> addingMap){ + for (Map.Entry> entry : addingMap.entrySet()) { + baseMap.computeIfAbsent(entry.getKey(), k -> new HashSet<>()).addAll(entry.getValue()); + } } } diff --git a/backend/src/main/java/moim_today/implement/file/FileUploader.java b/backend/src/main/java/moim_today/implement/file/FileUploader.java index d0f54bce..714697d6 100644 --- a/backend/src/main/java/moim_today/implement/file/FileUploader.java +++ b/backend/src/main/java/moim_today/implement/file/FileUploader.java @@ -32,7 +32,7 @@ public FileUploader(final AmazonS3 amazonS3) { this.amazonS3 = amazonS3; } - public FileInfoResponse uploadFile(final String fileType, final MultipartFile multipartFile) { + public String uploadFile(final String fileType, final MultipartFile multipartFile) { String uploadFolder = fileType; @@ -49,7 +49,7 @@ public FileInfoResponse uploadFile(final String fileType, final MultipartFile mu new PutObjectRequest(bucketName, keyName, inputStream, objectMetadata) .withCannedAcl(CannedAccessControlList.PublicRead)); // TODO: 데이터베이스에 대학 ID와 학번 ID를 key 값으로, uploadFileName 을 Value 값으로 저장하기 - return new FileInfoResponse(amazonS3.getUrl(bucketName, keyName).toString()); + return amazonS3.getUrl(bucketName, keyName).toString(); } catch (IOException e) { log.error("Exception [Err_Location]: {}", e.getStackTrace()[0]); throw new InternalServerException(FILE_UPLOAD_ERROR.message()); diff --git a/backend/src/main/java/moim_today/implement/member/AuthManager.java b/backend/src/main/java/moim_today/implement/member/AuthManager.java index 57295129..9dff87bd 100644 --- a/backend/src/main/java/moim_today/implement/member/AuthManager.java +++ b/backend/src/main/java/moim_today/implement/member/AuthManager.java @@ -50,7 +50,7 @@ public void logout(final HttpServletRequest request) { } } - public void register(final MemberRegisterRequest memberRegisterRequest, final HttpServletRequest request) { + public void signUp(final MemberRegisterRequest memberRegisterRequest, final HttpServletRequest request) { String encodedPassword = passwordEncode(memberRegisterRequest.password()); MemberJpaEntity saveMember = memberRepository.save(memberRegisterRequest.toEntity(encodedPassword)); setSessionByMemberSession(saveMember, request); diff --git a/backend/src/main/java/moim_today/implement/moim/MoimAppender.java b/backend/src/main/java/moim_today/implement/moim/MoimAppender.java new file mode 100644 index 00000000..af35a76d --- /dev/null +++ b/backend/src/main/java/moim_today/implement/moim/MoimAppender.java @@ -0,0 +1,33 @@ +package moim_today.implement.moim; + +import moim_today.dto.moim.PrivateMoimAppendRequest; +import moim_today.dto.moim.PublicMoimAppendRequest; +import moim_today.global.annotation.Implement; +import moim_today.persistence.entity.moim.moim.MoimJpaEntity; +import moim_today.persistence.repository.moim.moim.MoimRepository; +import org.springframework.transaction.annotation.Transactional; + +@Implement +public class MoimAppender { + + private final MoimRepository moimRepository; + + public MoimAppender(final MoimRepository moimRepository) { + this.moimRepository = moimRepository; + } + + @Transactional + public MoimJpaEntity createPublicMoim(final long memberId, final long universityId, + final PublicMoimAppendRequest publicMoimAppendRequest) { + + MoimJpaEntity moimJpaEntity = publicMoimAppendRequest.toEntity(memberId, universityId); + return moimRepository.save(moimJpaEntity); + } + + @Transactional + public MoimJpaEntity createPrivateMoim(final long memberId, final long universityId, + final PrivateMoimAppendRequest privateMoimAppendRequest) { + MoimJpaEntity moimJpaEntity = privateMoimAppendRequest.toEntity(memberId, universityId); + return moimRepository.save(moimJpaEntity); + } +} diff --git a/backend/src/main/java/moim_today/implement/moim/MoimFinder.java b/backend/src/main/java/moim_today/implement/moim/MoimFinder.java new file mode 100644 index 00000000..29231055 --- /dev/null +++ b/backend/src/main/java/moim_today/implement/moim/MoimFinder.java @@ -0,0 +1,21 @@ +package moim_today.implement.moim; + +import moim_today.global.annotation.Implement; +import moim_today.persistence.entity.moim.moim.MoimJpaEntity; +import moim_today.persistence.repository.moim.moim.MoimRepository; +import org.springframework.transaction.annotation.Transactional; + +@Implement +public class MoimFinder { + + private final MoimRepository moimRepository; + + public MoimFinder(final MoimRepository moimRepository) { + this.moimRepository = moimRepository; + } + + @Transactional(readOnly = true) + public MoimJpaEntity getById(final long moimId) { + return moimRepository.getById(moimId); + } +} diff --git a/backend/src/main/java/moim_today/implement/moim/MoimUpdater.java b/backend/src/main/java/moim_today/implement/moim/MoimUpdater.java new file mode 100644 index 00000000..571ecff4 --- /dev/null +++ b/backend/src/main/java/moim_today/implement/moim/MoimUpdater.java @@ -0,0 +1,24 @@ +package moim_today.implement.moim; + +import moim_today.dto.moim.MoimUpdateRequest; +import moim_today.global.annotation.Implement; +import moim_today.persistence.entity.moim.moim.MoimJpaEntity; +import moim_today.persistence.repository.moim.moim.MoimRepository; +import org.springframework.transaction.annotation.Transactional; + +@Implement +public class MoimUpdater { + + private final MoimRepository moimRepository; + + public MoimUpdater(final MoimRepository moimRepository) { + this.moimRepository = moimRepository; + } + + @Transactional + public void updateMoim(final long memberId, final MoimUpdateRequest moimUpdateRequest) { + MoimJpaEntity moimJpaEntity = moimRepository.getById(moimUpdateRequest.moimId()); + moimJpaEntity.validateMember(memberId); + moimJpaEntity.updateMoim(moimUpdateRequest); + } +} diff --git a/backend/src/main/java/moim_today/implement/schedule/ScheduleAppender.java b/backend/src/main/java/moim_today/implement/schedule/ScheduleAppender.java index 8066866e..b0f9358b 100644 --- a/backend/src/main/java/moim_today/implement/schedule/ScheduleAppender.java +++ b/backend/src/main/java/moim_today/implement/schedule/ScheduleAppender.java @@ -3,11 +3,15 @@ import moim_today.domain.schedule.Schedule; import moim_today.dto.schedule.TimeTableSchedulingTask; import moim_today.global.annotation.Implement; +import moim_today.global.error.BadRequestException; +import moim_today.persistence.entity.schedule.ScheduleJpaEntity; import moim_today.persistence.repository.schedule.ScheduleRepository; import org.springframework.transaction.annotation.Transactional; import java.util.List; +import static moim_today.global.constant.exception.ScheduleExceptionConstant.SCHEDULE_ALREADY_EXIST; + @Implement public class ScheduleAppender { @@ -23,4 +27,16 @@ public void batchUpdateSchedules(final List schedules, final long memb TimeTableSchedulingTask timeTableSchedulingTask = TimeTableSchedulingTask.of(schedules, memberId); scheduleRepository.batchUpdate(timeTableSchedulingTask); } -} + + @Transactional + public void createSchedule(final ScheduleJpaEntity scheduleJpaEntity) { + validateAlreadyExist(scheduleJpaEntity); + scheduleRepository.save(scheduleJpaEntity); + } + + private void validateAlreadyExist(final ScheduleJpaEntity scheduleJpaEntity) { + if (scheduleRepository.exists(scheduleJpaEntity)) { + throw new BadRequestException(SCHEDULE_ALREADY_EXIST.message()); + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/moim_today/implement/schedule/ScheduleDeleter.java b/backend/src/main/java/moim_today/implement/schedule/ScheduleDeleter.java new file mode 100644 index 00000000..5a1f177c --- /dev/null +++ b/backend/src/main/java/moim_today/implement/schedule/ScheduleDeleter.java @@ -0,0 +1,23 @@ +package moim_today.implement.schedule; + +import moim_today.global.annotation.Implement; +import moim_today.persistence.entity.schedule.ScheduleJpaEntity; +import moim_today.persistence.repository.schedule.ScheduleRepository; +import org.springframework.transaction.annotation.Transactional; + +@Implement +public class ScheduleDeleter { + + private final ScheduleRepository scheduleRepository; + + public ScheduleDeleter(final ScheduleRepository scheduleRepository) { + this.scheduleRepository = scheduleRepository; + } + + @Transactional + public void deleteSchedule(final long memberId, final long scheduleId) { + ScheduleJpaEntity scheduleJpaEntity = scheduleRepository.getById(scheduleId); + scheduleJpaEntity.validateMember(memberId); + scheduleRepository.delete(scheduleJpaEntity); + } +} diff --git a/backend/src/main/java/moim_today/implement/schedule/ScheduleUpdater.java b/backend/src/main/java/moim_today/implement/schedule/ScheduleUpdater.java new file mode 100644 index 00000000..10acf4e1 --- /dev/null +++ b/backend/src/main/java/moim_today/implement/schedule/ScheduleUpdater.java @@ -0,0 +1,36 @@ +package moim_today.implement.schedule; + +import moim_today.dto.schedule.ScheduleUpdateRequest; +import moim_today.global.annotation.Implement; +import moim_today.global.error.BadRequestException; +import moim_today.persistence.entity.schedule.ScheduleJpaEntity; +import moim_today.persistence.repository.schedule.ScheduleRepository; +import org.springframework.transaction.annotation.Transactional; + + +import static moim_today.global.constant.exception.ScheduleExceptionConstant.SCHEDULE_ALREADY_EXIST; + +@Implement +public class ScheduleUpdater { + + private final ScheduleRepository scheduleRepository; + + public ScheduleUpdater(final ScheduleRepository scheduleRepository) { + this.scheduleRepository = scheduleRepository; + } + + @Transactional + public void updateSchedule(final long memberId, final ScheduleUpdateRequest scheduleUpdateRequest) { + ScheduleJpaEntity scheduleJpaEntity = scheduleRepository.getById(scheduleUpdateRequest.scheduleId()); + scheduleJpaEntity.validateMember(memberId); + validateAlreadyExist(scheduleJpaEntity.getId(), memberId, scheduleUpdateRequest); + + scheduleJpaEntity.updateSchedule(scheduleUpdateRequest); + } + + private void validateAlreadyExist(final long scheduleId, final long memberId, final ScheduleUpdateRequest scheduleUpdateRequest) { + if (scheduleRepository.existsExcludeEntity(scheduleId, memberId, scheduleUpdateRequest)) { + throw new BadRequestException(SCHEDULE_ALREADY_EXIST.message()); + } + } +} diff --git a/backend/src/main/java/moim_today/implement/university/UniversityAppender.java b/backend/src/main/java/moim_today/implement/university/UniversityAppender.java index 13cbe6f9..aaa8729c 100644 --- a/backend/src/main/java/moim_today/implement/university/UniversityAppender.java +++ b/backend/src/main/java/moim_today/implement/university/UniversityAppender.java @@ -1,54 +1,15 @@ package moim_today.implement.university; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import moim_today.domain.university.ExtractUniversity; import moim_today.global.annotation.Implement; -import moim_today.global.error.InternalServerException; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.client.RestTemplate; -import static moim_today.global.constant.UniversityConstant.*; -import static moim_today.global.constant.exception.CrawlingExceptionConstant.CRAWLING_PARSE_ERROR; - @Implement public class UniversityAppender { - private final RestTemplate restTemplate; - private final ObjectMapper objectMapper; private final UniversityUpdater universityUpdater; - @Value("${university.api.key}") - private String apiKey; - public UniversityAppender(final RestTemplate restTemplate, final ObjectMapper objectMapper, final UniversityUpdater universityUpdater) { - this.restTemplate = restTemplate; - this.objectMapper = objectMapper; this.universityUpdater = universityUpdater; } - - @Transactional - public void fetchAllUniversity(){ - String url = UNIVERSITY_API_URL.value()+apiKey+FETCH_ALL_UNIVERSITY_URL.value(); - String response = restTemplate.getForObject(url, String.class); - - try{ - JsonNode root = objectMapper.readTree(response); - JsonNode content = root.path(DATA_SEARCH.value()).path(CONTENT.value()); - - for (JsonNode item : content) { - ExtractUniversity extractUniversity = objectMapper.readValue(item.toPrettyString(), ExtractUniversity.class); - if(!extractUniversity.checkUniversityType()){ - continue; - } - extractUniversity.extractEmailExtension(); - universityUpdater.putUniversity(extractUniversity.toEntity()); - } - } catch (JsonProcessingException e){ - e.printStackTrace(); - throw new InternalServerException(CRAWLING_PARSE_ERROR.message()); - } - } } diff --git a/backend/src/main/java/moim_today/implement/university/UniversityFinder.java b/backend/src/main/java/moim_today/implement/university/UniversityFinder.java index 21a476af..9594e52f 100644 --- a/backend/src/main/java/moim_today/implement/university/UniversityFinder.java +++ b/backend/src/main/java/moim_today/implement/university/UniversityFinder.java @@ -41,7 +41,7 @@ public UniversityJpaEntity getByUniversityEmail(final String emailDomain) { @Transactional(readOnly = true) public void validateExists(final String emailDomain) { - if (!universityRepository.existsByUniversityEmail(emailDomain)) { + if (!universityRepository.validateUniversityEmail(emailDomain)) { throw new NotFoundException(UNIVERSITY_EMAIL_NOT_FOUND.message()); } } @@ -51,4 +51,9 @@ public boolean checkUniversityIdIsPresent(final long universityId){ Optional findUniversity = universityRepository.findById(universityId); return findUniversity.isPresent(); } + + @Transactional(readOnly = true) + public List findUniversitiesByName(final List universityNames) { + return universityRepository.findExistingUniversities(universityNames); + } } diff --git a/backend/src/main/java/moim_today/implement/university/UniversityUpdater.java b/backend/src/main/java/moim_today/implement/university/UniversityUpdater.java index 9564f28f..f0599165 100644 --- a/backend/src/main/java/moim_today/implement/university/UniversityUpdater.java +++ b/backend/src/main/java/moim_today/implement/university/UniversityUpdater.java @@ -1,19 +1,60 @@ package moim_today.implement.university; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import moim_today.domain.university.ExtractUniversity; import moim_today.global.annotation.Implement; +import moim_today.global.error.InternalServerException; import moim_today.persistence.entity.university.UniversityJpaEntity; import moim_today.persistence.repository.university.UniversityRepository; +import org.springframework.beans.factory.annotation.Value; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.client.RestTemplate; import java.util.Optional; +import static moim_today.global.constant.UniversityConstant.*; +import static moim_today.global.constant.exception.CrawlingExceptionConstant.CRAWLING_PARSE_ERROR; + @Implement public class UniversityUpdater { private final UniversityRepository universityRepository; + private final ObjectMapper objectMapper; + private final RestTemplate restTemplate; + + @Value("${university.api.key}") + private String apiKey; - public UniversityUpdater(final UniversityRepository universityRepository) { + public UniversityUpdater(final UniversityRepository universityRepository, + ObjectMapper objectMapper, RestTemplate restTemplate) { this.universityRepository = universityRepository; + this.objectMapper = objectMapper; + this.restTemplate = restTemplate; + } + + @Transactional + public void fetchAllUniversity() { + String url = UNIVERSITY_API_URL.value() + apiKey + FETCH_ALL_UNIVERSITY_URL.value(); + String response = restTemplate.getForObject(url, String.class); + + try { + JsonNode root = objectMapper.readTree(response); + JsonNode content = root.path(DATA_SEARCH.value()).path(CONTENT.value()); + + for (JsonNode item : content) { + ExtractUniversity extractUniversity = objectMapper.readValue(item.toPrettyString(), ExtractUniversity.class); + if (!extractUniversity.checkUniversityType()) { + continue; + } + extractUniversity.extractEmailExtension(); + putUniversity(extractUniversity.toEntity()); + } + } catch (JsonProcessingException e) { + e.printStackTrace(); + throw new InternalServerException(CRAWLING_PARSE_ERROR.message()); + } } @Transactional diff --git a/backend/src/main/java/moim_today/persistence/entity/moim/moim/MoimJpaEntity.java b/backend/src/main/java/moim_today/persistence/entity/moim/moim/MoimJpaEntity.java index ed20047b..83737046 100644 --- a/backend/src/main/java/moim_today/persistence/entity/moim/moim/MoimJpaEntity.java +++ b/backend/src/main/java/moim_today/persistence/entity/moim/moim/MoimJpaEntity.java @@ -1,14 +1,21 @@ package moim_today.persistence.entity.moim.moim; -import moim_today.domain.moim.enums.MoimCategory; -import moim_today.global.annotation.Association; -import moim_today.global.base_entity.BaseTimeEntity; import jakarta.persistence.*; import lombok.Builder; import lombok.Getter; +import moim_today.domain.moim.DisplayStatus; +import moim_today.domain.moim.enums.MoimCategory; +import moim_today.dto.moim.MoimUpdateRequest; +import moim_today.global.annotation.Association; +import moim_today.global.base_entity.BaseTimeEntity; +import moim_today.global.error.ForbiddenException; import java.time.LocalDate; +import static moim_today.global.constant.MoimConstant.DEFAULT_MOIM_IMAGE_URL; +import static moim_today.global.constant.MoimConstant.DEFAULT_MOIM_PASSWORD; +import static moim_today.global.constant.exception.MoimExceptionConstant.MOIM_FORBIDDEN; + @Getter @Table(name = "moim") @Entity @@ -39,11 +46,14 @@ public class MoimJpaEntity extends BaseTimeEntity { @Enumerated(EnumType.STRING) private MoimCategory moimCategory; + @Enumerated(EnumType.STRING) + private DisplayStatus displayStatus; + private int views; - private LocalDate startDateTime; + private LocalDate startDate; - private LocalDate endDateTime; + private LocalDate endDate; protected MoimJpaEntity() { } @@ -52,7 +62,8 @@ protected MoimJpaEntity() { private MoimJpaEntity(final long universityId, final long memberId, final String title, final String contents, final int capacity, final int currentCount, final String imageUrl, final String password, final MoimCategory moimCategory, - final int views, final LocalDate startDateTime, final LocalDate endDateTime) { + final DisplayStatus displayStatus, final int views, + final LocalDate startDate, final LocalDate endDate) { this.universityId = universityId; this.memberId = memberId; this.title = title; @@ -62,8 +73,46 @@ private MoimJpaEntity(final long universityId, final long memberId, final String this.imageUrl = imageUrl; this.password = password; this.moimCategory = moimCategory; + this.displayStatus = displayStatus; this.views = views; - this.startDateTime = startDateTime; - this.endDateTime = endDateTime; + this.startDate = startDate; + this.endDate = endDate; + } + + public void validateMember(final long memberId) { + if (this.memberId != memberId) { + throw new ForbiddenException(MOIM_FORBIDDEN.message()); + } + } + + public void updateMoim(final MoimUpdateRequest moimUpdateRequest) { + this.title = moimUpdateRequest.title(); + this.contents = moimUpdateRequest.contents(); + this.capacity = moimUpdateRequest.capacity(); + this.moimCategory = moimUpdateRequest.moimCategory(); + this.startDate = moimUpdateRequest.startDate(); + this.endDate = moimUpdateRequest.endDate(); + this.displayStatus = moimUpdateRequest.displayStatus(); + + updatePasswordByDisplayStatus(moimUpdateRequest.password()); + updateImageUrl(moimUpdateRequest.imageUrl()); + } + + private void updateImageUrl(final String updateImageUrl) { + if (updateImageUrl == null) { + this.imageUrl = DEFAULT_MOIM_IMAGE_URL.value(); + } else { + this.imageUrl = updateImageUrl; + } + } + + private void updatePasswordByDisplayStatus(final String updatePassword) { + if (displayStatus.equals(DisplayStatus.PUBLIC)) { + this.password = DEFAULT_MOIM_PASSWORD.value(); + } else { + if (updatePassword != null) { + this.password = updatePassword; + } + } } } diff --git a/backend/src/main/java/moim_today/persistence/entity/schedule/ScheduleJpaEntity.java b/backend/src/main/java/moim_today/persistence/entity/schedule/ScheduleJpaEntity.java index fa507e1c..e8fdfe30 100644 --- a/backend/src/main/java/moim_today/persistence/entity/schedule/ScheduleJpaEntity.java +++ b/backend/src/main/java/moim_today/persistence/entity/schedule/ScheduleJpaEntity.java @@ -1,14 +1,18 @@ package moim_today.persistence.entity.schedule; +import moim_today.dto.schedule.ScheduleUpdateRequest; import moim_today.global.annotation.Association; import moim_today.global.base_entity.BaseTimeEntity; import jakarta.persistence.*; import lombok.Builder; import lombok.Getter; +import moim_today.global.error.ForbiddenException; import java.time.DayOfWeek; import java.time.LocalDateTime; +import static moim_today.global.constant.exception.ScheduleExceptionConstant.SCHEDULE_FORBIDDEN; + @Getter @Table(name = "schedule") @Entity @@ -47,4 +51,17 @@ private ScheduleJpaEntity(final long memberId, final long meetingId, final Strin this.startDateTime = startDateTime; this.endDateTime = endDateTime; } + + public void updateSchedule(final ScheduleUpdateRequest scheduleUpdateRequest) { + this.scheduleName = scheduleUpdateRequest.scheduleName(); + this.dayOfWeek = scheduleUpdateRequest.dayOfWeek(); + this.startDateTime = scheduleUpdateRequest.startDateTime(); + this.endDateTime = scheduleUpdateRequest.endDateTime(); + } + + public void validateMember(final long memberId) { + if (this.memberId != memberId) { + throw new ForbiddenException(SCHEDULE_FORBIDDEN.message()); + } + } } diff --git a/backend/src/main/java/moim_today/persistence/entity/university/UniversityJpaEntity.java b/backend/src/main/java/moim_today/persistence/entity/university/UniversityJpaEntity.java index a4110aa2..c1b1ce7b 100644 --- a/backend/src/main/java/moim_today/persistence/entity/university/UniversityJpaEntity.java +++ b/backend/src/main/java/moim_today/persistence/entity/university/UniversityJpaEntity.java @@ -22,7 +22,8 @@ protected UniversityJpaEntity() { } @Builder - public UniversityJpaEntity(final String universityName, final String universityEmail) { + public UniversityJpaEntity(long id, final String universityName, final String universityEmail) { + this.id = id; this.universityName = universityName; this.universityEmail = universityEmail; } diff --git a/backend/src/main/java/moim_today/persistence/repository/department/DepartmentRepository.java b/backend/src/main/java/moim_today/persistence/repository/department/DepartmentRepository.java index 1ee1024e..c59f15a9 100644 --- a/backend/src/main/java/moim_today/persistence/repository/department/DepartmentRepository.java +++ b/backend/src/main/java/moim_today/persistence/repository/department/DepartmentRepository.java @@ -12,4 +12,6 @@ public interface DepartmentRepository { DepartmentJpaEntity getById(final long departmentId); List findAllDepartmentOfUniversity(final long universityId); + + void batchUpdate(List departmentJpaEntities); } diff --git a/backend/src/main/java/moim_today/persistence/repository/department/DepartmentRepositoryImpl.java b/backend/src/main/java/moim_today/persistence/repository/department/DepartmentRepositoryImpl.java index b8e2701c..8e83c9b1 100644 --- a/backend/src/main/java/moim_today/persistence/repository/department/DepartmentRepositoryImpl.java +++ b/backend/src/main/java/moim_today/persistence/repository/department/DepartmentRepositoryImpl.java @@ -3,8 +3,12 @@ import moim_today.dto.department.DepartmentInfoResponse; import moim_today.global.error.NotFoundException; import moim_today.persistence.entity.department.DepartmentJpaEntity; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; +import java.sql.PreparedStatement; +import java.sql.SQLException; import java.util.List; import static moim_today.global.constant.exception.DepartmentExceptionConstant.DEPARTMENT_NOT_FOUND_ERROR; @@ -13,9 +17,11 @@ public class DepartmentRepositoryImpl implements DepartmentRepository { private final DepartmentJpaRepository departmentJpaRepository; + private final JdbcTemplate jdbcTemplate; - public DepartmentRepositoryImpl(final DepartmentJpaRepository departmentJpaRepository) { + public DepartmentRepositoryImpl(final DepartmentJpaRepository departmentJpaRepository, JdbcTemplate jdbcTemplate) { this.departmentJpaRepository = departmentJpaRepository; + this.jdbcTemplate = jdbcTemplate; } @Override @@ -30,6 +36,26 @@ public List findAllDepartmentOfUniversity(final long uni .toList(); } + @Override + public void batchUpdate(final List departmentJpaEntities) { + String sql = "INSERT INTO department (university_id, department_name) VALUES (?, ?)"; + + this.jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { + + @Override + public void setValues(PreparedStatement ps, int i) throws SQLException { + DepartmentJpaEntity department = departmentJpaEntities.get(i); + ps.setLong(1, department.getUniversityId()); + ps.setString(2, department.getDepartmentName()); + } + + @Override + public int getBatchSize() { + return departmentJpaEntities.size(); + } + }); + } + @Override public DepartmentJpaEntity getById(final long departmentId) { return departmentJpaRepository.findById(departmentId) diff --git a/backend/src/main/java/moim_today/persistence/repository/moim/moim/MoimRepository.java b/backend/src/main/java/moim_today/persistence/repository/moim/moim/MoimRepository.java index ddfa0bc3..20db69f0 100644 --- a/backend/src/main/java/moim_today/persistence/repository/moim/moim/MoimRepository.java +++ b/backend/src/main/java/moim_today/persistence/repository/moim/moim/MoimRepository.java @@ -1,4 +1,12 @@ package moim_today.persistence.repository.moim.moim; +import moim_today.persistence.entity.moim.moim.MoimJpaEntity; + public interface MoimRepository { + + MoimJpaEntity save(final MoimJpaEntity moimJpaEntity); + + long count(); + + MoimJpaEntity getById(final long moimId); } diff --git a/backend/src/main/java/moim_today/persistence/repository/moim/moim/MoimRepositoryImpl.java b/backend/src/main/java/moim_today/persistence/repository/moim/moim/MoimRepositoryImpl.java index c7d43851..29bc755a 100644 --- a/backend/src/main/java/moim_today/persistence/repository/moim/moim/MoimRepositoryImpl.java +++ b/backend/src/main/java/moim_today/persistence/repository/moim/moim/MoimRepositoryImpl.java @@ -1,7 +1,11 @@ package moim_today.persistence.repository.moim.moim; +import moim_today.global.error.NotFoundException; +import moim_today.persistence.entity.moim.moim.MoimJpaEntity; import org.springframework.stereotype.Repository; +import static moim_today.global.constant.exception.MoimExceptionConstant.MOIM_NOT_FOUND_ERROR; + @Repository public class MoimRepositoryImpl implements MoimRepository { @@ -10,4 +14,20 @@ public class MoimRepositoryImpl implements MoimRepository { public MoimRepositoryImpl(final MoimJpaRepository moimJpaRepository) { this.moimJpaRepository = moimJpaRepository; } + + @Override + public MoimJpaEntity save(final MoimJpaEntity moimJpaEntity) { + return moimJpaRepository.save(moimJpaEntity); + } + + @Override + public long count() { + return moimJpaRepository.count(); + } + + @Override + public MoimJpaEntity getById(final long moimId) { + return moimJpaRepository.findById(moimId) + .orElseThrow(() -> new NotFoundException(MOIM_NOT_FOUND_ERROR.message())); + } } diff --git a/backend/src/main/java/moim_today/persistence/repository/schedule/ScheduleRepository.java b/backend/src/main/java/moim_today/persistence/repository/schedule/ScheduleRepository.java index 2dac4d34..dc95862a 100644 --- a/backend/src/main/java/moim_today/persistence/repository/schedule/ScheduleRepository.java +++ b/backend/src/main/java/moim_today/persistence/repository/schedule/ScheduleRepository.java @@ -1,13 +1,23 @@ package moim_today.persistence.repository.schedule; +import moim_today.dto.schedule.ScheduleUpdateRequest; import moim_today.dto.schedule.TimeTableSchedulingTask; import moim_today.persistence.entity.schedule.ScheduleJpaEntity; + public interface ScheduleRepository { + ScheduleJpaEntity getById(final long scheduleId); + void save(final ScheduleJpaEntity scheduleJpaEntity); void batchUpdate(final TimeTableSchedulingTask timeTableSchedulingTask); + boolean exists(final ScheduleJpaEntity scheduleJpaEntity); + + boolean existsExcludeEntity(final long scheduleId, final long memberId, final ScheduleUpdateRequest scheduleUpdateRequest); + + void delete(final ScheduleJpaEntity scheduleJpaEntity); + long count(); } diff --git a/backend/src/main/java/moim_today/persistence/repository/schedule/ScheduleRepositoryImpl.java b/backend/src/main/java/moim_today/persistence/repository/schedule/ScheduleRepositoryImpl.java index dd7a9040..1a08cf3b 100644 --- a/backend/src/main/java/moim_today/persistence/repository/schedule/ScheduleRepositoryImpl.java +++ b/backend/src/main/java/moim_today/persistence/repository/schedule/ScheduleRepositoryImpl.java @@ -1,7 +1,11 @@ package moim_today.persistence.repository.schedule; +import com.querydsl.jpa.impl.JPAQueryFactory; import moim_today.domain.schedule.Schedule; +import moim_today.dto.schedule.ScheduleUpdateRequest; import moim_today.dto.schedule.TimeTableSchedulingTask; +import moim_today.global.error.NotFoundException; +import moim_today.persistence.entity.schedule.QScheduleJpaEntity; import moim_today.persistence.entity.schedule.ScheduleJpaEntity; import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.JdbcTemplate; @@ -14,19 +18,31 @@ import java.util.List; import static moim_today.global.constant.NumberConstant.SCHEDULE_MEETING_ID; +import static moim_today.global.constant.exception.ScheduleExceptionConstant.*; +import static moim_today.persistence.entity.schedule.QScheduleJpaEntity.*; + @Repository public class ScheduleRepositoryImpl implements ScheduleRepository { private final ScheduleJpaRepository scheduleJpaRepository; + private final JPAQueryFactory queryFactory; private final JdbcTemplate jdbcTemplate; public ScheduleRepositoryImpl(final ScheduleJpaRepository scheduleJpaRepository, + final JPAQueryFactory queryFactory, final JdbcTemplate jdbcTemplate) { this.scheduleJpaRepository = scheduleJpaRepository; + this.queryFactory = queryFactory; this.jdbcTemplate = jdbcTemplate; } + @Override + public ScheduleJpaEntity getById(final long scheduleId) { + return scheduleJpaRepository.findById(scheduleId) + .orElseThrow(() -> new NotFoundException(SCHEDULE_NOT_FOUND.message())); + } + @Override public void save(final ScheduleJpaEntity scheduleJpaEntity) { scheduleJpaRepository.save(scheduleJpaEntity); @@ -64,6 +80,35 @@ public int getBatchSize() { }); } + @Override + public boolean exists(final ScheduleJpaEntity entity) { + return queryFactory.selectFrom(scheduleJpaEntity) + .where( + scheduleJpaEntity.memberId.eq(entity.getMemberId()) + .and(scheduleJpaEntity.startDateTime.before(entity.getEndDateTime())) + .and(scheduleJpaEntity.endDateTime.after(entity.getStartDateTime())) + ) + .fetchFirst() != null; + } + + @Override + public boolean existsExcludeEntity(final long scheduleId, final long memberId, final ScheduleUpdateRequest scheduleUpdateRequest) { + return queryFactory + .selectFrom(scheduleJpaEntity) + .where( + scheduleJpaEntity.memberId.eq(memberId) + .and(scheduleJpaEntity.id.ne(scheduleId)) + .and(scheduleJpaEntity.startDateTime.before(scheduleUpdateRequest.endDateTime()) + .and(scheduleJpaEntity.endDateTime.after(scheduleUpdateRequest.startDateTime()))) + ) + .fetchFirst() != null; + } + + @Override + public void delete(final ScheduleJpaEntity scheduleJpaEntity) { + scheduleJpaRepository.delete(scheduleJpaEntity); + } + @Override public long count() { return scheduleJpaRepository.count(); diff --git a/backend/src/main/java/moim_today/persistence/repository/university/UniversityRepository.java b/backend/src/main/java/moim_today/persistence/repository/university/UniversityRepository.java index 2938a318..800644bf 100644 --- a/backend/src/main/java/moim_today/persistence/repository/university/UniversityRepository.java +++ b/backend/src/main/java/moim_today/persistence/repository/university/UniversityRepository.java @@ -13,11 +13,13 @@ public interface UniversityRepository { UniversityJpaEntity getByEmail(final String email); - boolean existsByUniversityEmail(final String universityEmail); + boolean validateUniversityEmail(final String universityEmail); Optional findByName(final String name); Optional findById(final long id); List findAll(); + + List findExistingUniversities(List universityNames); } diff --git a/backend/src/main/java/moim_today/persistence/repository/university/UniversityRepositoryImpl.java b/backend/src/main/java/moim_today/persistence/repository/university/UniversityRepositoryImpl.java index 881304dd..aad594ae 100644 --- a/backend/src/main/java/moim_today/persistence/repository/university/UniversityRepositoryImpl.java +++ b/backend/src/main/java/moim_today/persistence/repository/university/UniversityRepositoryImpl.java @@ -2,11 +2,16 @@ import moim_today.global.error.NotFoundException; import moim_today.persistence.entity.university.UniversityJpaEntity; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; +import java.util.ArrayList; import java.util.List; import java.util.Optional; +import static java.util.Collections.nCopies; +import static moim_today.global.constant.UniversityConstant.*; import static moim_today.global.constant.exception.UniversityExceptionConstant.UNIVERSITY_EMAIL_NOT_FOUND; import static moim_today.global.constant.exception.UniversityExceptionConstant.UNIVERSITY_NOT_FOUND; @@ -14,9 +19,11 @@ public class UniversityRepositoryImpl implements UniversityRepository { private final UniversityJpaRepository universityJpaRepository; + private final JdbcTemplate jdbcTemplate; - public UniversityRepositoryImpl(final UniversityJpaRepository universityJpaRepository) { + public UniversityRepositoryImpl(final UniversityJpaRepository universityJpaRepository, JdbcTemplate jdbcTemplate) { this.universityJpaRepository = universityJpaRepository; + this.jdbcTemplate = jdbcTemplate; } @Override @@ -37,7 +44,7 @@ public UniversityJpaEntity getByEmail(final String email) { } @Override - public boolean existsByUniversityEmail(final String universityEmail) { + public boolean validateUniversityEmail(final String universityEmail) { return universityJpaRepository.existsByUniversityEmail(universityEmail); } @@ -51,8 +58,28 @@ public List findAll() { return universityJpaRepository.findAll(); } + @Override + public List findExistingUniversities(final List universityNames) { + if (universityNames == null || universityNames.isEmpty()) { + return new ArrayList<>(); + } + + String inSql = String.join(",", nCopies(universityNames.size(), "?")); + String sql = "SELECT * FROM university WHERE "+UNIVERSITY_NAME.value()+" IN (" + inSql + ")"; + + return jdbcTemplate.query(sql, universityNames.toArray(new Object[0]), universityJpaEntityRowMapper()); + } + @Override public Optional findById(final long id) { return universityJpaRepository.findById(id); } + + private RowMapper universityJpaEntityRowMapper() { + return (rs, rowNum) -> UniversityJpaEntity.builder() + .id(Long.parseLong(rs.getString(UNIVERSITY_ID.value()))) + .universityName(rs.getString(UNIVERSITY_NAME.value())) + .universityEmail(rs.getString(UNIVERSITY_EMAIL.value())) + .build(); + } } diff --git a/backend/src/main/java/moim_today/presentation/auth/AuthController.java b/backend/src/main/java/moim_today/presentation/auth/AuthController.java index b8f0ecb5..0cf87182 100644 --- a/backend/src/main/java/moim_today/presentation/auth/AuthController.java +++ b/backend/src/main/java/moim_today/presentation/auth/AuthController.java @@ -33,9 +33,9 @@ public void logout(@Login final MemberSession memberSession, final HttpServletRe authService.logout(request); } - @PostMapping("/register") - public void register(@Valid @RequestBody final MemberRegisterRequest memberRegisterRequest, - final HttpServletRequest request){ - authService.register(memberRegisterRequest, request); + @PostMapping("/sign-up") + public void signUp(@Valid @RequestBody final MemberRegisterRequest memberRegisterRequest, + final HttpServletRequest request){ + authService.signUp(memberRegisterRequest, request); } } diff --git a/backend/src/main/java/moim_today/presentation/moim/MoimController.java b/backend/src/main/java/moim_today/presentation/moim/MoimController.java new file mode 100644 index 00000000..67453e0b --- /dev/null +++ b/backend/src/main/java/moim_today/presentation/moim/MoimController.java @@ -0,0 +1,48 @@ +package moim_today.presentation.moim; + +import moim_today.application.moim.MoimService; +import moim_today.domain.member.MemberSession; +import moim_today.dto.moim.*; +import moim_today.global.annotation.Login; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +@RequestMapping("/api/moims") +@RestController +public class MoimController { + + private final MoimService moimService; + + public MoimController(final MoimService moimService) { + this.moimService = moimService; + } + + @PostMapping("/public") + public void createPubicMoim(@Login final MemberSession memberSession, + @RequestBody final PublicMoimAppendRequest publicMoimAppendRequest) { + moimService.createPublicMoim(memberSession.id(), memberSession.universityId(), publicMoimAppendRequest); + } + + @PostMapping("/private") + public void createPrivateMoim(@Login final MemberSession memberSession, + @RequestBody final PrivateMoimAppendRequest privateMoimAppendRequest) { + moimService.createPrivateMoim(memberSession.id(), memberSession.universityId(), privateMoimAppendRequest); + } + + @PostMapping("/image") + public UploadMoimImageResponse uploadMoimImage(@Login final MemberSession memberSession, + @RequestPart final MultipartFile file) { + return moimService.uploadMoimImage(file); + } + + @GetMapping("/detail") + public MoimDetailResponse getMoimDetail(@RequestParam final long moimId) { + return moimService.getMoimDetail(moimId); + } + + @PatchMapping + public void updateMoim(@Login final MemberSession memberSession, + @RequestBody final MoimUpdateRequest moimUpdateRequest) { + moimService.updateMoim(memberSession.id(), moimUpdateRequest); + } +} diff --git a/backend/src/main/java/moim_today/presentation/schedule/ScheduleController.java b/backend/src/main/java/moim_today/presentation/schedule/ScheduleController.java index 56eb72fc..072de068 100644 --- a/backend/src/main/java/moim_today/presentation/schedule/ScheduleController.java +++ b/backend/src/main/java/moim_today/presentation/schedule/ScheduleController.java @@ -2,12 +2,12 @@ import moim_today.application.schedule.ScheduleService; import moim_today.domain.member.MemberSession; +import moim_today.dto.schedule.ScheduleCreateRequest; +import moim_today.dto.schedule.ScheduleDeleteRequest; +import moim_today.dto.schedule.ScheduleUpdateRequest; import moim_today.dto.schedule.TimeTableRequest; import moim_today.global.annotation.Login; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RequestMapping("/api/schedules") @@ -25,4 +25,22 @@ public void fetchTimeTable(@Login final MemberSession memberSession, @RequestBody final TimeTableRequest timeTableRequest) { scheduleService.fetchTimeTable(memberSession.id(), timeTableRequest); } + + @PostMapping + public void createSchedule(@Login final MemberSession memberSession, + @RequestBody final ScheduleCreateRequest scheduleCreateRequest) { + scheduleService.createSchedule(memberSession.id(), scheduleCreateRequest); + } + + @PatchMapping + public void updateSchedule(@Login final MemberSession memberSession, + @RequestBody final ScheduleUpdateRequest scheduleUpdateRequest) { + scheduleService.updateSchedule(memberSession.id(), scheduleUpdateRequest); + } + + @DeleteMapping + public void deleteSchedule(@Login final MemberSession memberSession, + @RequestBody final ScheduleDeleteRequest scheduleDeleteRequest) { + scheduleService.deleteSchedule(memberSession.id(), scheduleDeleteRequest.scheduleId()); + } } \ No newline at end of file diff --git a/backend/src/test/java/moim_today/dto/moim/PrivateMoimAppendRequestTest.java b/backend/src/test/java/moim_today/dto/moim/PrivateMoimAppendRequestTest.java new file mode 100644 index 00000000..5dba15f6 --- /dev/null +++ b/backend/src/test/java/moim_today/dto/moim/PrivateMoimAppendRequestTest.java @@ -0,0 +1,72 @@ +package moim_today.dto.moim; + +import moim_today.domain.moim.enums.MoimCategory; +import moim_today.persistence.entity.moim.moim.MoimJpaEntity; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.time.LocalDate; + +import static moim_today.global.constant.MoimConstant.DEFAULT_MOIM_IMAGE_URL; +import static moim_today.util.TestConstant.*; +import static org.assertj.core.api.Assertions.assertThat; + +class PrivateMoimAppendRequestTest { + + @DisplayName("Request에 ImageUrl 값이 없다면 DefaultUrl을 가진 엔티티를 생성한다.") + @Test + void NoneImageUrlCreateEntityWithDefaultUrl() { + + //given + int capacity = Integer.parseInt(CAPACITY.value()); + long memberId = Long.parseLong(MEMBER_ID.value()); + long universityId = Long.parseLong(UNIV_ID.value()); + LocalDate startDate = LocalDate.of(2024, 03, 01); + LocalDate endDate = LocalDate.of(2024, 06, 30); + + PrivateMoimAppendRequest privateMoimAppendRequest = PrivateMoimAppendRequest.builder() + .title(TITLE.value()) + .contents(CONTENTS.value()) + .capacity(capacity) + .password(PASSWORD.value()) + .moimCategory(MoimCategory.STUDY) + .startDate(startDate) + .endDate(endDate) + .build(); + + //when + MoimJpaEntity entity = privateMoimAppendRequest.toEntity(memberId, universityId); + + //then + assertThat((entity.getImageUrl())).isEqualTo(DEFAULT_MOIM_IMAGE_URL.value()); + } + + @DisplayName("Request에 ImageUrl 값이 있다면 엔티티에 정상적으로 들어간다.") + @Test + void CreateMoimJpaEntityWithRequestImageUrl() { + + //given + int capacity = Integer.parseInt(CAPACITY.value()); + long memberId = Long.parseLong(MEMBER_ID.value()); + long universityId = Long.parseLong(UNIV_ID.value()); + LocalDate startDate = LocalDate.of(2024, 03, 01); + LocalDate endDate = LocalDate.of(2024, 06, 30); + + PrivateMoimAppendRequest privateMoimAppendRequest = PrivateMoimAppendRequest.builder() + .title(TITLE.value()) + .contents(CONTENTS.value()) + .capacity(capacity) + .imageUrl(MOIM_IMAGE_URL.value()) + .password(PASSWORD.value()) + .moimCategory(MoimCategory.STUDY) + .startDate(startDate) + .endDate(endDate) + .build(); + + //when + MoimJpaEntity entity = privateMoimAppendRequest.toEntity(memberId, universityId); + + //then + assertThat((entity.getImageUrl())).isEqualTo(MOIM_IMAGE_URL.value()); + } +} diff --git a/backend/src/test/java/moim_today/dto/moim/PublicMoimAppendRequestTest.java b/backend/src/test/java/moim_today/dto/moim/PublicMoimAppendRequestTest.java new file mode 100644 index 00000000..17f3ca52 --- /dev/null +++ b/backend/src/test/java/moim_today/dto/moim/PublicMoimAppendRequestTest.java @@ -0,0 +1,70 @@ +package moim_today.dto.moim; + +import moim_today.domain.moim.enums.MoimCategory; +import moim_today.persistence.entity.moim.moim.MoimJpaEntity; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.time.LocalDate; + +import static moim_today.global.constant.MoimConstant.DEFAULT_MOIM_IMAGE_URL; +import static moim_today.util.TestConstant.*; + +class PublicMoimAppendRequestTest { + + @DisplayName("Request에 ImageUrl 값이 없다면 DefaultUrl을 가진 엔티티를 생성한다.") + @Test + void NoneImageUrlCreateEntityWithDefaultUrl() { + + //given + int capacity = Integer.parseInt(CAPACITY.value()); + long memberId = Long.parseLong(MEMBER_ID.value()); + long universityId = Long.parseLong(UNIV_ID.value()); + LocalDate startDate = LocalDate.of(2024, 03, 01); + LocalDate endDate = LocalDate.of(2024, 06, 30); + + PublicMoimAppendRequest publicMoimAppendRequest = PublicMoimAppendRequest.builder() + .title(TITLE.value()) + .contents(CONTENTS.value()) + .capacity(capacity) + .moimCategory(MoimCategory.STUDY) + .startDate(startDate) + .endDate(endDate) + .build(); + + //when + MoimJpaEntity entity = publicMoimAppendRequest.toEntity(memberId, universityId); + + //then + Assertions.assertThat((entity.getImageUrl())).isEqualTo(DEFAULT_MOIM_IMAGE_URL.value()); + } + + @DisplayName("Request에 ImageUrl 값이 있다면 엔티티에 정상적으로 들어간다.") + @Test + void CreateMoimJpaEntityWithRequestImageUrl() { + + //given + int capacity = Integer.parseInt(CAPACITY.value()); + long memberId = Long.parseLong(MEMBER_ID.value()); + long universityId = Long.parseLong(UNIV_ID.value()); + LocalDate startDate = LocalDate.of(2024, 03, 01); + LocalDate endDate = LocalDate.of(2024, 06, 30); + + PublicMoimAppendRequest publicMoimAppendRequest = PublicMoimAppendRequest.builder() + .title(TITLE.value()) + .contents(CONTENTS.value()) + .capacity(capacity) + .imageUrl(MOIM_IMAGE_URL.value()) + .moimCategory(MoimCategory.STUDY) + .startDate(startDate) + .endDate(endDate) + .build(); + + //when + MoimJpaEntity entity = publicMoimAppendRequest.toEntity(memberId, universityId); + + //then + Assertions.assertThat((entity.getImageUrl())).isEqualTo(MOIM_IMAGE_URL.value()); + } +} diff --git a/backend/src/test/java/moim_today/fake_class/auth/FakeAuthService.java b/backend/src/test/java/moim_today/fake_class/auth/FakeAuthService.java index 20760f41..039a9e0b 100644 --- a/backend/src/test/java/moim_today/fake_class/auth/FakeAuthService.java +++ b/backend/src/test/java/moim_today/fake_class/auth/FakeAuthService.java @@ -36,7 +36,7 @@ public void login(final MemberLoginRequest memberLoginRequest, final HttpServlet } @Override - public void register(final MemberRegisterRequest memberRegisterRequest, final HttpServletRequest request) { + public void signUp(final MemberRegisterRequest memberRegisterRequest, final HttpServletRequest request) { } diff --git a/backend/src/test/java/moim_today/fake_class/moim/FakeMoimService.java b/backend/src/test/java/moim_today/fake_class/moim/FakeMoimService.java new file mode 100644 index 00000000..f3a55ffd --- /dev/null +++ b/backend/src/test/java/moim_today/fake_class/moim/FakeMoimService.java @@ -0,0 +1,50 @@ +package moim_today.fake_class.moim; + +import moim_today.application.moim.MoimService; +import moim_today.domain.moim.DisplayStatus; +import moim_today.domain.moim.enums.MoimCategory; +import moim_today.dto.moim.*; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDate; + +import static moim_today.util.TestConstant.*; + +public class FakeMoimService implements MoimService { + + @Override + public void createPublicMoim(final long memberId, final long universityId, final PublicMoimAppendRequest publicMoimAppendRequest) { + + } + + @Override + public void createPrivateMoim(final long memberId, final long universityId, final PrivateMoimAppendRequest privateMoimAppendRequest) { + + } + + @Override + public UploadMoimImageResponse uploadMoimImage(final MultipartFile file) { + return UploadMoimImageResponse.from(MOIM_IMAGE_URL.value()); + } + + @Override + public MoimDetailResponse getMoimDetail(final long moimId) { + return MoimDetailResponse.builder() + .title(TITLE.value()) + .contents(CONTENTS.value()) + .capacity(Integer.parseInt((CAPACITY.value()))) + .currentCount(Integer.parseInt(CURRENT_COUNT.value())) + .imageUrl(MOIM_IMAGE_URL.value()) + .moimCategory(MoimCategory.STUDY) + .displayStatus(DisplayStatus.PUBLIC) + .views(Integer.parseInt(VIEWS.value())) + .startDate(LocalDate.of(2024,3,1)) + .endDate(LocalDate.of(2024,6,30)) + .build(); + } + + @Override + public void updateMoim(final long memberId, final MoimUpdateRequest moimUpdateRequest) { + + } +} diff --git a/backend/src/test/java/moim_today/fake_class/schedule/FakeScheduleService.java b/backend/src/test/java/moim_today/fake_class/schedule/FakeScheduleService.java index 205339a3..d9e56172 100644 --- a/backend/src/test/java/moim_today/fake_class/schedule/FakeScheduleService.java +++ b/backend/src/test/java/moim_today/fake_class/schedule/FakeScheduleService.java @@ -1,10 +1,17 @@ package moim_today.fake_class.schedule; import moim_today.application.schedule.ScheduleService; +import moim_today.dto.schedule.ScheduleCreateRequest; +import moim_today.dto.schedule.ScheduleUpdateRequest; import moim_today.dto.schedule.TimeTableRequest; import moim_today.global.error.BadRequestException; +import moim_today.global.error.ForbiddenException; +import moim_today.global.error.NotFoundException; + +import java.time.LocalDateTime; import static moim_today.global.constant.exception.EveryTimeExceptionConstant.TIME_INPUT_ERROR; +import static moim_today.global.constant.exception.ScheduleExceptionConstant.*; import static moim_today.util.TestConstant.*; public class FakeScheduleService implements ScheduleService { @@ -15,4 +22,33 @@ public void fetchTimeTable(final long memberId, final TimeTableRequest timeTable throw new BadRequestException(TIME_INPUT_ERROR.value()); } } + + @Override + public void createSchedule(final long memberId, final ScheduleCreateRequest scheduleCreateRequest) { + if (scheduleCreateRequest.startDateTime().equals(LocalDateTime.of(2024, 1, 1, 0, 0, 0))) { + throw new BadRequestException(SCHEDULE_ALREADY_EXIST.message()); + } + } + + @Override + public void updateSchedule(final long memberId, final ScheduleUpdateRequest scheduleUpdateRequest) { + if (scheduleUpdateRequest.scheduleId() == Long.parseLong(FORBIDDEN_SCHEDULE_ID.value())) { + throw new ForbiddenException(SCHEDULE_FORBIDDEN.message()); + } + + if(scheduleUpdateRequest.startDateTime().equals(LocalDateTime.of(2024, 1, 1, 0, 0, 0))) { + throw new BadRequestException(SCHEDULE_ALREADY_EXIST.message()); + } + } + + @Override + public void deleteSchedule(final long memberId, final long scheduleId) { + if (scheduleId == Long.parseLong(NOTFOUND_SCHEDULE_ID.value())) { + throw new NotFoundException(SCHEDULE_NOT_FOUND.message()); + } + + if (scheduleId == Long.parseLong(FORBIDDEN_SCHEDULE_ID.value())) { + throw new ForbiddenException(SCHEDULE_FORBIDDEN.message()); + } + } } diff --git a/backend/src/test/java/moim_today/implement/department/DepartmentAppenderTest.java b/backend/src/test/java/moim_today/implement/department/DepartmentAppenderTest.java new file mode 100644 index 00000000..5b70bd36 --- /dev/null +++ b/backend/src/test/java/moim_today/implement/department/DepartmentAppenderTest.java @@ -0,0 +1,71 @@ +package moim_today.implement.department; + +import moim_today.dto.department.DepartmentInfoResponse; +import moim_today.persistence.entity.department.DepartmentJpaEntity; +import moim_today.persistence.entity.university.UniversityJpaEntity; +import moim_today.util.ImplementTest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.*; + +import static moim_today.global.constant.DepartmentConstant.DEPARTMENT_UPDATE_BATCH_SIZE; +import static moim_today.util.TestConstant.*; +import static org.assertj.core.api.Assertions.assertThat; + +class DepartmentAppenderTest extends ImplementTest { + + @Autowired + private DepartmentAppender departmentAppender; + + @Autowired + private DepartmentFinder departmentFinder; + + private final int MAX_SIZE = 1500; + + @DisplayName("Department 정보 컬렉션을 한 번에 업데이트한다") + @Test + void batchUpdate() { + // given + List departmentJpaEntities = new ArrayList<>(); + for(int i = 0; i < 10; i++){ + departmentJpaEntities.add(DepartmentJpaEntity.builder() + .universityId(0) + .departmentName("departmentName"+i) + .build()); + } + + // when + departmentAppender.batchUpdate(departmentJpaEntities); + List allDepartment = departmentFinder.getAllDepartment(0, null); + + // then + assertThat(allDepartment.size()).isEqualTo(10); + } + + @DisplayName("Department 정보가 Size 값을 넘을 경우 batchUpdate를 실행한다") + @Test + void updateDepartmentsIfSizeOver() { + // given + Map> departmentJpaEntities = new HashMap<>(); + departmentJpaEntities.put(UNIVERSITY_NAME.value(), new HashSet<>()); + UniversityJpaEntity universityJpaEntity = UniversityJpaEntity.builder() + .universityName(UNIVERSITY_NAME.value()) + .universityEmail(AJOU_EMAIL_DOMAIN.value()) + .build(); + universityRepository.save(universityJpaEntity); + + for(int i = 0; i < MAX_SIZE; i++){ + departmentJpaEntities.get(UNIVERSITY_NAME.value()).add(DEPARTMENT_NAME.value()+i); + } + + // when + departmentAppender.updateDepartmentsIfSizeOver(departmentJpaEntities, DEPARTMENT_UPDATE_BATCH_SIZE.intValue()); + + // then + long universityId = universityRepository.getByName(UNIVERSITY_NAME.value()).getId(); + assertThat(departmentRepository.findAllDepartmentOfUniversity(universityId).size()) + .isEqualTo(MAX_SIZE); + } +} \ No newline at end of file diff --git a/backend/src/test/java/moim_today/implement/member/AuthManagerTest.java b/backend/src/test/java/moim_today/implement/member/AuthManagerTest.java index cb26ecdd..12c585d7 100644 --- a/backend/src/test/java/moim_today/implement/member/AuthManagerTest.java +++ b/backend/src/test/java/moim_today/implement/member/AuthManagerTest.java @@ -100,7 +100,7 @@ void register() throws JsonProcessingException { .build(); // when - authManager.register(memberRegisterRequest, mockHttpServletRequest); + authManager.signUp(memberRegisterRequest, mockHttpServletRequest); // then HttpSession session = mockHttpServletRequest.getSession(false); diff --git a/backend/src/test/java/moim_today/implement/moim/MoimAppenderTest.java b/backend/src/test/java/moim_today/implement/moim/MoimAppenderTest.java new file mode 100644 index 00000000..10299c18 --- /dev/null +++ b/backend/src/test/java/moim_today/implement/moim/MoimAppenderTest.java @@ -0,0 +1,118 @@ +package moim_today.implement.moim; + +import moim_today.domain.moim.DisplayStatus; +import moim_today.domain.moim.enums.MoimCategory; +import moim_today.dto.moim.PrivateMoimAppendRequest; +import moim_today.dto.moim.PublicMoimAppendRequest; +import moim_today.persistence.entity.moim.moim.MoimJpaEntity; +import moim_today.util.ImplementTest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.time.LocalDate; + +import static moim_today.global.constant.MoimConstant.DEFAULT_MOIM_PASSWORD; +import static moim_today.global.constant.NumberConstant.DEFAULT_MOIM_CURRENT_COUNT; +import static moim_today.global.constant.NumberConstant.DEFAULT_MOIM_VIEWS; +import static moim_today.util.TestConstant.*; +import static org.assertj.core.api.Assertions.assertThat; + +class MoimAppenderTest extends ImplementTest { + + @Autowired + private MoimAppender moimAppender; + + @DisplayName("공개 모임 생성 요청을 보내면 정상적으로 모든 필드가 초기화되어 DB에 저장된다.") + @Test + void savePublicMoim(){ + + //given + int capacity = Integer.parseInt(CAPACITY.value()); + long memberId = Long.parseLong(MEMBER_ID.value()); + long universityId = Long.parseLong(UNIV_ID.value()); + LocalDate startDate = LocalDate.of(2024, 03, 01); + LocalDate endDate = LocalDate.of(2024, 06, 30); + + PublicMoimAppendRequest publicMoimAppendRequest = new PublicMoimAppendRequest( + TITLE.value(), + CONTENTS.value(), + capacity, + MOIM_IMAGE_URL.value(), + MoimCategory.STUDY, + startDate, + endDate + ); + + //when + MoimJpaEntity moimJpaEntity = moimAppender.createPublicMoim( + memberId, + universityId, + publicMoimAppendRequest + ); + + //then + long count = moimRepository.count(); + assertThat(count).isEqualTo(1); + assertThat(moimJpaEntity.getMemberId()).isEqualTo(memberId); + assertThat(moimJpaEntity.getUniversityId()).isEqualTo(universityId); + assertThat(moimJpaEntity.getTitle()).isEqualTo(TITLE.value()); + assertThat(moimJpaEntity.getContents()).isEqualTo(CONTENTS.value()); + assertThat(moimJpaEntity.getCapacity()).isEqualTo(capacity); + assertThat(moimJpaEntity.getCurrentCount()).isEqualTo(DEFAULT_MOIM_CURRENT_COUNT.value()); + assertThat(moimJpaEntity.getImageUrl()).isEqualTo(MOIM_IMAGE_URL.value()); + assertThat(moimJpaEntity.getPassword()).isEqualTo(DEFAULT_MOIM_PASSWORD.value()); + assertThat(moimJpaEntity.getMoimCategory()).isEqualTo(MoimCategory.STUDY); + assertThat(moimJpaEntity.getDisplayStatus()).isEqualTo(DisplayStatus.PUBLIC); + assertThat(moimJpaEntity.getViews()).isEqualTo(DEFAULT_MOIM_VIEWS.value()); + assertThat(moimJpaEntity.getStartDate()).isEqualTo(startDate); + assertThat(moimJpaEntity.getEndDate()).isEqualTo(endDate); + } + + @DisplayName("비공개 모임 생성 요청을 보내면 정상적으로 모든 필드가 초기화되어 DB에 저장된다.") + @Test + void savePrivateMoim(){ + + //given + int capacity = Integer.parseInt(CAPACITY.value()); + long memberId = Long.parseLong(MEMBER_ID.value()); + long universityId = Long.parseLong(UNIV_ID.value()); + LocalDate startDate = LocalDate.of(2024, 03, 01); + LocalDate endDate = LocalDate.of(2024, 06, 30); + + PrivateMoimAppendRequest privateMoimAppendRequest = new PrivateMoimAppendRequest( + TITLE.value(), + CONTENTS.value(), + capacity, + PASSWORD.value(), + MOIM_IMAGE_URL.value(), + MoimCategory.STUDY, + startDate, + endDate + ); + + //when + MoimJpaEntity moimJpaEntity = moimAppender.createPrivateMoim( + memberId, + universityId, + privateMoimAppendRequest + ); + + //then + long count = moimRepository.count(); + assertThat(count).isEqualTo(1); + assertThat(moimJpaEntity.getMemberId()).isEqualTo(memberId); + assertThat(moimJpaEntity.getUniversityId()).isEqualTo(universityId); + assertThat(moimJpaEntity.getTitle()).isEqualTo(TITLE.value()); + assertThat(moimJpaEntity.getContents()).isEqualTo(CONTENTS.value()); + assertThat(moimJpaEntity.getCapacity()).isEqualTo(capacity); + assertThat(moimJpaEntity.getCurrentCount()).isEqualTo(DEFAULT_MOIM_CURRENT_COUNT.value()); + assertThat(moimJpaEntity.getImageUrl()).isEqualTo(MOIM_IMAGE_URL.value()); + assertThat(moimJpaEntity.getPassword()).isEqualTo(PASSWORD.value()); + assertThat(moimJpaEntity.getMoimCategory()).isEqualTo(MoimCategory.STUDY); + assertThat(moimJpaEntity.getDisplayStatus()).isEqualTo(DisplayStatus.PRIVATE); + assertThat(moimJpaEntity.getViews()).isEqualTo(DEFAULT_MOIM_VIEWS.value()); + assertThat(moimJpaEntity.getStartDate()).isEqualTo(startDate); + assertThat(moimJpaEntity.getEndDate()).isEqualTo(endDate); + } +} diff --git a/backend/src/test/java/moim_today/implement/moim/MoimFinderTest.java b/backend/src/test/java/moim_today/implement/moim/MoimFinderTest.java new file mode 100644 index 00000000..5d06a131 --- /dev/null +++ b/backend/src/test/java/moim_today/implement/moim/MoimFinderTest.java @@ -0,0 +1,47 @@ +package moim_today.implement.moim; + +import moim_today.global.error.NotFoundException; +import moim_today.persistence.entity.moim.moim.MoimJpaEntity; +import moim_today.util.ImplementTest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import static moim_today.global.constant.exception.MoimExceptionConstant.MOIM_NOT_FOUND_ERROR; +import static moim_today.util.TestConstant.MOIM_ID; +import static moim_today.util.TestConstant.TITLE; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class MoimFinderTest extends ImplementTest { + + @Autowired + private MoimFinder moimFinder; + + @DisplayName("getById로 모임을 조회하면 모임 엔티티를 반환한다.") + @Test + void getByIdTest(){ + //given + MoimJpaEntity moimJpaEntity = MoimJpaEntity.builder() + .title(TITLE.value()) + .build(); + + moimRepository.save(moimJpaEntity); + + //when + MoimJpaEntity findMoimJpaEntity = moimFinder.getById(moimJpaEntity.getId()); + + //then + assertThat(findMoimJpaEntity).isExactlyInstanceOf(MoimJpaEntity.class); + assertThat(findMoimJpaEntity.getTitle()).isEqualTo(TITLE.value()); + } + + @DisplayName("getById로 모임을 조회할 때, 해당하는 모임이 없으면 예외를 발생시킨다.") + @Test + void getByIdThrowExceptionTest(){ + //when & then + assertThatThrownBy(() -> moimFinder.getById(Long.parseLong(MOIM_ID.value()))) + .isInstanceOf(NotFoundException.class) + .hasMessage(MOIM_NOT_FOUND_ERROR.message()); + } +} diff --git a/backend/src/test/java/moim_today/implement/moim/MoimUpdaterTest.java b/backend/src/test/java/moim_today/implement/moim/MoimUpdaterTest.java new file mode 100644 index 00000000..22392cf4 --- /dev/null +++ b/backend/src/test/java/moim_today/implement/moim/MoimUpdaterTest.java @@ -0,0 +1,95 @@ +package moim_today.implement.moim; + +import moim_today.domain.moim.DisplayStatus; +import moim_today.domain.moim.enums.MoimCategory; +import moim_today.dto.moim.MoimUpdateRequest; +import moim_today.global.error.ForbiddenException; +import moim_today.persistence.entity.moim.moim.MoimJpaEntity; +import moim_today.util.ImplementTest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.time.LocalDate; + +import static moim_today.global.constant.exception.MoimExceptionConstant.MOIM_FORBIDDEN; +import static moim_today.util.TestConstant.*; +import static org.assertj.core.api.Assertions.*; + +class MoimUpdaterTest extends ImplementTest { + + @Autowired + private MoimUpdater moimUpdater; + + @DisplayName("자신이 만든 모임을 수정하려고 시도하면 수정에 성공한다.") + @Test + void updateMoimTest(){ + + //given + long memberId = Long.parseLong(MEMBER_ID.value()); + + MoimJpaEntity moimJpaEntity = MoimJpaEntity.builder() + .memberId(memberId) + .build(); + + moimRepository.save(moimJpaEntity); + long moimId = moimJpaEntity.getId(); + + int capacity = Integer.parseInt(CAPACITY.value()); + LocalDate startDate = LocalDate.of(2024, 3, 1); + LocalDate endDate = LocalDate.of(2024, 6, 30); + + MoimUpdateRequest moimUpdateRequest = MoimUpdateRequest.builder() + .moimId(moimId) + .title(TITLE.value()) + .contents(CONTENTS.value()) + .capacity(capacity) + .imageUrl(MOIM_IMAGE_URL.value()) + .password(PASSWORD.value()) + .moimCategory(MoimCategory.STUDY) + .displayStatus(DisplayStatus.PRIVATE) + .startDate(startDate) + .endDate(endDate) + .build(); + + //when & //then + assertThatCode(() -> moimUpdater.updateMoim(memberId, moimUpdateRequest)) + .doesNotThrowAnyException(); + + MoimJpaEntity updatedMoim = moimRepository.getById(moimId); + assertThat(updatedMoim.getTitle()).isEqualTo(TITLE.value()); + assertThat(updatedMoim.getContents()).isEqualTo(CONTENTS.value()); + assertThat(updatedMoim.getCapacity()).isEqualTo(capacity); + assertThat(updatedMoim.getImageUrl()).isEqualTo(MOIM_IMAGE_URL.value()); + assertThat(updatedMoim.getPassword()).isEqualTo(PASSWORD.value()); + assertThat(updatedMoim.getMoimCategory()).isEqualTo(MoimCategory.STUDY); + assertThat(updatedMoim.getDisplayStatus()).isEqualTo(DisplayStatus.PRIVATE); + assertThat(updatedMoim.getStartDate()).isEqualTo(startDate); + assertThat(updatedMoim.getEndDate()).isEqualTo(endDate); + } + + @DisplayName("수정 권한이 없는 모임을 수정하려고 시도하면 예외가 발생한다.") + @Test + void updateMoimFailureTest(){ + + //given + long memberId = Long.parseLong(MEMBER_ID.value()); + long forbiddenMemberId = memberId + 1; + + MoimJpaEntity moimJpaEntity = MoimJpaEntity.builder() + .memberId(forbiddenMemberId) + .build(); + + moimRepository.save(moimJpaEntity); + long moimId = moimJpaEntity.getId(); + + MoimUpdateRequest forbiddenMoimUpdateRequest = MoimUpdateRequest.builder() + .moimId(moimId) + .build(); + + //expected + assertThatThrownBy(() -> moimUpdater.updateMoim(memberId, forbiddenMoimUpdateRequest)) + .isInstanceOf(ForbiddenException.class) + .hasMessage(MOIM_FORBIDDEN.message()); + } +} diff --git a/backend/src/test/java/moim_today/implement/schedule/ScheduleAppenderTest.java b/backend/src/test/java/moim_today/implement/schedule/ScheduleAppenderTest.java index 25a72ae7..2a7c1dd5 100644 --- a/backend/src/test/java/moim_today/implement/schedule/ScheduleAppenderTest.java +++ b/backend/src/test/java/moim_today/implement/schedule/ScheduleAppenderTest.java @@ -1,6 +1,8 @@ package moim_today.implement.schedule; import moim_today.domain.schedule.Schedule; +import moim_today.global.error.BadRequestException; +import moim_today.persistence.entity.schedule.ScheduleJpaEntity; import moim_today.util.ImplementTest; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -10,6 +12,8 @@ import java.time.LocalDateTime; import java.util.List; +import static moim_today.global.constant.exception.ScheduleExceptionConstant.*; +import static moim_today.util.TestConstant.*; import static org.assertj.core.api.Assertions.*; class ScheduleAppenderTest extends ImplementTest { @@ -53,4 +57,159 @@ void batchUpdateSchedules() { // then assertThat(scheduleRepository.count()).isEqualTo(3); } + + @DisplayName("개인 일정을 등록한다.") + @Test + void createSchedule() { + // given + long memberId = 1L; + long meetingId = 2L; + + ScheduleJpaEntity scheduleJpaEntity = ScheduleJpaEntity.builder() + .memberId(memberId) + .meetingId(meetingId) + .scheduleName(SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.MONDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + // when + scheduleAppender.createSchedule(scheduleJpaEntity); + + // then + ScheduleJpaEntity findEntity = scheduleRepository.getById(scheduleJpaEntity.getId()); + + assertThat(scheduleRepository.count()).isEqualTo(1); + assertThat(findEntity.getMemberId()).isEqualTo(memberId); + assertThat(findEntity.getMeetingId()).isEqualTo(meetingId); + assertThat(findEntity.getScheduleName()).isEqualTo(SCHEDULE_NAME.value()); + assertThat(findEntity.getDayOfWeek()).isEqualTo(DayOfWeek.MONDAY); + assertThat(findEntity.getStartDateTime()).isEqualTo(LocalDateTime.of(2024, 1, 1, 10, 0, 0)); + assertThat(findEntity.getEndDateTime()).isEqualTo(LocalDateTime.of(2024, 1, 1, 12, 0, 0)); + } + + @DisplayName("다른 사용자의 스케줄은 영향을 주지 않는다.") + @Test + void notEffectOtherMemberSchedule() { + // given 1 + long memberId = 1L; + long anotherMemberId = 9999L; + long meetingId = 2L; + + ScheduleJpaEntity otherScheduleJpaEntity = ScheduleJpaEntity.builder() + .memberId(anotherMemberId) + .meetingId(meetingId) + .scheduleName(SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.MONDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + scheduleRepository.save(otherScheduleJpaEntity); + + // given 2 + ScheduleJpaEntity scheduleJpaEntity = ScheduleJpaEntity.builder() + .memberId(memberId) + .meetingId(meetingId) + .scheduleName(SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.MONDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + // when + scheduleAppender.createSchedule(scheduleJpaEntity); + + // then + ScheduleJpaEntity findEntity = scheduleRepository.getById(scheduleJpaEntity.getId()); + + assertThat(scheduleRepository.count()).isEqualTo(2); + assertThat(findEntity.getMemberId()).isEqualTo(memberId); + assertThat(findEntity.getMeetingId()).isEqualTo(meetingId); + assertThat(findEntity.getScheduleName()).isEqualTo(SCHEDULE_NAME.value()); + assertThat(findEntity.getDayOfWeek()).isEqualTo(DayOfWeek.MONDAY); + assertThat(findEntity.getStartDateTime()).isEqualTo(LocalDateTime.of(2024, 1, 1, 10, 0, 0)); + assertThat(findEntity.getEndDateTime()).isEqualTo(LocalDateTime.of(2024, 1, 1, 12, 0, 0)); + } + + @DisplayName("다른 스케줄 사이에 있는 일정을 등록한다.") + @Test + void createScheduleBetweenOtherSchedules() { + // given 1 + ScheduleJpaEntity BeforeScheduleJpaEntity = ScheduleJpaEntity.builder() + .startDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + ScheduleJpaEntity afterScheduleJpaEntity = ScheduleJpaEntity.builder() + .startDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 14, 0, 0)) + .build(); + + scheduleRepository.save(BeforeScheduleJpaEntity); + scheduleRepository.save(afterScheduleJpaEntity); + + // given 2 + ScheduleJpaEntity newScheduleJpaEntity = ScheduleJpaEntity.builder() + .startDateTime(LocalDateTime.of(2024, 1, 1, 14, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 16, 0, 0)) + .build(); + + // then + assertThatCode(() -> scheduleAppender.createSchedule(newScheduleJpaEntity)) + .doesNotThrowAnyException(); + + assertThat(scheduleRepository.count()).isEqualTo(3); + } + + @DisplayName("해당 시간대 앞에 스케줄이 존재하면 예외가 발생한다.") + @Test + void createScheduleFailAlreadyExistBeforeSchedule() { + // given 1 + ScheduleJpaEntity BeforeScheduleJpaEntity = ScheduleJpaEntity.builder() + .startDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + scheduleRepository.save(BeforeScheduleJpaEntity); + + // given 2 + ScheduleJpaEntity newScheduleJpaEntity = ScheduleJpaEntity.builder() + .startDateTime(LocalDateTime.of(2024, 1, 1, 11, 59, 59)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 16, 0, 0)) + .build(); + + // then + assertThatCode(() -> scheduleAppender.createSchedule(newScheduleJpaEntity)) + .isInstanceOf(BadRequestException.class) + .hasMessage(SCHEDULE_ALREADY_EXIST.message()); + + assertThat(scheduleRepository.count()).isEqualTo(1); + } + + @DisplayName("해당 시간대 뒤에 스케줄이 존재하면 예외가 발생한다.") + @Test + void createScheduleFailAlreadyExistAfterSchedule() { + // given 1 + ScheduleJpaEntity afterScheduleJpaEntity = ScheduleJpaEntity.builder() + .startDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + scheduleRepository.save(afterScheduleJpaEntity); + + // given 2 + ScheduleJpaEntity newScheduleJpaEntity = ScheduleJpaEntity.builder() + .startDateTime(LocalDateTime.of(2024, 1, 1, 8, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 1)) + .build(); + + // then + assertThatCode(() -> scheduleAppender.createSchedule(newScheduleJpaEntity)) + .isInstanceOf(BadRequestException.class) + .hasMessage(SCHEDULE_ALREADY_EXIST.message()); + + assertThat(scheduleRepository.count()).isEqualTo(1); + } } \ No newline at end of file diff --git a/backend/src/test/java/moim_today/implement/schedule/ScheduleDeleterTest.java b/backend/src/test/java/moim_today/implement/schedule/ScheduleDeleterTest.java new file mode 100644 index 00000000..747c72fc --- /dev/null +++ b/backend/src/test/java/moim_today/implement/schedule/ScheduleDeleterTest.java @@ -0,0 +1,66 @@ +package moim_today.implement.schedule; + +import moim_today.global.error.ForbiddenException; +import moim_today.global.error.NotFoundException; +import moim_today.persistence.entity.schedule.ScheduleJpaEntity; +import moim_today.util.ImplementTest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import static moim_today.global.constant.exception.ScheduleExceptionConstant.SCHEDULE_FORBIDDEN; +import static moim_today.global.constant.exception.ScheduleExceptionConstant.SCHEDULE_NOT_FOUND; +import static org.assertj.core.api.Assertions.*; + +class ScheduleDeleterTest extends ImplementTest { + + @Autowired + private ScheduleDeleter scheduleDeleter; + + @DisplayName("개인 일정을 삭제한다.") + @Test + void deleteSchedule() { + // given + long memberId = 1L; + + ScheduleJpaEntity scheduleJpaEntity = ScheduleJpaEntity.builder() + .memberId(memberId) + .build(); + + scheduleRepository.save(scheduleJpaEntity); + + // when + scheduleDeleter.deleteSchedule(memberId, scheduleJpaEntity.getId()); + + // then + assertThat(scheduleRepository.count()).isEqualTo(0); + } + + @DisplayName("해당 회원의 스케줄이 아니면 삭제할 수 없다.") + @Test + void deleteScheduleForbidden() { + // given + long memberId = 1L; + long anotherMemberId = 9999L; + + ScheduleJpaEntity scheduleJpaEntity = ScheduleJpaEntity.builder() + .memberId(memberId) + .build(); + + scheduleRepository.save(scheduleJpaEntity); + + // expected + assertThatCode(() -> scheduleDeleter.deleteSchedule(anotherMemberId, scheduleJpaEntity.getId())) + .isInstanceOf(ForbiddenException.class) + .hasMessage(SCHEDULE_FORBIDDEN.message()); + } + + @DisplayName("스케줄이 존재하지 않으면 삭제할 수 없다.") + @Test + void deleteScheduleNotFound() { + // expected + assertThatCode(() -> scheduleDeleter.deleteSchedule(1L, 9999L)) + .isInstanceOf(NotFoundException.class) + .hasMessage(SCHEDULE_NOT_FOUND.message()); + } +} \ No newline at end of file diff --git a/backend/src/test/java/moim_today/implement/schedule/ScheduleUpdaterTest.java b/backend/src/test/java/moim_today/implement/schedule/ScheduleUpdaterTest.java new file mode 100644 index 00000000..442cb2de --- /dev/null +++ b/backend/src/test/java/moim_today/implement/schedule/ScheduleUpdaterTest.java @@ -0,0 +1,232 @@ +package moim_today.implement.schedule; + +import moim_today.dto.schedule.ScheduleUpdateRequest; +import moim_today.global.error.BadRequestException; +import moim_today.global.error.ForbiddenException; +import moim_today.persistence.entity.schedule.ScheduleJpaEntity; +import moim_today.util.ImplementTest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.time.DayOfWeek; +import java.time.LocalDateTime; + +import static moim_today.global.constant.exception.ScheduleExceptionConstant.SCHEDULE_ALREADY_EXIST; +import static moim_today.global.constant.exception.ScheduleExceptionConstant.SCHEDULE_FORBIDDEN; +import static moim_today.util.TestConstant.*; +import static moim_today.util.TestConstant.SCHEDULE_NAME; +import static org.assertj.core.api.Assertions.*; + + +class ScheduleUpdaterTest extends ImplementTest { + + @Autowired + private ScheduleUpdater scheduleUpdater; + + @DisplayName("개인 일정을 수정한다.") + @Test + void updateSchedule() { + // given 1 + long memberId = 1L; + long meetingId = 2L; + + ScheduleJpaEntity scheduleJpaEntity = ScheduleJpaEntity.builder() + .memberId(memberId) + .meetingId(meetingId) + .scheduleName(SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.MONDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + scheduleRepository.save(scheduleJpaEntity); + + // given 2 + ScheduleUpdateRequest scheduleUpdateRequest = ScheduleUpdateRequest.builder() + .scheduleId(scheduleJpaEntity.getId()) + .scheduleName(NEW_SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.SATURDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 11, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 13, 0, 0)) + .build(); + + // when + scheduleUpdater.updateSchedule(memberId, scheduleUpdateRequest); + + // then + ScheduleJpaEntity findEntity = scheduleRepository.getById(scheduleJpaEntity.getId()); + + assertThat(scheduleRepository.count()).isEqualTo(1); + assertThat(findEntity.getScheduleName()).isEqualTo(NEW_SCHEDULE_NAME.value()); + assertThat(findEntity.getDayOfWeek()).isEqualTo(DayOfWeek.SATURDAY); + assertThat(findEntity.getStartDateTime()).isEqualTo(LocalDateTime.of(2024, 1, 1, 11, 0, 0)); + assertThat(findEntity.getEndDateTime()).isEqualTo(LocalDateTime.of(2024, 1, 1, 13, 0, 0)); + } + + @DisplayName("해당 시간대 앞에 스케줄이 존재하면 예외가 발생한다.") + @Test + void updateScheduleFailAlreadyExistBeforeSchedule() { + // given 1 + long memberId = 1L; + + ScheduleJpaEntity BeforeScheduleJpaEntity = ScheduleJpaEntity.builder() + .memberId(memberId) + .startDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + scheduleRepository.save(BeforeScheduleJpaEntity); + + // given 2 + ScheduleJpaEntity scheduleJpaEntity = ScheduleJpaEntity.builder() + .memberId(memberId) + .startDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 14, 0, 0)) + .build(); + + scheduleRepository.save(scheduleJpaEntity); + + // given 2 + ScheduleUpdateRequest scheduleUpdateRequest = ScheduleUpdateRequest.builder() + .scheduleId(scheduleJpaEntity.getId()) + .scheduleName(NEW_SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.SATURDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 11, 59, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 14, 0, 0)) + .build(); + + // expected + assertThatCode(() -> scheduleUpdater.updateSchedule(memberId, scheduleUpdateRequest)) + .isInstanceOf(BadRequestException.class) + .hasMessage(SCHEDULE_ALREADY_EXIST.message()); + + assertThat(scheduleRepository.count()).isEqualTo(2); + } + + @DisplayName("해당 시간대 뒤에 스케줄이 존재하면 예외가 발생한다.") + @Test + void updateScheduleFailAlreadyExistAfterSchedule() { + // given 1 + long memberId = 1L; + ScheduleJpaEntity afterScheduleJpaEntity = ScheduleJpaEntity.builder() + .memberId(memberId) + .startDateTime(LocalDateTime.of(2024, 1, 1, 14, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 16, 0, 0)) + .build(); + + scheduleRepository.save(afterScheduleJpaEntity); + + // given 2 + ScheduleJpaEntity scheduleJpaEntity = ScheduleJpaEntity.builder() + .memberId(memberId) + .startDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 14, 0, 0)) + .build(); + + scheduleRepository.save(scheduleJpaEntity); + + // given 2 + ScheduleUpdateRequest scheduleUpdateRequest = ScheduleUpdateRequest.builder() + .scheduleId(scheduleJpaEntity.getId()) + .scheduleName(NEW_SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.SATURDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 14, 1, 0)) + .build(); + + // expected + assertThatCode(() -> scheduleUpdater.updateSchedule(memberId, scheduleUpdateRequest)) + .isInstanceOf(BadRequestException.class) + .hasMessage(SCHEDULE_ALREADY_EXIST.message()); + + assertThat(scheduleRepository.count()).isEqualTo(2); + } + + @DisplayName("해당 회원의 스케줄이 아니면 예외가 발생한다.") + @Test + void validateMember() { + // given 1 + long memberId = 1L; + long anotherMemberId = 9999L; + + ScheduleJpaEntity scheduleJpaEntity = ScheduleJpaEntity.builder() + .memberId(memberId) + .startDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 14, 0, 0)) + .build(); + + scheduleRepository.save(scheduleJpaEntity); + + // given 2 + ScheduleUpdateRequest scheduleUpdateRequest = ScheduleUpdateRequest.builder() + .scheduleId(scheduleJpaEntity.getId()) + .scheduleName(NEW_SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.SATURDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 14, 1, 0)) + .build(); + + // expected + assertThatCode(() -> scheduleUpdater.updateSchedule(anotherMemberId, scheduleUpdateRequest)) + .isInstanceOf(ForbiddenException.class) + .hasMessage(SCHEDULE_FORBIDDEN.message()); + + assertThat(scheduleRepository.count()).isEqualTo(1); + } + + @DisplayName("다른 사용자의 스케줄은 영향을 주지 않는다.") + @Test + void notEffectOtherMemberSchedule() { + // given 1 + long memberId = 1L; + long anotherMemberId = 9999L; + long meetingId = 2L; + + ScheduleJpaEntity otherScheduleJpaEntity = ScheduleJpaEntity.builder() + .memberId(anotherMemberId) + .meetingId(meetingId) + .scheduleName(SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.MONDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + scheduleRepository.save(otherScheduleJpaEntity); + + // given 2 + ScheduleJpaEntity scheduleJpaEntity = ScheduleJpaEntity.builder() + .memberId(memberId) + .meetingId(meetingId) + .scheduleName(SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.MONDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + scheduleRepository.save(scheduleJpaEntity); + + // given 2 + ScheduleUpdateRequest scheduleUpdateRequest = ScheduleUpdateRequest.builder() + .scheduleId(scheduleJpaEntity.getId()) + .scheduleName(NEW_SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.SATURDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 11, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 13, 0, 0)) + .build(); + + // when + scheduleUpdater.updateSchedule(memberId, scheduleUpdateRequest); + + // then + ScheduleJpaEntity findEntity = scheduleRepository.getById(scheduleJpaEntity.getId()); + + assertThat(scheduleRepository.count()).isEqualTo(2); + assertThat(findEntity.getMemberId()).isEqualTo(memberId); + assertThat(findEntity.getMeetingId()).isEqualTo(meetingId); + assertThat(findEntity.getScheduleName()).isEqualTo(NEW_SCHEDULE_NAME.value()); + assertThat(findEntity.getDayOfWeek()).isEqualTo(DayOfWeek.SATURDAY); + assertThat(findEntity.getStartDateTime()).isEqualTo(LocalDateTime.of(2024, 1, 1, 11, 0, 0)); + assertThat(findEntity.getEndDateTime()).isEqualTo(LocalDateTime.of(2024, 1, 1, 13, 0, 0)); + } +} \ No newline at end of file diff --git a/backend/src/test/java/moim_today/implement/university/UniversityFinderTest.java b/backend/src/test/java/moim_today/implement/university/UniversityFinderTest.java index 7090712d..6b5c557b 100644 --- a/backend/src/test/java/moim_today/implement/university/UniversityFinderTest.java +++ b/backend/src/test/java/moim_today/implement/university/UniversityFinderTest.java @@ -10,9 +10,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.Random; -import static moim_today.util.TestConstant.EMAIL; -import static moim_today.util.TestConstant.UNIVERSITY_NAME; +import static moim_today.util.TestConstant.*; import static org.assertj.core.api.Assertions.assertThat; class UniversityFinderTest extends ImplementTest { @@ -62,17 +62,55 @@ void findByName() { @DisplayName("대학교 이름이 없을 때 테스트") @Test - void 대학교_이름으로_찾았는데_대학교가_없을_때() { + void noUniversityFoundByUniversityNameTest() { // when - Optional findUniversity = universityRepository.findByName(UNIVERSITY_NAME.value()); + Optional findUniversity = universityFinder.findByName(UNIVERSITY_NAME.value()); // then assertThat(findUniversity.isEmpty()).isTrue(); } + @DisplayName("대학교 테이블에 존재하는 대학교 이름만 반환한다") + @Test + void findUniversitiesByUniversityNames(){ + // given + final int MAX_UNIV = 5; + final int MAX_TEST_UNIV = 10; + Random random = new Random(); + List universityNames = new ArrayList<>(); + String testUniversityName = UNIVERSITY_NAME.value(); + + for(int i = 0; i < MAX_UNIV; i++){ + UniversityJpaEntity universityJpaEntity = UniversityJpaEntity.builder() + .universityName(testUniversityName+i) + .universityEmail(AJOU_EMAIL.value()) + .build(); + universityRepository.save(universityJpaEntity); + + universityNames.add(testUniversityName+i); + } + + for(int i = MAX_UNIV; i < MAX_TEST_UNIV; i++){ + universityNames.add(testUniversityName+i); + } + + // when + List findUniversities = universityFinder.findUniversitiesByName(universityNames); + + // then + UniversityJpaEntity randomUniversity = UniversityJpaEntity.builder() + .universityName(testUniversityName+(random.nextInt(MAX_UNIV))) + .universityEmail(AJOU_EMAIL.value()) + .build(); + assertThat(findUniversities.size()).isEqualTo(MAX_UNIV); + assertThat(findUniversities.stream().filter(u -> u.getUniversityName().equals(randomUniversity.getUniversityName())) + .findAny()) + .isPresent(); + } + @DisplayName("대학교 ID가 있는지 없는지 검사한다") @Test - void 대학교_ID가_있는지_검사() { + void validateUniversityIdTest() { // given UniversityJpaEntity universityJpaEntity = UniversityJpaEntity.builder() .universityName(UNIVERSITY_NAME.value()) diff --git a/backend/src/test/java/moim_today/persistence/entity/certification_token/PasswordCertificationJpaEntityTest.java b/backend/src/test/java/moim_today/persistence/entity/certification_token/PasswordCertificationJpaEntityTest.java index 9c4fda06..1aa235ee 100644 --- a/backend/src/test/java/moim_today/persistence/entity/certification_token/PasswordCertificationJpaEntityTest.java +++ b/backend/src/test/java/moim_today/persistence/entity/certification_token/PasswordCertificationJpaEntityTest.java @@ -6,8 +6,9 @@ import java.time.LocalDateTime; -import static moim_today.util.TestConstant.*; -import static org.assertj.core.api.Assertions.*; +import static moim_today.util.TestConstant.CERTIFICATION_TOKEN; +import static moim_today.util.TestConstant.NEW_CERTIFICATION_TOKEN; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; class PasswordCertificationJpaEntityTest { diff --git a/backend/src/test/java/moim_today/persistence/entity/moim/moim/MoimJpaEntityTest.java b/backend/src/test/java/moim_today/persistence/entity/moim/moim/MoimJpaEntityTest.java new file mode 100644 index 00000000..d38dbbb7 --- /dev/null +++ b/backend/src/test/java/moim_today/persistence/entity/moim/moim/MoimJpaEntityTest.java @@ -0,0 +1,208 @@ +package moim_today.persistence.entity.moim.moim; + +import moim_today.domain.moim.DisplayStatus; +import moim_today.domain.moim.enums.MoimCategory; +import moim_today.dto.moim.MoimUpdateRequest; +import moim_today.global.error.ForbiddenException; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.time.LocalDate; + +import static moim_today.global.constant.MoimConstant.DEFAULT_MOIM_IMAGE_URL; +import static moim_today.global.constant.MoimConstant.DEFAULT_MOIM_PASSWORD; +import static moim_today.global.constant.exception.MoimExceptionConstant.MOIM_FORBIDDEN; +import static moim_today.util.TestConstant.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; + +class MoimJpaEntityTest { + + @DisplayName("회원 id가 일치하면 검증에 성공한다.") + @Test + void validateMemberTest(){ + + //given + long memberId = Long.parseLong(MEMBER_ID.value()); + + MoimJpaEntity moimJpaEntity = MoimJpaEntity.builder() + .memberId(memberId) + .build(); + + //expected + assertThatCode(() -> moimJpaEntity.validateMember(memberId)) + .doesNotThrowAnyException(); + } + + @DisplayName("회원 id가 일치하지 않으면 예외가 발생한다") + @Test + void validateMemberThrowsExceptionTest(){ + + //given + long memberId = Long.parseLong(MEMBER_ID.value()); + long forbiddenMemberId = Long.parseLong(MEMBER_ID.value()) + 1L; + + MoimJpaEntity moimJpaEntity = MoimJpaEntity.builder() + .memberId(memberId) + .build(); + + //expected + assertThatCode(() -> moimJpaEntity.validateMember(forbiddenMemberId)) + .isInstanceOf(ForbiddenException.class) + .hasMessage(MOIM_FORBIDDEN.message()); + } + + @DisplayName("수정시 공개 여부가 PUBLIC이라면 default password가 설정된다.") + @Test + void updateMoimDisplayStatusPublicTest(){ + + //given + MoimJpaEntity moimJpaEntity = MoimJpaEntity.builder() + .build(); + + int capacity = Integer.parseInt(CAPACITY.value()); + LocalDate startDate = LocalDate.of(2024, 3, 1); + LocalDate endDate = LocalDate.of(2024, 6, 30); + + MoimUpdateRequest moimUpdateRequest = MoimUpdateRequest.builder() + .title(TITLE.value()) + .contents(CONTENTS.value()) + .capacity(capacity) + .imageUrl(MOIM_IMAGE_URL.value()) + .moimCategory(MoimCategory.STUDY) + .displayStatus(DisplayStatus.PUBLIC) + .startDate(startDate) + .endDate(endDate) + .build(); + + //expected + assertThatCode(() -> moimJpaEntity.updateMoim(moimUpdateRequest)) + .doesNotThrowAnyException(); + + assertThat(moimJpaEntity.getTitle()).isEqualTo(TITLE.value()); + assertThat(moimJpaEntity.getContents()).isEqualTo(CONTENTS.value()); + assertThat(moimJpaEntity.getCapacity()).isEqualTo(capacity); + assertThat(moimJpaEntity.getImageUrl()).isEqualTo(MOIM_IMAGE_URL.value()); + assertThat(moimJpaEntity.getPassword()).isEqualTo(DEFAULT_MOIM_PASSWORD.value()); + assertThat(moimJpaEntity.getMoimCategory()).isEqualTo(MoimCategory.STUDY); + assertThat(moimJpaEntity.getDisplayStatus()).isEqualTo(DisplayStatus.PUBLIC); + assertThat(moimJpaEntity.getStartDate()).isEqualTo(startDate); + assertThat(moimJpaEntity.getEndDate()).isEqualTo(endDate); + } + + @DisplayName("수정시 공개 여부가 PRIVATE이라면 입력한 password가 설정된다.") + @Test + void updateMoimDisplayStatusPrivateTest(){ + + //given + MoimJpaEntity moimJpaEntity = MoimJpaEntity.builder() + .build(); + + int capacity = Integer.parseInt(CAPACITY.value()); + LocalDate startDate = LocalDate.of(2024, 3, 1); + LocalDate endDate = LocalDate.of(2024, 6, 30); + + MoimUpdateRequest moimUpdateRequest = MoimUpdateRequest.builder() + .title(TITLE.value()) + .contents(CONTENTS.value()) + .capacity(capacity) + .password(PASSWORD.value()) + .imageUrl(MOIM_IMAGE_URL.value()) + .moimCategory(MoimCategory.STUDY) + .displayStatus(DisplayStatus.PRIVATE) + .startDate(startDate) + .endDate(endDate) + .build(); + + //expected + assertThatCode(() -> moimJpaEntity.updateMoim(moimUpdateRequest)) + .doesNotThrowAnyException(); + + assertThat(moimJpaEntity.getTitle()).isEqualTo(TITLE.value()); + assertThat(moimJpaEntity.getContents()).isEqualTo(CONTENTS.value()); + assertThat(moimJpaEntity.getCapacity()).isEqualTo(capacity); + assertThat(moimJpaEntity.getImageUrl()).isEqualTo(MOIM_IMAGE_URL.value()); + assertThat(moimJpaEntity.getPassword()).isEqualTo(PASSWORD.value()); + assertThat(moimJpaEntity.getMoimCategory()).isEqualTo(MoimCategory.STUDY); + assertThat(moimJpaEntity.getDisplayStatus()).isEqualTo(DisplayStatus.PRIVATE); + assertThat(moimJpaEntity.getStartDate()).isEqualTo(startDate); + assertThat(moimJpaEntity.getEndDate()).isEqualTo(endDate); + } + + @DisplayName("수정시 imageUrl값이 없다면 default imageURL 값이 들어간다.") + @Test + void updateMoimImageUrlIsNullTest(){ + + //given + MoimJpaEntity moimJpaEntity = MoimJpaEntity.builder() + .build(); + + int capacity = Integer.parseInt(CAPACITY.value()); + LocalDate startDate = LocalDate.of(2024, 3, 1); + LocalDate endDate = LocalDate.of(2024, 6, 30); + + MoimUpdateRequest moimUpdateRequest = MoimUpdateRequest.builder() + .title(TITLE.value()) + .contents(CONTENTS.value()) + .capacity(capacity) + .password(PASSWORD.value()) + .moimCategory(MoimCategory.STUDY) + .displayStatus(DisplayStatus.PRIVATE) + .startDate(startDate) + .endDate(endDate) + .build(); + + //expected + assertThatCode(() -> moimJpaEntity.updateMoim(moimUpdateRequest)) + .doesNotThrowAnyException(); + + assertThat(moimJpaEntity.getTitle()).isEqualTo(TITLE.value()); + assertThat(moimJpaEntity.getContents()).isEqualTo(CONTENTS.value()); + assertThat(moimJpaEntity.getCapacity()).isEqualTo(capacity); + assertThat(moimJpaEntity.getImageUrl()).isEqualTo(DEFAULT_MOIM_IMAGE_URL.value()); + assertThat(moimJpaEntity.getPassword()).isEqualTo(PASSWORD.value()); + assertThat(moimJpaEntity.getMoimCategory()).isEqualTo(MoimCategory.STUDY); + assertThat(moimJpaEntity.getDisplayStatus()).isEqualTo(DisplayStatus.PRIVATE); + assertThat(moimJpaEntity.getStartDate()).isEqualTo(startDate); + assertThat(moimJpaEntity.getEndDate()).isEqualTo(endDate); + } + + @DisplayName("수정시 imageUrl값이 있다면 값이 그대로 들어간다.") + @Test + void updateMoimImageUrlIsNotNullTest(){ + + //given + MoimJpaEntity moimJpaEntity = MoimJpaEntity.builder() + .build(); + + int capacity = Integer.parseInt(CAPACITY.value()); + LocalDate startDate = LocalDate.of(2024, 3, 1); + LocalDate endDate = LocalDate.of(2024, 6, 30); + + MoimUpdateRequest moimUpdateRequest = MoimUpdateRequest.builder() + .title(TITLE.value()) + .contents(CONTENTS.value()) + .capacity(capacity) + .password(PASSWORD.value()) + .imageUrl(MOIM_IMAGE_URL.value()) + .moimCategory(MoimCategory.STUDY) + .displayStatus(DisplayStatus.PRIVATE) + .startDate(startDate) + .endDate(endDate) + .build(); + + //expected + assertThatCode(() -> moimJpaEntity.updateMoim(moimUpdateRequest)) + .doesNotThrowAnyException(); + + assertThat(moimJpaEntity.getTitle()).isEqualTo(TITLE.value()); + assertThat(moimJpaEntity.getContents()).isEqualTo(CONTENTS.value()); + assertThat(moimJpaEntity.getCapacity()).isEqualTo(capacity); + assertThat(moimJpaEntity.getImageUrl()).isEqualTo(MOIM_IMAGE_URL.value()); + assertThat(moimJpaEntity.getPassword()).isEqualTo(PASSWORD.value()); + assertThat(moimJpaEntity.getMoimCategory()).isEqualTo(MoimCategory.STUDY); + assertThat(moimJpaEntity.getDisplayStatus()).isEqualTo(DisplayStatus.PRIVATE); + assertThat(moimJpaEntity.getStartDate()).isEqualTo(startDate); + assertThat(moimJpaEntity.getEndDate()).isEqualTo(endDate); + } +} diff --git a/backend/src/test/java/moim_today/persistence/entity/schedule/ScheduleJpaEntityTest.java b/backend/src/test/java/moim_today/persistence/entity/schedule/ScheduleJpaEntityTest.java new file mode 100644 index 00000000..17867dee --- /dev/null +++ b/backend/src/test/java/moim_today/persistence/entity/schedule/ScheduleJpaEntityTest.java @@ -0,0 +1,97 @@ +package moim_today.persistence.entity.schedule; + +import moim_today.dto.schedule.ScheduleUpdateRequest; +import moim_today.global.error.ForbiddenException; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.time.DayOfWeek; +import java.time.LocalDateTime; + +import static moim_today.global.constant.exception.ScheduleExceptionConstant.SCHEDULE_FORBIDDEN; +import static moim_today.util.TestConstant.*; +import static org.assertj.core.api.Assertions.*; + +class ScheduleJpaEntityTest { + + @DisplayName("개인 일정을 수정한다.") + @Test + void updateSchedule() { + // given + long memberId = 1L; + long meetingId = 2L; + + ScheduleJpaEntity scheduleJpaEntity = ScheduleJpaEntity.builder() + .memberId(memberId) + .meetingId(meetingId) + .scheduleName(SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.MONDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + ScheduleUpdateRequest scheduleUpdateRequest = ScheduleUpdateRequest.builder() + .scheduleId(1L) + .scheduleName(NEW_SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.SATURDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 14, 0, 0)) + .build(); + + // when + scheduleJpaEntity.updateSchedule(scheduleUpdateRequest); + + // then + assertThat(scheduleJpaEntity.getMemberId()).isEqualTo(memberId); + assertThat(scheduleJpaEntity.getMeetingId()).isEqualTo(meetingId); + assertThat(scheduleJpaEntity.getScheduleName()).isEqualTo(NEW_SCHEDULE_NAME.value()); + assertThat(scheduleJpaEntity.getDayOfWeek()).isEqualTo(DayOfWeek.SATURDAY); + assertThat(scheduleJpaEntity.getStartDateTime()).isEqualTo(LocalDateTime.of(2024, 1, 1, 12, 0, 0)); + assertThat(scheduleJpaEntity.getEndDateTime()).isEqualTo(LocalDateTime.of(2024, 1, 1, 14, 0, 0)); + } + + @DisplayName("회원 id가 일치하면 검증에 성공한다.") + @Test + void validateMember() { + // given + long memberId = 1L; + long meetingId = 2L; + + ScheduleJpaEntity scheduleJpaEntity = ScheduleJpaEntity.builder() + .memberId(memberId) + .meetingId(meetingId) + .scheduleName(SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.MONDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + // expected + assertThatCode(() -> scheduleJpaEntity.validateMember(memberId)) + .doesNotThrowAnyException(); + } + + @DisplayName("회원 id가 일치하지 않으면 예외가 발생한다.") + @Test + void validateMemberFail() { + // given + long memberId = 1L; + long meetingId = 2L; + + long anotherMemberId = 9999L; + + ScheduleJpaEntity scheduleJpaEntity = ScheduleJpaEntity.builder() + .memberId(memberId) + .meetingId(meetingId) + .scheduleName(SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.MONDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + // expected + assertThatCode(() -> scheduleJpaEntity.validateMember(anotherMemberId)) + .isInstanceOf(ForbiddenException.class) + .hasMessage(SCHEDULE_FORBIDDEN.message()); + } +} \ No newline at end of file diff --git a/backend/src/test/java/moim_today/presentation/auth/AuthControllerTest.java b/backend/src/test/java/moim_today/presentation/auth/AuthControllerTest.java index 95036b15..c560882b 100644 --- a/backend/src/test/java/moim_today/presentation/auth/AuthControllerTest.java +++ b/backend/src/test/java/moim_today/presentation/auth/AuthControllerTest.java @@ -67,7 +67,7 @@ void loginTestFail() throws Exception { .andExpect(status().isNotFound()) .andDo(document("로그인 실패", resource(ResourceSnippetParameters.builder() - .tag("로그인") + .tag("인증") .summary("로그인") .requestFields( fieldWithPath("email").type(STRING).description("이메일"), @@ -89,7 +89,7 @@ void logoutTest() throws Exception { .andExpect(status().isOk()) .andDo(document("로그아웃 성공", resource(ResourceSnippetParameters.builder() - .tag("로그아웃") + .tag("인증") .summary("로그아웃") .build() ) @@ -112,14 +112,14 @@ void registerTest() throws Exception { String json = objectMapper.writeValueAsString(memberRegisterRequest); - mockMvc.perform(post("/api/register") + mockMvc.perform(post("/api/sign-up") .contentType(APPLICATION_JSON) .accept(APPLICATION_JSON) .content(json)) .andExpect(status().isOk()) .andDo(document("회원가입 성공", resource(ResourceSnippetParameters.builder() - .tag("회원") + .tag("인증") .summary("회원가입") .requestFields( fieldWithPath("email").type(STRING).description("학교 이메일"), @@ -134,4 +134,4 @@ void registerTest() throws Exception { .build()) )); } -} \ No newline at end of file +} diff --git a/backend/src/test/java/moim_today/presentation/moim/MoimControllerTest.java b/backend/src/test/java/moim_today/presentation/moim/MoimControllerTest.java new file mode 100644 index 00000000..6140fc43 --- /dev/null +++ b/backend/src/test/java/moim_today/presentation/moim/MoimControllerTest.java @@ -0,0 +1,212 @@ +package moim_today.presentation.moim; + +import com.epages.restdocs.apispec.ResourceSnippetParameters; +import moim_today.domain.moim.DisplayStatus; +import moim_today.domain.moim.enums.MoimCategory; +import moim_today.dto.moim.MoimUpdateRequest; +import moim_today.dto.moim.PrivateMoimAppendRequest; +import moim_today.dto.moim.PublicMoimAppendRequest; +import moim_today.fake_class.moim.FakeMoimService; +import moim_today.util.ControllerTest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockMultipartFile; + +import java.time.LocalDate; + +import static com.epages.restdocs.apispec.ResourceDocumentation.resource; +import static moim_today.util.TestConstant.*; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.restdocs.payload.JsonFieldType.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.request.RequestDocumentation.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +class MoimControllerTest extends ControllerTest { + + private final FakeMoimService fakeMoimService = new FakeMoimService(); + + @Override + protected Object initController() { + return new MoimController(fakeMoimService); + } + + @DisplayName("공개 모임 생성 테스트") + @Test + void createPublicMoimApiTest() throws Exception { + LocalDate startDate = LocalDate.of(2024, 03, 01); + LocalDate endDate = LocalDate.of(2024, 06, 30); + + PublicMoimAppendRequest publicMoimAppendRequest = new PublicMoimAppendRequest( + TITLE.value(), + CONTENTS.value(), + Integer.parseInt(CAPACITY.value()), + MOIM_IMAGE_URL.value(), + MoimCategory.STUDY, + startDate, + endDate + ); + + mockMvc.perform(post("/api/moims/public") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(publicMoimAppendRequest)) + ) + .andExpect(status().isOk()) + .andDo(document("공개 모임 생성 성공", + resource(ResourceSnippetParameters.builder() + .tag("모임") + .summary("공개 모임 생성") + .requestFields( + fieldWithPath("title").type(STRING).description("모임명"), + fieldWithPath("contents").type(STRING).description("내용"), + fieldWithPath("capacity").type(NUMBER).description("모집 인원"), + fieldWithPath("imageUrl").type(STRING).description("모임 사진 URL"), + fieldWithPath("moimCategory").type(VARIES).description("카테고리"), + fieldWithPath("startDate").type(STRING).description("시작 일자"), + fieldWithPath("endDate").type(STRING).description("종료 일자") + ) + .build() + ))); + } + + @DisplayName("비공개 모임 생성 테스트") + @Test + void createPrivateMoimApiTest() throws Exception { + LocalDate startDate = LocalDate.of(2024, 03, 01); + LocalDate endDate = LocalDate.of(2024, 06, 30); + + PrivateMoimAppendRequest privateMoimAppendRequest = new PrivateMoimAppendRequest( + TITLE.value(), + CONTENTS.value(), + Integer.parseInt(CAPACITY.value()), + PASSWORD.value(), + MOIM_IMAGE_URL.value(), + MoimCategory.STUDY, + startDate, + endDate + ); + + mockMvc.perform(post("/api/moims/private") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(privateMoimAppendRequest)) + ) + .andExpect(status().isOk()) + .andDo(document("비공개 모임 생성 성공", + resource(ResourceSnippetParameters.builder() + .tag("모임") + .summary("비공개 모임 생성") + .requestFields( + fieldWithPath("title").type(STRING).description("모임명"), + fieldWithPath("contents").type(STRING).description("내용"), + fieldWithPath("capacity").type(NUMBER).description("모집 인원"), + fieldWithPath("password").type(STRING).description("모임 비밀번호"), + fieldWithPath("imageUrl").type(STRING).description("모임 사진 URL"), + fieldWithPath("moimCategory").type(VARIES).description("카테고리"), + fieldWithPath("startDate").type(STRING).description("시작 일자"), + fieldWithPath("endDate").type(STRING).description("종료 일자") + ) + .build() + ))); + } + + @DisplayName("모임 사진 업로드 테스트 성공") + @Test + void uploadMoimImageTest() throws Exception { + + MockMultipartFile file = new MockMultipartFile( + FILE_NAME.value(), + ORIGINAL_FILE_NAME.value(), + MediaType.MULTIPART_FORM_DATA_VALUE, + FILE_CONTENT.value().getBytes() + ); + + mockMvc.perform(multipart("/api/moims/image") + .file(file) + ) + .andExpect(status().isOk()) + .andDo(document("모임 사진 업로드 테스트", + requestParts( + partWithName("file").description("모임 사진 파일") + ), + resource(ResourceSnippetParameters.builder() + .tag("모임") + .summary("모임 사진 업로드 성공 테스트 입니다.") + .responseFields( + fieldWithPath("imageUrl").type(STRING).description("모임 사진 URL") + ) + .build() + ))); + } + + @DisplayName("모임 상제 정보 조회 테스트") + @Test + void getMoimDetailTest() throws Exception { + + mockMvc.perform(get("/api/moims/detail") + .param("moimId", "1") + ) + .andExpect(status().isOk()) + .andDo(document("모임 상세 정보 조회", + resource(ResourceSnippetParameters.builder() + .tag("모임") + .summary("모임 상세 정보 조회 API") + .queryParameters( + parameterWithName("moimId").description("모임 ID") + ) + .responseFields( + fieldWithPath("title").type(STRING).description("모임명"), + fieldWithPath("contents").type(STRING).description("내용"), + fieldWithPath("capacity").type(NUMBER).description("모집 인원"), + fieldWithPath("currentCount").type(NUMBER).description("현재 인원"), + fieldWithPath("imageUrl").type(STRING).description("모임 사진 URL"), + fieldWithPath("moimCategory").type(VARIES).description("카테고리"), + fieldWithPath("displayStatus").type(VARIES).description("공개여부"), + fieldWithPath("views").type(NUMBER).description("조회수"), + fieldWithPath("startDate").type(STRING).description("시작 일자"), + fieldWithPath("endDate").type(STRING).description("종료 일자") + ) + .build() + ))); + } + + @DisplayName("모임 정보 업데이트 테스트") + @Test + void updateMoimTest() throws Exception { + MoimUpdateRequest moimUpdateRequest = MoimUpdateRequest.builder() + .moimId(Long.parseLong(MOIM_ID.value())) + .title(TITLE.value()) + .contents(CONTENTS.value()) + .capacity(Integer.parseInt(CAPACITY.value())) + .imageUrl(MOIM_IMAGE_URL.value()) + .password(PASSWORD.value()) + .moimCategory(MoimCategory.STUDY) + .displayStatus(DisplayStatus.PRIVATE) + .startDate(LocalDate.of(2024,3,1)) + .endDate(LocalDate.of(2024,6,30)) + .build(); + + mockMvc.perform(patch("/api/moims") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(moimUpdateRequest))) + .andExpect(status().isOk()) + .andDo(document("모임 정보 업데이트 테스트", + resource(ResourceSnippetParameters.builder() + .tag("모임") + .summary("모임 정보를 업데이트(수정)하는 테스트 입니다.") + .requestFields( + fieldWithPath("moimId").type(NUMBER).description("수정할 모임의 ID"), + fieldWithPath("title").type(STRING).description("수정한 모임명"), + fieldWithPath("contents").type(STRING).description("수정한 내용"), + fieldWithPath("capacity").type(NUMBER).description("수정한 모집 인원"), + fieldWithPath("imageUrl").type(STRING).description("수정한 모임 사진 URL"), + fieldWithPath("password").type(STRING).description("수정한 비밀번호"), + fieldWithPath("moimCategory").type(VARIES).description("수정한 카테고리"), + fieldWithPath("displayStatus").type(VARIES).description("수정한 공개여부"), + fieldWithPath("startDate").type(STRING).description("수정한 시작일자"), + fieldWithPath("endDate").type(STRING).description("수정한 종료일자") + ).build() + ))); + } +} diff --git a/backend/src/test/java/moim_today/presentation/schedule/ScheduleControllerTest.java b/backend/src/test/java/moim_today/presentation/schedule/ScheduleControllerTest.java index c1899d8b..36ba1169 100644 --- a/backend/src/test/java/moim_today/presentation/schedule/ScheduleControllerTest.java +++ b/backend/src/test/java/moim_today/presentation/schedule/ScheduleControllerTest.java @@ -2,20 +2,27 @@ import com.epages.restdocs.apispec.ResourceSnippetParameters; import moim_today.application.schedule.ScheduleService; +import moim_today.dto.schedule.ScheduleCreateRequest; +import moim_today.dto.schedule.ScheduleDeleteRequest; +import moim_today.dto.schedule.ScheduleUpdateRequest; import moim_today.dto.schedule.TimeTableRequest; import moim_today.fake_class.schedule.FakeScheduleService; import moim_today.util.ControllerTest; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import java.time.DayOfWeek; import java.time.LocalDate; +import java.time.LocalDateTime; import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; import static com.epages.restdocs.apispec.ResourceDocumentation.resource; +import static moim_today.util.TestConstant.*; import static moim_today.util.TestConstant.EVERY_TIME_ID; import static moim_today.util.TestConstant.WRONG_EVERY_TIME_ID; import static org.springframework.http.MediaType.APPLICATION_JSON; -import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.restdocs.payload.JsonFieldType.NUMBER; import static org.springframework.restdocs.payload.JsonFieldType.STRING; import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -92,4 +99,254 @@ void fetchTimeTableFail() throws Exception { .build() ))); } + + @DisplayName("개인 일정을 생성한다.") + @Test + void createSchedule() throws Exception { + ScheduleCreateRequest scheduleCreateRequest = ScheduleCreateRequest.builder() + .scheduleName(SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.MONDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + String json = objectMapper.writeValueAsString(scheduleCreateRequest); + + mockMvc.perform(post("/api/schedules") + .contentType(APPLICATION_JSON) + .content(json) + ) + .andExpect(status().isOk()) + .andDo(document("개인 일정 등록 성공", + resource(ResourceSnippetParameters.builder() + .tag("스케줄") + .summary("개인 일정 등록") + .requestFields( + fieldWithPath("scheduleName").type(STRING).description("스케줄명"), + fieldWithPath("dayOfWeek").type(STRING).description("요일"), + fieldWithPath("startDateTime").type(STRING).description("시작 시간"), + fieldWithPath("endDateTime").type(STRING).description("종료 시간") + ) + .build() + ))); + } + + @DisplayName("이미 존재하는 시간대에 개인 일정을 등록하면 예외가 발생한다.") + @Test + void createScheduleFail() throws Exception { + ScheduleCreateRequest scheduleCreateRequest = ScheduleCreateRequest.builder() + .scheduleName(SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.MONDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 0, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + String json = objectMapper.writeValueAsString(scheduleCreateRequest); + + mockMvc.perform(post("/api/schedules") + .contentType(APPLICATION_JSON) + .content(json) + ) + .andExpect(status().isBadRequest()) + .andDo(document("개인 일정 등록 실패 - 이미 존재하는 시간대의 스케줄", + resource(ResourceSnippetParameters.builder() + .tag("스케줄") + .summary("개인 일정 등록") + .requestFields( + fieldWithPath("scheduleName").type(STRING).description("스케줄명"), + fieldWithPath("dayOfWeek").type(STRING).description("요일"), + fieldWithPath("startDateTime").type(STRING).description("시작 시간"), + fieldWithPath("endDateTime").type(STRING).description("종료 시간") + ) + .responseFields( + fieldWithPath("statusCode").type(STRING).description("상태 코드"), + fieldWithPath("message").type(STRING).description("오류 메세지") + ) + .build() + ))); + } + + @DisplayName("개인 일정을 수정한다.") + @Test + void updateSchedule() throws Exception { + ScheduleUpdateRequest scheduleUpdateRequest = ScheduleUpdateRequest.builder() + .scheduleId(1L) + .scheduleName(SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.MONDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + String json = objectMapper.writeValueAsString(scheduleUpdateRequest); + + mockMvc.perform(patch("/api/schedules") + .contentType(APPLICATION_JSON) + .content(json) + ) + .andExpect(status().isOk()) + .andDo(document("개인 일정 수정 성공", + resource(ResourceSnippetParameters.builder() + .tag("스케줄") + .summary("개인 일정 수정") + .requestFields( + fieldWithPath("scheduleId").type(NUMBER).description("스케줄 id"), + fieldWithPath("scheduleName").type(STRING).description("스케줄명"), + fieldWithPath("dayOfWeek").type(STRING).description("요일"), + fieldWithPath("startDateTime").type(STRING).description("시작 시간"), + fieldWithPath("endDateTime").type(STRING).description("종료 시간") + ) + .build() + ))); + } + + @DisplayName("변경하려는 시간에 다른 일정이 있으면 수정에 실패한다") + @Test + void updateScheduleBadRequest() throws Exception { + ScheduleUpdateRequest scheduleUpdateRequest = ScheduleUpdateRequest.builder() + .scheduleId(1L) + .scheduleName(SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.MONDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 0, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + String json = objectMapper.writeValueAsString(scheduleUpdateRequest); + + mockMvc.perform(patch("/api/schedules") + .contentType(APPLICATION_JSON) + .content(json) + ) + .andExpect(status().isBadRequest()) + .andDo(document("개인 일정 수정 실패 - 해당 시간에 다른 일정이 있음", + resource(ResourceSnippetParameters.builder() + .tag("스케줄") + .summary("개인 일정 수정") + .requestFields( + fieldWithPath("scheduleId").type(NUMBER).description("스케줄 id"), + fieldWithPath("scheduleName").type(STRING).description("스케줄명"), + fieldWithPath("dayOfWeek").type(STRING).description("요일"), + fieldWithPath("startDateTime").type(STRING).description("시작 시간"), + fieldWithPath("endDateTime").type(STRING).description("종료 시간") + ) + .responseFields( + fieldWithPath("statusCode").type(STRING).description("상태 코드"), + fieldWithPath("message").type(STRING).description("오류 메세지") + ) + .build() + ))); + } + + @DisplayName("회원의 스케줄이 아니면 수정할 수 없다.") + @Test + void updateScheduleForbidden() throws Exception { + ScheduleUpdateRequest scheduleUpdateRequest = ScheduleUpdateRequest.builder() + .scheduleId(Long.parseLong(FORBIDDEN_SCHEDULE_ID.value())) + .scheduleName(SCHEDULE_NAME.value()) + .dayOfWeek(DayOfWeek.MONDAY) + .startDateTime(LocalDateTime.of(2024, 1, 1, 10, 0, 0)) + .endDateTime(LocalDateTime.of(2024, 1, 1, 12, 0, 0)) + .build(); + + String json = objectMapper.writeValueAsString(scheduleUpdateRequest); + + mockMvc.perform(patch("/api/schedules") + .contentType(APPLICATION_JSON) + .content(json) + ) + .andExpect(status().isForbidden()) + .andDo(document("개인 일정 수정 실패 - 회원의 스케줄이 아님", + resource(ResourceSnippetParameters.builder() + .tag("스케줄") + .summary("개인 일정 수정") + .requestFields( + fieldWithPath("scheduleId").type(NUMBER).description("스케줄 id"), + fieldWithPath("scheduleName").type(STRING).description("스케줄명"), + fieldWithPath("dayOfWeek").type(STRING).description("요일"), + fieldWithPath("startDateTime").type(STRING).description("시작 시간"), + fieldWithPath("endDateTime").type(STRING).description("종료 시간") + ) + .responseFields( + fieldWithPath("statusCode").type(STRING).description("상태 코드"), + fieldWithPath("message").type(STRING).description("오류 메세지") + ) + .build() + ))); + } + + @DisplayName("개인 일정을 삭제한다.") + @Test + void deleteSchedule() throws Exception { + ScheduleDeleteRequest scheduleDeleteRequest = new ScheduleDeleteRequest(1L); + + String json = objectMapper.writeValueAsString(scheduleDeleteRequest); + + mockMvc.perform(delete("/api/schedules") + .contentType(APPLICATION_JSON) + .content(json) + ) + .andExpect(status().isOk()) + .andDo(document("개인 일정 삭제 성공", + resource(ResourceSnippetParameters.builder() + .tag("스케줄") + .summary("개인 일정 삭제") + .requestFields( + fieldWithPath("scheduleId").type(NUMBER).description("스케줄 id") + ) + .build() + ))); + } + + @DisplayName("회원의 스케줄이 아니면 삭제에 실패한다.") + @Test + void deleteScheduleForbidden() throws Exception { + ScheduleDeleteRequest scheduleDeleteRequest = new ScheduleDeleteRequest(Long.parseLong(FORBIDDEN_SCHEDULE_ID.value())); + + String json = objectMapper.writeValueAsString(scheduleDeleteRequest); + + mockMvc.perform(delete("/api/schedules") + .contentType(APPLICATION_JSON) + .content(json) + ) + .andExpect(status().isForbidden()) + .andDo(document("개인 일정 삭제 실패 - 회원의 스케줄이 아님", + resource(ResourceSnippetParameters.builder() + .tag("스케줄") + .summary("개인 일정 삭제") + .requestFields( + fieldWithPath("scheduleId").type(NUMBER).description("스케줄 id") + ) + .responseFields( + fieldWithPath("statusCode").type(STRING).description("상태 코드"), + fieldWithPath("message").type(STRING).description("오류 메세지") + ) + .build() + ))); + } + + @DisplayName("스케줄 정보를 찾을 수 없으면 삭제에 실패한다.") + @Test + void deleteScheduleNotFound() throws Exception { + ScheduleDeleteRequest scheduleDeleteRequest = new ScheduleDeleteRequest(Long.parseLong(NOTFOUND_SCHEDULE_ID.value())); + + String json = objectMapper.writeValueAsString(scheduleDeleteRequest); + + mockMvc.perform(delete("/api/schedules") + .contentType(APPLICATION_JSON) + .content(json) + ) + .andExpect(status().isNotFound()) + .andDo(document("개인 일정 삭제 실패 - 일정을 찾을 수 없음", + resource(ResourceSnippetParameters.builder() + .tag("스케줄") + .summary("개인 일정 삭제") + .requestFields( + fieldWithPath("scheduleId").type(NUMBER).description("스케줄 id") + ) + .responseFields( + fieldWithPath("statusCode").type(STRING).description("상태 코드"), + fieldWithPath("message").type(STRING).description("오류 메세지") + ) + .build() + ))); + } } \ No newline at end of file diff --git a/backend/src/test/java/moim_today/util/ControllerTest.java b/backend/src/test/java/moim_today/util/ControllerTest.java index 374386f8..cd965750 100644 --- a/backend/src/test/java/moim_today/util/ControllerTest.java +++ b/backend/src/test/java/moim_today/util/ControllerTest.java @@ -16,9 +16,10 @@ import java.io.IOException; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import static moim_today.util.TestConstant.LOCAL_DATE_FORMAT; +import static moim_today.util.TestConstant.*; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; @ExtendWith(RestDocumentationExtension.class) @@ -28,7 +29,8 @@ public abstract class ControllerTest { protected ObjectMapper objectMapper = serializingObjectMapper(); - private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(LOCAL_DATE_FORMAT.value()); + private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(LOCAL_DATE_FORMAT.value()); + private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern(LOCAL_DATE_TIME_FORMAT.value()); @BeforeEach void setUp(final RestDocumentationContextProvider provider) { @@ -43,25 +45,45 @@ void setUp(final RestDocumentationContextProvider provider) { private ObjectMapper serializingObjectMapper() { ObjectMapper objectMapper = new ObjectMapper(); JavaTimeModule javaTimeModule = new JavaTimeModule(); + javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer()); javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer()); + javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer()); + javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer()); objectMapper.registerModule(javaTimeModule); + return objectMapper; } - private class LocalDateSerializer extends JsonSerializer { + private static class LocalDateSerializer extends JsonSerializer { @Override public void serialize(final LocalDate value, JsonGenerator gen, final SerializerProvider serializers) throws IOException { - gen.writeString(value.format(FORMATTER)); + gen.writeString(value.format(DATE_FORMATTER)); } } - private class LocalDateDeserializer extends JsonDeserializer { + private static class LocalDateDeserializer extends JsonDeserializer { @Override public LocalDate deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException { - return LocalDate.parse(p.getValueAsString(), FORMATTER); + return LocalDate.parse(p.getValueAsString(), DATE_FORMATTER); + } + } + + private static class LocalDateTimeSerializer extends JsonSerializer { + + @Override + public void serialize(final LocalDateTime value, final JsonGenerator gen, final SerializerProvider serializerProvider) throws IOException { + gen.writeString(value.format(DATETIME_FORMATTER)); + } + } + + private static class LocalDateTimeDeserializer extends JsonDeserializer { + + @Override + public LocalDateTime deserialize(final JsonParser p, final DeserializationContext deserializationContext) throws IOException { + return LocalDateTime.parse(p.getValueAsString(), DATETIME_FORMATTER); } } diff --git a/backend/src/test/java/moim_today/util/ImplementTest.java b/backend/src/test/java/moim_today/util/ImplementTest.java index 1d4c21ee..0ac0efa9 100644 --- a/backend/src/test/java/moim_today/util/ImplementTest.java +++ b/backend/src/test/java/moim_today/util/ImplementTest.java @@ -5,6 +5,7 @@ import moim_today.persistence.repository.certification.password.PasswordCertificationRepository; import moim_today.persistence.repository.department.DepartmentRepository; import moim_today.persistence.repository.member.MemberRepository; +import moim_today.persistence.repository.moim.moim.MoimRepository; import moim_today.persistence.repository.schedule.ScheduleRepository; import moim_today.persistence.repository.university.UniversityRepository; import org.junit.jupiter.api.BeforeEach; @@ -36,6 +37,9 @@ public abstract class ImplementTest { @Autowired protected DepartmentRepository departmentRepository; + @Autowired + protected MoimRepository moimRepository; + @Autowired protected ScheduleRepository scheduleRepository; diff --git a/backend/src/test/java/moim_today/util/TestConstant.java b/backend/src/test/java/moim_today/util/TestConstant.java index e3bffe1f..74dd71c8 100644 --- a/backend/src/test/java/moim_today/util/TestConstant.java +++ b/backend/src/test/java/moim_today/util/TestConstant.java @@ -3,39 +3,67 @@ public enum TestConstant { + // 이메일 EMAIL("email"), AJOU_EMAIL("test@ajou.ac.kr"), AJOU_EMAIL_DOMAIN("ajou.ac.kr"), WRONG_EMAIL("wrongEmail"), ALREADY_EXIST_EMAIL("alreayExist@ajou.ac.kr"), + // 비밀번호 PASSWORD("password"), NEW_PASSWORD("newPassword"), WRONG_PASSWORD("wrongPassword"), + // 에브리타임 EVERY_TIME_ID("everyTimeId"), WRONG_EVERY_TIME_ID("wrong everyTimeId"), + // 인증토큰 CERTIFICATION_TOKEN("certificationToken"), NEW_CERTIFICATION_TOKEN("newCertificationToken"), WRONG_CERTIFICATION_TOKEN("wrongCertificationToken"), + // 파일 FILE_NAME("file"), ORIGINAL_FILE_NAME("file.txt"), FILE_CONTENT("content"), + + // 대학교 + UNIV_ID("194"), UNIVERSITY_NAME("universityName"), + + // 학과 + DEPARTMENT_ID("9369"), DEPARTMENT_NAME("departmentName"), + + // 회원 + MEMBER_ID("1"), USERNAME("username"), STUDENT_ID("studentId"), PROFILE_IMAGE_URL("profileImageUrl"), - UNIV_ID("194"), - DEPARTMENT_ID("9369"), + + + // 모임 + MOIM_ID("1"), + TITLE("title"), + CONTENTS("contents"), + CAPACITY("5"), + MOIM_IMAGE_URL("moimImageUrl"), + CURRENT_COUNT("0"), + VIEWS("10"), + + SCHEDULE_NAME("scheduleName"), + NEW_SCHEDULE_NAME("new scheduleName"), + FORBIDDEN_SCHEDULE_ID("9999"), + NOTFOUND_SCHEDULE_ID("0"), STATUS_CODE("200"), MESSAGE("message"), - LOCAL_DATE_FORMAT("yyyy-MM-dd"); + LOCAL_DATE_FORMAT("yyyy-MM-dd"), + LOCAL_DATE_TIME_FORMAT("yyyy-MM-dd HH:mm:ss"); private final String value; @@ -46,4 +74,8 @@ public enum TestConstant { public String value() { return value; } + + public int intValue(){ + return Integer.parseInt(value); + } }