refactor(users): login and registration use JdbcTemplate for users

This commit is contained in:
lobo committed 2026-09-30 13:41:56 +02:00
1 parent b6be1879f0
commit d082f3befd
12 files changed
+145 -262

No files matched your search

@@ -1,13 +1,19 @@
package auth_service.modules.login.persistence;
import auth_service.modules.login.persistence.entities.MinimalUserEntity;
import auth_service.modules.login.model.User;
import auth_service.shared.security.Role;
import auth_service.shared.test.AbstractPersistenceTest;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jpa.test.autoconfigure.TestEntityManager;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
import static org.junit.jupiter.api.Assertions.*;
import java.time.LocalDateTime;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@Import(MinimalUserRepositoryImpl.class)
class MinimalUserRepositoryTest extends AbstractPersistenceTest {
@@ -16,53 +22,47 @@ class MinimalUserRepositoryTest extends AbstractPersistenceTest {
private MinimalUserRepository minimalUserRepository;
@Autowired
private TestEntityManager entityManager;
private JdbcTemplate jdbc;
@Test
void findByEmail_Success() {
// Arrange
var email = "minimal@example.com";
var entity = MinimalUserEntity.builder()
.email(email)
.password("password")
.enabled(true)
.build();
entityManager.persist(entity);
entityManager.flush();
// Act
var result = minimalUserRepository.findByEmail(email);
// Assert
assertTrue(result.isPresent());
assertEquals(email, result.get().getEmail());
private long insertUser(String email) {
Long id = jdbc.queryForObject("INSERT INTO users (email, password, enabled, registration_date) "
+ "VALUES (?, 'password', TRUE, ?) RETURNING id", Long.class, email, LocalDateTime.now());
return id == null ? 0 : id;
}
@Test
void updateLoginDate_Success() {
// Arrange
var entity = MinimalUserEntity.builder()
.email("login@example.com")
.password("password")
.enabled(true)
.build();
entity = entityManager.persist(entity);
entityManager.flush();
void findByEmail_MapsTheUser() {
long id = insertUser("minimal@example.com");
jdbc.update("UPDATE users SET steam_id = 76561198000000001, deleted_at = now() WHERE id = ?", id);
// Act
minimalUserRepository.updateLoginDate(entity.getId());
entityManager.clear(); // Clear cache to force reload from DB
User user = minimalUserRepository.findByEmail("minimal@example.com").orElseThrow();
// Assert
var updated = entityManager.find(MinimalUserEntity.class, entity.getId());
assertNotNull(updated.getLastLoginDate());
assertEquals(id, user.getId());
assertEquals("password", user.getPassword());
assertEquals(76561198000000001L, user.getSteamId());
assertTrue(user.isEnabled());
assertTrue(user.isDeleted());
assertEquals(Role.USER, user.getRole());
}
@Test
void findById_UnknownUser_IsEmpty() {
assertFalse(minimalUserRepository.findById(-1).isPresent());
}
@Test
void updateLoginDate_StoresTheDate() {
long id = insertUser("login@example.com");
minimalUserRepository.updateLoginDate(id);
assertNotNull(jdbc.queryForObject("SELECT last_login_date FROM users WHERE id = ?", LocalDateTime.class, id));
}
// An access token from before V19 still carries the email as it was typed.
@Test
void findByEmail_IgnoresCase() {
entityManager.persist(MinimalUserEntity.builder().email("case@example.com").password("password").enabled(true).build());
entityManager.flush();
insertUser("case@example.com");
assertTrue(minimalUserRepository.findByEmail("Case@Example.com").isPresent());
}
@@ -1,14 +1,19 @@
package auth_service.modules.registration.persistence;
import auth_service.modules.registration.model.Registration;
import auth_service.modules.registration.persistence.entities.RegisteredUserEntity;
import auth_service.shared.test.AbstractPersistenceTest;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jpa.test.autoconfigure.TestEntityManager;
import org.springframework.context.annotation.Import;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.jdbc.core.JdbcTemplate;
import static org.junit.jupiter.api.Assertions.*;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@Import(RegisteredUserRepositoryImpl.class)
class RegisteredUserRepositoryTest extends AbstractPersistenceTest {
@@ -17,59 +22,49 @@ class RegisteredUserRepositoryTest extends AbstractPersistenceTest {
private RegisteredUserRepository registeredUserRepository;
@Autowired
private TestEntityManager entityManager;
private JdbcTemplate jdbc;
private static Registration registration(String email, String displayName) {
return Registration.builder().email(email).encryptedPassword("hashed").displayName(displayName).build();
}
@Test
void existsByEmail_Success() {
// Arrange
var email = "exists@example.com";
var entity = RegisteredUserEntity.builder()
.email(email)
.password("password")
.enabled(true)
.registrationDate(java.time.LocalDateTime.now())
.build();
entityManager.persist(entity);
entityManager.flush();
void existsByEmail_OnlyForAStoredEmail() {
registeredUserRepository.save(registration("exists@example.com", null));
// Act & Assert
assertTrue(registeredUserRepository.existsByEmail(email));
assertTrue(registeredUserRepository.existsByEmail("exists@example.com"));
assertFalse(registeredUserRepository.existsByEmail("other@example.com"));
}
@Test
void save_Success() {
// Arrange
var registration = Registration.builder()
.email("save@example.com")
.encryptedPassword("hashed")
.build();
void existsByDisplayName_IgnoresCase() {
registeredUserRepository.save(registration("named@example.com", "Lobo"));
// Act
long id = registeredUserRepository.save(registration);
assertTrue(registeredUserRepository.existsByDisplayName("lobo"));
assertFalse(registeredUserRepository.existsByDisplayName("Wolf"));
}
// Assert
assertTrue(id > 0);
var saved = entityManager.find(RegisteredUserEntity.class, id);
assertNotNull(saved);
assertEquals("save@example.com", saved.getEmail());
@Test
void save_StoresAnEnabledUser() {
long id = registeredUserRepository.save(registration("save@example.com", "Saver"));
Map<String, Object> saved = jdbc.queryForMap("SELECT * FROM users WHERE id = ?", id);
assertEquals("save@example.com", saved.get("email"));
assertEquals("hashed", saved.get("password"));
assertEquals(true, saved.get("enabled"));
assertEquals("Saver", saved.get("display_name"));
assertEquals("USER", saved.get("role"));
}
// V19: a second account under the same email in other case is refused by the database too.
@Test
void emailsThatDifferOnlyInCase_AreOneAccount() {
entityManager.persist(RegisteredUserEntity.builder().email("dup@example.com").password("password")
.enabled(true).registrationDate(java.time.LocalDateTime.now()).build());
entityManager.flush();
registeredUserRepository.save(registration("dup@example.com", null));
assertTrue(registeredUserRepository.existsByEmail("Dup@Example.com"));
var refused = assertThrows(org.hibernate.exception.ConstraintViolationException.class, () -> {
entityManager.persist(RegisteredUserEntity.builder().email("Dup@example.com").password("password")
.enabled(true).registrationDate(java.time.LocalDateTime.now()).build());
entityManager.flush();
});
// GlobalExceptionController decides on the state; on an English server Hibernate also gives the name.
assertEquals("23505", refused.getSQLState());
assertEquals("users_email_lower", refused.getConstraintName());
DuplicateKeyException refused = assertThrows(DuplicateKeyException.class,
() -> registeredUserRepository.save(registration("Dup@example.com", null)));
// GlobalExceptionController finds the name in the message, in every server language.
assertTrue(refused.getMostSpecificCause().getMessage().contains("users_email_lower"));
}
}