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 "base/bind.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/stringprintf.h"
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/test/thread_test_helper.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_apitest.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/extensions/test_extension_dir.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/declarative/rules_registry_service.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/declarative_webrequest/webrequest_constants.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/declarative_webrequest/webrequest_rules_registry.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_prefs.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/test/extension_test_message_listener.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using content::BrowserThread;
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using extensions::Extension;
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using extensions::ExtensionPrefs;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::RulesRegistry;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::RulesRegistryService;
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using extensions::TestExtensionDir;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::WebRequestRulesRegistry;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace {
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kArbitraryUrl[] = "http://www.example.com";  // Must be http://.
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The extension in "declarative/redirect_to_data" redirects every navigation to
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// a page with title |kTestTitle|.
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define TEST_TITLE_STRING ":TEST:"
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kTestTitle[] = TEST_TITLE_STRING;
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// All methods and constands below containing "RedirectToData" in their names
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// are parts of a test extension "Redirect to 'data:'".
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string GetRedirectToDataManifestWithVersion(unsigned version) {
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return base::StringPrintf(
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "{\n"
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "  \"name\": \"Redirect to 'data:' (declarative apitest)\",\n"
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "  \"version\": \"%d\",\n"
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "  \"manifest_version\": 2,\n"
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "  \"description\": \"Redirects all requests to a fixed data: URI.\",\n"
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "  \"background\": {\n"
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "    \"scripts\": [\"background.js\"]\n"
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "  },\n"
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "  \"permissions\": [\n"
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "    \"declarativeWebRequest\", \"<all_urls>\"\n"
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "  ]\n"
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "}\n",
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      version);
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kRedirectToDataConstants[] =
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "var redirectDataURI =\n"
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    'data:text/html;charset=utf-8,<html><head><title>' +\n"
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    '" TEST_TITLE_STRING "' +\n"
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    '<%2Ftitle><%2Fhtml>';\n";
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#undef TEST_TITLE_STRING
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kRedirectToDataRules[] =
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "var rules = [{\n"
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  conditions: [\n"
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    new chrome.declarativeWebRequest.RequestMatcher({\n"
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "        url: {schemes: ['http']}})\n"
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  ],\n"
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  actions: [\n"
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    new chrome.declarativeWebRequest.RedirectRequest({\n"
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "      redirectUrl: redirectDataURI\n"
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    })\n"
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  ]\n"
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "}];\n";
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kRedirectToDataInstallRules[] =
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "function report(details) {\n"
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  if (chrome.extension.lastError) {\n"
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    chrome.test.log(chrome.extension.lastError.message);\n"
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  } else {\n"
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    chrome.test.sendMessage(\"ready\", function(reply) {})\n"
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  }\n"
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "}\n"
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "\n"
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "chrome.runtime.onInstalled.addListener(function(details) {\n"
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  if (details.reason == 'install')\n"
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    chrome.declarativeWebRequest.onRequest.addRules(rules, report);\n"
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "});\n";
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kRedirectToDataNoRules[] =
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "chrome.runtime.onInstalled.addListener(function(details) {\n"
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  chrome.test.sendMessage(\"ready\", function(reply) {})\n"
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "});\n";
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DeclarativeApiTest : public ExtensionApiTest {
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string GetTitle() {
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::string16 title(
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        browser()->tab_strip_model()->GetActiveWebContents()->GetTitle());
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return base::UTF16ToUTF8(title);
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Reports the number of rules registered for the |extension_id| with the
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // non-webview rules registry.
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  size_t NumberOfRegisteredRules(const std::string& extension_id) {
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    RulesRegistryService* rules_registry_service =
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        extensions::RulesRegistryService::Get(browser()->profile());
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<RulesRegistry> rules_registry =
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        rules_registry_service->GetRulesRegistry(
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            RulesRegistry::WebViewKey(0, 0),
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            extensions::declarative_webrequest_constants::kOnRequest);
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::vector<linked_ptr<RulesRegistry::Rule> > rules;
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    BrowserThread::PostTask(
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        BrowserThread::IO,
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        FROM_HERE,
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::Bind(
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            &RulesRegistry::GetAllRules, rules_registry, extension_id, &rules));
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<base::ThreadTestHelper> io_helper(new base::ThreadTestHelper(
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get()));
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_TRUE(io_helper->Run());
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return rules.size();
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DeclarativeApiTest, DeclarativeApi) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(RunExtensionTest("declarative/api")) << message_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Check that uninstalling the extension has removed all rules.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string extension_id = GetSingleLoadedExtension()->id();
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UninstallExtension(extension_id);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UnloadExtension posts a task to the owner thread of the extension
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to process this unloading. The next task to retrive all rules
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is therefore processed after the UnloadExtension task has been executed.
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(0u, NumberOfRegisteredRules(extension_id));
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// PersistRules test first installs an extension, which registers some rules.
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Then after browser restart, it checks that the rules are still in effect.
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(DeclarativeApiTest, PRE_PersistRules) {
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Note that we cannot use an extension generated by *GetRedirectToData*
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // helpers in a TestExtensionDir, because we need the extension to persist
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // until the PersistRules test is run.
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(RunExtensionTest("declarative/redirect_to_data")) << message_;
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(DeclarativeApiTest, PersistRules) {
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kTestTitle, GetTitle());
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test that the rules are correctly persisted and (de)activated during
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// changing the "installed" and "enabled" status of an extension.
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(DeclarativeApiTest, ExtensionLifetimeRulesHandling) {
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TestExtensionDir ext_dir;
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 1. Install the extension. Rules should become active.
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ext_dir.WriteManifest(GetRedirectToDataManifestWithVersion(1));
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ext_dir.WriteFile(FILE_PATH_LITERAL("background.js"),
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    base::StringPrintf("%s%s%s",
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                       kRedirectToDataConstants,
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                       kRedirectToDataRules,
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                       kRedirectToDataInstallRules));
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ExtensionTestMessageListener ready("ready", /*will_reply=*/false);
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const Extension* extension = InstallExtensionWithUIAutoConfirm(
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ext_dir.Pack(), 1 /*+1 installed extension*/, browser());
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(extension);
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string extension_id(extension->id());
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(ready.WaitUntilSatisfied());
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(kTestTitle, GetTitle());
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(1u, NumberOfRegisteredRules(extension_id));
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 2. Disable the extension. Rules are no longer active, but are still
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // registered.
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DisableExtension(extension_id);
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_NE(kTestTitle, GetTitle());
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(1u, NumberOfRegisteredRules(extension_id));
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 3. Enable the extension again. Rules are active again.
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EnableExtension(extension_id);
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(kTestTitle, GetTitle());
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(1u, NumberOfRegisteredRules(extension_id));
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 4. Bump the version and update, without the code to add the rules. Rules
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // are still active, because the registry does not drop them unless the
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // extension gets uninstalled.
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ext_dir.WriteManifest(GetRedirectToDataManifestWithVersion(2));
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ext_dir.WriteFile(
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FILE_PATH_LITERAL("background.js"),
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::StringPrintf(
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          "%s%s", kRedirectToDataConstants, kRedirectToDataNoRules));
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ExtensionTestMessageListener ready_after_update("ready",
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                                  /*will_reply=*/false);
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(UpdateExtension(
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      extension_id, ext_dir.Pack(), 0 /*no new installed extension*/));
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(ready_after_update.WaitUntilSatisfied());
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(kTestTitle, GetTitle());
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(1u, NumberOfRegisteredRules(extension_id));
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 5. Reload the extension. Rules remain active.
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ReloadExtension(extension_id);
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(kTestTitle, GetTitle());
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(1u, NumberOfRegisteredRules(extension_id));
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // 6. Uninstall the extension. Rules are gone.
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UninstallExtension(extension_id);
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_NE(kTestTitle, GetTitle());
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(0u, NumberOfRegisteredRules(extension_id));
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// When an extenion is uninstalled, the state store deletes all preferences
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// stored for that extension. We need to make sure we don't store anything after
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// that deletion occurs.
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DeclarativeApiTest, NoTracesAfterUninstalling) {
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestExtensionDir ext_dir;
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // 1. Install the extension. Verify that rules become active and some prefs
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // are stored.
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ext_dir.WriteManifest(GetRedirectToDataManifestWithVersion(1));
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ext_dir.WriteFile(FILE_PATH_LITERAL("background.js"),
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    base::StringPrintf("%s%s%s",
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       kRedirectToDataConstants,
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       kRedirectToDataRules,
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       kRedirectToDataInstallRules));
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionTestMessageListener ready("ready", /*will_reply=*/false);
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const Extension* extension = InstallExtensionWithUIAutoConfirm(
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ext_dir.Pack(), 1 /*+1 installed extension*/, browser());
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(extension);
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string extension_id(extension->id());
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(ready.WaitUntilSatisfied());
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(kTestTitle, GetTitle());
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1u, NumberOfRegisteredRules(extension_id));
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(browser()->profile());
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(extension_prefs->HasPrefForExtension(extension_id));
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // 2. Uninstall the extension. Rules are gone and preferences should be empty.
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UninstallExtension(extension_id);
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), GURL(kArbitraryUrl));
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_NE(kTestTitle, GetTitle());
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0u, NumberOfRegisteredRules(extension_id));
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(extension_prefs->HasPrefForExtension(extension_id));
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
257