Combine .js and .py coverage reports.
Remove services that cannot be searched from search dropdown. Refactoring and additional unit tests.
This commit is contained in:
parent
2629464c18
commit
411a3781fd
2
.gitignore
vendored
2
.gitignore
vendored
@ -8,7 +8,7 @@
|
|||||||
MANIFEST
|
MANIFEST
|
||||||
build/
|
build/
|
||||||
cover/
|
cover/
|
||||||
coverage/
|
.karma_coverage/
|
||||||
coverage.xml
|
coverage.xml
|
||||||
dist/
|
dist/
|
||||||
docs/_build/
|
docs/_build/
|
||||||
|
|||||||
19
.travis.yml
19
.travis.yml
@ -1,10 +1,18 @@
|
|||||||
sudo: false
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
|
|
||||||
language: python
|
language: python
|
||||||
|
|
||||||
python:
|
python:
|
||||||
- "2.7_with_system_site_packages"
|
- "2.7_with_system_site_packages"
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- mopidy-stable
|
||||||
|
packages:
|
||||||
|
- mopidy
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- TOX_ENV=py27
|
- TOX_ENV=py27
|
||||||
- TOX_ENV=flake8
|
- TOX_ENV=flake8
|
||||||
@ -13,6 +21,11 @@ env:
|
|||||||
- TOX_ENV=csslint
|
- TOX_ENV=csslint
|
||||||
- TOX_ENV=tidy
|
- TOX_ENV=tidy
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- "sudo sed -i '/127.0.1.1/d' /etc/hosts" # Workaround https://github.com/tornadoweb/tornado/issues/1573
|
||||||
|
- "sudo apt-get update -qq"
|
||||||
|
- "sudo apt-get install -y gstreamer0.10-plugins-good python-gst0.10"
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- "pip install tox"
|
- "pip install tox"
|
||||||
|
|
||||||
@ -20,6 +33,4 @@ script:
|
|||||||
- "tox -e $TOX_ENV"
|
- "tox -e $TOX_ENV"
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
# TODO: find a way to combine .py and .js coverage reports.
|
- "if [ $TOX_ENV == 'test' ]; then pip install coveralls; coveralls --merge=./karma_coverage/coverage-final.json; fi"
|
||||||
# - "if [ $TOX_ENV == 'py27' ]; then pip install coveralls; coveralls; fi"
|
|
||||||
- "if [ $TOX_ENV == 'test' ]; then cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js; fi"
|
|
||||||
|
|||||||
@ -71,9 +71,10 @@ module.exports = function (config) {
|
|||||||
|
|
||||||
coverageReporter: {
|
coverageReporter: {
|
||||||
// specify a common output directory
|
// specify a common output directory
|
||||||
dir: 'coverage/',
|
dir: '.karma_coverage/',
|
||||||
reporters: [
|
reporters: [
|
||||||
{ type: 'lcov', subdir: '.' },
|
{ type: 'lcov', subdir: '.' },
|
||||||
|
{ type: 'json', subdir: '.' },
|
||||||
{ type: 'text' }
|
{ type: 'text' }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ from mopidy import config, ext
|
|||||||
__version__ = '2.2.0'
|
__version__ = '2.2.0'
|
||||||
|
|
||||||
|
|
||||||
class MusicBoxExtension(ext.Extension):
|
class Extension(ext.Extension):
|
||||||
|
|
||||||
dist_name = 'Mopidy-MusicBox-Webclient'
|
dist_name = 'Mopidy-MusicBox-Webclient'
|
||||||
ext_name = 'musicbox_webclient'
|
ext_name = 'musicbox_webclient'
|
||||||
@ -18,7 +18,7 @@ class MusicBoxExtension(ext.Extension):
|
|||||||
return config.read(conf_file)
|
return config.read(conf_file)
|
||||||
|
|
||||||
def get_config_schema(self):
|
def get_config_schema(self):
|
||||||
schema = super(MusicBoxExtension, self).get_config_schema()
|
schema = super(Extension, self).get_config_schema()
|
||||||
schema['musicbox'] = config.Boolean(optional=True)
|
schema['musicbox'] = config.Boolean(optional=True)
|
||||||
schema['websocket_host'] = config.Hostname(optional=True)
|
schema['websocket_host'] = config.Hostname(optional=True)
|
||||||
schema['websocket_port'] = config.Port(optional=True)
|
schema['websocket_port'] = config.Port(optional=True)
|
||||||
|
|||||||
@ -1,30 +1,14 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html manifest="mb.appcache">
|
<html manifest="mb.appcache">
|
||||||
<head>
|
<head>
|
||||||
<title>Musicbox</title>
|
<title>{{ title }}</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<script type="text/javascript" src="vendors/jquery/jquery-1.12.0.min.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="vendors/jquery_mobile_flat_ui_theme/jquery.mobile.flatui.min.css"/>
|
|
||||||
<script>
|
|
||||||
//configuration
|
|
||||||
var isMusicBox = '{{musicbox}}' == 'True'; // Remove MusicBox only content (e.g. settings, system pages)
|
|
||||||
var websocketUrl = ('{{useWebsocketUrl}}' == 'True') ? '{{websocket_url}}' : ''
|
|
||||||
var hasAlarmClock = '{{alarmclock}}' == 'True'; // Add Alarm Clock icons
|
|
||||||
|
|
||||||
$(document).bind("mobileinit", function () {
|
<script type="text/javascript" src="vendors/jquery/jquery-1.12.0.min.js"></script>
|
||||||
$.extend($.mobile, {
|
<script type="text/javascript" src="vendors/jquery_cookie/jquery.cookie.js"></script>
|
||||||
ajaxEnabled: false,
|
<script type="text/javascript" src="js/custom_scripting.js"></script>
|
||||||
hashListeningEnabled: false
|
|
||||||
// linkBindingEnabled: false
|
<link rel="stylesheet" type="text/css" href="vendors/jquery_mobile_flat_ui_theme/jquery.mobile.flatui.min.css"/>
|
||||||
// buttonMarkup.hoverDelay: 100,
|
|
||||||
// buttonMarkup.corners: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
/* window.addEventListener('load', function () {
|
|
||||||
new FastClick(document.body);
|
|
||||||
}, false);
|
|
||||||
*/
|
|
||||||
</script>
|
|
||||||
<link rel="icon" type="image/gif" href="images/icons/musicbox32.gif" />
|
<link rel="icon" type="image/gif" href="images/icons/musicbox32.gif" />
|
||||||
<link rel="apple-touch-icon" href="images/icons/musicbox57.png" />
|
<link rel="apple-touch-icon" href="images/icons/musicbox57.png" />
|
||||||
<link rel="apple-touch-icon" sizes="72x72" href="images/icons/musicbox72.png" />
|
<link rel="apple-touch-icon" sizes="72x72" href="images/icons/musicbox72.png" />
|
||||||
@ -52,7 +36,7 @@
|
|||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body data-websocket-url="{{websocketUrl}}" data-is-musicbox="{{isMusicBox}}" data-has-alarmclock="{{hasAlarmClock}}">
|
||||||
<div data-role="page" id="page" class="ui-responsive-panel" data-theme="c">
|
<div data-role="page" id="page" class="ui-responsive-panel" data-theme="c">
|
||||||
<div data-role="panel" id="panel" data-position="left" data-theme="a" data-display="reveal" data-position-fixed="true">
|
<div data-role="panel" id="panel" data-position="left" data-theme="a" data-display="reveal" data-position-fixed="true">
|
||||||
|
|
||||||
@ -501,7 +485,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- /page one -->
|
<!-- /page one -->
|
||||||
<script type="text/javascript" src="vendors/mopidy/mopidy.min.js"></script>
|
<script type="text/javascript" src="vendors/mopidy/mopidy.min.js"></script>
|
||||||
<script type="text/javascript" src="vendors/jquery_cookie/jquery.cookie.js"></script>
|
|
||||||
<script type="text/javascript" src="vendors/media_progress_timer/timer.js"></script>
|
<script type="text/javascript" src="vendors/media_progress_timer/timer.js"></script>
|
||||||
<script type="text/javascript" src="js/progress_timer.js"></script>
|
<script type="text/javascript" src="js/progress_timer.js"></script>
|
||||||
<script type="text/javascript" src="js/controls.js"></script>
|
<script type="text/javascript" src="js/controls.js"></script>
|
||||||
|
|||||||
8
mopidy_musicbox_webclient/static/js/custom_scripting.js
Normal file
8
mopidy_musicbox_webclient/static/js/custom_scripting.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// jQuery Mobile configuration options
|
||||||
|
// see: http://api.jquerymobile.com/1.3/global-config/
|
||||||
|
$(document).bind('mobileinit', function () {
|
||||||
|
$.extend($.mobile, {
|
||||||
|
ajaxEnabled: false,
|
||||||
|
hashListeningEnabled: false
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -110,6 +110,19 @@ var uriHumanList = [
|
|||||||
['subsonic', 'Subsonic']
|
['subsonic', 'Subsonic']
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// List of Mopidy URI schemes that should not be searched directly.
|
||||||
|
// Also blacklists 'yt' in favour of using the other 'youtube' supported scheme.
|
||||||
|
var searchBlacklist = [
|
||||||
|
'file',
|
||||||
|
'http',
|
||||||
|
'https',
|
||||||
|
'mms',
|
||||||
|
'rtmp',
|
||||||
|
'rtmps',
|
||||||
|
'rtsp',
|
||||||
|
'yt'
|
||||||
|
]
|
||||||
|
|
||||||
function scrollToTop () {
|
function scrollToTop () {
|
||||||
var divtop = 0
|
var divtop = 0
|
||||||
$('body,html').animate({
|
$('body,html').animate({
|
||||||
|
|||||||
@ -475,6 +475,7 @@ $(document).ready(function (event) {
|
|||||||
$(window).hashchange()
|
$(window).hashchange()
|
||||||
|
|
||||||
// Connect to server
|
// Connect to server
|
||||||
|
var websocketUrl = $(document.body).data('websocket-url')
|
||||||
if (websocketUrl) {
|
if (websocketUrl) {
|
||||||
try {
|
try {
|
||||||
mopidy = new Mopidy({
|
mopidy = new Mopidy({
|
||||||
@ -539,16 +540,16 @@ $(document).ready(function (event) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// remove buttons only for MusicBox
|
// Remove MusicBox only content (e.g. settings, system pages)
|
||||||
if (!isMusicBox) {
|
if (!$(document.body).data('is-musicbox')) {
|
||||||
$('#navSettings').hide()
|
$('#navSettings').hide()
|
||||||
$('#navshutdown').hide()
|
$('#navshutdown').hide()
|
||||||
$('#homesettings').hide()
|
$('#homesettings').hide()
|
||||||
$('#homeshutdown').hide()
|
$('#homeshutdown').hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove Alarm Clock if it is not present
|
// Remove Alarm Clock icons if it is not present
|
||||||
if (!hasAlarmClock) {
|
if (!$(document.body).data('has-alarmclock')) {
|
||||||
$('#navAlarmClock').hide()
|
$('#navAlarmClock').hide()
|
||||||
$('#homeAlarmClock').hide()
|
$('#homeAlarmClock').hide()
|
||||||
$('#homeAlarmClock').nextAll().find('.ui-block-a, .ui-block-b').toggleClass('ui-block-a').toggleClass('ui-block-b')
|
$('#homeAlarmClock').nextAll().find('.ui-block-a, .ui-block-b').toggleClass('ui-block-a').toggleClass('ui-block-b')
|
||||||
|
|||||||
@ -322,8 +322,11 @@ var library = {
|
|||||||
searchScheme = 'all'
|
searchScheme = 'all'
|
||||||
}
|
}
|
||||||
$('#selectSearchService').empty()
|
$('#selectSearchService').empty()
|
||||||
$('#selectSearchService').append(new Option('All backends', 'all'))
|
$('#selectSearchService').append(new Option('All services', 'all'))
|
||||||
mopidy.getUriSchemes().then(function (schemesArray) {
|
mopidy.getUriSchemes().then(function (schemesArray) {
|
||||||
|
schemesArray = schemesArray.filter(function (el) {
|
||||||
|
return searchBlacklist.indexOf(el) < 0
|
||||||
|
})
|
||||||
for (var i = 0; i < schemesArray.length; i++) {
|
for (var i = 0; i < schemesArray.length; i++) {
|
||||||
backendName = getMediaHuman(schemesArray[i])
|
backendName = getMediaHuman(schemesArray[i])
|
||||||
backendName = backendName.charAt(0).toUpperCase() + backendName.slice(1)
|
backendName = backendName.charAt(0).toUpperCase() + backendName.slice(1)
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
CACHE MANIFEST
|
CACHE MANIFEST
|
||||||
|
|
||||||
# 2016-03-19:v1
|
# 2016-03-28:v1
|
||||||
|
|
||||||
NETWORK:
|
NETWORK:
|
||||||
*
|
*
|
||||||
@ -19,8 +19,8 @@ images/icons/play_alt_12x12.png
|
|||||||
images/icons/play_alt_16x16.png
|
images/icons/play_alt_16x16.png
|
||||||
images/loader.gif
|
images/loader.gif
|
||||||
images/user_24x32.png
|
images/user_24x32.png
|
||||||
index.html
|
|
||||||
js/controls.js
|
js/controls.js
|
||||||
|
js/custom_scripting.js
|
||||||
js/functionsvars.js
|
js/functionsvars.js
|
||||||
js/gui.js
|
js/gui.js
|
||||||
js/images.js
|
js/images.js
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import string
|
||||||
|
|
||||||
import tornado.web
|
import tornado.web
|
||||||
|
|
||||||
from . import MusicBoxExtension
|
import mopidy_musicbox_webclient.webclient as mmw
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -21,40 +24,31 @@ class StaticHandler(tornado.web.StaticFileHandler):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_version(cls, settings, path):
|
def get_version(cls, settings, path):
|
||||||
return MusicBoxExtension.version
|
return mmw.Extension.version
|
||||||
|
|
||||||
|
|
||||||
class IndexHandler(tornado.web.RequestHandler):
|
class IndexHandler(tornado.web.RequestHandler):
|
||||||
|
|
||||||
def initialize(self, config, path):
|
def initialize(self, config, path):
|
||||||
ext_config = config[MusicBoxExtension.ext_name]
|
|
||||||
host, port = ext_config['websocket_host'], ext_config['websocket_port']
|
webclient = mmw.Webclient(config)
|
||||||
ws_url = ''
|
|
||||||
if host or port:
|
|
||||||
if not host:
|
|
||||||
host = self.request.host.partition(':')[0]
|
|
||||||
logger.warning('Musicbox websocket_host not specified, '
|
|
||||||
'using %s', host)
|
|
||||||
elif not port:
|
|
||||||
port = config['http']['port']
|
|
||||||
logger.warning('Musicbox websocket_port not specified, '
|
|
||||||
'using %s', port)
|
|
||||||
protocol = 'ws'
|
|
||||||
if self.request.protocol == 'https':
|
|
||||||
protocol = 'wss'
|
|
||||||
ws_url = "%s://%s:%d/mopidy/ws" % (protocol, host, port)
|
|
||||||
|
|
||||||
self.__dict = {
|
self.__dict = {
|
||||||
'version': MusicBoxExtension.version,
|
'isMusicBox': json.dumps(webclient.is_music_box()),
|
||||||
'musicbox': ext_config.get('musicbox', False),
|
'websocketUrl': webclient.get_websocket_url(self.request),
|
||||||
'useWebsocketUrl': ws_url != '',
|
'hasAlarmClock': json.dumps(webclient.has_alarm_clock()),
|
||||||
'websocket_url': ws_url,
|
|
||||||
'alarmclock': config.get('alarmclock', {}).get('enabled', False),
|
|
||||||
}
|
}
|
||||||
self.__path = path
|
self.__path = path
|
||||||
|
self.__title = string.Template('MusicBox on $hostname')
|
||||||
|
|
||||||
def get(self, path):
|
def get(self, path):
|
||||||
return self.render('index.html', **self.__dict)
|
return self.render(path, title=self.get_title(), **self.__dict)
|
||||||
|
|
||||||
|
def get_title(self):
|
||||||
|
hostname, sep, port = self.request.host.rpartition(':')
|
||||||
|
if not sep or not port.isdigit():
|
||||||
|
hostname, port = self.request.host, '80'
|
||||||
|
return self.__title.safe_substitute(hostname=hostname, port=port)
|
||||||
|
|
||||||
def get_template_path(self):
|
def get_template_path(self):
|
||||||
return self.__path
|
return self.__path
|
||||||
|
|||||||
46
mopidy_musicbox_webclient/webclient.py
Normal file
46
mopidy_musicbox_webclient/webclient.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from mopidy_musicbox_webclient import Extension
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class Webclient(object):
|
||||||
|
|
||||||
|
def __init__(self, config):
|
||||||
|
self.config = config
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ext_config(self):
|
||||||
|
return self.config.get(Extension.ext_name, {})
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_version(cls):
|
||||||
|
return Extension.version
|
||||||
|
|
||||||
|
def get_websocket_url(self, request):
|
||||||
|
host, port = self.ext_config['websocket_host'], self.ext_config['websocket_port']
|
||||||
|
ws_url = ''
|
||||||
|
if host or port:
|
||||||
|
if not host:
|
||||||
|
host = request.host.partition(':')[0]
|
||||||
|
logger.warning('Musicbox websocket_host not specified, '
|
||||||
|
'using %s', host)
|
||||||
|
elif not port:
|
||||||
|
port = self.config['http']['port']
|
||||||
|
logger.warning('Musicbox websocket_port not specified, '
|
||||||
|
'using %s', port)
|
||||||
|
protocol = 'ws'
|
||||||
|
if request.protocol == 'https':
|
||||||
|
protocol = 'wss'
|
||||||
|
ws_url = "%s://%s:%d/mopidy/ws" % (protocol, host, port)
|
||||||
|
|
||||||
|
return ws_url
|
||||||
|
|
||||||
|
def has_alarm_clock(self):
|
||||||
|
return self.ext_config.get('alarmclock', {}).get('enabled', False)
|
||||||
|
|
||||||
|
def is_music_box(self):
|
||||||
|
return self.ext_config.get('musicbox', False)
|
||||||
2
setup.py
2
setup.py
@ -29,7 +29,7 @@ setup(
|
|||||||
],
|
],
|
||||||
entry_points={
|
entry_points={
|
||||||
'mopidy.ext': [
|
'mopidy.ext': [
|
||||||
'musicbox_webclient = mopidy_musicbox_webclient:MusicBoxExtension',
|
'musicbox_webclient = mopidy_musicbox_webclient:Extension',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
classifiers=[
|
classifiers=[
|
||||||
|
|||||||
@ -1,22 +1,37 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
from mopidy_musicbox_webclient import MusicBoxExtension
|
import unittest
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
|
from mopidy_musicbox_webclient import Extension
|
||||||
|
|
||||||
|
|
||||||
def test_get_default_config():
|
class ExtensionTests(unittest.TestCase):
|
||||||
ext = MusicBoxExtension()
|
|
||||||
|
|
||||||
config = ext.get_default_config()
|
def test_get_default_config(self):
|
||||||
|
ext = Extension()
|
||||||
|
|
||||||
assert '[musicbox_webclient]' in config
|
config = ext.get_default_config()
|
||||||
assert 'enabled = true' in config
|
|
||||||
|
|
||||||
|
assert '[musicbox_webclient]' in config
|
||||||
|
assert 'enabled = true' in config
|
||||||
|
assert 'websocket_host =' in config
|
||||||
|
assert 'websocket_port =' in config
|
||||||
|
|
||||||
def test_get_config_schema():
|
def test_get_config_schema(self):
|
||||||
ext = MusicBoxExtension()
|
ext = Extension()
|
||||||
|
|
||||||
schema = ext.get_config_schema()
|
schema = ext.get_config_schema()
|
||||||
assert 'musicbox' in schema
|
|
||||||
|
|
||||||
|
assert 'musicbox' in schema
|
||||||
|
assert 'websocket_host' in schema
|
||||||
|
assert 'websocket_port' in schema
|
||||||
|
|
||||||
# TODO Write more tests
|
def test_setup(self):
|
||||||
|
registry = mock.Mock()
|
||||||
|
|
||||||
|
ext = Extension()
|
||||||
|
ext.setup(registry)
|
||||||
|
calls = [mock.call('http:app', {'name': ext.ext_name, 'factory': ext.factory})]
|
||||||
|
registry.add.assert_has_calls(calls, any_order=True)
|
||||||
|
|||||||
@ -7,7 +7,7 @@ chai.use(require('chai-jquery'))
|
|||||||
|
|
||||||
var sinon = require('sinon')
|
var sinon = require('sinon')
|
||||||
|
|
||||||
var coverArt = require('../mopidy_musicbox_webclient/static/js/library.js')
|
var library = require('../mopidy_musicbox_webclient/static/js/library.js')
|
||||||
|
|
||||||
var selectID = '#selectSearchService'
|
var selectID = '#selectSearchService'
|
||||||
var schemesArray
|
var schemesArray
|
||||||
|
|||||||
67
tests/test_web.py
Normal file
67
tests/test_web.py
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
|
import mopidy.config as config
|
||||||
|
|
||||||
|
import tornado.testing
|
||||||
|
import tornado.web
|
||||||
|
import tornado.websocket
|
||||||
|
|
||||||
|
from mopidy_musicbox_webclient import Extension
|
||||||
|
from mopidy_musicbox_webclient.web import StaticHandler
|
||||||
|
|
||||||
|
|
||||||
|
class BaseTest(tornado.testing.AsyncHTTPTestCase):
|
||||||
|
|
||||||
|
def get_app(self):
|
||||||
|
extension = Extension()
|
||||||
|
self.config = config.Proxy({'musicbox_webclient': {
|
||||||
|
'enabled': True,
|
||||||
|
'musicbox': True,
|
||||||
|
'websocket_host': '',
|
||||||
|
'websocket_port': '',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return tornado.web.Application(extension.factory(self.config, mock.Mock()))
|
||||||
|
|
||||||
|
|
||||||
|
class StaticFileHandlerTest(BaseTest):
|
||||||
|
|
||||||
|
def test_static_handler(self):
|
||||||
|
response = self.fetch('/vendors/mopidy/mopidy.js', method='GET')
|
||||||
|
|
||||||
|
assert response.code == 200
|
||||||
|
|
||||||
|
def test_get_version(self):
|
||||||
|
assert StaticHandler.get_version(None, None) == Extension.version
|
||||||
|
|
||||||
|
|
||||||
|
class RedirectHandlerTest(BaseTest):
|
||||||
|
|
||||||
|
def test_redirect_handler(self):
|
||||||
|
response = self.fetch('/', method='GET', follow_redirects=False)
|
||||||
|
|
||||||
|
assert response.code == 301
|
||||||
|
response.headers['Location'].endswith('index.html')
|
||||||
|
|
||||||
|
|
||||||
|
class IndexHandlerTest(BaseTest):
|
||||||
|
|
||||||
|
def test_index_handler(self):
|
||||||
|
response = self.fetch('/index.html', method='GET')
|
||||||
|
assert response.code == 200
|
||||||
|
|
||||||
|
def test_get_title(self):
|
||||||
|
response = self.fetch('/index.html', method='GET')
|
||||||
|
body = tornado.escape.to_unicode(response.body)
|
||||||
|
|
||||||
|
assert '<title>MusicBox on localhost</title>' in body
|
||||||
|
|
||||||
|
def test_initialize_sets_dictionary_objects(self):
|
||||||
|
response = self.fetch('/index.html', method='GET')
|
||||||
|
body = tornado.escape.to_unicode(response.body)
|
||||||
|
|
||||||
|
assert 'data-is-musicbox="true"' in body
|
||||||
|
assert 'data-has-alarmclock="false"' in body
|
||||||
|
assert 'data-websocket-url=""' in body
|
||||||
78
tests/test_webclient.py
Normal file
78
tests/test_webclient.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
|
import mopidy.config as mopidy_config
|
||||||
|
|
||||||
|
from mopidy_musicbox_webclient import Extension
|
||||||
|
from mopidy_musicbox_webclient.webclient import Webclient
|
||||||
|
|
||||||
|
|
||||||
|
class WebclientTests(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
config = mopidy_config.Proxy(
|
||||||
|
{
|
||||||
|
'musicbox_webclient': {
|
||||||
|
'enabled': True,
|
||||||
|
'musicbox': False,
|
||||||
|
'websocket_host': 'host_mock',
|
||||||
|
'websocket_port': 999,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
self.ext = Extension()
|
||||||
|
self.mmw = Webclient(config)
|
||||||
|
|
||||||
|
def test_get_version(self):
|
||||||
|
assert self.mmw.get_version() == self.ext.version
|
||||||
|
|
||||||
|
def test_get_websocket_url_uses_config_file(self):
|
||||||
|
assert self.mmw.get_websocket_url(mock.Mock()) == 'ws://host_mock:999/mopidy/ws'
|
||||||
|
|
||||||
|
def test_get_websocket_url_uses_request_host(self):
|
||||||
|
config = mopidy_config.Proxy(
|
||||||
|
{
|
||||||
|
'musicbox_webclient': {
|
||||||
|
'enabled': True,
|
||||||
|
'musicbox': False,
|
||||||
|
'websocket_host': '',
|
||||||
|
'websocket_port': 999,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
request_mock = mock.Mock(spec='tornado.HTTPServerRequest')
|
||||||
|
request_mock.host = '127.0.0.1'
|
||||||
|
request_mock.protocol = 'https'
|
||||||
|
|
||||||
|
self.mmw.config = config
|
||||||
|
assert self.mmw.get_websocket_url(request_mock) == 'wss://127.0.0.1:999/mopidy/ws'
|
||||||
|
|
||||||
|
def test_get_websocket_url_uses_http_port(self):
|
||||||
|
config = mopidy_config.Proxy(
|
||||||
|
{
|
||||||
|
'http': {
|
||||||
|
'port': 999
|
||||||
|
},
|
||||||
|
'musicbox_webclient': {
|
||||||
|
'enabled': True,
|
||||||
|
'musicbox': False,
|
||||||
|
'websocket_host': '127.0.0.1',
|
||||||
|
'websocket_port': '',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
request_mock = mock.Mock(spec='tornado.HTTPServerRequest')
|
||||||
|
request_mock.host = '127.0.0.1'
|
||||||
|
request_mock.protocol = 'https'
|
||||||
|
|
||||||
|
self.mmw.config = config
|
||||||
|
assert self.mmw.get_websocket_url(request_mock) == 'wss://127.0.0.1:999/mopidy/ws'
|
||||||
|
|
||||||
|
def test_has_alarmclock(self):
|
||||||
|
assert not self.mmw.has_alarm_clock()
|
||||||
|
|
||||||
|
def test_is_musicbox(self):
|
||||||
|
assert not self.mmw.is_music_box()
|
||||||
15
tox.ini
15
tox.ini
@ -2,12 +2,18 @@
|
|||||||
envlist = py27, flake8, test, eslint, csslint, tidy
|
envlist = py27, flake8, test, eslint, csslint, tidy
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
|
sitepackages = true
|
||||||
|
whitelist_externals =
|
||||||
|
py.test
|
||||||
deps =
|
deps =
|
||||||
mock
|
mock
|
||||||
mopidy
|
mopidy
|
||||||
pytest
|
pytest
|
||||||
|
pytest-capturelog
|
||||||
pytest-cov
|
pytest-cov
|
||||||
pytest-xdist
|
pytest-xdist
|
||||||
|
responses
|
||||||
|
install_command = pip install --allow-unverified=mopidy --pre {opts} {packages}
|
||||||
commands =
|
commands =
|
||||||
py.test \
|
py.test \
|
||||||
--basetemp={envtmpdir} \
|
--basetemp={envtmpdir} \
|
||||||
@ -16,13 +22,17 @@ commands =
|
|||||||
{posargs:tests/}
|
{posargs:tests/}
|
||||||
|
|
||||||
[testenv:flake8]
|
[testenv:flake8]
|
||||||
|
sitepackages = false
|
||||||
deps =
|
deps =
|
||||||
flake8
|
flake8
|
||||||
flake8-import-order
|
flake8-import-order
|
||||||
|
pep8-naming
|
||||||
skip_install = true
|
skip_install = true
|
||||||
commands = flake8 {posargs:mopidy_musicbox_webclient tests}
|
commands = flake8 --show-source --statistics --max-line-length 120 {posargs:mopidy_musicbox_webclient tests}
|
||||||
|
|
||||||
[testenv:test]
|
[testenv:test]
|
||||||
|
envdir = py27
|
||||||
|
sitepackages = false
|
||||||
whitelist_externals =
|
whitelist_externals =
|
||||||
/bin/bash
|
/bin/bash
|
||||||
deps =
|
deps =
|
||||||
@ -33,6 +43,7 @@ commands =
|
|||||||
bash -c '. {toxworkdir}/node_env/bin/activate; npm install; npm test'
|
bash -c '. {toxworkdir}/node_env/bin/activate; npm install; npm test'
|
||||||
|
|
||||||
[testenv:eslint]
|
[testenv:eslint]
|
||||||
|
sitepackages = false
|
||||||
whitelist_externals =
|
whitelist_externals =
|
||||||
/bin/bash
|
/bin/bash
|
||||||
deps =
|
deps =
|
||||||
@ -43,6 +54,7 @@ commands =
|
|||||||
bash -c '. {toxworkdir}/node_env/bin/activate; npm install; npm run eslint'
|
bash -c '. {toxworkdir}/node_env/bin/activate; npm install; npm run eslint'
|
||||||
|
|
||||||
[testenv:csslint]
|
[testenv:csslint]
|
||||||
|
sitepackages = false
|
||||||
whitelist_externals =
|
whitelist_externals =
|
||||||
/bin/bash
|
/bin/bash
|
||||||
deps =
|
deps =
|
||||||
@ -53,6 +65,7 @@ commands =
|
|||||||
bash -c '. {toxworkdir}/node_env/bin/activate; npm install; npm run csslint'
|
bash -c '. {toxworkdir}/node_env/bin/activate; npm install; npm run csslint'
|
||||||
|
|
||||||
[testenv:tidy]
|
[testenv:tidy]
|
||||||
|
sitepackages = false
|
||||||
whitelist_externals =
|
whitelist_externals =
|
||||||
/bin/bash
|
/bin/bash
|
||||||
deps =
|
deps =
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user