1 // Copyright (c) 2013 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.
8 #include "base/files/file_path.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/stl_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "xwalk/application/common/application_data.h"
13 #include "xwalk/application/common/manifest_handler.h"
14 #include "xwalk/application/common/install_warning.h"
15 #include "testing/gtest/include/gtest/gtest.h"
18 namespace application {
22 std::vector<std::string> SingleKey(const std::string& key) {
23 return std::vector<std::string>(1, key);
28 class ScopedTestingManifestHandlerRegistry {
30 ScopedTestingManifestHandlerRegistry(
31 const std::vector<ManifestHandler*>& handlers)
33 new ManifestHandlerRegistry(handlers)),
35 ManifestHandlerRegistry::GetInstance(Manifest::TYPE_XPK)) {
36 ManifestHandlerRegistry::SetInstanceForTesting(
37 registry_.get(), Manifest::TYPE_XPK);
40 ~ScopedTestingManifestHandlerRegistry() {
41 ManifestHandlerRegistry::SetInstanceForTesting(
42 prev_registry_, Manifest::TYPE_XPK);
45 scoped_ptr<ManifestHandlerRegistry> registry_;
46 ManifestHandlerRegistry* prev_registry_;
49 class ManifestHandlerTest : public testing::Test {
51 class ParsingWatcher {
53 // Called when a manifest handler parses.
54 void Record(const std::string& name) {
55 parsed_names_.push_back(name);
58 const std::vector<std::string>& parsed_names() {
62 // Returns true if |name_before| was parsed before |name_after|.
63 bool ParsedBefore(const std::string& name_before,
64 const std::string& name_after) {
65 size_t prev_iterator = parsed_names_.size();
66 size_t next_iterator = 0;
67 for (size_t i = 0; i < parsed_names_.size(); ++i) {
68 if (parsed_names_[i] == name_before)
70 if (parsed_names_[i] == name_after)
74 if (prev_iterator < next_iterator)
81 // The order of manifest handlers that we watched parsing.
82 std::vector<std::string> parsed_names_;
85 class TestManifestHandler : public ManifestHandler {
87 TestManifestHandler(const std::string& name,
88 const std::vector<std::string>& keys,
89 const std::vector<std::string>& prereqs,
90 ParsingWatcher* watcher)
91 : name_(name), keys_(keys), prereqs_(prereqs), watcher_(watcher) {
94 virtual ~TestManifestHandler() {}
97 scoped_refptr<ApplicationData> application,
98 base::string16* error) OVERRIDE {
99 watcher_->Record(name_);
103 virtual std::vector<std::string> PrerequisiteKeys() const OVERRIDE {
107 virtual std::vector<std::string> Keys() const OVERRIDE {
113 std::vector<std::string> keys_;
114 std::vector<std::string> prereqs_;
115 ParsingWatcher* watcher_;
118 class FailingTestManifestHandler : public TestManifestHandler {
120 FailingTestManifestHandler(const std::string& name,
121 const std::vector<std::string>& keys,
122 const std::vector<std::string>& prereqs,
123 ParsingWatcher* watcher)
124 : TestManifestHandler(name, keys, prereqs, watcher) {
127 scoped_refptr<ApplicationData> application,
128 base::string16* error) OVERRIDE {
129 *error = base::ASCIIToUTF16(name_);
134 class AlwaysParseTestManifestHandler : public TestManifestHandler {
136 AlwaysParseTestManifestHandler(const std::string& name,
137 const std::vector<std::string>& keys,
138 const std::vector<std::string>& prereqs,
139 ParsingWatcher* watcher)
140 : TestManifestHandler(name, keys, prereqs, watcher) {
143 virtual bool AlwaysParseForType(Manifest::Type type) const OVERRIDE {
148 class TestManifestValidator : public ManifestHandler {
150 TestManifestValidator(bool return_value,
151 bool always_validate,
152 std::vector<std::string> keys)
153 : return_value_(return_value),
154 always_validate_(always_validate),
159 scoped_refptr<ApplicationData> application,
160 base::string16* error) OVERRIDE {
164 virtual bool Validate(
165 scoped_refptr<const ApplicationData> application,
167 std::vector<InstallWarning>* warnings) const OVERRIDE {
168 return return_value_;
171 virtual bool AlwaysValidateForType(Manifest::Type type) const OVERRIDE {
172 return always_validate_;
175 virtual std::vector<std::string> Keys() const OVERRIDE {
181 bool always_validate_;
182 std::vector<std::string> keys_;
186 TEST_F(ManifestHandlerTest, DependentHandlers) {
187 std::vector<ManifestHandler*> handlers;
188 ParsingWatcher watcher;
189 std::vector<std::string> prereqs;
191 new TestManifestHandler("A", SingleKey("a"), prereqs, &watcher));
193 new TestManifestHandler("B", SingleKey("b"), prereqs, &watcher));
195 new TestManifestHandler("J", SingleKey("j"), prereqs, &watcher));
197 new AlwaysParseTestManifestHandler(
198 "K", SingleKey("k"), prereqs, &watcher));
199 prereqs.push_back("c.d");
200 std::vector<std::string> keys;
201 keys.push_back("c.e");
202 keys.push_back("c.z");
204 new TestManifestHandler("C.EZ", keys, prereqs, &watcher));
206 prereqs.push_back("b");
207 prereqs.push_back("k");
209 new TestManifestHandler("C.D", SingleKey("c.d"), prereqs, &watcher));
210 ScopedTestingManifestHandlerRegistry registry(handlers);
212 base::DictionaryValue manifest;
213 manifest.SetString("name", "no name");
214 manifest.SetString("version", "0");
215 manifest.SetInteger("manifest_version", 2);
216 manifest.SetInteger("a", 1);
217 manifest.SetInteger("b", 2);
218 manifest.SetInteger("c.d", 3);
219 manifest.SetInteger("c.e", 4);
220 manifest.SetInteger("c.f", 5);
221 manifest.SetInteger("g", 6);
223 scoped_refptr<ApplicationData> application = ApplicationData::Create(
225 Manifest::INVALID_TYPE,
229 EXPECT_TRUE(application.get());
230 // A, B, C.EZ, C.D, K
231 EXPECT_EQ(5u, watcher.parsed_names().size());
232 EXPECT_TRUE(watcher.ParsedBefore("B", "C.D"));
233 EXPECT_TRUE(watcher.ParsedBefore("K", "C.D"));
234 EXPECT_TRUE(watcher.ParsedBefore("C.D", "C.EZ"));
237 TEST_F(ManifestHandlerTest, FailingHandlers) {
238 scoped_ptr<ScopedTestingManifestHandlerRegistry> registry(
239 new ScopedTestingManifestHandlerRegistry(
240 std::vector<ManifestHandler*>()));
241 // Can't use ApplicationBuilder, because this application will fail to
243 base::DictionaryValue manifest_a;
244 manifest_a.SetString("name", "no name");
245 manifest_a.SetString("version", "0");
246 manifest_a.SetInteger("manifest_version", 2);
247 manifest_a.SetInteger("a", 1);
249 // Succeeds when "a" is not recognized.
251 scoped_refptr<ApplicationData> application = ApplicationData::Create(
253 Manifest::INVALID_TYPE,
257 EXPECT_TRUE(application.get());
259 // Register a handler for "a" that fails.
260 std::vector<ManifestHandler*> handlers;
261 ParsingWatcher watcher;
263 new FailingTestManifestHandler(
264 "A", SingleKey("a"), std::vector<std::string>(), &watcher));
266 registry.reset(new ScopedTestingManifestHandlerRegistry(handlers));
268 application = ApplicationData::Create(
270 Manifest::INVALID_TYPE,
274 EXPECT_FALSE(application.get());
275 EXPECT_EQ("A", error);
278 TEST_F(ManifestHandlerTest, Validate) {
279 scoped_ptr<ScopedTestingManifestHandlerRegistry> registry(
280 new ScopedTestingManifestHandlerRegistry(
281 std::vector<ManifestHandler*>()));
282 base::DictionaryValue manifest;
283 manifest.SetString("name", "no name");
284 manifest.SetString("version", "0");
285 manifest.SetInteger("manifest_version", 2);
286 manifest.SetInteger("a", 1);
287 manifest.SetInteger("b", 2);
289 scoped_refptr<ApplicationData> application = ApplicationData::Create(
291 Manifest::COMMAND_LINE,
295 EXPECT_TRUE(application.get());
297 std::vector<ManifestHandler*> handlers;
298 std::vector<InstallWarning> warnings;
299 // Always validates and fails.
301 new TestManifestValidator(false, true, SingleKey("c")));
303 registry.reset(new ScopedTestingManifestHandlerRegistry(handlers));
305 registry->registry_->ValidateAppManifest(application, &error, &warnings));
308 new TestManifestValidator(false, false, SingleKey("c")));
310 registry.reset(new ScopedTestingManifestHandlerRegistry(handlers));
312 registry->registry_->ValidateAppManifest(application, &error, &warnings));
314 // Validates "a" and fails.
316 (new TestManifestValidator(false, true, SingleKey("a")));
318 registry.reset(new ScopedTestingManifestHandlerRegistry(handlers));
320 registry->registry_->ValidateAppManifest(application, &error, &warnings));
323 } // namespace application