Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / xwalk / application / common / manifest_handler_unittest.cc
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.
4
5 #include <string>
6 #include <vector>
7
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 "testing/gtest/include/gtest/gtest.h"
15
16 namespace xwalk {
17 namespace application {
18
19 namespace {
20
21 std::vector<std::string> SingleKey(const std::string& key) {
22   return std::vector<std::string>(1, key);
23 }
24
25 }  // namespace
26
27 class ScopedTestingManifestHandlerRegistry {
28  public:
29   ScopedTestingManifestHandlerRegistry(
30       const std::vector<ManifestHandler*>& handlers)
31       : registry_(
32           new ManifestHandlerRegistry(handlers)),
33         prev_registry_(
34           ManifestHandlerRegistry::GetInstance(Package::XPK)) {
35     ManifestHandlerRegistry::SetInstanceForTesting(
36         registry_.get(), Package::XPK);
37   }
38
39   ~ScopedTestingManifestHandlerRegistry() {
40     ManifestHandlerRegistry::SetInstanceForTesting(
41         prev_registry_, Package::XPK);
42   }
43
44   scoped_ptr<ManifestHandlerRegistry> registry_;
45   ManifestHandlerRegistry* prev_registry_;
46 };
47
48 class ManifestHandlerTest : public testing::Test {
49  public:
50   class ParsingWatcher {
51    public:
52     // Called when a manifest handler parses.
53     void Record(const std::string& name) {
54       parsed_names_.push_back(name);
55     }
56
57     const std::vector<std::string>& parsed_names() {
58       return parsed_names_;
59     }
60
61     // Returns true if |name_before| was parsed before |name_after|.
62     bool ParsedBefore(const std::string& name_before,
63                       const std::string& name_after) {
64       size_t prev_iterator = parsed_names_.size();
65       size_t next_iterator = 0;
66       for (size_t i = 0; i < parsed_names_.size(); ++i) {
67         if (parsed_names_[i] == name_before)
68           prev_iterator = i;
69         if (parsed_names_[i] == name_after)
70           next_iterator = i;
71       }
72
73       if (prev_iterator < next_iterator)
74         return true;
75
76       return false;
77     }
78
79    private:
80     // The order of manifest handlers that we watched parsing.
81     std::vector<std::string> parsed_names_;
82   };
83
84   class TestManifestHandler : public ManifestHandler {
85    public:
86     TestManifestHandler(const std::string& name,
87                         const std::vector<std::string>& keys,
88                         const std::vector<std::string>& prereqs,
89                         ParsingWatcher* watcher)
90         : name_(name), keys_(keys), prereqs_(prereqs), watcher_(watcher) {
91     }
92
93     virtual ~TestManifestHandler() {}
94
95     virtual bool Parse(
96         scoped_refptr<ApplicationData> application,
97         base::string16* error) OVERRIDE {
98       watcher_->Record(name_);
99       return true;
100     }
101
102     virtual std::vector<std::string> PrerequisiteKeys() const OVERRIDE {
103       return prereqs_;
104     }
105
106     virtual std::vector<std::string> Keys() const OVERRIDE {
107       return keys_;
108     }
109
110    protected:
111     std::string name_;
112     std::vector<std::string> keys_;
113     std::vector<std::string> prereqs_;
114     ParsingWatcher* watcher_;
115   };
116
117   class FailingTestManifestHandler : public TestManifestHandler {
118    public:
119     FailingTestManifestHandler(const std::string& name,
120                                const std::vector<std::string>& keys,
121                                const std::vector<std::string>& prereqs,
122                                ParsingWatcher* watcher)
123         : TestManifestHandler(name, keys, prereqs, watcher) {
124     }
125     virtual bool Parse(
126         scoped_refptr<ApplicationData> application,
127         base::string16* error) OVERRIDE {
128       *error = base::ASCIIToUTF16(name_);
129       return false;
130     }
131   };
132
133   class AlwaysParseTestManifestHandler : public TestManifestHandler {
134    public:
135     AlwaysParseTestManifestHandler(const std::string& name,
136                                    const std::vector<std::string>& keys,
137                                    const std::vector<std::string>& prereqs,
138                                    ParsingWatcher* watcher)
139         : TestManifestHandler(name, keys, prereqs, watcher) {
140     }
141
142     virtual bool AlwaysParseForType(Manifest::Type type) const OVERRIDE {
143       return true;
144     }
145   };
146
147   class TestManifestValidator : public ManifestHandler {
148    public:
149     TestManifestValidator(bool return_value,
150                           bool always_validate,
151                           std::vector<std::string> keys)
152         : return_value_(return_value),
153           always_validate_(always_validate),
154           keys_(keys) {
155     }
156
157     virtual bool Parse(
158         scoped_refptr<ApplicationData> application,
159         base::string16* error) OVERRIDE {
160       return true;
161     }
162
163     virtual bool Validate(
164         scoped_refptr<const ApplicationData> application,
165         std::string* error) const OVERRIDE {
166       return return_value_;
167     }
168
169     virtual bool AlwaysValidateForType(Manifest::Type type) const OVERRIDE {
170       return always_validate_;
171     }
172
173     virtual std::vector<std::string> Keys() const OVERRIDE {
174       return keys_;
175     }
176
177    protected:
178     bool return_value_;
179     bool always_validate_;
180     std::vector<std::string> keys_;
181   };
182 };
183
184 TEST_F(ManifestHandlerTest, DependentHandlers) {
185   std::vector<ManifestHandler*> handlers;
186   ParsingWatcher watcher;
187   std::vector<std::string> prereqs;
188   handlers.push_back(
189       new TestManifestHandler("A", SingleKey("a"), prereqs, &watcher));
190   handlers.push_back(
191       new TestManifestHandler("B", SingleKey("b"), prereqs, &watcher));
192   handlers.push_back(
193       new TestManifestHandler("J", SingleKey("j"), prereqs, &watcher));
194   handlers.push_back(
195       new AlwaysParseTestManifestHandler(
196           "K", SingleKey("k"), prereqs, &watcher));
197   prereqs.push_back("c.d");
198   std::vector<std::string> keys;
199   keys.push_back("c.e");
200   keys.push_back("c.z");
201   handlers.push_back(
202       new TestManifestHandler("C.EZ", keys, prereqs, &watcher));
203   prereqs.clear();
204   prereqs.push_back("b");
205   prereqs.push_back("k");
206   handlers.push_back(
207       new TestManifestHandler("C.D", SingleKey("c.d"), prereqs, &watcher));
208   ScopedTestingManifestHandlerRegistry registry(handlers);
209
210   base::DictionaryValue manifest;
211   manifest.SetString("name", "no name");
212   manifest.SetString("version", "0");
213   manifest.SetInteger("manifest_version", 2);
214   manifest.SetInteger("a", 1);
215   manifest.SetInteger("b", 2);
216   manifest.SetInteger("c.d", 3);
217   manifest.SetInteger("c.e", 4);
218   manifest.SetInteger("c.f", 5);
219   manifest.SetInteger("g", 6);
220   std::string error;
221   scoped_refptr<ApplicationData> application = ApplicationData::Create(
222       base::FilePath(),
223       Manifest::INVALID_TYPE,
224       manifest,
225       "",
226       &error);
227   EXPECT_TRUE(application.get());
228   // A, B, C.EZ, C.D, K
229   EXPECT_EQ(5u, watcher.parsed_names().size());
230   EXPECT_TRUE(watcher.ParsedBefore("B", "C.D"));
231   EXPECT_TRUE(watcher.ParsedBefore("K", "C.D"));
232   EXPECT_TRUE(watcher.ParsedBefore("C.D", "C.EZ"));
233 }
234
235 TEST_F(ManifestHandlerTest, FailingHandlers) {
236   scoped_ptr<ScopedTestingManifestHandlerRegistry> registry(
237       new ScopedTestingManifestHandlerRegistry(
238           std::vector<ManifestHandler*>()));
239   // Can't use ApplicationBuilder, because this application will fail to
240   // be parsed.
241   base::DictionaryValue manifest_a;
242   manifest_a.SetString("name", "no name");
243   manifest_a.SetString("version", "0");
244   manifest_a.SetInteger("manifest_version", 2);
245   manifest_a.SetInteger("a", 1);
246
247   // Succeeds when "a" is not recognized.
248   std::string error;
249   scoped_refptr<ApplicationData> application = ApplicationData::Create(
250       base::FilePath(),
251       Manifest::INVALID_TYPE,
252       manifest_a,
253       "",
254       &error);
255   EXPECT_TRUE(application.get());
256
257   // Register a handler for "a" that fails.
258   std::vector<ManifestHandler*> handlers;
259   ParsingWatcher watcher;
260   handlers.push_back(
261       new FailingTestManifestHandler(
262           "A", SingleKey("a"), std::vector<std::string>(), &watcher));
263   registry.reset();
264   registry.reset(new ScopedTestingManifestHandlerRegistry(handlers));
265
266   application = ApplicationData::Create(
267       base::FilePath(),
268       Manifest::INVALID_TYPE,
269       manifest_a,
270       "",
271       &error);
272   EXPECT_FALSE(application.get());
273   EXPECT_EQ("A", error);
274 }
275
276 TEST_F(ManifestHandlerTest, Validate) {
277   scoped_ptr<ScopedTestingManifestHandlerRegistry> registry(
278       new ScopedTestingManifestHandlerRegistry(
279           std::vector<ManifestHandler*>()));
280   base::DictionaryValue manifest;
281   manifest.SetString("name", "no name");
282   manifest.SetString("version", "0");
283   manifest.SetInteger("manifest_version", 2);
284   manifest.SetInteger("a", 1);
285   manifest.SetInteger("b", 2);
286   std::string error;
287   scoped_refptr<ApplicationData> application = ApplicationData::Create(
288       base::FilePath(),
289       Manifest::COMMAND_LINE,
290       manifest,
291       "",
292       &error);
293   EXPECT_TRUE(application.get());
294
295   std::vector<ManifestHandler*> handlers;
296   // Always validates and fails.
297   handlers.push_back(
298       new TestManifestValidator(false, true, SingleKey("c")));
299   registry.reset();
300   registry.reset(new ScopedTestingManifestHandlerRegistry(handlers));
301   EXPECT_FALSE(
302       registry->registry_->ValidateAppManifest(application, &error));
303
304   handlers.push_back(
305       new TestManifestValidator(false, false, SingleKey("c")));
306   registry.reset();
307   registry.reset(new ScopedTestingManifestHandlerRegistry(handlers));
308   EXPECT_TRUE(
309       registry->registry_->ValidateAppManifest(application, &error));
310
311   // Validates "a" and fails.
312   handlers.push_back
313       (new TestManifestValidator(false, true, SingleKey("a")));
314   registry.reset();
315   registry.reset(new ScopedTestingManifestHandlerRegistry(handlers));
316   EXPECT_FALSE(
317       registry->registry_->ValidateAppManifest(application, &error));
318 }
319
320 }  // namespace application
321 }  // namespace xwalk