Flatten packages

Remove modules prefix
This commit is contained in:
2020-11-11 22:32:23 +01:00
parent e6a7af840a
commit 8439782430
155 changed files with 51 additions and 33 deletions
+1
View File
@@ -0,0 +1 @@
package be.simplenotes.domain
@@ -0,0 +1,51 @@
package be.simplenotes.domain.security
import be.simplenotes.config.JwtConfig
import be.simplenotes.domain.usecases.users.login.Token
import be.simplenotes.types.LoggedInUser
import com.auth0.jwt.JWT
import com.auth0.jwt.algorithms.Algorithm
import com.natpryce.hamkrest.absent
import com.natpryce.hamkrest.assertion.assertThat
import com.natpryce.hamkrest.equalTo
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.MethodSource
import java.util.concurrent.TimeUnit
import java.util.stream.Stream
internal class LoggedInUserExtractorTest {
private val jwtConfig = JwtConfig("a secret", 1, TimeUnit.HOURS)
private val simpleJwt = SimpleJwt(jwtConfig)
private val jwtPayloadExtractor = JwtPayloadExtractor(simpleJwt)
private fun createToken(username: String? = null, id: Int? = null, secret: String = jwtConfig.secret): Token {
val algo = Algorithm.HMAC256(secret)
return JWT.create().apply {
username?.let { withClaim(usernameField, it) }
id?.let { withClaim(userIdField, it) }
}.sign(algo)
}
@Suppress("Unused")
private fun invalidTokens() = Stream.of(
createToken(id = 1),
createToken(username = "user"),
createToken(),
createToken(username = "user", id = 1, secret = "not the correct secret"),
createToken(username = "user", id = 1) + "\"efesfsef",
"something that is not even a token"
)
@ParameterizedTest(name = "[{index}] token `{0}` should be invalid")
@MethodSource("invalidTokens")
fun `parse invalid tokens`(token: String) {
assertThat(jwtPayloadExtractor(token), absent())
}
@Test
fun `parse valid token`() {
val token = createToken(username = "someone", id = 1)
assertThat(jwtPayloadExtractor(token), equalTo(LoggedInUser(1, "someone")))
}
}
+42
View File
@@ -0,0 +1,42 @@
package be.simplenotes.domain.testutils
import arrow.core.Either
import com.natpryce.hamkrest.MatchResult
import com.natpryce.hamkrest.Matcher
fun isLeft() = object : Matcher<Either<*, *>> {
override val description: String
get() = "is Either.Left<>"
override fun invoke(actual: Either<*, *>) = when {
actual.isLeft() -> MatchResult.Match
else -> MatchResult.Mismatch("is Either.Right<>")
}
}
fun isRight() = object : Matcher<Either<*, *>> {
override val description: String
get() = "is Either.Right<>"
override fun invoke(actual: Either<*, *>) = when (actual) {
is Either.Right -> MatchResult.Match
is Either.Left -> {
val valueA = actual.a
MatchResult.Mismatch("is Either.Left<${if (valueA == null) "Null" else valueA::class.simpleName}>")
}
}
}
inline fun <reified A> isLeftOfType() = object : Matcher<Either<*, *>> {
override val description: String
get() = "is Either.Left<${A::class.qualifiedName}>"
override fun invoke(actual: Either<*, *>) = when (actual) {
is Either.Right -> MatchResult.Mismatch("was Either.Right<>")
is Either.Left -> {
val valueA = actual.a
if (valueA is A) MatchResult.Match
else MatchResult.Mismatch("was Left<${if (valueA == null) "Null" else valueA::class.simpleName}>")
}
}
}
@@ -0,0 +1,45 @@
package be.simplenotes.domain.usecases.search
import be.simplenotes.search.SearchTerms
import com.natpryce.hamkrest.assertion.assertThat
import com.natpryce.hamkrest.equalTo
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.MethodSource
import java.util.stream.Stream
internal class SearchTermsParserKtTest {
private fun createResult(
input: String,
title: String? = null,
tag: String? = null,
content: String? = null,
all: String? = null,
): Pair<String, SearchTerms> = input to SearchTerms(title, tag, content, all)
@Suppress("Unused")
private fun results() = Stream.of(
createResult("title:'example'", title = "example"),
createResult("title:'example with words'", title = "example with words"),
createResult("title:'example with words'", title = "example with words"),
createResult("""title:"double quotes"""", title = "double quotes"),
createResult("title:'example' something else", title = "example", all = "something else"),
createResult("tag:'example'", tag = "example"),
createResult("tag:'example' title:'other'", title = "other", tag = "example"),
createResult("blah blah tag:'example' title:'other'", title = "other", tag = "example", all = "blah blah"),
createResult("tag:'example' middle title:'other'", title = "other", tag = "example", all = "middle"),
createResult("tag:'example' title:'other' end", title = "other", tag = "example", all = "end"),
createResult(
"tag:'example abc' title:'other with words' this is the end ",
title = "other with words",
tag = "example abc",
all = "this is the end"
),
)
@ParameterizedTest
@MethodSource("results")
fun `valid search parser`(case: Pair<String, SearchTerms>) {
assertThat(parseSearchTerms(case.first), equalTo(case.second))
}
}
@@ -0,0 +1,64 @@
package be.simplenotes.domain.usecases.users.login
import be.simplenotes.config.JwtConfig
import be.simplenotes.domain.security.BcryptPasswordHash
import be.simplenotes.domain.security.SimpleJwt
import be.simplenotes.domain.testutils.isLeftOfType
import be.simplenotes.domain.testutils.isRight
import be.simplenotes.persistance.repositories.UserRepository
import be.simplenotes.types.PersistedUser
import com.natpryce.hamkrest.assertion.assertThat
import io.mockk.*
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import java.util.concurrent.TimeUnit
internal class LoginUseCaseImplTest {
// region setup
private val mockUserRepository = mockk<UserRepository>()
private val passwordHash = BcryptPasswordHash(test = true)
private val jwtConfig = JwtConfig("a secret", 1, TimeUnit.HOURS)
private val simpleJwt = SimpleJwt(jwtConfig)
private val loginUseCase = LoginUseCaseImpl(mockUserRepository, passwordHash, simpleJwt)
@BeforeEach
fun resetMocks() {
clearMocks(mockUserRepository)
}
// endregion
@Test
fun `Login should fail with invalid form`() {
val form = LoginForm("", "a")
assertThat(loginUseCase.login(form), isLeftOfType<InvalidLoginForm>())
verify { mockUserRepository wasNot called }
}
@Test
fun `Login should fail with non existing user`() {
val form = LoginForm("someusername", "somepassword")
every { mockUserRepository.find(form.username!!) } returns null
assertThat(loginUseCase.login(form), isLeftOfType<Unregistered>())
}
@Test
fun `Login should fail with wrong password`() {
val form = LoginForm("someusername", "wrongpassword")
every { mockUserRepository.find(form.username!!) } returns
PersistedUser(form.username!!, passwordHash.crypt("right password"), 1)
assertThat(loginUseCase.login(form), isLeftOfType<WrongPassword>())
}
@Test
fun `Login should succeed with existing user and correct password`() {
val loginForm = LoginForm("someusername", "somepassword")
every { mockUserRepository.find(loginForm.username!!) } returns
PersistedUser(loginForm.username!!, passwordHash.crypt(loginForm.password!!), 1)
val res = loginUseCase.login(loginForm)
assertThat(res, isRight())
}
}
@@ -0,0 +1,54 @@
package be.simplenotes.domain.usecases.users.register
import be.simplenotes.domain.security.BcryptPasswordHash
import be.simplenotes.domain.testutils.isLeftOfType
import be.simplenotes.domain.testutils.isRight
import be.simplenotes.persistance.repositories.UserRepository
import be.simplenotes.persistance.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
internal class RegisterUseCaseImplTest {
// region setup
private val mockUserRepository = mockk<UserRepository>()
private val passwordHash = BcryptPasswordHash(test = true)
private val noopTransactionService = object : TransactionService {
override fun <T> use(block: () -> T) = block()
}
private val registerUseCase = RegisterUseCaseImpl(mockUserRepository, passwordHash, noopTransactionService)
@BeforeEach
fun resetMocks() {
clearMocks(mockUserRepository)
}
// endregion
@Test
fun `register should fail with invalid form`() {
val form = RegisterForm("", "a".repeat(10))
assertThat(registerUseCase.register(form), isLeftOfType<InvalidRegisterForm>())
verify { mockUserRepository wasNot called }
}
@Test
fun `Register should fail with existing username`() {
val form = RegisterForm("someuser", "somepassword")
every { mockUserRepository.exists(form.username!!) } returns true
assertThat(registerUseCase.register(form), isLeftOfType<UserExists>())
}
@Test
fun `Register should succeed with new user`() {
val form = RegisterForm("someuser", "somepassword")
every { mockUserRepository.exists(form.username!!) } returns false
every { mockUserRepository.create(any()) } returns PersistedUser(form.username!!, form.password!!, 1)
val res = registerUseCase.register(form)
assertThat(res, isRight())
res.map { assertThat(it.username, equalTo(form.username)) }
}
}
@@ -0,0 +1,77 @@
package be.simplenotes.domain.validation
import be.simplenotes.domain.testutils.isLeftOfType
import be.simplenotes.domain.testutils.isRight
import be.simplenotes.domain.usecases.users.login.InvalidLoginForm
import be.simplenotes.domain.usecases.users.login.LoginForm
import be.simplenotes.domain.usecases.users.register.RegisterForm
import com.natpryce.hamkrest.assertion.assertThat
import org.junit.jupiter.api.Nested
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.MethodSource
import java.util.stream.Stream
internal class UserValidationsTest {
@Nested
inner class Login {
@Suppress("Unused")
fun invalidLoginForms(): Stream<LoginForm> = Stream.of(
LoginForm(username = null, password = null),
LoginForm(username = "", password = ""),
LoginForm(username = "a", password = "aaaa"),
LoginForm(username = "a".repeat(51), password = "a".repeat(8)),
LoginForm(username = "a".repeat(10), password = "a".repeat(7))
)
@ParameterizedTest
@MethodSource("invalidLoginForms")
fun `validate invalid logins`(form: LoginForm) {
assertThat(UserValidations.validateLogin(form), isLeftOfType<InvalidLoginForm>())
}
@Suppress("Unused")
fun validLoginForms(): Stream<LoginForm> = Stream.of(
LoginForm(username = "a".repeat(50), password = "a".repeat(72)),
LoginForm(username = "a".repeat(3), password = "a".repeat(8))
)
@ParameterizedTest
@MethodSource("validLoginForms")
fun `validate valid logins`(form: LoginForm) {
assertThat(UserValidations.validateLogin(form), isRight())
}
}
@Nested
inner class Register {
@Suppress("Unused")
fun invalidRegisterForms(): Stream<RegisterForm> = Stream.of(
RegisterForm(username = null, password = null),
RegisterForm(username = "", password = ""),
RegisterForm(username = "a", password = "aaaa"),
RegisterForm(username = "a".repeat(51), password = "a".repeat(8)),
RegisterForm(username = "a".repeat(10), password = "a".repeat(7))
)
@ParameterizedTest
@MethodSource("invalidRegisterForms")
fun `validate invalid register`(form: LoginForm) {
assertThat(UserValidations.validateLogin(form), isLeftOfType<InvalidLoginForm>())
}
@Suppress("Unused")
fun validRegisterForms(): Stream<RegisterForm> = Stream.of(
RegisterForm(username = "a".repeat(50), password = "a".repeat(72)),
RegisterForm(username = "a".repeat(3), password = "a".repeat(8))
)
@ParameterizedTest
@MethodSource("validRegisterForms")
fun `validate valid register`(form: LoginForm) {
assertThat(UserValidations.validateLogin(form), isRight())
}
}
}