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.
24 #include <libgupnp-av/gupnp-media-collection.h>
26 /* Flat DIDL_S playlist */
27 #define TEST_PARSE_COLLECTION_1 \
28 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \
30 " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"" \
31 " xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\"" \
32 " xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\"" \
33 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" \
34 " xsi:schemaLocation=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" \
35 " http://www.upnp.org/schemas/av/didl-lite-v2-20060531.xsd" \
36 " urn:schemas-upnp-org:metadata-1-0/upnp/" \
37 " http://www.upnp.org/schemas/av/upnp-v2-20060531.xsd\">" \
38 " <item id=\"\" parentID=\"0\" restricted=\"0\">" \
39 " <dc:title>Song1</dc:title>" \
40 " <upnp:class>object.item.audioItem</upnp:class>" \
41 " <res protocolInfo=\"*:*:*:*\" />" \
42 " <upnp:artist></upnp:artist>" \
44 " <item id=\"\" parentID=\"0\" restricted=\"0\">" \
45 " <dc:title>Song2</dc:title>" \
46 " <upnp:class>object.item.audioItem</upnp:class>" \
47 " <res protocolInfo=\"*:*:*:*\" />" \
49 " <item id=\"\" parentID=\"0\" restricted=\"0\">" \
50 " <dc:title>Song3</dc:title>" \
51 " <upnp:class>object.item.audioItem</upnp:class>" \
52 " <res protocolInfo=\"*:*:*:*\" />" \
56 /* Nested DIDL_S playlist */
57 #define TEST_PARSE_COLLECTION_2 \
58 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \
60 " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"" \
61 " xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\"" \
62 " xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\"" \
63 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" \
64 " xsi:schemaLocation=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" \
65 " http://www.upnp.org/schemas/av/didl-lite-v2-20060531.xsd" \
66 " urn:schemas-upnp-org:metadata-1-0/upnp/" \
67 " http://www.upnp.org/schemas/av/upnp-v2-20060531.xsd\">" \
68 " <container id=\"1\" parentID=\"0\" restricted=\"0\">" \
69 " <dc:title>NonFlatCollection</dc:title>" \
70 " <dc:creator>NonFlatCollection Author</dc:creator>" \
71 " <item id=\"\" parentID=\"1\" restricted=\"0\">" \
72 " <dc:title>Song1</dc:title>" \
73 " <upnp:class>object.item.audioItem</upnp:class>" \
74 " <res protocolInfo=\"*:*:*:*\" />" \
75 " <upnp:artist></upnp:artist>" \
77 " <item id=\"\" parentID=\"1\" restricted=\"0\">" \
78 " <dc:title>Song2</dc:title>" \
79 " <upnp:class>object.item.audioItem</upnp:class>" \
80 " <res protocolInfo=\"*:*:*:*\" />" \
82 " <item id=\"\" parentID=\"1\" restricted=\"0\">" \
83 " <dc:title>Song3</dc:title>" \
84 " <upnp:class>object.item.audioItem</upnp:class>" \
85 " <res protocolInfo=\"*:*:*:*\" />" \
90 #define TEST_CREATE_FLAT \
92 "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " \
93 "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" " \
94 "xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\" " \
95 "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\">" \
96 "<item restricted=\"1\">" \
97 "<dc:title>Song1</dc:title>" \
98 "<upnp:class>object.item.audioItem</upnp:class>" \
99 "<res>http://example.com/song1.mp3</res>" \
101 "<item restricted=\"1\">" \
102 "<dc:title>Song2</dc:title>" \
103 "<upnp:class>object.item.audioItem</upnp:class>" \
104 "<res>http://example.com/song2.mp3</res>" \
106 "<item restricted=\"1\">" \
107 "<dc:title>Song3</dc:title>" \
108 "<upnp:class>object.item.audioItem</upnp:class>" \
109 "<res>http://example.com/song3.mp3</res>" \
113 #define TEST_CREATE_FULL \
115 "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " \
116 "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" " \
117 "xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\" " \
118 "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\">" \
120 "<dc:title>TestCollection1</dc:title>" \
121 "<dc:creator>TestCollection1Author</dc:creator>" \
122 "<item restricted=\"1\">" \
123 "<dc:title>Song1</dc:title>" \
124 "<upnp:class>object.item.audioItem</upnp:class>" \
125 "<res>http://example.com/song1.mp3</res>" \
127 "<item restricted=\"1\">" \
128 "<dc:title>Song2</dc:title>" \
129 "<upnp:class>object.item.audioItem</upnp:class>" \
130 "<res>http://example.com/song2.mp3</res>" \
132 "<item restricted=\"1\">" \
133 "<dc:title>Song3</dc:title>" \
134 "<upnp:class>object.item.audioItem</upnp:class>" \
135 "<res>http://example.com/song3.mp3</res>" \
140 #define TEST_CREATE_FULL_REPARENT \
142 "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " \
143 "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" " \
144 "xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\" " \
145 "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\">" \
147 "<item restricted=\"1\">" \
148 "<dc:title>Song1</dc:title>" \
149 "<upnp:class>object.item.audioItem</upnp:class>" \
150 "<res>http://example.com/song1.mp3</res>" \
152 "<item restricted=\"1\">" \
153 "<dc:title>Song2</dc:title>" \
154 "<upnp:class>object.item.audioItem</upnp:class>" \
155 "<res>http://example.com/song2.mp3</res>" \
157 "<item restricted=\"1\">" \
158 "<dc:title>Song3</dc:title>" \
159 "<upnp:class>object.item.audioItem</upnp:class>" \
160 "<res>http://example.com/song3.mp3</res>" \
162 "<dc:title>TestCollection1</dc:title>" \
163 "<dc:creator>TestCollection1Author</dc:creator>" \
167 #define TEST_PARSE_NO_XML "This is just some random text"
170 test_didl_collection_construction ()
172 GUPnPMediaCollection *collection;
174 /* Check that a collection created via auxillary function is mutable */
175 collection = gupnp_media_collection_new ();
176 g_assert (gupnp_media_collection_get_mutable (collection));
177 g_object_unref (collection);
179 /* Check that a collection created via auxillary parse function is
181 collection = gupnp_media_collection_new_from_string
182 (TEST_PARSE_COLLECTION_1);
183 g_assert (!gupnp_media_collection_get_mutable (collection));
184 g_object_unref (collection);
186 /* Check that creating a collection via g_object_new and title/author
187 * properties set is mutable */
188 collection = g_object_new (GUPNP_TYPE_MEDIA_COLLECTION,
189 "title", "test01collection",
190 "author", "test01author",
192 g_assert (gupnp_media_collection_get_mutable (collection));
193 g_object_unref (collection);
195 /* Check that creating a collection via g_object_new and data is not
197 collection = g_object_new (GUPNP_TYPE_MEDIA_COLLECTION,
198 "data", TEST_PARSE_COLLECTION_1,
200 g_assert (!gupnp_media_collection_get_mutable (collection));
201 g_object_unref (collection);
203 /* Check that creating a collection with all properties set will result
204 * in a collection that ignored "title" and "author" properties.
206 collection = g_object_new (GUPNP_TYPE_MEDIA_COLLECTION,
207 "title", "test01collection",
208 "author", "test01author",
209 "data", TEST_PARSE_COLLECTION_1,
211 g_assert (!gupnp_media_collection_get_mutable (collection));
212 g_assert_cmpstr (gupnp_media_collection_get_author (collection), ==,
214 g_assert_cmpstr (gupnp_media_collection_get_title (collection), ==,
216 g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
217 TEST_PARSE_COLLECTION_1);
218 g_object_unref (collection);
222 test_didl_collection_parse_flat ()
224 GUPnPMediaCollection *collection;
227 collection = gupnp_media_collection_new_from_string
228 (TEST_PARSE_COLLECTION_1);
229 g_assert_cmpstr (gupnp_media_collection_get_author (collection), ==,
231 g_assert_cmpstr (gupnp_media_collection_get_title (collection), ==,
233 g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
234 TEST_PARSE_COLLECTION_1);
236 it = items = gupnp_media_collection_get_items (collection);
237 g_assert_cmpint (g_list_length (items), ==, 3);
238 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
241 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
244 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
246 g_list_free_full (items, (GDestroyNotify) g_object_unref);
250 test_didl_collection_parse_full ()
252 GUPnPMediaCollection *collection;
255 collection = gupnp_media_collection_new_from_string
256 (TEST_PARSE_COLLECTION_2);
257 g_assert_cmpstr (gupnp_media_collection_get_author (collection), ==,
258 "NonFlatCollection Author");
259 g_assert_cmpstr (gupnp_media_collection_get_title (collection), ==,
260 "NonFlatCollection");
261 g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
262 TEST_PARSE_COLLECTION_2);
264 it = items = gupnp_media_collection_get_items (collection);
265 g_assert_cmpint (g_list_length (items), ==, 3);
266 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
269 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
272 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
274 g_list_free_full (items, (GDestroyNotify) g_object_unref);
277 #define ERROR_MESSAGE "Failed to parse DIDL-Lite: No 'DIDL-Lite' node in the DIDL-Lite XML:"
280 ignore_xml_parse_error (G_GNUC_UNUSED const gchar *log_domain,
281 G_GNUC_UNUSED GLogLevelFlags log_level,
282 const gchar *message,
283 G_GNUC_UNUSED gpointer user_data)
285 if (strncmp (message,
287 g_utf8_strlen (ERROR_MESSAGE, -1) - 1) == 0) {
295 test_didl_collection_parse_invalid ()
297 GUPnPMediaCollection *collection;
300 g_test_log_set_fatal_handler (ignore_xml_parse_error, NULL);
301 collection = gupnp_media_collection_new_from_string (TEST_PARSE_NO_XML);
302 items = gupnp_media_collection_get_items (collection);
304 g_assert (items == NULL);
305 g_object_unref (collection);
309 test_didl_collection_create_flat ()
311 GUPnPMediaCollection *collection;
312 GUPnPDIDLLiteItem *item;
314 GUPnPDIDLLiteResource *res;
316 collection = gupnp_media_collection_new ();
317 item = gupnp_media_collection_add_item (collection);
318 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
320 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
321 "object.item.audioItem");
322 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
323 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song1.mp3");
324 g_object_unref (res);
325 g_object_unref (item);
326 item = gupnp_media_collection_add_item (collection);
327 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
329 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
330 "object.item.audioItem");
331 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
332 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song2.mp3");
333 g_object_unref (res);
334 g_object_unref (item);
335 item = gupnp_media_collection_add_item (collection);
336 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
338 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
339 "object.item.audioItem");
340 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
341 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song3.mp3");
342 g_object_unref (res);
343 g_object_unref (item);
344 it = items = gupnp_media_collection_get_items (collection);
345 g_assert_cmpint (g_list_length (items), ==, 3);
346 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
349 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
352 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
354 g_list_free_full (items, (GDestroyNotify) g_object_unref);
355 g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
360 test_didl_collection_create_full ()
362 GUPnPMediaCollection *collection;
363 GUPnPDIDLLiteItem *item;
365 GUPnPDIDLLiteResource *res;
367 collection = gupnp_media_collection_new ();
368 gupnp_media_collection_set_title (collection, "TestCollection1");
369 gupnp_media_collection_set_author (collection, "TestCollection1Author");
371 item = gupnp_media_collection_add_item (collection);
372 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
374 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
375 "object.item.audioItem");
376 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
377 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song1.mp3");
378 g_object_unref (res);
379 g_object_unref (item);
380 item = gupnp_media_collection_add_item (collection);
381 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
383 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
384 "object.item.audioItem");
385 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
386 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song2.mp3");
387 g_object_unref (res);
388 g_object_unref (item);
389 item = gupnp_media_collection_add_item (collection);
390 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
392 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
393 "object.item.audioItem");
394 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
395 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song3.mp3");
396 g_object_unref (res);
397 g_object_unref (item);
398 it = items = gupnp_media_collection_get_items (collection);
399 g_assert_cmpint (g_list_length (items), ==, 3);
400 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
403 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
406 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
408 g_list_free_full (items, (GDestroyNotify) g_object_unref);
409 g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
414 test_didl_collection_create_reparent ()
416 GUPnPMediaCollection *collection;
417 GUPnPDIDLLiteItem *item;
419 GUPnPDIDLLiteResource *res;
421 collection = gupnp_media_collection_new ();
423 item = gupnp_media_collection_add_item (collection);
424 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
426 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
427 "object.item.audioItem");
428 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
429 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song1.mp3");
430 g_object_unref (res);
431 g_object_unref (item);
432 item = gupnp_media_collection_add_item (collection);
433 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
435 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
436 "object.item.audioItem");
437 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
438 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song2.mp3");
439 g_object_unref (res);
440 g_object_unref (item);
441 item = gupnp_media_collection_add_item (collection);
442 gupnp_didl_lite_object_set_title (GUPNP_DIDL_LITE_OBJECT (item),
444 gupnp_didl_lite_object_set_upnp_class (GUPNP_DIDL_LITE_OBJECT (item),
445 "object.item.audioItem");
446 res = gupnp_didl_lite_object_add_resource (GUPNP_DIDL_LITE_OBJECT (item));
447 gupnp_didl_lite_resource_set_uri (res, "http://example.com/song3.mp3");
448 g_object_unref (res);
449 g_object_unref (item);
450 it = items = gupnp_media_collection_get_items (collection);
452 /* Force reparenting of the items in the XML */
453 gupnp_media_collection_set_title (collection, "TestCollection1");
454 gupnp_media_collection_set_author (collection, "TestCollection1Author");
456 g_assert_cmpint (g_list_length (items), ==, 3);
457 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
460 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
463 g_assert_cmpstr (gupnp_didl_lite_object_get_title (GUPNP_DIDL_LITE_OBJECT (it->data)), ==,
465 g_list_free_full (items, (GDestroyNotify) g_object_unref);
467 g_assert_cmpstr (gupnp_media_collection_get_string (collection), ==,
468 TEST_CREATE_FULL_REPARENT);
471 int main (int argc, char *argv[])
473 #if !GLIB_CHECK_VERSION (2, 35, 0)
476 g_test_init (&argc, &argv, NULL);
478 g_test_add_func ("/didl/collection/construction",
479 test_didl_collection_construction);
480 g_test_add_func ("/didl/collection/parse_flat",
481 test_didl_collection_parse_flat);
482 g_test_add_func ("/didl/collection/parse_full",
483 test_didl_collection_parse_full);
484 g_test_add_func ("/didl/collection/parse_invalid",
485 test_didl_collection_parse_invalid);
487 g_test_add_func ("/didl/collection/create_flat",
488 test_didl_collection_create_flat);
489 g_test_add_func ("/didl/collection/create_full",
490 test_didl_collection_create_full);
491 g_test_add_func ("/didl/collection/create_reparent",
492 test_didl_collection_create_reparent);
494 return g_test_run ();