-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathTestUserSetup.java
More file actions
95 lines (85 loc) · 3.25 KB
/
TestUserSetup.java
File metadata and controls
95 lines (85 loc) · 3.25 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
package contactapp.security;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.test.context.TestSecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
/**
* Test utility for setting up authenticated users in tests.
*
* <p>This class handles both database persistence and SecurityContext setup,
* ensuring that tests have a valid user that satisfies FK constraints when
* creating contacts, tasks, or appointments.
*
* <h2>Usage</h2>
* <pre>{@code
* @Autowired
* private TestUserSetup testUserSetup;
*
* @BeforeEach
* void setUp() {
* testUserSetup.setupTestUser();
* }
* }</pre>
*/
@Component
public class TestUserSetup {
private static final String TEST_PASSWORD_HASH =
"$2a$10$N9qo8uLOickgx2ZMRZoMye3.Jv8Q5J5YJO1gqRbC1I/pL.sZ5g5jC";
private final UserRepository userRepository;
public TestUserSetup(final UserRepository userRepository) {
this.userRepository = userRepository;
}
/**
* Creates a test user in the database and sets up the SecurityContext.
*
* <p>If a user with username "testuser" already exists, it's reused.
* The SecurityContext is populated with this user as the principal.
*
* @return the persisted test user
*/
@Transactional
public User setupTestUser() {
return setupTestUser("testuser", "testuser@example.com", Role.USER);
}
/**
* Creates a test user with custom attributes.
*
* @param username the username
* @param email the email
* @param role the role
* @return the persisted test user
*/
@Transactional
public User setupTestUser(final String username, final String email, final Role role) {
// Reset any stale authentication and ensure a fresh user row exists for FK targets
SecurityContextHolder.clearContext();
User user = userRepository.findByUsername(username).orElse(null);
if (user == null || (user.getId() != null && !userRepository.existsById(user.getId()))) {
user = new User(username, email, TEST_PASSWORD_HASH, role);
user = userRepository.saveAndFlush(user); // ensure row exists before tasks reference it
}
// Set up SecurityContext with this user
final SecurityContext context = SecurityContextHolder.createEmptyContext();
final var authentication = new UsernamePasswordAuthenticationToken(
user,
null,
user.getAuthorities()
);
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);
// Keep MockMvc's TestSecurityContextHolder in sync so controller requests
// and direct service calls share the same authenticated principal.
TestSecurityContextHolder.setContext(context);
return user;
}
/**
* Clears all test users and the SecurityContext.
*/
@Transactional
public void cleanup() {
SecurityContextHolder.clearContext();
userRepository.deleteAll();
}
}