Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions affirm/src/main/java/com/affirm/android/AffirmUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@

import static com.affirm.android.AffirmColor.AFFIRM_COLOR_TYPE_BLUE;
import static com.affirm.android.AffirmColor.AFFIRM_COLOR_TYPE_BLUE_BLACK;
import static com.affirm.android.AffirmConstants.LOGO_PLACEHOLDER;
import static com.affirm.android.AffirmConstants.PLACEHOLDER_END;
import static com.affirm.android.AffirmConstants.PLACEHOLDER_START;
import static com.affirm.android.AffirmLogoType.AFFIRM_DISPLAY_TYPE_TEXT;

public final class AffirmUtils {

private static final Pattern LOGO_PATTERN =
Pattern.compile("\\baffirm\\b", Pattern.CASE_INSENSITIVE);
Pattern.compile(Pattern.quote(LOGO_PLACEHOLDER));

private AffirmUtils() {
}
Expand Down Expand Up @@ -134,10 +135,11 @@ private static SpannableString getSpannable(
@NonNull AffirmColor affirmColor,
@NonNull Resources resources
) {
SpannableString spannable = new SpannableString(template);
if (logoDrawable == null) {
return spannable;
String text = LOGO_PATTERN.matcher(template).replaceAll("Affirm");
return new SpannableString(text);
}
SpannableString spannable = new SpannableString(template);
Matcher matcher = LOGO_PATTERN.matcher(template);
while (matcher.find()) {
int start = matcher.start();
Expand Down
4 changes: 2 additions & 2 deletions affirm/src/main/java/com/affirm/android/PromoRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ private void handleSuccessResponse(PromoResponse promoResponse) {

final String promoMessage = isHtmlStyle
? htmlPromo
: promo.replace(LOGO_PLACEHOLDER, "affirm");
final String promoDescription = promo.replace(LOGO_PLACEHOLDER, "affirm");
: promo;
Comment thread
sidharth-pardeshi marked this conversation as resolved.
final String promoDescription = promo.replace(LOGO_PLACEHOLDER, "Affirm");
if (TextUtils.isEmpty(promoMessage)) {
handleErrorResponse(new Exception("Promo message is null or empty!"));
} else {
Expand Down
116 changes: 115 additions & 1 deletion affirm/src/test/java/com/affirm/android/AffirmUtilsTest.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,46 @@
package com.affirm.android;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.text.SpannableString;
import android.text.style.ImageSpan;

import com.google.common.collect.ImmutableMap;
import com.google.common.truth.Truth;

import org.junit.Before;
import org.junit.Test;

import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.math.BigDecimal;
import java.util.Map;

import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(RobolectricTestRunner.class)
public class AffirmUtilsTest {

private Context mockContext;

@Before
public void setUp() {
// Create a mock Context and Resources so that drawable loading returns
// a fake Drawable instead of trying to inflate vector XML resources,
// which Robolectric cannot always resolve.
mockContext = mock(Context.class);
Resources mockResources = mock(Resources.class);
Drawable mockDrawable = mock(Drawable.class);

when(mockContext.getResources()).thenReturn(mockResources);
when(mockResources.getDrawable(anyInt())).thenReturn(mockDrawable);
when(mockDrawable.mutate()).thenReturn(mockDrawable);
when(mockDrawable.getIntrinsicWidth()).thenReturn(100);
when(mockDrawable.getIntrinsicHeight()).thenReturn(40);
}

@Test
public void convertToAffirmAmounts() {
Truth.assertThat(AffirmUtils.decimalDollarsToIntegerCents(BigDecimal.valueOf(15.5))).isEqualTo(1550);
Expand All @@ -25,4 +56,87 @@ public void replacePlaceHolders() {
Truth.assertThat(AffirmUtils.replacePlaceholders(text, map))
.contains("I paid 55 to jan last monday");
}

@Test
public void createSpannable_onlyReplacesPlaceholderWithLogo() {
// Template contains one {affirm_logo} placeholder and one plain text "Affirm"
String template = "Pay over time with {affirm_logo}. Affirm is a form of credit.";

SpannableString result = AffirmUtils.createSpannableForText(
template,
14f,
AffirmLogoType.AFFIRM_DISPLAY_TYPE_LOGO,
AffirmColor.AFFIRM_COLOR_TYPE_BLUE,
mockContext
);

// Only 1 ImageSpan should be present (for the placeholder), not 2
ImageSpan[] spans = result.getSpans(0, result.length(), ImageSpan.class);
Truth.assertThat(spans).hasLength(1);

// The plain text "Affirm" should remain as text in the output
String resultText = result.toString();
Truth.assertThat(resultText).contains("Affirm is a form of credit.");
}

@Test
public void createSpannable_plainTextAffirmNotReplacedWithLogo() {
// Template with ONLY plain text "Affirm" and no placeholder
String template = "Affirm offers great financing options.";

SpannableString result = AffirmUtils.createSpannableForText(
template,
14f,
AffirmLogoType.AFFIRM_DISPLAY_TYPE_LOGO,
AffirmColor.AFFIRM_COLOR_TYPE_BLUE,
mockContext
);

// No ImageSpan should be present since there is no {affirm_logo} placeholder
ImageSpan[] spans = result.getSpans(0, result.length(), ImageSpan.class);
Truth.assertThat(spans).hasLength(0);

// The text should remain unchanged
Truth.assertThat(result.toString()).isEqualTo(template);
}

@Test
public void createSpannable_multiplePlaceholdersAllReplaced() {
// Template with multiple {affirm_logo} placeholders
String template = "Pay with {affirm_logo} or learn about {affirm_logo} financing.";

SpannableString result = AffirmUtils.createSpannableForText(
template,
14f,
AffirmLogoType.AFFIRM_DISPLAY_TYPE_LOGO,
AffirmColor.AFFIRM_COLOR_TYPE_BLUE,
mockContext
);

// Both placeholders should get replaced with logo ImageSpans
ImageSpan[] spans = result.getSpans(0, result.length(), ImageSpan.class);
Truth.assertThat(spans).hasLength(2);
}

@Test
public void createSpannable_textDisplayType_noLogosInserted() {
// When display type is TEXT, no logos should be inserted even with placeholders
String template = "Pay over time with {affirm_logo}.";

SpannableString result = AffirmUtils.createSpannableForText(
template,
14f,
AffirmLogoType.AFFIRM_DISPLAY_TYPE_TEXT,
AffirmColor.AFFIRM_COLOR_TYPE_BLUE,
mockContext
);

ImageSpan[] spans = result.getSpans(0, result.length(), ImageSpan.class);
Truth.assertThat(spans).hasLength(0);

// The placeholder should be replaced with text "Affirm", not left as raw {affirm_logo}
String resultText = result.toString();
Truth.assertThat(resultText).doesNotContain("{affirm_logo}");
Truth.assertThat(resultText).contains("Pay over time with Affirm.");
}
}
2 changes: 1 addition & 1 deletion samples-java/src/main/java/com/affirm/samples/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

public class Config {

public static final String PUBLIC_KEY = "3HCWTVU5BYWZB9RK";
public static final String PUBLIC_KEY = "Y8CQXFF044903JC0";

public static final String MODAL_ID = "5LNMQ33SEUYHLNUC";
}
Loading