From 6a3cbd6cef923edb6ccaeb0879efb3a3edc675a1 Mon Sep 17 00:00:00 2001 From: Michael Shafrir Date: Mon, 6 Jan 2020 13:05:29 -0500 Subject: [PATCH] Update SourceParams fields - Update `setOwner()` to take `OwnerParams` instead of `Map` - Remove `setRedirect()`, use `setReturnUrl()` instead - Update some setters to take null values, simplifying usage - Update comments --- .../com/stripe/android/model/SourceParams.kt | 401 +++++++++--------- .../java/com/stripe/android/StripeTest.java | 3 +- .../stripe/android/model/SourceParamsTest.kt | 238 +++++------ 3 files changed, 310 insertions(+), 332 deletions(-) diff --git a/stripe/src/main/java/com/stripe/android/model/SourceParams.kt b/stripe/src/main/java/com/stripe/android/model/SourceParams.kt index a926e9c68bc..0acd88e6703 100644 --- a/stripe/src/main/java/com/stripe/android/model/SourceParams.kt +++ b/stripe/src/main/java/com/stripe/android/model/SourceParams.kt @@ -15,20 +15,24 @@ import org.json.JSONObject */ class SourceParams private constructor( /** - * @return a custom type of this source, if one has been set + * @return a custom type of this Source, if one has been set */ @SourceType val typeRaw: String ) : StripeParamsModel { /** - * @return the [Type][SourceType] of this source + * @return The type of the source to create. */ @get:SourceType @SourceType val type: String = asSourceType(typeRaw) /** - * @return the amount of the transaction + * @return Amount associated with the source. This is the amount for which the source will + * be chargeable once ready. Required for `single_use` sources. Not supported for `receiver` + * type sources, where charge amount may not be specified until funds land. + * + * See [amount](https://stripe.com/docs/api/sources/create#create_source-amount) */ @IntRange(from = 0) var amount: Long? = null @@ -41,35 +45,50 @@ class SourceParams private constructor( private set /** - * @return the currency code for the transaction + * @return Three-letter ISO code for the currency associated with the source. + * This is the currency for which the source will be chargeable once ready. + * + * See [currency](https://stripe.com/docs/api/sources/create#create_source-currency) */ var currency: String? = null private set /** - * @return details about the source owner (map contents are specific to source type) + * The URL you provide to redirect the customer back to you after they authenticated their + * payment. It can use your application URI scheme in the context of a mobile application. */ - var owner: Map? = null + var returnUrl: String? = null private set /** - * @return the custom metadata set on these params + * Information about the owner of the payment instrument that may be used or required by + * particular source types. */ - var metaData: Map? = null + var owner: OwnerParams? = null private set /** - * @return redirect map for the source + * @return the custom metadata set on these params */ - var redirect: Map? = null + var metaData: Map? = null private set private var extraParams: Map = emptyMap() + /** + * @return An optional token used to create the source. When passed, token properties will + * override source parameters. + * + * See [token](https://stripe.com/docs/api/sources/create#create_source-token) + */ private var token: String? = null /** - * @return the current usage of this source, if one has been set + * @return Either `reusable` or `single_use`. Whether this source should be reusable or not. + * Some source types may or may not be reusable by construction, while others may leave the + * option at creation. If an incompatible value is passed, an error will be returned. + * + * See [usage](https://stripe.com/docs/api/sources/create#create_source-usage) */ @get:Source.Usage @Source.Usage @@ -80,109 +99,92 @@ class SourceParams private constructor( /*---- Setters ----*/ /** - * @param amount currency amount for this source, in the lowest denomination. - * @return `this`, for chaining purposes + * @param amount Amount associated with the source. This is the amount for which the source will + * be chargeable once ready. Required for `single_use` sources. Not supported for `receiver` + * type sources, where charge amount may not be specified until funds land. + * + * See [amount](https://stripe.com/docs/api/sources/create#create_source-amount) */ - fun setAmount(@IntRange(from = 0) amount: Long?): SourceParams { + fun setAmount(@IntRange(from = 0) amount: Long?): SourceParams = apply { this.amount = amount - return this } /** * @param apiParameterMap a map of parameters specific for this type of source - * @return `this`, for chaining purposes */ - fun setApiParameterMap( - apiParameterMap: Map - ): SourceParams { + fun setApiParameterMap(apiParameterMap: Map?): SourceParams = apply { this.apiParameterMap = apiParameterMap - return this } /** - * @param currency currency code for this source (i.e. "EUR") - * @return `this`, for chaining purposes + * @param currency Three-letter ISO code for the currency associated with the source. + * This is the currency for which the source will be chargeable once ready. + * + * See [currency](https://stripe.com/docs/api/sources/create#create_source-currency) */ - fun setCurrency(currency: String): SourceParams { + fun setCurrency(currency: String): SourceParams = apply { this.currency = currency - return this - } - - /** - * @param owner an [SourceOwner] object for this source - * @return `this`, for chaining purposes - */ - fun setOwner(owner: Map): SourceParams { - this.owner = owner.takeIf { it.isNotEmpty() } - return this } /** - * Sets a redirect property map for this source object. If you only want to - * set a return url, use [setReturnUrl]. + * @param owner Information about the owner of the payment instrument that may be used or + * required by particular source types. * - * @param redirect a set of redirect parameters - * @return `this`, for chaining purposes + * See [owner](https://stripe.com/docs/api/sources/create#create_source-owner) */ - fun setRedirect(redirect: Map): SourceParams { - this.redirect = redirect - return this + fun setOwner(owner: OwnerParams?): SourceParams = apply { + this.owner = owner } /** * Sets extra params for this source object. * * @param extraParams a set of params - * @return `this`, for chaining purposes */ - fun setExtraParams(extraParams: Map): SourceParams { + fun setExtraParams(extraParams: Map): SourceParams = apply { this.extraParams = extraParams - return this } /** - * @param returnUrl a redirect URL for this source. - * @return `this`, for chaining purposes + * @param returnUrl The URL you provide to redirect the customer back to you after they + * authenticated their payment. It can use your application URI scheme in the context of a + * mobile application. + * + * See [redirect.return_url](https://stripe.com/docs/api/sources/create#create_source-redirect-return_url) */ - fun setReturnUrl(@Size(min = 1) returnUrl: String): SourceParams { - this.redirect = redirect.orEmpty().plus( - mapOf(PARAM_RETURN_URL to returnUrl) - ) - return this + fun setReturnUrl(@Size(min = 1) returnUrl: String): SourceParams = apply { + this.returnUrl = returnUrl } /** - * Set custom metadata on the parameters. + * @param metaData A set of key-value pairs that you can attach to a source object. It can be + * useful for storing additional information about the source in a structured format. * - * @return `this`, for chaining purposes + * See [metadata](https://stripe.com/docs/api/sources/create#create_source-metadata) */ - fun setMetaData(metaData: Map): SourceParams { + fun setMetaData(metaData: Map?): SourceParams = apply { this.metaData = metaData - return this } /** - * Sets a token ID on the parameters. + * @param token An optional token used to create the source. When passed, token properties will + * override source parameters. * - * @param token a token ID - * @return `this`, for chaining purposes + * See [token](https://stripe.com/docs/api/sources/create#create_source-token) */ - fun setToken(token: String): SourceParams { + fun setToken(token: String): SourceParams = apply { this.token = token - return this } /** - * Sets a usage value on the parameters. Used for Alipay, and should be - * either "single_use" or "reusable". Not setting this value defaults - * to "single_use". + * @param usage Either `reusable` or `single_use`. Whether this source should be reusable or not. + * Some source types may or may not be reusable by construction, while others may leave the + * option at creation. If an incompatible value is passed, an error will be returned. * - * @param usage either "single_use" or "reusable" - * @return `this` for chaining purposes + * See [usage](https://stripe.com/docs/api/sources/create#create_source-usage) */ - fun setUsage(@Source.Usage usage: String): SourceParams { + fun setUsage(@Source.Usage usage: String): SourceParams = apply { this.usage = usage - return this } private fun setWeChatParams(weChatParams: WeChatParams): SourceParams { @@ -191,10 +193,7 @@ class SourceParams private constructor( } /** - * Create a string-keyed map representing this object that is - * ready to be sent over the network. - * - * @return a String-keyed map + * Create a string-keyed map representing this object that is ready to be sent over the network. */ override fun toParamMap(): Map { return mapOf(PARAM_TYPE to typeRaw) @@ -214,13 +213,13 @@ class SourceParams private constructor( }.orEmpty() ) .plus( - owner.takeUnless { it.isNullOrEmpty() }?.let { - mapOf(PARAM_OWNER to it) + owner?.let { + mapOf(PARAM_OWNER to it.toParamMap()) }.orEmpty() ) .plus( - redirect?.let { - mapOf(PARAM_REDIRECT to it) + returnUrl?.let { + mapOf(PARAM_REDIRECT to mapOf(PARAM_RETURN_URL to it)) }.orEmpty() ) .plus( @@ -248,8 +247,8 @@ class SourceParams private constructor( @Parcelize internal data class WeChatParams( - private val appId: String?, - private val statementDescriptor: String? + private val appId: String? = null, + private val statementDescriptor: String? = null ) : StripeParamsModel, Parcelable { override fun toParamMap(): Map { return emptyMap() @@ -273,7 +272,7 @@ class SourceParams private constructor( override fun hashCode(): Int { return Objects.hash(amount, apiParameterMap, currency, typeRaw, owner, metaData, - redirect, extraParams, token, usage, type, weChatParams) + returnUrl, extraParams, token, usage, type, weChatParams) } override fun equals(other: Any?): Boolean { @@ -291,7 +290,7 @@ class SourceParams private constructor( Objects.equals(typeRaw, params.typeRaw) && Objects.equals(owner, params.owner) && Objects.equals(metaData, params.metaData) && - Objects.equals(redirect, params.redirect) && + Objects.equals(returnUrl, params.returnUrl) && Objects.equals(extraParams, params.extraParams) && Objects.equals(token, params.token) && Objects.equals(usage, params.usage) && @@ -300,15 +299,18 @@ class SourceParams private constructor( } /** - * [Owner param](https://stripe.com/docs/api/sources/create#create_source-owner) + * [owner](https://stripe.com/docs/api/sources/create#create_source-owner) param + * + * Information about the owner of the payment instrument that may be used or required by + * particular source types. */ - private data class Owner internal constructor( - private val address: Address? = null, - private val email: String? = null, - private val name: String? = null, - private val phone: String? = null - ) : StripeParamsModel { - + @Parcelize + data class OwnerParams internal constructor( + internal val address: Address? = null, + internal val email: String? = null, + internal val name: String? = null, + internal val phone: String? = null + ) : StripeParamsModel, Parcelable { override fun toParamMap(): Map { return emptyMap() .plus( @@ -399,11 +401,13 @@ class SourceParams private constructor( return SourceParams(SourceType.P24) .setAmount(amount) .setCurrency(currency) - .setRedirect(mapOf(PARAM_RETURN_URL to returnUrl)) - .setOwner(Owner( - email = email, - name = name - ).toParamMap()) + .setReturnUrl(returnUrl) + .setOwner( + OwnerParams( + email = email, + name = name + ) + ) } /** @@ -423,19 +427,20 @@ class SourceParams private constructor( @JvmStatic fun createAlipayReusableParams( currency: String, - name: String?, - email: String?, + name: String? = null, + email: String? = null, returnUrl: String ): SourceParams { - val ownerMap = Owner( - email = email, - name = name - ).toParamMap() return SourceParams(SourceType.ALIPAY) .setCurrency(currency) - .setRedirect(mapOf(PARAM_RETURN_URL to returnUrl)) + .setReturnUrl(returnUrl) .setUsage(Source.Usage.REUSABLE) - .setOwner(ownerMap) + .setOwner( + OwnerParams( + email = email, + name = name + ) + ) } /** @@ -458,19 +463,20 @@ class SourceParams private constructor( fun createAlipaySingleUseParams( @IntRange(from = 0) amount: Long, currency: String, - name: String?, - email: String?, + name: String? = null, + email: String? = null, returnUrl: String ): SourceParams { - val ownerMap = Owner( - email = email, - name = name - ).toParamMap() return SourceParams(SourceType.ALIPAY) .setCurrency(currency) .setAmount(amount) - .setRedirect(mapOf(PARAM_RETURN_URL to returnUrl)) - .setOwner(ownerMap) + .setReturnUrl(returnUrl) + .setOwner( + OwnerParams( + email = email, + name = name + ) + ) } /** @@ -492,7 +498,7 @@ class SourceParams private constructor( @IntRange(from = 0) amount: Long, currency: String, weChatAppId: String, - statementDescriptor: String? + statementDescriptor: String? = null ): SourceParams { return SourceParams(SourceType.WECHAT) .setCurrency(currency) @@ -542,11 +548,13 @@ class SourceParams private constructor( .setAmount(totalAmount.toLong()) .setCurrency(currency) .setReturnUrl(returnUrl) - .setOwner(Owner( - address = klarnaParams.billingAddress, - email = klarnaParams.billingEmail, - phone = klarnaParams.billingPhone - ).toParamMap()) + .setOwner( + OwnerParams( + address = klarnaParams.billingAddress, + email = klarnaParams.billingEmail, + phone = klarnaParams.billingPhone + ) + ) .setExtraParams( mapOf( PARAM_KLARNA to klarnaParams.toParamMap(), @@ -578,16 +586,16 @@ class SourceParams private constructor( @IntRange(from = 0) amount: Long, name: String, returnUrl: String, - statementDescriptor: String?, - preferredLanguage: String? + statementDescriptor: String? = null, + preferredLanguage: String? = null ): SourceParams { - val ownerMap = Owner(name = name) - .toParamMap() val params = SourceParams(SourceType.BANCONTACT) .setCurrency(Source.EURO) .setAmount(amount) - .setOwner(ownerMap) - .setRedirect(mapOf(PARAM_RETURN_URL to returnUrl)) + .setOwner( + OwnerParams(name = name) + ) + .setReturnUrl(returnUrl) val additionalParamsMap = emptyMap() .plus( statementDescriptor?.let { @@ -639,33 +647,29 @@ class SourceParams private constructor( */ @JvmStatic fun createCardParams(card: Card): SourceParams { - val params = SourceParams(SourceType.CARD) - // Not enforcing all fields to exist at this level. - // Instead, the server will return an error for invalid data. - val cardParams = mapOf( - PARAM_NUMBER to card.number, - PARAM_EXP_MONTH to card.expMonth, - PARAM_EXP_YEAR to card.expYear, - PARAM_CVC to card.cvc - ) - params.setApiParameterMap(cardParams) - params.setOwner( - Owner( - address = Address.Builder() - .setLine1(card.addressLine1) - .setLine2(card.addressLine2) - .setCity(card.addressCity) - .setState(card.addressState) - .setPostalCode(card.addressZip) - .setCountry(card.addressCountry) - .build(), - name = card.name - ).toParamMap() - ) - if (card.metadata != null) { - params.setMetaData(card.metadata) - } - return params + return SourceParams(SourceType.CARD) + .setApiParameterMap( + mapOf( + PARAM_NUMBER to card.number, + PARAM_EXP_MONTH to card.expMonth, + PARAM_EXP_YEAR to card.expYear, + PARAM_CVC to card.cvc + ) + ) + .setOwner( + OwnerParams( + address = Address.Builder() + .setLine1(card.addressLine1) + .setLine2(card.addressLine2) + .setCity(card.addressCity) + .setState(card.addressState) + .setPostalCode(card.addressZip) + .setCountry(card.addressCountry) + .build(), + name = card.name + ) + ) + .setMetaData(card.metadata) } /** @@ -678,16 +682,16 @@ class SourceParams private constructor( googlePayPaymentData: JSONObject ): SourceParams { val googlePayResult = GooglePayResult.fromJson(googlePayPaymentData) - val params = SourceParams(SourceType.CARD) + return SourceParams(SourceType.CARD) .setToken(requireNotNull(googlePayResult.token?.id)) - return params.setOwner( - Owner( - address = googlePayResult.address, - email = googlePayResult.email, - name = googlePayResult.name, - phone = googlePayResult.phoneNumber - ).toParamMap() - ) + .setOwner( + OwnerParams( + address = googlePayResult.address, + email = googlePayResult.email, + name = googlePayResult.name, + phone = googlePayResult.phoneNumber + ) + ) } /** @@ -708,21 +712,18 @@ class SourceParams private constructor( @IntRange(from = 0) amount: Long, name: String, returnUrl: String, - statementDescriptor: String? + statementDescriptor: String? = null ): SourceParams { - val ownerMap = Owner(name = name) - .toParamMap() - val params = SourceParams(SourceType.EPS) + return SourceParams(SourceType.EPS) .setCurrency(Source.EURO) .setAmount(amount) - .setOwner(ownerMap) - .setRedirect(mapOf(PARAM_RETURN_URL to returnUrl)) - if (statementDescriptor != null) { - params.setApiParameterMap( - mapOf(PARAM_STATEMENT_DESCRIPTOR to statementDescriptor) + .setOwner(OwnerParams(name = name)) + .setReturnUrl(returnUrl) + .setApiParameterMap( + statementDescriptor?.let { + mapOf(PARAM_STATEMENT_DESCRIPTOR to it) + } ) - } - return params } /** @@ -743,21 +744,18 @@ class SourceParams private constructor( @IntRange(from = 0) amount: Long, name: String, returnUrl: String, - statementDescriptor: String? + statementDescriptor: String? = null ): SourceParams { - val ownerMap = Owner(name = name) - .toParamMap() - val params = SourceParams(SourceType.GIROPAY) + return SourceParams(SourceType.GIROPAY) .setCurrency(Source.EURO) .setAmount(amount) - .setOwner(ownerMap) - .setRedirect(mapOf(PARAM_RETURN_URL to returnUrl)) - if (statementDescriptor != null) { - params.setApiParameterMap( - mapOf(PARAM_STATEMENT_DESCRIPTOR to statementDescriptor) + .setOwner(OwnerParams(name = name)) + .setReturnUrl(returnUrl) + .setApiParameterMap( + statementDescriptor?.let { + mapOf(PARAM_STATEMENT_DESCRIPTOR to it) + } ) - } - return params } /** @@ -779,16 +777,14 @@ class SourceParams private constructor( @IntRange(from = 0) amount: Long, name: String?, returnUrl: String, - statementDescriptor: String?, - bank: String? + statementDescriptor: String? = null, + bank: String? = null ): SourceParams { - val ownerMap = Owner(name = name) - .toParamMap() val params = SourceParams(SourceType.IDEAL) .setCurrency(Source.EURO) .setAmount(amount) - .setRedirect(mapOf(PARAM_RETURN_URL to returnUrl)) - .setOwner(ownerMap) + .setReturnUrl(returnUrl) + .setOwner(OwnerParams(name = name)) val additionalParamsMap = emptyMap() .plus( @@ -826,13 +822,11 @@ class SourceParams private constructor( returnUrl: String, email: String ): SourceParams { - val ownerMap = Owner(email = email) - .toParamMap() return SourceParams(SourceType.MULTIBANCO) .setCurrency(Source.EURO) .setAmount(amount) - .setRedirect(mapOf(PARAM_RETURN_URL to returnUrl)) - .setOwner(ownerMap) + .setReturnUrl(returnUrl) + .setOwner(OwnerParams(email = email)) } /** @@ -884,19 +878,20 @@ class SourceParams private constructor( postalCode: String?, @Size(2) country: String? ): SourceParams { - val ownerMap = Owner( - address = Address.Builder() - .setLine1(addressLine1) - .setCity(city) - .setPostalCode(postalCode) - .setCountry(country) - .build(), - email = email, - name = name - ).toParamMap() return SourceParams(SourceType.SEPA_DEBIT) .setCurrency(Source.EURO) - .setOwner(ownerMap) + .setOwner( + OwnerParams( + address = Address.Builder() + .setLine1(addressLine1) + .setCity(city) + .setPostalCode(postalCode) + .setCountry(country) + .build(), + email = email, + name = name + ) + ) .setApiParameterMap(mapOf(PARAM_IBAN to iban)) } @@ -918,9 +913,9 @@ class SourceParams private constructor( @IntRange(from = 0) amount: Long, returnUrl: String, @Size(2) country: String, - statementDescriptor: String? + statementDescriptor: String? = null ): SourceParams { - val sofortMap = mapOf(PARAM_COUNTRY to country) + val sofortData = mapOf(PARAM_COUNTRY to country) .plus( statementDescriptor?.let { mapOf(PARAM_STATEMENT_DESCRIPTOR to it) @@ -929,8 +924,8 @@ class SourceParams private constructor( return SourceParams(SourceType.SOFORT) .setCurrency(Source.EURO) .setAmount(amount) - .setRedirect(mapOf(PARAM_RETURN_URL to returnUrl)) - .setApiParameterMap(sofortMap) + .setReturnUrl(returnUrl) + .setApiParameterMap(sofortData) } /** @@ -955,7 +950,7 @@ class SourceParams private constructor( return SourceParams(SourceType.THREE_D_SECURE) .setCurrency(currency) .setAmount(amount) - .setRedirect(mapOf(PARAM_RETURN_URL to returnUrl)) + .setReturnUrl(returnUrl) .setApiParameterMap(mapOf(PARAM_CARD to cardId)) } diff --git a/stripe/src/test/java/com/stripe/android/StripeTest.java b/stripe/src/test/java/com/stripe/android/StripeTest.java index adcec3c021d..c5e228ad617 100644 --- a/stripe/src/test/java/com/stripe/android/StripeTest.java +++ b/stripe/src/test/java/com/stripe/android/StripeTest.java @@ -409,7 +409,8 @@ public void createSourceSynchronous_withBancontactParams_passesIntegrationTest() "John Doe", "example://path", "a statement described", - "en"); + "en" + ); final Map metamap = new HashMap() {{ put("flavor", "strawberry"); put("type", "sherbet"); diff --git a/stripe/src/test/java/com/stripe/android/model/SourceParamsTest.kt b/stripe/src/test/java/com/stripe/android/model/SourceParamsTest.kt index 3b28b353249..d042b37f802 100644 --- a/stripe/src/test/java/com/stripe/android/model/SourceParamsTest.kt +++ b/stripe/src/test/java/com/stripe/android/model/SourceParamsTest.kt @@ -1,10 +1,8 @@ package com.stripe.android.model import com.stripe.android.CardNumberFixtures.VALID_VISA_NO_SPACES -import com.stripe.android.testharness.JsonTestUtils import kotlin.test.Test import kotlin.test.assertEquals -import kotlin.test.assertFalse import kotlin.test.assertNull import org.json.JSONException @@ -19,36 +17,37 @@ class SourceParamsTest { "usd", "Jean Valjean", "jdog@lesmis.net", - "stripe://start") + RETURN_URL + ) assertEquals(Source.SourceType.ALIPAY, params.type) assertEquals(Source.Usage.REUSABLE, params.usage) assertNull(params.amount) assertEquals("usd", params.currency) - assertEquals("stripe://start", requireNotNull(params.redirect)["return_url"]) + assertEquals(RETURN_URL, params.returnUrl) val owner = requireNotNull(params.owner) - assertEquals("Jean Valjean", owner["name"]) - assertEquals("jdog@lesmis.net", owner["email"]) + assertEquals("Jean Valjean", owner.name) + assertEquals("jdog@lesmis.net", owner.email) } @Test fun createAlipayReusableParams_withOnlyName_hasOnlyExpectedFields() { val params = SourceParams.createAlipayReusableParams( - "cad", - "Hari Seldon", - null, - "stripe://start") + currency = "cad", + name = "Hari Seldon", + returnUrl = RETURN_URL + ) assertEquals(Source.SourceType.ALIPAY, params.type) assertEquals(Source.Usage.REUSABLE, params.usage) assertNull(params.amount) assertEquals("cad", params.currency) - assertEquals("stripe://start", requireNotNull(params.redirect)["return_url"]) + assertEquals(RETURN_URL, params.returnUrl) val owner = requireNotNull(params.owner) - assertEquals("Hari Seldon", owner["name"]) - assertFalse(owner.containsKey("email")) + assertEquals("Hari Seldon", owner.name) + assertNull(owner.email) } @Test @@ -58,37 +57,34 @@ class SourceParamsTest { "aud", "Jane Tester", "jane@test.com", - "stripe://testactivity") + RETURN_URL) assertEquals(Source.SourceType.ALIPAY, params.type) - requireNotNull(params.amount) assertEquals(1000L, params.amount) assertEquals("aud", params.currency) val owner = requireNotNull(params.owner) - assertEquals("Jane Tester", owner["name"]) - assertEquals("jane@test.com", owner["email"]) + assertEquals("Jane Tester", owner.name) + assertEquals("jane@test.com", owner.email) - assertEquals("stripe://testactivity", - requireNotNull(params.redirect)["return_url"]) + assertEquals(RETURN_URL, params.returnUrl) } @Test fun createAlipaySingleUseParams_withoutOwner_hasNoOwnerFields() { val params = SourceParams.createAlipaySingleUseParams( - 555L, - "eur", null, null, - "stripe://testactivity2") + amount = 555L, + currency = "eur", + returnUrl = RETURN_URL + ) assertEquals(Source.SourceType.ALIPAY, params.type) - requireNotNull(params.amount) assertEquals(555L, params.amount) assertEquals("eur", params.currency) - assertNull(params.owner) + assertEquals(SourceParams.OwnerParams(), params.owner) - assertEquals("stripe://testactivity2", - requireNotNull(params.redirect)["return_url"]) + assertEquals(RETURN_URL, params.returnUrl) } @Test @@ -102,10 +98,9 @@ class SourceParamsTest { assertEquals(Source.SourceType.BANCONTACT, params.type) assertEquals(Source.EURO, params.currency) - requireNotNull(params.amount) assertEquals(1000L, params.amount) - assertEquals("Stripe", requireNotNull(params.owner)["name"]) - assertEquals("return/url/3000", requireNotNull(params.redirect)["return_url"]) + assertEquals("Stripe", params.owner?.name) + assertEquals("return/url/3000", params.returnUrl) val apiMap = requireNotNull(params.apiParameterMap) assertEquals("descriptor", apiMap["statement_descriptor"]) @@ -133,7 +128,7 @@ class SourceParamsTest { ) ) - JsonTestUtils.assertMapEquals(expectedMap, params.toParamMap()) + assertEquals(expectedMap, params.toParamMap()) } @Test @@ -186,10 +181,11 @@ class SourceParamsTest { assertEquals("123", apiMap["cvc"]) val owner = requireNotNull(params.owner) - assertEquals("Captain Cardholder", owner["name"]) - assertEquals(2, owner.size) + assertEquals("Captain Cardholder", owner.name) + assertNull(owner.email) + assertNull(owner.phone) - val addressMap = getOwnerAddress(params) + val addressMap = owner.address?.toParamMap().orEmpty() assertEquals("1 ABC Street", addressMap["line1"]) assertEquals("Apt. 123", addressMap["line2"]) assertEquals("San Francisco", addressMap["city"]) @@ -226,7 +222,7 @@ class SourceParamsTest { "metadata" to METADATA ) - JsonTestUtils.assertMapEquals(totalExpectedMap, params.toParamMap()) + assertEquals(totalExpectedMap, params.toParamMap()) } @Test @@ -234,9 +230,9 @@ class SourceParamsTest { fun createCardParamsFromGooglePay_withNoBillingAddress() { val createdParams = SourceParams.createCardParamsFromGooglePay( GooglePayFixtures.GOOGLE_PAY_RESULT_WITH_NO_BILLING_ADDRESS) - - val expectedParams = SourceParams.createSourceFromTokenParams("tok_1F4ACMCRMbs6FrXf6fPqLnN7") - + val expectedParams = SourceParams + .createSourceFromTokenParams("tok_1F4ACMCRMbs6FrXf6fPqLnN7") + .setOwner(SourceParams.OwnerParams()) assertEquals(expectedParams, createdParams) } @@ -246,16 +242,16 @@ class SourceParamsTest { val createdParams = SourceParams.createCardParamsFromGooglePay( GooglePayFixtures.GOOGLE_PAY_RESULT_WITH_FULL_BILLING_ADDRESS) - val ownerParams = mapOf( - "email" to "stripe@example.com", - "name" to "Stripe Johnson", - "phone" to "1-888-555-1234", - "address" to mapOf( - "line1" to "510 Townsend St", - "city" to "San Francisco", - "state" to "CA", - "postal_code" to "94103", - "country" to "US" + val ownerParams = SourceParams.OwnerParams( + email = "stripe@example.com", + name = "Stripe Johnson", + phone = "1-888-555-1234", + address = Address( + line1 = "510 Townsend St", + city = "San Francisco", + state = "CA", + postalCode = "94103", + country = "US" ) ) @@ -270,14 +266,13 @@ class SourceParamsTest { val params = SourceParams.createEPSParams( 150L, "Stripe", - "stripe://return", + RETURN_URL, "stripe descriptor") assertEquals(Source.SourceType.EPS, params.type) assertEquals(Source.EURO, params.currency) - assertEquals("Stripe", requireNotNull(params.owner)["name"]) - assertEquals("stripe://return", - requireNotNull(params.redirect)["return_url"]) + assertEquals("Stripe", params.owner?.name) + assertEquals(RETURN_URL, params.returnUrl) val apiMap = requireNotNull(params.apiParameterMap) assertEquals("stripe descriptor", apiMap["statement_descriptor"]) @@ -288,7 +283,7 @@ class SourceParamsTest { val params = SourceParams.createEPSParams( 150L, "Stripe", - "stripe://return", + RETURN_URL, "stripe descriptor") val expectedMap = mapOf( @@ -296,11 +291,11 @@ class SourceParamsTest { "currency" to Source.EURO, "amount" to 150L, "owner" to mapOf("name" to "Stripe"), - "redirect" to mapOf("return_url" to "stripe://return"), + "redirect" to mapOf("return_url" to RETURN_URL), Source.SourceType.EPS to mapOf("statement_descriptor" to "stripe descriptor") ) - JsonTestUtils.assertMapEquals(expectedMap, params.toParamMap()) + assertEquals(expectedMap, params.toParamMap()) } @Test @@ -308,17 +303,17 @@ class SourceParamsTest { val params = SourceParams.createEPSParams( 150L, "Stripe", - "stripe://return", null) + RETURN_URL, null) val expectedMap = mapOf( "type" to Source.SourceType.EPS, "currency" to Source.EURO, "amount" to 150L, "owner" to mapOf("name" to "Stripe"), - "redirect" to mapOf("return_url" to "stripe://return") + "redirect" to mapOf("return_url" to RETURN_URL) ) - JsonTestUtils.assertMapEquals(expectedMap, params.toParamMap()) + assertEquals(expectedMap, params.toParamMap()) } @Test @@ -326,19 +321,16 @@ class SourceParamsTest { val params = SourceParams.createGiropayParams( 150L, "Stripe", - "stripe://return", + RETURN_URL, "stripe descriptor") assertEquals(Source.SourceType.GIROPAY, params.type) assertEquals(Source.EURO, params.currency) - requireNotNull(params.amount) assertEquals(150L, params.amount) - val owner = requireNotNull(params.owner) - assertEquals("Stripe", owner["name"]) + assertEquals("Stripe", params.owner?.name) - val redirect = requireNotNull(params.redirect) - assertEquals("stripe://return", redirect["return_url"]) + assertEquals(RETURN_URL, params.returnUrl) val apiMap = requireNotNull(params.apiParameterMap) assertEquals("stripe descriptor", apiMap["statement_descriptor"]) @@ -349,7 +341,7 @@ class SourceParamsTest { val params = SourceParams.createGiropayParams( 150L, "Stripe", - "stripe://return", + RETURN_URL, "stripe descriptor") val expectedMap = mapOf( @@ -360,14 +352,14 @@ class SourceParamsTest { "name" to "Stripe" ), "redirect" to mapOf( - "return_url" to "stripe://return" + "return_url" to RETURN_URL ), Source.SourceType.GIROPAY to mapOf( "statement_descriptor" to "stripe descriptor" ) ) - JsonTestUtils.assertMapEquals(expectedMap, params.toParamMap()) + assertEquals(expectedMap, params.toParamMap()) } @Test @@ -375,16 +367,15 @@ class SourceParamsTest { val params = SourceParams.createGiropayParams( 150L, "Stripe", - "stripe://return", null) + RETURN_URL, null) assertEquals(Source.SourceType.GIROPAY, params.type) assertEquals(Source.EURO, params.currency) - requireNotNull(params.amount) assertEquals(150L, params.amount) - assertEquals("Stripe", requireNotNull(params.owner)["name"]) + assertEquals("Stripe", params.owner?.name) - assertEquals("stripe://return", requireNotNull(params.redirect)["return_url"]) + assertEquals(RETURN_URL, params.returnUrl) assertNull(params.apiParameterMap) } @@ -393,17 +384,17 @@ class SourceParamsTest { val params = SourceParams.createIdealParams( 900L, "Default Name", - "stripe://anotherurl", + RETURN_URL, "something you bought", - "SVB") + "SVB" + ) assertEquals(Source.SourceType.IDEAL, params.type) assertEquals(Source.EURO, params.currency) - requireNotNull(params.amount) assertEquals(900L, params.amount) - assertEquals("Default Name", requireNotNull(params.owner)["name"]) + assertEquals("Default Name", params.owner?.name) - assertEquals("stripe://anotherurl", requireNotNull(params.redirect)["return_url"]) + assertEquals(RETURN_URL, params.returnUrl) val apiMap = requireNotNull(params.apiParameterMap) assertEquals("something you bought", apiMap["statement_descriptor"]) @@ -415,7 +406,7 @@ class SourceParamsTest { val params = SourceParams.createIdealParams( 900L, "Default Name", - "stripe://anotherurl", + RETURN_URL, "something you bought", "SVB") @@ -424,14 +415,14 @@ class SourceParamsTest { "currency" to Source.EURO, "amount" to 900L, "owner" to mapOf("name" to "Default Name"), - "redirect" to mapOf("return_url" to "stripe://anotherurl"), + "redirect" to mapOf("return_url" to RETURN_URL), Source.SourceType.IDEAL to mapOf( "statement_descriptor" to "something you bought", "bank" to "SVB" ) ) - JsonTestUtils.assertMapEquals(expectedMap, params.toParamMap()) + assertEquals(expectedMap, params.toParamMap()) } @Test @@ -441,19 +432,18 @@ class SourceParamsTest { "eur", "Jane Tester", "jane@test.com", - "stripe://testactivity") + RETURN_URL) assertEquals(Source.SourceType.P24, params.type) - requireNotNull(params.amount) assertEquals(1000L, params.amount) assertEquals("eur", params.currency) val owner = requireNotNull(params.owner) - assertEquals("Jane Tester", owner["name"]) - assertEquals("jane@test.com", owner["email"]) + assertEquals("Jane Tester", owner.name) + assertEquals("jane@test.com", owner.email) - assertEquals("stripe://testactivity", - requireNotNull(params.redirect)["return_url"]) + assertEquals(RETURN_URL, + params.returnUrl) } @Test @@ -462,42 +452,40 @@ class SourceParamsTest { 1000L, "eur", null, "jane@test.com", - "stripe://testactivity") + RETURN_URL) assertEquals(Source.SourceType.P24, params.type) - requireNotNull(params.amount) assertEquals(1000L, params.amount) assertEquals("eur", params.currency) val owner = requireNotNull(params.owner) - assertNull(owner["name"]) - assertEquals("jane@test.com", owner["email"]) + assertNull(owner.name) + assertEquals("jane@test.com", owner.email) - assertEquals("stripe://testactivity", - requireNotNull(params.redirect)["return_url"]) + assertEquals(RETURN_URL, + params.returnUrl) } @Test fun createMultibancoParams_hasExpectedFields() { val params = SourceParams.createMultibancoParams( 150L, - "stripe://testactivity", + RETURN_URL, "multibancoholder@stripe.com") assertEquals(Source.SourceType.MULTIBANCO, params.type) assertEquals(Source.EURO, params.currency) assertEquals(150L, params.amount) - assertEquals("stripe://testactivity", - requireNotNull(params.redirect)["return_url"]) - assertEquals("multibancoholder@stripe.com", - requireNotNull(params.owner)["email"]) + assertEquals(RETURN_URL, + params.returnUrl) + assertEquals("multibancoholder@stripe.com", params.owner?.email) } @Test fun createMultibancoParams_toParamMap_createsExpectedMap() { val params = SourceParams.createMultibancoParams( 150L, - "stripe://testactivity", + RETURN_URL, "multibancoholder@stripe.com") val expectedMap = mapOf( @@ -505,10 +493,10 @@ class SourceParamsTest { "currency" to Source.EURO, "amount" to 150L, "owner" to mapOf("email" to "multibancoholder@stripe.com"), - "redirect" to mapOf("return_url" to "stripe://testactivity") + "redirect" to mapOf("return_url" to RETURN_URL) ) - JsonTestUtils.assertMapEquals(expectedMap, params.toParamMap()) + assertEquals(expectedMap, params.toParamMap()) } @Test @@ -525,9 +513,9 @@ class SourceParamsTest { assertEquals(Source.SourceType.SEPA_DEBIT, params.type) assertEquals(Source.EURO, params.currency) - assertEquals("Jai Testa", requireNotNull(params.owner)["name"]) + assertEquals("Jai Testa", params.owner?.name) - val addressMap = getOwnerAddress(params) + val addressMap = params.owner?.address?.toParamMap().orEmpty() assertEquals("44 Fourth Street", addressMap["line1"]) assertEquals("Test City", addressMap["city"]) assertEquals("90210", addressMap["postal_code"]) @@ -567,22 +555,22 @@ class SourceParamsTest { assertEquals(Source.SourceType.SEPA_DEBIT, params.type) val actualMap = params.toParamMap() - JsonTestUtils.assertMapEquals(expectedMap, actualMap) + assertEquals(expectedMap, actualMap) } @Test fun createSofortParams_hasExpectedFields() { val params = SourceParams.createSofortParams( 50000L, - "example://return", + RETURN_URL, "UK", - "a thing you bought") + "a thing you bought" + ) assertEquals(Source.SourceType.SOFORT, params.type) assertEquals(Source.EURO, params.currency) - requireNotNull(params.amount) assertEquals(50000L, params.amount) - assertEquals("example://return", requireNotNull(params.redirect)["return_url"]) + assertEquals(RETURN_URL, params.returnUrl) val apiMap = requireNotNull(params.apiParameterMap) assertEquals("UK", apiMap["country"]) @@ -593,7 +581,7 @@ class SourceParamsTest { fun createSofortParams_toParamMap_createsExpectedMap() { val params = SourceParams.createSofortParams( 50000L, - "example://return", + RETURN_URL, "UK", "a thing you bought") @@ -601,14 +589,14 @@ class SourceParamsTest { "type" to Source.SourceType.SOFORT, "currency" to Source.EURO, "amount" to 50000L, - "redirect" to mapOf("return_url" to "example://return"), + "redirect" to mapOf("return_url" to RETURN_URL), Source.SourceType.SOFORT to mapOf( "country" to "UK", "statement_descriptor" to "a thing you bought" ) ) - JsonTestUtils.assertMapEquals(expectedMap, params.toParamMap()) + assertEquals(expectedMap, params.toParamMap()) } @Test @@ -616,16 +604,15 @@ class SourceParamsTest { val params = SourceParams.createThreeDSecureParams( 99000L, "brl", - "stripe://returnaddress", - "card_id_123") + RETURN_URL, + "card_id_123" + ) assertEquals(Source.SourceType.THREE_D_SECURE, params.type) // Brazilian Real assertEquals("brl", params.currency) - requireNotNull(params.amount) assertEquals(99000L, params.amount) - assertEquals("stripe://returnaddress", - requireNotNull(params.redirect)["return_url"]) + assertEquals(RETURN_URL, params.returnUrl) val apiMap = requireNotNull(params.apiParameterMap) assertEquals(1, apiMap.size) @@ -637,18 +624,18 @@ class SourceParamsTest { val params = SourceParams.createThreeDSecureParams( 99000L, "brl", - "stripe://returnaddress", + RETURN_URL, "card_id_123") val expectedMap = mapOf( "type" to Source.SourceType.THREE_D_SECURE, "currency" to "brl", "amount" to 99000L, - "redirect" to mapOf("return_url" to "stripe://returnaddress"), + "redirect" to mapOf("return_url" to RETURN_URL), Source.SourceType.THREE_D_SECURE to mapOf("card" to "card_id_123") ) - JsonTestUtils.assertMapEquals(expectedMap, params.toParamMap()) + assertEquals(expectedMap, params.toParamMap()) } @Test @@ -657,15 +644,13 @@ class SourceParamsTest { // including a source type params val dogecoin = "dogecoin" - val ownerMap = mapOf("name" to "Stripe") - val dogecoinParams = mapOf("statement_descriptor" to "stripe descriptor") val params = SourceParams.createCustomParams(dogecoin) .setCurrency(Source.EURO) .setAmount(150L) - .setReturnUrl("stripe://return") - .setOwner(ownerMap) + .setReturnUrl(RETURN_URL) + .setOwner(SourceParams.OwnerParams(name = "Stripe")) .setApiParameterMap(dogecoinParams) val expectedMap = mapOf( @@ -673,11 +658,11 @@ class SourceParamsTest { "currency" to Source.EURO, "amount" to 150L, "owner" to mapOf("name" to "Stripe"), - "redirect" to mapOf("return_url" to "stripe://return"), + "redirect" to mapOf("return_url" to RETURN_URL), dogecoin to mapOf("statement_descriptor" to "stripe descriptor") ) - JsonTestUtils.assertMapEquals(expectedMap, params.toParamMap()) + assertEquals(expectedMap, params.toParamMap()) } @Test @@ -712,17 +697,12 @@ class SourceParamsTest { val sourceParams = SourceParams.createCustomParams("bar_tab") .setAmount(99000L) .setCurrency("brl") - .setReturnUrl("stripe://returnaddress") + .setReturnUrl(RETURN_URL) .setApiParameterMap(apiParamMap) assertEquals(Source.SourceType.UNKNOWN, sourceParams.type) assertEquals("bar_tab", sourceParams.typeRaw) } - private fun getOwnerAddress(params: SourceParams): Map { - val owner = requireNotNull(params.owner) - return owner["address"] as Map - } - private companion object { private val METADATA = mapOf( @@ -730,6 +710,8 @@ class SourceParamsTest { "animal" to "dog" ) + private const val RETURN_URL = "stripe://return" + private val FULL_FIELDS_VISA_CARD = Card.Builder(VALID_VISA_NO_SPACES, 12, 2050, "123") .name("Captain Cardholder")