Skip to content

Commit

Permalink
Bug 1858945 - Expose API to report when shopping product is back in s…
Browse files Browse the repository at this point in the history
…tock for GeckoView r=owlish,geckoview-reviewers,ohall

Differential Revision: https://phabricator.services.mozilla.com/D194245
  • Loading branch information
calumozilla committed Nov 27, 2023
1 parent 8f98d11 commit 42dbc59
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 56 deletions.
1 change: 1 addition & 0 deletions mobile/android/geckoview/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,7 @@ package org.mozilla.geckoview {
method @UiThread public void releaseDisplay(@NonNull GeckoDisplay);
method @AnyThread public void reload();
method @AnyThread public void reload(int);
method @AnyThread @NonNull public GeckoResult<String> reportBackInStock(@NonNull String);
method @AnyThread @NonNull public GeckoResult<GeckoSession.ReviewAnalysis> requestAnalysis(@NonNull String);
method @AnyThread @NonNull public GeckoResult<String> requestAnalysisCreationStatus(@NonNull String);
method @AnyThread @NonNull public GeckoResult<String> requestCreateAnalysis(@NonNull String);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import junit.framework.TestCase.assertFalse
import junit.framework.TestCase.assertNull
import junit.framework.TestCase.assertTrue
import org.hamcrest.Matchers.* // ktlint-disable no-wildcard-imports
import org.junit.Assume.assumeThat
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
Expand All @@ -29,6 +29,16 @@ class ReviewQualityCheckerTest : BaseSessionTest() {
mapOf(
"toolkit.shopping.ohttpRelayURL" to "",
"toolkit.shopping.ohttpConfigURL" to "",
"geckoview.shopping.mock_test_response" to true,
),
)
}

@After
fun cleanup() {
sessionRule.setPrefsUntilTestEnd(
mapOf(
"geckoview.shopping.mock_test_response" to false,
),
)
}
Expand Down Expand Up @@ -59,8 +69,6 @@ class ReviewQualityCheckerTest : BaseSessionTest() {

@Test
fun requestAnalysis() {
assumeThat(sessionRule.env.isAutomation, equalTo(true))
// Test for the builder constructor
val productId = "banana"
val grade = "A"
Expand Down Expand Up @@ -92,22 +100,6 @@ class ReviewQualityCheckerTest : BaseSessionTest() {
assertTrue("Not a deleted product", analysisObject.deletedProduct)
assertThat("Last analysis time should match", analysisObject.lastAnalysisTime, equalTo(lastAnalysisTime))

sessionRule.setPrefsUntilTestEnd(
mapOf(
"geckoview.shopping.mock_test_response" to false,
),
)

// verify a non product page
val nonProductPageResult = mainSession.requestAnalysis("https://www.example.com/").accept {
assertTrue("Should not return analysis", false)
}
try {
sessionRule.waitForResult(nonProductPageResult)
} catch (e: Exception) {
assertTrue("Should have an exception", true)
}

sessionRule.setPrefsUntilTestEnd(
mapOf(
"geckoview.shopping.mock_test_response" to true,
Expand All @@ -131,7 +123,6 @@ class ReviewQualityCheckerTest : BaseSessionTest() {

@Test
fun requestCreateAnalysisAndStatus() {
assumeThat(sessionRule.env.isAutomation, equalTo(true))
sessionRule.setPrefsUntilTestEnd(
mapOf(
"geckoview.shopping.mock_test_response" to true,
Expand All @@ -146,8 +137,6 @@ class ReviewQualityCheckerTest : BaseSessionTest() {

@Test
fun requestRecommendations() {
assumeThat(sessionRule.env.isAutomation, equalTo(true))

// Test the Builder constructor
val url = "https://example.com/mock_url"
val adjustedRating = 3.5
Expand Down Expand Up @@ -178,28 +167,6 @@ class ReviewQualityCheckerTest : BaseSessionTest() {
assertThat("Price should match", recommendationObject.price, equalTo(price))
assertThat("Currency should match", recommendationObject.currency, equalTo(currency))

sessionRule.setPrefsUntilTestEnd(
mapOf(
"geckoview.shopping.mock_test_response" to false,
),
)

// verify a non product page
val nonProductPageResult = mainSession.requestRecommendations("https://www.amazon.com/").accept {
assertTrue("Should not return recommendation", false)
}
try {
sessionRule.waitForResult(nonProductPageResult)
} catch (e: Exception) {
assertTrue("Should have an exception", true)
}

sessionRule.setPrefsUntilTestEnd(
mapOf(
"geckoview.shopping.mock_test_response" to true,
),
)

val result = mainSession.requestRecommendations("https://www.example.com/mock")
sessionRule.waitForResult(result)
.let {
Expand All @@ -217,13 +184,7 @@ class ReviewQualityCheckerTest : BaseSessionTest() {

@Test
fun sendAttributionEvents() {
assumeThat(sessionRule.env.isAutomation, equalTo(true))
val aid = "TEST_AID"
sessionRule.setPrefsUntilTestEnd(
mapOf(
"geckoview.shopping.mock_test_response" to true,
),
)
val validClickResult = mainSession.sendClickAttributionEvent(aid)
assertThat(
"Click event success result should be true",
Expand All @@ -237,4 +198,10 @@ class ReviewQualityCheckerTest : BaseSessionTest() {
equalTo(true),
)
}

@Test
fun reportBackInStock() {
val result = mainSession.reportBackInStock("https://www.example.com/mock")
assertThat("Report back in stock status matches", sessionRule.waitForResult(result), equalTo("report created"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3086,6 +3086,20 @@ public void restoreState(final @NonNull SessionState state) {
});
}

/**
* Report that a product is back in stock.
*
* @param url The URL of the product page.
* @return a {@link GeckoResult} result of whether reporting a product is back in stock was
* successful.
*/
@AnyThread
public @NonNull GeckoResult<String> reportBackInStock(@NonNull final String url) {
final GeckoBundle bundle = new GeckoBundle(1);
bundle.putString("url", url);
return mEventDispatcher.queryString("GeckoView:ReportBackInStock", bundle);
}

// This is the GeckoDisplay acquired via acquireDisplay(), if any.
private GeckoDisplay mDisplay;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ exclude: true

## v122
- ⚠️ Removed [`onGetNimbusFeature`][115.5], please use `ExperimentDelegate.onGetExperimentFeature` instead.
- Added [`GeckoSession.reportBackInStock`][122.1] for reporting a Shopping product is back in stock.

[122.1]: {{javadoc_uri}}/GeckoSession.html#reportBackInStock(String)

## v121
- Added runtime controller functions. [`RuntimeTranslation`][121.1] has options for retrieving translation languages and managing language models.
Expand Down Expand Up @@ -1479,4 +1482,4 @@ to allow adding gecko profiler markers.
[65.24]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport(android.content.Context,android.os.Bundle,java.lang.String)
[65.25]: {{javadoc_uri}}/GeckoResult.html

[api-version]: 4096311f0fe200c9c2ede63aaaf2a685834d89da
[api-version]: c1902d61b73f96de2b6bc4b797760295a740267b
Original file line number Diff line number Diff line change
Expand Up @@ -1317,6 +1317,9 @@ public boolean onOptionsItemSelected(MenuItem item) {
case R.id.poll_shopping_analysis_status:
pollForAnalysisCompleted(session, mCurrentUri);
break;
case R.id.report_back_in_stock:
reportBackInStock(session, mCurrentUri);
break;
case R.id.translate:
translate(session);
break;
Expand Down Expand Up @@ -2451,6 +2454,16 @@ public void pollForAnalysisCompleted(
});
}

public void reportBackInStock(@NonNull final GeckoSession session, @NonNull final String url) {
Log.d(LOGTAG, "Report shopping product is back in stock");
GeckoResult<String> result = session.reportBackInStock(url);
result.map(
message -> {
Log.d(LOGTAG, "Shopping Analysis back in stock status: " + message);
return message;
});
}

public void requestRecommendations(
@NonNull final GeckoSession session, @NonNull final String url) {
GeckoResult<List<GeckoSession.Recommendation>> result = session.requestRecommendations(url);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<item android:title="Create Shopping Analysis" android:id="@+id/create_shopping_analysis"/>
<item android:title="Get Shopping Analysis Status" android:id="@+id/get_shopping_analysis_status"/>
<item android:title="Poll Until Analysis Completed" android:id="@+id/poll_shopping_analysis_status"/>
<item android:title="Report Back In Stock" android:id="@+id/report_back_in_stock"/>
<item android:title="@string/translate" android:id="@+id/translate"/>
<item android:title="@string/translate_restore" android:id="@+id/translate_restore"/>
<item android:title="@string/translate_manage" android:id="@+id/translate_manage"/>
Expand Down
31 changes: 26 additions & 5 deletions mobile/android/modules/geckoview/GeckoViewContent.sys.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export class GeckoViewContent extends GeckoViewModule {
"GeckoView:SendImpressionAttributionEvent",
"GeckoView:RequestAnalysis",
"GeckoView:RequestRecommendations",
"GeckoView:ReportBackInStock",
"GeckoView:ScrollBy",
"GeckoView:ScrollTo",
"GeckoView:SetActive",
Expand Down Expand Up @@ -256,6 +257,9 @@ export class GeckoViewContent extends GeckoViewModule {
case "GeckoView:RequestRecommendations":
this._requestRecommendations(aData, aCallback);
break;
case "GeckoView:ReportBackInStock":
this._reportBackInStock(aData, aCallback);
break;
case "GeckoView:IsPdfJs":
aCallback.onSuccess(this.isPdfJs);
break;
Expand Down Expand Up @@ -378,7 +382,6 @@ export class GeckoViewContent extends GeckoViewModule {

async _requestAnalysis(aData, aCallback) {
if (
Cu.isInAutomation &&
Services.prefs.getBoolPref("geckoview.shopping.mock_test_response", false)
) {
const analysis = {
Expand Down Expand Up @@ -413,7 +416,6 @@ export class GeckoViewContent extends GeckoViewModule {

async _requestCreateAnalysis(aData, aCallback) {
if (
Cu.isInAutomation &&
Services.prefs.getBoolPref("geckoview.shopping.mock_test_response", false)
) {
const status = "pending";
Expand All @@ -436,7 +438,6 @@ export class GeckoViewContent extends GeckoViewModule {

async _requestAnalysisCreationStatus(aData, aCallback) {
if (
Cu.isInAutomation &&
Services.prefs.getBoolPref("geckoview.shopping.mock_test_response", false)
) {
const status = "in_progress";
Expand Down Expand Up @@ -483,7 +484,6 @@ export class GeckoViewContent extends GeckoViewModule {
async _sendAttributionEvent(aEvent, aData, aCallback) {
let result;
if (
Cu.isInAutomation &&
Services.prefs.getBoolPref("geckoview.shopping.mock_test_response", false)
) {
result = { TEST_AID: "TEST_AID_RESPONSE" };
Expand All @@ -503,7 +503,6 @@ export class GeckoViewContent extends GeckoViewModule {

async _requestRecommendations(aData, aCallback) {
if (
Cu.isInAutomation &&
Services.prefs.getBoolPref("geckoview.shopping.mock_test_response", false)
) {
const recommendations = [
Expand Down Expand Up @@ -537,6 +536,28 @@ export class GeckoViewContent extends GeckoViewModule {
}
}

async _reportBackInStock(aData, aCallback) {
if (
Services.prefs.getBoolPref("geckoview.shopping.mock_test_response", false)
) {
const message = "report created";
aCallback.onSuccess(message);
return;
}
const url = Services.io.newURI(aData.url);
if (!lazy.isProductURL(url)) {
aCallback.onError(`Cannot reportBackInStock on a non-product url.`);
} else {
const product = new lazy.ShoppingProduct(url);
const message = await product.sendReport();
if (!message) {
aCallback.onError(`Reporting back in stock returned null.`);
return;
}
aCallback.onSuccess(message.message);
}
}

async _hasCookieBannerRuleForBrowsingContextTree(aCallback) {
const { browsingContext } = this.actor;
aCallback.onSuccess(
Expand Down

0 comments on commit 42dbc59

Please sign in to comment.