summaryrefslogtreecommitdiff
path: root/src/unittest/testwebvi.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/unittest/testwebvi.py')
-rw-r--r--src/unittest/testwebvi.py407
1 files changed, 407 insertions, 0 deletions
diff --git a/src/unittest/testwebvi.py b/src/unittest/testwebvi.py
new file mode 100644
index 0000000..6017ded
--- /dev/null
+++ b/src/unittest/testwebvi.py
@@ -0,0 +1,407 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# This file is part of vdr-webvideo-plugin.
+#
+# Copyright 2009,2010 Antti Ajanki <antti.ajanki@iki.fi>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""Blackbox tests for each of thee supported video sites and webvicli.
+
+Mainly useful for checking if the web sites have changed so much that
+the XSLT templates don't match to them anymore. Requires network
+connection because the tests automatically connect and navigate
+through links on the video sites.
+"""
+
+import unittest
+import sys
+import re
+
+sys.path.append('../webvicli')
+sys.path.append('../libwebvi')
+from webvicli import client, menu
+import webvi.api
+from webvi.constants import WebviConfig
+
+class TestServiceModules(unittest.TestCase):
+
+ # ========== Helper functions ==========
+
+ def setUp(self):
+ webvi.api.set_config(WebviConfig.TEMPLATE_PATH, '../../templates')
+ self.client = client.WVClient([], {}, {})
+
+ def getLinks(self, menuobj):
+ links = []
+ for i in xrange(len(menuobj)):
+ if isinstance(menuobj[i], menu.MenuItemLink):
+ links.append(menuobj[i])
+ return links
+
+ def downloadMenuPage(self, reference, menuname):
+ (status, statusmsg, menuobj) = self.client.getmenu(reference)
+ self.assertEqual(status, 0, 'Unexpected status code %s (%s) in %s menu\nFailed ref was %s' % (status, statusmsg, menuname, reference))
+ self.assertNotEqual(menuobj, None, 'Failed to get %s menu' % menuname)
+ return menuobj
+
+ def downloadAndExtractLinks(self, reference, minlinks, menuname):
+ menuobj = self.downloadMenuPage(reference, menuname)
+ links = self.getLinks(menuobj)
+ self.assertTrue(len(links) >= minlinks, 'Too few links in %s menu' % menuname)
+ return links
+
+ def checkMediaUrl(self, reference):
+ streamurl = self.client.get_stream_url(reference)
+ self.assertNotEqual(streamurl, None, 'get_stream_url returned None')
+ self.assertNotEqual(streamurl, '', 'get_stream_url returned empty string')
+
+ def getServiceReference(self, templatedir):
+ service = open(templatedir + '/service.xml').read()
+ m = re.search(r'<ref>(.*)</ref>', service)
+ self.assertNotEqual(m, None, 'no <ref> in service.xml')
+ return m.group(1)
+
+ # ========== Tests for supported websites ==========
+
+ def testMainMenu(self):
+ self.downloadAndExtractLinks('wvt:///?srcurl=mainmenu', 4, 'main')
+
+ def testYoutube(self):
+ # Category page
+ ref = self.getServiceReference('../../templates/youtube')
+ links = self.downloadAndExtractLinks(ref, 3, 'category')
+
+ # Navigation page
+ # The third one is the first "proper" category. The first and second are "Search" and "All"
+ navigationref = links[2].ref
+ links = self.downloadAndExtractLinks(navigationref, 2, 'navigation')
+
+ # Video link
+ videolink = links[0]
+ self.assertNotEqual(videolink.stream, None, 'No media object in a video link')
+ self.assertNotEqual(videolink.ref, None, 'No description page in a video link')
+ self.checkMediaUrl(videolink.stream)
+
+ def testYoutubeSearch(self):
+ menuobj = self.downloadMenuPage('wvt:///youtube/search.xsl', 'search')
+ self.assertTrue(len(menuobj) >= 4, 'Too few items in search menu')
+
+ self.assertTrue(isinstance(menuobj[0], menu.MenuItemTextField))
+ self.assertTrue(isinstance(menuobj[1], menu.MenuItemList))
+ self.assertTrue(len(menuobj[1].items) >= 4)
+ self.assertTrue(isinstance(menuobj[2], menu.MenuItemList))
+ self.assertTrue(len(menuobj[2].items) >= 4)
+ self.assertTrue(isinstance(menuobj[3], menu.MenuItemSubmitButton))
+
+ # Query term
+ menuobj[0].value = 'youtube'
+ # Sort by: rating
+ menuobj[1].current = 3
+ # Uploaded: This month
+ menuobj[2].current = 3
+
+ resultref = menuobj[3].activate()
+ self.assertNotEqual(resultref, None)
+ self.downloadAndExtractLinks(resultref, 1, 'search result')
+
+ def testGoogleSearch(self):
+ ref = self.getServiceReference('../../templates/google')
+ menuobj = self.downloadMenuPage(ref, 'search')
+ self.assertTrue(len(menuobj) == 4, 'Unexpected number of items in Google search menu')
+
+ self.assertTrue(isinstance(menuobj[0], menu.MenuItemTextField))
+ self.assertTrue(isinstance(menuobj[1], menu.MenuItemList))
+ self.assertTrue(len(menuobj[1].items) >= 4)
+ self.assertTrue(isinstance(menuobj[2], menu.MenuItemList))
+ self.assertTrue(len(menuobj[2].items) >= 4)
+ self.assertTrue(isinstance(menuobj[3], menu.MenuItemSubmitButton))
+
+ # Query term
+ menuobj[0].value = 'google'
+ # Sort by: date
+ menuobj[1].current = 3
+ # Duration: Short
+ menuobj[2].current = 1
+
+ resultref = menuobj[3].activate()
+ self.assertNotEqual(resultref, None)
+ self.downloadAndExtractLinks(resultref, 1, 'search result')
+
+ def testSVTPlay(self):
+ # Category page
+ ref = self.getServiceReference('../../templates/svtplay')
+ links = self.downloadAndExtractLinks(ref, 3, 'category')
+
+ # Navigation page
+ navigationref = links[0].ref
+ links = self.downloadAndExtractLinks(navigationref, 2, 'navigation')
+
+ # Single program
+ programref = links[0].ref
+ links = self.downloadAndExtractLinks(programref, 1, 'program')
+
+ # Video link
+ videolink = links[0]
+ self.assertNotEqual(videolink.stream, None, 'No media object in a video link')
+ self.assertNotEqual(videolink.ref, None, 'No description page in a video link')
+ self.checkMediaUrl(videolink.stream)
+
+ def testMetacafe(self):
+ # Category page
+ ref = self.getServiceReference('../../templates/metacafe')
+ links = self.downloadAndExtractLinks(ref, 3, 'category')
+
+ # The first is "Search", the second is "Channels" and the
+ # third is the first "proper" navigation.
+ channelsref = links[1].ref
+ navigationref = links[2].ref
+
+ # Navigation page
+ links = self.downloadAndExtractLinks(navigationref, 2, 'navigation')
+
+ # Video link
+ videolink = links[0]
+ self.assertNotEqual(videolink.stream, None, 'No media object in a video link')
+ self.assertNotEqual(videolink.ref, None, 'No description page in a video link')
+ self.checkMediaUrl(videolink.stream)
+
+ # User channels
+ links = self.downloadAndExtractLinks(channelsref, 3, 'channel list')
+
+ def testMetacafeSearch(self):
+ menuobj = self.downloadMenuPage('wvt:///metacafe/search.xsl', 'search')
+ self.assertTrue(len(menuobj) >= 4, 'Too few items in search menu')
+
+ self.assertTrue(isinstance(menuobj[0], menu.MenuItemTextField))
+ self.assertTrue(isinstance(menuobj[1], menu.MenuItemList))
+ self.assertTrue(len(menuobj[1].items) == 3)
+ self.assertTrue(isinstance(menuobj[2], menu.MenuItemList))
+ self.assertTrue(len(menuobj[2].items) == 4)
+ self.assertTrue(isinstance(menuobj[3], menu.MenuItemSubmitButton))
+
+ # Query term
+ menuobj[0].value = 'metacafe'
+ # Sort by: most discussed
+ menuobj[1].current = 2
+ # Published: Anytime
+ menuobj[2].current = 2
+
+ resultref = menuobj[3].activate()
+ self.assertNotEqual(resultref, None)
+ self.downloadAndExtractLinks(resultref, 1, 'search result')
+
+ def testVimeo(self):
+ # Category page
+ ref = self.getServiceReference('../../templates/vimeo')
+ links = self.downloadAndExtractLinks(ref, 3, 'Vimeo main page')
+
+ # The first is "Search", the second is "Channels" and the
+ # third is "Groups"
+ channelsref = links[1].ref
+ groupsref = links[2].ref
+
+ # Channels page
+ links = self.downloadAndExtractLinks(channelsref, 2, 'channels')
+
+ # Navigation page
+ links = self.downloadAndExtractLinks(links[0].ref, 2, 'channels navigation')
+
+ # Video link
+ videolink = links[0]
+ self.assertNotEqual(videolink.stream, None, 'No media object in a video link')
+ self.assertNotEqual(videolink.ref, None, 'No description page in a video link')
+ self.checkMediaUrl(videolink.stream)
+
+ # User groups
+ links = self.downloadAndExtractLinks(groupsref, 2, 'channel list')
+
+ # Navigation page
+ links = self.downloadAndExtractLinks(links[0].ref, 2, 'groups navigation')
+
+ def testVimeoSearch(self):
+ menuobj = self.downloadMenuPage('wvt:///vimeo/search.xsl?srcurl=http://www.vimeo.com/', 'search')
+ self.assertTrue(len(menuobj) >= 3, 'Too few items in search menu')
+
+ self.assertTrue(isinstance(menuobj[0], menu.MenuItemTextField))
+ self.assertTrue(isinstance(menuobj[1], menu.MenuItemList))
+ self.assertTrue(len(menuobj[1].items) >= 2)
+ self.assertTrue(isinstance(menuobj[2], menu.MenuItemSubmitButton))
+
+ # Query term
+ menuobj[0].value = 'vimeo'
+ # Sort by: newest
+ menuobj[1].current = 1
+
+ resultref = menuobj[2].activate()
+ self.assertNotEqual(resultref, None)
+ self.downloadAndExtractLinks(resultref, 1, 'search result')
+
+ def testYLEAreena(self):
+ # Category page
+ ref = self.getServiceReference('../../templates/yleareena')
+ links = self.downloadAndExtractLinks(ref, 3, 'category')
+
+ # The first is "Search", the second is "live", the third is
+ # "all", the rest are navigation links.
+ liveref = links[1].ref
+ navigationref = links[3].ref
+
+ # Navigation page
+ links = self.downloadAndExtractLinks(navigationref, 2, 'navigation')
+
+ # Video link
+ videolink = links[0]
+ self.assertNotEqual(videolink.stream, None, 'No media object in a video link')
+ self.assertNotEqual(videolink.ref, None, 'No description page in a video link')
+
+ # live broadcasts
+ links = self.downloadAndExtractLinks(liveref, 2, 'live broadcasts')
+
+ def testYLEAreenaSearch(self):
+ menuobj = self.downloadMenuPage('wvt:///yleareena/search.xsl?srcurl=http://areena.yle.fi/haku', 'search')
+ self.assertTrue(len(menuobj) >= 8, 'Too few items in search menu')
+
+ self.assertTrue(isinstance(menuobj[0], menu.MenuItemTextField))
+ self.assertTrue(isinstance(menuobj[1], menu.MenuItemList))
+ self.assertTrue(len(menuobj[1].items) >= 3)
+ self.assertTrue(isinstance(menuobj[2], menu.MenuItemList))
+ self.assertTrue(len(menuobj[2].items) >= 2)
+ self.assertTrue(isinstance(menuobj[3], menu.MenuItemList))
+ self.assertTrue(len(menuobj[3].items) >= 2)
+ self.assertTrue(isinstance(menuobj[4], menu.MenuItemList))
+ self.assertTrue(len(menuobj[4].items) >= 3)
+ self.assertTrue(isinstance(menuobj[5], menu.MenuItemList))
+ self.assertTrue(len(menuobj[5].items) >= 4)
+ self.assertTrue(isinstance(menuobj[6], menu.MenuItemList))
+ self.assertTrue(len(menuobj[6].items) >= 2)
+ self.assertTrue(isinstance(menuobj[7], menu.MenuItemSubmitButton))
+
+ # Query term
+ menuobj[0].value = 'yle'
+ # Media: video
+ menuobj[1].current = 1
+ # Category: all
+ menuobj[2].current = 0
+ # Channel: all
+ menuobj[3].current = 0
+ # Language: Finnish
+ menuobj[4].current = 1
+ # Uploaded: all
+ menuobj[5].current = 0
+ # Only outside Finland: no
+ menuobj[6].current = 0
+
+ resultref = menuobj[7].activate()
+ self.assertNotEqual(resultref, None)
+ self.downloadAndExtractLinks(resultref, 1, 'search result')
+
+ def testKatsomo(self):
+ # Category page
+ ref = self.getServiceReference('../../templates/katsomo')
+ links = self.downloadAndExtractLinks(ref, 2, 'category')
+
+ # The first is "Search", the rest are navigation links.
+ navigationref = links[1].ref
+
+ # Navigation page
+ links = self.downloadAndExtractLinks(navigationref, 1, 'navigation')
+
+ # Program page
+ links = self.downloadAndExtractLinks(links[0].ref, 1, 'program')
+
+ # Video link
+ # The first few links may be navigation links, but there
+ # should be video links after them.
+ foundVideo = False
+ for link in links:
+ if link.stream is not None:
+ foundVideo = True
+
+ self.assertTrue(link, 'No a video links in the program page')
+
+ def testKatsomoSearch(self):
+ menuobj = self.downloadMenuPage('wvt:///katsomo/search.xsl', 'search')
+ self.assertTrue(len(menuobj) >= 2, 'Too few items in search menu')
+
+ self.assertTrue(isinstance(menuobj[0], menu.MenuItemTextField))
+ self.assertTrue(isinstance(menuobj[1], menu.MenuItemSubmitButton))
+
+ # Query term
+ menuobj[0].value = 'mtv3'
+
+ resultref = menuobj[1].activate()
+ self.assertNotEqual(resultref, None)
+ self.downloadAndExtractLinks(resultref, 1, 'search result')
+
+ def testRuutuFi(self):
+ # Category page
+ ref = self.getServiceReference('../../templates/ruutufi')
+ links = self.downloadAndExtractLinks(ref, 4, 'category')
+
+ # The first is "Search", the second is "Series"
+ seriesref = links[1].ref
+
+ # Series page
+ links = self.downloadAndExtractLinks(seriesref, 1, 'series')
+
+ # Program page
+ links = self.downloadAndExtractLinks(links[0].ref, 1, 'program')
+
+ # Video link
+ videolink = links[0]
+ self.assertNotEqual(videolink.stream, None, 'No media object in a video link')
+ self.assertNotEqual(videolink.ref, None, 'No description page in a video link')
+
+ def testRuutuFiSearch(self):
+ menuobj = self.downloadMenuPage('wvt:///ruutufi/search.xsl', 'search')
+ self.assertTrue(len(menuobj) >= 2, 'Too few items in search menu')
+
+ self.assertTrue(isinstance(menuobj[0], menu.MenuItemTextField))
+ self.assertTrue(isinstance(menuobj[1], menu.MenuItemSubmitButton))
+
+ # Query term
+ menuobj[0].value = 'nelonen'
+
+ resultref = menuobj[1].activate()
+ self.assertNotEqual(resultref, None)
+ self.downloadAndExtractLinks(resultref, 1, 'search result')
+
+ def testSubtv(self):
+ # Category page
+ ref = self.getServiceReference('../../templates/subtv')
+ links = self.downloadAndExtractLinks(ref, 4, 'series')
+
+ # Program page
+ links = self.downloadAndExtractLinks(links[0].ref, 1, 'program')
+
+ # Video link
+ videolink = links[0]
+ self.assertNotEqual(videolink.stream, None, 'No media object in a video link')
+ self.assertNotEqual(videolink.ref, None, 'No description page in a video link')
+
+
+if __name__ == '__main__':
+ testnames = sys.argv[1:]
+
+ if testnames == []:
+ # Run all tests
+ unittest.main()
+ else:
+ # Run test listed on the command line
+ for test in testnames:
+ suite = unittest.TestSuite()
+ suite.addTest(TestServiceModules(test))
+ unittest.TextTestRunner(verbosity=2).run(suite)