Skip to content

Commit

Permalink
Merge pull request #94 from playkuround/feat/userNotification
Browse files Browse the repository at this point in the history
refactor: user notification
  • Loading branch information
redcarrot1 authored Mar 25, 2024
2 parents 7bb07a0 + 771e763 commit 8e71e21
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public boolean saveManualBadge(String userEmail, BadgeType badgeType, boolean re
Badge badge = Badge.createBadge(user, badgeType);
badgeRepository.save(badge);
if (registerMessage) {
user.addNewBadgeNotification(badgeType.name());
user.addNewBadgeNotification(badgeType);
}
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import com.playkuround.playkuroundserver.domain.user.api.response.UserProfileResponse;
import com.playkuround.playkuroundserver.domain.user.application.UserProfileService;
import com.playkuround.playkuroundserver.domain.user.domain.HighestScore;
import com.playkuround.playkuroundserver.domain.user.dto.UserNotification;
import com.playkuround.playkuroundserver.domain.user.domain.Notification;
import com.playkuround.playkuroundserver.domain.user.domain.NotificationEnum;
import com.playkuround.playkuroundserver.global.common.response.ApiResponse;
import com.playkuround.playkuroundserver.global.security.UserDetailsImpl;
import com.playkuround.playkuroundserver.global.util.ApiUtils;
Expand Down Expand Up @@ -54,10 +55,10 @@ public ApiResponse<Boolean> isAvailableNickname(@RequestParam("nickname") String
@GetMapping("/notification")
@Operation(summary = "유저 알림 얻기",
description = "유저 개인 알림을 얻습니다. 저장된 메시지는 (정상적인) 호출 이후 삭제됩니다.<br>" +
"=== name 명 리스트 ===<br>" +
"=== name 명 리스트(new_badge는 description도 중요) ===<br>" +
"1. 시스템 점검 중일 때(단독으로만 반환): system_check<br>" +
"2. 앱 버전 업데이트가 필요할 때(단독으로만 반환): update<br>" +
"3. 새로운 뱃지 획득: new_badge<br>" +
"3. 새로운 뱃지 획득: new_badge(MONTHLY_RANKING_1, MONTHLY_RANKING_2, MONTHLY_RANKING_3, COLLEGE_OF_BUSINESS_ADMINISTRATION_100_AND_FIRST_PLACE)<br>" +
"4. 개인 알림: alarm",
parameters = {
@Parameter(name = "version", description = "현재 앱 버전", example = "2.0.2", required = true),
Expand All @@ -69,13 +70,13 @@ public ApiResponse<List<UserNotificationResponse>> getNotification(@Authenticati
@RequestParam(name = "os", required = false, defaultValue = "android") String os) {
List<UserNotificationResponse> response;
if (!SystemCheck.isSystemAvailable()) {
response = UserNotificationResponse.from(UserNotificationResponse.NotificationEnum.SYSTEM_CHECK);
response = UserNotificationResponse.from(NotificationEnum.SYSTEM_CHECK);
}
else if (!AppVersion.isLatestUpdatedVersion(os, appVersion)) {
response = UserNotificationResponse.from(UserNotificationResponse.NotificationEnum.UPDATE);
response = UserNotificationResponse.from(NotificationEnum.UPDATE);
}
else {
List<UserNotification> notificationList = userProfileService.getNotification(userDetails.getUser());
List<Notification> notificationList = userProfileService.getNotification(userDetails.getUser());
response = UserNotificationResponse.from(notificationList);
}
return ApiUtils.success(response);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.playkuround.playkuroundserver.domain.user.api.response;

import com.playkuround.playkuroundserver.domain.user.dto.UserNotification;
import com.playkuround.playkuroundserver.domain.user.domain.Notification;
import com.playkuround.playkuroundserver.domain.user.domain.NotificationEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;
Expand All @@ -18,25 +19,12 @@ public class UserNotificationResponse {
private String description;

public static List<UserNotificationResponse> from(NotificationEnum notificationEnum) {
return List.of(new UserNotificationResponse(notificationEnum.name, notificationEnum.description));
return List.of(new UserNotificationResponse(notificationEnum.getName(), notificationEnum.getDefaultMessage()));
}

public static List<UserNotificationResponse> from(List<UserNotification> notificationList) {
public static List<UserNotificationResponse> from(List<Notification> notificationList) {
return notificationList.stream()
.map(notification -> new UserNotificationResponse(notification.name(), notification.description()))
.map(notification -> new UserNotificationResponse(notification.getName(), notification.getDescription()))
.toList();
}

public enum NotificationEnum {
UPDATE("update", "application is must update"),
SYSTEM_CHECK("system_check", "system is not available");

private final String name;
private final String description;

NotificationEnum(String name, String description) {
this.name = name;
this.description = description;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

import com.playkuround.playkuroundserver.domain.user.dao.UserRepository;
import com.playkuround.playkuroundserver.domain.user.domain.HighestScore;
import com.playkuround.playkuroundserver.domain.user.domain.Notification;
import com.playkuround.playkuroundserver.domain.user.domain.User;
import com.playkuround.playkuroundserver.domain.user.dto.UserNotification;
import com.playkuround.playkuroundserver.global.util.BadWordFilterUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

@Service
Expand All @@ -34,21 +34,16 @@ public HighestScore getUserGameHighestScore(User user) {
}

@Transactional
public List<UserNotification> getNotification(User user) {
String str_notification = user.getNotification();
if (str_notification == null) {
public List<Notification> getNotification(User user) {
Set<Notification> notificationSet = user.getNotification();
if (notificationSet == null || notificationSet.isEmpty()) {
return new ArrayList<>();
}

List<Notification> userNotifications = notificationSet.stream().toList();
user.clearNotification();
userRepository.save(user);
return convertToUserNotificationList(str_notification);
}

private List<UserNotification> convertToUserNotificationList(String str_notification) {
return Arrays.stream(str_notification.split("@"))
.map(notifications -> notifications.split("#"))
.filter(nameAndDescription -> nameAndDescription.length == 2)
.map(nameAndDescription -> new UserNotification(nameAndDescription[0], nameAndDescription[1]))
.toList();
return userNotifications;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.playkuround.playkuroundserver.domain.user.domain;

import lombok.EqualsAndHashCode;
import lombok.Getter;

import java.util.Objects;

@Getter
@EqualsAndHashCode
public class Notification {

private final String name;
private final String description;

public Notification(NotificationEnum notificationEnum, String description) {
Objects.requireNonNull(notificationEnum, "notificationEnum must be provided");

this.name = notificationEnum.getName();
this.description = (description == null ? "" : description);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.playkuround.playkuroundserver.domain.user.domain;

import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;

import java.util.*;
import java.util.stream.Collectors;

@Converter
public class NotificationConverter implements AttributeConverter<Set<Notification>, String> {

@Override
public String convertToDatabaseColumn(Set<Notification> notifications) {
if (notifications == null) {
return null;
}

StringBuilder sb = new StringBuilder();
for (Notification notification : notifications) {
if (!sb.isEmpty()) {
sb.append("@");
}
sb.append(notification.getName())
.append("#")
.append(notification.getDescription());
}
return sb.toString();
}

@Override
public Set<Notification> convertToEntityAttribute(String notifications) {
if (notifications == null || notifications.isEmpty()) {
return new HashSet<>();
}
return Arrays.stream(notifications.split("@"))
.map(notification -> notification.split("#"))
.filter(nameAndDescription -> nameAndDescription.length == 2)
.map(nameAndDescription -> {
Optional<NotificationEnum> notificationEnum = NotificationEnum.fromString(nameAndDescription[0]);
return notificationEnum
.map(anEnum -> new Notification(anEnum, nameAndDescription[1]))
.orElse(null);
})
.filter(Objects::nonNull)
.collect(Collectors.toSet());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.playkuround.playkuroundserver.domain.user.domain;

import lombok.Getter;

import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toMap;

@Getter
public enum NotificationEnum {

UPDATE("update", "application is must update"),
SYSTEM_CHECK("system_check", "system is not available"),
ALARM("alarm", "user message"),
NEW_BADGE("new_badge", "user get new badge");

private static final Map<String, NotificationEnum> stringToEnum =
Stream.of(values())
.collect(toMap(NotificationEnum::getName, e -> e));
private final String name;
private final String defaultMessage;

NotificationEnum(String name, String defaultMessage) {
this.name = name;
this.defaultMessage = defaultMessage;
}

public static Optional<NotificationEnum> fromString(String source) {
return Optional.ofNullable(stringToEnum.get(source));
}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package com.playkuround.playkuroundserver.domain.user.domain;

import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType;
import com.playkuround.playkuroundserver.domain.common.BaseTimeEntity;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.HashSet;
import java.util.Set;

@Entity
@Getter
@Table(name = "users")
Expand Down Expand Up @@ -36,7 +40,8 @@ public class User extends BaseTimeEntity {
@Embedded
private HighestScore highestScore;

private String notification;
@Convert(converter = NotificationConverter.class)
private Set<Notification> notification;

private User(String email, String nickname, Major major, Role role) {
this.email = email;
Expand All @@ -61,19 +66,15 @@ public void increaseAttendanceDay() {
}

public void clearNotification() {
this.notification = null;
}

private void addNotification(String name, String description) {
if (notification == null) {
notification = name + "#" + description;
}
else {
notification += "@" + name + "#" + description;
if (this.notification != null) {
this.notification.clear();
}
}

public void addNewBadgeNotification(String description) {
addNotification("new_badge", description);
public void addNewBadgeNotification(BadgeType badgeType) {
if (this.notification == null) {
this.notification = new HashSet<>();
}
this.notification.add(new Notification(NotificationEnum.NEW_BADGE, badgeType.name()));
}
}
3 changes: 3 additions & 0 deletions src/main/resources/logback-spring.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
<root level="info">
<appender-ref ref="STDOUT"/>
</root>
<logger name="org.hibernate.SQL" level="debug" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
</springProfile>

<!-- local 환경 -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark;
import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType;
import com.playkuround.playkuroundserver.domain.user.dao.UserRepository;
import com.playkuround.playkuroundserver.domain.user.domain.Notification;
import com.playkuround.playkuroundserver.domain.user.domain.NotificationEnum;
import com.playkuround.playkuroundserver.domain.user.domain.User;
import com.playkuround.playkuroundserver.global.util.DateUtils;
import org.junit.jupiter.api.DisplayName;
Expand Down Expand Up @@ -385,7 +387,8 @@ void success_2() {

// then
assertThat(result).isTrue();
assertThat(user.getNotification()).isEqualTo("new_badge#" + badgeType.name());
assertThat(user.getNotification())
.containsOnly(new Notification(NotificationEnum.NEW_BADGE, badgeType.name()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
import com.playkuround.playkuroundserver.domain.common.SystemCheck;
import com.playkuround.playkuroundserver.domain.user.api.request.ManualBadgeSaveRequest;
import com.playkuround.playkuroundserver.domain.user.dao.UserRepository;
import com.playkuround.playkuroundserver.domain.user.domain.Major;
import com.playkuround.playkuroundserver.domain.user.domain.Role;
import com.playkuround.playkuroundserver.domain.user.domain.User;
import com.playkuround.playkuroundserver.domain.user.domain.*;
import com.playkuround.playkuroundserver.securityConfig.WithMockCustomUser;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.DisplayName;
Expand All @@ -27,6 +25,7 @@

import java.util.List;
import java.util.Optional;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
Expand Down Expand Up @@ -190,7 +189,9 @@ void success_2() throws Exception {
assertThat(badges.get(0).getBadgeType()).isEqualTo(BadgeType.MONTHLY_RANKING_1);

Optional<User> optionalUser = userRepository.findByEmail(user.getEmail());
assertThat(optionalUser.get().getNotification()).isEqualTo("new_badge#" + BadgeType.MONTHLY_RANKING_1.name());
Set<Notification> notification = optionalUser.get().getNotification();
assertThat(notification)
.containsOnly(new Notification(NotificationEnum.NEW_BADGE, BadgeType.MONTHLY_RANKING_1.name()));
}

@Test
Expand Down
Loading

0 comments on commit 8e71e21

Please sign in to comment.