GooglePlayBillingVendor implements Vendor, PurchasesUpdatedListener,
        AbstractGooglePlayBillingApi.LifecycleListener { @Override public void getProductDetails(@NonNull Context context, @NonNull final String sku, final boolean isSubscription, @NonNull final ProductDetailsListener listener) { throwIfUninitialized(); api.getSkuDetails( isSubscription ? SkuType.SUBS : SkuType.INAPP, Collections.singletonList(sku), new SkuDetailsResponseListener() { @Override public void onSkuDetailsResponse(int responseCode, List<SkuDetails> skuDetailsList) { if (responseCode == BillingResponse.OK && skuDetailsList.size() == 1) { logSafely("Successfully got sku details for " + sku + "!"); listener.success( GooglePlayBillingProduct.create(skuDetailsList.get(0), isSubscription ? SkuType.SUBS : SkuType.INAPP) ); } else { logSafely("Error getting sku details for " + sku + " with code "+responseCode); listener.failure(getDetailsError(responseCode)); } } } ); } GooglePlayBillingVendor();  GooglePlayBillingVendor(String publicKey64);  GooglePlayBillingVendor(AbstractGooglePlayBillingApi api);  GooglePlayBillingVendor(AbstractGooglePlayBillingApi api, @Nullable String publicKey64); @Override String id(); @Override synchronized void initialize(Context context, InitializationListener listener); @Override synchronized void initialized(boolean success); @Override void disconnected(); @Override void dispose(Context context); @Override synchronized void purchase(Activity activity, Product product, String developerPayload, PurchaseListener listener); @Override void onPurchasesUpdated(@BillingResponse int responseCode,
                                   @Nullable List<com.android.billingclient.api.Purchase> purchases); @Override synchronized void consume(@NonNull final Context context, @NonNull final Purchase purchase, @NonNull final ConsumeListener listener); @Override void getInventory(@NonNull Context context, @Nullable Collection<String> itemSkus, @Nullable Collection<String> subSkus,
                             @NonNull InventoryListener listener); @Override void getProductDetails(@NonNull Context context, @NonNull final String sku, final boolean isSubscription,
                                  @NonNull final ProductDetailsListener listener); @Override void setLogger(Logger logger); @Override boolean available(); @Override boolean canPurchase(Product product); @Override boolean onActivityResult(int requestCode, int resultCode, Intent data); @Override Product getProductFrom(JSONObject json); @Override Purchase getPurchaseFrom(JSONObject json);  }
@Test public void get_product_details() { GooglePlayBillingVendor vendor = successfullyInitializedVendor(); ProductDetailsListener listener = mock(ProductDetailsListener.class); doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { List<String> skus = invocation.getArgument(1); SkuDetailsResponseListener responseListener = invocation.getArgument(2); assertEquals(1, skus.size()); responseListener.onSkuDetailsResponse(BillingClient.BillingResponse.OK, Collections.singletonList( TestData.getSkuDetail(skus.get(0)) )); return null; } }).when(api).getSkuDetails(eq(BillingClient.SkuType.INAPP), ArgumentMatchers.<String>anyList(), any(SkuDetailsResponseListener.class)); vendor.getProductDetails(context, TestData.productInappA.sku(), false, listener); ArgumentCaptor<List<String>> argumentSkus = ArgumentCaptor.forClass(List.class); verify(api).getSkuDetails(eq(BillingClient.SkuType.INAPP), argumentSkus.capture(), any(SkuDetailsResponseListener.class)); assertEquals(1, argumentSkus.getValue().size()); assertEquals(TestData.productInappA.sku(), argumentSkus.getValue().get(0)); ArgumentCaptor<Product> argumentProduct = ArgumentCaptor.forClass(Product.class); verify(listener).success(argumentProduct.capture()); assertEquals(TestData.productInappA, argumentProduct.getValue()); }
@Test public void get_product_details_failure() { GooglePlayBillingVendor vendor = successfullyInitializedVendor(); ProductDetailsListener listener = mock(ProductDetailsListener.class); doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { List<String> skus = invocation.getArgument(1); SkuDetailsResponseListener responseListener = invocation.getArgument(2); assertEquals(1, skus.size()); responseListener.onSkuDetailsResponse(BillingClient.BillingResponse.SERVICE_UNAVAILABLE, null); return null; } }).when(api).getSkuDetails(eq(BillingClient.SkuType.INAPP), ArgumentMatchers.<String>anyList(), any(SkuDetailsResponseListener.class)); vendor.getProductDetails(context, TestData.productInappA.sku(), false, listener); ArgumentCaptor<Vendor.Error> argumentError = ArgumentCaptor.forClass(Vendor.Error.class); verify(listener).failure(argumentError.capture()); assertEquals(VendorConstants.PRODUCT_DETAILS_UNAVAILABLE, argumentError.getValue().code); }