diff --git a/MIGRATING.md b/MIGRATING.md index 5921e3dc7f0..da9cd734c11 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -53,6 +53,14 @@ - Changes to `AddPaymentMethodActivity` - When `CustomerSession` is instantiated with a `stripeAccountId`, it will be used in `AddPaymentMethodActivity` when creating a payment method +- Changes to `Source` + - `Source.SourceFlow` has been renamed to `Source.Flow` and is now an enum + - `Source.SourceStatus` has been renamed to `Source.Status` and is now an enum + - `Source.Usage` is now an enum + - `SourceCodeVerification` has been moved to `Source.CodeVerification` + - `SourceOwner` has been moved to `Source.Owner` + - `SourceReceiver` has been moved to `Source.Receiver` + - `SourceRedirect` has been moved to `Source.Redirect` - Changes to `SourceTypeModel.Card` - `SourceTypeModel.Card.ThreeDSecureStatus` is now an enum - Changes to `BankAccount` diff --git a/example/src/main/java/com/stripe/example/activity/CreateCardSourceActivity.kt b/example/src/main/java/com/stripe/example/activity/CreateCardSourceActivity.kt index b2a62310b4d..c8cd0057a62 100644 --- a/example/src/main/java/com/stripe/example/activity/CreateCardSourceActivity.kt +++ b/example/src/main/java/com/stripe/example/activity/CreateCardSourceActivity.kt @@ -168,7 +168,7 @@ class CreateCardSourceActivity : AppCompatActivity() { * Authenticate the [Source] */ private fun authenticateSource(source: Source) { - if (source.flow == Source.SourceFlow.REDIRECT) { + if (source.flow == Source.Flow.Redirect) { createAuthenticateSourceDialog(source).let { alertDialog = it it.show() diff --git a/example/src/main/java/com/stripe/example/adapter/SourcesAdapter.kt b/example/src/main/java/com/stripe/example/adapter/SourcesAdapter.kt index 89660312f18..76e804f91b0 100644 --- a/example/src/main/java/com/stripe/example/adapter/SourcesAdapter.kt +++ b/example/src/main/java/com/stripe/example/adapter/SourcesAdapter.kt @@ -19,7 +19,7 @@ internal class SourcesAdapter : RecyclerView.Adapter( private val viewBinding: SourcesListItemBinding ) : RecyclerView.ViewHolder(viewBinding.root) { fun bind(source: Source) { - viewBinding.status.text = source.status + viewBinding.status.text = source.status?.toString() viewBinding.redirectStatus.text = getRedirectStatus(source) viewBinding.sourceId.text = source.id?.let { sourceId -> sourceId.substring(sourceId.length - 6) @@ -32,7 +32,7 @@ internal class SourcesAdapter : RecyclerView.Adapter( } private fun getRedirectStatus(source: Source): String? { - return source.redirect?.status + return source.redirect?.status?.toString() ?: (source.sourceTypeModel as SourceTypeModel.Card).threeDSecureStatus.toString() } } diff --git a/stripe/src/main/java/com/stripe/android/Stripe.kt b/stripe/src/main/java/com/stripe/android/Stripe.kt index 94d95583b16..59a4a090569 100644 --- a/stripe/src/main/java/com/stripe/android/Stripe.kt +++ b/stripe/src/main/java/com/stripe/android/Stripe.kt @@ -760,7 +760,7 @@ class Stripe internal constructor( /** * Authenticate a [Source] that requires user action via a redirect (i.e. [Source.flow] is - * [Source.SourceFlow.REDIRECT]. + * [Source.Flow.Redirect]. * * The result of this operation will be returned via `Activity#onActivityResult(int, int, Intent)}}` * @@ -784,7 +784,7 @@ class Stripe internal constructor( /** * Authenticate a [Source] that requires user action via a redirect (i.e. [Source.flow] is - * [Source.SourceFlow.REDIRECT]. + * [Source.Flow.Redirect]. * * The result of this operation will be returned via `Activity#onActivityResult(int, int, Intent)}}` * diff --git a/stripe/src/main/java/com/stripe/android/StripePaymentController.kt b/stripe/src/main/java/com/stripe/android/StripePaymentController.kt index a56719cf375..3c4e00757ac 100644 --- a/stripe/src/main/java/com/stripe/android/StripePaymentController.kt +++ b/stripe/src/main/java/com/stripe/android/StripePaymentController.kt @@ -156,7 +156,7 @@ internal class StripePaymentController internal constructor( source: Source, requestOptions: ApiRequest.Options ) { - if (source.flow == Source.SourceFlow.REDIRECT) { + if (source.flow == Source.Flow.Redirect) { analyticsRequestExecutor.executeAsync( analyticsRequestFactory.create( analyticsDataFactory.createAuthSourceParams( diff --git a/stripe/src/main/java/com/stripe/android/model/Source.kt b/stripe/src/main/java/com/stripe/android/model/Source.kt index b4628ebf271..62a21fc46c5 100644 --- a/stripe/src/main/java/com/stripe/android/model/Source.kt +++ b/stripe/src/main/java/com/stripe/android/model/Source.kt @@ -1,7 +1,7 @@ package com.stripe.android.model import androidx.annotation.StringDef -import com.stripe.android.model.Source.SourceFlow +import com.stripe.android.model.Source.Flow import com.stripe.android.model.Source.SourceType import com.stripe.android.model.parsers.SourceJsonParser import kotlinx.android.parcel.Parcelize @@ -37,7 +37,7 @@ data class Source internal constructor( * Information related to the code verification flow. Present if the source is authenticated * by a verification code (`flow` is `code_verification`). */ - val codeVerification: SourceCodeVerification? = null, + val codeVerification: CodeVerification? = null, /** * Time at which the object was created. Measured in seconds since the Unix epoch. @@ -55,8 +55,7 @@ data class Source internal constructor( * The authentication `flow` of the source. * `flow` is one of `redirect`, `receiver`, `code_verification`, `none`. */ - @param:SourceFlow @field:SourceFlow @get:SourceFlow - val flow: String? = null, + val flow: Flow? = null, /** * Has the value true if the object exists in live mode or the value false if the object @@ -74,26 +73,25 @@ data class Source internal constructor( * Information about the owner of the payment instrument that may be used or required by * particular source types. */ - val owner: SourceOwner? = null, + val owner: Owner? = null, /** * Information related to the receiver flow. - * Present if the source is a receiver ([flow] is [SourceFlow.RECEIVER]). + * Present if the source is a receiver ([flow] is [Flow.Receiver]). */ - val receiver: SourceReceiver? = null, + val receiver: Receiver? = null, /** * Information related to the redirect flow. Present if the source is authenticated by a - * redirect ([flow] is [SourceFlow.REDIRECT]). + * redirect ([flow] is [Flow.REDIRECT]). */ - val redirect: SourceRedirect? = null, + val redirect: Redirect? = null, /** * The status of the source, one of `canceled`, `chargeable`, `consumed`, `failed`, * or `pending`. Only `chargeable` sources can be used to create a charge. */ - @param:SourceStatus @field:SourceStatus @get:SourceStatus - val status: String? = null, + val status: Status? = null, val sourceTypeData: Map? = null, @@ -121,8 +119,7 @@ data class Source internal constructor( * 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 @field:Usage @get:Usage - val usage: String? = null, + val usage: Usage? = null, private val _weChat: WeChat? = null, @@ -183,40 +180,214 @@ data class Source internal constructor( } } - @Retention(AnnotationRetention.SOURCE) - @StringDef(SourceStatus.PENDING, SourceStatus.CHARGEABLE, SourceStatus.CONSUMED, - SourceStatus.CANCELED, SourceStatus.FAILED) - annotation class SourceStatus { - companion object { - const val PENDING: String = "pending" - const val CHARGEABLE: String = "chargeable" - const val CONSUMED: String = "consumed" - const val CANCELED: String = "canceled" - const val FAILED: String = "failed" + /** + * The status of the source, one of `canceled`, `chargeable`, `consumed`, `failed`, + * or `pending`. Only `chargeable` sources can be used to create a charge. + */ + enum class Status(private val code: String) { + Canceled("canceled"), + Chargeable("chargeable"), + Consumed("consumed"), + Failed("failed"), + Pending("pending"); + + override fun toString(): String = code + + internal companion object { + fun fromCode(code: String?) = values().firstOrNull { it.code == code } } } - @Retention(AnnotationRetention.SOURCE) - @StringDef(Usage.REUSABLE, Usage.SINGLE_USE) - annotation class Usage { - companion object { - const val REUSABLE: String = "reusable" - const val SINGLE_USE: String = "single_use" + /** + * 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. + */ + enum class Usage(internal val code: String) { + Reusable("reusable"), + SingleUse("single_use"); + + internal companion object { + fun fromCode(code: String?) = values().firstOrNull { it.code == code } } } - @Retention(AnnotationRetention.SOURCE) - @StringDef(SourceFlow.REDIRECT, SourceFlow.RECEIVER, SourceFlow.CODE_VERIFICATION, - SourceFlow.NONE) - annotation class SourceFlow { - companion object { - const val REDIRECT: String = "redirect" - const val RECEIVER: String = "receiver" - const val CODE_VERIFICATION: String = "code_verification" - const val NONE: String = "none" + /** + * The authentication `flow` of the source. + */ + enum class Flow(internal val code: String) { + Redirect("redirect"), + Receiver("receiver"), + CodeVerification("code_verification"), + None("none"); + + internal companion object { + fun fromCode(code: String?) = values().firstOrNull { it.code == code } + } + } + + /** + * Information related to the redirect flow. Present if the source is authenticated by a + * redirect ([flow] is [Flow.Redirect]). + */ + @Parcelize + data class Redirect( + /** + * The URL you provide to redirect the customer to after they authenticated their payment. + */ + val returnUrl: String?, + + /** + * The status of the redirect, either + * `pending` (ready to be used by your customer to authenticate the transaction), + * `succeeded` (succesful authentication, cannot be reused) or + * `not_required` (redirect should not be used) or + * `failed` (failed authentication, cannot be reused). + */ + val status: Status?, + + /** + * The URL provided to you to redirect a customer to as part of a `redirect` + * authentication flow. + */ + val url: String? + ) : StripeModel { + + enum class Status(private val code: String) { + Pending("pending"), + Succeeded("succeeded"), + NotRequired("not_required"), + Failed("failed"); + + override fun toString(): String = code + + internal companion object { + fun fromCode(code: String?) = values().firstOrNull { it.code == code } + } + } + } + + /** + * Information related to the code verification flow. Present if the source is authenticated + * by a verification code ([flow] is [Flow.CodeVerification]). + */ + @Parcelize + data class CodeVerification internal constructor( + /** + * The number of attempts remaining to authenticate the source object with a verification + * code. + */ + val attemptsRemaining: Int, + + /** + * The status of the code verification, either + * `pending` (awaiting verification, `attempts_remaining` should be greater than 0), + * `succeeded` (successful verification) or + * `failed` (failed verification, cannot be verified anymore as `attempts_remaining` should be 0). + */ + val status: Status? + ) : StripeModel { + + enum class Status(private val code: String) { + Pending("pending"), + Succeeded("succeeded"), + Failed("failed"); + + internal companion object { + fun fromCode(code: String?) = values().firstOrNull { it.code == code } + } } } + /** + * Information related to the receiver flow. Present if [flow] is [Source.Flow.Receiver]. + */ + @Parcelize + data class Receiver internal constructor( + /** + * The address of the receiver source. This is the value that should be communicated to the + * customer to send their funds to. + */ + val address: String?, + + /** + * The total amount that was moved to your balance. This is almost always equal to the amount + * charged. In rare cases when customers deposit excess funds and we are unable to refund + * those, those funds get moved to your balance and show up in amount_charged as well. + * The amount charged is expressed in the source’s currency. + */ + val amountCharged: Long, + + /** + * The total amount received by the receiver source. + * `amount_received = amount_returned + amount_charged` should be true for consumed sources + * unless customers deposit excess funds. The amount received is expressed in the source’s + * currency. + */ + val amountReceived: Long, + + /** + * The total amount that was returned to the customer. The amount returned is expressed in + * the source’s currency. + */ + val amountReturned: Long + ) : StripeModel + + /** + * Information about the owner of the payment instrument that may be used or required by + * particular source types. + */ + @Parcelize + data class Owner internal constructor( + /** + * Owner’s address. + */ + val address: Address?, + + /** + * Owner’s email address. + */ + val email: String?, + + /** + * Owner’s full name. + */ + val name: String?, + + /** + * Owner’s phone number (including extension). + */ + val phone: String?, + + /** + * Verified owner’s address. Verified values are verified or provided by the payment + * method directly (and if supported) at the time of authorization or settlement. + * They cannot be set or mutated. + */ + val verifiedAddress: Address?, + + /** + * Verified owner’s email address. Verified values are verified or provided by the + * payment method directly (and if supported) at the time of authorization or settlement. + * They cannot be set or mutated. + */ + val verifiedEmail: String?, + + /** + * Verified owner’s full name. Verified values are verified or provided by the payment + * method directly (and if supported) at the time of authorization or settlement. + * They cannot be set or mutated. + */ + val verifiedName: String?, + + /** + * Verified owner’s phone number (including extension). Verified values are verified or + * provided by the payment method directly (and if supported) at the time of authorization + * or settlement. They cannot be set or mutated. + */ + val verifiedPhone: String? + ) : StripeModel + @Parcelize data class Klarna( val firstName: String?, diff --git a/stripe/src/main/java/com/stripe/android/model/SourceCodeVerification.kt b/stripe/src/main/java/com/stripe/android/model/SourceCodeVerification.kt deleted file mode 100644 index ca44b95b0b3..00000000000 --- a/stripe/src/main/java/com/stripe/android/model/SourceCodeVerification.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.stripe.android.model - -import androidx.annotation.StringDef -import kotlinx.android.parcel.Parcelize - -/** - * Model for a [code verification](https://stripe.com/docs/api/sources/object#source_object-code_verification) - * object in the Sources API. - * - * *Not* source code verification. - */ -@Parcelize -data class SourceCodeVerification internal constructor( - val attemptsRemaining: Int, - @param:Status @field:Status @get:Status val status: String? -) : StripeModel { - - // Note: these are the same as the values for the @Redirect.Status StringDef. - // They don't have to stay the same forever, so they are redefined here. - @Retention(AnnotationRetention.SOURCE) - @StringDef(Status.PENDING, Status.SUCCEEDED, Status.FAILED) - internal annotation class Status { - companion object { - const val PENDING = "pending" - const val SUCCEEDED = "succeeded" - const val FAILED = "failed" - } - } -} diff --git a/stripe/src/main/java/com/stripe/android/model/SourceOwner.kt b/stripe/src/main/java/com/stripe/android/model/SourceOwner.kt deleted file mode 100644 index d241cf99f09..00000000000 --- a/stripe/src/main/java/com/stripe/android/model/SourceOwner.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.stripe.android.model - -import kotlinx.android.parcel.Parcelize - -/** - * Model for a [owner](https://stripe.com/docs/api#source_object-owner) object - * in the Source api. - */ -@Parcelize -data class SourceOwner internal constructor( - val address: Address?, - val email: String?, - val name: String?, - val phone: String?, - val verifiedAddress: Address?, - val verifiedEmail: String?, - val verifiedName: String?, - val verifiedPhone: String? -) : StripeModel 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 e0af82ffbfc..8175d0b1472 100644 --- a/stripe/src/main/java/com/stripe/android/model/SourceParams.kt +++ b/stripe/src/main/java/com/stripe/android/model/SourceParams.kt @@ -96,9 +96,7 @@ class SourceParams private constructor( * * See [usage](https://stripe.com/docs/api/sources/create#create_source-usage) */ - @get:Source.Usage - @Source.Usage - var usage: String? = null + var usage: Source.Usage? = null private set private var weChatParams: WeChatParams? = null @@ -189,7 +187,7 @@ class SourceParams private constructor( * * See [usage](https://stripe.com/docs/api/sources/create#create_source-usage) */ - fun setUsage(@Source.Usage usage: String): SourceParams = apply { + fun setUsage(usage: Source.Usage): SourceParams = apply { this.usage = usage } @@ -240,7 +238,7 @@ class SourceParams private constructor( ) .plus( usage?.let { - mapOf(PARAM_USAGE to it) + mapOf(PARAM_USAGE to it.code) }.orEmpty() ) .plus(extraParams) @@ -440,7 +438,7 @@ class SourceParams private constructor( return SourceParams(SourceType.ALIPAY) .setCurrency(currency) .setReturnUrl(returnUrl) - .setUsage(Source.Usage.REUSABLE) + .setUsage(Source.Usage.Reusable) .setOwner( OwnerParams( email = email, @@ -564,7 +562,7 @@ class SourceParams private constructor( .setExtraParams( mapOf( PARAM_KLARNA to klarnaParams.toParamMap(), - PARAM_FLOW to Source.SourceFlow.REDIRECT, + PARAM_FLOW to Source.Flow.Redirect.code, PARAM_SOURCE_ORDER to sourceOrderParams.toParamMap() ) ) diff --git a/stripe/src/main/java/com/stripe/android/model/SourceReceiver.kt b/stripe/src/main/java/com/stripe/android/model/SourceReceiver.kt deleted file mode 100644 index 8ea38e8546e..00000000000 --- a/stripe/src/main/java/com/stripe/android/model/SourceReceiver.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.stripe.android.model - -import kotlinx.android.parcel.Parcelize - -/** - * Model for a - * [receiver](https://stripe.com/docs/api/sources/object#source_object-receiver) object - * in the Sources API. Present if the [Source] is a receiver. - */ -@Parcelize -data class SourceReceiver internal constructor( - val address: String?, - val amountCharged: Long, - val amountReceived: Long, - val amountReturned: Long -) : StripeModel diff --git a/stripe/src/main/java/com/stripe/android/model/SourceRedirect.kt b/stripe/src/main/java/com/stripe/android/model/SourceRedirect.kt deleted file mode 100644 index cec8845c164..00000000000 --- a/stripe/src/main/java/com/stripe/android/model/SourceRedirect.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.stripe.android.model - -import androidx.annotation.StringDef -import kotlinx.android.parcel.Parcelize - -/** - * Model for a [redirect](https://stripe.com/docs/api/sources/object#source_object-redirect) object - * in the Sources API. - */ -@Parcelize -data class SourceRedirect internal constructor( - val returnUrl: String?, - @param:Status @field:Status @get:Status val status: String?, - val url: String? -) : StripeModel { - @Retention(AnnotationRetention.SOURCE) - @StringDef(Status.PENDING, Status.SUCCEEDED, Status.FAILED, Status.NOT_REQUIRED) - internal annotation class Status { - companion object { - const val PENDING = "pending" - const val SUCCEEDED = "succeeded" - const val FAILED = "failed" - const val NOT_REQUIRED = "not_required" - } - } -} diff --git a/stripe/src/main/java/com/stripe/android/model/parsers/SourceCodeVerificationJsonParser.kt b/stripe/src/main/java/com/stripe/android/model/parsers/SourceCodeVerificationJsonParser.kt deleted file mode 100644 index 0d4d129d427..00000000000 --- a/stripe/src/main/java/com/stripe/android/model/parsers/SourceCodeVerificationJsonParser.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.stripe.android.model.parsers - -import com.stripe.android.model.SourceCodeVerification -import com.stripe.android.model.StripeJsonUtils.optString -import org.json.JSONObject - -internal class SourceCodeVerificationJsonParser : ModelJsonParser { - override fun parse(json: JSONObject): SourceCodeVerification { - return SourceCodeVerification( - json.optInt(FIELD_ATTEMPTS_REMAINING, INVALID_ATTEMPTS_REMAINING), - asStatus(optString(json, FIELD_STATUS)) - ) - } - - private companion object { - private const val FIELD_ATTEMPTS_REMAINING = "attempts_remaining" - private const val FIELD_STATUS = "status" - private const val INVALID_ATTEMPTS_REMAINING = -1 - - @SourceCodeVerification.Status - private fun asStatus(stringStatus: String?): String? { - return when (stringStatus) { - SourceCodeVerification.Status.PENDING -> SourceCodeVerification.Status.PENDING - SourceCodeVerification.Status.SUCCEEDED -> SourceCodeVerification.Status.SUCCEEDED - SourceCodeVerification.Status.FAILED -> SourceCodeVerification.Status.FAILED - else -> null - } - } - } -} diff --git a/stripe/src/main/java/com/stripe/android/model/parsers/SourceJsonParser.kt b/stripe/src/main/java/com/stripe/android/model/parsers/SourceJsonParser.kt index e1325f85e03..c47abad8c39 100644 --- a/stripe/src/main/java/com/stripe/android/model/parsers/SourceJsonParser.kt +++ b/stripe/src/main/java/com/stripe/android/model/parsers/SourceJsonParser.kt @@ -17,6 +17,85 @@ internal class SourceJsonParser : ModelJsonParser { } } + internal class RedirectJsonParser : ModelJsonParser { + override fun parse(json: JSONObject): Source.Redirect { + return Source.Redirect( + returnUrl = optString(json, FIELD_RETURN_URL), + status = Source.Redirect.Status.fromCode(optString(json, FIELD_STATUS)), + url = optString(json, FIELD_URL) + ) + } + + internal companion object { + private const val FIELD_RETURN_URL = "return_url" + private const val FIELD_STATUS = "status" + private const val FIELD_URL = "url" + } + } + + internal class CodeVerificationJsonParser : ModelJsonParser { + override fun parse(json: JSONObject): Source.CodeVerification { + return Source.CodeVerification( + attemptsRemaining = json.optInt(FIELD_ATTEMPTS_REMAINING, INVALID_ATTEMPTS_REMAINING), + status = Source.CodeVerification.Status.fromCode(optString(json, FIELD_STATUS)) + ) + } + + private companion object { + private const val FIELD_ATTEMPTS_REMAINING = "attempts_remaining" + private const val FIELD_STATUS = "status" + private const val INVALID_ATTEMPTS_REMAINING = -1 + } + } + + internal class ReceiverJsonParser : ModelJsonParser { + override fun parse(json: JSONObject): Source.Receiver { + return Source.Receiver( + optString(json, FIELD_ADDRESS), + json.optLong(FIELD_AMOUNT_CHARGED), + json.optLong(FIELD_AMOUNT_RECEIVED), + json.optLong(FIELD_AMOUNT_RETURNED) + ) + } + + private companion object { + private const val FIELD_ADDRESS = "address" + private const val FIELD_AMOUNT_CHARGED = "amount_charged" + private const val FIELD_AMOUNT_RECEIVED = "amount_received" + private const val FIELD_AMOUNT_RETURNED = "amount_returned" + } + } + + internal class OwnerJsonParser : ModelJsonParser { + override fun parse(json: JSONObject): Source.Owner { + return Source.Owner( + address = json.optJSONObject(FIELD_ADDRESS)?.let { + AddressJsonParser().parse(it) + }, + email = StripeJsonUtils.optString(json, FIELD_EMAIL), + name = StripeJsonUtils.optString(json, FIELD_NAME), + phone = StripeJsonUtils.optString(json, FIELD_PHONE), + verifiedAddress = json.optJSONObject(FIELD_VERIFIED_ADDRESS)?.let { + AddressJsonParser().parse(it) + }, + verifiedEmail = StripeJsonUtils.optString(json, FIELD_VERIFIED_EMAIL), + verifiedName = StripeJsonUtils.optString(json, FIELD_VERIFIED_NAME), + verifiedPhone = StripeJsonUtils.optString(json, FIELD_VERIFIED_PHONE) + ) + } + + private companion object { + private const val FIELD_ADDRESS = "address" + private const val FIELD_EMAIL = "email" + private const val FIELD_NAME = "name" + private const val FIELD_PHONE = "phone" + private const val FIELD_VERIFIED_ADDRESS = "verified_address" + private const val FIELD_VERIFIED_EMAIL = "verified_email" + private const val FIELD_VERIFIED_NAME = "verified_name" + private const val FIELD_VERIFIED_PHONE = "verified_phone" + } + } + internal class KlarnaJsonParser : ModelJsonParser { override fun parse(json: JSONObject): Source.Klarna { return Source.Klarna( @@ -132,7 +211,7 @@ internal class SourceJsonParser : ModelJsonParser { ), created = StripeJsonUtils.optLong(jsonObject, FIELD_CREATED), currency = optString(jsonObject, FIELD_CURRENCY), - flow = asSourceFlow(optString(jsonObject, FIELD_FLOW)), + flow = Source.Flow.fromCode(optString(jsonObject, FIELD_FLOW)), isLiveMode = jsonObject.optBoolean(FIELD_LIVEMODE), metaData = StripeJsonUtils.jsonObjectToStringMap( jsonObject.optJSONObject(FIELD_METADATA) @@ -144,12 +223,12 @@ internal class SourceJsonParser : ModelJsonParser { SourceOrderJsonParser().parse(it) }, statementDescriptor = optString(jsonObject, FIELD_STATEMENT_DESCRIPTOR), - status = asSourceStatus(optString(jsonObject, FIELD_STATUS)), + status = Source.Status.fromCode(optString(jsonObject, FIELD_STATUS)), sourceTypeData = sourceTypeData, sourceTypeModel = sourceTypeModel, type = type, typeRaw = typeRaw, - usage = asUsage(optString(jsonObject, FIELD_USAGE)), + usage = Source.Usage.fromCode(optString(jsonObject, FIELD_USAGE)), _weChat = if (Source.SourceType.WECHAT == type) { WeChatJsonParser().parse( jsonObject.optJSONObject(FIELD_WECHAT) ?: JSONObject() @@ -178,22 +257,22 @@ internal class SourceJsonParser : ModelJsonParser { val model: StripeModel? = when (key) { FIELD_CODE_VERIFICATION -> { jsonObject.optJSONObject(FIELD_CODE_VERIFICATION)?.let { - SourceCodeVerificationJsonParser().parse(it) + CodeVerificationJsonParser().parse(it) } } FIELD_OWNER -> { jsonObject.optJSONObject(FIELD_OWNER)?.let { - SourceOwnerJsonParser().parse(it) + OwnerJsonParser().parse(it) } } FIELD_RECEIVER -> { jsonObject.optJSONObject(FIELD_RECEIVER)?.let { - SourceReceiverJsonParser().parse(it) + ReceiverJsonParser().parse(it) } } FIELD_REDIRECT -> { jsonObject.optJSONObject(FIELD_REDIRECT)?.let { - SourceRedirectJsonParser().parse(it) + RedirectJsonParser().parse(it) } } Source.SourceType.CARD -> { @@ -214,18 +293,6 @@ internal class SourceJsonParser : ModelJsonParser { return model as? T } - @Source.SourceStatus - private fun asSourceStatus(sourceStatus: String?): String? { - return when (sourceStatus) { - Source.SourceStatus.PENDING -> Source.SourceStatus.PENDING - Source.SourceStatus.CHARGEABLE -> Source.SourceStatus.CHARGEABLE - Source.SourceStatus.CONSUMED -> Source.SourceStatus.CONSUMED - Source.SourceStatus.CANCELED -> Source.SourceStatus.CANCELED - Source.SourceStatus.FAILED -> Source.SourceStatus.FAILED - else -> null - } - } - @Source.SourceType @JvmStatic fun asSourceType(sourceType: String?): String { @@ -247,25 +314,5 @@ internal class SourceJsonParser : ModelJsonParser { else -> Source.SourceType.UNKNOWN } } - - @Source.Usage - private fun asUsage(usage: String?): String? { - return when (usage) { - Source.Usage.REUSABLE -> Source.Usage.REUSABLE - Source.Usage.SINGLE_USE -> Source.Usage.SINGLE_USE - else -> null - } - } - - @Source.SourceFlow - private fun asSourceFlow(sourceFlow: String?): String? { - return when (sourceFlow) { - Source.SourceFlow.REDIRECT -> Source.SourceFlow.REDIRECT - Source.SourceFlow.RECEIVER -> Source.SourceFlow.RECEIVER - Source.SourceFlow.CODE_VERIFICATION -> Source.SourceFlow.CODE_VERIFICATION - Source.SourceFlow.NONE -> Source.SourceFlow.NONE - else -> null - } - } } } diff --git a/stripe/src/main/java/com/stripe/android/model/parsers/SourceOwnerJsonParser.kt b/stripe/src/main/java/com/stripe/android/model/parsers/SourceOwnerJsonParser.kt index ade33b93c4d..a65a12d333c 100644 --- a/stripe/src/main/java/com/stripe/android/model/parsers/SourceOwnerJsonParser.kt +++ b/stripe/src/main/java/com/stripe/android/model/parsers/SourceOwnerJsonParser.kt @@ -1,48 +1,35 @@ package com.stripe.android.model.parsers -import com.stripe.android.model.SourceOwner +import com.stripe.android.model.Source import com.stripe.android.model.StripeJsonUtils import org.json.JSONObject -internal class SourceOwnerJsonParser : ModelJsonParser { - override fun parse(json: JSONObject): SourceOwner { - val address = json.optJSONObject(FIELD_ADDRESS)?.let { - AddressJsonParser().parse(it) - } - - val email = StripeJsonUtils.optString(json, FIELD_EMAIL) - val name = StripeJsonUtils.optString(json, FIELD_NAME) - val phone = StripeJsonUtils.optString(json, FIELD_PHONE) - - val verifiedAddress = json.optJSONObject(FIELD_VERIFIED_ADDRESS)?.let { - AddressJsonParser().parse(it) - } - - val verifiedEmail = StripeJsonUtils.optString(json, FIELD_VERIFIED_EMAIL) - val verifiedName = StripeJsonUtils.optString(json, FIELD_VERIFIED_NAME) - val verifiedPhone = StripeJsonUtils.optString(json, FIELD_VERIFIED_PHONE) - - return SourceOwner( - address, - email, - name, - phone, - verifiedAddress, - verifiedEmail, - verifiedName, - verifiedPhone +internal class SourceOwnerJsonParser : ModelJsonParser { + override fun parse(json: JSONObject): Source.Owner { + return Source.Owner( + address = json.optJSONObject(FIELD_ADDRESS)?.let { + AddressJsonParser().parse(it) + }, + email = StripeJsonUtils.optString(json, FIELD_EMAIL), + name = StripeJsonUtils.optString(json, FIELD_NAME), + phone = StripeJsonUtils.optString(json, FIELD_PHONE), + verifiedAddress = json.optJSONObject(FIELD_VERIFIED_ADDRESS)?.let { + AddressJsonParser().parse(it) + }, + verifiedEmail = StripeJsonUtils.optString(json, FIELD_VERIFIED_EMAIL), + verifiedName = StripeJsonUtils.optString(json, FIELD_VERIFIED_NAME), + verifiedPhone = StripeJsonUtils.optString(json, FIELD_VERIFIED_PHONE) ) } private companion object { - private const val VERIFIED = "verified_" private const val FIELD_ADDRESS = "address" private const val FIELD_EMAIL = "email" private const val FIELD_NAME = "name" private const val FIELD_PHONE = "phone" - private const val FIELD_VERIFIED_ADDRESS = VERIFIED + FIELD_ADDRESS - private const val FIELD_VERIFIED_EMAIL = VERIFIED + FIELD_EMAIL - private const val FIELD_VERIFIED_NAME = VERIFIED + FIELD_NAME - private const val FIELD_VERIFIED_PHONE = VERIFIED + FIELD_PHONE + private const val FIELD_VERIFIED_ADDRESS = "verified_address" + private const val FIELD_VERIFIED_EMAIL = "verified_email" + private const val FIELD_VERIFIED_NAME = "verified_name" + private const val FIELD_VERIFIED_PHONE = "verified_phone" } } diff --git a/stripe/src/main/java/com/stripe/android/model/parsers/SourceReceiverJsonParser.kt b/stripe/src/main/java/com/stripe/android/model/parsers/SourceReceiverJsonParser.kt deleted file mode 100644 index 637c239c50a..00000000000 --- a/stripe/src/main/java/com/stripe/android/model/parsers/SourceReceiverJsonParser.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.stripe.android.model.parsers - -import com.stripe.android.model.SourceReceiver -import com.stripe.android.model.StripeJsonUtils -import org.json.JSONObject - -internal class SourceReceiverJsonParser : ModelJsonParser { - override fun parse(json: JSONObject): SourceReceiver { - return SourceReceiver( - StripeJsonUtils.optString(json, FIELD_ADDRESS), - json.optLong(FIELD_AMOUNT_CHARGED), - json.optLong(FIELD_AMOUNT_RECEIVED), - json.optLong(FIELD_AMOUNT_RETURNED) - ) - } - - private companion object { - private const val FIELD_ADDRESS = "address" - private const val FIELD_AMOUNT_CHARGED = "amount_charged" - private const val FIELD_AMOUNT_RECEIVED = "amount_received" - private const val FIELD_AMOUNT_RETURNED = "amount_returned" - } -} diff --git a/stripe/src/main/java/com/stripe/android/model/parsers/SourceRedirectJsonParser.kt b/stripe/src/main/java/com/stripe/android/model/parsers/SourceRedirectJsonParser.kt deleted file mode 100644 index 850e9d95274..00000000000 --- a/stripe/src/main/java/com/stripe/android/model/parsers/SourceRedirectJsonParser.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.stripe.android.model.parsers - -import androidx.annotation.VisibleForTesting -import com.stripe.android.model.SourceRedirect -import com.stripe.android.model.StripeJsonUtils.optString -import org.json.JSONObject - -internal class SourceRedirectJsonParser : ModelJsonParser { - override fun parse(json: JSONObject): SourceRedirect { - return SourceRedirect( - returnUrl = optString(json, FIELD_RETURN_URL), - status = asStatus(optString(json, FIELD_STATUS)), - url = optString(json, FIELD_URL) - ) - } - - internal companion object { - private const val FIELD_RETURN_URL = "return_url" - private const val FIELD_STATUS = "status" - private const val FIELD_URL = "url" - - @SourceRedirect.Status - @VisibleForTesting - internal fun asStatus(stringStatus: String?): String? { - return when (stringStatus) { - SourceRedirect.Status.PENDING -> SourceRedirect.Status.PENDING - SourceRedirect.Status.SUCCEEDED -> SourceRedirect.Status.SUCCEEDED - SourceRedirect.Status.FAILED -> SourceRedirect.Status.FAILED - SourceRedirect.Status.NOT_REQUIRED -> SourceRedirect.Status.NOT_REQUIRED - else -> null - } - } - } -} diff --git a/stripe/src/test/java/com/stripe/android/StripePaymentControllerTest.kt b/stripe/src/test/java/com/stripe/android/StripePaymentControllerTest.kt index e9908e303cb..8df5b6c10b3 100644 --- a/stripe/src/test/java/com/stripe/android/StripePaymentControllerTest.kt +++ b/stripe/src/test/java/com/stripe/android/StripePaymentControllerTest.kt @@ -713,7 +713,7 @@ class StripePaymentControllerTest { ) verify(sourceCallback).onSuccess(sourceArgumentCaptor.capture()) assertEquals( - Source.SourceStatus.CHARGEABLE, + Source.Status.Chargeable, sourceArgumentCaptor.firstValue.status ) @@ -725,7 +725,7 @@ class StripePaymentControllerTest { controller.startAuthenticateSource( host = host, source = SourceFixtures.SOURCE_WITH_SOURCE_ORDER.copy( - flow = Source.SourceFlow.NONE + flow = Source.Flow.None ), requestOptions = REQUEST_OPTIONS ) @@ -827,7 +827,7 @@ class StripePaymentControllerTest { callback: ApiResultCallback ) { callback.onSuccess( - SourceFixtures.SOURCE_CARD.copy(status = Source.SourceStatus.CHARGEABLE) + SourceFixtures.SOURCE_CARD.copy(status = Source.Status.Chargeable) ) } } diff --git a/stripe/src/test/java/com/stripe/android/StripeTest.java b/stripe/src/test/java/com/stripe/android/StripeTest.java index 4721ceec6d4..008e17e65d7 100644 --- a/stripe/src/test/java/com/stripe/android/StripeTest.java +++ b/stripe/src/test/java/com/stripe/android/StripeTest.java @@ -305,19 +305,20 @@ public void createSourceSynchronous_withAlipayReusableParams_passesIntegrationTe "usd", "Example Payer", "abc@def.com", - "stripe://start"); + "stripe://start" + ); final Source alipaySource = defaultStripe.createSourceSynchronous(alipayParams); assertNotNull(alipaySource); assertNotNull(alipaySource.getId()); assertNotNull(alipaySource.getClientSecret()); assertEquals(Source.SourceType.ALIPAY, alipaySource.getType()); - assertEquals("redirect", alipaySource.getFlow()); + assertEquals(Source.Flow.Redirect, alipaySource.getFlow()); assertNotNull(alipaySource.getOwner()); assertEquals("Example Payer", alipaySource.getOwner().getName()); assertEquals("abc@def.com", alipaySource.getOwner().getEmail()); assertEquals("usd", alipaySource.getCurrency()); - assertEquals(Source.Usage.REUSABLE, alipaySource.getUsage()); + assertEquals(Source.Usage.Reusable, alipaySource.getUsage()); assertNotNull(alipaySource.getRedirect()); assertEquals("stripe://start", alipaySource.getRedirect().getReturnUrl()); } @@ -339,12 +340,12 @@ public void createSourceSynchronous_withAlipaySingleUseParams_passesIntegrationT assertNotNull(alipaySource.getAmount()); assertEquals(1000L, alipaySource.getAmount().longValue()); assertEquals(Source.SourceType.ALIPAY, alipaySource.getType()); - assertEquals("redirect", alipaySource.getFlow()); + assertEquals(Source.Flow.Redirect, alipaySource.getFlow()); assertNotNull(alipaySource.getOwner()); assertEquals("Example Payer", alipaySource.getOwner().getName()); assertEquals("abc@def.com", alipaySource.getOwner().getEmail()); assertEquals("usd", alipaySource.getCurrency()); - assertEquals(Source.Usage.SINGLE_USE, alipaySource.getUsage()); + assertEquals(Source.Usage.SingleUse, alipaySource.getUsage()); assertNotNull(alipaySource.getRedirect()); assertEquals("stripe://start", alipaySource.getRedirect().getReturnUrl()); } @@ -542,12 +543,12 @@ public void createSourceSynchronous_withP24Params_passesIntegrationTest() assertNotNull(p24Source.getId()); assertNotNull(p24Source.getClientSecret()); assertEquals(Source.SourceType.P24, p24Source.getType()); - assertEquals("redirect", p24Source.getFlow()); + assertEquals(Source.Flow.Redirect, p24Source.getFlow()); assertNotNull(p24Source.getOwner()); assertEquals("Example Payer", p24Source.getOwner().getName()); assertEquals("abc@def.com", p24Source.getOwner().getEmail()); assertEquals("eur", p24Source.getCurrency()); - assertEquals(Source.Usage.SINGLE_USE, p24Source.getUsage()); + assertEquals(Source.Usage.SingleUse, p24Source.getUsage()); assertNotNull(p24Source.getRedirect()); assertEquals("stripe://start", p24Source.getRedirect().getReturnUrl()); } @@ -861,13 +862,13 @@ public void createSourceFromTokenParams_withExtraParams_succeeds() assertNotNull(token); final Map map = new HashMap<>(); - map.put("usage", Source.Usage.SINGLE_USE); + map.put("usage", "single_use"); final SourceParams sourceParams = SourceParams.createSourceFromTokenParams(token.getId()) .setExtraParams(map); final Source source = stripe.createSourceSynchronous(sourceParams); assertNotNull(source); - assertNotNull(Source.Usage.SINGLE_USE, source.getUsage()); + assertEquals(Source.Usage.SingleUse, source.getUsage()); } @Test diff --git a/stripe/src/test/java/com/stripe/android/model/SourceCodeVerificationTest.kt b/stripe/src/test/java/com/stripe/android/model/SourceCodeVerificationTest.kt deleted file mode 100644 index 7b17d6bb931..00000000000 --- a/stripe/src/test/java/com/stripe/android/model/SourceCodeVerificationTest.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.stripe.android.model - -import kotlin.test.Test -import kotlin.test.assertEquals - -/** - * Test class for [SourceCodeVerification]. - */ -class SourceCodeVerificationTest { - - @Test - fun fromJsonString_createsObject() { - val codeVerification = SourceFixtures.SOURCE_CODE_VERIFICATION - assertEquals(3, codeVerification.attemptsRemaining) - assertEquals(SourceCodeVerification.Status.PENDING, codeVerification.status) - } -} diff --git a/stripe/src/test/java/com/stripe/android/model/SourceFixtures.kt b/stripe/src/test/java/com/stripe/android/model/SourceFixtures.kt index 050eea791f1..6ec710b3e21 100644 --- a/stripe/src/test/java/com/stripe/android/model/SourceFixtures.kt +++ b/stripe/src/test/java/com/stripe/android/model/SourceFixtures.kt @@ -2,10 +2,7 @@ package com.stripe.android.model import com.stripe.android.model.SourceOrderFixtures.SOURCE_ORDER_JSON import com.stripe.android.model.parsers.CustomerSourceJsonParser -import com.stripe.android.model.parsers.SourceCodeVerificationJsonParser import com.stripe.android.model.parsers.SourceJsonParser -import com.stripe.android.model.parsers.SourceReceiverJsonParser -import com.stripe.android.model.parsers.SourceRedirectJsonParser import org.json.JSONObject internal object SourceFixtures { @@ -208,7 +205,8 @@ internal object SourceFixtures { """.trimIndent() ) - val SOURCE_REDIRECT = SourceRedirectJsonParser().parse(SOURCE_REDIRECT_JSON) + val REDIRECT = SourceJsonParser.RedirectJsonParser() + .parse(SOURCE_REDIRECT_JSON) private val SOURCE_CODE_VERIFICATION_JSON = JSONObject( """ @@ -220,7 +218,7 @@ internal object SourceFixtures { ) val SOURCE_CODE_VERIFICATION = - SourceCodeVerificationJsonParser().parse(SOURCE_CODE_VERIFICATION_JSON) + SourceJsonParser.CodeVerificationJsonParser().parse(SOURCE_CODE_VERIFICATION_JSON) private val SOURCE_RECEIVER_JSON = JSONObject( """ @@ -233,7 +231,8 @@ internal object SourceFixtures { """.trimIndent() ) - val SOURCE_RECEIVER = SourceReceiverJsonParser().parse(SOURCE_RECEIVER_JSON) + val SOURCE_RECEIVER = SourceJsonParser.ReceiverJsonParser() + .parse(SOURCE_RECEIVER_JSON) val SOURCE_OWNER_WITH_NULLS = JSONObject( """ 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 bab717bd88d..a3f58f5f9e0 100644 --- a/stripe/src/test/java/com/stripe/android/model/SourceParamsTest.kt +++ b/stripe/src/test/java/com/stripe/android/model/SourceParamsTest.kt @@ -21,7 +21,7 @@ class SourceParamsTest { ) assertEquals(Source.SourceType.ALIPAY, params.type) - assertEquals(Source.Usage.REUSABLE, params.usage) + assertEquals(Source.Usage.Reusable, params.usage) assertNull(params.amount) assertEquals("usd", params.currency) assertEquals(RETURN_URL, params.returnUrl) @@ -40,7 +40,7 @@ class SourceParamsTest { ) assertEquals(Source.SourceType.ALIPAY, params.type) - assertEquals(Source.Usage.REUSABLE, params.usage) + assertEquals(Source.Usage.Reusable, params.usage) assertNull(params.amount) assertEquals("cad", params.currency) assertEquals(RETURN_URL, params.returnUrl) diff --git a/stripe/src/test/java/com/stripe/android/model/SourceReceiverTest.kt b/stripe/src/test/java/com/stripe/android/model/SourceReceiverTest.kt deleted file mode 100644 index 88fe7db046c..00000000000 --- a/stripe/src/test/java/com/stripe/android/model/SourceReceiverTest.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.stripe.android.model - -import kotlin.test.Test -import kotlin.test.assertEquals - -/** - * Test class for [SourceReceiver]. - */ -class SourceReceiverTest { - - @Test - fun fromJson_createsExpectedObject() { - val sourceReceiver = SourceFixtures.SOURCE_RECEIVER - assertEquals("test_1MBhWS3uv4ynCfQXF3xQjJkzFPukr4K56N", sourceReceiver.address) - assertEquals(10, sourceReceiver.amountCharged) - assertEquals(20, sourceReceiver.amountReceived) - assertEquals(30, sourceReceiver.amountReturned) - } -} diff --git a/stripe/src/test/java/com/stripe/android/model/parsers/SourceJsonParserTest.kt b/stripe/src/test/java/com/stripe/android/model/parsers/SourceJsonParserTest.kt index 9db97131f70..122ea5759f2 100644 --- a/stripe/src/test/java/com/stripe/android/model/parsers/SourceJsonParserTest.kt +++ b/stripe/src/test/java/com/stripe/android/model/parsers/SourceJsonParserTest.kt @@ -1,14 +1,16 @@ package com.stripe.android.model.parsers import com.google.common.truth.Truth.assertThat +import com.stripe.android.model.Address import com.stripe.android.model.Source import com.stripe.android.model.SourceFixtures +import kotlin.test.assertEquals import org.junit.Test class SourceJsonParserTest { @Test - fun parse_shouldReturnExpectedObject() { + fun `should parse Klarna correctly`() { assertThat(SourceFixtures.KLARNA.klarna) .isEqualTo( Source.Klarna( @@ -33,4 +35,89 @@ class SourceJsonParserTest { ) ) } + + @Test + fun `should parse Redirect correctly`() { + assertThat(SourceFixtures.REDIRECT) + .isEqualTo( + Source.Redirect( + returnUrl = "https://google.com", + status = Source.Redirect.Status.Succeeded, + url = "examplecompany://redirect-link" + ) + ) + } + + @Test + fun `should parse CodeVertification correctly`() { + val codeVerification = SourceFixtures.SOURCE_CODE_VERIFICATION + assertEquals(3, codeVerification.attemptsRemaining) + assertEquals(Source.CodeVerification.Status.Pending, codeVerification.status) + } + + @Test + fun `should parse Receiver correctly`() { + assertThat(SourceFixtures.SOURCE_RECEIVER) + .isEqualTo( + Source.Receiver( + address = "test_1MBhWS3uv4ynCfQXF3xQjJkzFPukr4K56N", + amountCharged = 10, + amountReceived = 20, + amountReturned = 30 + ) + ) + } + + @Test + fun `should parse Owner with verified fields correctly`() { + assertThat( + SourceJsonParser.OwnerJsonParser() + .parse(SourceFixtures.SOURCE_OWNER_WITHOUT_NULLS) + ).isEqualTo( + Source.Owner( + address = Address( + line1 = "123 Market St", + line2 = "#345", + city = "San Francisco", + state = "CA", + country = "US", + postalCode = "94107" + ), + email = "jenny.rosen@example.com", + name = "Jenny Rosen", + phone = "4158675309", + verifiedAddress = Address( + line1 = "123 Market St", + line2 = "#345", + city = "San Francisco", + state = "CA", + country = "US", + postalCode = "94107" + ), + verifiedEmail = "jenny.rosen@example.com", + verifiedName = "Jenny Rosen", + verifiedPhone = "4158675309" + + ) + ) + } + + @Test + fun `should parse Owner without verified fields correctly`() { + assertThat( + SourceJsonParser.OwnerJsonParser() + .parse(SourceFixtures.SOURCE_OWNER_WITH_NULLS) + ).isEqualTo( + Source.Owner( + address = null, + email = "jenny.rosen@example.com", + name = "Jenny Rosen", + phone = "4158675309", + verifiedAddress = null, + verifiedEmail = null, + verifiedName = null, + verifiedPhone = null + ) + ) + } } diff --git a/stripe/src/test/java/com/stripe/android/model/parsers/SourceOwnerJsonParserTest.kt b/stripe/src/test/java/com/stripe/android/model/parsers/SourceOwnerJsonParserTest.kt deleted file mode 100644 index 8e6373c54a6..00000000000 --- a/stripe/src/test/java/com/stripe/android/model/parsers/SourceOwnerJsonParserTest.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.stripe.android.model.parsers - -import com.stripe.android.model.SourceFixtures -import kotlin.test.Test -import kotlin.test.assertNotNull - -class SourceOwnerJsonParserTest { - @Test - fun parse_withoutNulls_isNotNull() { - assertNotNull(SourceOwnerJsonParser().parse(SourceFixtures.SOURCE_OWNER_WITHOUT_NULLS)) - } - - @Test - fun parse_withNulls_IsNotNull() { - assertNotNull(SourceOwnerJsonParser().parse(SourceFixtures.SOURCE_OWNER_WITH_NULLS)) - } -} diff --git a/stripe/src/test/java/com/stripe/android/model/parsers/SourceRedirectJsonParserTest.kt b/stripe/src/test/java/com/stripe/android/model/parsers/SourceRedirectJsonParserTest.kt deleted file mode 100644 index 684ea823b3a..00000000000 --- a/stripe/src/test/java/com/stripe/android/model/parsers/SourceRedirectJsonParserTest.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.stripe.android.model.parsers - -import com.stripe.android.model.SourceFixtures -import com.stripe.android.model.SourceRedirect -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertNotNull -import kotlin.test.assertNull - -class SourceRedirectJsonParserTest { - @Test - fun asStatus() { - assertNotNull(SourceFixtures.SOURCE_REDIRECT) - - assertEquals(SourceRedirect.Status.FAILED, - SourceRedirectJsonParser.asStatus("failed")) - assertEquals(SourceRedirect.Status.SUCCEEDED, - SourceRedirectJsonParser.asStatus("succeeded")) - assertEquals(SourceRedirect.Status.PENDING, - SourceRedirectJsonParser.asStatus("pending")) - assertEquals(SourceRedirect.Status.NOT_REQUIRED, - SourceRedirectJsonParser.asStatus("not_required")) - assertNull(SourceRedirectJsonParser.asStatus("something_else")) - } -}