diff -Nru python-django-debug-toolbar-1.8/debian/changelog python-django-debug-toolbar-1.9.1/debian/changelog --- python-django-debug-toolbar-1.8/debian/changelog 2017-11-29 08:03:20.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/debian/changelog 2017-12-25 15:33:53.000000000 +0000 @@ -1,8 +1,13 @@ -python-django-debug-toolbar (1:1.8-1ubuntu1) bionic; urgency=medium +python-django-debug-toolbar (1:1.9.1-1) unstable; urgency=medium - * Add missing test dep on python{,3}-django-jinja. + * New upstream release. + * Add missing autopkgtest dependency on python{3}-django-jinja. + Closes: #883056 Thanks to Steve Langasek. + * Invoke tests via pybuild. + * Bump Standards-Version to 4.1.2, no changes. + * Build depend on python{3}-html5lib. - -- Steve Langasek Wed, 29 Nov 2017 00:03:20 -0800 + -- Andrew Starr-Bochicchio Mon, 25 Dec 2017 10:33:53 -0500 python-django-debug-toolbar (1:1.8-1) unstable; urgency=medium diff -Nru python-django-debug-toolbar-1.8/debian/control python-django-debug-toolbar-1.9.1/debian/control --- python-django-debug-toolbar-1.8/debian/control 2017-11-29 08:03:18.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/debian/control 2017-12-25 15:30:59.000000000 +0000 @@ -1,8 +1,7 @@ Source: python-django-debug-toolbar Section: python Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Debian Python Modules Team +Maintainer: Debian Python Modules Team Uploaders: Andrew Starr-Bochicchio Build-Depends: debhelper (>= 9), dh-python, @@ -12,12 +11,14 @@ python3-django, python-django-jinja, python3-django-jinja, + python-html5lib, + python3-html5lib, python-setuptools, python3-setuptools, python-sphinx (>= 1.0.7+dfsg-1~), python-sqlparse (>= 0.2.0), python3-sqlparse -Standards-Version: 3.9.8 +Standards-Version: 4.1.2 X-Python-Version: >= 2.6 X-Python3-Version: >= 3.2 Homepage: https://github.com/django-debug-toolbar/django-debug-toolbar diff -Nru python-django-debug-toolbar-1.8/debian/rules python-django-debug-toolbar-1.9.1/debian/rules --- python-django-debug-toolbar-1.8/debian/rules 2015-11-01 21:41:58.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/debian/rules 2017-12-25 15:23:32.000000000 +0000 @@ -5,16 +5,15 @@ PYTHON_VERSIONS=${PYTHON2_VERSIONS} ${PYTHON3_VERSIONS} export PYBUILD_NAME=django-debug-toolbar -export PYBUILD_TEST_PYTEST=1 %: dh $@ --with python2,python3,sphinxdoc --buildsystem=pybuild ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) -test-python%: - PYTHONPATH=. DJANGO_SETTINGS_MODULE=tests.settings python$* /usr/bin/django-admin test tests - -override_dh_auto_test: $(foreach pyversion,${PYTHON_VERSIONS},$(pyversion:%=test-python%)) +override_dh_auto_test: + PYBUILD_SYSTEM=custom \ + PYBUILD_TEST_ARGS="PYTHONPATH=. DJANGO_SETTINGS_MODULE=tests.settings django-admin test tests" \ + dh_auto_test endif override_dh_auto_build: diff -Nru python-django-debug-toolbar-1.8/debian/tests/control python-django-debug-toolbar-1.9.1/debian/tests/control --- python-django-debug-toolbar-1.8/debian/tests/control 2017-11-29 08:03:20.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/debian/tests/control 2017-12-25 15:33:09.000000000 +0000 @@ -1,2 +1,2 @@ Tests: testsuite -Depends: @, python, python-django, python-django-jinja, python3-django-jinja, python-sqlparse +Depends: @, python, python-django, python-django-jinja, python3-django-jinja, python-sqlparse, python-html5lib, python3-html5lib diff -Nru python-django-debug-toolbar-1.8/debug_toolbar/panels/profiling.py python-django-debug-toolbar-1.9.1/debug_toolbar/panels/profiling.py --- python-django-debug-toolbar-1.8/debug_toolbar/panels/profiling.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/debug_toolbar/panels/profiling.py 2017-11-15 16:39:07.000000000 +0000 @@ -6,7 +6,7 @@ from pstats import Stats from django.utils import six -from django.utils.safestring import mark_safe +from django.utils.html import format_html from django.utils.translation import ugettext_lazy as _ from debug_toolbar import settings as dt_settings @@ -78,15 +78,15 @@ file_path, file_name = file_name.rsplit(os.sep, 1) - return mark_safe( + return format_html( '{0}/' '{1}' ' in {3}' - '({2})'.format( - file_path, - file_name, - line_num, - method)) + '({2})', + file_path, + file_name, + line_num, + method) def subfuncs(self): i = 0 @@ -167,12 +167,13 @@ self.stats = DjangoDebugToolbarStats(self.profiler) self.stats.calc_callees() - root = FunctionCall(self.stats, self.stats.get_root_func(), depth=0) - - func_list = [] - self.add_node(func_list, - root, - dt_settings.get_config()['PROFILER_MAX_DEPTH'], - root.stats[3] / 8) - - self.record_stats({'func_list': func_list}) + root_func = self.stats.get_root_func() + # Ensure root function exists before continuing with function call analysis + if root_func: + root = FunctionCall(self.stats, root_func, depth=0) + func_list = [] + self.add_node(func_list, + root, + dt_settings.get_config()['PROFILER_MAX_DEPTH'], + root.stats[3] / 8) + self.record_stats({'func_list': func_list}) diff -Nru python-django-debug-toolbar-1.8/debug_toolbar/panels/redirects.py python-django-debug-toolbar-1.9.1/debug_toolbar/panels/redirects.py --- python-django-debug-toolbar-1.8/debug_toolbar/panels/redirects.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/debug_toolbar/panels/redirects.py 2017-11-15 16:39:07.000000000 +0000 @@ -1,6 +1,6 @@ from __future__ import absolute_import, unicode_literals -from django.shortcuts import render_to_response +from django.template.response import SimpleTemplateResponse from django.utils.translation import ugettext_lazy as _ from debug_toolbar.panels import Panel @@ -22,6 +22,8 @@ status_line = '%s %s' % (response.status_code, response.reason_phrase) cookies = response.cookies context = {'redirect_to': redirect_to, 'status_line': status_line} - response = render_to_response('debug_toolbar/redirect.html', context) + # Using SimpleTemplateResponse avoids running global context processors. + response = SimpleTemplateResponse('debug_toolbar/redirect.html', context) response.cookies = cookies + response.render() return response diff -Nru python-django-debug-toolbar-1.8/debug_toolbar/panels/request.py python-django-debug-toolbar-1.9.1/debug_toolbar/panels/request.py --- python-django-debug-toolbar-1.8/debug_toolbar/panels/request.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/debug_toolbar/panels/request.py 2017-11-15 16:39:07.000000000 +0000 @@ -9,7 +9,7 @@ try: from django.urls import resolve -except: # Django < 1.10 pragma: no cover +except ImportError: # Django < 1.10 pragma: no cover from django.core.urlresolvers import resolve diff -Nru python-django-debug-toolbar-1.8/debug_toolbar/panels/sql/views.py python-django-debug-toolbar-1.9.1/debug_toolbar/panels/sql/views.py --- python-django-debug-toolbar-1.8/debug_toolbar/panels/sql/views.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/debug_toolbar/panels/sql/views.py 2017-11-15 16:39:07.000000000 +0000 @@ -1,7 +1,7 @@ from __future__ import absolute_import, unicode_literals from django.http import HttpResponseBadRequest -from django.shortcuts import render_to_response +from django.template.response import SimpleTemplateResponse from django.views.decorators.csrf import csrf_exempt from debug_toolbar.decorators import require_show_toolbar @@ -29,8 +29,8 @@ 'headers': headers, 'alias': form.cleaned_data['alias'], } - # Using render_to_response avoids running global context processors. - return render_to_response('debug_toolbar/panels/sql_select.html', context) + # Using SimpleTemplateResponse avoids running global context processors. + return SimpleTemplateResponse('debug_toolbar/panels/sql_select.html', context) return HttpResponseBadRequest('Form errors') @@ -66,8 +66,8 @@ 'headers': headers, 'alias': form.cleaned_data['alias'], } - # Using render_to_response avoids running global context processors. - return render_to_response('debug_toolbar/panels/sql_explain.html', context) + # Using SimpleTemplateResponse avoids running global context processors. + return SimpleTemplateResponse('debug_toolbar/panels/sql_explain.html', context) return HttpResponseBadRequest('Form errors') @@ -113,6 +113,6 @@ 'headers': headers, 'alias': form.cleaned_data['alias'], } - # Using render_to_response avoids running global context processors. - return render_to_response('debug_toolbar/panels/sql_profile.html', context) + # Using SimpleTemplateResponse avoids running global context processors. + return SimpleTemplateResponse('debug_toolbar/panels/sql_profile.html', context) return HttpResponseBadRequest('Form errors') diff -Nru python-django-debug-toolbar-1.8/debug_toolbar/panels/templates/panel.py python-django-debug-toolbar-1.9.1/debug_toolbar/panels/templates/panel.py --- python-django-debug-toolbar-1.8/debug_toolbar/panels/templates/panel.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/debug_toolbar/panels/templates/panel.py 2017-11-15 16:39:07.000000000 +0000 @@ -7,6 +7,7 @@ from django import http from django.conf.urls import url +from django.core import signing from django.db.models.query import QuerySet, RawQuerySet from django.template import RequestContext, Template from django.test.signals import template_rendered @@ -192,8 +193,10 @@ template = template_data.get('template', None) if hasattr(template, 'origin') and template.origin and template.origin.name: template.origin_name = template.origin.name + template.origin_hash = signing.dumps(template.origin.name) else: template.origin_name = _('No origin') + template.origin_hash = '' info['template'] = template # Clean up context for better readability if self.toolbar.config['SHOW_TEMPLATE_CONTEXT']: diff -Nru python-django-debug-toolbar-1.8/debug_toolbar/panels/templates/views.py python-django-debug-toolbar-1.9.1/debug_toolbar/panels/templates/views.py --- python-django-debug-toolbar-1.8/debug_toolbar/panels/templates/views.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/debug_toolbar/panels/templates/views.py 2017-11-15 16:39:07.000000000 +0000 @@ -1,9 +1,10 @@ from __future__ import absolute_import, unicode_literals +from django.core import signing from django.http import HttpResponseBadRequest -from django.shortcuts import render_to_response from django.template import TemplateDoesNotExist from django.template.engine import Engine +from django.template.response import SimpleTemplateResponse from django.utils.safestring import mark_safe from debug_toolbar.decorators import require_show_toolbar @@ -23,6 +24,10 @@ template_origin_name = request.GET.get('template_origin', None) if template_origin_name is None: return HttpResponseBadRequest('"template_origin" key is required') + try: + template_origin_name = signing.loads(template_origin_name) + except Exception: + return HttpResponseBadRequest('"template_origin" is invalid') template_name = request.GET.get('template', template_origin_name) final_loaders = [] @@ -66,8 +71,8 @@ except ImportError: pass - # Using render_to_response avoids running global context processors. - return render_to_response('debug_toolbar/panels/template_source.html', { + # Using SimpleTemplateResponse avoids running global context processors. + return SimpleTemplateResponse('debug_toolbar/panels/template_source.html', { 'source': source, 'template_name': template_name }) diff -Nru python-django-debug-toolbar-1.8/debug_toolbar/panels/versions.py python-django-debug-toolbar-1.9.1/debug_toolbar/panels/versions.py --- python-django-debug-toolbar-1.8/debug_toolbar/panels/versions.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/debug_toolbar/panels/versions.py 2017-11-15 16:39:07.000000000 +0000 @@ -41,18 +41,25 @@ yield app.__name__, name, version def get_app_version(self, app): + version = self.get_version_from_app(app) + if isinstance(version, (list, tuple)): + # We strip dots from the right because we do not want to show + # trailing dots if there are empty elements in the list/tuple + version = '.'.join(str(o) for o in version).rstrip('.') + return version + + def get_version_from_app(self, app): if hasattr(app, 'get_version'): get_version = app.get_version if callable(get_version): - version = get_version() + try: + return get_version() + except TypeError: + pass else: - version = get_version - elif hasattr(app, 'VERSION'): - version = app.VERSION - elif hasattr(app, '__version__'): - version = app.__version__ - else: - return - if isinstance(version, (list, tuple)): - version = '.'.join(str(o) for o in version) - return version + return get_version + if hasattr(app, 'VERSION'): + return app.VERSION + if hasattr(app, '__version__'): + return app.__version__ + return diff -Nru python-django-debug-toolbar-1.8/debug_toolbar/static/debug_toolbar/js/toolbar.js python-django-debug-toolbar-1.9.1/debug_toolbar/static/debug_toolbar/js/toolbar.js --- python-django-debug-toolbar-1.8/debug_toolbar/static/debug_toolbar/js/toolbar.js 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/debug_toolbar/static/debug_toolbar/js/toolbar.js 2017-11-15 16:39:07.000000000 +0000 @@ -19,16 +19,15 @@ } else { $('.djdt-panelContent').hide(); // Hide any that are already open var inner = current.find('.djDebugPanelContent .djdt-scroll'), - store_id = $('#djDebug').data('store-id'), - render_panel_url = $('#djDebug').data('render-panel-url'); - if (store_id !== '' && inner.children().length === 0) { + store_id = $('#djDebug').data('store-id'); + if (store_id && inner.children().length === 0) { var ajax_data = { data: { store_id: store_id, panel_id: this.className }, type: 'GET', - url: render_panel_url + url: $('#djDebug').data('render-panel-url') }; $.ajax(ajax_data).done(function(data){ inner.prev().remove(); // Remove AJAX loader diff -Nru python-django-debug-toolbar-1.8/debug_toolbar/templates/debug_toolbar/base.html python-django-debug-toolbar-1.9.1/debug_toolbar/templates/debug_toolbar/base.html --- python-django-debug-toolbar-1.8/debug_toolbar/templates/debug_toolbar/base.html 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/debug_toolbar/templates/debug_toolbar/base.html 2017-11-15 16:39:07.000000000 +0000 @@ -11,7 +11,10 @@ {% endif %}
    diff -Nru python-django-debug-toolbar-1.8/debug_toolbar/templates/debug_toolbar/panels/templates.html python-django-debug-toolbar-1.9.1/debug_toolbar/templates/debug_toolbar/panels/templates.html --- python-django-debug-toolbar-1.8/debug_toolbar/templates/debug_toolbar/panels/templates.html 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/debug_toolbar/templates/debug_toolbar/panels/templates.html 2017-11-15 16:39:07.000000000 +0000 @@ -14,7 +14,7 @@ {% if templates %}
    {% for template in templates %} -
    {{ template.template.name|addslashes }}
    +
    {{ template.template.name|addslashes }}
    {{ template.template.origin_name|addslashes }}
    {% if template.context %}
    diff -Nru python-django-debug-toolbar-1.8/docs/changes.rst python-django-debug-toolbar-1.9.1/docs/changes.rst --- python-django-debug-toolbar-1.8/docs/changes.rst 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/docs/changes.rst 2017-11-15 16:39:07.000000000 +0000 @@ -1,12 +1,39 @@ Change log ========== +UNRELEASED +---------- + +* Fix erroneous ``ContentNotRenderedError`` raised by the redirects panel. + +1.9 +--- + +This version is compatible with Django 2.0 and requires Django 1.8 or +later. + +Bugfixes +~~~~~~~~ + +* The profiling panel now escapes reported data resulting in valid HTML. +* Many minor cleanups and bugfixes. + 1.8 --- This version is compatible with Django 1.11 and requires Django 1.8 or later. +**Backwards incompatible changes** +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ``debug_toolbar.middleware.show_toolbar`` (the default value of setting + ``SHOW_TOOLBAR_CALLBACK``) no longer returns ``False`` for AJAX requests. + This is to allow reusing the ``SHOW_TOOLBAR_CALLBACK`` function to verify + access to panel views requested via AJAX. Projects defining a custom + ``SHOW_TOOLBAR_CALLBACK`` should remove checks for AJAX requests in order to + continue to allow access to these panels. + Features ~~~~~~~~ diff -Nru python-django-debug-toolbar-1.8/docs/configuration.rst python-django-debug-toolbar-1.9.1/docs/configuration.rst --- python-django-debug-toolbar-1.8/docs/configuration.rst 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/docs/configuration.rst 2017-11-15 16:39:07.000000000 +0000 @@ -112,10 +112,15 @@ Default: 'debug_toolbar.middleware.show_toolbar' This is the dotted path to a function used for determining whether the - toolbar should show or not. The default checks are that ``DEBUG`` must be - set to ``True``, the IP of the request must be in ``INTERNAL_IPS``, and the - request must not be an AJAX request. You can provide your own function - ``callback(request)`` which returns ``True`` or ``False``. + toolbar should show or not. The default checks are that ``DEBUG`` must be set + to ``True`` and the IP of the request must be in ``INTERNAL_IPS``. You can + provide your own function ``callback(request)`` which returns ``True`` or + ``False``. + + For versions < 1.8, the callback should also return ``False`` for AJAX + requests. Since version 1.8, AJAX requests are checked in the middleware, not + the callback. This allows reusing the callback to verify access to panel + views requested via AJAX. Panel options ~~~~~~~~~~~~~ diff -Nru python-django-debug-toolbar-1.8/docs/conf.py python-django-debug-toolbar-1.9.1/docs/conf.py --- python-django-debug-toolbar-1.8/docs/conf.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/docs/conf.py 2017-11-15 16:39:07.000000000 +0000 @@ -59,9 +59,9 @@ # built documents. # # The short X.Y version. -version = '1.8' +version = '1.9' # The full version, including alpha/beta/rc tags. -release = '1.8' +release = '1.9' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff -Nru python-django-debug-toolbar-1.8/Makefile python-django-debug-toolbar-1.9.1/Makefile --- python-django-debug-toolbar-1.8/Makefile 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/Makefile 2017-11-15 16:39:07.000000000 +0000 @@ -21,17 +21,17 @@ test: DJANGO_SETTINGS_MODULE=tests.settings \ - django-admin test tests + django-admin test $${TEST_ARGS:-tests} test_selenium: DJANGO_SELENIUM_TESTS=true DJANGO_SETTINGS_MODULE=tests.settings \ - django-admin test tests + django-admin test $${TEST_ARGS:-tests} coverage: python --version coverage erase DJANGO_SETTINGS_MODULE=tests.settings \ - coverage run `which django-admin` test -v2 tests + coverage run `which django-admin` test -v2 $${TEST_ARGS:-tests} coverage report coverage html diff -Nru python-django-debug-toolbar-1.8/README.rst python-django-debug-toolbar-1.9.1/README.rst --- python-django-debug-toolbar-1.8/README.rst 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/README.rst 2017-11-15 16:39:07.000000000 +0000 @@ -31,7 +31,7 @@ In addition to the built-in panels, a number of third-party panels are contributed by the community. -The current version of the Debug Toolbar is 1.8. It works on Django ≥ 1.8. +The current version of the Debug Toolbar is 1.9. It works on Django ≥ 1.8. Documentation, including installation and configuration instructions, is available at https://django-debug-toolbar.readthedocs.io/. diff -Nru python-django-debug-toolbar-1.8/requirements_dev.txt python-django-debug-toolbar-1.9.1/requirements_dev.txt --- python-django-debug-toolbar-1.8/requirements_dev.txt 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/requirements_dev.txt 2017-11-15 16:39:07.000000000 +0000 @@ -11,8 +11,9 @@ # Testing coverage -isort flake8 +html5lib +isort selenium tox diff -Nru python-django-debug-toolbar-1.8/setup.cfg python-django-debug-toolbar-1.9.1/setup.cfg --- python-django-debug-toolbar-1.8/setup.cfg 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/setup.cfg 2017-11-15 16:39:07.000000000 +0000 @@ -13,5 +13,8 @@ multi_line_output = 5 not_skip = __init__.py -[wheel] +[bdist_wheel] universal = 1 + +[metadata] +license-file = LICENSE diff -Nru python-django-debug-toolbar-1.8/setup.py python-django-debug-toolbar-1.9.1/setup.py --- python-django-debug-toolbar-1.8/setup.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/setup.py 2017-11-15 16:39:07.000000000 +0000 @@ -6,7 +6,7 @@ setup( name='django-debug-toolbar', - version='1.8', + version='1.9.1', description='A configurable set of panels that display various debug ' 'information about the current request/response.', long_description=open('README.rst', encoding='utf-8').read(), @@ -30,6 +30,7 @@ 'Framework :: Django :: 1.9', 'Framework :: Django :: 1.10', 'Framework :: Django :: 1.11', + 'Framework :: Django :: 2.0', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', diff -Nru python-django-debug-toolbar-1.8/tests/base.py python-django-debug-toolbar-1.9.1/tests/base.py --- python-django-debug-toolbar-1.8/tests/base.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/tests/base.py 2017-11-15 16:39:07.000000000 +0000 @@ -2,6 +2,7 @@ import threading +import html5lib from django.http import HttpResponse from django.test import RequestFactory, TestCase @@ -24,3 +25,16 @@ self.response = response self.toolbar = toolbar self.toolbar.stats = {} + + def assertValidHTML(self, content, msg=None): + parser = html5lib.HTMLParser() + parser.parseFragment(self.panel.content) + if parser.errors: + default_msg = ['Content is invalid HTML:'] + lines = content.split('\n') + for position, errorcode, datavars in parser.errors: + default_msg.append(' %s' % html5lib.constants.E[errorcode] % datavars) + default_msg.append(' %s' % lines[position[0] - 1]) + + msg = self._formatMessage(msg, '\n'.join(default_msg)) + raise self.failureException(msg) diff -Nru python-django-debug-toolbar-1.8/tests/panels/test_cache.py python-django-debug-toolbar-1.9.1/tests/panels/test_cache.py --- python-django-debug-toolbar-1.8/tests/panels/test_cache.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/tests/panels/test_cache.py 2017-11-15 16:39:07.000000000 +0000 @@ -47,3 +47,4 @@ self.panel.generate_stats(self.request, self.response) # ensure the panel renders correctly. self.assertIn('café', self.panel.content) + self.assertValidHTML(self.panel.content) diff -Nru python-django-debug-toolbar-1.8/tests/panels/test_logging.py python-django-debug-toolbar-1.9.1/tests/panels/test_logging.py --- python-django-debug-toolbar-1.8/tests/panels/test_logging.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/tests/panels/test_logging.py 2017-11-15 16:39:07.000000000 +0000 @@ -57,6 +57,7 @@ self.panel.generate_stats(self.request, self.response) # ensure the panel renders correctly. self.assertIn('café', self.panel.content) + self.assertValidHTML(self.panel.content) def test_failing_formatting(self): class BadClass(object): diff -Nru python-django-debug-toolbar-1.8/tests/panels/test_profiling.py python-django-debug-toolbar-1.9.1/tests/panels/test_profiling.py --- python-django-debug-toolbar-1.8/tests/panels/test_profiling.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/tests/panels/test_profiling.py 2017-11-15 16:39:07.000000000 +0000 @@ -1,12 +1,15 @@ from __future__ import absolute_import, unicode_literals +import unittest + from django.contrib.auth.models import User from django.db import IntegrityError, transaction from django.test import TestCase from django.test.utils import override_settings +from django.utils import six from ..base import BaseTestCase -from ..views import regular_view +from ..views import listcomp_view, regular_view @override_settings(DEBUG_TOOLBAR_PANELS=['debug_toolbar.panels.profiling.ProfilingPanel']) @@ -35,6 +38,32 @@ self.panel.generate_stats(self.request, self.response) # ensure the panel renders correctly. self.assertIn('regular_view', self.panel.content) + self.assertValidHTML(self.panel.content) + + @unittest.skipIf(six.PY2, 'list comprehension not listed on Python 2') + def test_listcomp_escaped(self): + self.panel.process_view(self.request, listcomp_view, (), {}) + self.panel.generate_stats(self.request, self.response) + self.assertNotIn('', self.panel.content) + self.assertIn('<listcomp>', self.panel.content) + + def test_generate_stats_no_profiler(self): + """ + Test generating stats with no profiler. + """ + self.assertIsNone(self.panel.generate_stats(self.request, self.response)) + + def test_generate_stats_no_root_func(self): + """ + Test generating stats using profiler without root function. + """ + self.panel.process_view(self.request, regular_view, ('profiling',), {}) + self.panel.process_response(self.request, self.response) + self.panel.profiler.clear() + self.panel.profiler.enable() + self.panel.profiler.disable() + self.panel.generate_stats(self.request, self.response) + self.assertNotIn('func_list', self.panel.get_stats()) @override_settings(DEBUG=True, diff -Nru python-django-debug-toolbar-1.8/tests/panels/test_redirects.py python-django-debug-toolbar-1.9.1/tests/panels/test_redirects.py --- python-django-debug-toolbar-1.8/tests/panels/test_redirects.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/tests/panels/test_redirects.py 2017-11-15 16:39:07.000000000 +0000 @@ -4,12 +4,10 @@ from django.conf import settings from django.http import HttpResponse -from django.test.utils import override_settings from ..base import BaseTestCase -@override_settings(DEBUG_TOOLBAR_CONFIG={'INTERCEPT_REDIRECTS': True}) class RedirectsPanelTestCase(BaseTestCase): def setUp(self): diff -Nru python-django-debug-toolbar-1.8/tests/panels/test_request.py python-django-debug-toolbar-1.9.1/tests/panels/test_request.py --- python-django-debug-toolbar-1.8/tests/panels/test_request.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/tests/panels/test_request.py 2017-11-15 16:39:07.000000000 +0000 @@ -46,3 +46,4 @@ self.panel.generate_stats(self.request, self.response) # ensure the panel renders correctly. self.assertIn('nôt åscíì', self.panel.content) + self.assertValidHTML(self.panel.content) diff -Nru python-django-debug-toolbar-1.8/tests/panels/test_sql.py python-django-debug-toolbar-1.9.1/tests/panels/test_sql.py --- python-django-debug-toolbar-1.8/tests/panels/test_sql.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/tests/panels/test_sql.py 2017-11-15 16:39:07.000000000 +0000 @@ -81,6 +81,7 @@ self.panel.generate_stats(self.request, self.response) # ensure the panel renders correctly. self.assertIn('café', self.panel.content) + self.assertValidHTML(self.panel.content) @unittest.skipUnless(connection.vendor == 'postgresql', 'Test valid only on PostgreSQL') diff -Nru python-django-debug-toolbar-1.8/tests/panels/test_staticfiles.py python-django-debug-toolbar-1.9.1/tests/panels/test_staticfiles.py --- python-django-debug-toolbar-1.8/tests/panels/test_staticfiles.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/tests/panels/test_staticfiles.py 2017-11-15 16:39:07.000000000 +0000 @@ -42,3 +42,4 @@ # ensure the panel renders correctly. self.assertIn('django.contrib.staticfiles.finders.' 'AppDirectoriesFinder', self.panel.content) + self.assertValidHTML(self.panel.content) diff -Nru python-django-debug-toolbar-1.8/tests/panels/test_template.py python-django-debug-toolbar-1.9.1/tests/panels/test_template.py --- python-django-debug-toolbar-1.8/tests/panels/test_template.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/tests/panels/test_template.py 2017-11-15 16:39:07.000000000 +0000 @@ -64,6 +64,7 @@ self.panel.generate_stats(self.request, self.response) # ensure the panel renders correctly. self.assertIn('nôt åscíì', self.panel.content) + self.assertValidHTML(self.panel.content) def test_custom_context_processor(self): self.panel.process_request(self.request) diff -Nru python-django-debug-toolbar-1.8/tests/panels/test_versions.py python-django-debug-toolbar-1.9.1/tests/panels/test_versions.py --- python-django-debug-toolbar-1.8/tests/panels/test_versions.py 1970-01-01 00:00:00.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/tests/panels/test_versions.py 2017-11-15 16:39:07.000000000 +0000 @@ -0,0 +1,52 @@ +# coding: utf-8 + +from __future__ import absolute_import, unicode_literals + +from collections import namedtuple + +from ..base import BaseTestCase + +version_info_t = namedtuple('version_info_t', ( + 'major', 'minor', 'micro', 'releaselevel', 'serial', +)) + + +class VersionsPanelTestCase(BaseTestCase): + + def setUp(self): + super(VersionsPanelTestCase, self).setUp() + self.panel = self.toolbar.get_panel_by_id('VersionsPanel') + + def test_app_version_from_get_version_fn(self): + + class FakeApp: + def get_version(self): + return version_info_t(1, 2, 3, '', '') + + self.assertEqual(self.panel.get_app_version(FakeApp()), '1.2.3') + + def test_incompatible_app_version_fn(self): + + class FakeApp: + + def get_version(self, some_other_arg): + # This should be ignored by the get_version_from_app + return version_info_t(0, 0, 0, '', '') + + VERSION = version_info_t(1, 2, 3, '', '') + + self.assertEqual(self.panel.get_app_version(FakeApp()), '1.2.3') + + def test_app_version_from_VERSION(self): + + class FakeApp: + VERSION = version_info_t(1, 2, 3, '', '') + + self.assertEqual(self.panel.get_app_version(FakeApp()), '1.2.3') + + def test_app_version_from_underscore_version(self): + + class FakeApp: + __version__ = version_info_t(1, 2, 3, '', '') + + self.assertEqual(self.panel.get_app_version(FakeApp()), '1.2.3') diff -Nru python-django-debug-toolbar-1.8/tests/settings.py python-django-debug-toolbar-1.9.1/tests/settings.py --- python-django-debug-toolbar-1.8/tests/settings.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/tests/settings.py 2017-11-15 16:39:07.000000000 +0000 @@ -30,7 +30,7 @@ MEDIA_URL = '/media/' # Avoids https://code.djangoproject.com/ticket/21451 -MIDDLEWARE_CLASSES = [ +MIDDLEWARE = [ 'debug_toolbar.middleware.DebugToolbarMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', @@ -40,6 +40,8 @@ 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] +# Django < 1.10 +MIDDLEWARE_CLASSES = MIDDLEWARE ROOT_URLCONF = 'tests.urls' diff -Nru python-django-debug-toolbar-1.8/tests/test_integration.py python-django-debug-toolbar-1.9.1/tests/test_integration.py --- python-django-debug-toolbar-1.8/tests/test_integration.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/tests/test_integration.py 2017-11-15 16:39:07.000000000 +0000 @@ -8,6 +8,7 @@ import django from django.contrib.staticfiles.testing import StaticLiveServerTestCase +from django.core import signing from django.core.checks import Error, run_checks from django.template.loader import get_template from django.test import RequestFactory, TestCase @@ -143,7 +144,7 @@ url = '/__debug__/template_source/' data = { 'template': template.template.name, - 'template_origin': template.template.origin.name + 'template_origin': signing.dumps(template.template.origin.name) } response = self.client.get(url, data) @@ -219,6 +220,24 @@ response = self.client.post(url, data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(response.status_code, 404) + @override_settings(DEBUG_TOOLBAR_CONFIG={'RENDER_PANELS': True}) + def test_data_store_id_not_rendered_when_none(self): + url = '/regular/basic/' + response = self.client.get(url) + self.assertIn(b'id="djDebug"', response.content) + self.assertNotIn(b'data-store-id', response.content) + + def test_view_returns_template_response(self): + response = self.client.get('/template_response/basic/') + self.assertEqual(response.status_code, 200) + + @override_settings(DEBUG_TOOLBAR_CONFIG={'DISABLE_PANELS': set()}) + def test_incercept_redirects(self): + response = self.client.get('/redirect/') + self.assertEqual(response.status_code, 200) + # Link to LOCATION header. + self.assertIn(b'href="/regular/redirect/"', response.content) + @unittest.skipIf(webdriver is None, "selenium isn't installed") @unittest.skipUnless('DJANGO_SELENIUM_TESTS' in os.environ, "selenium tests not requested") @@ -368,7 +387,7 @@ def test_middleware_factory_functions_supported(self): messages = run_checks() - if django.VERSION[:2] < (1, 10): + if django.VERSION[:2] < (1, 10) or django.VERSION[:2] >= (2, 0): self.assertEqual(messages, []) else: self.assertEqual(messages[0].id, '1_10.W001') diff -Nru python-django-debug-toolbar-1.8/tests/urls.py python-django-debug-toolbar-1.9.1/tests/urls.py --- python-django-debug-toolbar-1.8/tests/urls.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/tests/urls.py 2017-11-15 16:39:07.000000000 +0000 @@ -14,10 +14,12 @@ url(r'^resolving2/(?P.+)/(?P.+)/$', views.resolving_view), url(r'^resolving3/(.+)/$', views.resolving_view, {'arg2': 'default'}), url(r'^regular/(?P.*)/$', views.regular_view), + url(r'^template_response/(?P<title>.*)/$', views.template_response_view), url(r'^regular_jinja/(?P<title>.*)/$', views.regular_jinjia_view), url(r'^non_ascii_request/$', views.regular_view, {'title': NonAsciiRepr()}), url(r'^new_user/$', views.new_user), url(r'^execute_sql/$', views.execute_sql), url(r'^cached_view/$', views.cached_view), + url(r'^redirect/$', views.redirect_view), url(r'^__debug__/', include(debug_toolbar.urls)), ] diff -Nru python-django-debug-toolbar-1.8/tests/views.py python-django-debug-toolbar-1.9.1/tests/views.py --- python-django-debug-toolbar-1.8/tests/views.py 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/tests/views.py 2017-11-15 16:39:07.000000000 +0000 @@ -3,8 +3,9 @@ from __future__ import absolute_import, unicode_literals from django.contrib.auth.models import User -from django.http import HttpResponse +from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render +from django.template.response import TemplateResponse from django.views.decorators.cache import cache_page @@ -17,6 +18,10 @@ return render(request, 'basic.html', {'title': title}) +def template_response_view(request, title): + return TemplateResponse(request, 'basic.html', {'title': title}) + + def new_user(request, username='joe'): User.objects.create_user(username=username) return render(request, 'basic.html', {'title': 'new user'}) @@ -34,3 +39,12 @@ def regular_jinjia_view(request, title): return render(request, 'jinja2/basic.jinja', {'title': title}) + + +def listcomp_view(request): + lst = [i for i in range(50000) if i % 2 == 0] + return render(request, 'basic.html', {'title': 'List comprehension', 'lst': lst}) + + +def redirect_view(request): + return HttpResponseRedirect('/regular/redirect/') diff -Nru python-django-debug-toolbar-1.8/tox.ini python-django-debug-toolbar-1.9.1/tox.ini --- python-django-debug-toolbar-1.8/tox.ini 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/tox.ini 2017-11-15 16:39:07.000000000 +0000 @@ -3,48 +3,41 @@ py{27,33,34}-dj18, py{27,34,35}-dj{19,110,111}, py36-dj111 + py{35,36}-dj20 flake8, isort, readme [testenv] -basepython = - py27: python2.7 - py33: python3.3 - py34: python3.4 - py35: python3.5 - py36: python3.6 deps = dj18: Django>=1.8,<1.9 dj19: Django>=1.9,<1.10 dj110: Django>=1.10,<1.11 dj111: Django>=1.11,<2.0 + dj20: Django==2.0b1 coverage + django_jinja + html5lib selenium<4.0 sqlparse - django_jinja setenv = PYTHONPATH = {toxinidir} whitelist_externals = make pip_pre = True usedevelop = true -commands = make coverage +commands = make coverage TEST_ARGS='{posargs:tests}' [testenv:flake8] -basepython = python2.7 commands = make flake8 deps = flake8 [testenv:isort] -basepython = python2.7 commands = make isort_check_only deps = isort [testenv:jshint] -basepython = python2.7 commands = make jshint [testenv:readme] -basepython = python2.7 commands = python setup.py check -r -s deps = readme_renderer diff -Nru python-django-debug-toolbar-1.8/.travis.yml python-django-debug-toolbar-1.9.1/.travis.yml --- python-django-debug-toolbar-1.8/.travis.yml 2017-05-05 07:19:24.000000000 +0000 +++ python-django-debug-toolbar-1.9.1/.travis.yml 2017-11-15 16:39:07.000000000 +0000 @@ -27,14 +27,15 @@ env: TOXENV=py34-dj111 - python: 3.5 env: TOXENV=py35-dj111 + - python: 3.5 + env: TOXENV=py35-dj20 - python: 3.6 env: TOXENV=py36-dj111 - - python: 2.7 - env: TOXENV=flake8 - - python: 2.7 - env: TOXENV=isort - - python: 2.7 - env: TOXENV=readme + - python: 3.6 + env: TOXENV=py36-dj20 + - env: TOXENV=flake8 + - env: TOXENV=isort + - env: TOXENV=readme install: - pip install tox codecov script: