Skip to content

Commit

Permalink
feat: 유저 업데이트 기능 추가 (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
devxb authored Jan 2, 2024
1 parent 249f932 commit f6a1d05
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import net.teumteum.core.error.ErrorResponse;
import net.teumteum.user.domain.request.UserUpdateRequest;
import net.teumteum.user.domain.response.UserGetResponse;
import net.teumteum.user.domain.response.UsersGetByIdResponse;
import net.teumteum.user.service.UserService;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
Expand Down Expand Up @@ -38,6 +41,12 @@ public UsersGetByIdResponse getUsersById(@RequestParam("id") String userIds) {
return userService.getUsersById(parsedUserIds);
}

@PutMapping
@ResponseStatus(HttpStatus.OK)
public void updateUser(@RequestBody UserUpdateRequest request) {
userService.updateUser(request);
}

@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(IllegalArgumentException.class)
public ErrorResponse handleIllegalArgumentException(IllegalArgumentException illegalArgumentException) {
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/net/teumteum/user/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,30 @@ public class User extends TimeBaseEntity {
@PrePersist
private void assertField() {
assertName();
assertMannerTemperature();
}

public void update(User updatedUser) {
this.name = updatedUser.name;
this.birth = updatedUser.birth;
this.characterId = updatedUser.characterId;
this.activityArea = updatedUser.activityArea;
this.mbti = updatedUser.mbti;
this.status = updatedUser.status;
this.goal = updatedUser.goal;
this.job = updatedUser.job;
this.interests = updatedUser.interests;
assertName();
assertMannerTemperature();
}

private void assertName() {
Assert.doesNotContain(name, " ", () -> "이름에 공백이 포함되어 있습니다. \"" + name + "\"");
Assert.isTrue(name.length() >= 2 && name.length() <= 10, () -> "이름은 2자 ~ 10자 사이가 되어야 합니다. \"" + name + "\"");
}

private void assertMannerTemperature() {
Assert.isTrue(mannerTemperature >= 0, () -> "매너 온도는 0도 이상 이여야 합니다. \"" + mannerTemperature + "\"");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package net.teumteum.user.domain.request;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import net.teumteum.user.domain.ActivityArea;
import net.teumteum.user.domain.Job;
import net.teumteum.user.domain.JobStatus;
import net.teumteum.user.domain.Oauth;
import net.teumteum.user.domain.Terms;
import net.teumteum.user.domain.User;

public record UserUpdateRequest(
Long id,
String newName,
String newBirth,
Long newCharacterId,
NewActivityArea newActivityArea,
String newMbti,
String newStatus,
String newGoal,
NewJob newJob,
List<String> newInterests
) {

private static final Long IGNORE_ID = null;
private static final int IGNORE_MANNER_TEMPERATURE = -1;
private static final Oauth IGNORE_OAUTH = null;
private static final boolean NOT_CERTIFICATED = false;
private static final Terms IGNORE_TERMS = null;

public User toUser() {
return new User(
IGNORE_ID,
newName,
newBirth,
newCharacterId,
IGNORE_MANNER_TEMPERATURE,
IGNORE_OAUTH,
new ActivityArea(
newActivityArea.city,
newActivityArea.streets
),
newMbti,
JobStatus.valueOf(newStatus),
newGoal,
new Job(
newJob.name,
NOT_CERTIFICATED,
newJob.jobClass,
newJob.detailClass
),
newInterests,
IGNORE_TERMS
);
}

public record NewActivityArea(
String city,
List<String> streets
) {

}

public record NewJob(
String name,
@JsonProperty("class")
String jobClass,
String detailClass
) {

}
}
9 changes: 9 additions & 0 deletions src/main/java/net/teumteum/user/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import lombok.RequiredArgsConstructor;
import net.teumteum.user.domain.User;
import net.teumteum.user.domain.UserRepository;
import net.teumteum.user.domain.request.UserUpdateRequest;
import net.teumteum.user.domain.response.UserGetResponse;
import net.teumteum.user.domain.response.UsersGetByIdResponse;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -36,4 +37,12 @@ private void assertIsAllUserExist(List<Long> userIds, List<User> existUsers) {
Assert.isTrue(userIds.size() == existUsers.size(),
() -> "요청한 userId들에 해당하는 User가 모두 존재하지 않습니다.");
}

@Transactional
public void updateUser(UserUpdateRequest request) {
var existUser = userRepository.findById(request.id())
.orElseThrow(() -> new IllegalArgumentException("userId에 해당하는 user를 찾을 수 없습니다. \"" + request.id() + "\""));

existUser.update(request.toUser());
}
}
9 changes: 9 additions & 0 deletions src/test/java/net/teumteum/user/integration/Api.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.teumteum.user.integration;

import net.teumteum.user.domain.request.UserUpdateRequest;
import org.springframework.boot.test.context.TestComponent;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpHeaders;
Expand Down Expand Up @@ -31,4 +32,12 @@ ResponseSpec getUsersById(String token, String userIds) {
.exchange();
}

ResponseSpec updateUser(String token, UserUpdateRequest userUpdateRequest) {
return webTestClient.put()
.uri("/users")
.header(HttpHeaders.AUTHORIZATION, token)
.bodyValue(userUpdateRequest)
.exchange();
}

}
40 changes: 40 additions & 0 deletions src/test/java/net/teumteum/user/integration/RequestFixture.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package net.teumteum.user.integration;

import net.teumteum.user.domain.User;
import net.teumteum.user.domain.request.UserUpdateRequest;
import net.teumteum.user.domain.request.UserUpdateRequest.NewActivityArea;
import net.teumteum.user.domain.request.UserUpdateRequest.NewJob;

public class RequestFixture {

public static UserUpdateRequest userUpdateRequest(User user) {
return new UserUpdateRequest(
user.getId(),
"new_name",
user.getBirth(),
user.getCharacterId(),
newActivityArea(user),
user.getMbti(),
user.getStatus().name(),
user.getGoal(),
newJob(user),
user.getInterests()
);
}

private static NewActivityArea newActivityArea(User user) {
return new NewActivityArea(
user.getActivityArea().getCity(),
user.getActivityArea().getStreet()
);
}

private static NewJob newJob(User user) {
return new NewJob(
user.getJob().getName(),
user.getJob().getJobClass(),
user.getJob().getDetailJobClass()
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import net.teumteum.user.domain.response.UserGetResponse;
import net.teumteum.user.domain.response.UsersGetByIdResponse;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -103,4 +101,23 @@ void Return_400_bad_request_if_empty_user_ids_input() {
result.expectStatus().isBadRequest();
}
}

@Nested
@DisplayName("유저 수정 API는")
class Update_user_api {

@Test
@DisplayName("수정할 회원의 정보가 주어지면, 회원 정보를 수정한다")
void Update_user_info() {
// given
var existUser = repository.saveAndGetUser();
var updateUser = RequestFixture.userUpdateRequest(existUser);

// when
var result = api.updateUser(VALID_TOKEN, updateUser);

// then
result.expectStatus().isOk();
}
}
}

0 comments on commit f6a1d05

Please sign in to comment.