2 * Copyright (C) 2012 Intel Corporation.
4 * Author: Jens Georg <jensg@openismus.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
22 #include <libgupnp-av/gupnp-media-collection.h>
24 /* Flat DIDL_S playlist */
25 #define TEST_PARSE_COLLECTION_1 \
26 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \
28 " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"" \
29 " xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\"" \
30 " xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\"" \
31 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" \
32 " xsi:schemaLocation=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" \
33 " http://www.upnp.org/schemas/av/didl-lite-v2-20060531.xsd" \
34 " urn:schemas-upnp-org:metadata-1-0/upnp/" \
35 " http://www.upnp.org/schemas/av/upnp-v2-20060531.xsd\">" \
36 " <item id=\"\" parentID=\"0\" restricted=\"0\">" \
37 " <dc:title>Song1</dc:title>" \
38 " <upnp:class>object.item.audioItem</upnp:class>" \
39 " <res protocolInfo=\"*:*:*:*\" />" \
40 " <upnp:artist></upnp:artist>" \
42 " <item id=\"\" parentID=\"0\" restricted=\"0\">" \
43 " <dc:title>Song2</dc:title>" \
44 " <upnp:class>object.item.audioItem</upnp:class>" \
45 " <res protocolInfo=\"*:*:*:*\" />" \
47 " <item id=\"\" parentID=\"0\" restricted=\"0\">" \
48 " <dc:title>Song3</dc:title>" \
49 " <upnp:class>object.item.audioItem</upnp:class>" \
50 " <res protocolInfo=\"*:*:*:*\" />" \
54 /* Nested DIDL_S playlist */
55 #define TEST_PARSE_COLLECTION_2 \
56 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \
58 " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"" \
59 " xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\"" \
60 " xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\"" \
61 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" \
62 " xsi:schemaLocation=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" \
63 " http://www.upnp.org/schemas/av/didl-lite-v2-20060531.xsd" \
64 " urn:schemas-upnp-org:metadata-1-0/upnp/" \
65 " http://www.upnp.org/schemas/av/upnp-v2-20060531.xsd\">" \
66 " <container id=\"1\" parentID=\"0\" restricted=\"0\">" \
67 " <dc:title>NonFlatCollection</dc:title>" \
68 " <dc:creator>NonFlatCollection Author</dc:creator>" \
69 " <item id=\"\" parentID=\"1\" restricted=\"0\">" \
70 " <dc:title>Song1</dc:title>" \
71 " <upnp:class>object.item.audioItem</upnp:class>" \
72 " <res protocolInfo=\"*:*:*:*\" />" \
73 " <upnp:artist></upnp:artist>" \
75 " <item id=\"\" parentID=\"1\" restricted=\"0\">" \
76 " <dc:title>Song2</dc:title>" \
77 " <upnp:class>object.item.audioItem</upnp:class>" \
78 " <res protocolInfo=\"*:*:*:*\" />" \
80 " <item id=\"\" parentID=\"1\" restricted=\"0\">" \
81 " <dc:title>Song3</dc:title>" \
82 " <upnp:class>object.item.audioItem</upnp:class>" \
83 " <res protocolInfo=\"*:*:*:*\" />" \
88 #define TEST_CREATE_FLAT \
90 "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " \
91 "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" " \
92 "xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\" " \
93 "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\">" \
94 "<item restricted=\"1\">" \
95 "<dc:title>Song1</dc:title>" \
96 "<upnp:class>object.item.audioItem</upnp:class>" \
97 "<res>http://example.com/song1.mp3</res>" \
99 "<item restricted=\"1\">" \
100 "<dc:title>Song2</dc:title>" \
101 "<upnp:class>object.item.audioItem</upnp:class>" \
102 "<res>http://example.com/song2.mp3</res>" \
104 "<item restricted=\"1\">" \
105 "<dc:title>Song3</dc:title>" \
106 "<upnp:class>object.item.audioItem</upnp:class>" \
107 "<res>http://example.com/song3.mp3</res>" \
111 #define TEST_CREATE_FULL \
113 "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " \
114 "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" " \
115 "xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\" " \
116 "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\">" \
118 "<dc:title>TestCollection1</dc:title>" \
119 "<dc:creator>TestCollection1Author</dc:creator>" \
120 "<item restricted=\"1\">" \
121 "<dc:title>Song1</dc:title>" \
122 "<upnp:class>object.item.audioItem</upnp:class>" \
123 "<res>http://example.com/song1.mp3</res>" \
125 "<item restricted=\"1\">" \
126 "<dc:title>Song2</dc:title>" \
127 "<upnp:class>object.item.audioItem</upnp:class>" \
128 "<res>http://example.com/song2.mp3</res>" \
130 "<item restricted=\"1\">" \
131 "<dc:title>Song3</dc:title>" \
132 "<upnp:class>object.item.audioItem</upnp:class>" \
133 "<res>http://example.com/song3.mp3</res>" \
138 #define TEST_CREATE_FULL_REPARENT \
140 "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " \
141 "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" " \
142 "xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\" " \
143 "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\">" \
145 "<item restricted=\"1\">" \
146 "<dc:title>Song1</dc:title>" \
147 "<upnp:class>object.item.audioItem</upnp:class>" \
148 "<res>http://example.com/song1.mp3</res>" \
150 "<item restricted=\"1\">" \
151 "<dc:title>Song2</dc:title>" \
152 "<upnp:class>object.item.audioItem</upnp:class>" \
153 "<res>http://example.com/song2.mp3</res>" \
155 "<item restricted=\"1\">" \
156 "<dc:title>Song3</dc:title>" \
157 "<upnp:class>object.item.audioItem</upnp:class>" \
158 "<res>http://example.com/song3.mp3</res>" \
160 "<dc:title>TestCollection1</dc:title>" \
161 "<dc:creator>TestCollection1Author</dc:creator>" \
165 #define TEST_PARSE_NO_XML "This is just some random text"
168 test_didl_collection_construction ()
170 GUPnPMediaCollection *collection;
172 /* Check that a collection created via auxillary function is mutable */
173 collection = gupnp_media_collection_new ();
174 g_assert (gupnp_media_collection_get_mutable (collection));
175 g_object_unref (collection);
177 /* Check that a collection created via auxillary parse function is
179 collection = gupnp_media_collection_new_from_string
180 (TEST_PARSE_COLLECTION_1);
181 g_assert (!gupnp_media_collection_get_mutable (collection));
182 g_object_unref (collection);
184 /* Check that creating a collection via g_object_new and title/author
185 * properties set is mutable */
186 collection = g_object_new (GUPNP_TYPE_MEDIA_COLLECTION,
187 "title", "test01collection",
188 "author", "test01author",
190 g_assert (gupnp_media_collection_get_mutable (collection));
191 g_object_unref (collection);
193 /* Check that creating a collection via g_object_new and data is not
195 collection = g_object_new (GUPNP_TYPE_MEDIA_COLLECTION,
196 "data", TEST_PARSE_COLLECTION_1,
198 g_assert (!gupnp_media_collection_get_mutable (collection));
199 g_object_unref (collection);
201 /* Check that creating a collection with all properties set will result
202 * in a collection that ignored "title" and "author" properties.
204 collection = g_object_new (GUPNP_TYPE_MEDIA_COLLECTION,
205 "title", "test01collection",
206 "author", "test01author",
207 "data", TEST_PARSE_COLLECTION_1,
209 g_assert (!gupnp_media_collection_get_mutable (collection));
210 g_assert_cmpstr (gupnp_media_collection_get_author (collection), ==,
212 g_assert_cmpstr (gupnp_media_collection_get_title (collection), ==,
214 g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
215 TEST_PARSE_COLLECTION_1);
216 g_object_unref (collection);
220 test_didl_collection_parse_flat ()
222 GUPnPMediaCollection *collection;
225 collection = gupnp_media_collection_new_from_string
226 (TEST_PARSE_COLLECTION_1);
227 g_assert_cmpstr (gupnp_media_collection_get_author (collection), ==,
229 g_assert_cmpstr (gupnp_media_collection_get_title (collection), ==,
231 g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
232 TEST_PARSE_COLLECTION_1);
234 it = items = gupnp_media_collection_get_items (collection);
235 g_assert_cmpint (g_list_length (items), ==, 3);
236 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
239 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
242 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
244 g_list_free_full (items, (GDestroyNotify) g_object_unref);
248 test_didl_collection_parse_full ()
250 GUPnPMediaCollection *collection;
253 collection = gupnp_media_collection_new_from_string
254 (TEST_PARSE_COLLECTION_2);
255 g_assert_cmpstr (gupnp_media_collection_get_author (collection), ==,
256 "NonFlatCollection Author");
257 g_assert_cmpstr (gupnp_media_collection_get_title (collection), ==,
258 "NonFlatCollection");
259 g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
260 TEST_PARSE_COLLECTION_2);
262 it = items = gupnp_media_collection_get_items (collection);
263 g_assert_cmpint (g_list_length (items), ==, 3);
264 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
267 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
270 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
272 g_list_free_full (items, (GDestroyNotify) g_object_unref);
275 #define ERROR_MESSAGE "Failed to parse DIDL-Lite: No 'DIDL-Lite' node in the DIDL-Lite XML:"
278 ignore_xml_parse_error (const gchar *log_domain,
279 GLogLevelFlags log_level,
280 const gchar *message,
283 if (strncmp (message,
285 g_utf8_strlen (ERROR_MESSAGE, -1) - 1) == 0) {
293 test_didl_collection_parse_invalid ()
295 GUPnPMediaCollection *collection;
298 g_test_log_set_fatal_handler (ignore_xml_parse_error, NULL);
299 collection = gupnp_media_collection_new_from_string (TEST_PARSE_NO_XML);
300 items = gupnp_media_collection_get_items (collection);
302 g_assert (items == NULL);
303 g_object_unref (collection);
307 test_didl_collection_create_flat ()
309 GUPnPMediaCollection *collection;
310 GUPnPDIDLLiteItem *item;
312 GUPnPDIDLLiteResource *res;
314 collection = gupnp_media_collection_new ();
315 item = gupnp_media_collection_add_item (collection);
316 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
318 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
319 "object.item.audioItem");
320 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
321 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song1.mp3");
322 g_object_unref (res);
323 g_object_unref (item);
324 item = gupnp_media_collection_add_item (collection);
325 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
327 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
328 "object.item.audioItem");
329 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
330 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song2.mp3");
331 g_object_unref (res);
332 g_object_unref (item);
333 item = gupnp_media_collection_add_item (collection);
334 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
336 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
337 "object.item.audioItem");
338 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
339 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song3.mp3");
340 g_object_unref (res);
341 g_object_unref (item);
342 it = items = gupnp_media_collection_get_items (collection);
343 g_assert_cmpint (g_list_length (items), ==, 3);
344 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
347 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
350 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
352 g_list_free_full (items, (GDestroyNotify) g_object_unref);
353 g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
358 test_didl_collection_create_full ()
360 GUPnPMediaCollection *collection;
361 GUPnPDIDLLiteItem *item;
363 GUPnPDIDLLiteResource *res;
365 collection = gupnp_media_collection_new ();
366 gupnp_media_collection_set_title (collection, "TestCollection1");
367 gupnp_media_collection_set_author (collection, "TestCollection1Author");
369 item = gupnp_media_collection_add_item (collection);
370 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
372 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
373 "object.item.audioItem");
374 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
375 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song1.mp3");
376 g_object_unref (res);
377 g_object_unref (item);
378 item = gupnp_media_collection_add_item (collection);
379 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
381 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
382 "object.item.audioItem");
383 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
384 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song2.mp3");
385 g_object_unref (res);
386 g_object_unref (item);
387 item = gupnp_media_collection_add_item (collection);
388 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
390 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
391 "object.item.audioItem");
392 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
393 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song3.mp3");
394 g_object_unref (res);
395 g_object_unref (item);
396 it = items = gupnp_media_collection_get_items (collection);
397 g_assert_cmpint (g_list_length (items), ==, 3);
398 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
401 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
404 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
406 g_list_free_full (items, (GDestroyNotify) g_object_unref);
407 g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
412 test_didl_collection_create_reparent ()
414 GUPnPMediaCollection *collection;
415 GUPnPDIDLLiteItem *item;
417 GUPnPDIDLLiteResource *res;
419 collection = gupnp_media_collection_new ();
421 item = gupnp_media_collection_add_item (collection);
422 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
424 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
425 "object.item.audioItem");
426 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
427 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song1.mp3");
428 g_object_unref (res);
429 g_object_unref (item);
430 item = gupnp_media_collection_add_item (collection);
431 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
433 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
434 "object.item.audioItem");
435 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
436 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song2.mp3");
437 g_object_unref (res);
438 g_object_unref (item);
439 item = gupnp_media_collection_add_item (collection);
440 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
442 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
443 "object.item.audioItem");
444 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
445 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song3.mp3");
446 g_object_unref (res);
447 g_object_unref (item);
448 it = items = gupnp_media_collection_get_items (collection);
450 /* Force reparenting of the items in the XML */
451 gupnp_media_collection_set_title (collection, "TestCollection1");
452 gupnp_media_collection_set_author (collection, "TestCollection1Author");
454 g_assert_cmpint (g_list_length (items), ==, 3);
455 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
458 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
461 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
463 g_list_free_full (items, (GDestroyNotify) g_object_unref);
465 g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
466 TEST_CREATE_FULL_REPARENT);
469 int main (int argc, char *argv[])
471 #if !GLIB_CHECK_VERSION (2, 35, 0)
474 g_test_init (&argc, &argv, NULL);
476 g_test_add_func ("/didl/collection/construction",
477 test_didl_collection_construction);
478 g_test_add_func ("/didl/collection/parse_flat",
479 test_didl_collection_parse_flat);
480 g_test_add_func ("/didl/collection/parse_full",
481 test_didl_collection_parse_full);
482 g_test_add_func ("/didl/collection/parse_invalid",
483 test_didl_collection_parse_invalid);
485 g_test_add_func ("/didl/collection/create_flat",
486 test_didl_collection_create_flat);
487 g_test_add_func ("/didl/collection/create_full",
488 test_didl_collection_create_full);
489 g_test_add_func ("/didl/collection/create_reparent",
490 test_didl_collection_create_reparent);
492 return g_test_run ();