4cd57f3250dbbe39cb83a2d5ff5d538ed4e44d36
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / content_verifier_browsertest.cc
1 // Copyright 2014 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 "base/scoped_observer.h"
6 #include "chrome/browser/extensions/extension_browsertest.h"
7 #include "chrome/common/chrome_switches.h"
8 #include "content/public/test/test_utils.h"
9 #include "extensions/browser/content_verify_job.h"
10 #include "extensions/browser/extension_prefs.h"
11 #include "extensions/browser/extension_registry.h"
12 #include "extensions/browser/extension_registry_observer.h"
13
14 namespace extensions {
15
16 namespace {
17
18 // Helper for observing extension unloads.
19 class UnloadObserver : public ExtensionRegistryObserver {
20  public:
21   explicit UnloadObserver(ExtensionRegistry* registry) : observer_(this) {
22     observer_.Add(registry);
23   }
24   virtual ~UnloadObserver() {}
25
26   void WaitForUnload(const ExtensionId& id) {
27     if (ContainsKey(observed_, id))
28       return;
29
30     ASSERT_TRUE(loop_runner_.get() == NULL);
31     awaited_id_ = id;
32     loop_runner_ = new content::MessageLoopRunner();
33     loop_runner_->Run();
34   }
35
36   virtual void OnExtensionUnloaded(
37       content::BrowserContext* browser_context,
38       const Extension* extension,
39       UnloadedExtensionInfo::Reason reason) OVERRIDE {
40     observed_.insert(extension->id());
41     if (awaited_id_ == extension->id())
42       loop_runner_->Quit();
43   }
44
45  private:
46   ExtensionId awaited_id_;
47   std::set<ExtensionId> observed_;
48   scoped_refptr<content::MessageLoopRunner> loop_runner_;
49   ScopedObserver<ExtensionRegistry, UnloadObserver> observer_;
50 };
51
52 // Helper for forcing ContentVerifyJob's to return an error.
53 class JobDelegate : public ContentVerifyJob::TestDelegate {
54  public:
55   JobDelegate() : fail_next_read_(false), fail_next_done_(false) {}
56
57   virtual ~JobDelegate() {}
58
59   void set_id(const ExtensionId& id) { id_ = id; }
60   void fail_next_read() { fail_next_read_ = true; }
61   void fail_next_done() { fail_next_done_ = true; }
62
63   virtual ContentVerifyJob::FailureReason BytesRead(const ExtensionId& id,
64                                                     int count,
65                                                     const char* data) OVERRIDE {
66     if (id == id_ && fail_next_read_) {
67       fail_next_read_ = false;
68       return ContentVerifyJob::HASH_MISMATCH;
69     }
70     return ContentVerifyJob::NONE;
71   }
72
73   virtual ContentVerifyJob::FailureReason DoneReading(
74       const ExtensionId& id) OVERRIDE {
75     if (id == id_ && fail_next_done_) {
76       fail_next_done_ = false;
77       return ContentVerifyJob::HASH_MISMATCH;
78     }
79     return ContentVerifyJob::NONE;
80   }
81
82  private:
83   DISALLOW_COPY_AND_ASSIGN(JobDelegate);
84
85   ExtensionId id_;
86   bool fail_next_read_;
87   bool fail_next_done_;
88 };
89
90 }  // namespace
91
92 class ContentVerifierTest : public ExtensionBrowserTest {
93  public:
94   ContentVerifierTest() {}
95   virtual ~ContentVerifierTest() {}
96
97   virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE {
98     ExtensionBrowserTest::SetUpCommandLine(command_line);
99     command_line->AppendSwitchASCII(
100         switches::kExtensionContentVerification,
101         switches::kExtensionContentVerificationEnforce);
102   }
103
104   // Setup our unload observer and JobDelegate, and install a test extension.
105   virtual void SetUpOnMainThread() OVERRIDE {
106     ExtensionBrowserTest::SetUpOnMainThread();
107     unload_observer_.reset(
108         new UnloadObserver(ExtensionRegistry::Get(profile())));
109     const Extension* extension = InstallExtensionFromWebstore(
110         test_data_dir_.AppendASCII("content_verifier/v1.crx"), 1);
111     ASSERT_TRUE(extension);
112     id_ = extension->id();
113     page_url_ = extension->GetResourceURL("page.html");
114     delegate_.set_id(id_);
115     ContentVerifyJob::SetDelegateForTests(&delegate_);
116   }
117
118   virtual void TearDownOnMainThread() OVERRIDE {
119     ContentVerifyJob::SetDelegateForTests(NULL);
120     ExtensionBrowserTest::TearDownOnMainThread();
121   }
122
123   virtual void OpenPageAndWaitForUnload() {
124     AddTabAtIndex(1, page_url_, ui::PAGE_TRANSITION_LINK);
125     unload_observer_->WaitForUnload(id_);
126     ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
127     int reasons = prefs->GetDisableReasons(id_);
128     EXPECT_TRUE(reasons & Extension::DISABLE_CORRUPTED);
129
130     // This needs to happen before the ExtensionRegistry gets deleted, which
131     // happens before TearDownOnMainThread is called.
132     unload_observer_.reset();
133   }
134
135  protected:
136   JobDelegate delegate_;
137   scoped_ptr<UnloadObserver> unload_observer_;
138   ExtensionId id_;
139   GURL page_url_;
140 };
141
142 IN_PROC_BROWSER_TEST_F(ContentVerifierTest, FailOnRead) {
143   delegate_.fail_next_read();
144   OpenPageAndWaitForUnload();
145 }
146
147 IN_PROC_BROWSER_TEST_F(ContentVerifierTest, FailOnDone) {
148   delegate_.fail_next_done();
149   OpenPageAndWaitForUnload();
150 }
151
152 }  // namespace extensions