15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/app_list/apps_model_builder.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 124311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch#include "base/run_loop.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_function_test_utils.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service_unittest.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_sorting.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension_constants.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/manifest.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/pref_names.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/testing_profile.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/app_list/app_list_item_model.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kHostedAppId[] = "dceacbkfkmllgmjmbhgkpjegnodmildf"; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPackagedApp1Id[] = "emfkafnhnpcmabnnkckkchdilgeoekbo"; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPackagedApp2Id[] = "jlklkagmeajbjiobondfhiekepofmljl"; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get a string of all apps in |model| joined with ','. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetModelContent(app_list::AppListModel::Apps* model) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string content; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < model->item_count(); ++i) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i > 0) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content += ','; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content += model->GetItemAt(i)->title(); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return content; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<extensions::Extension> MakeApp(const std::string& name, 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& version, 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& url, 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& id) { 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string err; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DictionaryValue value; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value.SetString("name", name); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value.SetString("version", version); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value.SetString("app.launch.web_url", url); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<extensions::Extension> app = 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::Extension::Create( 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath(), 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::Manifest::INTERNAL, 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value, 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::Extension::WAS_INSTALLED_BY_DEFAULT, 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) id, 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &err); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(err, ""); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return app; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppsModelBuilderTest : public ExtensionServiceTestBase { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppsModelBuilderTest() {} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~AppsModelBuilderTest() {} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExtensionServiceTestBase::SetUp(); 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load "app_list" extensions test profile. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The test profile has 4 extensions: 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1 dummy extension, 2 packaged extension apps and 1 hosted extension app. 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath source_install_dir = data_dir_ 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .AppendASCII("app_list") 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .AppendASCII("Extensions"); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath pref_path = source_install_dir 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .DirName() 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .AppendASCII("Preferences"); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInstalledExtensionService(pref_path, source_install_dir); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_->Init(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There should be 4 extensions in the test profile. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExtensionSet* extensions = service_->extensions(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(static_cast<size_t>(4), extensions->size()); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppsModelBuilderTest, Build) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<app_list::AppListModel::Apps> model( 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new app_list::AppListModel::Apps); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppsModelBuilder builder(profile_.get(), model.get(), NULL); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) builder.Build(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The apps list would have 3 extension apps in the profile. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(std::string("Packaged App 1,Packaged App 2,Hosted App"), 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModelContent(model.get())); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AppsModelBuilderTest, HideWebStore) { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Install a "web store" app. 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<extensions::Extension> store = 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MakeApp("webstore", 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "0.0", 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "http://google.com", 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string(extension_misc::kWebStoreAppId)); 1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) service_->AddExtension(store.get()); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Install an "enterprise web store" app. 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<extensions::Extension> enterprise_store = 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MakeApp("enterprise_webstore", 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "0.0", 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "http://google.com", 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string(extension_misc::kEnterpriseWebStoreAppId)); 1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) service_->AddExtension(enterprise_store.get()); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Web stores should be present in the AppListModel. 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_list::AppListModel::Apps model1; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppsModelBuilder builder1(profile_.get(), &model1, NULL); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder1.Build(); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string content = GetModelContent(&model1); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_NE(std::string::npos, content.find("webstore")); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_NE(std::string::npos, content.find("enterprise_webstore")); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Activate the HideWebStoreIcon policy. 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_->GetPrefs()->SetBoolean(prefs::kHideWebStoreIcon, true); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Web stores should NOT be in the AppListModel. 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_list::AppListModel::Apps model2; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppsModelBuilder builder2(profile_.get(), &model2, NULL); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder2.Build(); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content = GetModelContent(&model2); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(std::string::npos, content.find("webstore")); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(std::string::npos, content.find("enterprise_webstore")); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppsModelBuilderTest, DisableAndEnable) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<app_list::AppListModel::Apps> model( 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new app_list::AppListModel::Apps); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppsModelBuilder builder(profile_.get(), model.get(), NULL); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) builder.Build(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_->DisableExtension(kHostedAppId, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::Extension::DISABLE_NONE); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(std::string("Packaged App 1,Packaged App 2,Hosted App"), 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModelContent(model.get())); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_->EnableExtension(kHostedAppId); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(std::string("Packaged App 1,Packaged App 2,Hosted App"), 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModelContent(model.get())); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AppsModelBuilderTest, Uninstall) { 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<app_list::AppListModel::Apps> model( 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new app_list::AppListModel::Apps); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppsModelBuilder builder(profile_.get(), model.get(), NULL); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder.Build(); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) service_->UninstallExtension(kPackagedApp2Id, false, NULL); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(std::string("Packaged App 1,Hosted App"), 1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetModelContent(model.get())); 1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1644311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch base::RunLoop().RunUntilIdle(); 1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST_F(AppsModelBuilderTest, UninstallTerminatedApp) { 1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<app_list::AppListModel::Apps> model( 1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch new app_list::AppListModel::Apps); 1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AppsModelBuilder builder(profile_.get(), model.get(), NULL); 1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch builder.Build(); 1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const extensions::Extension* app = 1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch service_->GetInstalledExtension(kPackagedApp2Id); 1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ASSERT_TRUE(app != NULL); 1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Simulate an app termination. 1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch service_->TrackTerminatedExtensionForTest(app); 1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch service_->UninstallExtension(kPackagedApp2Id, false, NULL); 1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_EQ(std::string("Packaged App 1,Hosted App"), 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetModelContent(model.get())); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1844311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch base::RunLoop().RunUntilIdle(); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppsModelBuilderTest, OrdinalPrefsChange) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<app_list::AppListModel::Apps> model( 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new app_list::AppListModel::Apps); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppsModelBuilder builder(profile_.get(), model.get(), NULL); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) builder.Build(); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting(); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::StringOrdinal package_app_page = 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorting->GetPageOrdinal(kPackagedApp1Id); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorting->SetPageOrdinal(kHostedAppId, package_app_page.CreateBefore()); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(std::string("Hosted App,Packaged App 1,Packaged App 2"), 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModelContent(model.get())); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::StringOrdinal app1_ordinal = 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorting->GetAppLaunchOrdinal(kPackagedApp1Id); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::StringOrdinal app2_ordinal = 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorting->GetAppLaunchOrdinal(kPackagedApp2Id); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorting->SetPageOrdinal(kHostedAppId, package_app_page); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorting->SetAppLaunchOrdinal(kHostedAppId, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app1_ordinal.CreateBetween(app2_ordinal)); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(std::string("Packaged App 1,Hosted App,Packaged App 2"), 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModelContent(model.get())); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppsModelBuilderTest, OnExtensionMoved) { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<app_list::AppListModel::Apps> model( 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new app_list::AppListModel::Apps); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppsModelBuilder builder(profile_.get(), model.get(), NULL); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) builder.Build(); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorting->SetPageOrdinal(kHostedAppId, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorting->GetPageOrdinal(kPackagedApp1Id)); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_->OnExtensionMoved(kHostedAppId, kPackagedApp1Id, kPackagedApp2Id); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(std::string("Packaged App 1,Hosted App,Packaged App 2"), 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModelContent(model.get())); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_->OnExtensionMoved(kHostedAppId, kPackagedApp2Id, std::string()); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(std::string("Packaged App 1,Packaged App 2,Hosted App"), 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModelContent(model.get())); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_->OnExtensionMoved(kHostedAppId, std::string(), kPackagedApp1Id); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(std::string("Hosted App,Packaged App 1,Packaged App 2"), 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModelContent(model.get())); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AppsModelBuilderTest, InvalidOrdinal) { 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Creates a no-ordinal case. 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting(); 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sorting->ClearOrdinals(kPackagedApp1Id); 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Creates an corrupted ordinal case. 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionScopedPrefs* scoped_prefs = service_->extension_prefs(); 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_prefs->UpdateExtensionPref( 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kHostedAppId, 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "page_ordinal", 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value::CreateStringValue("a corrupted ordinal")); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<app_list::AppListModel::Apps> model( 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new app_list::AppListModel::Apps); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppsModelBuilder builder(profile_.get(), model.get(), NULL); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This should not assert or crash. 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder.Build(); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AppsModelBuilderTest, OrdinalConfilicts) { 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Creates conflict ordinals for app1 and app2. 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::StringOrdinal conflict_ordinal = 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::StringOrdinal::CreateInitialOrdinal(); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting(); 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sorting->SetPageOrdinal(kHostedAppId, conflict_ordinal); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sorting->SetAppLaunchOrdinal(kHostedAppId, conflict_ordinal); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sorting->SetPageOrdinal(kPackagedApp1Id, conflict_ordinal); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sorting->SetAppLaunchOrdinal(kPackagedApp1Id, conflict_ordinal); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sorting->SetPageOrdinal(kPackagedApp2Id, conflict_ordinal); 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sorting->SetAppLaunchOrdinal(kPackagedApp2Id, conflict_ordinal); 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<app_list::AppListModel::Apps> model( 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new app_list::AppListModel::Apps); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AppsModelBuilder builder(profile_.get(), model.get(), NULL); 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) builder.Build(); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // By default, conflicted items are sorted by their app ids. 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(std::string("Hosted App,Packaged App 1,Packaged App 2"), 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetModelContent(model.get())); 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Move hosted app between app1 and app2 and it should not crash. 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) service_->OnExtensionMoved(kHostedAppId, kPackagedApp1Id, kPackagedApp2Id); 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(std::string("Packaged App 1,Hosted App,Packaged App 2"), 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetModelContent(model.get())); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 284