@SuppressWarnings("ThrowableInstanceNeverThrown") @Test public void initializeUploadFailsWith400CodeAndSmartReceiptsApiExceptionWithDuplicatePurchaseError() { final SmartReceiptsApiErrorResponse errorResponse = new SmartReceiptsApiErrorResponse(Arrays.asList("error1", "Purchase has already been taken", "error3")); final SmartReceiptsApiException smartReceiptsApiException = new SmartReceiptsApiException(Response.error(400, retrofitResponseBody), new Exception("test"), errorResponse); when(purchaseManager.getAllOwnedPurchases()).thenReturn(Observable.just(Collections.singleton(managedProduct))); when(mobileAppPurchasesService.addPurchase(any(PurchaseRequest.class))).thenReturn(Observable.error(smartReceiptsApiException)); ocrPurchaseTracker.initialize(); verify(purchaseManager).addEventListener(ocrPurchaseTracker); verify(localOcrScansTracker).setRemainingScans(REMAINING_SCANS); verify(defaultInAppPurchaseConsumer, never()).consumePurchase(any(ManagedProduct.class), any(PurchaseFamily.class)); }
@SuppressLint("CheckResult") public void initialize() { Logger.debug(this, "Initializing..."); this.purchaseManager.addEventListener(this); this.identityManager.isLoggedInStream() .subscribeOn(subscribeOnScheduler) .filter(isLoggedIn -> isLoggedIn) .flatMap(aBoolean -> { return fetchAndPersistAvailableRecognitions(); }) .flatMap(integer -> purchaseManager.getAllOwnedPurchases()) .flatMap(managedProducts -> { for (final ManagedProduct managedProduct : managedProducts) { if (managedProduct.getInAppPurchase().getPurchaseFamilies().contains(PurchaseFamily.Ocr)) { Logger.debug(OcrPurchaseTracker.this, "Found available OCR purchase: {}", managedProduct.getInAppPurchase()); if (!defaultInAppPurchaseConsumer.isConsumed(managedProduct, PurchaseFamily.Ocr)) { return uploadOcrPurchase(managedProduct); } else { Logger.debug(OcrPurchaseTracker.this, "But {} was already consumed...", managedProduct.getInAppPurchase()); } } } return Observable.empty(); }) .subscribe(o -> Logger.info(OcrPurchaseTracker.this, "Successfully initialized"), throwable -> Logger.error(OcrPurchaseTracker.this, "Failed to initialize.", throwable)); }
OcrPurchaseTracker implements PurchaseEventsListener { @SuppressLint("CheckResult") public void initialize() { Logger.debug(this, "Initializing..."); this.purchaseManager.addEventListener(this); this.identityManager.isLoggedInStream() .subscribeOn(subscribeOnScheduler) .filter(isLoggedIn -> isLoggedIn) .flatMap(aBoolean -> { return fetchAndPersistAvailableRecognitions(); }) .flatMap(integer -> purchaseManager.getAllOwnedPurchases()) .flatMap(managedProducts -> { for (final ManagedProduct managedProduct : managedProducts) { if (managedProduct.getInAppPurchase().getPurchaseFamilies().contains(PurchaseFamily.Ocr)) { Logger.debug(OcrPurchaseTracker.this, "Found available OCR purchase: {}", managedProduct.getInAppPurchase()); if (!defaultInAppPurchaseConsumer.isConsumed(managedProduct, PurchaseFamily.Ocr)) { return uploadOcrPurchase(managedProduct); } else { Logger.debug(OcrPurchaseTracker.this, "But {} was already consumed...", managedProduct.getInAppPurchase()); } } } return Observable.empty(); }) .subscribe(o -> Logger.info(OcrPurchaseTracker.this, "Successfully initialized"), throwable -> Logger.error(OcrPurchaseTracker.this, "Failed to initialize.", throwable)); } }
OcrPurchaseTracker implements PurchaseEventsListener { @SuppressLint("CheckResult") public void initialize() { Logger.debug(this, "Initializing..."); this.purchaseManager.addEventListener(this); this.identityManager.isLoggedInStream() .subscribeOn(subscribeOnScheduler) .filter(isLoggedIn -> isLoggedIn) .flatMap(aBoolean -> { return fetchAndPersistAvailableRecognitions(); }) .flatMap(integer -> purchaseManager.getAllOwnedPurchases()) .flatMap(managedProducts -> { for (final ManagedProduct managedProduct : managedProducts) { if (managedProduct.getInAppPurchase().getPurchaseFamilies().contains(PurchaseFamily.Ocr)) { Logger.debug(OcrPurchaseTracker.this, "Found available OCR purchase: {}", managedProduct.getInAppPurchase()); if (!defaultInAppPurchaseConsumer.isConsumed(managedProduct, PurchaseFamily.Ocr)) { return uploadOcrPurchase(managedProduct); } else { Logger.debug(OcrPurchaseTracker.this, "But {} was already consumed...", managedProduct.getInAppPurchase()); } } } return Observable.empty(); }) .subscribe(o -> Logger.info(OcrPurchaseTracker.this, "Successfully initialized"), throwable -> Logger.error(OcrPurchaseTracker.this, "Failed to initialize.", throwable)); } @Inject  OcrPurchaseTracker(@NonNull IdentityManager identityManager,
                              @NonNull WebServiceManager webServiceManager,
                              @NonNull PurchaseManager purchaseManager,
                              @NonNull PurchaseWallet purchaseWallet,
                              @NonNull DefaultInAppPurchaseConsumer defaultInAppPurchaseConsumer,
                              @NonNull LocalOcrScansTracker localOcrScansTracker); @VisibleForTesting  OcrPurchaseTracker(@NonNull IdentityManager identityManager,
                       @NonNull WebServiceManager webServiceManager,
                       @NonNull PurchaseManager purchaseManager,
                       @NonNull PurchaseWallet purchaseWallet,
                       @NonNull DefaultInAppPurchaseConsumer defaultInAppPurchaseConsumer,
                       @NonNull LocalOcrScansTracker localOcrScansTracker,
                       @NonNull Scheduler subscribeOnScheduler); }
OcrPurchaseTracker implements PurchaseEventsListener { @SuppressLint("CheckResult") public void initialize() { Logger.debug(this, "Initializing..."); this.purchaseManager.addEventListener(this); this.identityManager.isLoggedInStream() .subscribeOn(subscribeOnScheduler) .filter(isLoggedIn -> isLoggedIn) .flatMap(aBoolean -> { return fetchAndPersistAvailableRecognitions(); }) .flatMap(integer -> purchaseManager.getAllOwnedPurchases()) .flatMap(managedProducts -> { for (final ManagedProduct managedProduct : managedProducts) { if (managedProduct.getInAppPurchase().getPurchaseFamilies().contains(PurchaseFamily.Ocr)) { Logger.debug(OcrPurchaseTracker.this, "Found available OCR purchase: {}", managedProduct.getInAppPurchase()); if (!defaultInAppPurchaseConsumer.isConsumed(managedProduct, PurchaseFamily.Ocr)) { return uploadOcrPurchase(managedProduct); } else { Logger.debug(OcrPurchaseTracker.this, "But {} was already consumed...", managedProduct.getInAppPurchase()); } } } return Observable.empty(); }) .subscribe(o -> Logger.info(OcrPurchaseTracker.this, "Successfully initialized"), throwable -> Logger.error(OcrPurchaseTracker.this, "Failed to initialize.", throwable)); } @Inject  OcrPurchaseTracker(@NonNull IdentityManager identityManager,
                              @NonNull WebServiceManager webServiceManager,
                              @NonNull PurchaseManager purchaseManager,
                              @NonNull PurchaseWallet purchaseWallet,
                              @NonNull DefaultInAppPurchaseConsumer defaultInAppPurchaseConsumer,
                              @NonNull LocalOcrScansTracker localOcrScansTracker); @VisibleForTesting  OcrPurchaseTracker(@NonNull IdentityManager identityManager,
                       @NonNull WebServiceManager webServiceManager,
                       @NonNull PurchaseManager purchaseManager,
                       @NonNull PurchaseWallet purchaseWallet,
                       @NonNull DefaultInAppPurchaseConsumer defaultInAppPurchaseConsumer,
                       @NonNull LocalOcrScansTracker localOcrScansTracker,
                       @NonNull Scheduler subscribeOnScheduler); @SuppressLint("CheckResult") void initialize(); @Override void onPurchaseSuccess(@NonNull InAppPurchase inAppPurchase, @NonNull PurchaseSource purchaseSource); @Override void onPurchaseFailed(@NonNull PurchaseSource purchaseSource); int getRemainingScans(); Observable<Integer> getRemainingScansStream(); boolean hasAvailableScans(); void decrementRemainingScans(); }
OcrPurchaseTracker implements PurchaseEventsListener { @SuppressLint("CheckResult") public void initialize() { Logger.debug(this, "Initializing..."); this.purchaseManager.addEventListener(this); this.identityManager.isLoggedInStream() .subscribeOn(subscribeOnScheduler) .filter(isLoggedIn -> isLoggedIn) .flatMap(aBoolean -> { return fetchAndPersistAvailableRecognitions(); }) .flatMap(integer -> purchaseManager.getAllOwnedPurchases()) .flatMap(managedProducts -> { for (final ManagedProduct managedProduct : managedProducts) { if (managedProduct.getInAppPurchase().getPurchaseFamilies().contains(PurchaseFamily.Ocr)) { Logger.debug(OcrPurchaseTracker.this, "Found available OCR purchase: {}", managedProduct.getInAppPurchase()); if (!defaultInAppPurchaseConsumer.isConsumed(managedProduct, PurchaseFamily.Ocr)) { return uploadOcrPurchase(managedProduct); } else { Logger.debug(OcrPurchaseTracker.this, "But {} was already consumed...", managedProduct.getInAppPurchase()); } } } return Observable.empty(); }) .subscribe(o -> Logger.info(OcrPurchaseTracker.this, "Successfully initialized"), throwable -> Logger.error(OcrPurchaseTracker.this, "Failed to initialize.", throwable)); } @Inject  OcrPurchaseTracker(@NonNull IdentityManager identityManager,
                              @NonNull WebServiceManager webServiceManager,
                              @NonNull PurchaseManager purchaseManager,
                              @NonNull PurchaseWallet purchaseWallet,
                              @NonNull DefaultInAppPurchaseConsumer defaultInAppPurchaseConsumer,
                              @NonNull LocalOcrScansTracker localOcrScansTracker); @VisibleForTesting  OcrPurchaseTracker(@NonNull IdentityManager identityManager,
                       @NonNull WebServiceManager webServiceManager,
                       @NonNull PurchaseManager purchaseManager,
                       @NonNull PurchaseWallet purchaseWallet,
                       @NonNull DefaultInAppPurchaseConsumer defaultInAppPurchaseConsumer,
                       @NonNull LocalOcrScansTracker localOcrScansTracker,
                       @NonNull Scheduler subscribeOnScheduler); @SuppressLint("CheckResult") void initialize(); @Override void onPurchaseSuccess(@NonNull InAppPurchase inAppPurchase, @NonNull PurchaseSource purchaseSource); @Override void onPurchaseFailed(@NonNull PurchaseSource purchaseSource); int getRemainingScans(); Observable<Integer> getRemainingScansStream(); boolean hasAvailableScans(); void decrementRemainingScans();  }