blob: b4ef370d9914f65151a20e054186b8d4ec3c302e [file] [log] [blame]
// Copyright 2017 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.
#include "components/language/content/browser/geo_language_provider.h"
#include <memory>
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/macros.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/timer/timer.h"
#include "components/language/content/browser/test_utils.h"
#include "components/language/content/browser/ulp_language_code_locator/ulp_language_code_locator.h"
#include "components/language/core/common/language_experiments.h"
#include "components/prefs/testing_pref_service.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace language {
class GeoLanguageProviderTest : public testing::Test {
public:
GeoLanguageProviderTest()
: geo_language_provider_(task_environment_.GetMainThreadTaskRunner()),
mock_ip_geo_location_provider_(&mock_geo_location_) {
language::GeoLanguageProvider::OverrideBinderForTesting(
base::BindRepeating(&MockIpGeoLocationProvider::Bind,
base::Unretained(&mock_ip_geo_location_provider_)));
language::GeoLanguageProvider::RegisterLocalStatePrefs(
local_state_.registry());
language::UlpLanguageCodeLocator::RegisterLocalStatePrefs(
local_state_.registry());
}
~GeoLanguageProviderTest() override {
language::GeoLanguageProvider::OverrideBinderForTesting(
base::NullCallback());
}
protected:
std::vector<std::string> GetCurrentGeoLanguages() {
return geo_language_provider_.CurrentGeoLanguages();
}
void StartGeoLanguageProvider() {
geo_language_provider_.StartUp(&local_state_);
}
void MoveToLocation(float latitude, float longitude) {
mock_geo_location_.MoveToLocation(latitude, longitude);
}
int GetQueryNextPositionCalledTimes() {
return mock_geo_location_.query_next_position_called_times();
}
void SetGeoLanguages(const std::vector<std::string>& languages) {
geo_language_provider_.SetGeoLanguages(languages);
}
void SetUpCachedLanguages(const std::vector<std::string>& languages) {
base::ListValue cache_list;
for (size_t i = 0; i < languages.size(); ++i) {
cache_list.Set(i, std::make_unique<base::Value>(languages[i]));
}
local_state_.Set(GeoLanguageProvider::kCachedGeoLanguagesPref, cache_list);
}
const std::vector<std::string> GetCachedLanguages() {
std::vector<std::string> languages;
const base::ListValue* const cached_languages_list =
local_state_.GetList(GeoLanguageProvider::kCachedGeoLanguagesPref);
for (const auto& language_value : cached_languages_list->GetList()) {
languages.push_back(language_value.GetString());
}
return languages;
}
base::test::ScopedFeatureList scoped_feature_list_;
base::test::TaskEnvironment task_environment_{
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
private:
// Object under test.
GeoLanguageProvider geo_language_provider_;
MockGeoLocation mock_geo_location_;
MockIpGeoLocationProvider mock_ip_geo_location_provider_;
TestingPrefServiceSimple local_state_;
};
TEST_F(GeoLanguageProviderTest, GetCurrentGeoLanguages_India) {
// Setup a random place in West Bengal, India.
MoveToLocation(23.0, 85.7);
StartGeoLanguageProvider();
task_environment_.RunUntilIdle();
std::vector<std::string> expected_langs = {"hi", "bn", "en"};
EXPECT_EQ(expected_langs, GetCurrentGeoLanguages());
}
TEST_F(GeoLanguageProviderTest, GetCurrentGeoLanguages_OutsideIndia) {
// Setup a random place in Montreal, Canada.
MoveToLocation(45.5, 73.5);
StartGeoLanguageProvider();
task_environment_.RunUntilIdle();
std::vector<std::string> expected_langs = {};
EXPECT_EQ(expected_langs, GetCurrentGeoLanguages());
}
TEST_F(GeoLanguageProviderTest, NoFrequentCalls) {
// Setup a random place in Madhya Pradesh, India.
MoveToLocation(23.0, 80.0);
StartGeoLanguageProvider();
task_environment_.RunUntilIdle();
const std::vector<std::string>& result = GetCurrentGeoLanguages();
std::vector<std::string> expected_langs = {"hi", "en"};
EXPECT_EQ(expected_langs, result);
task_environment_.FastForwardBy(base::Hours(12));
EXPECT_EQ(1, GetQueryNextPositionCalledTimes());
EXPECT_EQ(expected_langs, GetCachedLanguages());
}
TEST_F(GeoLanguageProviderTest, ButDoCallInTheNextDay) {
// Setup a random place in Madhya Pradesh, India.
MoveToLocation(23.0, 80.0);
StartGeoLanguageProvider();
task_environment_.RunUntilIdle();
std::vector<std::string> result = GetCurrentGeoLanguages();
std::vector<std::string> expected_langs = {"hi", "en"};
EXPECT_EQ(expected_langs, result);
EXPECT_EQ(expected_langs, GetCachedLanguages());
// Move to another random place in Karnataka, India.
MoveToLocation(23.0, 85.7);
task_environment_.FastForwardBy(base::Hours(25));
EXPECT_EQ(2, GetQueryNextPositionCalledTimes());
result = GetCurrentGeoLanguages();
std::vector<std::string> expected_langs_2 = {"hi", "bn", "en"};
EXPECT_EQ(expected_langs_2, result);
EXPECT_EQ(expected_langs_2, GetCachedLanguages());
}
TEST_F(GeoLanguageProviderTest, CachedLanguagesPresent) {
SetUpCachedLanguages({"en", "fr"});
MoveToLocation(23.0, 80.0);
StartGeoLanguageProvider();
std::vector<std::string> expected_langs = {"en", "fr"};
EXPECT_EQ(expected_langs, GetCurrentGeoLanguages());
task_environment_.RunUntilIdle();
expected_langs = {"hi", "en"};
EXPECT_EQ(expected_langs, GetCurrentGeoLanguages());
EXPECT_EQ(expected_langs, GetCachedLanguages());
}
} // namespace language