Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/user details #230

Merged
merged 14 commits into from
Apr 14, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package lab.en2b.quizapi.commons.user;

import lab.en2b.quizapi.commons.user.dtos.UserResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/users")
@RequiredArgsConstructor
public class UserController {

private final UserService userService;

/**
* Gets the user details for the given authentication
* Returns 200 if the user details are successfully retrieved
* Returns 403 if the user is not logged in
* @param authentication the authentication object
* @return the response dto for the user details
*/
@GetMapping("/details")
public ResponseEntity<UserResponseDto> getUserDetails(Authentication authentication) {
return ResponseEntity.ok(userService.getUserDetailsByAuthentication(authentication));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import lab.en2b.quizapi.auth.config.UserDetailsImpl;
import lab.en2b.quizapi.auth.dtos.RegisterDto;
import lab.en2b.quizapi.commons.exceptions.InvalidAuthenticationException;
import lab.en2b.quizapi.commons.user.dtos.UserResponseDto;
import lab.en2b.quizapi.commons.user.mappers.UserResponseDtoMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
Expand All @@ -22,6 +24,7 @@ public class UserService implements UserDetailsService {
private final UserRepository userRepository;
@Value("${REFRESH_TOKEN_DURATION_MS}")
private long refreshTokenDurationMs;
private final UserResponseDtoMapper userResponseDtoMapper;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
return UserDetailsImpl.build(userRepository.findByEmail(email).orElseThrow(() -> new InvalidAuthenticationException("Invalid email or password provided!")));
Expand Down Expand Up @@ -64,4 +67,8 @@ public User getUserByAuthentication(Authentication authentication) {
UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
return userRepository.findByEmail(userDetails.getEmail()).orElseThrow();
}

public UserResponseDto getUserDetailsByAuthentication(Authentication authentication) {
return userResponseDtoMapper.apply(getUserByAuthentication(authentication));
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package lab.en2b.quizapi.commons.user;
package lab.en2b.quizapi.commons.user.dtos;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package lab.en2b.quizapi.commons.user.mappers;

import lab.en2b.quizapi.commons.user.User;
import lab.en2b.quizapi.commons.user.UserResponseDto;
import lab.en2b.quizapi.commons.user.dtos.UserResponseDto;
import org.springframework.stereotype.Service;

import java.util.function.Function;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@

import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lab.en2b.quizapi.commons.user.UserResponseDto;
import lab.en2b.quizapi.commons.user.dtos.UserResponseDto;
import lab.en2b.quizapi.game.GameMode;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.time.LocalDateTime;
import java.time.OffsetDateTime;

@AllArgsConstructor
@Data
@Builder
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package lab.en2b.quizapi.statistics.dtos;

import com.fasterxml.jackson.annotation.JsonProperty;
import lab.en2b.quizapi.commons.user.UserResponseDto;
import lab.en2b.quizapi.commons.user.dtos.UserResponseDto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class AuthServiceTest {
User defaultUser;
@BeforeEach
void setUp() {
this.userService = new UserService(userRepository);
this.userService = new UserService(userRepository,null);
this.authService = new AuthService(authenticationManager,userService,jwtUtils);
this.defaultUser = User.builder()
.id(1L)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import ch.qos.logback.core.util.TimeUtil;
import lab.en2b.quizapi.commons.user.User;
import lab.en2b.quizapi.commons.user.UserResponseDto;
import lab.en2b.quizapi.commons.user.dtos.UserResponseDto;
import lab.en2b.quizapi.commons.user.UserService;
import lab.en2b.quizapi.commons.user.mappers.UserResponseDtoMapper;
import lab.en2b.quizapi.game.dtos.CustomGameDto;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import ch.qos.logback.core.util.TimeUtil;
import lab.en2b.quizapi.commons.user.User;
import lab.en2b.quizapi.commons.user.UserResponseDto;
import lab.en2b.quizapi.commons.user.dtos.UserResponseDto;
import lab.en2b.quizapi.commons.user.UserService;
import lab.en2b.quizapi.statistics.dtos.StatisticsResponseDto;
import lab.en2b.quizapi.statistics.mappers.StatisticsResponseDtoMapper;
Expand Down
46 changes: 46 additions & 0 deletions api/src/test/java/lab/en2b/quizapi/user/UserControllerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package lab.en2b.quizapi.user;

import lab.en2b.quizapi.auth.config.SecurityConfig;
import lab.en2b.quizapi.auth.jwt.JwtUtils;
import lab.en2b.quizapi.commons.user.UserController;
import lab.en2b.quizapi.commons.user.UserService;
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.context.annotation.Import;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest(UserController.class)
@AutoConfigureMockMvc
@Import(SecurityConfig.class)
public class UserControllerTest {

@Autowired
MockMvc mockMvc;

@MockBean
JwtUtils jwtUtils;

@MockBean
UserService userService;

@Test
void getUserShouldReturn200() throws Exception{
mockMvc.perform(get("/users/details")
.with(user("test").roles("user")))
.andExpect(status().isOk());
}

@Test
void getUserShouldReturn403() throws Exception{
mockMvc.perform(get("/users/details"))
.andExpect(status().isForbidden());
}

}
74 changes: 74 additions & 0 deletions api/src/test/java/lab/en2b/quizapi/user/UserServiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package lab.en2b.quizapi.user;

import lab.en2b.quizapi.auth.config.UserDetailsImpl;
import lab.en2b.quizapi.commons.user.User;
import lab.en2b.quizapi.commons.user.UserRepository;
import lab.en2b.quizapi.commons.user.UserService;
import lab.en2b.quizapi.commons.user.dtos.UserResponseDto;
import lab.en2b.quizapi.commons.user.mappers.UserResponseDtoMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.NoSuchElementException;
import java.util.Optional;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@ExtendWith({MockitoExtension.class, SpringExtension.class})
public class UserServiceTest {

@InjectMocks
private UserService userService;

@Mock
private UserRepository userRepository;

private User defaultUser;

private UserResponseDto defaultUserResponseDto;

@BeforeEach
public void setUp() {
userService = new UserService(userRepository, new UserResponseDtoMapper());
defaultUser = User.builder()
.id(1L)
.username("HordyJurtado")
.email("[email protected]")
.password("password")
.role("ROLE_USER")
.build();
defaultUserResponseDto = UserResponseDto.builder()
.id(1L)
.username("HordyJurtado")
.email("[email protected]")
.build();
}

@Test
public void getUserDetailsTest(){
Authentication authentication = mock(Authentication.class);
when(authentication.getPrincipal()).thenReturn(UserDetailsImpl.build(defaultUser));
when(userRepository.findByEmail(any())).thenReturn(Optional.of(defaultUser));
UserResponseDto result = userService.getUserDetailsByAuthentication(authentication);
Assertions.assertEquals(defaultUserResponseDto, result);
}

@Test
public void getUserDetailsWhenNotFound() {
Authentication authentication = mock(Authentication.class);
when(authentication.getPrincipal()).thenReturn(UserDetailsImpl.build(defaultUser));
when(userRepository.findByEmail(any())).thenReturn(Optional.empty());
Assertions.assertThrows(NoSuchElementException.class, () -> userService.getUserDetailsByAuthentication(authentication));
}

}