-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: 유저 조회 API를 개발한다 * feat: ErrorResponse를 정의한다
- Loading branch information
Showing
12 changed files
with
290 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package net.teumteum.core.error; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Getter | ||
@NoArgsConstructor | ||
@AllArgsConstructor(access = AccessLevel.PRIVATE) | ||
public class ErrorResponse { | ||
|
||
private String message; | ||
|
||
public static ErrorResponse of(Throwable exception) { | ||
return new ErrorResponse(exception.getMessage()); | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
src/main/java/net/teumteum/user/controller/UserController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package net.teumteum.user.controller; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import net.teumteum.core.error.ErrorResponse; | ||
import net.teumteum.user.domain.response.UserGetResponse; | ||
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.RequestMapping; | ||
import org.springframework.web.bind.annotation.ResponseStatus; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
@RequestMapping("/users") | ||
public class UserController { | ||
|
||
private final UserService userService; | ||
|
||
@GetMapping("/{userId}") | ||
@ResponseStatus(HttpStatus.OK) | ||
public UserGetResponse getUserById(@PathVariable("userId") Long userId) { | ||
return userService.getUserById(userId); | ||
} | ||
|
||
@ResponseStatus(HttpStatus.BAD_REQUEST) | ||
@ExceptionHandler(IllegalArgumentException.class) | ||
public ErrorResponse handleIllegalArgumentException(IllegalArgumentException illegalArgumentException) { | ||
return ErrorResponse.of(illegalArgumentException); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
src/main/java/net/teumteum/user/domain/response/UserGetResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package net.teumteum.user.domain.response; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import java.util.List; | ||
import net.teumteum.user.domain.User; | ||
|
||
public record UserGetResponse( | ||
Long id, | ||
String name, | ||
String birth, | ||
Long characterId, | ||
int mannerTemperature, | ||
String authenticated, | ||
ActivityArea activityArea, | ||
String mbti, | ||
String status, | ||
String goal, | ||
Job job, | ||
List<String> interests | ||
) { | ||
|
||
public static UserGetResponse of(User user) { | ||
return new UserGetResponse( | ||
user.getId(), | ||
user.getName(), | ||
user.getBirth(), | ||
user.getCharacterId(), | ||
user.getMannerTemperature(), | ||
user.getOauth().getAuthenticated(), | ||
ActivityArea.of(user), | ||
user.getMbti(), | ||
user.getStatus().name(), | ||
user.getGoal(), | ||
Job.of(user), | ||
user.getInterests() | ||
); | ||
} | ||
|
||
public record ActivityArea( | ||
String city, | ||
List<String> streets | ||
) { | ||
|
||
public static ActivityArea of(User user) { | ||
return new ActivityArea( | ||
user.getActivityArea().getCity(), | ||
user.getActivityArea().getStreet() | ||
); | ||
} | ||
|
||
} | ||
|
||
public record Job( | ||
String name, | ||
boolean certificated, | ||
@JsonProperty("class") | ||
String jobClass, | ||
String detailClass | ||
) { | ||
|
||
public static Job of(User user) { | ||
return new Job( | ||
user.getJob().getName(), | ||
user.getJob().isCertificated(), | ||
user.getJob().getJobClass(), | ||
user.getJob().getDetailJobClass() | ||
); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package net.teumteum.user.service; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import net.teumteum.user.domain.UserRepository; | ||
import net.teumteum.user.domain.response.UserGetResponse; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
@Transactional(readOnly = true) | ||
public class UserService { | ||
|
||
private final UserRepository userRepository; | ||
|
||
public UserGetResponse getUserById(Long userId) { | ||
var existUser = userRepository.findById(userId) | ||
.orElseThrow(() -> new IllegalArgumentException("userId에 해당하는 user를 찾을 수 없습니다. \"" + userId + "\"")); | ||
|
||
return UserGetResponse.of(existUser); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package net.teumteum.user.integration; | ||
|
||
import org.springframework.boot.test.context.TestComponent; | ||
import org.springframework.context.ApplicationContext; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.test.web.reactive.server.WebTestClient; | ||
import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; | ||
|
||
@TestComponent | ||
class Api { | ||
|
||
private final WebTestClient webTestClient; | ||
|
||
public Api(ApplicationContext applicationContext) { | ||
var controllers = applicationContext.getBeansWithAnnotation(Controller.class).values(); | ||
webTestClient = WebTestClient.bindToController(controllers.toArray()).build(); | ||
} | ||
|
||
ResponseSpec getUser(String token, Long userId) { | ||
return webTestClient.get() | ||
.uri("/users/" + userId) | ||
.header(HttpHeaders.AUTHORIZATION, token) | ||
.exchange(); | ||
} | ||
|
||
} |
19 changes: 19 additions & 0 deletions
19
src/test/java/net/teumteum/user/integration/IntegrationTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package net.teumteum.user.integration; | ||
|
||
import net.teumteum.Application; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; | ||
import org.springframework.test.context.ContextConfiguration; | ||
|
||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) | ||
@ContextConfiguration(classes = {Application.class, Api.class, Repository.class}) | ||
abstract class IntegrationTest { | ||
|
||
@Autowired | ||
protected Api api; | ||
|
||
@Autowired | ||
protected Repository repository; | ||
|
||
} |
24 changes: 24 additions & 0 deletions
24
src/test/java/net/teumteum/user/integration/Repository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package net.teumteum.user.integration; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import net.teumteum.user.domain.User; | ||
import net.teumteum.user.domain.UserFixture; | ||
import net.teumteum.user.domain.UserRepository; | ||
import org.springframework.boot.test.context.TestComponent; | ||
|
||
@TestComponent | ||
@RequiredArgsConstructor | ||
class Repository { | ||
|
||
private final UserRepository userRepository; | ||
|
||
User saveAndGetUser() { | ||
var user = UserFixture.getNullIdUser(); | ||
return userRepository.saveAndFlush(user); | ||
} | ||
|
||
void clear() { | ||
userRepository.deleteAll(); | ||
} | ||
|
||
} |
61 changes: 61 additions & 0 deletions
61
src/test/java/net/teumteum/user/integration/UserIntegrationTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package net.teumteum.user.integration; | ||
|
||
import net.teumteum.core.error.ErrorResponse; | ||
import net.teumteum.user.domain.response.UserGetResponse; | ||
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; | ||
|
||
@DisplayName("유저 통합테스트의") | ||
class UserIntegrationTest extends IntegrationTest { | ||
|
||
private static final String VALID_TOKEN = "VALID_TOKEN"; | ||
private static final String INVALID_TOKEN = "IN_VALID_TOKEN"; | ||
|
||
@AfterEach | ||
@BeforeEach | ||
void clearAll() { | ||
repository.clear(); | ||
} | ||
|
||
@Nested | ||
@DisplayName("유저 조회 API는") | ||
class Find_user_api { | ||
|
||
@Test | ||
@DisplayName("존재하는 유저의 id가 주어지면, 유저 정보를 응답한다.") | ||
void Return_user_info_if_exist_user_id_received() { | ||
// given | ||
var user = repository.saveAndGetUser(); | ||
var expected = UserGetResponse.of(user); | ||
|
||
// when | ||
var result = api.getUser(VALID_TOKEN, user.getId()); | ||
|
||
// then | ||
Assertions.assertThat( | ||
result.expectStatus().isOk() | ||
.expectBody(UserGetResponse.class) | ||
.returnResult().getResponseBody()) | ||
.usingRecursiveComparison() | ||
.isEqualTo(expected); | ||
} | ||
|
||
@Test | ||
@DisplayName("존재하지 않는 유저의 id가 주어지면, 400 Bad Request를 응답한다.") | ||
void Return_400_bad_request_if_not_exists_user_id_received() { | ||
// given | ||
var notExistUserId = 1L; | ||
|
||
// when | ||
var result = api.getUser(VALID_TOKEN, notExistUserId); | ||
|
||
// then | ||
result.expectStatus().isBadRequest() | ||
.expectBody(ErrorResponse.class); | ||
} | ||
} | ||
} |