cb91510e78f8ec00bdddbb70ee5929593351240c
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / customization_document_unittest.cc
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/customization_document.h"
6
7 #include "base/message_loop/message_loop.h"
8 #include "base/prefs/testing_pref_service.h"
9 #include "base/run_loop.h"
10 #include "base/strings/stringprintf.h"
11 #include "chrome/browser/chromeos/net/network_portal_detector_test_impl.h"
12 #include "chrome/browser/extensions/external_provider_impl.h"
13 #include "chrome/browser/prefs/browser_prefs.h"
14 #include "chrome/browser/prefs/pref_service_mock_factory.h"
15 #include "chrome/browser/prefs/pref_service_syncable.h"
16 #include "chrome/browser/ui/app_list/app_list_syncable_service.h"
17 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h"
18 #include "chrome/test/base/testing_browser_process.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "chromeos/dbus/dbus_thread_manager.h"
21 #include "chromeos/network/network_handler.h"
22 #include "chromeos/system/mock_statistics_provider.h"
23 #include "components/user_prefs/pref_registry_syncable.h"
24 #include "content/public/test/test_browser_thread_bundle.h"
25 #include "extensions/common/extension.h"
26 #include "extensions/common/manifest.h"
27 #include "net/http/http_response_headers.h"
28 #include "net/http/http_status_code.h"
29 #include "net/url_request/test_url_fetcher_factory.h"
30 #include "net/url_request/url_request_status.h"
31 #include "testing/gmock/include/gmock/gmock.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33
34 using ::testing::Exactly;
35 using ::testing::Invoke;
36 using ::testing::Mock;
37 using ::testing::_;
38
39 namespace {
40
41 const char kGoodStartupManifest[] =
42     "{"
43     "  \"version\": \"1.0\","
44     "  \"initial_locale\" : \"en-US\","
45     "  \"initial_timezone\" : \"US/Pacific\","
46     "  \"keyboard_layout\" : \"xkb:us::eng\","
47     "  \"setup_content\" : {"
48     "    \"en-US\" : {"
49     "      \"eula_page\" : \"file:///opt/oem/eula/en-US/eula.html\","
50     "    },"
51     "    \"ru-RU\" : {"
52     "      \"eula_page\" : \"file:///opt/oem/eula/ru-RU/eula.html\","
53     "    },"
54     "    \"default\" : {"
55     "      \"eula_page\" : \"file:///opt/oem/eula/en/eula.html\","
56     "    },"
57     "  },"
58     "  \"hwid_map\" : ["
59     "    {"
60     "      \"hwid_mask\": \"ZGA*34\","
61     "      \"initial_locale\" : \"ja\","
62     "      \"initial_timezone\" : \"Asia/Tokyo\","
63     "      \"keyboard_layout\" : \"mozc-jp\","
64     "    },"
65     "    {"
66     "      \"hwid_mask\": \"Mario 1?3*\","
67     "      \"initial_locale\" : \"ru-RU\","
68     "      \"initial_timezone\" : \"Europe/Moscow\","
69     "      \"keyboard_layout\" : \"xkb:ru::rus\","
70     "    },"
71     "  ],"
72     "}";
73
74 const char kBadManifest[] = "{\"version\": \"1\"}";
75
76 const char kGoodServicesManifest[] =
77     "{"
78     "  \"version\": \"1.0\","
79     "  \"default_apps\": [\n"
80     "    \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\n"
81     "    \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"\n"
82     "  ],\n"
83     "  \"localized_content\": {\n"
84     "    \"en-US\": {\n"
85     "      \"default_apps_folder_name\": \"EN-US OEM Name\"\n"
86     "    },\n"
87     "    \"en\": {\n"
88     "      \"default_apps_folder_name\": \"EN OEM Name\"\n"
89     "    },\n"
90     "    \"default\": {\n"
91     "      \"default_apps_folder_name\": \"Default OEM Name\"\n"
92     "    }\n"
93     "  }\n"
94     "}";
95
96 const char kDummyCustomizationID[] = "test-dummy";
97
98 // Note the path name must be the same as in shill stub.
99 const char kStubEthernetServicePath[] = "eth1";
100
101 }  // anonymous namespace
102
103 namespace chromeos {
104
105 using ::testing::_;
106 using ::testing::DoAll;
107 using ::testing::NotNull;
108 using ::testing::Return;
109 using ::testing::SetArgumentPointee;
110
111 TEST(StartupCustomizationDocumentTest, Basic) {
112   system::MockStatisticsProvider mock_statistics_provider;
113   EXPECT_CALL(mock_statistics_provider, GetMachineStatistic(_, NotNull()))
114       .WillRepeatedly(Return(false));
115   EXPECT_CALL(mock_statistics_provider,
116       GetMachineStatistic(std::string("hardware_class"), NotNull()))
117           .WillOnce(DoAll(SetArgumentPointee<1>(std::string("Mario 12345")),
118                           Return(true)));
119   StartupCustomizationDocument customization(&mock_statistics_provider,
120                                              kGoodStartupManifest);
121   EXPECT_EQ("ru-RU", customization.initial_locale());
122   EXPECT_EQ("Europe/Moscow", customization.initial_timezone());
123   EXPECT_EQ("xkb:ru::rus", customization.keyboard_layout());
124
125   EXPECT_EQ("file:///opt/oem/eula/en-US/eula.html",
126             customization.GetEULAPage("en-US"));
127   EXPECT_EQ("file:///opt/oem/eula/ru-RU/eula.html",
128             customization.GetEULAPage("ru-RU"));
129   EXPECT_EQ("file:///opt/oem/eula/en/eula.html",
130             customization.GetEULAPage("ja"));
131 }
132
133 TEST(StartupCustomizationDocumentTest, VPD) {
134   system::MockStatisticsProvider mock_statistics_provider;
135   EXPECT_CALL(mock_statistics_provider,
136       GetMachineStatistic(std::string("hardware_class"), NotNull()))
137           .WillOnce(DoAll(SetArgumentPointee<1>(std::string("Mario 12345")),
138                           Return(true)));
139   EXPECT_CALL(mock_statistics_provider,
140       GetMachineStatistic(std::string("initial_locale"), NotNull()))
141           .WillOnce(DoAll(SetArgumentPointee<1>(std::string("ja")),
142                           Return(true)));
143   EXPECT_CALL(mock_statistics_provider,
144       GetMachineStatistic(std::string("initial_timezone"), NotNull()))
145           .WillOnce(DoAll(SetArgumentPointee<1>(std::string("Asia/Tokyo")),
146                           Return(true)));
147   EXPECT_CALL(mock_statistics_provider,
148       GetMachineStatistic(std::string("keyboard_layout"), NotNull()))
149           .WillOnce(DoAll(SetArgumentPointee<1>(std::string("mozc-jp")),
150                           Return(true)));
151   StartupCustomizationDocument customization(&mock_statistics_provider,
152                                              kGoodStartupManifest);
153   EXPECT_TRUE(customization.IsReady());
154   EXPECT_EQ("ja", customization.initial_locale());
155   EXPECT_EQ("Asia/Tokyo", customization.initial_timezone());
156   EXPECT_EQ("mozc-jp", customization.keyboard_layout());
157 }
158
159 TEST(StartupCustomizationDocumentTest, BadManifest) {
160   system::MockStatisticsProvider mock_statistics_provider;
161   StartupCustomizationDocument customization(&mock_statistics_provider,
162                                              kBadManifest);
163   EXPECT_FALSE(customization.IsReady());
164 }
165
166 class TestURLFetcherCallback {
167  public:
168   scoped_ptr<net::FakeURLFetcher> CreateURLFetcher(
169       const GURL& url,
170       net::URLFetcherDelegate* d,
171       const std::string& response_data,
172       net::HttpStatusCode response_code,
173       net::URLRequestStatus::Status status) {
174     scoped_ptr<net::FakeURLFetcher> fetcher(
175         new net::FakeURLFetcher(url, d, response_data, response_code, status));
176     OnRequestCreate(url, fetcher.get());
177     return fetcher.Pass();
178   }
179   MOCK_METHOD2(OnRequestCreate,
180                void(const GURL&, net::FakeURLFetcher*));
181 };
182
183 void AddMimeHeader(const GURL& url, net::FakeURLFetcher* fetcher) {
184   scoped_refptr<net::HttpResponseHeaders> download_headers =
185       new net::HttpResponseHeaders("");
186   download_headers->AddHeader("Content-Type: application/json");
187   fetcher->set_response_headers(download_headers);
188 }
189
190 class MockExternalProviderVisitor
191     : public extensions::ExternalProviderInterface::VisitorInterface {
192  public:
193   MockExternalProviderVisitor() {}
194
195   MOCK_METHOD6(OnExternalExtensionFileFound,
196                bool(const std::string&,
197                     const base::Version*,
198                     const base::FilePath&,
199                     extensions::Manifest::Location,
200                     int,
201                     bool));
202   MOCK_METHOD6(OnExternalExtensionUpdateUrlFound,
203                bool(const std::string&,
204                     const std::string&,
205                     const GURL&,
206                     extensions::Manifest::Location,
207                     int,
208                     bool));
209   MOCK_METHOD1(OnExternalProviderReady,
210                void(const extensions::ExternalProviderInterface* provider));
211 };
212
213 class ServicesCustomizationDocumentTest : public testing::Test {
214  protected:
215   ServicesCustomizationDocumentTest()
216     : factory_(NULL,
217                base::Bind(&TestURLFetcherCallback::CreateURLFetcher,
218                base::Unretained(&url_callback_))) {
219   }
220
221   // testing::Test:
222   virtual void SetUp() OVERRIDE {
223     ServicesCustomizationDocument::InitializeForTesting();
224
225     EXPECT_CALL(mock_statistics_provider_, GetMachineStatistic(_, NotNull()))
226         .WillRepeatedly(Return(false));
227     chromeos::system::StatisticsProvider::SetTestProvider(
228         &mock_statistics_provider_);
229
230     DBusThreadManager::InitializeWithStub();
231     NetworkHandler::Initialize();
232
233     NetworkPortalDetector::InitializeForTesting(&network_portal_detector_);
234     NetworkPortalDetector::CaptivePortalState online_state;
235     online_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE;
236     online_state.response_code = 204;
237     network_portal_detector_.SetDefaultNetworkPathForTesting(
238         kStubEthernetServicePath);
239     network_portal_detector_.SetDetectionResultsForTesting(
240         kStubEthernetServicePath, online_state);
241
242     TestingBrowserProcess::GetGlobal()->SetLocalState(&local_state_);
243     ServicesCustomizationDocument::RegisterPrefs(local_state_.registry());
244   }
245
246   virtual void TearDown() OVERRIDE {
247     TestingBrowserProcess::GetGlobal()->SetLocalState(NULL);
248     NetworkHandler::Shutdown();
249     DBusThreadManager::Shutdown();
250     NetworkPortalDetector::InitializeForTesting(NULL);
251     chromeos::system::StatisticsProvider::SetTestProvider(NULL);
252
253     ServicesCustomizationDocument::ShutdownForTesting();
254   }
255
256   void RunUntilIdle() {
257     base::RunLoop().RunUntilIdle();
258   }
259
260   void AddCustomizationIdToVp(const std::string& id) {
261     EXPECT_CALL(mock_statistics_provider_,
262         GetMachineStatistic(system::kCustomizationIdKey, NotNull()))
263             .WillOnce(DoAll(SetArgumentPointee<1>(id),
264                             Return(true)));
265   }
266
267   void AddExpectedManifest(const std::string& id,
268                            const std::string& manifest) {
269     GURL url(base::StringPrintf(ServicesCustomizationDocument::kManifestUrl,
270                                 id.c_str()));
271     factory_.SetFakeResponse(url,
272                              manifest,
273                              net::HTTP_OK,
274                              net::URLRequestStatus::SUCCESS);
275     EXPECT_CALL(url_callback_, OnRequestCreate(url, _))
276       .Times(Exactly(1))
277       .WillRepeatedly(Invoke(AddMimeHeader));
278   }
279
280   void AddManifestNotFound(const std::string& id) {
281     GURL url(base::StringPrintf(ServicesCustomizationDocument::kManifestUrl,
282                                 id.c_str()));
283     factory_.SetFakeResponse(url,
284                              std::string(),
285                              net::HTTP_NOT_FOUND,
286                              net::URLRequestStatus::SUCCESS);
287     EXPECT_CALL(url_callback_, OnRequestCreate(url, _))
288       .Times(Exactly(1))
289       .WillRepeatedly(Invoke(AddMimeHeader));
290   }
291
292   scoped_ptr<TestingProfile> CreateProfile() {
293     TestingProfile::Builder profile_builder;
294     PrefServiceMockFactory factory;
295     scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
296         new user_prefs::PrefRegistrySyncable);
297     scoped_ptr<PrefServiceSyncable> prefs(
298         factory.CreateSyncable(registry.get()));
299     chrome::RegisterUserProfilePrefs(registry.get());
300     profile_builder.SetPrefService(prefs.Pass());
301     return profile_builder.Build();
302   }
303
304  private:
305   system::MockStatisticsProvider mock_statistics_provider_;
306   content::TestBrowserThreadBundle thread_bundle_;
307   TestingPrefServiceSimple local_state_;
308   TestURLFetcherCallback url_callback_;
309   net::FakeURLFetcherFactory factory_;
310   NetworkPortalDetectorTestImpl network_portal_detector_;
311 };
312
313 TEST_F(ServicesCustomizationDocumentTest, Basic) {
314   AddCustomizationIdToVp(kDummyCustomizationID);
315   AddExpectedManifest(kDummyCustomizationID, kGoodServicesManifest);
316
317   ServicesCustomizationDocument* doc =
318       ServicesCustomizationDocument::GetInstance();
319   EXPECT_FALSE(doc->IsReady());
320
321   doc->StartFetching();
322   RunUntilIdle();
323   EXPECT_TRUE(doc->IsReady());
324
325   GURL wallpaper_url;
326   EXPECT_FALSE(doc->GetDefaultWallpaperUrl(&wallpaper_url));
327   EXPECT_EQ("", wallpaper_url.spec());
328
329   std::vector<std::string> default_apps;
330   EXPECT_TRUE(doc->GetDefaultApps(&default_apps));
331   ASSERT_EQ(default_apps.size(), 2u);
332
333   EXPECT_EQ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", default_apps[0]);
334   EXPECT_EQ("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", default_apps[1]);
335
336   EXPECT_EQ("EN-US OEM Name", doc->GetOemAppsFolderName("en-US"));
337   EXPECT_EQ("EN OEM Name", doc->GetOemAppsFolderName("en"));
338   EXPECT_EQ("Default OEM Name", doc->GetOemAppsFolderName("ru"));
339 }
340
341 TEST_F(ServicesCustomizationDocumentTest, NoCustomizationIdInVpd) {
342   ServicesCustomizationDocument* doc =
343       ServicesCustomizationDocument::GetInstance();
344   EXPECT_FALSE(doc->IsReady());
345
346   scoped_ptr<TestingProfile> profile = CreateProfile();
347   extensions::ExternalLoader* loader = doc->CreateExternalLoader(profile.get());
348   EXPECT_TRUE(loader);
349
350   MockExternalProviderVisitor visitor;
351   scoped_ptr<extensions::ExternalProviderImpl> provider(
352       new extensions::ExternalProviderImpl(
353           &visitor,
354           loader,
355           profile.get(),
356           extensions::Manifest::EXTERNAL_PREF,
357           extensions::Manifest::EXTERNAL_PREF_DOWNLOAD,
358           extensions::Extension::FROM_WEBSTORE |
359               extensions::Extension::WAS_INSTALLED_BY_DEFAULT));
360
361   EXPECT_CALL(visitor, OnExternalExtensionFileFound(_, _, _, _, _, _))
362       .Times(0);
363   EXPECT_CALL(visitor, OnExternalExtensionUpdateUrlFound(_, _, _, _, _, _))
364       .Times(0);
365   EXPECT_CALL(visitor, OnExternalProviderReady(_))
366       .Times(1);
367
368   // Manually request a load.
369   RunUntilIdle();
370   loader->StartLoading();
371   Mock::VerifyAndClearExpectations(&visitor);
372
373   RunUntilIdle();
374   // Empty customization is used when there is no customization ID in VPD.
375   EXPECT_TRUE(doc->IsReady());
376 }
377
378 TEST_F(ServicesCustomizationDocumentTest, DefaultApps) {
379   AddCustomizationIdToVp(kDummyCustomizationID);
380   AddExpectedManifest(kDummyCustomizationID, kGoodServicesManifest);
381
382   ServicesCustomizationDocument* doc =
383       ServicesCustomizationDocument::GetInstance();
384   EXPECT_FALSE(doc->IsReady());
385
386   scoped_ptr<TestingProfile> profile = CreateProfile();
387   extensions::ExternalLoader* loader = doc->CreateExternalLoader(profile.get());
388   EXPECT_TRUE(loader);
389
390   app_list::AppListSyncableServiceFactory::GetInstance()->
391       SetTestingFactoryAndUse(
392           profile.get(),
393           &app_list::AppListSyncableServiceFactory::BuildInstanceFor);
394
395   MockExternalProviderVisitor visitor;
396   scoped_ptr<extensions::ExternalProviderImpl> provider(
397       new extensions::ExternalProviderImpl(
398           &visitor,
399           loader,
400           profile.get(),
401           extensions::Manifest::EXTERNAL_PREF,
402           extensions::Manifest::EXTERNAL_PREF_DOWNLOAD,
403           extensions::Extension::FROM_WEBSTORE |
404               extensions::Extension::WAS_INSTALLED_BY_DEFAULT));
405
406   EXPECT_CALL(visitor, OnExternalExtensionFileFound(_, _, _, _, _, _))
407       .Times(0);
408   EXPECT_CALL(visitor, OnExternalExtensionUpdateUrlFound(_, _, _, _, _, _))
409       .Times(0);
410   EXPECT_CALL(visitor, OnExternalProviderReady(_))
411       .Times(1);
412
413   // Manually request a load.
414   loader->StartLoading();
415   Mock::VerifyAndClearExpectations(&visitor);
416
417   EXPECT_CALL(visitor, OnExternalExtensionFileFound(_, _, _, _, _, _))
418       .Times(0);
419   EXPECT_CALL(visitor, OnExternalExtensionUpdateUrlFound(_, _, _, _, _, _))
420       .Times(2);
421   EXPECT_CALL(visitor, OnExternalProviderReady(_))
422       .Times(1);
423
424   RunUntilIdle();
425   EXPECT_TRUE(doc->IsReady());
426
427   app_list::AppListSyncableService* service =
428       app_list::AppListSyncableServiceFactory::GetForProfile(profile.get());
429   ASSERT_TRUE(service);
430   EXPECT_EQ("EN OEM Name", service->GetOemFolderNameForTest());
431 }
432
433 TEST_F(ServicesCustomizationDocumentTest, CustomizationManifestNotFound) {
434   AddCustomizationIdToVp(kDummyCustomizationID);
435   AddManifestNotFound(kDummyCustomizationID);
436
437   ServicesCustomizationDocument* doc =
438       ServicesCustomizationDocument::GetInstance();
439   EXPECT_FALSE(doc->IsReady());
440
441   scoped_ptr<TestingProfile> profile = CreateProfile();
442   extensions::ExternalLoader* loader = doc->CreateExternalLoader(profile.get());
443   EXPECT_TRUE(loader);
444
445   MockExternalProviderVisitor visitor;
446   scoped_ptr<extensions::ExternalProviderImpl> provider(
447       new extensions::ExternalProviderImpl(
448           &visitor,
449           loader,
450           profile.get(),
451           extensions::Manifest::EXTERNAL_PREF,
452           extensions::Manifest::EXTERNAL_PREF_DOWNLOAD,
453           extensions::Extension::FROM_WEBSTORE |
454               extensions::Extension::WAS_INSTALLED_BY_DEFAULT));
455
456   EXPECT_CALL(visitor, OnExternalExtensionFileFound(_, _, _, _, _, _))
457       .Times(0);
458   EXPECT_CALL(visitor, OnExternalExtensionUpdateUrlFound(_, _, _, _, _, _))
459       .Times(0);
460   EXPECT_CALL(visitor, OnExternalProviderReady(_))
461       .Times(1);
462
463   // Manually request a load.
464   loader->StartLoading();
465   Mock::VerifyAndClearExpectations(&visitor);
466
467   EXPECT_CALL(visitor, OnExternalExtensionFileFound(_, _, _, _, _, _))
468       .Times(0);
469   EXPECT_CALL(visitor, OnExternalExtensionUpdateUrlFound(_, _, _, _, _, _))
470       .Times(0);
471   EXPECT_CALL(visitor, OnExternalProviderReady(_))
472       .Times(1);
473
474   RunUntilIdle();
475   EXPECT_TRUE(doc->IsReady());
476 }
477
478 }  // namespace chromeos