Fix wgt lib to extract manifest and icon only
[platform/core/appfw/wgt-backend.git] / src / unit_tests / manifest_test.cc
1 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache-2.0 license that can be
3 // found in the LICENSE file.
4
5 #include <boost/filesystem/path.hpp>
6
7 #include <common/installer_context.h>
8 #include <common/request.h>
9 #include <common/utils/glist_range.h>
10
11 #include <wgt_manifest_handlers/setting_handler.h>
12
13 #include <glib.h>
14 #include <gtest/gtest.h>
15
16 #include <map>
17 #include <memory>
18 #include <string>
19 #include <vector>
20
21 #include "wgt/step/configuration/step_parse.h"
22 #include "wgt/wgt_backend_data.h"
23
24 #define ASSERT_CSTR_EQ(STR1, STR2)                                             \
25   ASSERT_EQ(strcmp(STR1, STR2), 0)                                             \
26
27 namespace bf = boost::filesystem;
28 namespace ci = common_installer;
29
30 namespace {
31
32 const char kManifestTestcaseData[] =
33     "/usr/share/wgt-backend-ut/test_samples/manifest/";
34
35 template<typename T>
36 gint Size(GListRange<T>* range) {
37   return std::distance(range->begin(), range->end());
38 }
39
40 class StepParseRunner {
41  public:
42   explicit StepParseRunner(const std::string& dir_suffix,
43                            bool ignore_start_files = true)
44       : dir_suffix_(dir_suffix),
45         ignore_start_files_(ignore_start_files),
46         context_(nullptr) {
47   }
48
49   bool Run() {
50     PrepareContext();
51     wgt::configuration::StepParse step(context_.get(),
52         wgt::configuration::StepParse::ConfigLocation::PACKAGE,
53         !ignore_start_files_);
54     return step.process() == ci::Step::Status::OK;
55   }
56
57   wgt::WgtBackendData* GetBackendData() const {
58     return static_cast<wgt::WgtBackendData*>(context_->backend_data.get());
59   }
60
61   manifest_x* GetManifest() const {
62     return context_->manifest_data.get();
63   }
64
65  private:
66   void PrepareContext() {
67     context_.reset(new ci::InstallerContext());
68     context_->root_application_path.set(ci::GetRootAppPath(false, getuid()));
69     context_->unpacked_dir_path.set(
70         bf::path(kManifestTestcaseData) / dir_suffix_);
71     context_->backend_data.set(new wgt::WgtBackendData());
72   }
73
74   std::string dir_suffix_;
75   bool ignore_start_files_;
76   std::unique_ptr<ci::InstallerContext> context_;
77 };
78
79 }  // namespace
80
81 class ManifestTest : public testing::Test {
82  public:
83   std::string GetMyName() const {
84     std::string suite =
85         testing::UnitTest::GetInstance()->current_test_info()->test_case_name();
86     std::string case_name =
87         testing::UnitTest::GetInstance()->current_test_info()->name();
88     return suite + '.' + case_name;
89   }
90 };
91
92 TEST_F(ManifestTest, WidgetElement_Valid) {
93   StepParseRunner runner(GetMyName());
94   ASSERT_TRUE(runner.Run());
95   manifest_x* m = runner.GetManifest();
96   ASSERT_NE(m, nullptr);
97   ASSERT_CSTR_EQ(m->package, "package0id");
98   auto apps = GListRange<application_x*>(m->application);
99   ASSERT_EQ(Size(&apps), 1);
100   application_x* app = *apps.begin();
101   ASSERT_CSTR_EQ(app->appid, "package0id.appid");
102 }
103
104 TEST_F(ManifestTest, WidgetElement_InvalidNamespace) {
105   StepParseRunner runner(GetMyName());
106   ASSERT_FALSE(runner.Run());
107 }
108
109 TEST_F(ManifestTest, WidgetElement_MissingNamespace) {
110   StepParseRunner runner(GetMyName());
111   ASSERT_FALSE(runner.Run());
112 }
113
114 TEST_F(ManifestTest, WidgetElement_ManyNamespaces) {
115   StepParseRunner runner(GetMyName());
116   ASSERT_FALSE(runner.Run());
117 }
118
119 TEST_F(ManifestTest, ApplicationElement_ManyElements) {
120   StepParseRunner runner(GetMyName());
121   ASSERT_FALSE(runner.Run());
122 }
123
124 TEST_F(ManifestTest, ApplicationElement_ValidAppId) {
125   StepParseRunner runner(GetMyName());
126   ASSERT_TRUE(runner.Run());
127   manifest_x* m = runner.GetManifest();
128   ASSERT_NE(m, nullptr);
129   auto apps = GListRange<application_x*>(m->application);
130   application_x* app = *apps.begin();
131   ASSERT_NE(app, nullptr);
132   ASSERT_CSTR_EQ(app->appid, "package0id.appid");
133 }
134
135 TEST_F(ManifestTest, ApplicationElement_MissingAppId) {
136   StepParseRunner runner(GetMyName());
137   ASSERT_FALSE(runner.Run());
138 }
139
140 TEST_F(ManifestTest, ApplicationElement_InvalidAppId) {
141   StepParseRunner runner(GetMyName());
142   ASSERT_FALSE(runner.Run());
143 }
144
145 TEST_F(ManifestTest, ApplicationElement_ValidPackage) {
146   StepParseRunner runner(GetMyName());
147   ASSERT_TRUE(runner.Run());
148   manifest_x* m = runner.GetManifest();
149   ASSERT_NE(m, nullptr);
150   ASSERT_CSTR_EQ(m->package, "package0id");
151 }
152
153 TEST_F(ManifestTest, ApplicationElement_InvalidPackage) {
154   StepParseRunner runner(GetMyName());
155   ASSERT_FALSE(runner.Run());
156 }
157
158 TEST_F(ManifestTest, ApplicationElement_MissingPackage) {
159   StepParseRunner runner(GetMyName());
160   ASSERT_FALSE(runner.Run());
161 }
162
163 TEST_F(ManifestTest, ApplicationElement_ValidVersion) {
164   StepParseRunner runner(GetMyName());
165   ASSERT_TRUE(runner.Run());
166   manifest_x* m = runner.GetManifest();
167   ASSERT_NE(m, nullptr);
168   ASSERT_CSTR_EQ(m->api_version, "3.0");
169 }
170
171 TEST_F(ManifestTest, ApplicationElement_InvalidVersion) {
172   StepParseRunner runner(GetMyName());
173   ASSERT_FALSE(runner.Run());
174 }
175
176 TEST_F(ManifestTest, ApplicationElement_MissingVersion) {
177   StepParseRunner runner(GetMyName());
178   ASSERT_FALSE(runner.Run());
179 }
180
181 TEST_F(ManifestTest, PrivilegeElement_ValidName) {
182   StepParseRunner runner(GetMyName());
183   ASSERT_TRUE(runner.Run());
184   manifest_x* m = runner.GetManifest();
185   ASSERT_NE(m, nullptr);
186   std::vector<std::string> priv_vec;
187   for (privilege_x* priv : GListRange<privilege_x*>(m->privileges)) {
188     priv_vec.push_back(priv->value);
189   }
190   ASSERT_FALSE(priv_vec.empty());
191   const char* expected_name = "http://tizen.org/privilege/application.launch";
192   ASSERT_CSTR_EQ(priv_vec[0].c_str(), expected_name);
193 }
194
195 TEST_F(ManifestTest, PrivilegeElement_ManyElements) {
196   StepParseRunner runner(GetMyName());
197   ASSERT_TRUE(runner.Run());
198   manifest_x* m = runner.GetManifest();
199   ASSERT_NE(m, nullptr);
200   std::vector<std::string> priv_vec;
201   for (privilege_x* priv : GListRange<privilege_x*>(m->privileges)) {
202     priv_vec.push_back(priv->value);
203   }
204   ASSERT_EQ(priv_vec.size(), 2);
205   const char* first_priv = "http://tizen.org/privilege/application.close";
206   ASSERT_CSTR_EQ(priv_vec[0].c_str(), first_priv);
207   const char* second_priv = "http://tizen.org/privilege/application.launch";
208   ASSERT_CSTR_EQ(priv_vec[1].c_str(), second_priv);
209 }
210
211 TEST_F(ManifestTest, PrivilegeElement_InvalidName) {
212   StepParseRunner runner(GetMyName());
213   ASSERT_FALSE(runner.Run());
214 }
215
216 TEST_F(ManifestTest, PrivilegeElement_MissingName) {
217   StepParseRunner runner(GetMyName());
218   ASSERT_FALSE(runner.Run());
219 }
220
221
222 TEST_F(ManifestTest, AppControlElement_Valid) {
223   StepParseRunner runner(GetMyName());
224   ASSERT_TRUE(runner.Run());
225   manifest_x* m = runner.GetManifest();
226   ASSERT_NE(m, nullptr);
227   auto apps = GListRange<application_x*>(m->application);
228   application_x* app = *apps.begin();
229   ASSERT_NE(app, nullptr);
230   std::vector<appcontrol_x*> app_controls;
231   for (appcontrol_x* app_control : GListRange<appcontrol_x*>(app->appcontrol)) {
232     app_controls.push_back(app_control);
233   }
234   ASSERT_EQ(app_controls.size(), 1);
235   ASSERT_CSTR_EQ(app_controls[0]->mime, "image/jpg");
236   ASSERT_CSTR_EQ(app_controls[0]->operation,
237                  "http://tizen.org/appcontrol/operation/edit");
238   ASSERT_CSTR_EQ(app_controls[0]->uri, "myapp");
239 }
240
241 TEST_F(ManifestTest, AppControlElement_MissingMIME) {
242   StepParseRunner runner(GetMyName());
243   ASSERT_TRUE(runner.Run());
244   manifest_x* m = runner.GetManifest();
245   ASSERT_NE(m, nullptr);
246   auto apps = GListRange<application_x*>(m->application);
247   application_x* app = *apps.begin();
248   ASSERT_NE(app, nullptr);
249   std::vector<appcontrol_x*> app_controls;
250   for (appcontrol_x* app_control : GListRange<appcontrol_x*>(app->appcontrol)) {
251     app_controls.push_back(app_control);
252   }
253   ASSERT_CSTR_EQ(app_controls[0]->mime, "");
254 }
255
256 TEST_F(ManifestTest, AppControlElement_MissingOperation) {
257   StepParseRunner runner(GetMyName());
258   ASSERT_FALSE(runner.Run());
259 }
260
261 TEST_F(ManifestTest, AppControlElement_MissingSrc) {
262   StepParseRunner runner(GetMyName());
263   ASSERT_FALSE(runner.Run());
264 }
265
266 TEST_F(ManifestTest, AppControlElement_MissingURI) {
267   StepParseRunner runner(GetMyName());
268   ASSERT_TRUE(runner.Run());
269   manifest_x* m = runner.GetManifest();
270   ASSERT_NE(m, nullptr);
271   auto apps = GListRange<application_x*>(m->application);
272   application_x* app = *apps.begin();
273   ASSERT_NE(app, nullptr);
274   std::vector<appcontrol_x*> app_controls;
275   for (appcontrol_x* app_control : GListRange<appcontrol_x*>(app->appcontrol)) {
276     app_controls.push_back(app_control);
277   }
278   ASSERT_CSTR_EQ(app_controls[0]->uri, "");
279 }
280
281 TEST_F(ManifestTest, SettingsElement_Valid) {
282   StepParseRunner runner(GetMyName());
283   ASSERT_TRUE(runner.Run());
284   manifest_x* m = runner.GetManifest();
285   ASSERT_NE(m, nullptr);
286   auto backend_data = runner.GetBackendData();
287   auto settings = backend_data->settings.get();
288
289   ASSERT_EQ(settings.background_support_enabled(), true);
290   ASSERT_EQ(settings.context_menu_enabled(), false);
291   ASSERT_EQ(settings.encryption_enabled(), true);
292   ASSERT_EQ(settings.screen_orientation(),
293             wgt::parse::SettingInfo::ScreenOrientation::LANDSCAPE);
294   ASSERT_EQ(settings.install_location(),
295             wgt::parse::SettingInfo::InstallLocation::INTERNAL);
296   ASSERT_EQ(settings.hwkey_enabled(), true);
297   ASSERT_EQ(settings.background_vibration(), true);
298 }
299
300 TEST_F(ManifestTest, SettingsElement_BackgroundSupportEnabled) {
301   StepParseRunner runner(GetMyName());
302   ASSERT_TRUE(runner.Run());
303   manifest_x* m = runner.GetManifest();
304   ASSERT_NE(m, nullptr);
305   auto backend_data = runner.GetBackendData();
306   auto settings = backend_data->settings.get();
307   ASSERT_EQ(settings.background_support_enabled(), true);
308 }
309
310 TEST_F(ManifestTest, SettingsElement_BackgroundSupportDisabled) {
311   StepParseRunner runner(GetMyName());
312   ASSERT_TRUE(runner.Run());
313   manifest_x* m = runner.GetManifest();
314   ASSERT_NE(m, nullptr);
315   auto backend_data = runner.GetBackendData();
316   auto settings = backend_data->settings.get();
317   ASSERT_EQ(settings.background_support_enabled(), false);
318 }
319
320 TEST_F(ManifestTest, SettingsElement_MissingBackgroundSupport) {
321   StepParseRunner runner(GetMyName());
322   ASSERT_TRUE(runner.Run());
323   manifest_x* m = runner.GetManifest();
324   ASSERT_NE(m, nullptr);
325   auto backend_data = runner.GetBackendData();
326   auto settings = backend_data->settings.get();
327   ASSERT_EQ(settings.background_support_enabled(), false);
328 }
329
330 TEST_F(ManifestTest, SettingsElement_BackgroundVibrationEnabled) {
331   StepParseRunner runner(GetMyName());
332   ASSERT_TRUE(runner.Run());
333   manifest_x* m = runner.GetManifest();
334   ASSERT_NE(m, nullptr);
335   auto backend_data = runner.GetBackendData();
336   auto settings = backend_data->settings.get();
337   ASSERT_EQ(settings.background_vibration(), true);
338 }
339
340 TEST_F(ManifestTest, SettingsElement_BackgroundVibrationDisabled) {
341   StepParseRunner runner(GetMyName());
342   ASSERT_TRUE(runner.Run());
343   manifest_x* m = runner.GetManifest();
344   ASSERT_NE(m, nullptr);
345   auto backend_data = runner.GetBackendData();
346   auto settings = backend_data->settings.get();
347   ASSERT_EQ(settings.background_vibration(), false);
348 }
349
350 TEST_F(ManifestTest, SettingsElement_MissingBackgroundVibration) {
351   StepParseRunner runner(GetMyName());
352   ASSERT_TRUE(runner.Run());
353   manifest_x* m = runner.GetManifest();
354   ASSERT_NE(m, nullptr);
355   auto backend_data = runner.GetBackendData();
356   auto settings = backend_data->settings.get();
357   ASSERT_EQ(settings.background_vibration(), false);
358 }
359
360 TEST_F(ManifestTest, SettingsElement_ContextMenuEnabled) {
361   StepParseRunner runner(GetMyName());
362   ASSERT_TRUE(runner.Run());
363   manifest_x* m = runner.GetManifest();
364   ASSERT_NE(m, nullptr);
365   auto backend_data = runner.GetBackendData();
366   auto settings = backend_data->settings.get();
367   ASSERT_EQ(settings.context_menu_enabled(), true);
368 }
369
370 TEST_F(ManifestTest, SettingsElement_ContextMenuDisabled) {
371   StepParseRunner runner(GetMyName());
372   ASSERT_TRUE(runner.Run());
373   manifest_x* m = runner.GetManifest();
374   ASSERT_NE(m, nullptr);
375   auto backend_data = runner.GetBackendData();
376   auto settings = backend_data->settings.get();
377   ASSERT_EQ(settings.context_menu_enabled(), false);
378 }
379
380 TEST_F(ManifestTest, SettingsElement_MissingContextMenu) {
381   StepParseRunner runner(GetMyName());
382   ASSERT_TRUE(runner.Run());
383   manifest_x* m = runner.GetManifest();
384   ASSERT_NE(m, nullptr);
385   auto backend_data = runner.GetBackendData();
386   auto settings = backend_data->settings.get();
387   ASSERT_EQ(settings.context_menu_enabled(), true);
388 }
389
390 TEST_F(ManifestTest, SettingsElement_EncryptionEnabled) {
391   StepParseRunner runner(GetMyName());
392   ASSERT_TRUE(runner.Run());
393   manifest_x* m = runner.GetManifest();
394   ASSERT_NE(m, nullptr);
395   auto backend_data = runner.GetBackendData();
396   auto settings = backend_data->settings.get();
397   ASSERT_EQ(settings.encryption_enabled(), true);
398 }
399
400 TEST_F(ManifestTest, SettingsElement_EncryptionDisabled) {
401   StepParseRunner runner(GetMyName());
402   ASSERT_TRUE(runner.Run());
403   manifest_x* m = runner.GetManifest();
404   ASSERT_NE(m, nullptr);
405   auto backend_data = runner.GetBackendData();
406   auto settings = backend_data->settings.get();
407   ASSERT_EQ(settings.encryption_enabled(), false);
408 }
409
410 TEST_F(ManifestTest, SettingsElement_MissingEncryption) {
411   StepParseRunner runner(GetMyName());
412   ASSERT_TRUE(runner.Run());
413   manifest_x* m = runner.GetManifest();
414   ASSERT_NE(m, nullptr);
415   auto backend_data = runner.GetBackendData();
416   auto settings = backend_data->settings.get();
417   ASSERT_EQ(settings.encryption_enabled(), false);
418 }
419
420 TEST_F(ManifestTest, SettingsElement_HwKeyEnabled) {
421   StepParseRunner runner(GetMyName());
422   ASSERT_TRUE(runner.Run());
423   manifest_x* m = runner.GetManifest();
424   ASSERT_NE(m, nullptr);
425   auto backend_data = runner.GetBackendData();
426   auto settings = backend_data->settings.get();
427   ASSERT_EQ(settings.hwkey_enabled(), true);
428 }
429
430 TEST_F(ManifestTest, SettingsElement_HwKeyDisabled) {
431   StepParseRunner runner(GetMyName());
432   ASSERT_TRUE(runner.Run());
433   manifest_x* m = runner.GetManifest();
434   ASSERT_NE(m, nullptr);
435   auto backend_data = runner.GetBackendData();
436   auto settings = backend_data->settings.get();
437   ASSERT_EQ(settings.hwkey_enabled(), false);
438 }
439
440 TEST_F(ManifestTest, SettingsElement_MissingHwKeyEvent) {
441   StepParseRunner runner(GetMyName());
442   ASSERT_TRUE(runner.Run());
443   manifest_x* m = runner.GetManifest();
444   ASSERT_NE(m, nullptr);
445   auto backend_data = runner.GetBackendData();
446   auto settings = backend_data->settings.get();
447   ASSERT_EQ(settings.hwkey_enabled(), true);
448 }
449
450 TEST_F(ManifestTest, SettingsElement_MissingInstallLocation) {
451   StepParseRunner runner(GetMyName());
452   ASSERT_TRUE(runner.Run());
453   manifest_x* m = runner.GetManifest();
454   ASSERT_NE(m, nullptr);
455   auto backend_data = runner.GetBackendData();
456   auto settings = backend_data->settings.get();
457   ASSERT_EQ(settings.install_location(),
458             wgt::parse::SettingInfo::InstallLocation::AUTO);
459 }
460
461 TEST_F(ManifestTest, SettingsElement_MissingScreenOrientation) {
462   StepParseRunner runner(GetMyName());
463   ASSERT_TRUE(runner.Run());
464   manifest_x* m = runner.GetManifest();
465   ASSERT_NE(m, nullptr);
466   auto backend_data = runner.GetBackendData();
467   auto settings = backend_data->settings.get();
468   ASSERT_EQ(settings.screen_orientation(),
469             wgt::parse::SettingInfo::ScreenOrientation::AUTO);
470 }
471
472 TEST_F(ManifestTest, MetadataElement_Valid) {
473   StepParseRunner runner(GetMyName());
474   ASSERT_TRUE(runner.Run());
475   manifest_x* m = runner.GetManifest();
476   ASSERT_NE(m, nullptr);
477   auto apps = GListRange<application_x*>(m->application);
478   application_x* app = *apps.begin();
479
480   std::map<std::string, std::string> meta_data_map;
481   for (metadata_x* meta_data : GListRange<metadata_x*>(app->metadata)) {
482     if (meta_data->value)
483       meta_data_map[meta_data->key] = meta_data->value;
484     else
485       meta_data_map[meta_data->key] = std::string();
486   }
487   ASSERT_EQ(meta_data_map.size(), 2);
488   ASSERT_CSTR_EQ(meta_data_map["key1"].c_str(), "");
489   ASSERT_CSTR_EQ(meta_data_map["key2"].c_str(), "value2");
490 }
491
492 TEST_F(ManifestTest, MetadataElement_DuplicateKey) {
493   StepParseRunner runner(GetMyName());
494   ASSERT_TRUE(runner.Run());
495   manifest_x* m = runner.GetManifest();
496   ASSERT_NE(m, nullptr);
497   auto apps = GListRange<application_x*>(m->application);
498   application_x* app = *apps.begin();
499
500   std::map<std::string, std::string> meta_data_map;
501   for (metadata_x* meta_data : GListRange<metadata_x*>(app->metadata)) {
502     meta_data_map[meta_data->key] = meta_data->value;
503   }
504   ASSERT_EQ(meta_data_map.size(), 2);
505   ASSERT_CSTR_EQ(meta_data_map["key1"].c_str(), "key1value");
506   ASSERT_CSTR_EQ(meta_data_map["key2"].c_str(), "key2value");
507 }
508
509 TEST_F(ManifestTest, MetadataElement_MissingValue) {
510   StepParseRunner runner(GetMyName());
511   ASSERT_TRUE(runner.Run());
512   manifest_x* m = runner.GetManifest();
513   ASSERT_NE(m, nullptr);
514   auto apps = GListRange<application_x*>(m->application);
515   application_x* app = *apps.begin();
516
517   std::map<std::string, std::string> meta_data_map;
518   for (metadata_x* meta_data : GListRange<metadata_x*>(app->metadata)) {
519     if (meta_data->value)
520       meta_data_map[meta_data->key] = meta_data->value;
521     else
522       meta_data_map[meta_data->key] = std::string();
523   }
524   ASSERT_EQ(meta_data_map.size(), 2);
525   ASSERT_CSTR_EQ(meta_data_map["key1"].c_str(), "");
526   ASSERT_CSTR_EQ(meta_data_map["key2"].c_str(), "");
527 }
528
529 TEST_F(ManifestTest, MetadataElement_MissingKey) {
530   StepParseRunner runner(GetMyName());
531   ASSERT_TRUE(runner.Run());
532   manifest_x* m = runner.GetManifest();
533   ASSERT_NE(m, nullptr);
534   auto apps = GListRange<application_x*>(m->application);
535   application_x* app = *apps.begin();
536
537   std::map<std::string, std::string> meta_data_map;
538   for (metadata_x* meta_data : GListRange<metadata_x*>(app->metadata)) {
539     if (meta_data->key && meta_data->value)
540       meta_data_map[meta_data->key] = meta_data->value;
541   }
542   ASSERT_EQ(meta_data_map.size(), 0);
543 }
544
545 TEST_F(ManifestTest, CategoryElement_Valid) {
546   StepParseRunner runner(GetMyName());
547   ASSERT_TRUE(runner.Run());
548   manifest_x* m = runner.GetManifest();
549   ASSERT_NE(m, nullptr);
550   auto apps = GListRange<application_x*>(m->application);
551   application_x* app = *apps.begin();
552
553   std::vector<std::string> categories;
554   for (const char* category : GListRange<char*>(app->category)) {
555     categories.push_back(category);
556   }
557   ASSERT_EQ(categories.size(), 1);
558   ASSERT_CSTR_EQ(categories[0].c_str(),
559                  "http://tizen.org/category/wearable_clock");
560 }
561
562 TEST_F(ManifestTest, CategoryElement_MissingName) {
563   StepParseRunner runner(GetMyName());
564   ASSERT_TRUE(runner.Run());
565   manifest_x* m = runner.GetManifest();
566   ASSERT_NE(m, nullptr);
567   auto apps = GListRange<application_x*>(m->application);
568   application_x* app = *apps.begin();
569
570   std::vector<std::string> categories;
571   for (const char* category : GListRange<char*>(app->category)) {
572     categories.push_back(category);
573   }
574   ASSERT_TRUE(categories.empty());
575 }
576
577 TEST_F(ManifestTest, CategoryElement_MultipleElements) {
578   StepParseRunner runner(GetMyName());
579   ASSERT_TRUE(runner.Run());
580   manifest_x* m = runner.GetManifest();
581   ASSERT_NE(m, nullptr);
582   auto apps = GListRange<application_x*>(m->application);
583   application_x* app = *apps.begin();
584
585   std::vector<std::string> categories;
586   for (const char* category : GListRange<char*>(app->category)) {
587     categories.push_back(category);
588   }
589   ASSERT_EQ(categories.size(), 3);
590   ASSERT_CSTR_EQ(categories[0].c_str(),
591                  "http://tizen.org/category/category_0");
592   ASSERT_CSTR_EQ(categories[1].c_str(),
593                  "http://tizen.org/category/category_1");
594   ASSERT_CSTR_EQ(categories[2].c_str(),
595                  "http://tizen.org/category/category_2");
596 }