Index: chrome/browser/engagement/site_engagement_service_unittest.cc |
diff --git a/chrome/browser/engagement/site_engagement_service_unittest.cc b/chrome/browser/engagement/site_engagement_service_unittest.cc |
index e43d6d63f38d409f1452d918097426f4ac572b93..77a2f4d91e58768f9cc3d4ae7162515c9730baa3 100644 |
--- a/chrome/browser/engagement/site_engagement_service_unittest.cc |
+++ b/chrome/browser/engagement/site_engagement_service_unittest.cc |
@@ -27,6 +27,7 @@ |
#include "components/history/core/browser/history_database_params.h" |
#include "components/history/core/browser/history_service.h" |
#include "components/history/core/test/test_history_database.h" |
+#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/navigation_entry.h" |
#include "content/public/browser/page_navigator.h" |
#include "content/public/browser/web_contents.h" |
@@ -97,6 +98,35 @@ std::unique_ptr<KeyedService> BuildTestHistoryService( |
} // namespace |
+class CallbackTester { |
+ public: |
+ CallbackTester(const GURL& url, double score) |
+ : url_(url), score_(score), callback_called_(false), run_loop_() {} |
+ |
+ void EngagementCallback(const GURL& url, double score) { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ EXPECT_EQ(url_, url); |
+ EXPECT_EQ(score_, score); |
+ set_callback_called(true); |
+ run_loop_.Quit(); |
+ } |
+ |
+ void Wait() { run_loop_.Run(); } |
+ |
+ bool callback_called() { return callback_called_; } |
+ void set_callback_called(bool callback_called) { |
+ callback_called_ = callback_called; |
+ } |
+ |
+ private: |
+ GURL url_; |
+ double score_; |
+ bool callback_called_; |
+ base::RunLoop run_loop_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CallbackTester); |
+}; |
+ |
class SiteEngagementServiceTest : public ChromeRenderViewHostTestHarness { |
public: |
void SetUp() override { |
@@ -983,6 +1013,255 @@ TEST_F(SiteEngagementServiceTest, EngagementLevel) { |
url2, SiteEngagementService::ENGAGEMENT_LEVEL_MAX)); |
} |
+TEST_F(SiteEngagementServiceTest, RegisterCallbacks) { |
+ base::SimpleTestClock* clock = new base::SimpleTestClock(); |
+ std::unique_ptr<SiteEngagementService> service( |
+ new SiteEngagementService(profile(), base::WrapUnique(clock))); |
+ |
+ base::Time current_day = GetReferenceTime(); |
+ clock->SetNow(current_day); |
+ GURL url_score_1("http://www.google.com/maps"); |
+ GURL url_score_2("http://www.google.com/drive"); |
+ GURL url_score_3("http://www.google.com/"); |
+ GURL url_level_1("http://maps.google.com/"); |
+ GURL url_level_2("http://maps.google.com/path"); |
+ GURL url_level_3("http://maps.google.com/foo/bar"); |
+ GURL url_level_4("http://drive.google.com/"); |
+ GURL url_level_5("http://drive.google.com/path"); |
+ GURL url_level_6("http://drive.google.com/foo/bar"); |
+ GURL url_not_called_1("https://www.google.com/"); |
+ GURL url_not_called_2("http://foobar.com/foo/bar"); |
+ GURL url_not_called_3("http://maps.google.com.au"); |
+ |
+ // Register some callbacks that should never be called. |
+ CallbackTester tester_not_called_1(url_not_called_1, 1); |
+ CallbackTester tester_not_called_2( |
+ url_not_called_2, SiteEngagementScore::GetMinimumEngagementIncrement()); |
+ CallbackTester tester_not_called_3(url_not_called_1, 5); |
+ |
+ service->RegisterCallback(base::Bind(&CallbackTester::EngagementCallback, |
+ base::Unretained(&tester_not_called_1)), |
+ url_not_called_1, 1); |
+ service->RegisterCallback(base::Bind(&CallbackTester::EngagementCallback, |
+ base::Unretained(&tester_not_called_2)), |
+ url_not_called_2, |
+ SiteEngagementService::ENGAGEMENT_LEVEL_LOW); |
+ service->RegisterCallback(base::Bind(&CallbackTester::EngagementCallback, |
+ base::Unretained(&tester_not_called_3)), |
+ url_not_called_3, 5); |
+ |
+ // Register a callback for score 0. It should be called immediately with the |
+ // origin as an argument. |
+ { |
+ CallbackTester tester(url_score_3, 0); |
+ service->RegisterCallback(base::Bind(&CallbackTester::EngagementCallback, |
+ base::Unretained(&tester)), url_score_1, 0); |
+ tester.Wait(); |
+ |
+ EXPECT_TRUE(tester.callback_called()); |
+ EXPECT_FALSE(tester_not_called_1.callback_called()); |
+ EXPECT_FALSE(tester_not_called_2.callback_called()); |
+ EXPECT_FALSE(tester_not_called_3.callback_called()); |
+ EXPECT_EQ(3u, service->engagement_callbacks_.size()); |
+ } |
+ |
+ // Register a callback for score 1. |
+ { |
+ CallbackTester tester(url_score_1, 1); |
+ service->RegisterCallback(base::Bind(&CallbackTester::EngagementCallback, |
+ base::Unretained(&tester)), url_score_1, 1); |
+ service->AddPoints(url_score_1, 1); |
+ tester.Wait(); |
+ |
+ EXPECT_TRUE(tester.callback_called()); |
+ EXPECT_FALSE(tester_not_called_1.callback_called()); |
+ EXPECT_FALSE(tester_not_called_2.callback_called()); |
+ EXPECT_FALSE(tester_not_called_3.callback_called()); |
+ EXPECT_EQ(3u, service->engagement_callbacks_.size()); |
+ } |
+ |
+ // Register a callback for score 1.5 on a different URL, but same origin. |
+ { |
+ CallbackTester tester(url_score_1, 1.5); |
+ service->RegisterCallback(base::Bind(&CallbackTester::EngagementCallback, |
+ base::Unretained(&tester)), url_score_2, 1.5); |
+ service->AddPoints(url_score_1, 0.25); |
+ EXPECT_FALSE(tester.callback_called()); |
+ service->AddPoints(url_score_1, 0.25); |
+ tester.Wait(); |
+ |
+ EXPECT_TRUE(tester.callback_called()); |
+ EXPECT_FALSE(tester_not_called_1.callback_called()); |
+ EXPECT_FALSE(tester_not_called_2.callback_called()); |
+ EXPECT_FALSE(tester_not_called_3.callback_called()); |
+ EXPECT_EQ(3u, service->engagement_callbacks_.size()); |
+ } |
+ |
+ // Register a callback for score 2.5 on the origin. |
+ { |
+ CallbackTester tester(url_score_3, 2.5); |
+ service->RegisterCallback(base::Bind(&CallbackTester::EngagementCallback, |
+ base::Unretained(&tester)), url_score_1, 2.5); |
+ service->AddPoints(url_score_3, 0.5); |
+ EXPECT_FALSE(tester.callback_called()); |
+ service->AddPoints(url_score_3, 0.3); |
+ EXPECT_FALSE(tester.callback_called()); |
+ service->AddPoints(url_score_3, 0.2); |
+ tester.Wait(); |
+ |
+ EXPECT_TRUE(tester.callback_called()); |
+ EXPECT_FALSE(tester_not_called_1.callback_called()); |
+ EXPECT_FALSE(tester_not_called_2.callback_called()); |
+ EXPECT_FALSE(tester_not_called_3.callback_called()); |
+ EXPECT_EQ(3u, service->engagement_callbacks_.size()); |
+ } |
+ |
+ // Register a callback for score 1 on the origin. It should be called |
+ // immediately. |
+ { |
+ CallbackTester tester(url_score_3, 2.5); |
+ service->RegisterCallback(base::Bind(&CallbackTester::EngagementCallback, |
+ base::Unretained(&tester)), url_score_2, 1); |
+ tester.Wait(); |
+ |
+ EXPECT_TRUE(tester.callback_called()); |
+ EXPECT_FALSE(tester_not_called_1.callback_called()); |
+ EXPECT_FALSE(tester_not_called_2.callback_called()); |
+ EXPECT_FALSE(tester_not_called_3.callback_called()); |
+ EXPECT_EQ(3u, service->engagement_callbacks_.size()); |
+ } |
+ |
+ // Register a callback for score 100 on the origin. |
+ { |
+ CallbackTester tester(url_score_3, 100); |
+ service->RegisterCallback(base::Bind(&CallbackTester::EngagementCallback, |
+ base::Unretained(&tester)), url_score_2, 100); |
+ |
+ service->AddPoints(url_score_2, 2.5); |
+ for (int i = 0; i < 18; ++i) { |
+ current_day += base::TimeDelta::FromDays(1); |
+ clock->SetNow(current_day); |
+ service->AddPoints(url_score_1, 5.0); |
+ } |
+ |
+ // Last one to tip over 100 engagement. |
+ EXPECT_FALSE(tester.callback_called()); |
+ current_day += base::TimeDelta::FromDays(1); |
+ clock->SetNow(current_day); |
+ service->AddPoints(url_score_3, 5.0); |
+ tester.Wait(); |
+ |
+ EXPECT_TRUE(tester.callback_called()); |
+ EXPECT_FALSE(tester_not_called_1.callback_called()); |
+ EXPECT_FALSE(tester_not_called_2.callback_called()); |
+ EXPECT_FALSE(tester_not_called_3.callback_called()); |
+ EXPECT_EQ(3u, service->engagement_callbacks_.size()); |
+ } |
+ |
+ // Register a callback for level NONE. It should be called immediately. |
+ { |
+ CallbackTester tester(url_level_1, 0); |
+ service->RegisterCallback(base::Bind(&CallbackTester::EngagementCallback, |
+ base::Unretained(&tester)), |
+ url_level_1, |
+ SiteEngagementService::ENGAGEMENT_LEVEL_NONE); |
+ tester.Wait(); |
+ |
+ EXPECT_TRUE(tester.callback_called()); |
+ EXPECT_FALSE(tester_not_called_1.callback_called()); |
+ EXPECT_FALSE(tester_not_called_2.callback_called()); |
+ EXPECT_FALSE(tester_not_called_3.callback_called()); |
+ EXPECT_EQ(3u, service->engagement_callbacks_.size()); |
+ } |
+ |
+ // Register a callback for level LOW. |
+ { |
+ CallbackTester tester(url_level_2, |
+ SiteEngagementScore::GetMinimumEngagementIncrement()); |
+ service->RegisterCallback(base::Bind(&CallbackTester::EngagementCallback, |
+ base::Unretained(&tester)), |
+ url_level_1, |
+ SiteEngagementService::ENGAGEMENT_LEVEL_LOW); |
+ service->AddPoints(url_level_2, |
+ SiteEngagementScore::GetMinimumEngagementIncrement()); |
+ tester.Wait(); |
+ |
+ EXPECT_TRUE(tester.callback_called()); |
+ EXPECT_FALSE(tester_not_called_1.callback_called()); |
+ EXPECT_FALSE(tester_not_called_2.callback_called()); |
+ EXPECT_FALSE(tester_not_called_3.callback_called()); |
+ EXPECT_EQ(3u, service->engagement_callbacks_.size()); |
+ } |
+ |
+ // Register a callback for level MEDIUM. |
+ { |
+ CallbackTester tester(url_level_2, |
+ SiteEngagementScore::GetMediumEngagementBoundary()); |
+ service->RegisterCallback(base::Bind(&CallbackTester::EngagementCallback, |
+ base::Unretained(&tester)), |
+ url_level_3, |
+ SiteEngagementService::ENGAGEMENT_LEVEL_MEDIUM); |
+ service->AddPoints(url_level_2, 5.0); |
+ tester.Wait(); |
+ |
+ EXPECT_TRUE(tester.callback_called()); |
+ EXPECT_FALSE(tester_not_called_1.callback_called()); |
+ EXPECT_FALSE(tester_not_called_2.callback_called()); |
+ EXPECT_FALSE(tester_not_called_3.callback_called()); |
+ EXPECT_EQ(3u, service->engagement_callbacks_.size()); |
+ } |
+ |
+ // Register a callback for level HIGH. |
+ { |
+ CallbackTester tester(url_level_5, |
+ SiteEngagementScore::GetHighEngagementBoundary()); |
+ service->RegisterCallback(base::Bind(&CallbackTester::EngagementCallback, |
+ base::Unretained(&tester)), |
+ url_level_4, |
+ SiteEngagementService::ENGAGEMENT_LEVEL_HIGH); |
+ for (int i = 0; i < 9; ++i) { |
+ current_day += base::TimeDelta::FromDays(1); |
+ clock->SetNow(current_day); |
+ service->AddPoints(url_level_4, 5.0); |
+ } |
+ EXPECT_FALSE(tester.callback_called()); |
+ current_day += base::TimeDelta::FromDays(1); |
+ clock->SetNow(current_day); |
+ service->AddPoints(url_level_5, 5.0); |
+ tester.Wait(); |
+ |
+ EXPECT_TRUE(tester.callback_called()); |
+ EXPECT_FALSE(tester_not_called_1.callback_called()); |
+ EXPECT_FALSE(tester_not_called_2.callback_called()); |
+ EXPECT_FALSE(tester_not_called_3.callback_called()); |
+ EXPECT_EQ(3u, service->engagement_callbacks_.size()); |
+ } |
+ |
+ // Register a callback for level MAX. |
+ { |
+ CallbackTester tester(url_level_6, 100); |
+ service->RegisterCallback(base::Bind(&CallbackTester::EngagementCallback, |
+ base::Unretained(&tester)), |
+ url_level_5, |
+ SiteEngagementService::ENGAGEMENT_LEVEL_MAX); |
+ for (int i = 0; i < 9; ++i) { |
+ current_day += base::TimeDelta::FromDays(1); |
+ clock->SetNow(current_day); |
+ service->AddPoints(url_level_4, 5.0); |
+ } |
+ EXPECT_FALSE(tester.callback_called()); |
+ current_day += base::TimeDelta::FromDays(1); |
+ clock->SetNow(current_day); |
+ service->AddPoints(url_level_6, 5.0); |
+ tester.Wait(); |
+ |
+ EXPECT_FALSE(tester_not_called_1.callback_called()); |
+ EXPECT_FALSE(tester_not_called_2.callback_called()); |
+ EXPECT_FALSE(tester_not_called_3.callback_called()); |
+ EXPECT_EQ(3u, service->engagement_callbacks_.size()); |
+ } |
+} |
+ |
TEST_F(SiteEngagementServiceTest, ScoreDecayHistograms) { |
base::SimpleTestClock* clock = new base::SimpleTestClock(); |
std::unique_ptr<SiteEngagementService> service( |