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
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
- When modifying or adding UI, add screenshot tests in `androidApp/src/androidTest` following existing patterns to keep visual coverage current.
- Run `./gradlew :shared:check` for KMP unit coverage;
- Name tests with intent (e.g., `shouldReturnZeroBalanceWhenEmptyWallet`); group by feature or use-case.
- When you change the API surface of composables, search for related tests and update them so snapshots and unit coverage stay in sync.

## Commit & Pull Request Guidelines
- Commit messages: concise, imperative. Conventional prefixes (`feat:`, `fix:`, `chore:`, `docs:`) are welcome and match existing history.
Expand Down
Binary file modified image/roborazzi/home_screen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions shared/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import java.net.URI

import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

Expand Down Expand Up @@ -147,6 +149,23 @@ dependencies {

tasks.withType<Test>().configureEach {
systemProperty("roborazzi.test.record.dir", rootProject.layout.projectDirectory.dir("image/roborazzi").asFile.path)

listOf(
"http" to System.getenv("http_proxy"),
"https" to System.getenv("https_proxy"),
).forEach { (scheme, proxyValue) ->
proxyValue
?.takeIf { it.isNotBlank() }
?.let(::URI)
?.let { proxyUri ->
proxyUri.host?.let { host ->
systemProperty("$scheme.proxyHost", host)
}
proxyUri.port.takeIf { it != -1 }?.let { port ->
systemProperty("$scheme.proxyPort", port)
}
}
}
}

sqldelight {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.prof18.moneyflow

import androidx.compose.material.Scaffold
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.test.ext.junit.runners.AndroidJUnit4
Expand All @@ -24,25 +25,28 @@ class AddTransactionRoborazziTest : RoborazziTestBase() {
fun captureAddTransactionScreen() {
composeRule.setContent {
MoneyFlowTheme {
AddTransactionScreen(
categoryState = remember { mutableStateOf(RoborazziSampleData.sampleCategory) },
navigateUp = {},
navigateToCategoryList = {},
addTransaction = {},
amountText = "10.00",
updateAmountText = {},
descriptionText = "Pizza 🍕",
updateDescriptionText = {},
selectedTransactionType = TransactionType.OUTCOME,
updateTransactionType = {},
updateYear = {},
updateMonth = {},
updateDay = {},
saveDate = {},
dateLabel = "11 July 2021",
addTransactionAction = null,
resetAction = {},
)
Scaffold {
AddTransactionScreen(
categoryState = remember { mutableStateOf(RoborazziSampleData.sampleCategory) },
navigateUp = {},
navigateToCategoryList = {},
addTransaction = {},
amountText = "10.00",
updateAmountText = {},
descriptionText = "Pizza 🍕",
updateDescriptionText = {},
selectedTransactionType = TransactionType.OUTCOME,
updateTransactionType = {},
updateYear = {},
updateMonth = {},
updateDay = {},
saveDate = {},
dateLabel = "11 July 2021",
addTransactionAction = null,
resetAction = {},
paddingValues = it,
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.prof18.moneyflow

import androidx.compose.material.Scaffold
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.prof18.moneyflow.features.alltransactions.AllTransactionsUiState
import com.prof18.moneyflow.presentation.alltransactions.AllTransactionsScreen
Expand All @@ -19,14 +20,17 @@ class AllTransactionsRoborazziTest : RoborazziTestBase() {
fun captureAllTransactionsScreen() {
composeRule.setContent {
MoneyFlowTheme {
AllTransactionsScreen(
stateFlow = MutableStateFlow(
AllTransactionsUiState(
transactions = RoborazziSampleData.sampleTransactions,
Scaffold {
AllTransactionsScreen(
stateFlow = MutableStateFlow(
AllTransactionsUiState(
transactions = RoborazziSampleData.sampleTransactions,
),
),
),
loadNextPage = {},
)
loadNextPage = {},
paddingValues = it,
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.prof18.moneyflow

import androidx.compose.material.Scaffold
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.prof18.moneyflow.domain.entities.Category
import com.prof18.moneyflow.presentation.categories.CategoriesScreen
Expand All @@ -20,25 +21,28 @@ class CategoriesRoborazziTest : RoborazziTestBase() {
fun captureCategoriesScreen() {
composeRule.setContent {
MoneyFlowTheme {
CategoriesScreen(
navigateUp = {},
sendCategoryBack = {},
isFromAddTransaction = true,
categoryModel = CategoryModel.CategoryState(
categories = listOf(
Category(
id = 0,
name = "Food",
icon = CategoryIcon.IC_HAMBURGER_SOLID,
),
Category(
id = 1,
name = "Drinks",
icon = CategoryIcon.IC_COCKTAIL_SOLID,
Scaffold {
CategoriesScreen(
navigateUp = {},
sendCategoryBack = {},
isFromAddTransaction = true,
categoryModel = CategoryModel.CategoryState(
categories = listOf(
Category(
id = 0,
name = "Food",
icon = CategoryIcon.IC_HAMBURGER_SOLID,
),
Category(
id = 1,
name = "Drinks",
icon = CategoryIcon.IC_COCKTAIL_SOLID,
),
),
),
),
)
paddingValues = it,
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.prof18.moneyflow

import androidx.compose.material.Scaffold
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.prof18.moneyflow.domain.entities.BalanceRecap
import com.prof18.moneyflow.presentation.home.HomeModel
Expand All @@ -19,18 +20,21 @@ class HomeRoborazziTest : RoborazziTestBase() {
fun captureHomeScreen() {
composeRule.setContent {
MoneyFlowTheme {
HomeScreen(
homeModel = HomeModel.HomeState(
balanceRecap = BalanceRecap(
totalBalance = 5000.0,
monthlyIncome = 1000.0,
monthlyExpenses = 50.0,
Scaffold {
HomeScreen(
homeModel = HomeModel.HomeState(
balanceRecap = BalanceRecap(
totalBalance = 5000.0,
monthlyIncome = 1000.0,
monthlyExpenses = 50.0,
),
latestTransactions = RoborazziSampleData.sampleTransactions,
),
latestTransactions = RoborazziSampleData.sampleTransactions,
),
hideSensitiveDataState = false,
navigateToAllTransactions = {},
)
hideSensitiveDataState = false,
navigateToAllTransactions = {},
paddingValues = it,
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.prof18.moneyflow

import androidx.compose.material.Scaffold
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.prof18.moneyflow.features.settings.BiometricAvailabilityChecker
import com.prof18.moneyflow.presentation.settings.SettingsScreen
Expand All @@ -18,15 +19,18 @@ class SettingsRoborazziTest : RoborazziTestBase() {
fun captureSettingsScreen() {
composeRule.setContent {
MoneyFlowTheme {
SettingsScreen(
biometricAvailabilityChecker = object : BiometricAvailabilityChecker {
override fun isBiometricSupported(): Boolean = true
},
biometricState = true,
onBiometricEnabled = {},
hideSensitiveDataState = true,
onHideSensitiveDataEnabled = {},
)
Scaffold {
SettingsScreen(
biometricAvailabilityChecker = object : BiometricAvailabilityChecker {
override fun isBiometricSupported(): Boolean = true
},
biometricState = true,
onBiometricEnabled = {},
hideSensitiveDataState = true,
onHideSensitiveDataEnabled = {},
paddingValues = it,
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,13 @@ private fun EntryProviderScope<AppRoute>.screens(
val hideSensitiveData by homeViewModel.hideSensitiveDataState.collectAsState()

HomeScreen(
navigateToAddTransaction = { backStack.add(AddTransactionRoute) },
paddingValues = paddingValues,
deleteTransaction = { id -> homeViewModel.deleteTransaction(id) },
homeModel = homeModel,
hideSensitiveDataState = hideSensitiveData,
changeSensitiveDataVisibility = { homeViewModel.changeSensitiveDataVisibility(it) },
navigateToAllTransactions = { backStack.add(AllTransactionsRoute) },
paddingValues = paddingValues,
navigateToAddTransaction = { backStack.add(AddTransactionRoute) },
deleteTransaction = { id -> homeViewModel.deleteTransaction(id) },
changeSensitiveDataVisibility = { homeViewModel.changeSensitiveDataVisibility(it) },
)
}

Expand All @@ -165,6 +165,7 @@ private fun EntryProviderScope<AppRoute>.screens(
dateLabel = uiState.dateLabel,
addTransactionAction = uiState.addTransactionAction,
resetAction = viewModel::resetAction,
paddingValues = paddingValues,
)
}

Expand All @@ -182,15 +183,17 @@ private fun EntryProviderScope<AppRoute>.screens(
},
isFromAddTransaction = route.fromAddTransaction,
categoryModel = categoryModel,
paddingValues = paddingValues,
)
}

entry<AllTransactionsRoute> {
val viewModel = koinViewModel<AllTransactionsViewModel>()
AllTransactionsScreen(
navigateUp = { backStack.removeLastOrNull() },
stateFlow = viewModel.state,
loadNextPage = viewModel::loadNextPage,
paddingValues = paddingValues,
navigateUp = { backStack.removeLastOrNull() },
)
}

Expand All @@ -206,6 +209,7 @@ private fun EntryProviderScope<AppRoute>.screens(
onBiometricEnabled = viewModel::updateBiometricState,
hideSensitiveDataState = hideDataState,
onHideSensitiveDataEnabled = viewModel::updateHideSensitiveDataState,
paddingValues = paddingValues,
)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.prof18.moneyflow.presentation.addtransaction

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Icon
Expand Down Expand Up @@ -61,6 +62,7 @@ internal fun AddTransactionScreen(
dateLabel: String?,
addTransactionAction: AddTransactionAction?,
resetAction: () -> Unit,
paddingValues: PaddingValues,
) {
val (showDatePickerDialog, setShowedDatePickerDialog) = remember { mutableStateOf(false) }

Expand Down Expand Up @@ -102,6 +104,7 @@ internal fun AddTransactionScreen(
val keyboardController = LocalSoftwareKeyboardController.current

Scaffold(
modifier = Modifier.padding(paddingValues),
scaffoldState = scaffoldState,
topBar = {
MFTopBar(
Expand All @@ -115,8 +118,8 @@ internal fun AddTransactionScreen(
actionEnabled = categoryState.value?.id != null && amountText.isNotEmpty(),
)
},
content = {
Column {
content = { innerPadding ->
Column(modifier = Modifier.padding(innerPadding)) {
DatePickerDialog(
showDatePickerDialog,
setShowedDatePickerDialog,
Expand Down Expand Up @@ -239,6 +242,7 @@ private fun AddTransactionScreenPreview() {
dateLabel = "11 July 2021",
addTransactionAction = null,
resetAction = {},
paddingValues = PaddingValues(),
)
}
}
Expand Down
Loading