Skip to content

Commit

Permalink
Merge pull request #12 from taco-official/KL-66/임시-유저-api-구현
Browse files Browse the repository at this point in the history
feat(KL-66): create User API
  • Loading branch information
idealflower-k authored Jul 22, 2024
2 parents 83afae0 + 5a2e0f2 commit 934d8b7
Show file tree
Hide file tree
Showing 10 changed files with 340 additions and 1 deletion.
28 changes: 28 additions & 0 deletions src/main/java/taco/klkl/domain/user/controller/UserController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package taco.klkl.domain.user.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import lombok.extern.slf4j.Slf4j;
import taco.klkl.domain.user.domain.User;
import taco.klkl.domain.user.service.UserService;

@Slf4j
@RestController
@RequestMapping("api/v1/users")
public class UserController {
final UserService userService;

public UserController(UserService userService) {
this.userService = userService;
}

@GetMapping("/me")
public ResponseEntity<User> getMe() {
User user = userService.me();
return new ResponseEntity<>(user, HttpStatus.OK);
}
}
11 changes: 11 additions & 0 deletions src/main/java/taco/klkl/domain/user/dao/UserRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package taco.klkl.domain.user.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import taco.klkl.domain.user.domain.User;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findFirstByName(String name);
}
60 changes: 60 additions & 0 deletions src/main/java/taco/klkl/domain/user/domain/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package taco.klkl.domain.user.domain;

import java.time.LocalDateTime;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.PrePersist;
import lombok.Getter;
import lombok.NoArgsConstructor;
import taco.klkl.global.common.enums.Gender;

@Getter
@NoArgsConstructor
@Entity(name = "user")
public class User {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "user_id")
private Long id;

@Column(length = 500, nullable = false)
private String profile = "image/default.jpg";

@Column(unique = true, length = 30, nullable = false)
private String name;

@Column(length = 1, nullable = false)
private Gender gender;

@Column(nullable = false)
private int age;

@Column(length = 100)
private String description;

// TODO: created_at 이름으로 json나가야 함
@Column(name = "created_at", nullable = false, updatable = false)
private LocalDateTime createdAt;

@PrePersist
protected void onCreate() {
if (this.profile == null) {
this.profile = "image/default.jpg";
}
this.createdAt = LocalDateTime.now();
}

public User(String profile, String name, Gender gender, int age, String description) {
this.profile = profile;
this.name = name;
this.gender = gender;
this.age = age;
this.description = description;
}

}
34 changes: 34 additions & 0 deletions src/main/java/taco/klkl/domain/user/service/UserService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package taco.klkl.domain.user.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import lombok.extern.slf4j.Slf4j;
import taco.klkl.domain.user.dao.UserRepository;
import taco.klkl.domain.user.domain.User;

@Slf4j
@Service
@Transactional
public class UserService {
@Autowired
UserRepository userRepository;

/**
* 임시 나의 정보 조회
* Id 1번 유저를 반환합니다.
*/
public User me() {
return userRepository.findFirstByName("testUser");
}

/**
* @param user user object
* @return Long user_id
*/
public Long join(User user) {
userRepository.save(user);
return user.getId();
}
}
31 changes: 31 additions & 0 deletions src/main/java/taco/klkl/global/common/convert/GenderConvert.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package taco.klkl.global.common.convert;

import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
import taco.klkl.global.common.enums.Gender;

@Converter(autoApply = true)
public class GenderConvert implements AttributeConverter<Gender, String> {

@Override
public String convertToDatabaseColumn(Gender gender) {
if (gender == null) {
return null;
}

return gender.getDescription();
}

@Override
public Gender convertToEntityAttribute(String dbData) {
if (dbData == null || dbData.isEmpty()) {
throw new IllegalArgumentException("Unknown value" + dbData);
}

return switch (dbData) {
case "남" -> Gender.MALE;
case "여" -> Gender.FEMALE;
default -> throw new IllegalArgumentException("Unknown value" + dbData);
};
}
}
13 changes: 13 additions & 0 deletions src/main/java/taco/klkl/global/common/enums/Gender.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package taco.klkl.global.common.enums;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum Gender {
MALE("남"),
FEMALE("여");

private final String description;
}
3 changes: 2 additions & 1 deletion src/main/resources/application-h2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ spring:
# Database Setting Info (Database를 H2로 사용하기 위해 H2연결 정보 입력)
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:klkldb
url: jdbc:h2:mem:klkldb;NON_KEYWORDS=USER

username: sa
password:
jpa:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package taco.klkl.domain.user.integration;

import static org.hamcrest.Matchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;

import taco.klkl.domain.user.dao.UserRepository;
import taco.klkl.domain.user.domain.User;
import taco.klkl.domain.user.service.UserService;
import taco.klkl.global.common.enums.Gender;

@SpringBootTest
@AutoConfigureMockMvc
@Transactional
public class UserIntegrationTest {
@Autowired
MockMvc mockMvc;

@Autowired
UserService userService;

@Autowired
UserRepository userRepository;

User user;

@Test
public void testUserMe() throws Exception {
// given
User user = new User(null, "testUser", Gender.MALE, 20, "테스트 유저입니다.");

// when
userRepository.save(user);
user = userService.me();

// then
mockMvc.perform(get("/api/v1/users/me"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.isSuccess", is(true)))
.andExpect(jsonPath("$.code", is("C000")))
.andExpect(jsonPath("$.data.id", is(user.getId().intValue())))
.andExpect(jsonPath("$.data.name", is(user.getName())))
.andExpect(jsonPath("$.data.gender", is(user.getGender().toString())))
.andExpect(jsonPath("$.data.age", is(user.getAge())))
.andExpect(jsonPath("$.data.description", is(user.getDescription())))
.andExpect(jsonPath("$.data.profile", is("image/default.jpg")))
.andExpect(jsonPath("$.data.createdAt", notNullValue()))
.andExpect(jsonPath("$.timestamp", notNullValue()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package taco.klkl.domain.user.controller;

import static org.hamcrest.Matchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

import taco.klkl.domain.user.domain.User;
import taco.klkl.domain.user.service.UserService;
import taco.klkl.global.common.enums.Gender;

@WebMvcTest(UserController.class)
class UserControllerTest {

@Autowired
MockMvc mockMvc;

@MockBean
UserService userService;

private User user;

@BeforeEach
public void setUp() {
user = new User(null, "testUser", Gender.MALE, 20, "테스트 유저입니다.");
}

@Test
public void getMe() throws Exception {
// given
Mockito.when(userService.me()).thenReturn(user);

// when & then
mockMvc.perform(get("/api/v1/users/me")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.isSuccess", is(true)))
.andExpect(jsonPath("$.code", is("C000")))
.andExpect(jsonPath("$.data.id", is(nullValue())))
.andExpect(jsonPath("$.data.name", is(user.getName())))
.andExpect(jsonPath("$.data.gender", is(user.getGender().toString())))
.andExpect(jsonPath("$.data.age", is(user.getAge())))
.andExpect(jsonPath("$.data.description", is(user.getDescription())))
.andExpect(jsonPath("$.data.profile", is(nullValue())))
.andExpect(jsonPath("$.data.createdAt", is(nullValue())))
.andExpect(jsonPath("$.timestamp", notNullValue()));
}
}
48 changes: 48 additions & 0 deletions src/test/java/taco/klkl/domain/user/service/UserServiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package taco.klkl.domain.user.service;

import static org.assertj.core.api.Assertions.*;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

import taco.klkl.domain.user.dao.UserRepository;
import taco.klkl.domain.user.domain.User;
import taco.klkl.global.common.enums.Gender;

@SpringBootTest
@Transactional
class UserServiceTest {
private static final Logger log = LoggerFactory.getLogger(UserServiceTest.class);
@Autowired
UserService userService;

@Autowired
UserRepository userRepository;

@BeforeEach
public void beforeEach() {
userRepository.deleteAll();
}

@Test
public void testMe() {
// given
User user = new User(null, "testUser", Gender.MALE, 20, "테스트 유저입니다.");

// when
userService.join(user);
User foundUser = userService.me();

// then
assertThat(foundUser.getId()).isNotNull();
assertThat(user.getName()).isEqualTo(foundUser.getName());
assertThat(user.getGender()).isEqualTo(foundUser.getGender());
assertThat(user.getAge()).isEqualTo(foundUser.getAge());
assertThat(user.getDescription()).isEqualTo(foundUser.getDescription());
}
}

0 comments on commit 934d8b7

Please sign in to comment.