Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/java/application/user/UserLogin.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public UserLogin(PasswordHasher hasher, UserRepository repo) {

public User execute(String login, String password) {
// normalize (trim etc.)
login.trim().toLowerCase();
login = login.trim().toLowerCase();

User user = repo.findByLogin(login)
.orElseThrow(() -> new IllegalArgumentException("Invalid credentials"));
Expand Down
162 changes: 162 additions & 0 deletions src/test/java/application/user/UserLoginTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package application.user;

import application.security.PasswordHasher;
import domain.user.User;
import org.junit.jupiter.api.Test;
import persistence.UserRepository;

import java.util.Optional;

import static org.junit.jupiter.api.Assertions.*;

public class UserLoginTest {

@Test
void executeReturnsUserWhenCredentialsAreValid() {
User user = new User("testuser", "12345678", "hashed-secret", "test@example.com");
PasswordHasher hasher = new FakePasswordHasher("hashed-secret");
UserRepository repo = new FakeUserRepository(Optional.of(user));

UserLogin userLogin = new UserLogin(hasher, repo);

User result = userLogin.execute("testuser", "secret");

assertSame(user, result);

}

@Test
void executeThrowsWhenLoginDoesNotExist() {
PasswordHasher hasher = new FakePasswordHasher("hashed-secret");
UserRepository repo = new FakeUserRepository(Optional.empty());

UserLogin userLogin = new UserLogin(hasher, repo);

IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> userLogin.execute("missing-user", "secret")
);

assertEquals("Invalid credentials", exception.getMessage());
}

@Test
void executeThrowsWhenPasswordIsWrong() {
User user = new User("testuser", "12345678", "stored-hash", "test@example.com");
PasswordHasher hasher = new FakePasswordHasher("different-hash");
UserRepository repo = new FakeUserRepository(Optional.of(user));

UserLogin userLogin = new UserLogin(hasher, repo);

IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> userLogin.execute("testuser", "wrong-password")
);

assertEquals("Invalid password", exception.getMessage());
}

@Test
void executeUsesNormalizedLoginBeforeLookup() {
User user = new User("testuser", "12345678", "hashed-secret", "test@example.com");
RecordingUserRepository repo = new RecordingUserRepository(Optional.of(user));
PasswordHasher hasher = new FakePasswordHasher("hashed-secret");

UserLogin userLogin = new UserLogin(hasher, repo);

userLogin.execute(" TestUser ", "secret");

assertEquals("testuser", repo.lastLoginUsed);
}

private static class FakePasswordHasher implements PasswordHasher{
private final String hashToReturn;
private FakePasswordHasher(String hashToReturn) {
this.hashToReturn = hashToReturn;
}

@Override
public String hash(String password) {
return hashToReturn;
}
}

private static class FakeUserRepository implements UserRepository {
private final Optional<User> userToReturn;

private FakeUserRepository(Optional<User> userToReturn) {
this.userToReturn = userToReturn;
}

@Override
public Optional<User> findByUsername(String username){
return Optional.empty();
}

@Override
public Optional<User> findByEmail(String email){
return Optional.empty();
}

@Override
public Optional<User> findByLogin(String login) {
return userToReturn;
}

@Override
public boolean existsByEmail(String email) {
return false;
}

@Override
public boolean existsByUsername(String username) {
return false;
}

@Override
public void insert(User user) {
}
}

private static class RecordingUserRepository implements UserRepository {
private final Optional<User> userToReturn;
private String lastLoginUsed;

private RecordingUserRepository(Optional<User> userToReturn) {
this.userToReturn = userToReturn;
}

@Override
public Optional<User> findByUsername(String username) {
return Optional.empty();
}

@Override
public Optional<User> findByEmail(String email) {
return Optional.empty();
}

@Override
public Optional<User> findByLogin(String login) {
lastLoginUsed = login;
return userToReturn;
}

@Override
public boolean existsByEmail(String email) {
return false;
}

@Override
public boolean existsByUsername(String username) {
return false;
}

@Override
public void insert(User user) {
}
}


}

170 changes: 170 additions & 0 deletions src/test/java/application/user/UserRegisterTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package application.user;

import application.security.PasswordHasher;
import domain.user.User;
import org.junit.jupiter.api.Test;
import persistence.UserRepository;

import java.util.Optional;

import static org.junit.jupiter.api.Assertions.*;

public class UserRegisterTest {

@Test
void executeInsertsUserWhenInputIsValid() {
RecordingUserRepository repo = new RecordingUserRepository();
PasswordHasher hasher = new FakePasswordHasher("hashed-password");
UserRegister userRegister = new UserRegister(hasher, repo);

userRegister.execute("testuser", "12345678", "secret", "test@example.com");

assertNotNull(repo.insertedUser);
assertEquals("testuser", repo.insertedUser.getUsername());
assertEquals("12345678", repo.insertedUser.getPhoneNumber());
assertEquals("hashed-password", repo.insertedUser.getPassword());
assertEquals("test@example.com", repo.insertedUser.getEMail());
}


@Test
void executeNormalizesUsernameEmailAndPhoneBeforeInsert() {
RecordingUserRepository repo = new RecordingUserRepository();
PasswordHasher hasher = new FakePasswordHasher("hashed-password");
UserRegister userRegister = new UserRegister(hasher, repo);

userRegister.execute(" testuser ", " 12345678 ", "secret", " TEST@EXAMPLE.COM ");

assertNotNull(repo.insertedUser);
assertEquals("testuser", repo.insertedUser.getUsername());
assertEquals("12345678", repo.insertedUser.getPhoneNumber());
assertEquals("test@example.com", repo.insertedUser.getEMail());
}


@Test
void executeThrowsWhenEmailAlreadyExists() {
RecordingUserRepository repo = new RecordingUserRepository();
repo.emailExists = true;
PasswordHasher hasher = new FakePasswordHasher("hashed-password");
UserRegister userRegister = new UserRegister(hasher, repo);

IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> userRegister.execute("testuser", "12345678", "secret", "test@example.com")
);

assertEquals("Email already in use", exception.getMessage());
assertNull(repo.insertedUser);
}

@Test
void executeThrowsWhenUsernameAlreadyExists() {
RecordingUserRepository repo = new RecordingUserRepository();
repo.usernameExists = true;
PasswordHasher hasher = new FakePasswordHasher("hashed-password");
UserRegister userRegister = new UserRegister(hasher, repo);

IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> userRegister.execute("testuser", "12345678", "secret", "test@example.com")
);

assertEquals("This username is taken", exception.getMessage());
assertNull(repo.insertedUser);
}

@Test
void executeHashesPasswordBeforeSavingUser() {
RecordingUserRepository repo = new RecordingUserRepository();
RecordingPasswordHasher hasher = new RecordingPasswordHasher("hashed-password");
UserRegister userRegister = new UserRegister(hasher, repo);

userRegister.execute("testuser", "12345678", "secret", "test@example.com");

assertEquals("secret", hasher.lastPasswordInput);
assertNotNull(repo.insertedUser);
assertEquals("hashed-password", repo.insertedUser.getPassword());
}

@Test
void executePropagatesDomainValidationErrors() {
RecordingUserRepository repo = new RecordingUserRepository();
PasswordHasher hasher = new FakePasswordHasher("hashed-password");
UserRegister userRegister = new UserRegister(hasher, repo);

IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> userRegister.execute("testuser", "1234", "secret", "test@example.com")
);

assertEquals("Fill in a phonenumber with 8 digits", exception.getMessage());
assertNull(repo.insertedUser);
}

private static class FakePasswordHasher implements PasswordHasher {
private final String hashToReturn;

private FakePasswordHasher(String hashToReturn) {
this.hashToReturn = hashToReturn;
}

@Override
public String hash(String password) {
return hashToReturn;
}
}


private static class RecordingPasswordHasher implements PasswordHasher {
private final String hashToReturn;
private String lastPasswordInput;

private RecordingPasswordHasher(String hashToReturn) {
this.hashToReturn = hashToReturn;
}

@Override
public String hash(String password) {
lastPasswordInput = password;
return hashToReturn;
}
}

private static class RecordingUserRepository implements UserRepository {
private boolean emailExists;
private boolean usernameExists;
private User insertedUser;

@Override
public Optional<User> findByUsername(String username) {
return Optional.empty();
}

@Override
public Optional<User> findByEmail(String email) {
return Optional.empty();
}

@Override
public Optional<User> findByLogin(String login) {
return Optional.empty();
}


@Override
public boolean existsByEmail(String email) {
return emailExists;
}

@Override
public boolean existsByUsername(String username) {
return usernameExists;
}

@Override
public void insert(User user) {
insertedUser = user;
}
}
}
Loading
Loading