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.Arrays;
import java.util.Collections;
import java.util.HashSet;
import co.smartreceipts.android.purchases.model.ConsumablePurchase;
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.assertNull;
import static org.junit.Assert.assertTrue;
@RunWith(RobolectricTestRunner.class)
public class PlusPurchaseWalletTest {
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
PlusPurchaseWallet plusPurchaseWallet;
SharedPreferences preferences;
ManagedProduct managedProduct;
ManagedProduct plusManagedProduct;
@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.OcrScans50.getSku());
purchaseData.put("purchaseTime", 1234567890123L);
purchaseData.put("purchaseState", 0);
purchaseData.put("developerPayload", "1234567890");
purchaseData.put("purchaseToken", PURCHASE_TOKEN);
this.purchaseData = purchaseData.toString();
managedProduct = new ConsumablePurchase(InAppPurchase.OcrScans50, this.purchaseData, PURCHASE_TOKEN, IN_APP_DATA_SIGNATURE);
plusManagedProduct = new Subscription(InAppPurchase.SmartReceiptsPlus, "", "", "");
preferences = PreferenceManager.getDefaultSharedPreferences(RuntimeEnvironment.application);
preferences.edit().putString(TEST, TEST).apply();
plusPurchaseWallet = new PlusPurchaseWallet(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() {
assertTrue(plusPurchaseWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertEquals(plusManagedProduct, plusPurchaseWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertFalse(plusPurchaseWallet.hasActivePurchase(InAppPurchase.OcrScans50));
assertNull(plusPurchaseWallet.getManagedProduct(InAppPurchase.OcrScans50));
assertEquals(plusPurchaseWallet.getActivePurchases(), Collections.singleton(plusManagedProduct));
}
@Test
public void singlePurchase() {
plusPurchaseWallet.addPurchaseToWallet(managedProduct);
assertTrue(plusPurchaseWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertEquals(plusManagedProduct, plusPurchaseWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertTrue(plusPurchaseWallet.hasActivePurchase(InAppPurchase.OcrScans50));
assertEquals(managedProduct, plusPurchaseWallet.getManagedProduct(InAppPurchase.OcrScans50));
assertEquals(plusPurchaseWallet.getActivePurchases(), new HashSet<>(Arrays.asList(managedProduct, plusManagedProduct)));
assertEquals(preferences.getStringSet("key_sku_set", Collections.<String>emptySet()), Collections.singleton(InAppPurchase.OcrScans50.getSku()));
assertEquals(preferences.getString("ocr_purchase_1_purchaseData", null), this.purchaseData);
assertEquals(preferences.getString("ocr_purchase_1_inAppDataSignature", null), IN_APP_DATA_SIGNATURE);
}
@Test
public void updatePurchases() {
plusPurchaseWallet.updatePurchasesInWallet(Collections.singleton(managedProduct));
assertTrue(plusPurchaseWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertTrue(plusPurchaseWallet.hasActivePurchase(InAppPurchase.OcrScans50));
assertEquals(plusPurchaseWallet.getActivePurchases(), new HashSet<>(Arrays.asList(managedProduct, plusManagedProduct)));
assertEquals(preferences.getStringSet("key_sku_set", Collections.<String>emptySet()), Collections.singleton(InAppPurchase.OcrScans50.getSku()));
assertEquals(preferences.getString("ocr_purchase_1_purchaseData", null), this.purchaseData);
assertEquals(preferences.getString("ocr_purchase_1_inAppDataSignature", null), IN_APP_DATA_SIGNATURE);
}
@Test
public void removeMissingPurchase() {
plusPurchaseWallet.removePurchaseFromWallet(InAppPurchase.OcrScans50);
assertTrue(plusPurchaseWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertEquals(plusManagedProduct, plusPurchaseWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertFalse(plusPurchaseWallet.hasActivePurchase(InAppPurchase.OcrScans50));
assertNull(plusPurchaseWallet.getManagedProduct(InAppPurchase.OcrScans50));
assertEquals(plusPurchaseWallet.getActivePurchases(), Collections.singleton(plusManagedProduct));
assertEquals(preferences.getStringSet("key_sku_set", Collections.<String>emptySet()), Collections.<String>emptySet());
assertFalse(preferences.contains("ocr_purchase_1_purchaseData"));
assertFalse(preferences.contains("ocr_purchase_1_inAppDataSignature"));
}
@Test
public void ensureAddedPurchaseIsPersistedAndPlusRemains() {
plusPurchaseWallet.addPurchaseToWallet(managedProduct);
final PurchaseWallet newWallet = new PlusPurchaseWallet(preferences);
assertTrue(newWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertEquals(plusManagedProduct, newWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertTrue(plusPurchaseWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertEquals(plusManagedProduct, plusPurchaseWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertTrue(newWallet.hasActivePurchase(InAppPurchase.OcrScans50));
assertEquals(managedProduct, newWallet.getManagedProduct(InAppPurchase.OcrScans50));
assertEquals(newWallet.getActivePurchases(), new HashSet<>(Arrays.asList(managedProduct, plusManagedProduct)));
assertTrue(plusPurchaseWallet.hasActivePurchase(InAppPurchase.OcrScans50));
assertEquals(managedProduct, plusPurchaseWallet.getManagedProduct(InAppPurchase.OcrScans50));
assertEquals(plusPurchaseWallet.getActivePurchases(), new HashSet<>(Arrays.asList(managedProduct, plusManagedProduct)));
assertEquals(preferences.getStringSet("key_sku_set", Collections.<String>emptySet()), Collections.singleton(InAppPurchase.OcrScans50.getSku()));
assertEquals(preferences.getString("ocr_purchase_1_purchaseData", null), this.purchaseData);
assertEquals(preferences.getString("ocr_purchase_1_inAppDataSignature", null), IN_APP_DATA_SIGNATURE);
}
@Test
public void ensureUpdatedPurchaseListIsPersistedAndPlusRemains() {
// First add it
plusPurchaseWallet.addPurchaseToWallet(managedProduct);
// Then revoke it
plusPurchaseWallet.updatePurchasesInWallet(Collections.<ManagedProduct>emptySet());
final PurchaseWallet newWallet = new PlusPurchaseWallet(preferences);
assertTrue(newWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertEquals(plusManagedProduct, newWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertTrue(plusPurchaseWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertEquals(plusManagedProduct, plusPurchaseWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertFalse(newWallet.hasActivePurchase(InAppPurchase.OcrScans50));
assertNull(newWallet.getManagedProduct(InAppPurchase.OcrScans50));
assertFalse(plusPurchaseWallet.hasActivePurchase(InAppPurchase.OcrScans50));
assertNull(plusPurchaseWallet.getManagedProduct(InAppPurchase.OcrScans50));
assertEquals(newWallet.getActivePurchases(), Collections.singleton(plusManagedProduct));
assertEquals(plusPurchaseWallet.getActivePurchases(), Collections.singleton(plusManagedProduct));
assertEquals(preferences.getStringSet("key_sku_set", Collections.<String>emptySet()), Collections.emptySet());
assertFalse(preferences.contains("ocr_purchase_1_purchaseData"));
assertFalse(preferences.contains("ocr_purchase_1_inAppDataSignature"));
}
@Test
public void ensureRemovedPurchaseIsPersisted() {
plusPurchaseWallet.addPurchaseToWallet(managedProduct);
plusPurchaseWallet.removePurchaseFromWallet(InAppPurchase.OcrScans50);
final PurchaseWallet newWallet = new PlusPurchaseWallet(preferences);
assertTrue(newWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertEquals(plusManagedProduct, newWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertTrue(plusPurchaseWallet.hasActivePurchase(InAppPurchase.SmartReceiptsPlus));
assertEquals(plusManagedProduct, plusPurchaseWallet.getManagedProduct(InAppPurchase.SmartReceiptsPlus));
assertFalse(newWallet.hasActivePurchase(InAppPurchase.OcrScans50));
assertNull(newWallet.getManagedProduct(InAppPurchase.OcrScans50));
assertFalse(plusPurchaseWallet.hasActivePurchase(InAppPurchase.OcrScans50));
assertNull(plusPurchaseWallet.getManagedProduct(InAppPurchase.OcrScans50));
assertEquals(newWallet.getActivePurchases(), Collections.singleton(plusManagedProduct));
assertEquals(plusPurchaseWallet.getActivePurchases(), Collections.singleton(plusManagedProduct));
assertEquals(preferences.getStringSet("key_sku_set", Collections.<String>emptySet()), Collections.emptySet());
assertFalse(preferences.contains("ocr_purchase_1_purchaseData"));
assertFalse(preferences.contains("ocr_purchase_1_inAppDataSignature"));
}
}