55755f3ce5824f6e747fe5c0eef32a0eb817e207
[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 "xwalk/application/common/install_warning.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace xwalk {
18 namespace application {
19
20 namespace {
21
22 std::vector<std::string> SingleKey(const std::string& key) {
23   return std::vector<std::string>(1, key);
24 }
25
26 }  // namespace
27
28 class ScopedTestingManifestHandlerRegistry {
29  public:
30   ScopedTestingManifestHandlerRegistry(
31       const std::vector<ManifestHandler*>& handlers)
32       : registry_(
33           new ManifestHandlerRegistry(handlers)),
34         prev_registry_(
35           ManifestHandlerRegistry::GetInstance(Manifest::TYPE_XPK)) {
36     ManifestHandlerRegistry::SetInstanceForTesting(
37         registry_.get(), Manifest::TYPE_XPK);
38   }
39
40   ~ScopedTestingManifestHandlerRegistry() {
41     ManifestHandlerRegistry::SetInstanceForTesting(
42         prev_registry_, Manifest::TYPE_XPK);
43   }
44
45   scoped_ptr<ManifestHandlerRegistry> registry_;
46   ManifestHandlerRegistry* prev_registry_;
47 };
48
49 class ManifestHandlerTest : public testing::Test {
50  public:
51   class ParsingWatcher {
52    public:
53     // Called when a manifest handler parses.
54     void Record(const std::string& name) {
55       parsed_names_.push_back(name);
56     }
57
58     const std::vector<std::string>& parsed_names() {
59       return parsed_names_;
60     }
61
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)
69           prev_iterator = i;
70         if (parsed_names_[i] == name_after)
71           next_iterator = i;
72       }
73
74       if (prev_iterator < next_iterator)
75         return true;
76
77       return false;
78     }
79
80    private:
81     // The order of manifest handlers that we watched parsing.
82     std::vector<std::string> parsed_names_;
83   };
84
85   class TestManifestHandler : public ManifestHandler {
86    public:
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) {
92     }
93
94     virtual ~TestManifestHandler() {}
95
96     virtual bool Parse(
97         scoped_refptr<ApplicationData> application,
98         base::string16* error) OVERRIDE {
99       watcher_->Record(name_);
100       return true;
101     }
102
103     virtual std::vector<std::string> PrerequisiteKeys() const OVERRIDE {
104       return prereqs_;
105     }
106
107     virtual std::vector<std::string> Keys() const OVERRIDE {
108       return keys_;
109     }
110
111    protected:
112     std::string name_;
113     std::vector<std::string> keys_;
114     std::vector<std::string> prereqs_;
115     ParsingWatcher* watcher_;
116   };
117
118   class FailingTestManifestHandler : public TestManifestHandler {
119    public:
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) {
125     }
126     virtual bool Parse(
127         scoped_refptr<ApplicationData> application,
128         base::string16* error) OVERRIDE {
129       *error = base::ASCIIToUTF16(name_);
130       return false;
131     }
132   };
133
134   class AlwaysParseTestManifestHandler : public TestManifestHandler {
135    public:
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) {
141     }
142
143     virtual bool AlwaysParseForType(Manifest::Type type) const OVERRIDE {
144       return true;
145     }
146   };
147
148   class TestManifestValidator : public ManifestHandler {
149    public:
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),
155           keys_(keys) {
156     }
157
158     virtual bool Parse(
159         scoped_refptr<ApplicationData> application,
160         base::string16* error) OVERRIDE {
161       return true;
162     }
163
164     virtual bool Validate(
165         scoped_refptr<const ApplicationData> application,
166         std::string* error,
167         std::vector<InstallWarning>* warnings) const OVERRIDE {
168       return return_value_;
169     }
170
171     virtual bool AlwaysValidateForType(Manifest::Type type) const OVERRIDE {
172       return always_validate_;
173     }
174
175     virtual std::vector<std::string> Keys() const OVERRIDE {
176       return keys_;
177     }
178
179  protected:
180     bool return_value_;
181     bool always_validate_;
182     std::vector<std::string> keys_;
183   };
184 };
185
186 TEST_F(ManifestHandlerTest, DependentHandlers) {
187   std::vector<ManifestHandler*> handlers;
188   ParsingWatcher watcher;
189   std::vector<std::string> prereqs;
190   handlers.push_back(
191       new TestManifestHandler("A", SingleKey("a"), prereqs, &watcher));
192   handlers.push_back(
193       new TestManifestHandler("B", SingleKey("b"), prereqs, &watcher));
194   handlers.push_back(
195       new TestManifestHandler("J", SingleKey("j"), prereqs, &watcher));
196   handlers.push_back(
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");
203   handlers.push_back(
204       new TestManifestHandler("C.EZ", keys, prereqs, &watcher));
205   prereqs.clear();
206   prereqs.push_back("b");
207   prereqs.push_back("k");
208   handlers.push_back(
209       new TestManifestHandler("C.D", SingleKey("c.d"), prereqs, &watcher));
210   ScopedTestingManifestHandlerRegistry registry(handlers);
211
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);
222   std::string error;
223   scoped_refptr<ApplicationData> application = ApplicationData::Create(
224       base::FilePath(),
225       Manifest::INVALID_TYPE,
226       manifest,
227       "",
228       &error);
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"));
235 }
236
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
242   // be parsed.
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);
248
249   // Succeeds when "a" is not recognized.
250   std::string error;
251   scoped_refptr<ApplicationData> application = ApplicationData::Create(
252       base::FilePath(),
253       Manifest::INVALID_TYPE,
254       manifest_a,
255       "",
256       &error);
257   EXPECT_TRUE(application.get());
258
259   // Register a handler for "a" that fails.
260   std::vector<ManifestHandler*> handlers;
261   ParsingWatcher watcher;
262   handlers.push_back(
263       new FailingTestManifestHandler(
264           "A", SingleKey("a"), std::vector<std::string>(), &watcher));
265   registry.reset();
266   registry.reset(new ScopedTestingManifestHandlerRegistry(handlers));
267
268   application = ApplicationData::Create(
269       base::FilePath(),
270       Manifest::INVALID_TYPE,
271       manifest_a,
272       "",
273       &error);
274   EXPECT_FALSE(application.get());
275   EXPECT_EQ("A", error);
276 }
277
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);
288   std::string error;
289   scoped_refptr<ApplicationData> application = ApplicationData::Create(
290       base::FilePath(),
291       Manifest::COMMAND_LINE,
292       manifest,
293       "",
294       &error);
295   EXPECT_TRUE(application.get());
296
297   std::vector<ManifestHandler*> handlers;
298   std::vector<InstallWarning> warnings;
299   // Always validates and fails.
300   handlers.push_back(
301       new TestManifestValidator(false, true, SingleKey("c")));
302   registry.reset();
303   registry.reset(new ScopedTestingManifestHandlerRegistry(handlers));
304   EXPECT_FALSE(
305       registry->registry_->ValidateAppManifest(application, &error, &warnings));
306
307   handlers.push_back(
308       new TestManifestValidator(false, false, SingleKey("c")));
309   registry.reset();
310   registry.reset(new ScopedTestingManifestHandlerRegistry(handlers));
311   EXPECT_TRUE(
312       registry->registry_->ValidateAppManifest(application, &error, &warnings));
313
314   // Validates "a" and fails.
315   handlers.push_back
316       (new TestManifestValidator(false, true, SingleKey("a")));
317   registry.reset();
318   registry.reset(new ScopedTestingManifestHandlerRegistry(handlers));
319   EXPECT_FALSE(
320       registry->registry_->ValidateAppManifest(application, &error, &warnings));
321 }
322
323 }  // namespace application
324 }  // namespace xwalk