50. User registration - Testing (#4)
This commit is contained in:
@ -0,0 +1,29 @@
|
|||||||
|
package net.shyshkin.study.fullstack.supportportal.backend.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class PasswordEncoderConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
PasswordEncoder passwordEncoder() {
|
||||||
|
String idForEncode = "bcrypt";
|
||||||
|
Map<String, PasswordEncoder> encoders = new HashMap<>();
|
||||||
|
encoders.put(idForEncode, new BCryptPasswordEncoder());
|
||||||
|
encoders.put("noop", NoOpPasswordEncoder.getInstance());
|
||||||
|
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
|
||||||
|
encoders.put("scrypt", new SCryptPasswordEncoder());
|
||||||
|
|
||||||
|
return new DelegatingPasswordEncoder(idForEncode, encoders);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,7 +5,6 @@ import net.shyshkin.study.fullstack.supportportal.backend.filter.JwtAccessDenied
|
|||||||
import net.shyshkin.study.fullstack.supportportal.backend.filter.JwtAuthenticationEntryPoint;
|
import net.shyshkin.study.fullstack.supportportal.backend.filter.JwtAuthenticationEntryPoint;
|
||||||
import net.shyshkin.study.fullstack.supportportal.backend.filter.JwtAuthorizationFilter;
|
import net.shyshkin.study.fullstack.supportportal.backend.filter.JwtAuthorizationFilter;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
@ -13,26 +12,19 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
|
|||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
|
||||||
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
|
|
||||||
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
|
|
||||||
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
|
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
private final JwtAuthorizationFilter jwtAuthorizationFilter;
|
private final JwtAuthorizationFilter jwtAuthorizationFilter;
|
||||||
private final UserDetailsService userService;
|
private final UserDetailsService userDetailsService;
|
||||||
private final JwtAccessDeniedHandler jwtAccessDeniedHandler;
|
private final JwtAccessDeniedHandler jwtAccessDeniedHandler;
|
||||||
private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
|
private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
|
||||||
|
private final PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
@Value("${app.public-urls}")
|
@Value("${app.public-urls}")
|
||||||
private String[] publicUrls;
|
private String[] publicUrls;
|
||||||
@ -60,20 +52,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
@Override
|
@Override
|
||||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
auth
|
auth
|
||||||
.userDetailsService(userService)
|
.userDetailsService(userDetailsService)
|
||||||
.passwordEncoder(passwordEncoder());
|
.passwordEncoder(passwordEncoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
|
||||||
PasswordEncoder passwordEncoder() {
|
|
||||||
String idForEncode = "bcrypt";
|
|
||||||
Map<String, PasswordEncoder> encoders = new HashMap<>();
|
|
||||||
encoders.put(idForEncode, new BCryptPasswordEncoder());
|
|
||||||
encoders.put("noop", NoOpPasswordEncoder.getInstance());
|
|
||||||
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
|
|
||||||
encoders.put("scrypt", new SCryptPasswordEncoder());
|
|
||||||
|
|
||||||
return new DelegatingPasswordEncoder(idForEncode, encoders);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ public abstract class BaseUserTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
protected UserRepository userRepository;
|
protected UserRepository userRepository;
|
||||||
|
|
||||||
protected User user;
|
protected static User user;
|
||||||
|
|
||||||
protected User createRandomUser() {
|
protected User createRandomUser() {
|
||||||
return User.builder()
|
return User.builder()
|
||||||
|
|||||||
@ -6,20 +6,24 @@ import net.shyshkin.study.fullstack.supportportal.backend.domain.HttpResponse;
|
|||||||
import net.shyshkin.study.fullstack.supportportal.backend.domain.User;
|
import net.shyshkin.study.fullstack.supportportal.backend.domain.User;
|
||||||
import net.shyshkin.study.fullstack.supportportal.backend.domain.UserPrincipal;
|
import net.shyshkin.study.fullstack.supportportal.backend.domain.UserPrincipal;
|
||||||
import net.shyshkin.study.fullstack.supportportal.backend.utility.JwtTokenProvider;
|
import net.shyshkin.study.fullstack.supportportal.backend.utility.JwtTokenProvider;
|
||||||
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
|
import org.junit.jupiter.api.Order;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.RequestEntity;
|
import org.springframework.http.RequestEntity;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertAll;
|
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||||
import static org.springframework.http.HttpStatus.FORBIDDEN;
|
import static org.springframework.http.HttpStatus.*;
|
||||||
import static org.springframework.http.HttpStatus.OK;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
@TestMethodOrder(value = MethodOrderer.OrderAnnotation.class)
|
||||||
class UserResourceTest extends BaseUserTest {
|
class UserResourceTest extends BaseUserTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -29,6 +33,7 @@ class UserResourceTest extends BaseUserTest {
|
|||||||
JwtTokenProvider jwtTokenProvider;
|
JwtTokenProvider jwtTokenProvider;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Order(10)
|
||||||
void showUserHome_forbidden() {
|
void showUserHome_forbidden() {
|
||||||
|
|
||||||
//when
|
//when
|
||||||
@ -49,6 +54,7 @@ class UserResourceTest extends BaseUserTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Order(20)
|
||||||
void showUserHome_correctToken() {
|
void showUserHome_correctToken() {
|
||||||
|
|
||||||
//given
|
//given
|
||||||
@ -71,4 +77,86 @@ class UserResourceTest extends BaseUserTest {
|
|||||||
.isNotNull()
|
.isNotNull()
|
||||||
.isEqualTo("Application works");
|
.isEqualTo("Application works");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(30)
|
||||||
|
void registerUser_new() {
|
||||||
|
|
||||||
|
//given
|
||||||
|
User fakeUser = createRandomUser();
|
||||||
|
|
||||||
|
//when
|
||||||
|
ResponseEntity<User> responseEntity = restTemplate.postForEntity("/user/register", fakeUser, User.class);
|
||||||
|
|
||||||
|
//then
|
||||||
|
log.debug("Response Entity: {}", responseEntity);
|
||||||
|
assertThat(responseEntity.getStatusCode()).isEqualTo(OK);
|
||||||
|
User registeredUser = responseEntity.getBody();
|
||||||
|
assertThat(registeredUser)
|
||||||
|
.isNotNull()
|
||||||
|
.hasNoNullFieldsOrPropertiesExcept("lastLoginDate", "lastLoginDateDisplay")
|
||||||
|
.hasFieldOrPropertyWithValue("username", fakeUser.getUsername())
|
||||||
|
.hasFieldOrPropertyWithValue("email", fakeUser.getEmail())
|
||||||
|
.hasFieldOrPropertyWithValue("firstName", fakeUser.getFirstName())
|
||||||
|
.hasFieldOrPropertyWithValue("lastName", fakeUser.getLastName())
|
||||||
|
.hasFieldOrPropertyWithValue("isActive", true)
|
||||||
|
.hasFieldOrPropertyWithValue("isNotLocked", true)
|
||||||
|
.hasFieldOrPropertyWithValue("role", "ROLE_USER")
|
||||||
|
;
|
||||||
|
user = registeredUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(40)
|
||||||
|
void registerUser_usernameExists() {
|
||||||
|
|
||||||
|
//given
|
||||||
|
User fakeUser = createRandomUser();
|
||||||
|
String username = user.getUsername();
|
||||||
|
fakeUser.setUsername(username);
|
||||||
|
String expectedMessage = ("Username `" + username + "` is already taken. Please select another one").toUpperCase();
|
||||||
|
|
||||||
|
//when
|
||||||
|
ResponseEntity<HttpResponse> responseEntity = restTemplate.postForEntity("/user/register", fakeUser, HttpResponse.class);
|
||||||
|
|
||||||
|
//then
|
||||||
|
log.debug("Response Entity: {}", responseEntity);
|
||||||
|
assertThat(responseEntity.getStatusCode()).isEqualTo(BAD_REQUEST);
|
||||||
|
assertThat(responseEntity.getBody())
|
||||||
|
.isNotNull()
|
||||||
|
.hasNoNullFieldsOrProperties()
|
||||||
|
.satisfies(httpResponse -> assertAll(
|
||||||
|
() -> assertThat(httpResponse.getHttpStatusCode()).isEqualTo(400),
|
||||||
|
() -> assertThat(httpResponse.getHttpStatus()).isEqualTo(BAD_REQUEST),
|
||||||
|
() -> assertThat(httpResponse.getReason()).isEqualTo("BAD REQUEST"),
|
||||||
|
() -> assertThat(httpResponse.getMessage()).isEqualTo(expectedMessage)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(41)
|
||||||
|
void registerUser_emailExists() {
|
||||||
|
|
||||||
|
//given
|
||||||
|
User fakeUser = createRandomUser();
|
||||||
|
String email = user.getEmail();
|
||||||
|
fakeUser.setEmail(email);
|
||||||
|
String expectedMessage = ("User with email `" + email + "` is already registered").toUpperCase();
|
||||||
|
|
||||||
|
//when
|
||||||
|
ResponseEntity<HttpResponse> responseEntity = restTemplate.postForEntity("/user/register", fakeUser, HttpResponse.class);
|
||||||
|
|
||||||
|
//then
|
||||||
|
log.debug("Response Entity: {}", responseEntity);
|
||||||
|
assertThat(responseEntity.getStatusCode()).isEqualTo(BAD_REQUEST);
|
||||||
|
assertThat(responseEntity.getBody())
|
||||||
|
.isNotNull()
|
||||||
|
.hasNoNullFieldsOrProperties()
|
||||||
|
.satisfies(httpResponse -> assertAll(
|
||||||
|
() -> assertThat(httpResponse.getHttpStatusCode()).isEqualTo(400),
|
||||||
|
() -> assertThat(httpResponse.getHttpStatus()).isEqualTo(BAD_REQUEST),
|
||||||
|
() -> assertThat(httpResponse.getReason()).isEqualTo("BAD REQUEST"),
|
||||||
|
() -> assertThat(httpResponse.getMessage()).isEqualTo(expectedMessage)
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user