Skip to content

Commit

Permalink
Refactor applyLinks add events to link,usbank,aubecs (stripe#3471)
Browse files Browse the repository at this point in the history
## Summary
Refactor applyLinks, add events to link,usbank,aubecs

## Motivation
Refactor was an old 'todo', which had an assert in 3 places. Moved this
to a single place.

## Testing
None

## Changelog
<!-- Is this a notable change that affects users? If so, add a line to
`CHANGELOG.md` and prefix the line with one of the following:
    - [Added] for new features.
    - [Changed] for changes in existing functionality.
    - [Deprecated] for soon-to-be removed features.
    - [Removed] for now removed features.
    - [Fixed] for any bug fixes.
    - [Security] in case of vulnerabilities.
-->
  • Loading branch information
wooj-stripe authored Apr 8, 2024
1 parent 9d4be40 commit aaabb02
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@
//

import Foundation
@_spi(STP) import StripeCore
@_spi(STP) import StripePaymentsUI

typealias STPTaggedSubstringCompletionBlock = (String?, NSRange) -> Void
typealias STPTaggedSubstringsCompletionBlock = (String, [String: NSValue]) -> Void
extension STPStringUtils {
enum Error: Swift.Error {
case tagMissing
}
/// Takes a string with the named html-style tags, removes the tags,
/// and then calls the completion block with the modified string and the range
/// in it that the tag would have enclosed.
Expand Down Expand Up @@ -136,4 +140,28 @@ extension STPStringUtils {

completion(modifiedString, tagsToRange)
}

class func applyLinksToString(template: String, links: [String: URL]) -> NSMutableAttributedString {
let formattedString = NSMutableAttributedString()
STPStringUtils.parseRanges(from: template, withTags: Set<String>(links.keys)) { string, matches in
formattedString.append(NSAttributedString(string: string))
for (tag, range) in matches {
guard range.rangeValue.location != NSNotFound else {
let errorAnalytic = ErrorAnalytic(event: .unexpectedPaymentSheetError,
error: Error.tagMissing,
additionalNonPIIParams: ["template": template,
"tag_missing": tag,
])
STPAnalyticsClient.sharedClient.log(analytic: errorAnalytic)
stpAssertionFailure("Tag '<\(tag)>' not found")
continue
}

if let url = links[tag] {
formattedString.addAttributes([.link: url], range: range.rangeValue)
}
}
}
return formattedString
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
// Copyright © 2022 Stripe, Inc. All rights reserved.
//

@_spi(STP) import StripeCore
@_spi(STP) import StripePaymentsUI
@_spi(STP) import StripeUICore

import UIKit

protocol LinkLegalTermsViewDelegate: AnyObject {
Expand Down Expand Up @@ -109,24 +111,7 @@ final class LinkLegalTermsView: UIView {
)
}
}()

let formattedString = NSMutableAttributedString()

STPStringUtils.parseRanges(from: string, withTags: Set<String>(links.keys)) { string, matches in
formattedString.append(NSAttributedString(string: string))

for (tag, range) in matches {
guard range.rangeValue.location != NSNotFound else {
assertionFailure("Tag '<\(tag)>' not found")
continue
}

if let url = links[tag] {
formattedString.addAttributes([.link: url], range: range.rangeValue)
}
}
}

let formattedString = STPStringUtils.applyLinksToString(template: string, links: links)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = LinkUI.lineSpacing(
fromRelativeHeight: Constants.lineHeight,
Expand All @@ -141,6 +126,9 @@ final class LinkLegalTermsView: UIView {
}

extension LinkLegalTermsView: UITextViewDelegate {
enum Error: Swift.Error {
case linkLegalTermsViewUITextViewDelegate
}

#if !canImport(CompositorServices)
func textView(
Expand All @@ -155,7 +143,11 @@ extension LinkLegalTermsView: UITextViewDelegate {
}

let handled = delegate?.legalTermsView(self, didTapOnLinkWithURL: URL) ?? false
assert(handled, "Link not handled by delegate")

let errorAnalytic = ErrorAnalytic(event: .unexpectedPaymentSheetError,
error: Error.linkLegalTermsViewUITextViewDelegate)
STPAnalyticsClient.sharedClient.log(analytic: errorAnalytic)
stpAssert(handled, "Link not handled by delegate")

// If not handled by the delegate, let the system handle the link.
return !handled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ final class USBankAccountPaymentMethodElement: Element {
&& configuration.defaultBillingDetails.name != nil
let hasDefaultEmail = configuration.billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod
&& configuration.defaultBillingDetails.email != nil

// Fail loudly: This is an integration error
assert(
(collectingName || hasDefaultName) && (collectingEmail || hasDefaultEmail),
"If name or email are not collected, they must be provided through defaults"
Expand Down Expand Up @@ -168,37 +170,18 @@ final class USBankAccountPaymentMethodElement: Element {
} else if case .paymentSheet = configuration, !linkedBank.instantlyVerified {
mandateText = String.init(format: Self.MicrodepositCopy, merchantName) + "\n" + mandateText
}
let formattedString = applyLinksToString(template: mandateText, links: links)
let formattedString = STPStringUtils.applyLinksToString(template: mandateText, links: links)
applyStyle(formattedString: formattedString, theme: theme)
return formattedString
}

class func attributedMandateTextSavedPaymentMethod(theme: ElementsUITheme = .default) -> NSMutableAttributedString {
let mandateText = Self.ContinueMandateText
let formattedString = applyLinksToString(template: mandateText, links: links)
let formattedString = STPStringUtils.applyLinksToString(template: mandateText, links: links)
applyStyle(formattedString: formattedString, theme: theme)
return formattedString
}

// TODO(wooj): Refactor this code to be common across multiple classes
private class func applyLinksToString(template: String, links: [String: URL]) -> NSMutableAttributedString {
let formattedString = NSMutableAttributedString()
STPStringUtils.parseRanges(from: template, withTags: Set<String>(links.keys)) { string, matches in
formattedString.append(NSAttributedString(string: string))
for (tag, range) in matches {
guard range.rangeValue.location != NSNotFound else {
assertionFailure("Tag '<\(tag)>' not found")
continue
}

if let url = links[tag] {
formattedString.addAttributes([.link: url], range: range.rangeValue)
}
}
}
return formattedString
}

private class func applyStyle(formattedString: NSMutableAttributedString, theme: ElementsUITheme = .default) {
let style = NSMutableParagraphStyle()
style.alignment = .center
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,25 +62,7 @@ final class AUBECSLegalTermsView: UIView {
"Legal text shown when using AUBECS."
)
let string = String(format: template, configuration.merchantDisplayName)

let formattedString = NSMutableAttributedString()

STPStringUtils.parseRanges(from: string, withTags: Set<String>(links.keys)) { string, matches in
formattedString.append(NSAttributedString(string: string))

for (tag, range) in matches {
guard range.rangeValue.location != NSNotFound else {
assertionFailure("Tag '<\(tag)>' not found")
continue
}

if let url = links[tag] {
formattedString.addAttributes([.link: url], range: range.rangeValue)
}
}
}

return formattedString
return STPStringUtils.applyLinksToString(template: string, links: links)
}

}
Expand Down

0 comments on commit aaabb02

Please sign in to comment.