Skip to content

Commit 1a87ecc

Browse files
committed
Revert "refactor: update ModalFragment to use newInstance factory method for clientId handling"
This reverts commit a559b55.
1 parent a559b55 commit 1a87ecc

File tree

7 files changed

+11
-181
lines changed

7 files changed

+11
-181
lines changed

library/src/androidTest/java/com/paypal/messages/ModalExternalLinkTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class ModalExternalLinkTest {
3737
val webView = WebView(recordingContext)
3838

3939
// Initialize the modal WebView configuration
40-
val fragment = ModalFragment.newInstance("test-client-id")
40+
val fragment = ModalFragment(clientId = "test-client-id")
4141
fragment.setupWebView(webView)
4242

4343
// Load a minimal page that triggers a target=_blank navigation
Lines changed: 3 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -1,159 +1,13 @@
1-
package com.paypal.messages
1+
package com.paypal.messages.totest
22

3-
import android.os.Bundle
4-
import androidx.fragment.app.testing.launchFragmentInContainer
53
import androidx.test.ext.junit.runners.AndroidJUnit4
6-
import org.junit.Assert.assertEquals
7-
import org.junit.Assert.assertNotNull
84
import org.junit.Test
95
import org.junit.runner.RunWith
106

117
@RunWith(AndroidJUnit4::class)
128
class ModalFragmentTest {
13-
14-
@Test
15-
fun newInstance_setsClientIdInArguments() {
16-
val testClientId = "test-client-id-123"
17-
val fragment = ModalFragment.newInstance(testClientId)
18-
19-
assertNotNull("Fragment should not be null", fragment)
20-
assertNotNull("Arguments should not be null", fragment.arguments)
21-
assertEquals(
22-
"ClientId should be stored in arguments",
23-
testClientId,
24-
fragment.arguments?.getString("clientId"),
25-
)
26-
}
27-
28-
@Test
29-
fun fragmentRestoration_preservesClientId() {
30-
val testClientId = "test-client-id-restoration"
31-
32-
// Create fragment using factory method
33-
val originalFragment = ModalFragment.newInstance(testClientId)
34-
35-
// Get the arguments that would be saved (Android automatically saves/restores arguments)
36-
val savedArguments = originalFragment.arguments
37-
38-
// Create a new fragment instance (simulating Android's recreation when "Don't keep activities" is enabled)
39-
// This uses the no-arg constructor, which is required for proper state restoration
40-
val recreatedFragment = ModalFragment()
41-
42-
// Restore the arguments (Android does this automatically during recreation)
43-
recreatedFragment.arguments = savedArguments
44-
45-
// Verify clientId can be accessed (this would fail with the old constructor approach)
46-
// We can't directly access private clientId, but we can verify arguments are set
47-
assertNotNull("Recreated fragment arguments should not be null", recreatedFragment.arguments)
48-
assertEquals(
49-
"ClientId should be preserved in recreated fragment",
50-
testClientId,
51-
recreatedFragment.arguments?.getString("clientId"),
52-
)
53-
}
54-
55-
@Test
56-
fun fragmentRecreation_withActivityScenario() {
57-
val testClientId = "test-client-id-scenario"
58-
59-
// Launch fragment in a container using FragmentScenario
60-
val scenario = launchFragmentInContainer<ModalFragment>(
61-
Bundle().apply {
62-
putString("clientId", testClientId)
63-
},
64-
)
65-
66-
// Verify fragment is created
67-
scenario.onFragment { fragment ->
68-
assertNotNull("Fragment should be created", fragment)
69-
assertNotNull("Fragment arguments should be set", fragment.arguments)
70-
assertEquals(
71-
"ClientId should be accessible",
72-
testClientId,
73-
fragment.arguments?.getString("clientId"),
74-
)
75-
}
76-
77-
// Simulate activity recreation (like "Don't keep activities")
78-
scenario.recreate()
79-
80-
// Verify fragment is recreated with same arguments
81-
scenario.onFragment { recreatedFragment ->
82-
assertNotNull("Recreated fragment should not be null", recreatedFragment)
83-
assertNotNull("Recreated fragment arguments should not be null", recreatedFragment.arguments)
84-
assertEquals(
85-
"ClientId should be preserved after recreation",
86-
testClientId,
87-
recreatedFragment.arguments?.getString("clientId"),
88-
)
89-
}
90-
}
91-
92-
@Test
93-
fun fragmentWithoutArguments_throwsException() {
94-
// Create fragment without using newInstance (simulating old way or error case)
95-
val fragment = ModalFragment()
96-
fragment.arguments = null // No arguments set
97-
98-
// Accessing clientId property should throw IllegalStateException
99-
// We test this indirectly by verifying the fragment can't work without arguments
100-
// Since clientId is private, we test via reflection or by ensuring arguments are required
101-
assertNotNull("Fragment should be created", fragment)
102-
// The actual exception would be thrown when clientId is accessed internally
103-
// This test documents the expected behavior
104-
}
105-
106-
@Test
107-
fun newInstance_differentClientIds() {
108-
val clientId1 = "client-id-1"
109-
val clientId2 = "client-id-2"
110-
111-
val fragment1 = ModalFragment.newInstance(clientId1)
112-
val fragment2 = ModalFragment.newInstance(clientId2)
113-
114-
assertEquals(
115-
"First fragment should have first clientId",
116-
clientId1,
117-
fragment1.arguments?.getString("clientId"),
118-
)
119-
assertEquals(
120-
"Second fragment should have second clientId",
121-
clientId2,
122-
fragment2.arguments?.getString("clientId"),
123-
)
124-
}
125-
1269
@Test
127-
fun fragmentStateRestoration_simulatesDontKeepActivities() {
128-
val testClientId = "test-client-dont-keep-activities"
129-
130-
// Step 1: Create fragment using factory method (normal flow)
131-
val fragment = ModalFragment.newInstance(testClientId)
132-
133-
// Step 2: Simulate what happens when "Don't keep activities" is enabled:
134-
// - Activity is destroyed
135-
// - Fragment arguments are automatically saved by Android
136-
// - Fragment instance is destroyed
137-
val savedArguments = Bundle().apply {
138-
putAll(fragment.arguments ?: Bundle())
139-
}
140-
141-
// Step 3: Simulate Android recreating the fragment (uses no-arg constructor)
142-
// This is the key fix: the fragment must have a no-arg constructor
143-
val recreatedFragment = ModalFragment()
144-
145-
// Step 4: Android restores the arguments Bundle automatically
146-
recreatedFragment.arguments = savedArguments
147-
148-
// Step 5: Verify the fragment can function properly
149-
// The key test: can we access clientId without constructor?
150-
assertEquals(
151-
"Recreated fragment should have same clientId",
152-
testClientId,
153-
recreatedFragment.arguments?.getString("clientId"),
154-
)
155-
156-
// This test verifies the fix: fragment can be recreated using no-arg constructor
157-
// and clientId is accessible via arguments Bundle
10+
fun testSomething() {
11+
//
15812
}
15913
}

library/src/androidTest/java/com/paypal/messages/PayPalMessageViewTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ class PayPalMessageViewTest {
113113
// fun dismissAfterFragmentDetached_shouldThrow() {
114114
// val scenario: ActivityScenario<TestActivity> = ActivityScenario.launch(TestActivity::class.java)
115115
// scenario.onActivity { activity: TestActivity ->
116-
// val fragment = ModalFragment.newInstance("test_client_id")
116+
// val fragment = ModalFragment("test_client_id")
117117
// fragment.show(activity.supportFragmentManager, "test")
118118
//
119119
// // Remove the fragment to simulate detachment

library/src/main/java/com/paypal/messages/ModalFragment.kt

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -50,35 +50,13 @@ import java.util.UUID
5050
import kotlin.system.measureTimeMillis
5151
import com.paypal.messages.config.PayPalMessageOfferType as OfferType
5252

53-
internal class ModalFragment : BottomSheetDialogFragment() {
54-
companion object {
55-
private const val ARG_CLIENT_ID = "clientId"
56-
57-
/**
58-
* Factory method to create a new instance of ModalFragment with clientId.
59-
* This pattern is required for proper fragment state restoration when
60-
* "Don't keep activities" is enabled.
61-
*/
62-
fun newInstance(clientId: String): ModalFragment {
63-
return ModalFragment().apply {
64-
arguments = Bundle().apply {
65-
putString(ARG_CLIENT_ID, clientId)
66-
}
67-
}
68-
}
69-
}
70-
53+
internal class ModalFragment(
54+
private val clientId: String,
55+
) : BottomSheetDialogFragment() {
7156
private val TAG = "PayPalMessageModal"
7257
private val offsetTop = 50.dp
7358
private val gson = GsonBuilder().setPrettyPrinting().create()
7459

75-
/**
76-
* Gets the clientId from arguments Bundle.
77-
* This ensures proper state restoration when Android recreates the fragment.
78-
*/
79-
private val clientId: String
80-
get() = arguments?.getString(ARG_CLIENT_ID) ?: throw IllegalStateException("clientId must be set via newInstance()")
81-
8260
private var modalUrl: String? = null
8361

8462
// MODAL CONFIG VALUES

library/src/main/java/com/paypal/messages/PayPalComposableModal.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,7 @@ fun PayPalComposableModal(
5959
var errorMessage by remember { mutableStateOf("") }
6060

6161
// Create the ModalFragment instance for WebView setup
62-
// Use clientId as key to ensure fragment is recreated if clientId changes
63-
// This also ensures proper recreation when "Don't keep activities" is enabled
64-
val modalFragment = remember(clientId) { ModalFragment.newInstance(clientId) }
62+
val modalFragment = remember { ModalFragment(clientId) }
6563
val offerEnum = offerType?.let {
6664
try {
6765
PayPalMessageOfferType.valueOf(it)

library/src/main/java/com/paypal/messages/PayPalModalActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ class PayPalModalActivity : ComponentActivity() {
368368
}
369369

370370
// Create and setup the modal fragment
371-
val modalFragment = ModalFragment.newInstance(clientId)
371+
val modalFragment = ModalFragment(clientId)
372372
val offerEnum = offerType?.let {
373373
try {
374374
com.paypal.messages.config.PayPalMessageOfferType.valueOf(it)

library/src/main/java/com/paypal/messages/data/PayPalMessageDataProvider.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ class PayPalMessageDataProvider {
311311
// For AppCompatActivity contexts, use ModalFragment
312312
appCompatContext != null -> {
313313
val modal = modalInstances[instanceId] ?: run {
314-
val newModal = ModalFragment.newInstance(config.data.clientID)
314+
val newModal = ModalFragment(config.data.clientID)
315315

316316
// Build modal config
317317
val modalConfig = ModalConfig(

0 commit comments

Comments
 (0)