@file:Suppress("MemberVisibilityCanBePrivate") package be.simplenotes.domain import be.simplenotes.config.JwtConfig import be.simplenotes.domain.security.BcryptPasswordHash import be.simplenotes.domain.security.SimpleJwt import be.simplenotes.domain.security.UserJwtMapper import be.simplenotes.domain.testutils.isLeftOfType import be.simplenotes.domain.testutils.isRight import be.simplenotes.persistence.repositories.UserRepository import be.simplenotes.persistence.transactions.TransactionService import be.simplenotes.types.PersistedUser import com.natpryce.hamkrest.assertion.assertThat import com.natpryce.hamkrest.equalTo import io.mockk.* import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import java.util.concurrent.TimeUnit internal class UserServiceTest { val userRepository = mockk() val passwordHash = BcryptPasswordHash(test = true) val jwtConfig = JwtConfig("a secret", 1, TimeUnit.HOURS) val simpleJwt = SimpleJwt(jwtConfig, UserJwtMapper()) val noopTransactionService = object : TransactionService { override fun use(block: () -> T) = block() } val userService = UserServiceImpl( userRepository = userRepository, passwordHash = passwordHash, jwt = simpleJwt, searcher = mockk(), transactionService = noopTransactionService ) @BeforeEach fun resetMocks() { clearMocks(userRepository) } @Test fun `register should fail with invalid form`() { val form = RegisterForm("", "a".repeat(10)) assertThat(userService.register(form), isLeftOfType()) verify { userRepository wasNot called } } @Test fun `Register should fail with existing username`() { val form = RegisterForm("someuser", "somepassword") every { userRepository.exists(form.username!!) } returns true assertThat(userService.register(form), isLeftOfType()) } @Test fun `Register should succeed with new user`() { val form = RegisterForm("someuser", "somepassword") every { userRepository.exists(form.username!!) } returns false every { userRepository.create(any()) } returns PersistedUser(form.username!!, form.password!!, 1) val res = userService.register(form) assertThat(res, isRight()) res.map { assertThat(it.username, equalTo(form.username)) } } @Test fun `Login should fail with invalid form`() { val form = LoginForm("", "a") assertThat(userService.login(form), isLeftOfType()) verify { userRepository wasNot called } } @Test fun `Login should fail with non existing user`() { val form = LoginForm("someusername", "somepassword") every { userRepository.find(form.username!!) } returns null assertThat(userService.login(form), isLeftOfType()) } @Test fun `Login should fail with wrong password`() { val form = LoginForm("someusername", "wrongpassword") every { userRepository.find(form.username!!) } returns PersistedUser(form.username!!, passwordHash.crypt("right password"), 1) assertThat(userService.login(form), isLeftOfType()) } @Test fun `Login should succeed with existing user and correct password`() { val loginForm = LoginForm("someusername", "somepassword") every { userRepository.find(loginForm.username!!) } returns PersistedUser(loginForm.username!!, passwordHash.crypt(loginForm.password!!), 1) val res = userService.login(loginForm) assertThat(res, isRight()) } }