Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PIMOB: 2109: Allow injection of cardholder name field in paymentformConfig #221

Conversation

chintan-soni-cko
Copy link
Contributor

@chintan-soni-cko chintan-soni-cko commented Aug 16, 2023

Issue

PIMOB-2109

Proposed changes

1 Add cardHolderName in PaymentFormConfig
2 Load the cardholdername field in the Payment form from PaymentFormConfig
3. Refactored existing unit test for paymentformstatemanager field

Test Steps

  1. add cardHolderName in PaymentFormConfig
  2. Verify the paymentform details' cardholder name is updated
    Screen_recording_20230816_114904.webm

Checklist

Put an x in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.

  • Reviewers assigned
  • I have performed a self-review of my code and manual testing
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if applicable)

Further comments

If this is a relatively large or complex change, kick off the discussion by explaining why you choose the solution you did and what alternatives you considered, etc...

@chintan-soni-cko chintan-soni-cko force-pushed the feature/PIMOB-2109_allow_injection_cardholdername_in_paymentformconfig branch from e8ed52b to b94c80d Compare August 16, 2023 11:21
Copy link
Contributor

@jheng-hao-lin-cko jheng-hao-lin-cko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing good to have is that now we know some files have no test at all, we could start adding them, such as PaymentFormViewModel, PaymentFormScreen, PaymentFormConfig, etc.

We can just do a bare minimum test against the values we added when there's no existing tests file.

For instance,

  • for PaymentFormViewModel test we can cover the injector provides the correct card holder name, and cardholder name default value is an empty string.
  • for PaymentFormScreen test we can cover the same for the viewModel.

It will be a long way to go at the beginning as we lack quite some tests, but over the time it will get things easier. Of course if there's difficult writing tests or tight deadline we can drop it

@chintan-soni-cko
Copy link
Contributor Author

One thing good to have is that now we know some files have no test at all, we could start adding them, such as PaymentFormViewModel, PaymentFormScreen, PaymentFormConfig, etc.

We can just do a bare minimum test against the values we added when there's no existing tests file.

For instance,

  • for PaymentFormViewModel test we can cover the injector provides the correct card holder name, and cardholder name default value is an empty string.
  • for PaymentFormScreen test we can cover the same for the viewModel.

It will be a long way to go at the beginning as we lack quite some tests, but over the time it will get things easier. Of course if there's difficult writing tests or tight deadline we can drop it

@jheng-hao-lin-cko Thanks for the suggestion. I have tried to add test cases for new classes which are apparently not easy to testable due to their design and capabilities of injection in constructors.

Copy link
Contributor

@jheng-hao-lin-cko jheng-hao-lin-cko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just experiment writing a test against PaymentFormScreen which works fine checking whether the screen has a field contains the prefilled data, thou it might not be taken by the test coverage analysis because of the setup.

will leave the test code here, up to you whether we like to include it in this PR.

package com.checkout.frames.screen.paymentform

import android.content.Context
import androidx.compose.material3.MaterialTheme
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import com.checkout.base.model.CardScheme
import com.checkout.base.model.Country
import com.checkout.base.model.Environment
import com.checkout.frames.api.PaymentFlowHandler
import com.checkout.frames.screen.paymentform.model.BillingFormAddress
import com.checkout.frames.screen.paymentform.model.PaymentFormConfig
import com.checkout.frames.screen.paymentform.model.PrefillData
import com.checkout.frames.style.screen.PaymentFormStyle
import com.checkout.tokenization.model.Address
import com.checkout.tokenization.model.Phone
import com.checkout.tokenization.model.TokenDetails
import io.mockk.junit5.MockKExtension
import io.mockk.mockk
import org.junit.Rule
import org.junit.Test
import org.junit.jupiter.api.extension.ExtendWith

@ExtendWith(MockKExtension::class)
internal class PaymentFormScreenTest {
    @get:Rule
    val composeTestRule = createComposeRule()

    private val expectedMockContext: Context = mockk(relaxed = true)

    private val paymentFormConfig = PaymentFormConfig(
        context = expectedMockContext,
        environment = Environment.PRODUCTION,
        publicKey = "Test key",
        style = PaymentFormStyle(),
        supportedCardSchemeList = listOf(CardScheme.VISA, CardScheme.MAESTRO),
        paymentFlowHandler = object : PaymentFlowHandler {
            override fun onSubmit() {}
            override fun onSuccess(tokenDetails: TokenDetails) {}
            override fun onFailure(errorMessage: String) {}
            override fun onBackPressed() {}
        },
        prefillData = PrefillData(
            cardHolderName = "Test Name",
            billingFormAddress = BillingFormAddress(
                name = "Test Billing Address name",
                address = Address(
                    addressLine1 = "Checkout.com",
                    addressLine2 = "90 Tottenham Court Road",
                    city = "London",
                    state = "London",
                    zip = "W1T 4TJ",
                    country = Country.from(iso3166Alpha2 = "GB")
                ),
                phone = Phone(
                    number = "4155552671", country = Country.from(iso3166Alpha2 = "GB")
                )
            )
        )
    )

    @Test
    fun paymentFormScreenShouldBeCreatedWithTheCorrectTestNameFilled() {
        composeTestRule.setContent {
            MaterialTheme { PaymentFormScreen(paymentFormConfig) }
        }

        composeTestRule.onNodeWithText("Test Name").assertIsDisplayed()
    }
}

) : ViewModelProvider.Factory, InjectionClient {

@Inject
lateinit var viewModel: PaymentFormViewModel

private lateinit var injector: Injector
@VisibleForTesting
lateinit var injector: Injector
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make it internal just for exposing to tests?

@chintan-soni-cko
Copy link
Contributor Author

Just experiment writing a test against PaymentFormScreen which works fine checking whether the screen has a field contains the prefilled data, thou it might not be taken by the test coverage analysis because of the setup.

will leave the test code here, up to you whether we like to include it in this PR.

package com.checkout.frames.screen.paymentform

import android.content.Context
import androidx.compose.material3.MaterialTheme
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import com.checkout.base.model.CardScheme
import com.checkout.base.model.Country
import com.checkout.base.model.Environment
import com.checkout.frames.api.PaymentFlowHandler
import com.checkout.frames.screen.paymentform.model.BillingFormAddress
import com.checkout.frames.screen.paymentform.model.PaymentFormConfig
import com.checkout.frames.screen.paymentform.model.PrefillData
import com.checkout.frames.style.screen.PaymentFormStyle
import com.checkout.tokenization.model.Address
import com.checkout.tokenization.model.Phone
import com.checkout.tokenization.model.TokenDetails
import io.mockk.junit5.MockKExtension
import io.mockk.mockk
import org.junit.Rule
import org.junit.Test
import org.junit.jupiter.api.extension.ExtendWith

@ExtendWith(MockKExtension::class)
internal class PaymentFormScreenTest {
    @get:Rule
    val composeTestRule = createComposeRule()

    private val expectedMockContext: Context = mockk(relaxed = true)

    private val paymentFormConfig = PaymentFormConfig(
        context = expectedMockContext,
        environment = Environment.PRODUCTION,
        publicKey = "Test key",
        style = PaymentFormStyle(),
        supportedCardSchemeList = listOf(CardScheme.VISA, CardScheme.MAESTRO),
        paymentFlowHandler = object : PaymentFlowHandler {
            override fun onSubmit() {}
            override fun onSuccess(tokenDetails: TokenDetails) {}
            override fun onFailure(errorMessage: String) {}
            override fun onBackPressed() {}
        },
        prefillData = PrefillData(
            cardHolderName = "Test Name",
            billingFormAddress = BillingFormAddress(
                name = "Test Billing Address name",
                address = Address(
                    addressLine1 = "Checkout.com",
                    addressLine2 = "90 Tottenham Court Road",
                    city = "London",
                    state = "London",
                    zip = "W1T 4TJ",
                    country = Country.from(iso3166Alpha2 = "GB")
                ),
                phone = Phone(
                    number = "4155552671", country = Country.from(iso3166Alpha2 = "GB")
                )
            )
        )
    )

    @Test
    fun paymentFormScreenShouldBeCreatedWithTheCorrectTestNameFilled() {
        composeTestRule.setContent {
            MaterialTheme { PaymentFormScreen(paymentFormConfig) }
        }

        composeTestRule.onNodeWithText("Test Name").assertIsDisplayed()
    }
}

Thanks, @jheng-hao-lin-cko will include in the next PR. So, it will include for billing form address as well.

@chintan-soni-cko chintan-soni-cko merged commit 4d9154e into master Aug 17, 2023
@chintan-soni-cko chintan-soni-cko deleted the feature/PIMOB-2109_allow_injection_cardholdername_in_paymentformconfig branch August 17, 2023 10:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants