Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,4 @@ src/apps/mobile/android/build/
src/apps/mobile/android/*/build/
src/apps/mobile/android/local.properties
src/apps/mobile/android/.kotlin/
/src/apps/mobile/ios/build/
4 changes: 3 additions & 1 deletion src/apps/mobile/android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ android {
minSdk = libs.versions.androidMinSdk.get().toInt()
targetSdk = libs.versions.androidTargetSdk.get().toInt()
versionCode = 1
versionName = "0.1.0"
versionName = "1.0.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

Expand Down Expand Up @@ -79,6 +79,8 @@ dependencies {
implementation(libs.google.code.scanner)
implementation(libs.androidx.window)

testImplementation("junit:junit:4.13.2")

debugImplementation(libs.compose.ui.tooling)
debugImplementation(libs.compose.ui.test.manifest)
androidTestImplementation(platform(libs.compose.bom))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,25 @@ import androidx.compose.ui.test.assertCountEquals
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.v2.createComposeRule
import androidx.compose.ui.test.onAllNodesWithText
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import com.bitfun.mobile.app.ui.remote.CONNECT_ACCOUNT_DEVICE_REFRESH_TEST_TAG
import com.bitfun.mobile.app.ui.remote.CONNECT_ACCOUNT_DEVICE_ROW_TEST_TAG_PREFIX
import com.bitfun.mobile.app.ui.remote.CONNECT_ACCOUNT_DEVICE_SCAN_TEST_TAG
import com.bitfun.mobile.app.ui.remote.ConnectAccountDeviceScreen
import com.bitfun.mobile.app.ui.remote.AccountRemoteScreen
import com.bitfun.mobile.app.ui.theme.BitFunTheme
import com.bitfun.mobile.core.feature.account.AccountDeviceUi
import com.bitfun.mobile.core.feature.account.AccountUiState
import com.bitfun.mobile.core.feature.connection.ConnectionPhase
import com.bitfun.mobile.core.feature.layout.SettingsPlacement
import com.bitfun.mobile.core.feature.layout.SettingsPlacementMode
import com.bitfun.mobile.core.feature.session.RemoteSessionUiState
import com.bitfun.mobile.core.feature.workspace.RemoteWorkspaceUiState
import org.junit.Rule
import org.junit.Test
import org.junit.Assert.assertEquals

class AccountRemoteScreenTest {
@get:Rule
Expand All @@ -27,8 +38,29 @@ class AccountRemoteScreenTest {
workspaceState = RemoteWorkspaceUiState.Idle,
deviceId = "device-1",
deviceName = "Studio Mac",
createDevices = emptyList(),
accountUsername = "tester",
phase = ConnectionPhase.CONNECTED,
settingsPlacement = SettingsPlacement(
mode = SettingsPlacementMode.BOTTOM,
width = 0,
height = 0,
maxHeight = 0,
),
sessionDetailsPlacement = SettingsPlacement(
mode = SettingsPlacementMode.BOTTOM,
width = 0,
height = 0,
maxHeight = 0,
),
viewSettingsPlacement = SettingsPlacement(
mode = SettingsPlacementMode.BOTTOM,
width = 0,
height = 0,
maxHeight = 0,
),
onOpenRemoteSettings = {},
onCreateDevicePick = {},
onSessionIntent = {},
onWorkspaceIntent = {},
modifier = Modifier,
Expand All @@ -38,4 +70,42 @@ class AccountRemoteScreenTest {

composeRule.onAllNodesWithText("Connect to a desktop").assertCountEquals(0)
}

@Test
fun aSignedInAccountWithoutATargetCanRefreshSelectOrScan() {
var refreshes = 0
var selected = ""
var scans = 0
composeRule.setContent {
BitFunTheme(dark = false) {
ConnectAccountDeviceScreen(
state = AccountUiState.Ready(
userId = "user-1",
username = "tester",
devices = listOf(
AccountDeviceUi("desk-1", "Studio Mac", online = true, lastSeenAt = null),
AccountDeviceUi("desk-2", "Office PC", online = false, lastSeenAt = null),
),
selectedDeviceId = null,
selectedDeviceName = null,
),
onBack = {},
onRefresh = { refreshes += 1 },
onSelect = { selected = it },
onOpenScanner = { scans += 1 },
modifier = Modifier,
)
}
}

composeRule.onNodeWithText("Choose a desktop").assertIsDisplayed()
composeRule.onNodeWithTag(CONNECT_ACCOUNT_DEVICE_REFRESH_TEST_TAG).performClick()
composeRule.onNodeWithTag(CONNECT_ACCOUNT_DEVICE_ROW_TEST_TAG_PREFIX + "desk-1").performClick()
composeRule.onNodeWithTag(CONNECT_ACCOUNT_DEVICE_ROW_TEST_TAG_PREFIX + "desk-2").performClick()
composeRule.onNodeWithTag(CONNECT_ACCOUNT_DEVICE_SCAN_TEST_TAG).performClick()

assertEquals(1, refreshes)
assertEquals("desk-1", selected)
assertEquals(1, scans)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.compose.ui.test.getUnclippedBoundsInRoot
import androidx.compose.ui.test.junit4.v2.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.test.platform.app.InstrumentationRegistry
import com.bitfun.mobile.app.ui.chat.ChatMessageBubble
import com.bitfun.mobile.app.ui.chat.message.SUBAGENT_GROUP_TEST_TAG
import com.bitfun.mobile.app.ui.chat.message.TYPING_DOTS_TEST_TAG
Expand Down Expand Up @@ -91,12 +92,12 @@ class ChatMessageBubbleTest {
}

@Test
fun aMessageThatNeverLeftTheDeviceSaysSo() {
fun aMessageThatNeverLeftTheDeviceUsesTheSendFailureCopy() {
composeRule.setContent {
Bubble(row(kind = ConversationRowKind.USER, text = "ship it", showRetry = true))
}

composeRule.onNodeWithText("Not delivered.").assertIsDisplayed()
composeRule.onNodeWithText(string(R.string.chat_send_failed)).assertIsDisplayed()
}

@Test
Expand Down Expand Up @@ -181,4 +182,7 @@ class ChatMessageBubbleTest {
question = null,
actions = emptySet(),
)

private fun string(resource: Int): String =
InstrumentationRegistry.getInstrumentation().targetContext.getString(resource)
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class ConversationViewTest {
BitFunTheme(dark = false) {
ConversationTimelineView(
rows = listOf(assistantRow(answer)),
hasMoreMessages = false,
onLoadOlder = {},
enabled = true,
onApproveTool = {},
onRejectTool = { _, _ -> },
Expand Down Expand Up @@ -175,6 +177,8 @@ class ConversationViewTest {
private fun TimelineForTest(rows: List<ConversationRow>) {
ConversationTimelineView(
rows = rows,
hasMoreMessages = false,
onLoadOlder = {},
enabled = true,
onApproveTool = {},
onRejectTool = { _, _ -> },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performTextInput
import com.bitfun.mobile.app.ui.chat.COMPOSER_INPUT_TEST_TAG
import com.bitfun.mobile.app.ui.chat.COMPOSER_SEND_TEST_TAG
import com.bitfun.mobile.app.ui.chat.MODEL_CONTROL_TEST_TAG
import com.bitfun.mobile.app.ui.chat.MODEL_SELECTOR_OPTION_TEST_TAG_PREFIX
import com.bitfun.mobile.app.ui.remote.CREATE_SESSION_BACK_TEST_TAG
import com.bitfun.mobile.app.ui.remote.CREATE_SESSION_WORKSPACE_TEST_TAG
import com.bitfun.mobile.app.ui.remote.CreateDeviceChoice
import com.bitfun.mobile.app.ui.remote.CreateSessionScreen
import com.bitfun.mobile.core.feature.connection.ConnectionPhase
import com.bitfun.mobile.core.feature.session.RemoteSessionIntent
import com.bitfun.mobile.core.feature.session.ModelOption
import com.bitfun.mobile.core.feature.workspace.RemoteFileDownloadUiState
import com.bitfun.mobile.core.feature.workspace.RemoteFilePreviewUiState
import com.bitfun.mobile.core.feature.workspace.RemoteWorkspaceUiState
Expand Down Expand Up @@ -54,6 +58,9 @@ class CreateSessionScreenTest {
workspaceState = readyWorkspace(),
phase = ConnectionPhase.CONNECTED,
deviceId = "desk-1",
devices = emptyList(),
compact = true,
onDevicePick = {},
busy = false,
onBack = {},
onWorkspaceIntent = {},
Expand Down Expand Up @@ -84,6 +91,9 @@ class CreateSessionScreenTest {
workspaceState = readyWorkspace(),
phase = ConnectionPhase.CONNECTED,
deviceId = "",
devices = emptyList(),
compact = true,
onDevicePick = {},
busy = false,
onBack = {},
onWorkspaceIntent = {},
Expand All @@ -101,13 +111,47 @@ class CreateSessionScreenTest {
assertNull(intent)
}

@Test
fun selectedModelIsAppliedToTheNewSession() {
var intent: RemoteSessionIntent? = null
composeRule.setContent {
CreateSessionScreen(
workspaceState = readyWorkspace(),
phase = ConnectionPhase.CONNECTED,
deviceId = "desk-1",
devices = emptyList(),
modelOptions = listOf(
ModelOption("model-primary", "Primary", "Account", selected = true),
ModelOption("model-fast", "Fast", "Account", selected = false),
),
compact = true,
onDevicePick = {},
busy = false,
onBack = {},
onWorkspaceIntent = {},
onIntent = { intent = it },
modifier = Modifier,
)
}

composeRule.onNodeWithTag(COMPOSER_INPUT_TEST_TAG).performTextInput("review the parser")
composeRule.onNodeWithTag(MODEL_CONTROL_TEST_TAG).performClick()
composeRule.onNodeWithTag(MODEL_SELECTOR_OPTION_TEST_TAG_PREFIX + "model-fast").performClick()
composeRule.onNodeWithTag(COMPOSER_SEND_TEST_TAG).performClick()

assertEquals("model-fast", (intent as RemoteSessionIntent.CreateSession).modelId)
}

@Test
fun theWorkspaceRowOpensAPickerThatSaysWhenThereIsNothingToPick() {
composeRule.setContent {
CreateSessionScreen(
workspaceState = readyWorkspace(),
phase = ConnectionPhase.CONNECTED,
deviceId = "desk-1",
devices = emptyList(),
compact = true,
onDevicePick = {},
busy = false,
onBack = {},
onWorkspaceIntent = {},
Expand All @@ -125,6 +169,34 @@ class CreateSessionScreenTest {
.assertIsDisplayed()
}

@Test
fun wideCreateRouteAnchorsTheDesktopPickerAndSwitchesTargets() {
var picked: String? = null
composeRule.setContent {
CreateSessionScreen(
workspaceState = readyWorkspace(),
phase = ConnectionPhase.CONNECTED,
deviceId = "desk-1",
devices = listOf(
CreateDeviceChoice("desk-1", "Studio Mac", online = true, selected = true),
CreateDeviceChoice("desk-2", "Office PC", online = true, selected = false),
),
compact = false,
onDevicePick = { picked = it },
busy = false,
onBack = {},
onWorkspaceIntent = {},
onIntent = {},
modifier = Modifier,
)
}

composeRule.onNodeWithText("Studio Mac").performClick()
composeRule.onNodeWithText("Office PC").assertIsDisplayed().performClick()

assertEquals("desk-2", picked)
}

@Test
fun backLeavesWithoutCreatingAnything() {
var back = 0
Expand All @@ -135,6 +207,9 @@ class CreateSessionScreenTest {
workspaceState = readyWorkspace(),
phase = ConnectionPhase.CONNECTED,
deviceId = "desk-1",
devices = emptyList(),
compact = true,
onDevicePick = {},
busy = false,
onBack = { back += 1 },
onWorkspaceIntent = {},
Expand Down
Loading
Loading