1 // Copyright (c) 2012 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.
5 #include "chrome/common/extensions/manifest.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "chrome/common/extensions/extension_manifest_constants.h"
15 #include "chrome/common/extensions/extension_error_utils.h"
16 #include "chrome/common/extensions/features/feature.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 namespace errors
= extension_manifest_errors
;
20 namespace keys
= extension_manifest_keys
;
22 namespace extensions
{
24 class ManifestTest
: public testing::Test
{
26 ManifestTest() : default_value_("test") {}
29 void AssertType(Manifest
* manifest
, Extension::Type type
) {
30 EXPECT_EQ(type
, manifest
->type());
31 EXPECT_EQ(type
== Extension::TYPE_THEME
, manifest
->is_theme());
32 EXPECT_EQ(type
== Extension::TYPE_PLATFORM_APP
,
33 manifest
->is_platform_app());
34 EXPECT_EQ(type
== Extension::TYPE_LEGACY_PACKAGED_APP
,
35 manifest
->is_legacy_packaged_app());
36 EXPECT_EQ(type
== Extension::TYPE_HOSTED_APP
, manifest
->is_hosted_app());
39 // Helper function that replaces the Manifest held by |manifest| with a copy
40 // with its |key| changed to |value|. If |value| is NULL, then |key| will
41 // instead be deleted.
43 scoped_ptr
<Manifest
>* manifest
, const std::string
& key
, Value
* value
) {
44 scoped_ptr
<DictionaryValue
> manifest_value(
45 manifest
->get()->value()->DeepCopy());
47 manifest_value
->Set(key
, value
);
49 manifest_value
->Remove(key
, NULL
);
50 manifest
->reset(new Manifest(Extension::INTERNAL
, manifest_value
.Pass()));
53 std::string default_value_
;
56 // Verifies that extensions can access the correct keys.
57 TEST_F(ManifestTest
, Extension
) {
58 scoped_ptr
<DictionaryValue
> manifest_value(new DictionaryValue());
59 manifest_value
->SetString(keys::kName
, "extension");
60 manifest_value
->SetString(keys::kVersion
, "1");
61 // Only supported in manifest_version=1.
62 manifest_value
->SetString(keys::kBackgroundPageLegacy
, "bg.html");
63 manifest_value
->SetString("unknown_key", "foo");
65 scoped_ptr
<Manifest
> manifest(
66 new Manifest(Extension::INTERNAL
, manifest_value
.Pass()));
68 Extension::InstallWarningVector warnings
;
69 manifest
->ValidateManifest(&error
, &warnings
);
70 EXPECT_TRUE(error
.empty());
71 ASSERT_EQ(1u, warnings
.size());
72 AssertType(manifest
.get(), Extension::TYPE_EXTENSION
);
74 // The known key 'background_page' should be accessible.
76 EXPECT_TRUE(manifest
->GetString(keys::kBackgroundPageLegacy
, &value
));
77 EXPECT_EQ("bg.html", value
);
79 // The unknown key 'unknown_key' should be accesible.
81 EXPECT_TRUE(manifest
->GetString("unknown_key", &value
));
82 EXPECT_EQ("foo", value
);
84 // Set the manifest_version to 2; background_page should stop working.
87 &manifest
, keys::kManifestVersion
, Value::CreateIntegerValue(2));
88 EXPECT_FALSE(manifest
->GetString("background_page", &value
));
91 // Validate should also give a warning.
93 manifest
->ValidateManifest(&error
, &warnings
);
94 EXPECT_TRUE(error
.empty());
95 ASSERT_EQ(2u, warnings
.size());
98 feature
.set_name("background_page");
99 feature
.set_max_manifest_version(1);
101 "'background_page' requires manifest version of 1 or lower.",
102 warnings
[0].message
);
105 // Test DeepCopy and Equals.
106 scoped_ptr
<Manifest
> manifest2(manifest
->DeepCopy());
107 EXPECT_TRUE(manifest
->Equals(manifest2
.get()));
108 EXPECT_TRUE(manifest2
->Equals(manifest
.get()));
110 &manifest
, "foo", Value::CreateStringValue("blah"));
111 EXPECT_FALSE(manifest
->Equals(manifest2
.get()));
114 // Verifies that key restriction based on type works.
115 TEST_F(ManifestTest
, ExtensionTypes
) {
116 scoped_ptr
<DictionaryValue
> value(new DictionaryValue());
117 value
->SetString(keys::kName
, "extension");
118 value
->SetString(keys::kVersion
, "1");
120 scoped_ptr
<Manifest
> manifest(
121 new Manifest(Extension::INTERNAL
, value
.Pass()));
123 Extension::InstallWarningVector warnings
;
124 manifest
->ValidateManifest(&error
, &warnings
);
125 EXPECT_TRUE(error
.empty());
126 EXPECT_TRUE(warnings
.empty());
128 // By default, the type is Extension.
129 AssertType(manifest
.get(), Extension::TYPE_EXTENSION
);
133 &manifest
, keys::kTheme
, new DictionaryValue());
134 AssertType(manifest
.get(), Extension::TYPE_THEME
);
136 &manifest
, keys::kTheme
, NULL
);
140 &manifest
, keys::kApp
, new DictionaryValue());
141 AssertType(manifest
.get(), Extension::TYPE_LEGACY_PACKAGED_APP
);
145 &manifest
, keys::kPlatformAppBackground
, new DictionaryValue());
146 AssertType(manifest
.get(), Extension::TYPE_PLATFORM_APP
);
148 &manifest
, keys::kPlatformAppBackground
, NULL
);
152 &manifest
, keys::kWebURLs
, new ListValue());
153 AssertType(manifest
.get(), Extension::TYPE_HOSTED_APP
);
155 &manifest
, keys::kWebURLs
, NULL
);
157 &manifest
, keys::kLaunchWebURL
, Value::CreateStringValue("foo"));
158 AssertType(manifest
.get(), Extension::TYPE_HOSTED_APP
);
160 &manifest
, keys::kLaunchWebURL
, NULL
);
163 // Verifies that the getters filter restricted keys.
164 TEST_F(ManifestTest
, RestrictedKeys
) {
165 scoped_ptr
<DictionaryValue
> value(new DictionaryValue());
166 value
->SetString(keys::kName
, "extension");
167 value
->SetString(keys::kVersion
, "1");
169 scoped_ptr
<Manifest
> manifest(
170 new Manifest(Extension::INTERNAL
, value
.Pass()));
172 Extension::InstallWarningVector warnings
;
173 manifest
->ValidateManifest(&error
, &warnings
);
174 EXPECT_TRUE(error
.empty());
175 EXPECT_TRUE(warnings
.empty());
177 // Platform apps cannot have a "page_action" key.
179 &manifest
, keys::kPageAction
, new DictionaryValue());
180 AssertType(manifest
.get(), Extension::TYPE_EXTENSION
);
181 base::Value
* output
= NULL
;
182 EXPECT_TRUE(manifest
->HasKey(keys::kPageAction
));
183 EXPECT_TRUE(manifest
->Get(keys::kPageAction
, &output
));
186 &manifest
, keys::kPlatformAppBackground
, new DictionaryValue());
187 AssertType(manifest
.get(), Extension::TYPE_PLATFORM_APP
);
188 EXPECT_FALSE(manifest
->HasKey(keys::kPageAction
));
189 EXPECT_FALSE(manifest
->Get(keys::kPageAction
, &output
));
191 &manifest
, keys::kPlatformAppBackground
, NULL
);
193 // "commands" is restricted to manifest_version >= 2.
195 // ... and dev channel, for now.
196 Feature::ScopedCurrentChannel
dev_channel_scope(
197 chrome::VersionInfo::CHANNEL_DEV
);
200 &manifest
, keys::kCommands
, new DictionaryValue());
201 EXPECT_FALSE(manifest
->HasKey(keys::kCommands
));
202 EXPECT_FALSE(manifest
->Get(keys::kCommands
, &output
));
205 &manifest
, keys::kManifestVersion
, Value::CreateIntegerValue(2));
206 EXPECT_TRUE(manifest
->HasKey(keys::kCommands
));
207 EXPECT_TRUE(manifest
->Get(keys::kCommands
, &output
));
211 } // namespace extensions