@@ -190,13 +190,94 @@ class DefaultPaymentMethodFilterTest {
190190 assertThat(observedElements).containsExactlyElementsIn(expectedElements).inOrder()
191191 }
192192
193+ private fun usCard (id : String , state : String? ): PaymentMethod = PaymentMethodFactory .card(id = id).update(
194+ last4 = " 1000" ,
195+ addCbcNetworks = false ,
196+ brand = CardBrand .Visa ,
197+ ).copy(
198+ billingDetails = PaymentMethod .BillingDetails (
199+ address = Address (
200+ line1 = " 123 Main St" ,
201+ city = " San Francisco" ,
202+ state = state,
203+ postalCode = " 94111" ,
204+ country = " US" ,
205+ ),
206+ ),
207+ )
208+
209+ @Test
210+ fun `Drops SPM lacking automatic-tax-required fields when automatic tax requires a billing address` () = runTest {
211+ val complete = usCard(id = " pm_complete" , state = " CA" )
212+ val incomplete = usCard(id = " pm_incomplete" , state = null )
213+
214+ val observed = filter(
215+ paymentMethods = listOf (complete, incomplete),
216+ requiresBillingAddressForAutomaticTax = true ,
217+ )
218+
219+ assertThat(observed).containsExactly(complete)
220+ }
221+
222+ @Test
223+ fun `Does not filter by automatic-tax fields when automatic tax does not require a billing address` () = runTest {
224+ val complete = usCard(id = " pm_complete" , state = " CA" )
225+ val incomplete = usCard(id = " pm_incomplete" , state = null )
226+
227+ val observed = filter(
228+ paymentMethods = listOf (complete, incomplete),
229+ requiresBillingAddressForAutomaticTax = false ,
230+ )
231+
232+ assertThat(observed).containsExactly(complete, incomplete)
233+ }
234+
235+ @Test
236+ fun `Keeps a country-only-sufficient SPM when automatic tax requires a billing address` () = runTest {
237+ // FR has no additional automatic-tax fields, so country alone is sufficient. Proves the
238+ // clause does not over-drop valid cards.
239+ val frCard = PaymentMethodFactory .card(id = " pm_fr" ).update(
240+ last4 = " 1000" ,
241+ addCbcNetworks = false ,
242+ brand = CardBrand .Visa ,
243+ ).copy(
244+ billingDetails = PaymentMethod .BillingDetails (
245+ address = Address (country = " FR" ),
246+ ),
247+ )
248+
249+ val observed = filter(
250+ paymentMethods = listOf (frCard),
251+ requiresBillingAddressForAutomaticTax = true ,
252+ )
253+
254+ assertThat(observed).containsExactly(frCard)
255+ }
256+
257+ @Test
258+ fun `Drops SPM with null billing address when automatic tax requires a billing address` () = runTest {
259+ val noAddress = PaymentMethodFactory .card(id = " pm_no_addr" ).update(
260+ last4 = " 1000" ,
261+ addCbcNetworks = false ,
262+ brand = CardBrand .Visa ,
263+ ).copy(billingDetails = PaymentMethod .BillingDetails (address = null ))
264+
265+ val observed = filter(
266+ paymentMethods = listOf (noAddress),
267+ requiresBillingAddressForAutomaticTax = true ,
268+ )
269+
270+ assertThat(observed).isEmpty()
271+ }
272+
193273 private suspend fun filter (
194274 paymentMethods : List <PaymentMethod >,
195275 billingDetailsCollectionConfiguration : PaymentSheet .BillingDetailsCollectionConfiguration =
196276 PaymentSheet .BillingDetailsCollectionConfiguration (),
197277 isPaymentMethodSetAsDefaultEnabled : Boolean = false,
198278 remoteDefaultPaymentMethodId : String? = null,
199279 localSavedSelection : SavedSelection = SavedSelection .None ,
280+ requiresBillingAddressForAutomaticTax : Boolean = false,
200281 cardBrandFilter : PaymentSheetCardBrandFilter = PaymentSheetCardBrandFilter (
201282 cardBrandAcceptance = PaymentSheet .CardBrandAcceptance .all(),
202283 ),
@@ -222,6 +303,7 @@ class DefaultPaymentMethodFilterTest {
222303 localSavedSelection = CompletableDeferred (localSavedSelection),
223304 cardBrandFilter = cardBrandFilter,
224305 cardFundingFilter = cardFundingFilter,
306+ requiresBillingAddressForAutomaticTax = requiresBillingAddressForAutomaticTax,
225307 )
226308 )
227309 }
0 commit comments