Commit ba6b8857 authored by Pete Williamson's avatar Pete Williamson Committed by Commit Bot

Refactor FeedbackCollector.

For feedback on the Discover feed (on the NTP), we want to drop all
the PSD other than the ones directly relevant for the feed.  The
feedback will be processed by the discover team instead of the
chrome team, and we want to make sure PII is not leaked to teams
outside chrome to strongly comply with privacy.

The approach we took was to make FeedbackCollector a base class.
For feedback going to chrome we use a derived class called
ChromeFeedbackCollector.  For feedback going to the AGSA team,
we use a derived class called FeedFeedbackCollector, which only
includes PSD specific to the Chrome feed.

A new unit test for the FeedFeedbackCollector has been added.

We also removed the FeedContext parameter from the FeedbackCollector,
since it is only used now by the FeedFeedbackCollector.

Bug: 1091058
Change-Id: Ia088b20aaf2ef4a50c2ce163cacd159f7a0c28e7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2241455
Commit-Queue: Peter Williamson <petewil@chromium.org>
Reviewed-by: default avatarTommy Nyquist <nyquist@chromium.org>
Cr-Commit-Position: refs/heads/master@{#782810}
parent 46060cdf
...@@ -685,11 +685,13 @@ chrome_java_sources = [ ...@@ -685,11 +685,13 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/feature_engagement/TrackerFactory.java", "java/src/org/chromium/chrome/browser/feature_engagement/TrackerFactory.java",
"java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSource.java", "java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSource.java",
"java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSourceAdapter.java", "java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSourceAdapter.java",
"java/src/org/chromium/chrome/browser/feedback/ChromeFeedbackCollector.java",
"java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java", "java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java",
"java/src/org/chromium/chrome/browser/feedback/ConnectivityFeedbackSource.java", "java/src/org/chromium/chrome/browser/feedback/ConnectivityFeedbackSource.java",
"java/src/org/chromium/chrome/browser/feedback/ConnectivityTask.java", "java/src/org/chromium/chrome/browser/feedback/ConnectivityTask.java",
"java/src/org/chromium/chrome/browser/feedback/DataReductionProxyFeedbackSource.java", "java/src/org/chromium/chrome/browser/feedback/DataReductionProxyFeedbackSource.java",
"java/src/org/chromium/chrome/browser/feedback/DuetFeedbackSource.java", "java/src/org/chromium/chrome/browser/feedback/DuetFeedbackSource.java",
"java/src/org/chromium/chrome/browser/feedback/FeedFeedbackCollector.java",
"java/src/org/chromium/chrome/browser/feedback/FeedbackCollector.java", "java/src/org/chromium/chrome/browser/feedback/FeedbackCollector.java",
"java/src/org/chromium/chrome/browser/feedback/FeedbackContextFeedbackSource.java", "java/src/org/chromium/chrome/browser/feedback/FeedbackContextFeedbackSource.java",
"java/src/org/chromium/chrome/browser/feedback/FeedbackReporter.java", "java/src/org/chromium/chrome/browser/feedback/FeedbackReporter.java",
......
...@@ -89,7 +89,8 @@ chrome_junit_test_java_sources = [ ...@@ -89,7 +89,8 @@ chrome_junit_test_java_sources = [
"junit/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryUnitTest.java", "junit/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryUnitTest.java",
"junit/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPageStateUnitTest.java", "junit/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPageStateUnitTest.java",
"junit/src/org/chromium/chrome/browser/externalauth/ExternalAuthUtilsTest.java", "junit/src/org/chromium/chrome/browser/externalauth/ExternalAuthUtilsTest.java",
"junit/src/org/chromium/chrome/browser/feedback/FeedbackCollectorTest.java", "junit/src/org/chromium/chrome/browser/feedback/ChromeFeedbackCollectorTest.java",
"junit/src/org/chromium/chrome/browser/feedback/FeedFeedbackCollectorTest.java",
"junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java", "junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java",
"junit/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationUnitTest.java", "junit/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationUnitTest.java",
"junit/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiverTest.java", "junit/src/org/chromium/chrome/browser/firstrun/ToSAckedReceiverTest.java",
......
...@@ -9,7 +9,7 @@ import android.app.Activity; ...@@ -9,7 +9,7 @@ import android.app.Activity;
import org.chromium.base.ThreadUtils; import org.chromium.base.ThreadUtils;
import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.CalledByNative;
import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.AppHooks;
import org.chromium.chrome.browser.feedback.FeedbackCollector; import org.chromium.chrome.browser.feedback.ChromeFeedbackCollector;
import org.chromium.chrome.browser.feedback.FeedbackReporter; import org.chromium.chrome.browser.feedback.FeedbackReporter;
import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.base.WindowAndroid;
...@@ -27,8 +27,9 @@ public final class ChildAccountFeedbackReporter { ...@@ -27,8 +27,9 @@ public final class ChildAccountFeedbackReporter {
sFeedbackReporter = AppHooks.get().createFeedbackReporter(); sFeedbackReporter = AppHooks.get().createFeedbackReporter();
} }
new FeedbackCollector(activity, profile, url, null /* categoryTag */, description, null, new ChromeFeedbackCollector(activity, null /* categoryTag */, description,
true /* takeScreenshot */, null /* feed context */, true /* takeScreenshot */,
new ChromeFeedbackCollector.InitParams(profile, url, null),
collector -> { sFeedbackReporter.reportFeedback(collector); }); collector -> { sFeedbackReporter.reportFeedback(collector); });
} }
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.feedback;
import android.app.Activity;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import org.chromium.base.Callback;
import org.chromium.chrome.browser.profiles.Profile;
import java.util.ArrayList;
import java.util.List;
/**
* Used for gathering a variety of feedback from various components in Chrome and bundling it into
* a set of Key - Value pairs used to submit feedback requests.
*/
public class ChromeFeedbackCollector
extends FeedbackCollector<ChromeFeedbackCollector.InitParams> implements Runnable {
/** Initialization Parameters of the Chrome overload of FeedbackCollector<T>. */
public static class InitParams {
public Profile profile;
public String url;
public String feedbackContext;
public InitParams(Profile profile, String url, String feedbackContext) {
this.profile = profile;
this.url = url;
this.feedbackContext = feedbackContext;
}
}
public ChromeFeedbackCollector(Activity activity, @Nullable String categoryTag,
@Nullable String description, boolean takeScreenshot, InitParams initParams,
Callback<FeedbackCollector> callback) {
super(categoryTag, description, callback);
init(activity, takeScreenshot, initParams);
}
@VisibleForTesting
@Override
protected List<FeedbackSource> buildSynchronousFeedbackSources(InitParams initParams) {
List<FeedbackSource> sources = new ArrayList<>();
// This is the list of all synchronous sources of feedback. Please add new synchronous
// entries here.
sources.add(new UrlFeedbackSource(initParams.url));
sources.add(new VariationsFeedbackSource(initParams.profile));
sources.add(new DataReductionProxyFeedbackSource(initParams.profile));
sources.add(new HistogramFeedbackSource(initParams.profile));
sources.add(new LowEndDeviceFeedbackSource());
sources.add(new IMEFeedbackSource());
sources.add(new PermissionFeedbackSource());
sources.add(new FeedbackContextFeedbackSource(initParams.feedbackContext));
sources.add(new DuetFeedbackSource());
return sources;
}
@VisibleForTesting
@Override
protected List<AsyncFeedbackSource> buildAsynchronousFeedbackSources(InitParams initParams) {
List<AsyncFeedbackSource> sources = new ArrayList<>();
// This is the list of all asynchronous sources of feedback. Please add new asynchronous
// entries here.
sources.add(new ConnectivityFeedbackSource(initParams.profile));
sources.add(new SystemInfoFeedbackSource());
sources.add(new ProcessIdFeedbackSource());
return sources;
}
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.feedback;
import android.app.Activity;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import org.chromium.base.Callback;
import org.chromium.chrome.browser.profiles.Profile;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Used for gathering feedback from the feed in Chrome and bundling it into a set of Key - Value
* pairs used to submit feedback requests.
*/
public class FeedFeedbackCollector
extends FeedbackCollector<FeedFeedbackCollector.InitParams> implements Runnable {
/** Initialization parameters needed by the Feed overload of FeedbackCollector<T>. */
public static class InitParams {
public Profile profile;
public String url;
public Map<String, String> feedContext;
public InitParams(Profile profile, String url, Map<String, String> feedContext) {
this.profile = profile;
this.url = url;
this.feedContext = feedContext;
}
}
public FeedFeedbackCollector(Activity activity, @Nullable String categoryTag,
@Nullable String description, @Nullable String feedbackContext, boolean takeScreenshot,
InitParams initParams, Callback<FeedbackCollector> callback) {
super(categoryTag, description, callback);
init(activity, takeScreenshot, initParams);
}
@VisibleForTesting
@Override
protected List<FeedbackSource> buildSynchronousFeedbackSources(InitParams initParams) {
List<FeedbackSource> sources = new ArrayList<>();
// Since Interest feed feedback goes to a different destiation, we don't include other PSD
// for privacy reasons.
sources.add(new UrlFeedbackSource(initParams.url));
sources.add(new InterestFeedFeedbackSource(initParams.feedContext));
return sources;
}
@VisibleForTesting
@Override
protected List<AsyncFeedbackSource> buildAsynchronousFeedbackSources(InitParams initParams) {
List<AsyncFeedbackSource> sources = new ArrayList<>();
// This is the list of all asynchronous sources of feedback. Please add new asynchronous
// entries here.
sources.add(new ConnectivityFeedbackSource(initParams.profile));
sources.add(new SystemInfoFeedbackSource());
sources.add(new ProcessIdFeedbackSource());
return sources;
}
}
...@@ -10,6 +10,7 @@ import android.os.Bundle; ...@@ -10,6 +10,7 @@ import android.os.Bundle;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.Pair; import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
...@@ -17,10 +18,8 @@ import org.chromium.base.Callback; ...@@ -17,10 +18,8 @@ import org.chromium.base.Callback;
import org.chromium.base.CollectionUtil; import org.chromium.base.CollectionUtil;
import org.chromium.base.ThreadUtils; import org.chromium.base.ThreadUtils;
import org.chromium.base.task.PostTask; import org.chromium.base.task.PostTask;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.UiThreadTaskTraits;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -28,35 +27,41 @@ import java.util.Map; ...@@ -28,35 +27,41 @@ import java.util.Map;
/** /**
* Used for gathering a variety of feedback from various components in Chrome and bundling it into * Used for gathering a variety of feedback from various components in Chrome and bundling it into
* a set of Key - Value pairs used to submit feedback requests. * a set of Key - Value pairs used to submit feedback requests.
* @param <T> Initialization params used by subclasses for the feedback source builders.
*/ */
public class FeedbackCollector implements Runnable { public abstract class FeedbackCollector<T> implements Runnable {
/** The timeout for gathering data asynchronously. This timeout is ignored for screenshots. */ /** The timeout for gathering data asynchronously. This timeout is ignored for screenshots. */
private static final int TIMEOUT_MS = 500; private static final int TIMEOUT_MS = 500;
private final List<FeedbackSource> mSynchronousSources;
private final List<AsyncFeedbackSource> mAsynchronousSources;
private final long mStartTime = SystemClock.elapsedRealtime(); private final long mStartTime = SystemClock.elapsedRealtime();
private final String mCategoryTag; private final String mCategoryTag;
private final String mDescription; private final String mDescription;
private List<FeedbackSource> mSynchronousSources;
private List<AsyncFeedbackSource> mAsynchronousSources;
private ScreenshotSource mScreenshotTask; private ScreenshotSource mScreenshotTask;
/** The callback is cleared once notified so we will never notify the caller twice. */ /** The callback is cleared once notified so we will never notify the caller twice. */
private Callback<FeedbackCollector> mCallback; private Callback<FeedbackCollector> mCallback;
public FeedbackCollector(Activity activity, Profile profile, @Nullable String url, public FeedbackCollector(@Nullable String categoryTag, @Nullable String description,
@Nullable String categoryTag, @Nullable String description, Callback<FeedbackCollector> callback) {
@Nullable String feedbackContext, boolean takeScreenshot,
@Nullable Map<String, String> feedContext, Callback<FeedbackCollector> callback) {
mCategoryTag = categoryTag; mCategoryTag = categoryTag;
mDescription = description; mDescription = description;
mCallback = callback; mCallback = callback;
}
// Subclasses must invoke init() at construction time.
protected void init(Activity activity, boolean takeScreenshot, T initParams) {
// 1. Build all synchronous and asynchronous sources. // 1. Build all synchronous and asynchronous sources.
mSynchronousSources = mSynchronousSources = buildSynchronousFeedbackSources(initParams);
buildSynchronousFeedbackSources(profile, url, feedbackContext, feedContext); mAsynchronousSources = buildAsynchronousFeedbackSources(initParams);
mAsynchronousSources = buildAsynchronousFeedbackSources(profile);
// Sanity check in case a source is added to the wrong list.
for (FeedbackSource source : mSynchronousSources) {
assert !(source instanceof AsyncFeedbackSource);
}
// 2. Build the screenshot task if necessary. // 2. Build the screenshot task if necessary.
if (takeScreenshot) mScreenshotTask = buildScreenshotSource(activity); if (takeScreenshot) mScreenshotTask = buildScreenshotSource(activity);
...@@ -73,44 +78,12 @@ public class FeedbackCollector implements Runnable { ...@@ -73,44 +78,12 @@ public class FeedbackCollector implements Runnable {
} }
@VisibleForTesting @VisibleForTesting
protected List<FeedbackSource> buildSynchronousFeedbackSources(Profile profile, @NonNull
@Nullable String url, @Nullable String feedbackContext, protected abstract List<FeedbackSource> buildSynchronousFeedbackSources(T initParams);
@Nullable Map<String, String> feedContext) {
List<FeedbackSource> sources = new ArrayList<>();
// This is the list of all synchronous sources of feedback. Please add new synchronous
// entries here.
sources.add(new UrlFeedbackSource(url));
sources.add(new VariationsFeedbackSource(profile));
sources.add(new DataReductionProxyFeedbackSource(profile));
sources.add(new HistogramFeedbackSource(profile));
sources.add(new LowEndDeviceFeedbackSource());
sources.add(new IMEFeedbackSource());
sources.add(new PermissionFeedbackSource());
sources.add(new FeedbackContextFeedbackSource(feedbackContext));
sources.add(new DuetFeedbackSource());
sources.add(new InterestFeedFeedbackSource(feedContext));
// Sanity check in case a source is added to the wrong list.
for (FeedbackSource source : sources) {
assert !(source instanceof AsyncFeedbackSource);
}
return sources;
}
@VisibleForTesting @VisibleForTesting
protected List<AsyncFeedbackSource> buildAsynchronousFeedbackSources(Profile profile) { @NonNull
List<AsyncFeedbackSource> sources = new ArrayList<>(); protected abstract List<AsyncFeedbackSource> buildAsynchronousFeedbackSources(T initParams);
// This is the list of all asynchronous sources of feedback. Please add new asynchronous
// entries here.
sources.add(new ConnectivityFeedbackSource(profile));
sources.add(new SystemInfoFeedbackSource());
sources.add(new ProcessIdFeedbackSource());
return sources;
}
@VisibleForTesting @VisibleForTesting
protected ScreenshotSource buildScreenshotSource(Activity activity) { protected ScreenshotSource buildScreenshotSource(Activity activity) {
......
...@@ -18,6 +18,8 @@ import org.chromium.base.ThreadUtils; ...@@ -18,6 +18,8 @@ import org.chromium.base.ThreadUtils;
import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.metrics.RecordUserAction;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.AppHooks;
import org.chromium.chrome.browser.feedback.ChromeFeedbackCollector;
import org.chromium.chrome.browser.feedback.FeedFeedbackCollector;
import org.chromium.chrome.browser.feedback.FeedbackCollector; import org.chromium.chrome.browser.feedback.FeedbackCollector;
import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.embedder_support.util.UrlConstants;
...@@ -88,9 +90,10 @@ public class HelpAndFeedback { ...@@ -88,9 +90,10 @@ public class HelpAndFeedback {
public void show(final Activity activity, final String helpContext, Profile profile, public void show(final Activity activity, final String helpContext, Profile profile,
@Nullable String url) { @Nullable String url) {
RecordUserAction.record("MobileHelpAndFeedback"); RecordUserAction.record("MobileHelpAndFeedback");
new FeedbackCollector(activity, profile, url, null /* categoryTag */, new ChromeFeedbackCollector(activity, null /* categoryTag */, null /* description */,
null /* description */, helpContext, true /* takeScreenshot */, true /* takeScreenshot */,
null /* feed context */, collector -> show(activity, helpContext, collector)); new ChromeFeedbackCollector.InitParams(profile, url, helpContext),
collector -> show(activity, helpContext, collector));
} }
/** /**
...@@ -104,18 +107,18 @@ public class HelpAndFeedback { ...@@ -104,18 +107,18 @@ public class HelpAndFeedback {
*/ */
public void showFeedback(final Activity activity, Profile profile, @Nullable String url, public void showFeedback(final Activity activity, Profile profile, @Nullable String url,
@Nullable final String categoryTag) { @Nullable final String categoryTag) {
new FeedbackCollector(activity, profile, url, categoryTag, null /* description */, null, new ChromeFeedbackCollector(activity, categoryTag, null /* description */,
true /* takeScreenshot */, null /* feed context */, true /* takeScreenshot */,
new ChromeFeedbackCollector.InitParams(profile, url, null),
collector -> showFeedback(activity, collector)); collector -> showFeedback(activity, collector));
} }
/** /**
* Starts an activity prompting the user to enter feedback. * Starts an activity prompting the user to enter feedback for the interest feed.
* *
* @param activity The activity to use for starting the feedback activity and to take a * @param activity The activity to use for starting the feedback activity and to take a
* screenshot of. * screenshot of.
* @param profile the current profile. * @param profile the current profile.
* @param url the current URL. May be null.
* @param categoryTag The category that this feedback report falls under. * @param categoryTag The category that this feedback report falls under.
* @param feedContext Feed specific parameters (url, title, etc) to include with feedback. * @param feedContext Feed specific parameters (url, title, etc) to include with feedback.
* @param feedbackContext The context that describes the current feature being used. * @param feedbackContext The context that describes the current feature being used.
...@@ -123,8 +126,9 @@ public class HelpAndFeedback { ...@@ -123,8 +126,9 @@ public class HelpAndFeedback {
public void showFeedback(final Activity activity, Profile profile, @Nullable String url, public void showFeedback(final Activity activity, Profile profile, @Nullable String url,
@Nullable final String categoryTag, @Nullable final Map<String, String> feedContext, @Nullable final String categoryTag, @Nullable final Map<String, String> feedContext,
@Nullable final String feedbackContext) { @Nullable final String feedbackContext) {
new FeedbackCollector(activity, profile, url, categoryTag, null /* description */, new FeedFeedbackCollector(activity, categoryTag, null /* description */, feedbackContext,
feedbackContext, true /* takeScreenshot */, feedContext, true /* takeScreenshot */,
new FeedFeedbackCollector.InitParams(profile, url, feedContext),
collector -> showFeedback(activity, collector)); collector -> showFeedback(activity, collector));
} }
/** /**
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.feedback;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.app.Activity;
import android.os.Bundle;
import android.os.Looper;
import androidx.annotation.Nullable;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowLooper;
import org.chromium.base.Callback;
import org.chromium.base.ThreadUtils;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.Feature;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.test.util.browser.Features;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Test for {@link FeedFeedbackCollector}.
*/
@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class FeedFeedbackCollectorTest {
@Rule
public MockitoRule mMockitoRule = MockitoJUnit.rule();
// Enable the Features class, so we can override command line switches in the test.
@Rule
public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor();
@Mock
private Activity mActivity;
@Mock
private Profile mProfile;
// Test constants.
private static final String CATEGORY_TAG = "category_tag";
private static final String DESCRIPTION = "description";
private static final String FEEDBACK_CONTEXT = "feedback_context";
public static final String CARD_URL = "CardUrl";
public static final String CARD_PUBLISHER = "CardPublisher";
public static final String CARD_PUBLISHING_DATE = "CardPublishingDate";
public static final String CARD_TITLE = "CardTitle";
public static final String THE_URL = "https://www.google.com";
public static final String THE_PUBLISHER = "Google";
public static final String THE_PUBLISHING_DATE = "July 4, 1776";
public static final String THE_TITLE = "Declaration of Independence";
private static void verifySynchronousSources(Bundle bundle) {
assertTrue(bundle.containsKey(CARD_URL));
assertTrue(bundle.containsKey(CARD_PUBLISHER));
assertTrue(bundle.containsKey(CARD_PUBLISHING_DATE));
assertTrue(bundle.containsKey(CARD_TITLE));
assertEquals(THE_URL, bundle.getString(CARD_URL));
assertEquals(THE_PUBLISHER, bundle.getString(CARD_PUBLISHER));
assertEquals(THE_PUBLISHING_DATE, bundle.getString(CARD_PUBLISHING_DATE));
assertEquals(THE_TITLE, bundle.getString(CARD_TITLE));
}
private static class EmptyFeedFeedbackCollector extends FeedFeedbackCollector {
EmptyFeedFeedbackCollector(Activity activity, Profile profile, @Nullable String url,
@Nullable String categoryTag, @Nullable String description,
@Nullable String feedbackContext, boolean takeScreenshot,
@Nullable Map<String, String> feedContext, Callback<FeedbackCollector> callback) {
super(activity, categoryTag, description, feedbackContext, takeScreenshot,
new FeedFeedbackCollector.InitParams(profile, url, feedContext), callback);
}
// Override the async feedback sources to return an empty list, so we are only testing ths
// sync sources.
@Override
protected List<AsyncFeedbackSource> buildAsynchronousFeedbackSources(
FeedFeedbackCollector.InitParams initParams) {
return new ArrayList<>();
}
}
@Before
public void setUp() {
ThreadUtils.setUiThread(Looper.getMainLooper());
}
@After
public void tearDown() {
ThreadUtils.setUiThread(null);
}
@Test
@Feature({"Feed"})
@Features.EnableFeatures({ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS,
ChromeFeatureList.INTEREST_FEED_FEEDBACK})
public void
testFeedSynchronousData() {
@SuppressWarnings("unchecked")
Callback<FeedbackCollector> callback = mock(Callback.class);
Map<String, String> feedContext = new HashMap<String, String>();
feedContext.put(CARD_URL, THE_URL);
feedContext.put(CARD_PUBLISHER, THE_PUBLISHER);
feedContext.put(CARD_PUBLISHING_DATE, THE_PUBLISHING_DATE);
feedContext.put(CARD_TITLE, THE_TITLE);
FeedFeedbackCollector collector =
new EmptyFeedFeedbackCollector(mActivity, mProfile, null, CATEGORY_TAG, DESCRIPTION,
null, false, feedContext, (result) -> callback.onResult(result));
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
verify(callback, times(1)).onResult(collector);
ThreadUtils.runOnUiThreadBlocking(() -> {
verifySynchronousSources(collector.getBundle());
assertFalse(collector.getBundle().containsKey(
FeedbackContextFeedbackSource.FEEDBACK_CONTEXT_KEY));
assertEquals(CATEGORY_TAG, collector.getCategoryTag());
assertEquals(DESCRIPTION, collector.getDescription());
});
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment