Skip to content

Commit acbd1fc

Browse files
committed
[OING-341] feature: 가족 이름 수정 API 추가 및 조회 API 응답 수정 (#264)
* feature: add familyName field in api * feature: add UpdateFamilyName API * fix: fix failed test related to family * test: add updateFamilyName test code * refactor: add familyNameEditorId to FamilyResponse
1 parent 8cbb346 commit acbd1fc

File tree

13 files changed

+177
-5
lines changed

13 files changed

+177
-5
lines changed

family/src/main/java/com/oing/controller/FamilyController.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.oing.controller;
22

33
import com.oing.domain.Family;
4+
import com.oing.dto.request.UpdateFamilyNameRequest;
45
import com.oing.dto.response.FamilyResponse;
56
import com.oing.exception.AuthorizationFailedException;
67
import com.oing.restapi.FamilyApi;
@@ -28,4 +29,14 @@ public FamilyResponse getFamilyCreatedAt(String familyId, String loginFamilyId)
2829
Family family = familyService.getFamilyById(familyId);
2930
return FamilyResponse.of(family);
3031
}
32+
33+
@Override
34+
public FamilyResponse updateFamilyName(String familyId, String loginFamilyId, String loginMemberId, UpdateFamilyNameRequest request) {
35+
if (!familyId.equals(loginFamilyId)) {
36+
throw new AuthorizationFailedException();
37+
}
38+
39+
Family family = familyService.updateFamilyName(familyId, loginMemberId, request.familyName());
40+
return FamilyResponse.of(family);
41+
}
3142
}

family/src/main/java/com/oing/domain/Family.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import lombok.Getter;
88
import lombok.NoArgsConstructor;
99

10+
import java.security.InvalidParameterException;
11+
1012
@Entity(name = "family")
1113
@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED)
1214
@AllArgsConstructor
@@ -20,13 +22,17 @@ public class Family extends BaseEntity {
2022
@Column(name = "family_name", columnDefinition = "CHAR(10)")
2123
private String familyName;
2224

25+
@Column(name = "family_name_editor_id", columnDefinition = "CHAR(26)")
26+
private String familyNameEditorId;
27+
2328
@Column(name = "score", nullable = false)
2429
private Integer score = 0;
2530

2631

27-
public Family(String id, String familyName) {
32+
public Family(String id, String familyName, String familyNameEditorId) {
2833
this.id = id;
2934
this.familyName = familyName;
35+
this.familyNameEditorId = familyNameEditorId;
3036
}
3137

3238
public static final int NEW_POST_SCORE = 20;
@@ -86,4 +92,21 @@ public void subtractScore(int score) {
8692
public void resetScore() {
8793
this.score = 0;
8894
}
95+
96+
public void updateFamilyName(String familyName, String loginFamilyId) {
97+
if (familyName == null) {
98+
this.familyName = null;
99+
this.familyNameEditorId = null;
100+
} else {
101+
validateFamilyName(familyName);
102+
this.familyName = familyName;
103+
this.familyNameEditorId = loginFamilyId;
104+
}
105+
}
106+
107+
private void validateFamilyName(String familyName) {
108+
if ((familyName.codePoints().count() > 10) || familyName.isBlank()) {
109+
throw new InvalidParameterException();
110+
}
111+
}
89112
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.oing.dto.request;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import jakarta.validation.constraints.Size;
5+
6+
@Schema(description = "가족 이름 수정 요청")
7+
public record UpdateFamilyNameRequest(
8+
9+
@Size(max = 10)
10+
@Schema(description = "가족 이름", example = "오잉")
11+
String familyName
12+
) {
13+
}

family/src/main/java/com/oing/dto/response/FamilyResponse.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,20 @@ public record FamilyResponse(
1111
@Schema(description = "가족 ID", example = "01HGW2N7EHJVJ4CJ999RRS2E97")
1212
String familyId,
1313

14+
@Schema(description = "가족 이름", example = "미밍이네")
15+
String familyName,
16+
17+
@Schema(description = "가족 이름 마지막 수정자 ID", example = "01HGW2N7EHJVJ4CJ999RRS2E97")
18+
String familyNameEditorId,
19+
1420
@Schema(description = "가족 생성 시간", example = "2021-12-05T12:30:00.000+09:00")
1521
ZonedDateTime createdAt
1622
) {
1723
public static FamilyResponse of(Family family) {
1824
return new FamilyResponse(
1925
family.getId(),
26+
family.getFamilyName(),
27+
family.getFamilyNameEditorId(),
2028
family.getCreatedAt().atZone(ZoneId.systemDefault())
2129
);
2230
}

family/src/main/java/com/oing/restapi/FamilyApi.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.oing.restapi;
22

3+
import com.oing.dto.request.UpdateFamilyNameRequest;
34
import com.oing.dto.response.FamilyResponse;
45
import com.oing.util.security.LoginFamilyId;
6+
import com.oing.util.security.LoginMemberId;
57
import io.swagger.v3.oas.annotations.Operation;
68
import io.swagger.v3.oas.annotations.Parameter;
79
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -28,4 +30,23 @@ FamilyResponse getFamilyCreatedAt(
2830
@LoginFamilyId
2931
String loginFamilyId
3032
);
33+
34+
@Operation(summary = "가족 이름 변경", description = "가족 이름을 변경합니다.")
35+
@PutMapping("/{familyId}/name")
36+
FamilyResponse updateFamilyName(
37+
@Parameter(description = "가족 ID", example = "01HGW2N7EHJVJ4CJ999RRS2E97")
38+
@PathVariable
39+
String familyId,
40+
41+
@Parameter(hidden = true)
42+
@LoginFamilyId
43+
String loginFamilyId,
44+
45+
@Parameter(hidden = true)
46+
@LoginMemberId
47+
String loginMemberId,
48+
49+
@RequestBody
50+
UpdateFamilyNameRequest request
51+
);
3152
}

family/src/main/java/com/oing/service/FamilyService.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public class FamilyService {
2424

2525
@Transactional
2626
public Family createFamily() {
27-
Family family = new Family(identityGenerator.generateIdentity(), null);
27+
Family family = new Family(identityGenerator.generateIdentity(), null, null);
2828
return familyRepository.save(family);
2929
}
3030

@@ -57,4 +57,11 @@ private int calculateLiveFamilyTopPercentage(String familyId) {
5757
// score 를 통한 순위를 통해 전체 가족들 중 상위 백분율 계산 (1%에 가까울수록 고순위)
5858
return familyScoreBridge.calculateFamilyTopPercentage(rank, familiesCount);
5959
}
60+
61+
@Transactional
62+
public Family updateFamilyName(String familyId, String loginMemberId, String familyName) {
63+
Family family = getFamilyById(familyId);
64+
family.updateFamilyName(familyName, loginMemberId);
65+
return family;
66+
}
6067
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.oing.service;
2+
3+
import com.oing.domain.Family;
4+
import com.oing.repository.FamilyRepository;
5+
import com.oing.util.IdentityGenerator;
6+
import jakarta.transaction.Transactional;
7+
import org.junit.jupiter.api.Test;
8+
import org.junit.jupiter.api.extension.ExtendWith;
9+
import org.mockito.InjectMocks;
10+
import org.mockito.Mock;
11+
import org.mockito.junit.jupiter.MockitoExtension;
12+
import org.springframework.test.context.ActiveProfiles;
13+
14+
import java.security.InvalidParameterException;
15+
import java.util.Optional;
16+
17+
import static org.junit.jupiter.api.Assertions.assertEquals;
18+
import static org.junit.jupiter.api.Assertions.assertThrows;
19+
import static org.mockito.Mockito.when;
20+
21+
@Transactional
22+
@ActiveProfiles("test")
23+
@ExtendWith(MockitoExtension.class)
24+
public class FamilyServiceTest {
25+
26+
@InjectMocks
27+
private FamilyService familyService;
28+
@Mock
29+
private FamilyRepository familyRepository;
30+
@Mock
31+
private FamilyTopPercentageHistoryService familyTopPercentageHistoryService;
32+
@Mock
33+
private FamilyScoreBridge familyScoreBridge;
34+
@Mock
35+
private IdentityGenerator identityGenerator;
36+
37+
@Test
38+
void 가족_이름_수정_테스트() {
39+
// given
40+
String newName = "new-name";
41+
String memberId = "1";
42+
String familyId = "1";
43+
44+
// when
45+
when(familyRepository.findById(familyId)).thenReturn(Optional.of(new Family(familyId, null, null)));
46+
Family family = familyService.updateFamilyName(familyId, memberId, newName);
47+
48+
// then
49+
assertEquals(newName, family.getFamilyName());
50+
assertEquals(memberId, family.getFamilyNameEditorId());
51+
}
52+
53+
@Test
54+
void 열_자_초과_가족_이름_수정_예외_검증() {
55+
// given
56+
String newName = "wrong-length-name";
57+
String memberId = "1";
58+
String familyId = "1";
59+
60+
// when
61+
when(familyRepository.findById(familyId)).thenReturn(Optional.of(new Family(familyId, null, null)));
62+
63+
// then
64+
assertThrows(InvalidParameterException.class, () -> familyService.updateFamilyName(familyId, memberId, newName));
65+
}
66+
67+
@Test
68+
void 공백만을_포함한_이름_수정_예외_검증() {
69+
// given
70+
String newName = " ";
71+
String memberId = "1";
72+
String familyId = "1";
73+
74+
// when
75+
when(familyRepository.findById(familyId)).thenReturn(Optional.of(new Family(familyId, null, null)));
76+
77+
// then
78+
assertThrows(InvalidParameterException.class, () -> familyService.updateFamilyName(familyId, memberId, newName));
79+
}
80+
}

gateway/src/main/java/com/oing/controller/MainViewController.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public class MainViewController implements MainViewApi {
3030
private final MemberBridge memberBridge;
3131
private final MissionBridge missionBridge;
3232
private final PostController postController;
33+
private final FamilyBridge familyBridge;
3334

3435
private static final int PAGE_FETCH_SIZE = 1000;
3536

@@ -75,10 +76,12 @@ public DaytimePageResponse getDaytimePage(
7576
.isMeMissionUploadedToday();
7677
int leftUploadCountUntilMissionUnlock = postController.getRemainingSurvivalPostCount(loginMemberId, loginMemberId, familyId)
7778
.leftUploadCountUntilMissionUnlock();
79+
String familyName = familyBridge.findFamilyNameByFamilyId(familyId);
7880

7981
return new DaytimePageResponse(
8082
members.stream().sorted(comparator).map((member) -> new MainPageTopBarResponse(
8183
member.memberId(),
84+
familyName,
8285
member.imageUrl(),
8386
String.valueOf(member.name().charAt(0)),
8487
member.name(),
@@ -143,8 +146,10 @@ public DaytimePageResponse getDaytimePage(
143146
public NighttimePageResponse getNighttimePage(String loginMemberId, String loginFamilyId) {
144147
Page<FamilyMemberProfileResponse> members = memberService.getFamilyMembersProfilesByFamilyId(loginFamilyId, 1, PAGE_FETCH_SIZE);
145148
LocalDate today = ZonedDateTime.now().toLocalDate();
149+
String familyName = familyBridge.findFamilyNameByFamilyId(loginFamilyId);
146150
List<MainPageTopBarResponse> mainPageTopBarResponses = members.stream().map((member) -> new MainPageTopBarResponse(
147151
member.memberId(),
152+
familyName,
148153
member.imageUrl(),
149154
String.valueOf(member.name().charAt(0)),
150155
member.name(),

gateway/src/main/java/com/oing/dto/response/MainPageTopBarResponse.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ public record MainPageTopBarResponse(
1313
@Schema(description = "멤버ID", example = "01HGW2N7EHJVJ4CJ999RRS2E97")
1414
String memberId,
1515

16+
@Schema(description = "가족 이름", example = "미밍이네")
17+
String familyName,
18+
1619
@Schema(description = "이미지 URL", example = "https://no5ing.com/image/01HGW2N7EHJVJ4CJ999RRS2E97")
1720
String imageUrl,
1821

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE `family` ADD COLUMN (`family_name_editor_id` CHAR(26) COMMENT 'ULID');

0 commit comments

Comments
 (0)