Skip to content
Merged
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
18 changes: 18 additions & 0 deletions src/main/kotlin/authentication/Auth.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package authentication

import Secrets

interface Auth {
suspend fun login(
email: String,
password: String,
)

suspend fun logout()

suspend fun isLoggedIn(): Boolean

class Factory {
fun create(): Auth = if (Secrets.USE_LOCAL_MOCKS) LocalAuth else RemoteAuth
}
}
4 changes: 2 additions & 2 deletions src/main/kotlin/authentication/Authentication.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package authentication

import org.koin.core.module.dsl.singleOf
import org.koin.dsl.module

val authenticationModule =
module {
singleOf(::Authenticator)
factory { Auth.Factory() }
factory<Auth> { get<Auth.Factory>().create() }
}
26 changes: 0 additions & 26 deletions src/main/kotlin/authentication/Authenticator.kt

This file was deleted.

31 changes: 31 additions & 0 deletions src/main/kotlin/authentication/LocalAuth.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package authentication

import kotlinx.coroutines.delay
import kotlin.time.Duration.Companion.seconds

object LocalAuth : Auth {
private var isLoggedIn: Boolean = false

override suspend fun login(
email: String,
password: String,
) {
delay(3.seconds)
println("local Auth login")
isLoggedIn = (email in validUsers && password == PASSWORD)
}

override suspend fun logout() {
println("local Auth logout")
isLoggedIn = false
}

override suspend fun isLoggedIn(): Boolean {
println("local local is logged in")
return isLoggedIn
}

private val validUsers =
listOf("Robert", "Dunia", "Tom", "Max", "Casper", "Ed", "Kai", "Laura", "Niamh", "Sofia")
private const val PASSWORD = "ILoveRoky"
}
32 changes: 32 additions & 0 deletions src/main/kotlin/authentication/RemoteAuth.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package authentication

import kotlinx.coroutines.delay
import kotlin.time.Duration.Companion.seconds

// SUPABASEEEE
object RemoteAuth : Auth {
private var isLoggedIn: Boolean = false

override suspend fun login(
email: String,
password: String,
) {
println("Remote Auth login")
delay(3.seconds)
isLoggedIn = (email in validUsers && password == PASSWORD)
}

override suspend fun logout() {
println("Remote Auth logout")
isLoggedIn = false
}

override suspend fun isLoggedIn(): Boolean {
println("Remote Auth is logged in")
return isLoggedIn
}

private val validUsers =
listOf("Robert", "Dunia", "Tom", "Max", "Casper", "Ed", "Kai", "Laura", "Niamh", "Sofia")
private const val PASSWORD = "ILoveRoky"
}
9 changes: 6 additions & 3 deletions src/main/kotlin/login/LoginUseCase.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package login

import authentication.Authenticator
import authentication.Auth
import login.LoginEvent.Login
import login.LoginViewState.Idle

class LoginUseCase(
private val authenticator: Authenticator,
private val authenticator: Auth,
) {
suspend operator fun invoke(event: Login): LoginViewState =
with(event) {
val status =
when {
username.isBlank() -> ERROR_USERNAME
password.isBlank() -> ERROR_PASSWORD
else -> if (authenticator.login(username, password)) LOGIN_SUCCESS else LOGIN_FAILURE
else -> {
authenticator.login(username, password)
if (authenticator.isLoggedIn()) LOGIN_SUCCESS else LOGIN_FAILURE
}
}
return Idle(userName = event.username, password = "", status = status)
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/mainmenu/MainMenuPresenter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package mainmenu
import StopApp
import arch.Presenter
import arch.RokyDispatchers
import authentication.Authenticator
import authentication.Auth
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
Expand All @@ -15,7 +15,7 @@ import navigation.NavigateToAppWindow
class MainMenuPresenter(
private val quit: StopApp,
private val navigate: NavigateToAppWindow,
private val authenticator: Authenticator,
private val authenticator: Auth,
private val windowScope: CoroutineScope,
dispatchers: RokyDispatchers,
) : Presenter<MainMenuView>(dispatchers) {
Expand Down
12 changes: 5 additions & 7 deletions src/test/kotlin/login/LoginUseCaseTest.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package login

import authentication.Authenticator
import authentication.Auth
import coAnswersDelayed
import io.kotest.matchers.Matcher
import io.kotest.matchers.MatcherResult
import io.kotest.matchers.should
import io.mockk.coEvery
import io.mockk.mockk
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import login.LoginEvent.Login
import login.LoginUseCase.Companion.ERROR_PASSWORD
Expand All @@ -17,15 +16,14 @@ import login.LoginUseCase.Companion.LOGIN_SUCCESS
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

@OptIn(ExperimentalCoroutinesApi::class)
class LoginUseCaseTest {
private lateinit var logIn: LoginUseCase
private lateinit var authenticator: Authenticator
private lateinit var authenticator: Auth

@BeforeEach
fun setUp() {
authenticator = mockk(relaxed = true)
coEvery { authenticator.login(any(), any()) } coAnswersDelayed { false }
coEvery { authenticator.isLoggedIn() } coAnswersDelayed { false }
logIn = LoginUseCase(authenticator)
}

Expand All @@ -46,15 +44,15 @@ class LoginUseCaseTest {
@Test
fun `given username and password is present, when credentials are valid, then status is login success`() =
runTest {
coEvery { authenticator.login(any(), any()) } coAnswersDelayed { true }
coEvery { authenticator.isLoggedIn() } coAnswersDelayed { true }
val event = Login(username = "rob", password = "rob")
logIn(event) should haveStatus(LOGIN_SUCCESS)
}

@Test
fun `given username and password is present, when credentials are invalid, then status is login failure`() =
runTest {
coEvery { authenticator.login(any(), any()) } coAnswersDelayed { false }
coEvery { authenticator.isLoggedIn() } coAnswersDelayed { false }
val event = Login(username = "rob", password = "rob")
logIn(event) should haveStatus(LOGIN_FAILURE)
}
Expand Down
4 changes: 2 additions & 2 deletions src/test/kotlin/mainmenu/MainMenuPresenterTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package mainmenu

import StopApp
import arch.RokyDispatchers
import authentication.Authenticator
import authentication.Auth
import coAnswersDelayed
import io.mockk.coEvery
import io.mockk.every
Expand All @@ -25,7 +25,7 @@ import org.junit.jupiter.api.Test
@OptIn(ExperimentalCoroutinesApi::class)
class MainMenuPresenterTest {
private lateinit var quit: StopApp
private lateinit var authenticator: Authenticator
private lateinit var authenticator: Auth
private lateinit var presenter: MainMenuPresenter
private lateinit var navigate: NavigateToAppWindow
private lateinit var view: MainMenuView
Expand Down