|
1 | 1 | package com.syncapi.controller.auth; |
2 | 2 |
|
3 | | -import com.syncapi.AbstractIntegrationTest; |
| 3 | +import com.syncapi.JsonTestUtil; |
| 4 | +import com.syncapi.TestUtil; |
| 5 | +import com.syncapi.dto.auth.AuthResponse; |
4 | 6 | import com.syncapi.dto.auth.LoginRequest; |
5 | 7 | import com.syncapi.dto.auth.RegisterRequest; |
6 | | -import com.syncapi.entity.User; |
7 | 8 | import com.syncapi.repository.UserRepository; |
8 | | -import org.junit.jupiter.api.BeforeEach; |
| 9 | +import com.syncapi.security.JwtUtil; |
| 10 | +import com.syncapi.service.auth.AuthService; |
9 | 11 | import org.junit.jupiter.api.Test; |
10 | 12 | import org.junit.jupiter.params.ParameterizedTest; |
11 | 13 | import org.junit.jupiter.params.provider.MethodSource; |
12 | 14 | import org.springframework.beans.factory.annotation.Autowired; |
13 | 15 | import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; |
| 16 | +import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; |
14 | 17 | import org.springframework.http.MediaType; |
| 18 | +import org.springframework.test.context.bean.override.mockito.MockitoBean; |
15 | 19 | import org.springframework.test.web.servlet.MockMvc; |
16 | 20 | import org.springframework.test.web.servlet.ResultActions; |
17 | 21 |
|
18 | 22 | import java.util.stream.Stream; |
19 | 23 |
|
20 | | -import static com.syncapi.TestUtil.*; |
21 | | -import static org.assertj.core.api.Assertions.assertThat; |
| 24 | +import static org.mockito.ArgumentMatchers.any; |
| 25 | +import static org.mockito.Mockito.*; |
22 | 26 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; |
23 | 27 |
|
24 | | -@AutoConfigureMockMvc |
25 | | -class AuthControllerTest extends AbstractIntegrationTest { |
| 28 | +@WebMvcTest(controllers = AuthController.class) |
| 29 | +@AutoConfigureMockMvc(addFilters = false) |
| 30 | +class AuthControllerTest { |
26 | 31 | private static final String AUTH_URL = "/api/auth"; |
27 | 32 |
|
28 | 33 | @Autowired |
29 | 34 | private MockMvc mockMvc; |
30 | 35 |
|
31 | | - @Autowired |
32 | | - private UserRepository userRepository; |
| 36 | + @MockitoBean |
| 37 | + private AuthService authService; |
33 | 38 |
|
34 | | - @BeforeEach |
35 | | - void setUp() { |
36 | | - userRepository.deleteAll(); |
37 | | - } |
| 39 | + // required as JwtAuthenticationFilter dependency |
| 40 | + @MockitoBean |
| 41 | + private JwtUtil jwtUtil; |
| 42 | + @MockitoBean |
| 43 | + private UserRepository userRepository; |
38 | 44 |
|
39 | 45 | @Test |
40 | 46 | void shouldRegisterNewUser() throws Exception { |
41 | 47 | // given |
42 | | - String name = generateRandomName(); |
43 | | - String email = generateRandomEmail(); |
44 | | - RegisterRequest request = new RegisterRequest(name, email, generateRandomPassword()); |
| 48 | + String name = TestUtil.generateRandomName(); |
| 49 | + String email = TestUtil.generateRandomEmail(); |
| 50 | + RegisterRequest request = new RegisterRequest(name, email, TestUtil.generateRandomPassword()); |
| 51 | + |
| 52 | + String token = TestUtil.generateRandomToken(); |
| 53 | + AuthResponse response = new AuthResponse(token, email, name); |
| 54 | + |
| 55 | + when(authService.register(any(RegisterRequest.class))) |
| 56 | + .thenReturn(response); |
45 | 57 |
|
46 | 58 | // when |
47 | | - ResultActions res = mockMvc.perform(postJson(AUTH_URL + "/register", request)); |
| 59 | + ResultActions res = mockMvc.perform(JsonTestUtil.postJson(AUTH_URL + "/register", request)); |
48 | 60 |
|
49 | 61 | // then |
50 | 62 | res.andExpect(status().isOk()) |
51 | 63 | .andExpect(content().contentType(MediaType.APPLICATION_JSON)) |
52 | | - .andExpect(jsonPath("$.token").isString()) |
53 | | - .andExpect(jsonPath("$.token").isNotEmpty()) |
54 | | - .andExpect(jsonPath("$.email").value(email)) |
55 | | - .andExpect(jsonPath("$.name").value(name)); |
56 | | - |
57 | | - User user = userRepository.findByEmail(email).orElseThrow(); |
58 | | - assertThat(user.getName()).isEqualTo(name); |
59 | | - assertThat(user.getPasswordHash()).isNotBlank(); |
| 64 | + .andExpectAll( |
| 65 | + jsonPath("$.token").value(token), |
| 66 | + jsonPath("$.email").value(email), |
| 67 | + jsonPath("$.name").value(name) |
| 68 | + ); |
| 69 | + |
| 70 | + verify(authService).register(any(RegisterRequest.class)); |
60 | 71 | } |
61 | 72 |
|
62 | 73 | @Test |
63 | 74 | void shouldFailWhenEmailAlreadyExists() throws Exception { |
64 | 75 | // given |
65 | | - String email = generateRandomEmail(); |
66 | | - RegisterRequest first = new RegisterRequest(generateRandomName(), email, generateRandomPassword()); |
67 | | - RegisterRequest second = new RegisterRequest(generateRandomName(), email, generateRandomPassword()); |
| 76 | + RegisterRequest request = new RegisterRequest( |
| 77 | + TestUtil.generateRandomName(), TestUtil.generateRandomEmail(), TestUtil.generateRandomPassword() |
| 78 | + ); |
| 79 | + |
| 80 | + when(authService.register(any(RegisterRequest.class))) |
| 81 | + .thenThrow(new RuntimeException("email already exists")); |
68 | 82 |
|
69 | 83 | // when / then |
70 | | - mockMvc.perform(postJson(AUTH_URL + "/register", first)) |
71 | | - .andExpect(status().isOk()); |
72 | | - mockMvc.perform(postJson(AUTH_URL + "/register", second)) |
| 84 | + mockMvc.perform(JsonTestUtil.postJson(AUTH_URL + "/register", request)) |
73 | 85 | .andExpect(status().isBadRequest()); |
| 86 | + |
| 87 | + verify(authService).register(any(RegisterRequest.class)); |
74 | 88 | } |
75 | 89 |
|
76 | 90 | @ParameterizedTest(name = "[{index}] invalid register request -> 400") |
77 | 91 | @MethodSource("invalidRegisterRequests") |
78 | 92 | void shouldFailValidationForInvalidRegisterRequest(RegisterRequest request) throws Exception { |
79 | 93 | // when / then |
80 | | - mockMvc.perform(postJson(AUTH_URL + "/register", request)) |
| 94 | + mockMvc.perform(JsonTestUtil.postJson(AUTH_URL + "/register", request)) |
81 | 95 | .andExpect(status().isBadRequest()); |
| 96 | + |
| 97 | + verifyNoInteractions(authService); |
82 | 98 | } |
83 | 99 |
|
84 | 100 | private static Stream<RegisterRequest> invalidRegisterRequests() { |
85 | 101 | return Stream.of( |
86 | | - new RegisterRequest("", generateRandomEmail(), generateRandomPassword()), // blank name |
87 | | - new RegisterRequest(null, generateRandomEmail(), generateRandomPassword()), // null name |
88 | | - new RegisterRequest("John", "not-an-email", generateRandomPassword()), // invalid email |
89 | | - new RegisterRequest("John", "", generateRandomPassword()), // blank email |
90 | | - new RegisterRequest("John", generateRandomEmail(), "123") // short password |
| 102 | + new RegisterRequest("", TestUtil.generateRandomEmail(), TestUtil.generateRandomPassword()), |
| 103 | + new RegisterRequest(null, TestUtil.generateRandomEmail(), TestUtil.generateRandomPassword()), |
| 104 | + new RegisterRequest("John", "not-an-email", TestUtil.generateRandomPassword()), |
| 105 | + new RegisterRequest("John", "", TestUtil.generateRandomPassword()), |
| 106 | + new RegisterRequest("John", TestUtil.generateRandomEmail(), "123") |
91 | 107 | ); |
92 | 108 | } |
93 | 109 |
|
94 | 110 | @Test |
95 | 111 | void shouldLoginSuccessfully() throws Exception { |
96 | 112 | // given |
97 | | - String email = generateRandomEmail(); |
98 | | - String password = generateRandomPassword(); |
99 | | - RegisterRequest register = new RegisterRequest("Login User", email, password); |
| 113 | + String email = TestUtil.generateRandomEmail(); |
| 114 | + String token = TestUtil.generateRandomToken(); |
100 | 115 |
|
101 | | - mockMvc.perform(postJson(AUTH_URL + "/register", register)) |
102 | | - .andExpect(status().isOk()); |
| 116 | + LoginRequest request = new LoginRequest(email, TestUtil.generateRandomPassword()); |
| 117 | + AuthResponse response = new AuthResponse(token, email, TestUtil.generateRandomName()); |
103 | 118 |
|
104 | | - LoginRequest login = new LoginRequest(email, password); |
| 119 | + when(authService.login(any(LoginRequest.class))) |
| 120 | + .thenReturn(response); |
105 | 121 |
|
106 | 122 | // when |
107 | | - ResultActions res = mockMvc.perform(postJson(AUTH_URL + "/login", login)); |
| 123 | + ResultActions res = mockMvc.perform(JsonTestUtil.postJson(AUTH_URL + "/login", request)); |
108 | 124 |
|
109 | 125 | // then |
110 | 126 | res.andExpect(status().isOk()) |
111 | 127 | .andExpect(content().contentType(MediaType.APPLICATION_JSON)) |
112 | | - .andExpect(jsonPath("$.token").isString()) |
113 | | - .andExpect(jsonPath("$.token").isNotEmpty()) |
114 | | - .andExpect(jsonPath("$.email").value(email)); |
| 128 | + .andExpectAll( |
| 129 | + jsonPath("$.token").value(token), |
| 130 | + jsonPath("$.email").value(email) |
| 131 | + ); |
| 132 | + |
| 133 | + verify(authService).login(any(LoginRequest.class)); |
115 | 134 | } |
116 | 135 |
|
117 | 136 | @ParameterizedTest(name = "[{index}] invalid login -> 400") |
118 | 137 | @MethodSource("invalidLoginRequests") |
119 | 138 | void shouldFailLoginForInvalidCredentials(LoginRequest request) throws Exception { |
120 | | - // when / then |
121 | | - mockMvc.perform(postJson(AUTH_URL + "/login", request)) |
| 139 | + boolean passesValidation = request.getEmail() != null |
| 140 | + && !request.getEmail().isBlank() |
| 141 | + && request.getEmail().contains("@") |
| 142 | + && request.getPassword() != null |
| 143 | + && !request.getPassword().isBlank(); |
| 144 | + if (passesValidation) { |
| 145 | + when(authService.login(any(LoginRequest.class))) |
| 146 | + .thenThrow(new RuntimeException("invalid credentials")); |
| 147 | + } |
| 148 | + |
| 149 | + mockMvc.perform(JsonTestUtil.postJson(AUTH_URL + "/login", request)) |
122 | 150 | .andExpect(status().isBadRequest()); |
| 151 | + |
| 152 | + if (passesValidation) { |
| 153 | + verify(authService).login(any(LoginRequest.class)); |
| 154 | + } else { |
| 155 | + verifyNoInteractions(authService); |
| 156 | + } |
123 | 157 | } |
124 | 158 |
|
125 | 159 | private static Stream<LoginRequest> invalidLoginRequests() { |
126 | 160 | return Stream.of( |
127 | | - new LoginRequest("not-an-email", "password"), // invalid email |
128 | | - new LoginRequest("", "password"), // blank email |
129 | | - new LoginRequest(generateRandomEmail(), ""), // blank password |
130 | | - new LoginRequest(generateRandomEmail(), "wrong-password") // wrong password |
| 161 | + new LoginRequest("not-an-email", "password"), |
| 162 | + new LoginRequest("", "password"), |
| 163 | + new LoginRequest(TestUtil.generateRandomEmail(), ""), |
| 164 | + new LoginRequest(TestUtil.generateRandomEmail(), "wrong-password") |
131 | 165 | ); |
132 | 166 | } |
133 | 167 | } |
0 commit comments