OcrPurchaseTracker implements PurchaseEventsListener { @Override public void onPurchaseSuccess(@NonNull InAppPurchase inAppPurchase, @NonNull PurchaseSource purchaseSource) { if (inAppPurchase.getPurchaseFamilies().contains(PurchaseFamily.Ocr)) { final ManagedProduct managedProduct = purchaseWallet.getLocalInAppManagedProduct(inAppPurchase); if (managedProduct != null) { this.identityManager.isLoggedInStream() .subscribeOn(subscribeOnScheduler) .filter(isLoggedIn -> isLoggedIn) .flatMap(aBoolean -> uploadOcrPurchase(managedProduct)) .subscribe(o -> { }, throwable -> Logger.error(OcrPurchaseTracker.this, "Failed to upload purchase of " + managedProduct.getInAppPurchase(), throwable), () -> Logger.info(OcrPurchaseTracker.this, "Successfully uploaded and consumed purchase of {}.", managedProduct.getInAppPurchase()) ); } } } @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();  }
@Test public void onPurchaseSuccessWhenNotLoggedIn() { when(identityManager.isLoggedInStream()).thenReturn(Observable.just(false)); ocrPurchaseTracker.onPurchaseSuccess(InAppPurchase.OcrScans50, PurchaseSource.Unknown); verify(defaultInAppPurchaseConsumer, never()).consumePurchase(any(ManagedProduct.class), any(PurchaseFamily.class)); verify(localOcrScansTracker, never()).setRemainingScans(REMAINING_SCANS); verifyZeroInteractions(webServiceManager); }
@Test public void onPurchaseSuccessForUnTrackedType() { ocrPurchaseTracker.onPurchaseSuccess(InAppPurchase.TestConsumablePurchase, PurchaseSource.Unknown); verify(defaultInAppPurchaseConsumer, never()).consumePurchase(any(ManagedProduct.class), any(PurchaseFamily.class)); verify(localOcrScansTracker, never()).setRemainingScans(REMAINING_SCANS); verifyZeroInteractions(webServiceManager); }
@Test public void onPurchaseSuccessUploadFails() { when(mobileAppPurchasesService.addPurchase(any(PurchaseRequest.class))).thenReturn(Observable.error(new Exception("test"))); ocrPurchaseTracker.onPurchaseSuccess(InAppPurchase.OcrScans50, PurchaseSource.Unknown); verify(defaultInAppPurchaseConsumer, never()).consumePurchase(any(ManagedProduct.class), any(PurchaseFamily.class)); verify(localOcrScansTracker, never()).setRemainingScans(REMAINING_SCANS); }
@Test public void onPurchaseSuccessSucceedsButConsumeFails() { when(defaultInAppPurchaseConsumer.consumePurchase(managedProduct, PurchaseFamily.Ocr)).thenReturn(Completable.error(new Exception("test"))); when(mobileAppPurchasesService.addPurchase(any(PurchaseRequest.class))).thenReturn(Observable.just(purchaseResponse)); ocrPurchaseTracker.onPurchaseSuccess(InAppPurchase.OcrScans50, PurchaseSource.Unknown); verify(defaultInAppPurchaseConsumer).consumePurchase(managedProduct, PurchaseFamily.Ocr); verify(localOcrScansTracker, never()).setRemainingScans(REMAINING_SCANS); }
@Test public void onPurchaseSuccessSucceeds() { when(defaultInAppPurchaseConsumer.consumePurchase(managedProduct, PurchaseFamily.Ocr)).thenReturn(Completable.complete()); when(mobileAppPurchasesService.addPurchase(any(PurchaseRequest.class))).thenReturn(Observable.just(purchaseResponse)); ocrPurchaseTracker.onPurchaseSuccess(InAppPurchase.OcrScans50, PurchaseSource.Unknown); verify(defaultInAppPurchaseConsumer).consumePurchase(managedProduct, PurchaseFamily.Ocr); verify(localOcrScansTracker).setRemainingScans(REMAINING_SCANS); }
@Test public void onPurchaseSuccessSucceedsForOtherPurchaseType() { when(managedProduct.getInAppPurchase()).thenReturn(InAppPurchase.OcrScans10); when(purchaseWallet.getLocalInAppManagedProduct(InAppPurchase.OcrScans10)).thenReturn(managedProduct); when(defaultInAppPurchaseConsumer.consumePurchase(managedProduct, PurchaseFamily.Ocr)).thenReturn(Completable.complete()); when(mobileAppPurchasesService.addPurchase(any(PurchaseRequest.class))).thenReturn(Observable.just(purchaseResponse)); ocrPurchaseTracker.onPurchaseSuccess(InAppPurchase.OcrScans10, PurchaseSource.Unknown); verify(defaultInAppPurchaseConsumer).consumePurchase(managedProduct, PurchaseFamily.Ocr); verify(localOcrScansTracker).setRemainingScans(REMAINING_SCANS); }
@Test public void onPurchaseSuccessSucceedsButFailsToFetchMe() { when(identityManager.getMe()).thenReturn(Observable.error(new Exception("test"))); when(defaultInAppPurchaseConsumer.consumePurchase(managedProduct, PurchaseFamily.Ocr)).thenReturn(Completable.complete()); when(mobileAppPurchasesService.addPurchase(any(PurchaseRequest.class))).thenReturn(Observable.just(purchaseResponse)); ocrPurchaseTracker.onPurchaseSuccess(InAppPurchase.OcrScans50, PurchaseSource.Unknown); verify(defaultInAppPurchaseConsumer).consumePurchase(managedProduct, PurchaseFamily.Ocr); verify(localOcrScansTracker, never()).setRemainingScans(anyInt()); }
@Test public void onPurchaseSuccessSucceedsButReturnsInvalidMeResponse() { when(meResponse.getUser()).thenReturn(null); when(defaultInAppPurchaseConsumer.consumePurchase(managedProduct, PurchaseFamily.Ocr)).thenReturn(Completable.complete()); when(mobileAppPurchasesService.addPurchase(any(PurchaseRequest.class))).thenReturn(Observable.just(purchaseResponse)); ocrPurchaseTracker.onPurchaseSuccess(InAppPurchase.OcrScans50, PurchaseSource.Unknown); verify(defaultInAppPurchaseConsumer).consumePurchase(managedProduct, PurchaseFamily.Ocr); verify(localOcrScansTracker, never()).setRemainingScans(anyInt()); }
@Test public void onPurchaseSuccessSucceedsForLateLogin() { final PublishSubject<Boolean> loggedInStream = PublishSubject.create(); loggedInStream.onNext(false); when(identityManager.isLoggedInStream()).thenReturn(loggedInStream); when(defaultInAppPurchaseConsumer.consumePurchase(managedProduct, PurchaseFamily.Ocr)).thenReturn(Completable.complete()); when(mobileAppPurchasesService.addPurchase(any(PurchaseRequest.class))).thenReturn(Observable.just(purchaseResponse)); ocrPurchaseTracker.onPurchaseSuccess(InAppPurchase.OcrScans50, PurchaseSource.Unknown); loggedInStream.onNext(true); verify(defaultInAppPurchaseConsumer).consumePurchase(managedProduct, PurchaseFamily.Ocr); verify(localOcrScansTracker).setRemainingScans(REMAINING_SCANS); }