package co.smartreceipts.android.purchases.wallet;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import org.json.JSONObject;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.util.Collections;
import co.smartreceipts.android.purchases.model.InAppPurchase;
import co.smartreceipts.android.purchases.model.ManagedProduct;
import co.smartreceipts.android.purchases.model.Subscription;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@RunWith(RobolectricTestRunner.class)
public class DefaultPurchaseWalletTest {
private static final String TEST = "test";
private static final String PURCHASE_TOKEN = "012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689";
private static final String IN_APP_DATA_SIGNATURE = "012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689012345689ABCDEF012345689ABCDEF012345689ABCDEF012345689==";
private String purchaseData;
// Class under test
DefaultPurchaseWallet defaultPurchaseWallet;
SharedPreferences preferences;
ManagedProduct managedProduct;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
// https://developer.android.com/google/play/billing/billing_reference.html
final JSONObject purchaseData = new JSONObject();
purchaseData.put("autoRenewing", true);
purchaseData.put("orderId", "orderId");
purchaseData.put("packageName", "co.smartreceipts.android");
purchaseData.put("productId", InAppPurchase.SmartReceiptsPlus.getSku());
purchaseData.put("purchaseTime", 1234567890123L);
purchaseData.put("purchaseState", 0);
purchaseData.put("developerPayload", "1234567890");
purchaseData.put("purchaseToken", PURCHASE_TOKEN);
this.purchaseData = purchaseData.toString();
managedProduct = new Subscription(InAppPurchase.SmartReceiptsPlus, this.purchaseData, PURCHASE_TOKEN, IN_APP_DATA_SIGNATURE);
preferences = PreferenceManager.getDefaultSharedPreferences(RuntimeEnvironment.application);
preferences.edit().putString(TEST, TEST).apply();
defaultPurchaseWallet = new DefaultPurchaseWallet(preferences);
}
@After
public void tearDown() {
// Verify that we don't clear out everything then remove our test values
assertEquals(TEST, preferences.getString(TEST, null));
preferences.edit().clear().apply();
}
@Test
public void emptyPurchases() {
assertFalse(defaultPurchaseWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertNull(defaultPurchaseWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertEquals(defaultPurchaseWallet.getActivePurchases(), Collections.<ManagedProduct>emptySet());
}
@Test
public void singlePurchase() {
defaultPurchaseWallet.addPurchaseToWallet(managedProduct);
assertTrue(defaultPurchaseWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertEquals(managedProduct, defaultPurchaseWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertEquals(defaultPurchaseWallet.getActivePurchases(), Collections.singleton(managedProduct));
assertEquals(preferences.getStringSet("key_sku_set", Collections.<String>emptySet()), Collections.singleton(InAppPurchase.SmartReceiptsPlus.getSku()));
assertEquals(preferences.getString("pro_sku_3_purchaseData", null), purchaseData);
assertEquals(preferences.getString("pro_sku_3_inAppDataSignature", null), IN_APP_DATA_SIGNATURE);
}
@Test
public void updatePurchases() {
defaultPurchaseWallet.updatePurchasesInWallet(Collections.singleton(managedProduct));
assertTrue(defaultPurchaseWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertEquals(managedProduct, defaultPurchaseWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertEquals(defaultPurchaseWallet.getActivePurchases(), Collections.singleton(managedProduct));
assertEquals(preferences.getStringSet("key_sku_set", Collections.<String>emptySet()), Collections.singleton(InAppPurchase.SmartReceiptsPlus.getSku()));
assertEquals(preferences.getString("pro_sku_3_purchaseData", null), purchaseData);
assertEquals(preferences.getString("pro_sku_3_inAppDataSignature", null), IN_APP_DATA_SIGNATURE);
}
@Test
public void removeMissingPurchase() {
defaultPurchaseWallet.removePurchaseFromWallet(InAppPurchase.SmartReceiptsPlus);
assertFalse(defaultPurchaseWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertNull(defaultPurchaseWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertEquals(defaultPurchaseWallet.getActivePurchases(), Collections.<ManagedProduct>emptySet());
assertEquals(preferences.getStringSet("key_sku_set", Collections.<String>emptySet()), Collections.<String>emptySet());
assertFalse(preferences.contains("pro_sku_3_purchaseData"));
assertFalse(preferences.contains("pro_sku_3_inAppDataSignature"));
}
@Test
public void ensureAddedPurchaseIsPersisted() {
defaultPurchaseWallet.addPurchaseToWallet(managedProduct);
final PurchaseWallet newWallet = new DefaultPurchaseWallet(preferences);
assertTrue(newWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertTrue(defaultPurchaseWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertEquals(managedProduct, newWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertEquals(managedProduct, defaultPurchaseWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertEquals(newWallet.getActivePurchases(), Collections.singleton(managedProduct));
assertEquals(defaultPurchaseWallet.getActivePurchases(), Collections.singleton(managedProduct));
assertEquals(preferences.getStringSet("key_sku_set", Collections.<String>emptySet()), Collections.singleton(InAppPurchase.SmartReceiptsPlus.getSku()));
assertEquals(preferences.getString("pro_sku_3_purchaseData", null), purchaseData);
assertEquals(preferences.getString("pro_sku_3_inAppDataSignature", null), IN_APP_DATA_SIGNATURE);
}
@Test
public void ensureUpdatedPurchaseListIsPersisted() {
// First add it
defaultPurchaseWallet.addPurchaseToWallet(managedProduct);
// Then revoke it
defaultPurchaseWallet.updatePurchasesInWallet(Collections.<ManagedProduct>emptySet());
final PurchaseWallet newWallet = new DefaultPurchaseWallet(preferences);
assertFalse(newWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertFalse(defaultPurchaseWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertNull(newWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertNull(defaultPurchaseWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertEquals(newWallet.getActivePurchases(), Collections.<ManagedProduct>emptySet());
assertEquals(defaultPurchaseWallet.getActivePurchases(), Collections.<ManagedProduct>emptySet());
assertEquals(preferences.getStringSet("key_sku_set", Collections.<String>emptySet()), Collections.emptySet());
assertFalse(preferences.contains("pro_sku_3_purchaseData"));
assertFalse(preferences.contains("pro_sku_3_inAppDataSignature"));
}
@Test
public void ensureRemovedPurchaseIsPersisted() {
defaultPurchaseWallet.addPurchaseToWallet(managedProduct);
defaultPurchaseWallet.removePurchaseFromWallet(InAppPurchase.SmartReceiptsPlus);
final PurchaseWallet newWallet = new DefaultPurchaseWallet(preferences);
assertFalse(newWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertFalse(defaultPurchaseWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertNull(newWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertNull(defaultPurchaseWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertEquals(newWallet.getActivePurchases(), Collections.<ManagedProduct>emptySet());
assertEquals(defaultPurchaseWallet.getActivePurchases(), Collections.<ManagedProduct>emptySet());
assertEquals(preferences.getStringSet("key_sku_set", Collections.<String>emptySet()), Collections.emptySet());
assertFalse(preferences.contains("pro_sku_3_purchaseData"));
assertFalse(preferences.contains("pro_sku_3_inAppDataSignature"));
}
@Test
public void upgradeFrom_V_4_2_0_249_WhenWeDidNotPersistDataOrSignature() {
// Historically, we only used to save the sku set and not the token or signature
preferences.edit().putStringSet("key_sku_set", Collections.singleton(InAppPurchase.SmartReceiptsPlus.getSku())).apply();
final PurchaseWallet newWallet = new DefaultPurchaseWallet(preferences);
assertTrue(newWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
final ManagedProduct partialManagedProduct = newWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus);
assertNotNull(partialManagedProduct);
assertTrue(!partialManagedProduct.equals(managedProduct));
assertEquals(partialManagedProduct.getInAppPurchase(), InAppPurchase.SmartReceiptsPlus);
assertEquals(partialManagedProduct.getInAppDataSignature(), "");
assertEquals(partialManagedProduct.getPurchaseToken(), "");
assertEquals(partialManagedProduct.getPurchaseData(), "");
assertEquals(newWallet.getActivePurchases(), Collections.singleton(partialManagedProduct));
// Update from Google InAppBilling
newWallet.updatePurchasesInWallet(Collections.singleton(managedProduct));
// Verify that we've now save the extra params
assertEquals(preferences.getString("pro_sku_3_purchaseData", null), purchaseData);
assertEquals(preferences.getString("pro_sku_3_inAppDataSignature", null), IN_APP_DATA_SIGNATURE);
assertEquals(managedProduct, newWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertEquals(newWallet.getActivePurchases(), Collections.singleton(managedProduct));
}
}