-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAuthenticationControllerTest.java
More file actions
257 lines (215 loc) · 11 KB
/
AuthenticationControllerTest.java
File metadata and controls
257 lines (215 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
package com.podzilla.auth.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.podzilla.auth.dto.LoginRequest;
import com.podzilla.auth.dto.SignupRequest;
import com.podzilla.auth.model.Address;
import com.podzilla.auth.model.ERole;
import com.podzilla.auth.model.Role;
import com.podzilla.auth.model.User;
import com.podzilla.auth.repository.AddressRepository;
import com.podzilla.auth.repository.RoleRepository;
import com.podzilla.auth.repository.UserRepository;
import com.podzilla.auth.service.TokenService; // Assuming you have a JwtService
import com.podzilla.auth.dto.DeliveryAddress;
import jakarta.servlet.http.Cookie;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
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.http.MediaType;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import java.util.Optional;
import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@SpringBootTest
@AutoConfigureMockMvc
class AuthenticationControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private UserRepository userRepository;
@Autowired
private RoleRepository roleRepository; // Inject RoleRepository
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private ObjectMapper objectMapper;
@Autowired
private TokenService tokenService;
private final String testUserEmail = "testuser@example.com";
private final String testUserPassword = "password123";
@BeforeEach
void setUp() {
roleRepository.deleteAll();
userRepository.deleteAll(); // Clean slate before each test
Role adminRole = new Role();
adminRole.setErole(ERole.ROLE_ADMIN);
roleRepository.save(adminRole);
Role userRole = new Role();
userRole.setErole(ERole.ROLE_USER);
roleRepository.save(userRole);
Address address = new Address();
address.setStreet("123 Test St");
address.setCity("Test City");
address.setState("Test State");
address.setCountry("Test Country");
address.setPostalCode("12345");
// Create a pre-existing user for login tests
User user = new User();
user.setEmail(testUserEmail);
user.setPassword(passwordEncoder.encode(testUserPassword));
user.setName("Test User"); // Assuming name is required or desired
user.setMobileNumber("1234567890");
user.setAddress(address);
address.setUser(user);
user.getRoles().add(userRole);
userRepository.save(user);
}
@AfterEach
void tearDown() {
userRepository.deleteAll(); // Clean up after each test
roleRepository.deleteAll();
}
@Test
void registerUser_shouldCreateNewUser_whenEmailIsNotTaken() throws Exception {
SignupRequest signupRequest = new SignupRequest();
signupRequest.setEmail("newuser@example.com");
signupRequest.setPassword("newpassword");
signupRequest.setName("New User");
signupRequest.setMobileNumber("1234562137890");
signupRequest.setAddress(new DeliveryAddress("456 New St", "New City",
"New State", "New Country", "54321"));
mockMvc.perform(post("/auth/register")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(signupRequest)))
.andExpect(status().isCreated())
.andExpect(content().string("Account registered."));
// Verify user exists in the database
Optional<User> registeredUser = userRepository.findByEmail("newuser@example.com");
assertTrue(registeredUser.isPresent());
assertEquals("New User", registeredUser.get().getName());
assertTrue(passwordEncoder.matches("newpassword", registeredUser.get().getPassword()));
// Verify role assignment if applicable (assuming default role is USER)
assertTrue(registeredUser.get().getRoles().stream()
.anyMatch(role -> role.getErole() == ERole.ROLE_USER));
}
@Test
void registerUser_shouldReturnBadRequest_whenEmailIsTaken() throws Exception {
SignupRequest signupRequest = new SignupRequest();
signupRequest.setEmail(testUserEmail); // Email already exists from setup
signupRequest.setPassword("anotherpassword");
signupRequest.setName("Another User");
mockMvc.perform(post("/auth/register")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(signupRequest)))
// Assuming AuthenticationService throws an exception leading to 4xx
// Adjust status code based on actual exception handling (e.g., 400 Bad Request or 409 Conflict)
.andExpect(status().isBadRequest()); // Or Conflict (409) depending on implementation
}
@Test
void login_shouldReturnOkAndSetCookies_whenCredentialsAreValid() throws Exception {
LoginRequest loginRequest = new LoginRequest();
loginRequest.setEmail(testUserEmail);
loginRequest.setPassword(testUserPassword);
mockMvc.perform(post("/auth/login")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(loginRequest)))
.andExpect(status().isOk())
.andExpect(content().string("User " + testUserEmail + " logged in successfully"))
.andExpect(cookie().exists("accessToken")) // Check if cookies are set
.andExpect(cookie().exists("refreshToken"));
// Add more specific cookie checks if needed (e.g., HttpOnly, Secure, MaxAge)
// .andExpect(cookie().httpOnly("accessToken", true))
// .andExpect(cookie().maxAge("accessToken", expectedMaxAge));
}
@Test
void login_shouldReturnUnauthorized_whenCredentialsAreInvalid() throws Exception {
LoginRequest loginRequest = new LoginRequest();
loginRequest.setEmail(testUserEmail);
loginRequest.setPassword("wrongpassword");
mockMvc.perform(post("/auth/login")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(loginRequest)))
.andExpect(status().isUnauthorized()); // Standard Spring Security behavior
}
@Test
void logoutUser_shouldClearCookiesAndReturnOk() throws Exception {
// First, log in to get cookies
LoginRequest loginRequest = new LoginRequest();
loginRequest.setEmail(testUserEmail);
loginRequest.setPassword(testUserPassword);
MvcResult loginResult = mockMvc.perform(post("/auth/login")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(loginRequest)))
.andExpect(status().isOk())
.andReturn();
Cookie accessTokenCookie = loginResult.getResponse().getCookie("accessToken");
Cookie refreshTokenCookie = loginResult.getResponse().getCookie("refreshToken");
assertNotNull(accessTokenCookie);
assertNotNull(refreshTokenCookie);
// Perform logout using the obtained cookies
mockMvc.perform(post("/auth/logout")
.cookie(accessTokenCookie) // Send cookies back
.cookie(refreshTokenCookie))
.andExpect(status().isOk())
.andExpect(content().string("You've been signed out!"))
// Check that cookies are cleared (Max-Age=0)
.andExpect(cookie().value("accessToken", (String) null))
.andExpect(cookie().value("refreshToken", (String) null));
}
@Test
void refreshToken_shouldReturnOkAndNewTokens_whenRefreshTokenIsValid() throws Exception {
// 1. Login to get initial tokens
LoginRequest loginRequest = new LoginRequest();
loginRequest.setEmail(testUserEmail);
loginRequest.setPassword(testUserPassword);
MvcResult loginResult = mockMvc.perform(post("/auth/login")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(loginRequest)))
.andExpect(status().isOk())
.andReturn();
Cookie initialAccessToken = loginResult.getResponse().getCookie("accessToken");
Cookie initialRefreshToken = loginResult.getResponse().getCookie("refreshToken");
assertNotNull(initialRefreshToken);
assertNotNull(initialAccessToken);
assertNotEquals(0, initialRefreshToken.getMaxAge()); // Ensure it's not already expired
Thread.sleep(3000);
// 2. Use the refresh token to get new tokens
MvcResult refreshResult = mockMvc.perform(post("/auth/refresh-token")
.cookie(initialRefreshToken)) // Send only the refresh token
.andExpect(status().isOk())
.andExpect(content().string(containsString("refreshed tokens successfully")))
.andExpect(cookie().exists("accessToken"))
.andExpect(cookie().exists("refreshToken"))
.andReturn();
// 3. Verify new tokens are different from old ones
Cookie newAccessToken = refreshResult.getResponse().getCookie("accessToken");
Cookie newRefreshToken = refreshResult.getResponse().getCookie("refreshToken");
assertNotNull(newAccessToken);
assertNotNull(newRefreshToken);
assertNotEquals(initialAccessToken.getValue(), newAccessToken.getValue());
// Depending on your implementation, the refresh token might also be rotated
// assertNotEquals(initialRefreshToken.getValue(), newRefreshToken.getValue());
// Optional: Verify the expiry/max-age of the new cookies
assertNotEquals(0, newAccessToken.getMaxAge());
assertNotEquals(0, newRefreshToken.getMaxAge());
}
@Test
void refreshToken_shouldReturnUnauthorized_whenRefreshTokenIsMissingOrInvalid() throws Exception {
// Test without sending any cookie
mockMvc.perform(post("/auth/refresh-token"))
.andExpect(status().isForbidden());
// Test with an invalid/expired cookie
Cookie invalidCookie = new Cookie("refreshToken", "invalid-or-expired-token-value");
invalidCookie.setPath("/"); // Set path and other relevant attributes if needed
mockMvc.perform(post("/auth/refresh-token")
.cookie(invalidCookie))
.andExpect(status().isForbidden());
}
}