Skip to content

Commit

Permalink
release: 0.4.0 (#193)
Browse files Browse the repository at this point in the history
* feat: 리뷰 등록시 회원 매너 온도 반영 기능 추가 및 리뷰 등록 리팩토링 (#158)

* refactor: 회원 리뷰 등록 API 리팩토링 (#157)

* feat: 회원 리뷰 등록시, 온도 반영 및 리뷰 피드백 반영 (#157)

* feat: User 엔티티 메소드 추가 (#157)

* feat: Review enum 필드 추가 (#157)

* test: 리뷰 등록시 온도 업데이트에 대한 단위 테스트 (#157)

* test: 리뷰 등록 기능 통합 테스트 (#157)

* refactor: 회원 리뷰 등록 메소드 수정 (#157)

* test: 불필요한 테스트 제거 및 CI 오류 수정 (#157)

* test: MeetingRepository 테스트에서 시간과 id비교 비활서화

* refactor: 회원 탈퇴 URI 변경 (#162)

* refactor: 회원 탈퇴 URI 수정 (#161)

* test: 회원 탈퇴 URI 수정에 대한 테스트 수정 (#161)

* fix: CI 에러 수정 (#161)

* fix: 필드 값 비교를 위해 deprecated 된 메소드을 대체 (#161)

* fix: 필드 값 비교를 위해 deprecated 된 메소드을 대체 (#161)

* feat: fcm token 업데이트 api 추가 (#166)

* fix: user_alert ddl의 pk에 auto_increment를 추가한다

* feat: token 업데이트 api를 추가한다

* fix: 모임 수정 시 이미지가 추가되는 버그 수정 (#169)

* perf: upgrade GPT-3.5 to GPT-4 (#174)

* refactor: 위치 기반 데이터 값 유효기간 변경

* refactor: 위치 기반 데이터 값 유효기간 변경

* refactor: 위치 기반 데이터 값 유효기간 변경

* feat: 모임 종료, 사용자 추천 알림을 추가 (#182)

* feat: Alert Entity를 추가하고, 알림 전송 기능이 Entity를 파라미터로 받아 동작하게 수정한다

* refactor: MeetingAlerted를 BeforeMeetingAlerted로 직관적으로 변경한다

* feat: 모임 종료 알림을 추가한다

* feat: 유저가 추천받았을때 알림 전송 기능을 추가한다

* feat: 유저가 한달 동안 받은 알람을 조회하는 기능 개발 (#185)

* fix: flyway schema에 _이 하나밖에 없는 버그를 수정한다

* feat: 유저가 한달동안 받은 알람을 조회하는 기능을 개발한다

* refactor: AlertRepository의 finalAll 메소드를 findAllByCreatedAt으로 변경한다

* feat: 북마크 추가, 취소 기능 구현 (#184)

* chore: 북마크 스키마 추가

* feat: 북마크 추가, 삭제 기능

* test: 북마크 추가, 삭제 테스트 작성

- 북마크 추가 케이스
- 북마크 취소 케이스
- 모임 단일 응답에 북마크 여부 추

* feat: bookmarked -> isBookmarked, V1__ 언더바 누락 수정

* fix: flyway_schema alert userId를 user_id로 변경한다

* fix: flyway 13 의 alert table문을 변경한다

* refactor: 알람 조회에 읽은알람인지, 언제 발행되었는지를 추가 (#189)

* feat: 회원탈퇴, 로그아웃 시, 회원 위치 데이터 삭제 로직 추가 및 위치 데이터 유효기간 변경 (#179)

* refactor: 주변 위치 데이터 응답 데이터 구조 변경 및 유효기간 30 초 설정 (#178)

* feat: 회원탈퇴, 로그아웃 시 저장되어 있는 위치 정보 Redis 에서 삭제 (#178)

* feat: 회원탈퇴, 로그아웃 시 저장되어 있는 위치 정보 Redis 삭제 메소드 추가 (#178)

* test: 로직 수정에 따른 단위 테스트 수정 (#178)

* refactor: UserService 로그아웃, 회원 탈퇴 시 위치 데이터 삭제 로직 제거 (#178)

* refactor: logout @transactional 제거 (#178)

* refactor: TeumTeumService 리팩토링 (#178)

* test: 회원탈퇴, 로그아웃 유닛 테스트 수정 (#178)

* feat: 모임 참여자 정보 조회 기능을 구현 (#192)

* feat: 모임 참여자 정보 조회 API 기능 구현 (#178)

* test: 테스트 코드 구현 및 테스트 (#178)

---------

Co-authored-by: devxb <[email protected]>
Co-authored-by: xb205 <[email protected]>
Co-authored-by: ddingmin <[email protected]>
  • Loading branch information
4 people authored Feb 11, 2024
1 parent e8560f0 commit 3320e60
Show file tree
Hide file tree
Showing 12 changed files with 132 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/main/java/net/teumteum/alert/app/AlertHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ private String toCommaString(List<Long> ids) {
for (int i = 0; i < ids.size() - 1; i++) {
stringBuilder.append(ids.get(i)).append(",");
}
stringBuilder.append(ids.getLast());
stringBuilder.append(ids.get(ids.size() - 1));
return stringBuilder.toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public void setUserLocation(UserLocation userLocation, Long duration) {
} catch (JsonProcessingException e) {
throw new IllegalArgumentException(e);
}
setDataWithExpiration(key,value,duration);
setDataWithExpiration(key, value, duration);
}

public Set<UserLocation> getAllUserLocations() {
Expand All @@ -69,4 +69,8 @@ public Set<UserLocation> getAllUserLocations() {
}
}).collect(Collectors.toSet());
}

public void deleteUserLocation(Long id) {
deleteData(HASH_KEY + id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import net.teumteum.meeting.domain.Topic;
import net.teumteum.meeting.domain.request.CreateMeetingRequest;
import net.teumteum.meeting.domain.request.UpdateMeetingRequest;
import net.teumteum.meeting.domain.response.MeetingParticipantsResponse;
import net.teumteum.meeting.domain.response.MeetingResponse;
import net.teumteum.meeting.domain.response.MeetingsResponse;
import net.teumteum.meeting.model.PageDto;
Expand Down Expand Up @@ -97,6 +98,12 @@ public void deleteParticipant(@PathVariable("meetingId") Long meetingId) {
meetingService.cancelParticipant(meetingId, userId);
}

@GetMapping("/{meetingId}/participants")
@ResponseStatus(HttpStatus.OK)
public List<MeetingParticipantsResponse> getParticipants(@PathVariable("meetingId") Long meetingId) {
return meetingService.getParticipants(meetingId);
}

@PostMapping("/{meetingId}/reports")
@ResponseStatus(HttpStatus.CREATED)
public void reportMeeting(@PathVariable("meetingId") Long meetingId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package net.teumteum.meeting.domain.response;

import net.teumteum.user.domain.User;

public record MeetingParticipantsResponse(
Long id,
Long characterId,
String name,
String job
) {

public static MeetingParticipantsResponse of(
User user
) {
return new MeetingParticipantsResponse(
user.getId(),
user.getCharacterId(),
user.getName(),
user.getJob().getDetailJobClass()
);
}

}
15 changes: 15 additions & 0 deletions src/main/java/net/teumteum/meeting/service/MeetingService.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.teumteum.meeting.service;

import java.util.List;
import java.util.Optional;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import net.teumteum.meeting.domain.ImageUpload;
Expand All @@ -11,9 +12,11 @@
import net.teumteum.meeting.domain.Topic;
import net.teumteum.meeting.domain.request.CreateMeetingRequest;
import net.teumteum.meeting.domain.request.UpdateMeetingRequest;
import net.teumteum.meeting.domain.response.MeetingParticipantsResponse;
import net.teumteum.meeting.domain.response.MeetingResponse;
import net.teumteum.meeting.domain.response.MeetingsResponse;
import net.teumteum.meeting.model.PageDto;
import net.teumteum.user.domain.UserConnector;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
Expand All @@ -27,6 +30,7 @@ public class MeetingService {

private final MeetingRepository meetingRepository;
private final ImageUpload imageUpload;
private final UserConnector userConnector;

@Transactional
public MeetingResponse createMeeting(List<MultipartFile> images, CreateMeetingRequest meetingRequest, Long userId) {
Expand Down Expand Up @@ -148,6 +152,17 @@ public void cancelParticipant(Long meetingId, Long userId) {
existMeeting.cancelParticipant(userId);
}

@Transactional(readOnly = true)
public List<MeetingParticipantsResponse> getParticipants(Long meetingId) {
var existMeeting = getMeeting(meetingId);

return existMeeting.getParticipantUserIds().stream()
.map(userConnector::findUserById)
.flatMap(Optional::stream)
.map(MeetingParticipantsResponse::of)
.toList();
}

@Transactional
public void addBookmark(Long meetingId, Long userId) {
var existMeeting = getMeeting(meetingId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package net.teumteum.teum_teum.domain.response;

import java.util.List;
import java.util.Set;
import net.teumteum.teum_teum.domain.UserLocation;

public record UserAroundLocationsResponse(
List<UserAroundLocationResponse> aroundUserLocations
) {

public static UserAroundLocationsResponse of(List<UserLocation> userData) {
public static UserAroundLocationsResponse of(Set<UserLocation> userData) {
return new UserAroundLocationsResponse(
userData.stream()
.map(UserAroundLocationResponse::of)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,43 @@
import static java.lang.Math.toRadians;
import static java.util.Comparator.comparingDouble;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.teumteum.core.security.service.RedisService;
import net.teumteum.teum_teum.domain.UserLocation;
import net.teumteum.teum_teum.domain.request.UserLocationRequest;
import net.teumteum.teum_teum.domain.response.UserAroundLocationsResponse;
import org.springframework.stereotype.Service;

@Slf4j

@Service
@RequiredArgsConstructor
public class TeumTeumService {

private static final int SEARCH_LIMIT = 6;
private static final long USER_LOCATION_DATA_DURATION = 10L;
private static final int AROUND_USER_LOCATION_DISTANCE = 100;

private final RedisService redisService;

public UserAroundLocationsResponse saveAndGetUserAroundLocations(UserLocationRequest request) {
redisService.setUserLocation(request.toUserLocation(), 60L);
redisService.setUserLocation(request.toUserLocation(), USER_LOCATION_DATA_DURATION);
return getUserAroundLocations(request);
}

private UserAroundLocationsResponse getUserAroundLocations(UserLocationRequest request) {
Set<UserLocation> allUserLocations = redisService.getAllUserLocations();

List<UserLocation> aroundUserLocations = allUserLocations.stream()
Set<UserLocation> aroundUserLocations = allUserLocations.stream()
.filter(userLocation -> !userLocation.id().equals(request.id()))
.filter(userLocation -> calculateDistance(request.latitude(), request.longitude(),
userLocation.latitude(), userLocation.longitude()) <= 100)
userLocation.latitude(), userLocation.longitude()) <= AROUND_USER_LOCATION_DISTANCE)
.sorted(comparingDouble(userLocation
-> calculateDistance(request.latitude(), request.longitude(),
userLocation.latitude(), userLocation.longitude()))
).limit(SEARCH_LIMIT)
.toList();
.collect(Collectors.toSet());

return UserAroundLocationsResponse.of(aroundUserLocations);
}
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/net/teumteum/user/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,10 @@ public void addFriends(Long myId, Long friendId) {
public void withdraw(UserWithdrawRequest request, Long userId) {
var existUser = getUser(userId);

userRepository.delete(existUser);
redisService.deleteData(String.valueOf(userId));

userRepository.delete(existUser);

withdrawReasonRepository.saveAll(request.toEntity());
}

Expand All @@ -95,9 +96,9 @@ public UserRegisterResponse register(UserRegisterRequest request) {
return UserRegisterResponse.of(savedUser.getId(), jwtService.createServiceToken(savedUser));
}

@Transactional
public void logout(Long userId) {
redisService.deleteData(String.valueOf(userId));

SecurityService.clearSecurityContext();
}

Expand Down
8 changes: 8 additions & 0 deletions src/test/java/net/teumteum/integration/Api.java
Original file line number Diff line number Diff line change
Expand Up @@ -213,4 +213,12 @@ ResponseSpec registerUserReview(String accessToken, Long meetingId, ReviewRegist
.bodyValue(request)
.exchange();
}

ResponseSpec getMeetingParticipants(String accessToken, Long meetingId) {
return webTestClient
.get()
.uri("/meetings/" + meetingId + "/participants")
.header(HttpHeaders.AUTHORIZATION, accessToken)
.exchange();
}
}
19 changes: 17 additions & 2 deletions src/test/java/net/teumteum/integration/MeetingIntegrationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
class MeetingIntegrationTest extends IntegrationTest {

public static final int DEFAULT_QUERY_SIZE = 5;
public static final Pageable FIRST_PAGE_NATION = PageRequest.of(0, DEFAULT_QUERY_SIZE, Sort.Direction.DESC, "id");
private static final String VALID_TOKEN = "VALID_TOKEN";
private static final String INVALID_TOKEN = "IN_VALID_TOKEN";
public static final Pageable FIRST_PAGE_NATION = PageRequest.of(0, DEFAULT_QUERY_SIZE, Sort.Direction.DESC, "id");

@Nested
@DisplayName("단일 미팅 조회 API는")
Expand Down Expand Up @@ -288,7 +288,6 @@ void Return_400_bad_request_if_already_joined_meeting_id_received() {

securityContextSetting.set(me.getId());

loginContext.setUserId(me.getId());
api.joinMeeting(VALID_TOKEN, meeting.getId());
// when
var result = api.joinMeeting(VALID_TOKEN, meeting.getId());
Expand Down Expand Up @@ -472,4 +471,20 @@ void Return_400_bad_request_if_not_bookmarked_meeting_id_received() {
.expectBody(ErrorResponse.class);
}
}

@Nested
@DisplayName("미팅 참가자 조회 API는")
class Get_meeting_participants_api {

@Test
@DisplayName("참여한 meeting id 가 주어지면, 참여한 참가자들의 정보가 주어진다.")
void Get_participants_if_exist_meeting_id_received() {
// given
var meeting = repository.saveAndGetOpenMeeting();
// when
var result = api.getMeetingParticipants(VALID_TOKEN, meeting.getId());
// then
result.expectStatus().isOk();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.springframework.http.HttpHeaders.AUTHORIZATION;
import static org.springframework.http.MediaType.APPLICATION_JSON;
Expand Down Expand Up @@ -220,4 +221,25 @@ void Get_user_reviews_with_200_ok() throws Exception {
.andExpect(jsonPath("$[0].review").value("별로에요"));
}
}

@Nested
@DisplayName("회원 로그아웃 API는")
class Logout_user_api_unit {

@Test
@DisplayName("")
void Logout_user_with_200_ok() throws Exception {
// given
var userId = 1L;

doNothing().when(userService).logout(anyLong());

// when && then
mockMvc.perform(post("/users/logouts")
.with(csrf())
.header(AUTHORIZATION, VALID_ACCESS_TOKEN))
.andDo(print())
.andExpect(status().isOk());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public class UserServiceTest {
@Mock
MeetingConnector meetingConnector;


private User user;

@BeforeEach
Expand Down Expand Up @@ -111,7 +112,26 @@ void If_user_already_exist_register_user_card_fail() {
}

@Nested
@DisplayName("유저 탈퇴 API는")
@DisplayName("회원 로그아웃 API는")
class Logout_user_api_unit {

@Test
@DisplayName("정상적인 요청시, 회원 로그아웃을 진행하고 200 OK을 반환한다.")
void If_valid_user_logout_request_return_200_OK() {
// given
Long userId = 1L;
doNothing().when(redisService).deleteData(anyString());

// when
userService.logout(userId);

// then
verify(redisService, times(1)).deleteData(anyString());
}
}

@Nested
@DisplayName("회원 탈퇴 API는")
class Withdraw_user_api_unit {

@Test
Expand Down

0 comments on commit 3320e60

Please sign in to comment.