Public Access
refactor(users): login and registration use JdbcTemplate for users
This commit is contained in:
1 parent
b6be1879f0
commit
d082f3befd
12 files changed
+145
-262
No files matched your search
+39
-39
@@ -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());
|
||||
}
|
||||
|
||||
+36
-41
@@ -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"));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user