Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Added testing for add business form
  • Loading branch information
andylamax committed Oct 19, 2021
commit 519d9bbf055b9cbb80a130c6344e6f50e82606b0
8 changes: 4 additions & 4 deletions bitframe-client/ui/react/src/main/kotlin/bitframe/Bitframe.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ private fun defaultRenderers(

fun RBuilder.Bitframe(
client: BitframeService,
routeRenderers: Map<String, Renderer> = mapOf(),
moduleRenderers: Map<String, Renderer> = mapOf(),
pages: Map<String, Renderer> = mapOf(),
modules: Map<String, Renderer> = mapOf(),
version: String
) = browserRouter {
val allRouteRenderers = routeRenderers.toMutableMap().apply {
putAll(defaultRenderers(client, moduleRenderers, version))
val allRouteRenderers = pages.toMutableMap().apply {
putAll(defaultRenderers(client, modules, version))
}
switch {
for ((path, renderer) in allRouteRenderers) route(path, render = renderer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@ import kotlin.js.JsExport
import kotlin.js.JsName

data class DropDownInputField(
val options: List<Option>
@JsName("_options") val options: List<Option>
) {
@JsName("from")
constructor(vararg options: Option) : this(options.toList())

val items get() = options.toTypedArray()

val selected get() = options.firstOrNull { it.selected }

data class Option(
val label: String, val value: String = label, val selected: Boolean = false
val label: String,
val value: String = label,
val selected: Boolean = false
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,39 @@ package pimonitor.evaluation.business
import logging.console
import pimonitor.PiMonitorService
import pimonitor.evaluation.business.forms.CreateBusinessState
import pimonitor.evaluation.business.forms.CreateBusinessState.*
import react.Props
import react.RBuilder
import react.fc
import react.useEffectOnce
import reakt.ErrorBox
import reakt.LoadingBox
import useViewModelState

private external interface AddBusinessProps : Props {
var uid: String?
var scope: AddBusinessScope
}

private val AddBusiness = fc<AddBusinessProps> { props ->
val scope = props.scope
val vm = scope.viewModel
useEffectOnce {
scope.showForm(null)
scope.showForm(props.uid)
}
when (val state = useViewModelState(vm)) {
is CreateBusinessState.Loading -> LoadingBox(state.message)
is CreateBusinessState.Form -> CreateBusinessForm(
is Loading -> LoadingBox(state.message)
is Form -> CreateBusinessForm(
state = state,
onSubmit = {
console.log(it)
}
)
is Failure -> ErrorBox(state.cause)
}
}

internal fun RBuilder.AddBusiness(service: PiMonitorService) = child(AddBusiness) {
internal fun RBuilder.AddBusiness(service: PiMonitorService, uid: String? = null) = child(AddBusiness) {
attrs.scope = AddBusinessScope(service)
attrs.uid = uid
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package pimonitor.evaluation.business

import pimonitor.PiMonitorService
import react.RBuilder

fun RBuilder.InviteBusiness(service: PiMonitorService, uid: String?) = AddBusiness(service, uid)
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import kotlinx.extensions.get
import org.w3c.dom.HTMLDivElement
import pimonitor.authentication.signup.SignUp
import pimonitor.evaluation.business.BusinessContainer
import pimonitor.evaluation.business.InviteBusiness
import reakt.setContent

fun main() = document.get<HTMLDivElement>(By.id("root")).setContent {
Expand All @@ -21,10 +22,11 @@ fun main() = document.get<HTMLDivElement>(By.id("root")).setContent {
val version: String by konfig()
Bitframe(
client = client,
routeRenderers = mapOf(
"/authentication/sign-up" to { SignUp(client) }
pages = mapOf(
"/authentication/sign-up" to { SignUp(client) },
"/invite/:uid" to { InviteBusiness(client, it.match.params["uid"]) }
),
moduleRenderers = mapOf(
modules = mapOf(
"/evaluation/business" to { BusinessContainer(client) }
),
version = version
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package acceptance.monitors

import acceptance.utils.AcceptanceTest
import kotlinx.coroutines.delay
import org.junit.jupiter.api.TestInstance
import org.testcontainers.junit.jupiter.Testcontainers
import pimonitor.authentication.signup.SignUpParams
import pimonitor.monitored.CreateMonitoredBusinessParams
import pimonitor.test
import kotlin.test.Test

@Testcontainers
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class AddBusinessTest : AcceptanceTest() {
@Test
fun should_be_able_to_add_a_business() = application.test {
val params = SignUpParams.Individual(
name = "Jane Doe", email = "[email protected]", password = "janedoe"
)
val dashboard = openSignUpScreen().signUp(params).expectToBeSigningUp()
val details = CreateMonitoredBusinessParams(
businessName = "PiCortex",
contactName = "Mohammed Majapa",
contactEmail = "[email protected]"
)
val businesses = dashboard.selectBusinesses()
businesses.clickCreateButton().apply {
enter(details)
submitByPressingEnter()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import kotlin.js.JsExport

data class IndividualFormFields(
val select: DropDownInputField = DropDownInputField(
Option("Select account type"),
Option("Register as Business"),
Option("Register as Individual", selected = true)
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package pimonitor.evaluation.business.forms

import bitframe.authentication.users.Contacts
import bitframe.authentication.users.UserRef
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
Expand Down Expand Up @@ -32,9 +30,9 @@ class CreateBusinessViewModel(
private fun CoroutineScope.showInviteForm(uid: String) = launch {
flow {
emit(State.Loading("Fetching invite information, please wait . . ."))
val monitor = monitorService.monitor(UserRef(uid = uid, name = "", tag = "", contacts = Contacts.None, null)).await()
val monitor = monitorService.load(uid).await() ?: throw RuntimeException("Failed to load inviter(uid=$uid) information")
val fields = InviteBusinessFormFields(monitor)
emit(State.Form(fields,null))
emit(State.Form(fields, null))
}.catch {
emit(State.Failure(it))
}.collect { ui.value = it }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ import pimonitor.authentication.signup.SignUpState as State

class SignUpScope(
private val service: PiMonitorService
) : SignUpServiceWrapper(service.signUp) {

val viewModel: ViewModel<Intent, State> = SignUpViewModel(service.signUp, service.signIn)
) {
val viewModel: ViewModel<Intent, State> by lazy { SignUpViewModel(service.signUp, service.signIn) }

val registerAsIndividual = {
viewModel.post(Intent.SelectRegisterAsIndividual)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package pimonitor.screens.authentication

import bitframe.authentication.signin.SignInCredentials
import pimonitor.screens.api.Screen
import pimonitor.screens.dashboard.DashboardScreen

interface SignInScreen : Screen {
suspend fun isShowingInvalidCredentials(): Boolean
suspend fun signIn(credentials: SignInCredentials)
suspend fun signIn(credentials: SignInCredentials): DashboardScreen
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package pimonitor.screens.authentication

import pimonitor.screens.dashboard.DashboardScreen

interface SignUpProcess {
fun expectToBeSigningUp() : DashboardScreen
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import pimonitor.authentication.signup.SignUpParams
import pimonitor.screens.api.Screen

interface SignUpScreen : Screen {
suspend fun signUp(with: SignUpParams)
suspend fun signUp(with: SignUpParams): SignUpProcess
suspend fun expectUserToBeRegistered()
suspend fun expectToBeSigningUp()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package pimonitor.screens.dashboard

import pimonitor.monitored.CreateMonitoredBusinessParams

interface AddBusinessForm {
suspend fun enter(details: CreateMonitoredBusinessParams)
suspend fun submitByPressingEnter()
suspend fun submitByClicking()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package pimonitor.screens.dashboard

interface BusinessesScreen {
fun clickCreateButton(): AddBusinessForm
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package pimonitor.screens.dashboard

import pimonitor.screens.api.Screen

interface DashboardScreen : Screen {
suspend fun selectBusinesses(): BusinessesScreen
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package pimonitor.screens

import com.codeborne.selenide.Selectors.withText
import pimonitor.screens.dashboard.BusinessesScreen
import pimonitor.screens.dashboard.BusinessesScreenWeb
import pimonitor.screens.dashboard.DashboardScreen
import pimonitor.utils.isVisible
import com.codeborne.selenide.Selenide.`$` as S

class DashboardScreenWeb : DashboardScreen {
override suspend fun isVisible(): Boolean {
return S(withText("Dashboard")).isVisible()
}

override suspend fun selectBusinesses(): BusinessesScreen {
S(withText("Business")).click()
return BusinessesScreenWeb()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import bitframe.authentication.signin.SignInCredentials
import com.codeborne.selenide.Selectors.withText
import org.openqa.selenium.By
import pimonitor.screens.authentication.SignInScreen
import pimonitor.screens.dashboard.DashboardScreen
import pimonitor.utils.isVisible
import com.codeborne.selenide.Selenide.`$` as S

Expand All @@ -13,10 +14,11 @@ class SignInScreenWeb : SignInScreen {

override suspend fun isVisible(): Boolean = email.isVisible() && pass.isVisible()

override suspend fun signIn(credentials: SignInCredentials) {
override suspend fun signIn(credentials: SignInCredentials): DashboardScreen {
email.sendKeys(credentials.alias)
pass.sendKeys(credentials.password)
pass.pressEnter()
return DashboardScreenWeb()
}

override suspend fun isShowingInvalidCredentials(): Boolean {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package pimonitor.screens

import com.codeborne.selenide.Selectors
import com.codeborne.selenide.Selectors.withText
import pimonitor.screens.authentication.SignUpProcess
import pimonitor.screens.dashboard.DashboardScreen
import pimonitor.utils.isVisible
import com.codeborne.selenide.Selenide.`$` as S

class SignUpProcessWeb : SignUpProcess {
override fun expectToBeSigningUp(): DashboardScreen {
S(withText("Creating your account, please wait . . .")).isVisible()
S(withText("Success. Signing you in, please wait . . .")).isVisible()
S(withText("Dashboard")).isVisible()
return DashboardScreenWeb()
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package pimonitor.screens

import com.codeborne.selenide.Selectors.byAttribute
import com.codeborne.selenide.Selectors.withText
import com.codeborne.selenide.SelenideElement
import org.openqa.selenium.By
import pimonitor.authentication.signup.SignUpParams
import pimonitor.screens.authentication.SignUpProcess
import pimonitor.screens.authentication.SignUpScreen
import pimonitor.utils.isVisible
import kotlin.properties.ReadOnlyProperty
import pimonitor.utils.name
import pimonitor.utils.submit
import com.codeborne.selenide.Selenide.`$` as S

class SignUpScreenWeb : SignUpScreen {
val select = S(By.name("registrationType"))
private val nextOrSubmitButton = S(byAttribute("type", "submit"))
private val nextOrSubmitButton by submit()

private fun signUp(params: SignUpParams.Individual) {
private fun signUp(params: SignUpParams.Individual): SignUpProcess {
val name by name()
val email by name()
val password by name()
Expand All @@ -24,13 +24,10 @@ class SignUpScreenWeb : SignUpScreen {
password.sendKeys(params.password)

nextOrSubmitButton.click()
return SignUpProcessWeb()
}

fun name() = ReadOnlyProperty<Any?, SelenideElement> { thisRef, property ->
S(By.name(property.name))
}

private fun signUp(params: SignUpParams.Business) {
private fun signUp(params: SignUpParams.Business): SignUpProcess {
select.selectOption(1)

val businessName by name()
Expand All @@ -43,13 +40,19 @@ class SignUpScreenWeb : SignUpScreen {
individualEmail.sendKeys(params.individualEmail)
password.sendKeys(params.password)
nextOrSubmitButton.click()
return SignUpProcessWeb()
}

override suspend fun signUp(with: SignUpParams) = when (with) {
is SignUpParams.Business -> signUp(with)
is SignUpParams.Individual -> signUp(with)
}

override suspend fun expectToBeSigningUp() {
S(withText("Creating your account, please wait . . .")).isVisible()
S(withText("Success. signing you in . . .")).isVisible()
}

private suspend fun expectUserToBeRegistered(waitCounts: Int) {
// TODO
//
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package pimonitor.screens.dashboard

import pimonitor.monitored.CreateMonitoredBusinessParams
import pimonitor.utils.name
import pimonitor.utils.submit

class AddBusinessFormWeb : AddBusinessForm {
val businessName by name()
val contactName by name()
val contactEmail by name()

val submit by submit()

override suspend fun enter(details: CreateMonitoredBusinessParams) {
businessName.sendKeys(details.businessName)
contactName.sendKeys(details.contactName)
contactEmail.sendKeys(details.contactEmail)
}

override suspend fun submitByPressingEnter() {
contactEmail.pressEnter()
}

override suspend fun submitByClicking() {
submit.click()
}
}
Loading