Skip to content

Commit

Permalink
MBL-1479: Fix payment card - fix pledge CTA flow (#2073)
Browse files Browse the repository at this point in the history
* add fix payment click

* fix payment

* polish

* cleanup and mock data

* linter

* Add activity result that triggers when fix payment successful

* linter:

* When user changes payment method, refresh list

* linter

* Update mock data

* Fix mock data again

* Fix test:

---------

Co-authored-by: Leigh Douglas <[email protected]>
  • Loading branch information
leighdouglas and Leigh Douglas authored Jul 16, 2024
1 parent df6646a commit d0fbc87
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,24 @@ class PPOCardFactory private constructor() {
viewType = PPOCardViewType.CONFIRM_ADDRESS
)
}

fun fixPaymentCard(): PPOCard {
return ppoCard(
backingID = "1234",
amount = "$12.00",
address = "Firsty Lasty\n123 First Street, Apt #5678\nLos Angeles, CA 90025-1234\nUnited States",
currencySymbol = "$",
currencyCode = CurrencyCode.USD,
projectName = "Super Duper Project",
projectId = "12345",
projectSlug = "project/slug",
imageUrl = "image/url",
creatorName = "Creator Name",
backingDetailsUrl = "backing/details/url",
timeNumberForAction = 7,
showBadge = false,
viewType = PPOCardViewType.FIX_PAYMENT
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.kickstarter.features.pledgedprojectsoverview.ui

import android.app.Activity
import android.content.Intent
import android.os.Build
import android.os.Bundle
import androidx.activity.OnBackPressedCallback
import androidx.activity.compose.setContent
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.isSystemInDarkTheme
Expand All @@ -17,11 +20,15 @@ import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.paging.compose.collectAsLazyPagingItems
import com.kickstarter.features.pledgedprojectsoverview.data.PledgedProjectsOverviewQueryData
import com.kickstarter.features.pledgedprojectsoverview.viewmodel.PledgedProjectsOverviewViewModel
import com.kickstarter.libs.MessagePreviousScreenType
import com.kickstarter.libs.RefTag
import com.kickstarter.libs.utils.TransitionUtils
import com.kickstarter.libs.utils.extensions.getEnvironment
import com.kickstarter.libs.utils.extensions.getProjectIntent
import com.kickstarter.libs.utils.extensions.isDarkModeEnabled
import com.kickstarter.libs.utils.extensions.isTrue
import com.kickstarter.ui.IntentKey
import com.kickstarter.ui.SharedPreferenceKey
import com.kickstarter.ui.activities.AppThemes
Expand All @@ -36,6 +43,20 @@ class PledgedProjectsOverviewActivity : AppCompatActivity() {
private lateinit var viewModelFactory: PledgedProjectsOverviewViewModel.Factory
private val viewModel: PledgedProjectsOverviewViewModel by viewModels { viewModelFactory }
private var theme = AppThemes.MATCH_SYSTEM.ordinal
private var startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val data = result.data?.getBooleanExtra(IntentKey.FIX_PAYMENT_SUCCESS, false)
data?.let {
if (it.isTrue()) {
viewModel.getPledgedProjects(
PledgedProjectsOverviewQueryData(
25, null, null, null
)
)
}
}
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand Down Expand Up @@ -87,7 +108,8 @@ class PledgedProjectsOverviewActivity : AppCompatActivity() {
onSeeAllBackedProjectsClick = { startProfileActivity() },
pullRefreshCallback = {
// TODO call viewmodel.getPledgedProjects() here
}
},
onFixPaymentClick = { projectSlug -> openManagePledge(projectSlug, resultLauncher = startForResult) }
)
}

Expand Down Expand Up @@ -128,4 +150,16 @@ class PledgedProjectsOverviewActivity : AppCompatActivity() {
TransitionUtils.transition(it, TransitionUtils.slideInFromRight())
}
}

private fun openManagePledge(projectSlug: String, resultLauncher: ActivityResultLauncher<Intent>) {
resultLauncher.launch(
Intent().getProjectIntent(this)
.putExtra(IntentKey.PROJECT_PARAM, projectSlug)
.putExtra(IntentKey.EXPAND_PLEDGE_SHEET, true)
.putExtra(IntentKey.REF_TAG, RefTag.activity())
)
this.let {
TransitionUtils.transition(it, TransitionUtils.slideInFromRight())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ private fun PledgedProjectsOverviewScreenPreview() {
backgroundColor = colors.backgroundSurfacePrimary
) { padding ->
val ppoCardList1 = (0..10).map {
PPOCardFactory.confirmAddressCard()
PPOCardFactory.fixPaymentCard()
}
val ppoCardPagingList = flowOf(PagingData.from(ppoCardList1)).collectAsLazyPagingItems()
PledgedProjectsOverviewScreen(
Expand All @@ -76,7 +76,8 @@ private fun PledgedProjectsOverviewScreenPreview() {
onProjectPledgeSummaryClick = {},
onSendMessageClick = {},
onSeeAllBackedProjectsClick = {},
errorSnackBarHostState = SnackbarHostState()
errorSnackBarHostState = SnackbarHostState(),
onFixPaymentClick = {}
)
}
}
Expand Down Expand Up @@ -105,7 +106,8 @@ private fun PledgedProjectsOverviewScreenErrorPreview() {
onSendMessageClick = {},
onSeeAllBackedProjectsClick = {},
isErrored = true,
errorSnackBarHostState = SnackbarHostState()
errorSnackBarHostState = SnackbarHostState(),
onFixPaymentClick = {}
)
}
}
Expand All @@ -129,8 +131,9 @@ private fun PledgedProjectsOverviewScreenEmptyPreview() {
onAddressConfirmed = {},
onProjectPledgeSummaryClick = {},
onSendMessageClick = {},
errorSnackBarHostState = SnackbarHostState(),
onFixPaymentClick = {},
onSeeAllBackedProjectsClick = {},
errorSnackBarHostState = SnackbarHostState()
)
}
}
Expand All @@ -151,7 +154,8 @@ fun PledgedProjectsOverviewScreen(
onSeeAllBackedProjectsClick: () -> Unit,
isLoading: Boolean = false,
isErrored: Boolean = false,
pullRefreshCallback: () -> Unit = {}
pullRefreshCallback: () -> Unit = {},
onFixPaymentClick: (projectSlug: String) -> Unit,
) {
val openConfirmAddressAlertDialog = remember { mutableStateOf(false) }
var confirmedAddress by remember { mutableStateOf("") } // TODO: This is either the original shipping address or the user-edited address
Expand Down Expand Up @@ -227,7 +231,14 @@ fun PledgedProjectsOverviewScreen(
sendAMessageClickAction = { onSendMessageClick(it.projectSlug() ?: "") },
shippingAddress = it.address() ?: "", // TODO replace with formatted address from PPO response
showBadge = it.showBadge(),
onActionButtonClicked = { },
onActionButtonClicked = {
when (it.viewType()) {
PPOCardViewType.FIX_PAYMENT -> {
onFixPaymentClick(it.projectSlug() ?: "")
}
else -> {}
}
},
onSecondaryActionButtonClicked = {
when (it.viewType()) {
PPOCardViewType.CONFIRM_ADDRESS -> {
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/com/kickstarter/ui/IntentKey.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,5 @@ object IntentKey {
const val FLAGGINGKIND = "com.kickstarter.kickstarter.intent_report_project"
const val PREVIOUS_SCREEN = "com.kickstarter.kickstarter.previous_screen"
const val OAUTH_REDIRECT_URL = "com.kickstarter.kickstarter.oauth_redirect_url"
const val FIX_PAYMENT_SUCCESS = "com.kickstarter.kickstarter.fix_payment_success"
}
Original file line number Diff line number Diff line change
Expand Up @@ -1120,6 +1120,9 @@ class ProjectPageActivity :
private fun showUpdatePledgeSuccess() {
clearFragmentBackStack()
backingFragment()?.pledgeSuccessfullyUpdated()
val intent = Intent()
.putExtra(IntentKey.FIX_PAYMENT_SUCCESS, true)
setResult(Activity.RESULT_OK, intent)
}

private fun startShareIntent(projectNameAndShareUrl: Pair<String, String>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ PledgedProjectsOverviewScreenTest : KSRobolectricTestCase() {
onSendMessageClick = {},
onAddressConfirmed = {},
onProjectPledgeSummaryClick = {},
onSeeAllBackedProjectsClick = {}
onSeeAllBackedProjectsClick = {},
onFixPaymentClick = {}
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import com.kickstarter.mock.factories.ProjectFactory
import com.kickstarter.mock.services.MockApolloClientV2
import com.kickstarter.models.Project
import io.reactivex.Observable
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test

@OptIn(ExperimentalCoroutinesApi::class)
class PledgedProjectsOverviewViewModelTest : KSRobolectricTestCase() {

private lateinit var viewModel: PledgedProjectsOverviewViewModel
Expand All @@ -27,7 +29,7 @@ class PledgedProjectsOverviewViewModelTest : KSRobolectricTestCase() {
}

@Test
fun `emits_project_when_message_creator_called`() =
fun `emits project when message creator called`() =
runTest {
val projectState = mutableListOf<Project>()

Expand All @@ -53,7 +55,7 @@ class PledgedProjectsOverviewViewModelTest : KSRobolectricTestCase() {
}

@Test
fun `emits_error_when_message_creator_called`() =
fun `emits error when message creator called`() =
runTest {
var snackbarAction = 0
viewModel = PledgedProjectsOverviewViewModel.Factory(
Expand All @@ -76,7 +78,7 @@ class PledgedProjectsOverviewViewModelTest : KSRobolectricTestCase() {
}

@Test
fun `emits_snackbar_when_confirms_address`() =
fun `emits snackbar when confirms address`() =
runTest {
var snackbarAction = 0
viewModel.provideSnackbarMessage { snackbarAction = it }
Expand All @@ -90,7 +92,7 @@ class PledgedProjectsOverviewViewModelTest : KSRobolectricTestCase() {
}

@Test
fun `emits_error_state_when_errored`() =
fun `emits error state when errored`() =
runTest {
val mockApolloClientV2 = object : MockApolloClientV2() {

Expand Down Expand Up @@ -121,7 +123,7 @@ class PledgedProjectsOverviewViewModelTest : KSRobolectricTestCase() {
}

@Test
fun `emits_empty_state_when_no_pledges`() =
fun `emits empty state when no pledges`() =
runTest {
val mockApolloClientV2 = object : MockApolloClientV2() {

Expand Down Expand Up @@ -152,7 +154,7 @@ class PledgedProjectsOverviewViewModelTest : KSRobolectricTestCase() {
}

@Test
fun `emits_loading_then_success_state_when_successful`() =
fun `emits loading then success state when successful`() =
runTest {
val mockApolloClientV2 = object : MockApolloClientV2() {

Expand Down

0 comments on commit d0fbc87

Please sign in to comment.