-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
200 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
# This file is generated by the 'io.freefair.lombok' Gradle plugin | ||
config.stopBubbling = true | ||
lombok.extern.findbugs.addSuppressFBWarnings = true |
20 changes: 20 additions & 0 deletions
20
src/main/java/io/github/raeperd/realworld/application/UserLoginRequestDTO.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,20 @@ | ||
package io.github.raeperd.realworld.application; | ||
|
||
import io.github.raeperd.realworld.domain.User; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
public class UserLoginRequestDTO { | ||
|
||
private final String email; | ||
private final String password; | ||
|
||
public UserLoginRequestDTO(String email, String password) { | ||
this.email = email; | ||
this.password = password; | ||
} | ||
|
||
public User toUser() { | ||
return User.fromEmailAndPassword(email, password); | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
src/main/java/io/github/raeperd/realworld/application/UserResponseDTO.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 io.github.raeperd.realworld.application; | ||
|
||
import com.fasterxml.jackson.annotation.JsonTypeInfo; | ||
import com.fasterxml.jackson.annotation.JsonTypeInfo.As; | ||
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; | ||
import com.fasterxml.jackson.annotation.JsonTypeName; | ||
import io.github.raeperd.realworld.domain.User; | ||
import lombok.Getter; | ||
|
||
@JsonTypeName("user") | ||
@JsonTypeInfo(include = As.WRAPPER_OBJECT, use = Id.NAME) | ||
@Getter | ||
public class UserResponseDTO { | ||
|
||
private final String email; | ||
private final String token; | ||
private final String username; | ||
private final String bio; | ||
private final String image; | ||
|
||
public static UserResponseDTO fromUser(User user) { | ||
return new UserResponseDTO(user); | ||
} | ||
|
||
private UserResponseDTO(User user) { | ||
this.email = user.getEmail(); | ||
this.username = user.getUsername(); | ||
this.bio = user.getBio(); | ||
this.image = user.getImage(); | ||
// TODO: Generate token from user somewhere else | ||
this.token = ""; | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/io/github/raeperd/realworld/application/UserRestController.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,26 @@ | ||
package io.github.raeperd.realworld.application; | ||
|
||
import io.github.raeperd.realworld.domain.UserRepository; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import static org.springframework.http.ResponseEntity.of; | ||
|
||
@RestController | ||
public class UserRestController { | ||
|
||
private final UserRepository userRepository; | ||
|
||
public UserRestController(UserRepository userRepository) { | ||
this.userRepository = userRepository; | ||
} | ||
|
||
@PostMapping("/users/login") | ||
public ResponseEntity<UserResponseDTO> login(@RequestBody UserLoginRequestDTO loginRequest) { | ||
return of(userRepository.findFirstByEmailAndPassword(loginRequest.getEmail(), loginRequest.getPassword()) | ||
.map(UserResponseDTO::fromUser)); | ||
} | ||
|
||
} |
45 changes: 45 additions & 0 deletions
45
src/main/java/io/github/raeperd/realworld/domain/User.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,45 @@ | ||
package io.github.raeperd.realworld.domain; | ||
|
||
import javax.persistence.Entity; | ||
import javax.persistence.Id; | ||
|
||
@Entity | ||
public class User { | ||
|
||
@Id | ||
private long id; | ||
|
||
private String email; | ||
private String password; | ||
private String username; | ||
private String bio; | ||
private String image; | ||
|
||
protected User() { | ||
} | ||
|
||
public static User fromEmailAndPassword(String email, String password) { | ||
return new User(email, password); | ||
} | ||
|
||
private User(String email, String password) { | ||
this.email = email; | ||
this.password = password; | ||
} | ||
|
||
public String getEmail() { | ||
return email; | ||
} | ||
|
||
public String getUsername() { | ||
return username; | ||
} | ||
|
||
public String getBio() { | ||
return bio; | ||
} | ||
|
||
public String getImage() { | ||
return image; | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/io/github/raeperd/realworld/domain/UserRepository.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,10 @@ | ||
package io.github.raeperd.realworld.domain; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
import java.util.Optional; | ||
|
||
public interface UserRepository extends JpaRepository<User, Long> { | ||
|
||
Optional<User> findFirstByEmailAndPassword(String email, String password); | ||
} |
65 changes: 65 additions & 0 deletions
65
src/test/java/io/github/raeperd/realworld/application/UserRestControllerTest.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,65 @@ | ||
package io.github.raeperd.realworld.application; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import io.github.raeperd.realworld.domain.UserRepository; | ||
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.autoconfigure.web.servlet.WebMvcTest; | ||
import org.springframework.boot.test.mock.mockito.MockBean; | ||
import org.springframework.test.web.servlet.MockMvc; | ||
|
||
import static io.github.raeperd.realworld.domain.User.fromEmailAndPassword; | ||
import static java.util.Optional.of; | ||
import static org.mockito.ArgumentMatchers.anyString; | ||
import static org.mockito.BDDMockito.then; | ||
import static org.mockito.Mockito.times; | ||
import static org.mockito.Mockito.when; | ||
import static org.springframework.http.MediaType.APPLICATION_JSON; | ||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; | ||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; | ||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||
|
||
@AutoConfigureMockMvc | ||
@WebMvcTest(UserRestController.class) | ||
class UserRestControllerTest { | ||
|
||
@MockBean | ||
private UserRepository userRepository; | ||
|
||
@Autowired | ||
private MockMvc mockMvc; | ||
@Autowired | ||
private ObjectMapper objectMapper; | ||
|
||
@Test | ||
void when_post_login_expect_userRepository_findFirstByEmailAndPassword_called() throws Exception { | ||
final var loginDTO = new UserLoginRequestDTO("email", "password"); | ||
when(userRepository.findFirstByEmailAndPassword(loginDTO.getEmail(), loginDTO.getPassword())) | ||
.thenReturn(of(fromEmailAndPassword(loginDTO.getEmail(), loginDTO.getPassword()))); | ||
|
||
mockMvc.perform(post("/users/login") | ||
.contentType(APPLICATION_JSON) | ||
.content(objectMapper.writeValueAsString(loginDTO))); | ||
|
||
then(userRepository).should(times(1)) | ||
.findFirstByEmailAndPassword(loginDTO.getEmail(), loginDTO.getPassword()); | ||
} | ||
|
||
@Test | ||
void when_post_login_expect_valid_response_body() throws Exception { | ||
when(userRepository.findFirstByEmailAndPassword(anyString(), anyString())) | ||
.thenReturn(of(fromEmailAndPassword("email", "password"))); | ||
|
||
mockMvc.perform(post("/users/login") | ||
.contentType(APPLICATION_JSON) | ||
.content(objectMapper.writeValueAsString(new UserLoginRequestDTO("email", "password")))) | ||
.andExpect(status().isOk()) | ||
.andExpect(jsonPath("$.user").exists()) | ||
.andExpect(jsonPath("$.user.email").exists()) | ||
.andExpect(jsonPath("$.user.bio").hasJsonPath()) | ||
.andExpect(jsonPath("$.user.image").hasJsonPath()) | ||
.andExpect(jsonPath("$.user.token").hasJsonPath()); | ||
} | ||
|
||
} |