diff --git a/browser/ui/webui/brave_rewards_ui.cc b/browser/ui/webui/brave_rewards_ui.cc index 480f44e0574f..bf67174be9f0 100644 --- a/browser/ui/webui/brave_rewards_ui.cc +++ b/browser/ui/webui/brave_rewards_ui.cc @@ -550,11 +550,15 @@ void RewardsDOMHandler::GetAddresses(const base::ListValue* args) { void RewardsDOMHandler::OnAutoContributePropsReady( std::unique_ptr props) { - rewards_service_->GetContentSiteList(0, 0, - props->contribution_min_time, props->reconcile_stamp, + rewards_service_->GetContentSiteList( + 0, + 0, + props->contribution_min_time, + props->reconcile_stamp, props->contribution_non_verified, + props->contribution_min_visits, base::Bind(&RewardsDOMHandler::OnContentSiteList, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr())); } void RewardsDOMHandler::OnContentSiteUpdated( diff --git a/components/brave_rewards/browser/publisher_info_database.cc b/components/brave_rewards/browser/publisher_info_database.cc index 58b296d603d4..0abec8149ab7 100644 --- a/components/brave_rewards/browser/publisher_info_database.cc +++ b/components/brave_rewards/browser/publisher_info_database.cc @@ -434,7 +434,7 @@ bool PublisherInfoDatabase::InsertOrUpdateActivityInfo( activity_info_insert.BindInt(5, info.month); activity_info_insert.BindInt(6, info.year); activity_info_insert.BindInt64(7, info.reconcile_stamp); - activity_info_insert.BindInt64(8, info.visits); + activity_info_insert.BindInt(8, info.visits); return activity_info_insert.Run(); } @@ -458,7 +458,7 @@ bool PublisherInfoDatabase::GetActivityList( std::string query = "SELECT ai.publisher_id, ai.duration, ai.score, " "ai.percent, ai.weight, pi.verified, pi.excluded, " "ai.month, ai.year, pi.name, pi.url, pi.provider, " - "pi.favIcon, ai.reconcile_stamp " + "pi.favIcon, ai.reconcile_stamp, ai.visits " "FROM activity_info AS ai " "INNER JOIN publisher_info AS pi " "ON ai.publisher_id = pi.publisher_id " @@ -499,6 +499,10 @@ bool PublisherInfoDatabase::GetActivityList( query += " AND ai.percent >= ?"; } + if (filter.min_visits > 0) { + query += " AND ai.visits >= ?"; + } + if (!filter.non_verified) { query += " AND pi.verified = 1"; } @@ -554,6 +558,10 @@ bool PublisherInfoDatabase::GetActivityList( info_sql.BindInt(column++, filter.percent); } + if (filter.min_visits > 0) { + info_sql.BindInt(column++, filter.min_visits); + } + while (info_sql.Step()) { std::string id(info_sql.ColumnString(0)); ledger::ACTIVITY_MONTH month( @@ -572,6 +580,7 @@ bool PublisherInfoDatabase::GetActivityList( info.provider = info_sql.ColumnString(11); info.favicon_url = info_sql.ColumnString(12); info.reconcile_stamp = info_sql.ColumnInt64(13); + info.visits = info_sql.ColumnInt(14); info.excluded = static_cast( info_sql.ColumnInt(6)); @@ -579,7 +588,7 @@ bool PublisherInfoDatabase::GetActivityList( list->push_back(info); } - return list; + return true; } /** diff --git a/components/brave_rewards/browser/publisher_info_database_unittest.cc b/components/brave_rewards/browser/publisher_info_database_unittest.cc index 14966c230bdb..9d05570bd422 100644 --- a/components/brave_rewards/browser/publisher_info_database_unittest.cc +++ b/components/brave_rewards/browser/publisher_info_database_unittest.cc @@ -184,12 +184,12 @@ TEST_F(PublisherInfoDatabaseTest, InsertOrUpdateActivityInfo) { ledger::PublisherInfo info; info.id = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - info.verified = false; + info.verified = true; info.excluded = ledger::PUBLISHER_EXCLUDE::DEFAULT; info.name = "name"; info.url = "https://brave.com"; - info.provider = ""; - info.favicon_url = ""; + info.provider = "youtube"; + info.favicon_url = "favicon.ico"; info.duration = 10; info.score = 1.1; info.percent = 100; @@ -220,6 +220,22 @@ TEST_F(PublisherInfoDatabaseTest, InsertOrUpdateActivityInfo) { EXPECT_EQ(static_cast(info_sql.ColumnInt64(8)), info.reconcile_stamp); + query = "SELECT * FROM publisher_info WHERE publisher_id=?"; + sql::Statement info_sql_0(GetDB().GetUniqueStatement(query.c_str())); + + info_sql_0.BindString(0, info.id); + + EXPECT_TRUE(info_sql_0.Step()); + EXPECT_EQ(CountTableRows("publisher_info"), 1); + EXPECT_EQ(info_sql_0.ColumnString(0), info.id); + EXPECT_EQ(info_sql_0.ColumnBool(1), info.verified); + EXPECT_EQ(static_cast(info_sql_0.ColumnInt(2)), + info.excluded); + EXPECT_EQ(info_sql_0.ColumnString(3), info.name); + EXPECT_EQ(info_sql_0.ColumnString(4), info.favicon_url); + EXPECT_EQ(info_sql_0.ColumnString(5), info.url); + EXPECT_EQ(info_sql_0.ColumnString(6), info.provider); + /** * Make sure that second insert is update and not insert, * month, year and stamp is unique key @@ -402,7 +418,183 @@ TEST_F(PublisherInfoDatabaseTest, InsertOrUpdateRecurringDonation) { } TEST_F(PublisherInfoDatabaseTest, InsertPendingContribution) { + /** + * Good path + */ + base::ScopedTempDir temp_dir; + base::FilePath db_file; + CreateTempDatabase(&temp_dir, &db_file); + + ledger::PendingContribution contribution1; + contribution1.publisher_key = "key1"; + contribution1.amount = 10; + contribution1.added_date = 10; + contribution1.viewing_id = "fsodfsdnf23r23rn"; + contribution1.category = ledger::REWARDS_CATEGORY::AUTO_CONTRIBUTE; + + ledger::PendingContribution contribution2; + contribution2.publisher_key = "key2"; + contribution2.amount = 20; + contribution2.viewing_id = "aafsofdfsdnf23r23rn"; + contribution2.category = ledger::REWARDS_CATEGORY::DIRECT_DONATION; + + ledger::PendingContributionList list; + list.list_.push_back(contribution1); + list.list_.push_back(contribution2); + + bool success = publisher_info_database_->InsertPendingContribution( + list); + EXPECT_TRUE(success); + + std::string query = "SELECT * FROM pending_contribution"; + sql::Statement info_sql(GetDB().GetUniqueStatement(query.c_str())); + + EXPECT_EQ(CountTableRows("pending_contribution"), 2); + + // First contribution + EXPECT_TRUE(info_sql.Step()); + EXPECT_EQ(info_sql.ColumnString(0), contribution1.publisher_key); + EXPECT_EQ(info_sql.ColumnDouble(1), contribution1.amount); + EXPECT_GE(info_sql.ColumnInt64(2), 20); + EXPECT_EQ(info_sql.ColumnString(3), contribution1.viewing_id); + EXPECT_EQ(static_cast(info_sql.ColumnInt(4)), + contribution1.category); + + // Second contribution + EXPECT_TRUE(info_sql.Step()); + EXPECT_EQ(info_sql.ColumnString(0), contribution2.publisher_key); + EXPECT_EQ(info_sql.ColumnDouble(1), contribution2.amount); + EXPECT_GE(info_sql.ColumnInt64(2), 0); + EXPECT_EQ(info_sql.ColumnString(3), contribution2.viewing_id); + EXPECT_EQ(static_cast(info_sql.ColumnInt(4)), + contribution2.category); +} + +TEST_F(PublisherInfoDatabaseTest, GetActivityList) { + base::ScopedTempDir temp_dir; + base::FilePath db_file; + CreateTempDatabase(&temp_dir, &db_file); + // first entry publisher + ledger::PublisherInfo info; + info.id = "publisher_1"; + info.name = "publisher_name_1"; + info.url = "https://publisher1.com"; + info.excluded = ledger::PUBLISHER_EXCLUDE::DEFAULT; + info.duration = 0; + info.verified = false; + info.visits = 0; + info.month = ledger::ACTIVITY_MONTH::JANUARY; + info.year = 1970; + info.reconcile_stamp = 1; + EXPECT_TRUE(publisher_info_database_->InsertOrUpdateActivityInfo(info)); + + // with duration + info.id = "publisher_2"; + info.name = "publisher_name_2"; + info.url = "https://publisher2.com"; + info.excluded = ledger::PUBLISHER_EXCLUDE::DEFAULT; + info.duration = 100; + info.verified = false; + info.visits = 1; + EXPECT_TRUE(publisher_info_database_->InsertOrUpdateActivityInfo(info)); + + // verified publisher + info.id = "publisher_3"; + info.name = "publisher_name_3"; + info.url = "https://publisher3.com"; + info.excluded = ledger::PUBLISHER_EXCLUDE::DEFAULT; + info.duration = 1; + info.verified = true; + info.visits = 1; + EXPECT_TRUE(publisher_info_database_->InsertOrUpdateActivityInfo(info)); + + // excluded publisher + info.id = "publisher_4"; + info.name = "publisher_name_4"; + info.url = "https://publisher4.com"; + info.excluded = ledger::PUBLISHER_EXCLUDE::EXCLUDED; + info.duration = 1; + info.verified = false; + info.visits = 1; + EXPECT_TRUE(publisher_info_database_->InsertOrUpdateActivityInfo(info)); + + // with visits + info.id = "publisher_5"; + info.name = "publisher_name_5"; + info.url = "https://publisher5.com"; + info.excluded = ledger::PUBLISHER_EXCLUDE::DEFAULT; + info.duration = 1; + info.verified = false; + info.visits = 10; + EXPECT_TRUE(publisher_info_database_->InsertOrUpdateActivityInfo(info)); + + // full + info.id = "publisher_6"; + info.name = "publisher_name_6"; + info.url = "https://publisher6.com"; + info.excluded = ledger::PUBLISHER_EXCLUDE::INCLUDED; + info.duration = 5000; + info.verified = true; + info.visits = 10; + EXPECT_TRUE(publisher_info_database_->InsertOrUpdateActivityInfo(info)); + + EXPECT_EQ(CountTableRows("activity_info"), 6); + EXPECT_EQ(CountTableRows("publisher_info"), 6); + + /** + * Get publisher with min_duration + */ + ledger::PublisherInfoList list_1; + ledger::ActivityInfoFilter filter_1; + filter_1.min_duration = 50; + filter_1.excluded = ledger::EXCLUDE_FILTER::FILTER_ALL; + EXPECT_TRUE(publisher_info_database_->GetActivityList(0, 0, filter_1, &list_1)); + EXPECT_EQ(static_cast(list_1.size()), 2); + + EXPECT_EQ(list_1.at(0).id, "publisher_2"); + EXPECT_EQ(list_1.at(1).id, "publisher_6"); + + /** + * Get verified publishers + */ + ledger::PublisherInfoList list_2; + ledger::ActivityInfoFilter filter_2; + filter_2.non_verified = false; + filter_2.excluded = ledger::EXCLUDE_FILTER::FILTER_ALL; + EXPECT_TRUE(publisher_info_database_->GetActivityList(0, 0, filter_2, &list_2)); + EXPECT_EQ(static_cast(list_2.size()), 2); + + EXPECT_EQ(list_2.at(0).id, "publisher_3"); + EXPECT_EQ(list_2.at(1).id, "publisher_6"); + + /** + * Get all publishers that are not excluded + */ + ledger::PublisherInfoList list_3; + ledger::ActivityInfoFilter filter_3; + filter_3.excluded = ledger::EXCLUDE_FILTER::FILTER_ALL_EXCEPT_EXCLUDED; + EXPECT_TRUE(publisher_info_database_->GetActivityList(0, 0, filter_3, &list_3)); + EXPECT_EQ(static_cast(list_3.size()), 5); + + EXPECT_EQ(list_3.at(0).id, "publisher_1"); + EXPECT_EQ(list_3.at(1).id, "publisher_2"); + EXPECT_EQ(list_3.at(2).id, "publisher_3"); + EXPECT_EQ(list_3.at(3).id, "publisher_5"); + EXPECT_EQ(list_3.at(4).id, "publisher_6"); + + /** + * Get publisher with min_visits + */ + ledger::PublisherInfoList list_4; + ledger::ActivityInfoFilter filter_4; + filter_4.min_visits = 5; + filter_4.excluded = ledger::EXCLUDE_FILTER::FILTER_ALL; + EXPECT_TRUE(publisher_info_database_->GetActivityList(0, 0, filter_4, &list_4)); + EXPECT_EQ(static_cast(list_4.size()), 2); + + EXPECT_EQ(list_4.at(0).id, "publisher_5"); + EXPECT_EQ(list_4.at(1).id, "publisher_6"); } } // namespace brave_rewards diff --git a/components/brave_rewards/browser/rewards_service.h b/components/brave_rewards/browser/rewards_service.h index ec32738584c8..361e9c31307f 100644 --- a/components/brave_rewards/browser/rewards_service.h +++ b/components/brave_rewards/browser/rewards_service.h @@ -73,6 +73,7 @@ class RewardsService : public KeyedService { uint64_t min_visit_time, uint64_t reconcile_stamp, bool allow_non_verified, + uint32_t min_visits, const GetContentSiteListCallback& callback) = 0; virtual void FetchGrant(const std::string& lang, const std::string& paymentId) = 0; virtual void GetGrantCaptcha() = 0; diff --git a/components/brave_rewards/browser/rewards_service_impl.cc b/components/brave_rewards/browser/rewards_service_impl.cc index a3967b8d1f86..269e0ddad2f8 100644 --- a/components/brave_rewards/browser/rewards_service_impl.cc +++ b/components/brave_rewards/browser/rewards_service_impl.cc @@ -425,6 +425,7 @@ void RewardsServiceImpl::GetContentSiteList( uint64_t min_visit_time, uint64_t reconcile_stamp, bool allow_non_verified, + uint32_t min_visits, const GetContentSiteListCallback& callback) { ledger::ActivityInfoFilter filter; filter.month = ledger::ACTIVITY_MONTH::ANY; @@ -436,6 +437,7 @@ void RewardsServiceImpl::GetContentSiteList( ledger::EXCLUDE_FILTER::FILTER_ALL_EXCEPT_EXCLUDED; filter.percent = 1; filter.non_verified = allow_non_verified; + filter.min_visits = min_visits; GetActivityInfoList(start, limit, filter, diff --git a/components/brave_rewards/browser/rewards_service_impl.h b/components/brave_rewards/browser/rewards_service_impl.h index e404b1710e2c..78c5de76f77e 100644 --- a/components/brave_rewards/browser/rewards_service_impl.h +++ b/components/brave_rewards/browser/rewards_service_impl.h @@ -95,6 +95,7 @@ class RewardsServiceImpl : public RewardsService, uint64_t min_visit_time, uint64_t reconcile_stamp, bool allow_non_verified, + uint32_t min_visits, const GetContentSiteListCallback& callback) override; void OnGetContentSiteList( const GetContentSiteListCallback& callback, diff --git a/vendor/bat-native-ledger/include/bat/ledger/publisher_info.h b/vendor/bat-native-ledger/include/bat/ledger/publisher_info.h index 6c164431c9c0..7a2699d96966 100644 --- a/vendor/bat-native-ledger/include/bat/ledger/publisher_info.h +++ b/vendor/bat-native-ledger/include/bat/ledger/publisher_info.h @@ -69,6 +69,7 @@ LEDGER_EXPORT struct ActivityInfoFilter { uint64_t min_duration; uint64_t reconcile_stamp; bool non_verified; + uint32_t min_visits; }; LEDGER_EXPORT struct ContributionInfo { diff --git a/vendor/bat-native-ledger/src/bat/ledger/ledger.cc b/vendor/bat-native-ledger/src/bat/ledger/ledger.cc index df46502413bd..daf5da045cd3 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/ledger.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/ledger.cc @@ -132,7 +132,8 @@ ActivityInfoFilter::ActivityInfoFilter() : percent(0), min_duration(0), reconcile_stamp(0), - non_verified(true) {} + non_verified(true), + min_visits(0u) {} ActivityInfoFilter::ActivityInfoFilter(const ActivityInfoFilter& filter) : id(filter.id), @@ -143,7 +144,8 @@ ActivityInfoFilter::ActivityInfoFilter(const ActivityInfoFilter& filter) : order_by(filter.order_by), min_duration(filter.min_duration), reconcile_stamp(filter.reconcile_stamp), - non_verified(filter.non_verified) {} + non_verified(filter.non_verified), + min_visits(filter.min_visits) {} ActivityInfoFilter::~ActivityInfoFilter() {} @@ -185,6 +187,12 @@ bool ActivityInfoFilter::loadFromJson(const std::string& json) { order_by.push_back(std::make_pair(i.name.GetString(), i.value.GetBool())); } + + if (d.HasMember("min_visits") && d["min_visits"].IsUint()) { + min_visits = d["min_visits"].GetUint(); + } else { + min_visits = 0u; + } } return !error; diff --git a/vendor/bat-native-ledger/src/bat_contribution.cc b/vendor/bat-native-ledger/src/bat_contribution.cc index 7e0fe904f3e0..974b10868d07 100644 --- a/vendor/bat-native-ledger/src/bat_contribution.cc +++ b/vendor/bat-native-ledger/src/bat_contribution.cc @@ -238,7 +238,8 @@ void BatContribution::StartAutoContribute() { ledger::EXCLUDE_FILTER::FILTER_ALL_EXCEPT_EXCLUDED, true, current_reconcile_stamp, - ledger_->GetPublisherAllowNonVerified()); + ledger_->GetPublisherAllowNonVerified(), + ledger_->GetPublisherMinVisits()); ledger_->GetActivityInfoList( 0, 0, diff --git a/vendor/bat-native-ledger/src/bat_get_media.cc b/vendor/bat-native-ledger/src/bat_get_media.cc index 4d5e146bcd78..4fe1939f9b22 100644 --- a/vendor/bat-native-ledger/src/bat_get_media.cc +++ b/vendor/bat-native-ledger/src/bat_get_media.cc @@ -608,7 +608,8 @@ void BatGetMedia::fetchPublisherDataFromDB( ledger::EXCLUDE_FILTER::FILTER_ALL, false, ledger_->GetReconcileStamp(), - true); + true, + false); ledger_->GetPanelPublisherInfo(filter, std::bind(&BatGetMedia::onFetchPublisherFromDBResponse, this, _1, _2, windowId, visit_data, providerType, diff --git a/vendor/bat-native-ledger/src/bat_helper.cc b/vendor/bat-native-ledger/src/bat_helper.cc index 58c617c42270..4e75333e3b20 100644 --- a/vendor/bat-native-ledger/src/bat_helper.cc +++ b/vendor/bat-native-ledger/src/bat_helper.cc @@ -2655,6 +2655,9 @@ static bool ignore_ = false; writer.String("non_verified"); writer.Bool(info.non_verified); + writer.String("min_visits"); + writer.Uint(info.min_visits); + writer.EndObject(); } diff --git a/vendor/bat-native-ledger/src/bat_publishers.cc b/vendor/bat-native-ledger/src/bat_publishers.cc index 18f4e15c2cdc..9b8ac77759dc 100644 --- a/vendor/bat-native-ledger/src/bat_publishers.cc +++ b/vendor/bat-native-ledger/src/bat_publishers.cc @@ -95,7 +95,8 @@ void BatPublishers::saveVisit(const std::string& publisher_id, ledger::EXCLUDE_FILTER::FILTER_ALL, false, ledger_->GetReconcileStamp(), - true); + true, + false); ledger::PublisherInfoCallback callbackGetPublishers = std::bind(&BatPublishers::saveVisitInternal, this, @@ -118,7 +119,8 @@ ledger::ActivityInfoFilter BatPublishers::CreateActivityFilter( ledger::EXCLUDE_FILTER::FILTER_ALL, true, 0, - true); + true, + false); } ledger::ActivityInfoFilter BatPublishers::CreateActivityFilter( @@ -132,7 +134,8 @@ ledger::ActivityInfoFilter BatPublishers::CreateActivityFilter( excluded, true, 0, - true); + true, + false); } ledger::ActivityInfoFilter BatPublishers::CreateActivityFilter( @@ -146,7 +149,8 @@ ledger::ActivityInfoFilter BatPublishers::CreateActivityFilter( ledger::EXCLUDE_FILTER::FILTER_ALL, min_duration, 0, - true); + true, + false); } ledger::ActivityInfoFilter BatPublishers::CreateActivityFilter( @@ -156,7 +160,8 @@ ledger::ActivityInfoFilter BatPublishers::CreateActivityFilter( ledger::EXCLUDE_FILTER excluded, bool min_duration, const uint64_t& currentReconcileStamp, - bool non_verified) { + bool non_verified, + bool min_visits) { ledger::ActivityInfoFilter filter; filter.id = publisher_id; filter.month = month; @@ -165,6 +170,7 @@ ledger::ActivityInfoFilter BatPublishers::CreateActivityFilter( filter.min_duration = min_duration ? getPublisherMinVisitTime() : 0; filter.reconcile_stamp = currentReconcileStamp; filter.non_verified = non_verified; + filter.min_visits = min_visits ? getPublisherMinVisits() : 0; return filter; } @@ -595,7 +601,8 @@ void BatPublishers::synopsisNormalizer() { ledger::EXCLUDE_FILTER::FILTER_ALL_EXCEPT_EXCLUDED, true, ledger_->GetReconcileStamp(), - ledger_->GetPublisherAllowNonVerified()); + ledger_->GetPublisherAllowNonVerified(), + ledger_->GetPublisherMinVisits()); // TODO SZ: We pull the whole list currently, I don't think it consumes lots of RAM, but could. // We need to limit it and iterate. ledger_->GetActivityInfoList( @@ -832,7 +839,8 @@ void BatPublishers::getPublisherActivityFromUrl( ledger::EXCLUDE_FILTER::FILTER_ALL, false, ledger_->GetReconcileStamp(), - true); + true, + false); ledger::VisitData new_data; new_data.domain = visit_data.domain; diff --git a/vendor/bat-native-ledger/src/bat_publishers.h b/vendor/bat-native-ledger/src/bat_publishers.h index ecfaf3b671c6..32aff96fbf53 100644 --- a/vendor/bat-native-ledger/src/bat_publishers.h +++ b/vendor/bat-native-ledger/src/bat_publishers.h @@ -121,7 +121,8 @@ class BatPublishers : public ledger::LedgerCallbackHandler { ledger::EXCLUDE_FILTER excluded, bool min_duration, const uint64_t& currentReconcileStamp, - bool non_verified); + bool non_verified, + bool min_visits); void clearAllBalanceReports(); void NormalizeContributeWinners(ledger::PublisherInfoList* newList, diff --git a/vendor/bat-native-ledger/src/ledger_impl.cc b/vendor/bat-native-ledger/src/ledger_impl.cc index 15e2954f77e1..088ae6aa186c 100644 --- a/vendor/bat-native-ledger/src/ledger_impl.cc +++ b/vendor/bat-native-ledger/src/ledger_impl.cc @@ -892,14 +892,16 @@ ledger::ActivityInfoFilter LedgerImpl::CreateActivityFilter( ledger::EXCLUDE_FILTER excluded, bool min_duration, const uint64_t& currentReconcileStamp, - bool non_verified) { + bool non_verified, + bool min_visits) { return bat_publishers_->CreateActivityFilter(publisher_id, month, year, excluded, min_duration, currentReconcileStamp, - non_verified); + non_verified, + min_visits); } diff --git a/vendor/bat-native-ledger/src/ledger_impl.h b/vendor/bat-native-ledger/src/ledger_impl.h index fec7da811105..ba9368fadbbf 100644 --- a/vendor/bat-native-ledger/src/ledger_impl.h +++ b/vendor/bat-native-ledger/src/ledger_impl.h @@ -209,7 +209,8 @@ class LedgerImpl : public ledger::Ledger, ledger::EXCLUDE_FILTER excluded, bool min_duration, const uint64_t& currentReconcileStamp, - bool non_verified); + bool non_verified, + bool min_visits); std::unique_ptr Log( const char* file, int line,