1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Use of this source code is governed by a BSD-style license that can be
3dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// found in the LICENSE file.
4dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// TODO(rickcam): Bug 73183: Add unit tests for image loading
6dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
7dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include <cstdlib>
8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include <set>
9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/background_application_list_model.h"
11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/command_line.h"
13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/file_path.h"
14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/file_util.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/message_loop.h"
17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/stl_util-inl.h"
18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/extensions/extension_service.h"
19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/common/extensions/extension.h"
20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/test/testing_profile.h"
21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_registrar.h"
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "testing/gtest/include/gtest/gtest.h"
26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// This value is used to seed the PRNG at the beginning of a sequence of
28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// operations to produce a repeatable sequence.
29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#define RANDOM_SEED (0x33F7A7A7)
30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// For ExtensionService interface when it requires a path that is not used.
32dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenFilePath bogus_file_path() {
33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return FilePath(FILE_PATH_LITERAL("//foobar_nonexistent"));
34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenclass BackgroundApplicationListModelTest : public testing::Test {
37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen public:
38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  BackgroundApplicationListModelTest();
39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ~BackgroundApplicationListModelTest();
40dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  virtual void InitializeEmptyExtensionService();
42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen protected:
44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_ptr<Profile> profile_;
45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_refptr<ExtensionService> service_;
46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  MessageLoop loop_;
47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  BrowserThread ui_thread_;
48dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen};
49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// The message loop may be used in tests which require it to be an IO loop.
51dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenBackgroundApplicationListModelTest::BackgroundApplicationListModelTest()
52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    : loop_(MessageLoop::TYPE_IO),
53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      ui_thread_(BrowserThread::UI, &loop_) {
54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
56dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenBackgroundApplicationListModelTest::~BackgroundApplicationListModelTest() {
57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Drop reference to ExtensionService and TestingProfile, so that they can be
58dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // destroyed while BrowserThreads and MessageLoop are still around.  They
59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // are used in the destruction process.
60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  service_ = NULL;
61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  profile_.reset(NULL);
62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  MessageLoop::current()->RunAllPending();
63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// This is modeled on a similar routine in ExtensionServiceTestBase.
66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid BackgroundApplicationListModelTest::InitializeEmptyExtensionService() {
67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  TestingProfile* profile = new TestingProfile();
68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  profile_.reset(profile);
69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  service_ = profile->CreateExtensionService(
70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      CommandLine::ForCurrentProcess(),
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      bogus_file_path(), false);
72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  service_->set_extensions_enabled(true);
73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  service_->set_show_extensions_prompts(false);
74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  service_->OnLoadedInstalledExtensions(); /* Sends EXTENSIONS_READY */
75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Returns a barebones test Extension object with the specified |name|.  The
78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// returned extension will include background permission iff
79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// |background_permission| is true.
80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic scoped_refptr<Extension> CreateExtension(const std::string& name,
81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                                bool background_permission) {
82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DictionaryValue manifest;
83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  manifest.SetString(extension_manifest_keys::kVersion, "1.0.0.0");
84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  manifest.SetString(extension_manifest_keys::kName, name);
85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (background_permission) {
86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    ListValue* permissions = new ListValue();
87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    manifest.Set(extension_manifest_keys::kPermissions, permissions);
88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    permissions->Append(Value::CreateStringValue("background"));
89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
90dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string error;
91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_refptr<Extension> extension = Extension::Create(
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      bogus_file_path().AppendASCII(name), Extension::INVALID, manifest,
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      Extension::STRICT_ERROR_CHECKS, &error);
94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Cannot ASSERT_* here because that attempts an illegitimate return.
95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Cannot EXPECT_NE here because that assumes non-pointers unlike EXPECT_EQ
96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(extension.get() != NULL) << error;
97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return extension;
98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// With minimal test logic, verifies behavior over an explicit set of
101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// extensions, of which some are Background Apps and others are not.
102dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(BackgroundApplicationListModelTest, LoadExplicitExtensions) {
103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  InitializeEmptyExtensionService();
104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ExtensionService* service = profile_->GetExtensionService();
105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(service);
106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(service->is_ready());
107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(service->extensions());
108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(service->extensions()->empty());
109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_ptr<BackgroundApplicationListModel> model(
110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      new BackgroundApplicationListModel(profile_.get()));
111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(0U, model->size());
112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_refptr<Extension> ext1 = CreateExtension("alpha", false);
114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_refptr<Extension> ext2 = CreateExtension("bravo", false);
115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_refptr<Extension> ext3 = CreateExtension("charlie", false);
116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_refptr<Extension> bgapp1 = CreateExtension("delta", true);
117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_refptr<Extension> bgapp2 = CreateExtension("echo", true);
118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(service->extensions() != NULL);
119dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(0U, service->extensions()->size());
120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(0U, model->size());
121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Add alternating Extensions and Background Apps
122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_FALSE(BackgroundApplicationListModel::IsBackgroundApp(*ext1));
123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  service->AddExtension(ext1);
124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(1U, service->extensions()->size());
125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(0U, model->size());
126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(BackgroundApplicationListModel::IsBackgroundApp(*bgapp1));
127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  service->AddExtension(bgapp1);
128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(2U, service->extensions()->size());
129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(1U, model->size());
130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_FALSE(BackgroundApplicationListModel::IsBackgroundApp(*ext2));
131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  service->AddExtension(ext2);
132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(3U, service->extensions()->size());
133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(1U, model->size());
134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(BackgroundApplicationListModel::IsBackgroundApp(*bgapp2));
135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  service->AddExtension(bgapp2);
136dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(4U, service->extensions()->size());
137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(2U, model->size());
138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_FALSE(BackgroundApplicationListModel::IsBackgroundApp(*ext3));
139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  service->AddExtension(ext3);
140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(5U, service->extensions()->size());
141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(2U, model->size());
142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Remove in FIFO order.
143dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_FALSE(BackgroundApplicationListModel::IsBackgroundApp(*ext1));
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service->UninstallExtension(ext1->id(), false, NULL);
145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(4U, service->extensions()->size());
146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(2U, model->size());
147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(BackgroundApplicationListModel::IsBackgroundApp(*bgapp1));
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service->UninstallExtension(bgapp1->id(), false, NULL);
149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(3U, service->extensions()->size());
150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(1U, model->size());
151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_FALSE(BackgroundApplicationListModel::IsBackgroundApp(*ext2));
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service->UninstallExtension(ext2->id(), false, NULL);
153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(2U, service->extensions()->size());
154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(1U, model->size());
155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(BackgroundApplicationListModel::IsBackgroundApp(*bgapp2));
156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service->UninstallExtension(bgapp2->id(), false, NULL);
157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(1U, service->extensions()->size());
158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(0U, model->size());
159dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_FALSE(BackgroundApplicationListModel::IsBackgroundApp(*ext3));
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service->UninstallExtension(ext3->id(), false, NULL);
161dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(0U, service->extensions()->size());
162dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(0U, model->size());
163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
164dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
165dc0f95d653279beabeb9817299e2902918ba123eKristian Monsentypedef std::set<scoped_refptr<Extension> > ExtensionSet;
166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
167dc0f95d653279beabeb9817299e2902918ba123eKristian Monsennamespace {
168dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstd::string GenerateUniqueExtensionName() {
169dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  static int uniqueness = 0;
170dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::ostringstream output;
171dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  output << "Unique Named Extension " << uniqueness;
172dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ++uniqueness;
173dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return output.str();
174dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
175dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
176dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
177dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Verifies behavior with a pseudo-randomly generated set of actions: Adding and
178dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// removing extensions, of which some are Background Apps and others are not.
179dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(BackgroundApplicationListModelTest, LoadRandomExtension) {
180dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  InitializeEmptyExtensionService();
181dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ExtensionService* service = profile_->GetExtensionService();
182dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(service);
183dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(service->is_ready());
184dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(service->extensions());
185dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(service->extensions()->empty());
186dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_ptr<BackgroundApplicationListModel> model(
187dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      new BackgroundApplicationListModel(profile_.get()));
188dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_EQ(0U, model->size());
189dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
190dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  static const int kIterations = 500;
191dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ExtensionSet extensions;
192dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  size_t count = 0;
193dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  size_t expected = 0;
194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  srand(RANDOM_SEED);
195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  for (int index = 0; index < kIterations; ++index) {
196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (rand() % 2) {  // Add an extension
197dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      std::string name = GenerateUniqueExtensionName();
198dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      bool create_background = false;
199dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      if (rand() % 2) {
200dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        create_background = true;
201dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        ++expected;
202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
203dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      scoped_refptr<Extension> extension =
204dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          CreateExtension(name, create_background);
205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      ASSERT_EQ(BackgroundApplicationListModel::IsBackgroundApp(*extension),
206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                create_background);
207dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      extensions.insert(extension);
208dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      ++count;
209dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      ASSERT_EQ(count, extensions.size());
210dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      service->AddExtension(extension);
211dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      ASSERT_EQ(count, service->extensions()->size());
212dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      ASSERT_EQ(expected, model->size());
213dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    } else {  // Maybe remove an extension.
214dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      ExtensionSet::iterator cursor = extensions.begin();
215dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      if (cursor == extensions.end()) {
216dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        // Nothing to remove.  Just verify accounting.
217dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        ASSERT_EQ(0U, count);
218dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        ASSERT_EQ(0U, expected);
219dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        ASSERT_EQ(0U, service->extensions()->size());
220dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        ASSERT_EQ(0U, model->size());
221dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      } else {
222dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        // Randomly select which extension to remove
223dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        if (extensions.size() > 1) {
224dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          int offset = rand() % (extensions.size() - 1);
225dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          for (int index = 0; index < offset; ++index)
226dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen            ++cursor;
227dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        }
228dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        scoped_refptr<Extension> extension = cursor->get();
229dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        std::string id = extension->id();
230dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        if (BackgroundApplicationListModel::IsBackgroundApp(*extension))
231dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          --expected;
232dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        extensions.erase(cursor);
233dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        --count;
234dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        ASSERT_EQ(count, extensions.size());
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        service->UninstallExtension(extension->id(), false, NULL);
236dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        ASSERT_EQ(count, service->extensions()->size());
237dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        ASSERT_EQ(expected, model->size());
238dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
239dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
240dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
241dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
242