Drop Python 3.2 support

Refactor Travis CI configuration

Add flake8 checks, address all complaints
This commit is contained in:
Peter Bittner 2017-10-15 19:46:44 +02:00
parent bec45403ee
commit c7b14bdf5c
42 changed files with 393 additions and 336 deletions

View file

@ -1,23 +1,27 @@
language: python
python: "3.5"
python:
- 2.7
- 3.3
- 3.4
- 3.5
# - 3.6
env:
- DJANGO=1.7
- DJANGO=1.8
- DJANGO=1.9
# - DJANGO=1.10
# - DJANGO=1.11
matrix:
exclude:
- python: 3.5
env: DJANGO=1.7
- python: 3.3
env: DJANGO=1.9
include:
- python: 2.7
env: TOXENV=flake8
install:
# continue to support Python 3.2 (see issue #84)
- pip install "virtualenv<14.0.0"
- pip install coveralls tox
- pip install tox-travis
script:
- tox
env:
# NOTE: To generate (update) the env list run
# $ tox -l | sort | xargs -I ITEM echo " - TOXENV="ITEM
- TOXENV=py27-django17
- TOXENV=py27-django18
- TOXENV=py27-django19
- TOXENV=py32-django17
- TOXENV=py32-django18
- TOXENV=py33-django17
- TOXENV=py33-django18
- TOXENV=py34-django17
- TOXENV=py34-django18
- TOXENV=py34-django19
- TOXENV=py35-django18
- TOXENV=py35-django19

View file

@ -1,7 +1,7 @@
django-analytical |latest-version|
==================================
|travis-ci| |coveralls| |health| |python-support| |downloads| |license| |gitter|
|travis-ci| |coveralls| |health| |python-support| |license| |gitter|
The django-analytical application integrates analytics services into a
Django_ project.
@ -26,7 +26,7 @@ an asynchronous version of the Javascript code if possible.
.. |latest-version| image:: https://img.shields.io/pypi/v/django-analytical.svg
:alt: Latest version on PyPI
:target: https://pypi.python.org/pypi/django-analytical
.. |travis-ci| image:: https://travis-ci.org/jcassee/django-analytical.svg
.. |travis-ci| image:: https://img.shields.io/travis/jcassee/django-analytical/master.svg
:alt: Build status
:target: https://travis-ci.org/jcassee/django-analytical
.. |coveralls| image:: https://coveralls.io/repos/jcassee/django-analytical/badge.svg
@ -38,9 +38,6 @@ an asynchronous version of the Javascript code if possible.
.. |python-support| image:: https://img.shields.io/pypi/pyversions/django-analytical.svg
:target: https://pypi.python.org/pypi/django-analytical
:alt: Python versions
.. |downloads| image:: https://img.shields.io/pypi/dm/django-analytical.svg
:alt: Monthly downloads from PyPI
:target: https://pypi.python.org/pypi/django-analytical
.. |license| image:: https://img.shields.io/pypi/l/django-analytical.svg
:alt: Software license
:target: https://github.com/jcassee/django-analytical/blob/master/LICENSE.txt

View file

@ -35,7 +35,7 @@ SETUP_CODE = """
loadChartbeat : function() { oldonload(); loadChartbeat(); };
})();
</script>
"""
""" # noqa
DOMAIN_CONTEXT_KEY = 'chartbeat_domain'
@ -80,7 +80,7 @@ def chartbeat_bottom(parser, token):
class ChartbeatBottomNode(Node):
def __init__(self):
self.user_id = get_required_setting('CHARTBEAT_USER_ID', USER_ID_RE,
"must be (a string containing) a number")
"must be (a string containing) a number")
def render(self, context):
config = {'uid': self.user_id}

View file

@ -29,8 +29,7 @@ TRACKING_CODE = """
})();
</script>
<noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/%(site_id)sns.gif" /></p></noscript>
"""
""" # noqa
register = Library()
@ -52,8 +51,9 @@ def clicky(parser, token):
class ClickyNode(Node):
def __init__(self):
self.site_id = get_required_setting('CLICKY_SITE_ID', SITE_ID_RE,
"must be a (string containing) a number")
self.site_id = get_required_setting(
'CLICKY_SITE_ID', SITE_ID_RE,
"must be a (string containing) a number")
def render(self, context):
custom = {}
@ -66,8 +66,10 @@ class ClickyNode(Node):
if identity is not None:
custom.setdefault('session', {})['username'] = identity
html = TRACKING_CODE % {'site_id': self.site_id,
'custom': json.dumps(custom, sort_keys=True)}
html = TRACKING_CODE % {
'site_id': self.site_id,
'custom': json.dumps(custom, sort_keys=True),
}
if is_internal_ip(context, 'CLICKY'):
html = disable_html(html, 'Clicky')
return html

View file

@ -91,10 +91,12 @@ class GoogleAnalyticsNode(Node):
source = DISPLAY_ADVERTISING_SOURCE
else:
source = DEFAULT_SOURCE
html = SETUP_CODE % {'property_id': self.property_id,
'commands': " ".join(commands),
'source_scheme': source[0],
'source_url': source[1]}
html = SETUP_CODE % {
'property_id': self.property_id,
'commands': " ".join(commands),
'source_scheme': source[0],
'source_url': source[1],
}
if is_internal_ip(context, 'GOOGLE_ANALYTICS'):
html = disable_html(html, 'Google Analytics')
return html
@ -109,8 +111,7 @@ class GoogleAnalyticsNode(Node):
domain = get_domain(context, 'google_analytics')
if domain is None:
raise AnalyticalException(
"tracking multiple domains with Google Analytics"
" requires a domain name")
"tracking multiple domains with Google Analytics requires a domain name")
commands.append(DOMAIN_CODE % domain)
commands.append(NO_ALLOW_HASH_CODE)
if tracking_type == TRACK_MULTIPLE_DOMAINS:
@ -157,7 +158,8 @@ class GoogleAnalyticsNode(Node):
if siteSpeedSampleRate is not False:
value = decimal.Decimal(siteSpeedSampleRate)
if not 0 <= value <= 100:
raise AnalyticalException("'GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE' must be >= 0 and <= 100")
raise AnalyticalException(
"'GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE' must be >= 0 and <= 100")
commands.append(SITE_SPEED_SAMPLE_RATE_CODE % value.quantize(TWOPLACES))
sessionCookieTimeout = getattr(settings, 'GOOGLE_ANALYTICS_SESSION_COOKIE_TIMEOUT', False)

View file

@ -26,7 +26,7 @@ TRACKING_CODE = """
w.addEventListener?w.addEventListener("load",gs,false):w.attachEvent("onload",gs);
})(window);
</script>
"""
""" # noqa
TOKEN_CODE = 'GoSquared.acct = "%s";'
IDENTIFY_CODE = 'GoSquared.UserName = "%s";'

View file

@ -23,7 +23,7 @@ TRACKING_CODE = """
})(document,"script","hs-analytics",300000);
</script>
<!-- End of Async HubSpot Analytics Code -->
"""
""" # noqa
register = Library()
@ -44,8 +44,8 @@ def hubspot(parser, token):
class HubSpotNode(Node):
def __init__(self):
self.portal_id = get_required_setting('HUBSPOT_PORTAL_ID',
PORTAL_ID_RE, "must be a (string containing a) number")
self.portal_id = get_required_setting('HUBSPOT_PORTAL_ID', PORTAL_ID_RE,
"must be a (string containing a) number")
def render(self, context):
html = TRACKING_CODE % {'portal_id': self.portal_id}

View file

@ -18,7 +18,7 @@ TRACKING_CODE = """
window.intercomSettings = %(settings_json)s;
</script>
<script>(function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',intercomSettings);}else{var d=document;var i=function(){i.c(arguments)};i.q=[];i.c=function(args){i.q.push(args)};w.Intercom=i;function l(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://static.intercomcdn.com/intercom.v1.js';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);}if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})()</script>
"""
""" # noqa
register = Library()

View file

@ -16,7 +16,7 @@ SITE_CODE_RE = re.compile(r'^[\w]+$')
SETUP_CODE = """
<script type="text/javascript">var _kiq = _kiq || []; %(commands)s</script>
<script type="text/javascript" src="//s3.amazonaws.com/ki.js/%(account_number)s/%(site_code)s.js" async="true"></script>
"""
""" # noqa
IDENTIFY_CODE = "_kiq.push(['identify', '%s']);"
SHOW_SURVEY_CODE = "_kiq.push(['showSurvey', %s]);"
SHOW_SURVEY_CONTEXT_KEY = 'kiss_insights_show_survey'
@ -44,10 +44,11 @@ def kiss_insights(parser, token):
class KissInsightsNode(Node):
def __init__(self):
self.account_number = get_required_setting(
'KISS_INSIGHTS_ACCOUNT_NUMBER', ACCOUNT_NUMBER_RE,
"must be (a string containing) a number")
self.site_code = get_required_setting('KISS_INSIGHTS_SITE_CODE',
SITE_CODE_RE, "must be a string containing three characters")
'KISS_INSIGHTS_ACCOUNT_NUMBER', ACCOUNT_NUMBER_RE,
"must be (a string containing) a number")
self.site_code = get_required_setting(
'KISS_INSIGHTS_SITE_CODE', SITE_CODE_RE,
"must be a string containing three characters")
def render(self, context):
commands = []
@ -55,12 +56,14 @@ class KissInsightsNode(Node):
if identity is not None:
commands.append(IDENTIFY_CODE % identity)
try:
commands.append(SHOW_SURVEY_CODE
% context[SHOW_SURVEY_CONTEXT_KEY])
commands.append(SHOW_SURVEY_CODE % context[SHOW_SURVEY_CONTEXT_KEY])
except KeyError:
pass
html = SETUP_CODE % {'account_number': self.account_number,
'site_code': self.site_code, 'commands': " ".join(commands)}
html = SETUP_CODE % {
'account_number': self.account_number,
'site_code': self.site_code,
'commands': " ".join(commands),
}
return html

View file

@ -61,9 +61,9 @@ def kiss_metrics(parser, token):
class KissMetricsNode(Node):
def __init__(self):
self.api_key = get_required_setting('KISS_METRICS_API_KEY',
API_KEY_RE,
"must be a string containing a 40-digit hexadecimal number")
self.api_key = get_required_setting(
'KISS_METRICS_API_KEY', API_KEY_RE,
"must be a string containing a 40-digit hexadecimal number")
def render(self, context):
commands = []
@ -78,18 +78,23 @@ class KissMetricsNode(Node):
pass
try:
name, properties = context[EVENT_CONTEXT_KEY]
commands.append(EVENT_CODE % {'name': name,
'properties': json.dumps(properties, sort_keys=True)})
commands.append(EVENT_CODE % {
'name': name,
'properties': json.dumps(properties, sort_keys=True),
})
except KeyError:
pass
try:
properties = context[PROPERTY_CONTEXT_KEY]
commands.append(PROPERTY_CODE % {
'properties': json.dumps(properties, sort_keys=True)})
'properties': json.dumps(properties, sort_keys=True),
})
except KeyError:
pass
html = TRACKING_CODE % {'api_key': self.api_key,
'commands': " ".join(commands)}
html = TRACKING_CODE % {
'api_key': self.api_key,
'commands': " ".join(commands),
}
if is_internal_ip(context, 'KISS_METRICS'):
html = disable_html(html, 'KISSmetrics')
return html

View file

@ -22,7 +22,7 @@ e,d])};b.__SV=1.2}})(document,window.mixpanel||[]);
mixpanel.init('%(token)s');
%(commands)s
</script>
"""
""" # noqa
IDENTIFY_CODE = "mixpanel.identify('%s');"
IDENTIFY_PROPERTIES = "mixpanel.people.set(%s);"
EVENT_CODE = "mixpanel.track('%(name)s', %(properties)s);"
@ -62,12 +62,16 @@ class MixpanelNode(Node):
commands.append(IDENTIFY_CODE % identity)
try:
name, properties = context[EVENT_CONTEXT_KEY]
commands.append(EVENT_CODE % {'name': name,
'properties': json.dumps(properties, sort_keys=True)})
commands.append(EVENT_CODE % {
'name': name,
'properties': json.dumps(properties, sort_keys=True),
})
except KeyError:
pass
html = TRACKING_CODE % {'token': self._token,
'commands': " ".join(commands)}
html = TRACKING_CODE % {
'token': self._token,
'commands': " ".join(commands),
}
if is_internal_ip(context, 'MIXPANEL'):
html = disable_html(html, 'Mixpanel')
return mark_safe(html)

View file

@ -18,7 +18,7 @@ SETUP_CODE = """
/*{literal}<![CDATA[*/ window.olark||(function(k){var g=window,j=document,a=g.location.protocol=="https:"?"https:":"http:",i=k.name,b="load",h="addEventListener";(function(){g[i]=function(){(c.s=c.s||[]).push(arguments)};var c=g[i]._={},f=k.methods.length;while(f--){(function(l){g[i][l]=function(){g[i]("call",l,arguments)}})(k.methods[f])}c.l=k.loader;c.i=arguments.callee;c.p={0:+new Date};c.P=function(l){c.p[l]=new Date-c.p[0]};function e(){c.P(b);g[i](b)}g[h]?g[h](b,e,false):g.attachEvent("on"+b,e);c.P(1);var d=j.createElement("script"),m=document.getElementsByTagName("script")[0];d.type="text/javascript";d.async=true;d.src=a+"//"+c.l;m.parentNode.insertBefore(d,m);c.P(2)})()})({loader:(function(a){return "static.olark.com/jsclient/loader1.js?ts="+(a?a[1]:(+new Date))})(document.cookie.match(/olarkld=([0-9]+)/)),name:"olark",methods:["configure","extend","declare","identify"]}); olark.identify('%(site_id)s');/*]]>{/literal}*/
%(extra_code)s
</script>
"""
""" # noqa
NICKNAME_CODE = "olark('api.chat.updateVisitorNickname', {snippet: '%s'});"
NICKNAME_CONTEXT_KEY = 'olark_nickname'
FULLNAME_CODE = "olark('api.visitor.updateFullName', {{fullName: '{0}'}});"
@ -28,14 +28,16 @@ EMAIL_CONTEXT_KEY = 'olark_email'
STATUS_CODE = "olark('api.chat.updateVisitorStatus', {snippet: %s});"
STATUS_CONTEXT_KEY = 'olark_status'
MESSAGE_CODE = "olark.configure('locale.%(key)s', \"%(msg)s\");"
MESSAGE_KEYS = set(["welcome_title", "chatting_title", "unavailable_title",
"busy_title", "away_message", "loading_title", "welcome_message",
"busy_message", "chat_input_text", "name_input_text",
"email_input_text", "offline_note_message", "send_button_text",
"offline_note_thankyou_text", "offline_note_error_text",
"offline_note_sending_text", "operator_is_typing_text",
"operator_has_stopped_typing_text", "introduction_error_text",
"introduction_messages", "introduction_submit_button_text"])
MESSAGE_KEYS = {
"welcome_title", "chatting_title", "unavailable_title",
"busy_title", "away_message", "loading_title", "welcome_message",
"busy_message", "chat_input_text", "name_input_text",
"email_input_text", "offline_note_message", "send_button_text",
"offline_note_thankyou_text", "offline_note_error_text",
"offline_note_sending_text", "operator_is_typing_text",
"operator_has_stopped_typing_text", "introduction_error_text",
"introduction_messages", "introduction_submit_button_text",
}
register = Library()
@ -56,8 +58,9 @@ def olark(parser, token):
class OlarkNode(Node):
def __init__(self):
self.site_id = get_required_setting('OLARK_SITE_ID', SITE_ID_RE,
"must be a string looking like 'XXXX-XXX-XX-XXXX'")
self.site_id = get_required_setting(
'OLARK_SITE_ID', SITE_ID_RE,
"must be a string looking like 'XXXX-XXX-XX-XXXX'")
def render(self, context):
extra_code = []
@ -76,13 +79,15 @@ class OlarkNode(Node):
except KeyError:
pass
try:
extra_code.append(STATUS_CODE %
json.dumps(context[STATUS_CONTEXT_KEY], sort_keys=True))
extra_code.append(STATUS_CODE % json.dumps(context[STATUS_CONTEXT_KEY],
sort_keys=True))
except KeyError:
pass
extra_code.extend(self._get_configuration(context))
html = SETUP_CODE % {'site_id': self.site_id,
'extra_code': " ".join(extra_code)}
html = SETUP_CODE % {
'site_id': self.site_id,
'extra_code': " ".join(extra_code),
}
return html
def _get_nickname(self, user):

View file

@ -16,7 +16,7 @@ from analytical.utils import is_internal_ip, disable_html, get_identity, \
API_KEY_RE = re.compile(r'^\w+$')
SETUP_CODE = """
<script src="//d1nu2rn22elx8m.cloudfront.net/performable/pax/%(api_key)s.js" type="text/javascript"></script>
"""
""" # noqa
IDENTIFY_CODE = """
<script type="text/javascript">
var _paq = _paq || [];
@ -32,7 +32,7 @@ EMBED_CODE = """
$f.write();
})()
</script>
"""
""" # noqa
register = Library()
@ -54,8 +54,9 @@ def performable(parser, token):
class PerformableNode(Node):
def __init__(self):
self.api_key = get_required_setting('PERFORMABLE_API_KEY', API_KEY_RE,
"must be a string looking like 'XXXXX'")
self.api_key = get_required_setting(
'PERFORMABLE_API_KEY', API_KEY_RE,
"must be a string looking like 'XXXXX'")
def render(self, context):
html = SETUP_CODE % {'api_key': self.api_key}
@ -72,7 +73,10 @@ def performable_embed(hostname, page_id):
"""
Include a Performable landing page.
"""
return mark_safe(EMBED_CODE % {'hostname': hostname, 'page_id': page_id})
return mark_safe(EMBED_CODE % {
'hostname': hostname,
'page_id': page_id,
})
def contribute_to_analytical(add_node):

View file

@ -4,10 +4,8 @@ Rating@Mail.ru template tags and filters.
from __future__ import absolute_import
import json
import re
from django.conf import settings
from django.template import Library, Node, TemplateSyntaxError
from analytical.utils import is_internal_ip, disable_html, \
@ -30,7 +28,7 @@ COUNTER_CODE = """
<noscript><div style="position:absolute;left:-10000px;">
<img src="//top-fwz1.mail.ru/counter?id=%(counter_id)s;js=na" style="border:0;" height="1" width="1" alt="Rating@Mail.ru" />
</div></noscript>
"""
""" # noqa
register = Library()
@ -54,8 +52,8 @@ def rating_mailru(parser, token):
class RatingMailruNode(Node):
def __init__(self):
self.counter_id = get_required_setting(
'RATING_MAILRU_COUNTER_ID', COUNTER_ID_RE,
"must be (a string containing) a number'")
'RATING_MAILRU_COUNTER_ID', COUNTER_ID_RE,
"must be (a string containing) a number'")
def render(self, context):
html = COUNTER_CODE % {

View file

@ -12,7 +12,6 @@ from django.utils import translation
from analytical.utils import get_identity, get_required_setting
BUTTON_LOCATION_LEFT = 0
BUTTON_LOCATION_RIGHT = 1
BUTTON_LOCATION_TOP = 2
@ -33,7 +32,7 @@ SETUP_CODE = """
document.write(unescape("%%3Cscript src='" + ((document.location.protocol=="https:")?"https://snapabug.appspot.com":"http://www.snapengage.com") + "/snapabug.js' type='text/javascript'%%3E%%3C/script%%3E"));</script><script type="text/javascript">
%(settings_code)s
</script>
"""
""" # noqa
DOMAIN_CODE = 'SnapABug.setDomain("%s");'
SECURE_CONNECTION_CODE = 'SnapABug.setSecureConnexion();'
INIT_CODE = 'SnapABug.init("%s");'
@ -69,21 +68,22 @@ def snapengage(parser, token):
class SnapEngageNode(Node):
def __init__(self):
self.widget_id = get_required_setting('SNAPENGAGE_WIDGET_ID',
WIDGET_ID_RE, "must be a string looking like this: "
"'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'")
self.widget_id = get_required_setting(
'SNAPENGAGE_WIDGET_ID', WIDGET_ID_RE,
"must be a string looking like this: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'")
def render(self, context):
settings_code = []
domain = self._get_setting(context, 'snapengage_domain',
'SNAPENGAGE_DOMAIN')
'SNAPENGAGE_DOMAIN')
if domain is not None:
settings_code.append(DOMAIN_CODE % domain)
secure_connection = self._get_setting(context,
'snapengage_secure_connection', 'SNAPENGAGE_SECURE_CONNECTION',
False)
'snapengage_secure_connection',
'SNAPENGAGE_SECURE_CONNECTION',
False)
if secure_connection:
settings_code.append(SECURE_CONNECTION_CODE)
@ -92,41 +92,42 @@ class SnapEngageNode(Node):
email = get_identity(context, 'snapengage', lambda u: u.email)
if email is not None:
if self._get_setting(context, 'snapengage_readonly_email',
'SNAPENGAGE_READONLY_EMAIL', False):
'SNAPENGAGE_READONLY_EMAIL', False):
readonly_tail = ',true'
else:
readonly_tail = ''
settings_code.append(SETEMAIL_CODE % (email, readonly_tail))
locale = self._get_setting(context, 'snapengage_locale',
'SNAPENGAGE_LOCALE')
'SNAPENGAGE_LOCALE')
if locale is None:
locale = translation.to_locale(translation.get_language())
settings_code.append(SETLOCALE_CODE % locale)
form_position = self._get_setting(context,
'snapengage_form_position', 'SNAPENGAGE_FORM_POSITION')
'snapengage_form_position', 'SNAPENGAGE_FORM_POSITION')
if form_position is not None:
settings_code.append(FORM_POSITION_CODE % form_position)
form_top_position = self._get_setting(context,
'snapengage_form_top_position', 'SNAPENGAGE_FORM_TOP_POSITION')
'snapengage_form_top_position',
'SNAPENGAGE_FORM_TOP_POSITION')
if form_top_position is not None:
settings_code.append(FORM_TOP_POSITION_CODE % form_top_position)
show_offline = self._get_setting(context, 'snapengage_show_offline',
'SNAPENGAGE_SHOW_OFFLINE', True)
'SNAPENGAGE_SHOW_OFFLINE', True)
if not show_offline:
settings_code.append(DISABLE_OFFLINE_CODE)
screenshots = self._get_setting(context, 'snapengage_screenshots',
'SNAPENGAGE_SCREENSHOTS', True)
'SNAPENGAGE_SCREENSHOTS', True)
if not screenshots:
settings_code.append(DISABLE_SCREENSHOT_CODE)
offline_screenshots = self._get_setting(context,
'snapengage_offline_screenshots',
'SNAPENGAGE_OFFLINE_SCREENSHOTS', True)
'snapengage_offline_screenshots',
'SNAPENGAGE_OFFLINE_SCREENSHOTS', True)
if not offline_screenshots:
settings_code.append(DISABLE_OFFLINE_SCREENSHOT_CODE)
@ -134,37 +135,41 @@ class SnapEngageNode(Node):
settings_code.append(DISABLE_PROACTIVE_CHAT_CODE)
sounds = self._get_setting(context, 'snapengage_sounds',
'SNAPENGAGE_SOUNDS', True)
'SNAPENGAGE_SOUNDS', True)
if not sounds:
settings_code.append(DISABLE_SOUNDS_CODE)
button_effect = self._get_setting(context, 'snapengage_button_effect',
'SNAPENGAGE_BUTTON_EFFECT')
'SNAPENGAGE_BUTTON_EFFECT')
if button_effect is not None:
settings_code.append(BUTTONEFFECT_CODE % button_effect)
button = self._get_setting(context, 'snapengage_button',
'SNAPENGAGE_BUTTON', BUTTON_STYLE_DEFAULT)
'SNAPENGAGE_BUTTON', BUTTON_STYLE_DEFAULT)
if button == BUTTON_STYLE_NONE:
settings_code.append(INIT_CODE % self.widget_id)
else:
if not isinstance(button, int):
# Assume button as a URL to a custom image
settings_code.append(SETBUTTON_CODE % button)
button_location = self._get_setting(context,
'snapengage_button_location', 'SNAPENGAGE_BUTTON_LOCATION',
BUTTON_LOCATION_LEFT)
button_offset = self._get_setting(context,
'snapengage_button_location_offset',
'SNAPENGAGE_BUTTON_LOCATION_OFFSET', '55%')
button_location = self._get_setting(
context,
'snapengage_button_location', 'SNAPENGAGE_BUTTON_LOCATION',
BUTTON_LOCATION_LEFT)
button_offset = self._get_setting(
context,
'snapengage_button_location_offset',
'SNAPENGAGE_BUTTON_LOCATION_OFFSET', '55%')
settings_code.append(ADDBUTTON_CODE % {
'id': self.widget_id,
'location': button_location,
'offset': button_offset,
'dynamic_tail': ',true' if (button == BUTTON_STYLE_LIVE) else '',
})
html = SETUP_CODE % {'widget_id': self.widget_id,
'settings_code': " ".join(settings_code)}
})
html = SETUP_CODE % {
'widget_id': self.widget_id,
'settings_code': " ".join(settings_code),
}
return html
def _get_setting(self, context, context_key, setting=None, default=None):

View file

@ -29,8 +29,7 @@ TRACKING_CODE = """
)();
%(custom_commands)s
</script>
"""
""" # noqa
register = Library()

View file

@ -49,8 +49,8 @@ def uservoice(parser, token):
class UserVoiceNode(Node):
def __init__(self):
self.default_widget_key = get_required_setting('USERVOICE_WIDGET_KEY',
WIDGET_KEY_RE, "must be an alphanumeric string")
self.default_widget_key = get_required_setting(
'USERVOICE_WIDGET_KEY', WIDGET_KEY_RE, "must be an alphanumeric string")
def render(self, context):
widget_key = context.get('uservoice_widget_key')

View file

@ -28,7 +28,7 @@ TRACKING_CODE = """
woopra.identify(woo_visitor);
woopra.track();
</script>
"""
""" # noqa
register = Library()

View file

@ -37,7 +37,7 @@ COUNTER_CODE = """
})(document, window, "yandex_metrika_callbacks");
</script>
<noscript><div><img src="https://mc.yandex.ru/watch/%(counter_id)s" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
"""
""" # noqa
register = Library()

View file

@ -18,6 +18,7 @@ def _location_node(location):
return "<!-- dummy_%s -->" % location
return DummyNode
_location_nodes = dict((l, _location_node(l)) for l in TAG_LOCATIONS)
@ -29,6 +30,7 @@ def _location_tag(location):
return _location_nodes[location]
return dummy_tag
for loc in TAG_LOCATIONS:
register.tag('dummy_%s' % loc, _location_tag(loc))

View file

@ -27,8 +27,7 @@ class AnalyticsTagTestCase(TagTestCase):
def render_location_tag(self, location, vars=None):
if vars is None:
vars = {}
t = Template("{%% load analytical %%}{%% analytical_%s %%}"
% location)
t = Template("{%% load analytical %%}{%% analytical_%s %%}" % location)
return t.render(Context(vars))
def test_location_tags(self):

View file

@ -39,10 +39,8 @@ class ChartbeatTagTestCaseWithSites(TestCase):
site = Site.objects.create(domain="test.com", name="test")
with override_settings(SITE_ID=site.id):
r = ChartbeatBottomNode().render(Context())
self.assertTrue(re.search(
'var _sf_async_config={.*"uid": "12345".*};', r), r)
self.assertTrue(re.search(
'var _sf_async_config={.*"domain": "test.com".*};', r), r)
self.assertTrue(re.search('var _sf_async_config={.*"uid": "12345".*};', r), r)
self.assertTrue(re.search('var _sf_async_config={.*"domain": "test.com".*};', r), r)
@override_settings(CHARTBEAT_AUTO_DOMAIN=False)
def test_auto_domain_false(self):
@ -62,30 +60,26 @@ class ChartbeatTagTestCase(TagTestCase):
"""
def test_top_tag(self):
r = self.render_tag('chartbeat', 'chartbeat_top',
{'chartbeat_domain': "test.com"})
r = self.render_tag('chartbeat', 'chartbeat_top', {'chartbeat_domain': "test.com"})
self.assertTrue('var _sf_startpt=(new Date()).getTime()' in r, r)
def test_bottom_tag(self):
r = self.render_tag('chartbeat', 'chartbeat_bottom',
{'chartbeat_domain': "test.com"})
self.assertTrue(re.search(
'var _sf_async_config={.*"uid": "12345".*};', r), r)
self.assertTrue(re.search(
'var _sf_async_config={.*"domain": "test.com".*};', r), r)
r = self.render_tag('chartbeat', 'chartbeat_bottom', {'chartbeat_domain': "test.com"})
self.assertTrue(re.search('var _sf_async_config={.*"uid": "12345".*};', r), r)
self.assertTrue(re.search('var _sf_async_config={.*"domain": "test.com".*};', r), r)
def test_top_node(self):
r = ChartbeatTopNode().render(
Context({'chartbeat_domain': "test.com"}))
r = ChartbeatTopNode().render(Context({
'chartbeat_domain': "test.com",
}))
self.assertTrue('var _sf_startpt=(new Date()).getTime()' in r, r)
def test_bottom_node(self):
r = ChartbeatBottomNode().render(
Context({'chartbeat_domain': "test.com"}))
self.assertTrue(re.search(
'var _sf_async_config={.*"uid": "12345".*};', r), r)
self.assertTrue(re.search(
'var _sf_async_config={.*"domain": "test.com".*};', r), r)
r = ChartbeatBottomNode().render(Context({
'chartbeat_domain': "test.com",
}))
self.assertTrue(re.search('var _sf_async_config={.*"uid": "12345".*};', r), r)
self.assertTrue(re.search('var _sf_async_config={.*"domain": "test.com".*};', r), r)
@override_settings(CHARTBEAT_USER_ID=None)
def test_no_user_id(self):

View file

@ -23,14 +23,12 @@ class ClickyTagTestCase(TagTestCase):
def test_tag(self):
r = self.render_tag('clicky', 'clicky')
self.assertTrue('clicky_site_ids.push(12345678);' in r, r)
self.assertTrue('src="//in.getclicky.com/12345678ns.gif"' in r,
r)
self.assertTrue('src="//in.getclicky.com/12345678ns.gif"' in r, r)
def test_node(self):
r = ClickyNode().render(Context({}))
self.assertTrue('clicky_site_ids.push(12345678);' in r, r)
self.assertTrue('src="//in.getclicky.com/12345678ns.gif"' in r,
r)
self.assertTrue('src="//in.getclicky.com/12345678ns.gif"' in r, r)
@override_settings(CLICKY_SITE_ID=None)
def test_no_site_id(self):
@ -43,9 +41,7 @@ class ClickyTagTestCase(TagTestCase):
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
def test_identify(self):
r = ClickyNode().render(Context({'user': User(username='test')}))
self.assertTrue(
'var clicky_custom = {"session": {"username": "test"}};' in r,
r)
self.assertTrue('var clicky_custom = {"session": {"username": "test"}};' in r, r)
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
def test_identify_anonymous_user(self):
@ -53,10 +49,13 @@ class ClickyTagTestCase(TagTestCase):
self.assertFalse('var clicky_custom = {"session": {"username":' in r, r)
def test_custom(self):
r = ClickyNode().render(Context({'clicky_var1': 'val1',
'clicky_var2': 'val2'}))
self.assertTrue(re.search('var clicky_custom = {.*'
'"var1": "val1", "var2": "val2".*};', r), r)
r = ClickyNode().render(Context({
'clicky_var1': 'val1',
'clicky_var2': 'val2',
}))
self.assertTrue(
re.search(r'var clicky_custom = {.*"var1": "val1", "var2": "val2".*};', r),
r)
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
def test_render_internal_ip(self):

View file

@ -32,8 +32,7 @@ class GaugesTagTestCase(TagTestCase):
s.parentNode.insertBefore(t, s);
})();
</script>
""",
self.render_tag('gauges', 'gauges'))
""", self.render_tag('gauges', 'gauges'))
def test_node(self):
self.assertEqual(
@ -51,8 +50,7 @@ class GaugesTagTestCase(TagTestCase):
s.parentNode.insertBefore(t, s);
})();
</script>
""",
GaugesNode().render(Context()))
""", GaugesNode().render(Context()))
@override_settings(GAUGES_SITE_ID=None)
def test_no_account_number(self):

View file

@ -14,7 +14,7 @@ from analytical.utils import AnalyticalException
@override_settings(GOOGLE_ANALYTICS_PROPERTY_ID='UA-123456-7',
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_SINGLE_DOMAIN)
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_SINGLE_DOMAIN)
class GoogleAnalyticsTagTestCase(TagTestCase):
"""
Tests for the ``google_analytics`` template tag.
@ -38,16 +38,15 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
def test_wrong_property_id(self):
self.assertRaises(AnalyticalException, GoogleAnalyticsNode)
@override_settings(
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_SUBDOMAINS,
GOOGLE_ANALYTICS_DOMAIN='example.com')
@override_settings(GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_SUBDOMAINS,
GOOGLE_ANALYTICS_DOMAIN='example.com')
def test_track_multiple_subdomains(self):
r = GoogleAnalyticsNode().render(Context())
self.assertTrue("_gaq.push(['_setDomainName', 'example.com']);" in r, r)
self.assertTrue("_gaq.push(['_setAllowHash', false]);" in r, r)
@override_settings(GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_DOMAINS,
GOOGLE_ANALYTICS_DOMAIN='example.com')
GOOGLE_ANALYTICS_DOMAIN='example.com')
def test_track_multiple_domains(self):
r = GoogleAnalyticsNode().render(Context())
self.assertTrue("_gaq.push(['_setDomainName', 'example.com']);" in r, r)
@ -62,14 +61,10 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
'google_analytics_var5': ('test5', 'qux', SCOPE_PAGE),
})
r = GoogleAnalyticsNode().render(context)
self.assertTrue("_gaq.push(['_setCustomVar', 1, 'test1', 'foo', 3]);"
in r, r)
self.assertTrue("_gaq.push(['_setCustomVar', 2, 'test2', 'bar', 1]);"
in r, r)
self.assertTrue("_gaq.push(['_setCustomVar', 4, 'test4', 'baz', 2]);"
in r, r)
self.assertTrue("_gaq.push(['_setCustomVar', 5, 'test5', 'qux', 3]);"
in r, r)
self.assertTrue("_gaq.push(['_setCustomVar', 1, 'test1', 'foo', 3]);" in r, r)
self.assertTrue("_gaq.push(['_setCustomVar', 2, 'test2', 'bar', 1]);" in r, r)
self.assertTrue("_gaq.push(['_setCustomVar', 4, 'test4', 'baz', 2]);" in r, r)
self.assertTrue("_gaq.push(['_setCustomVar', 5, 'test5', 'qux', 3]);" in r, r)
@override_settings(GOOGLE_ANALYTICS_SITE_SPEED=True)
def test_track_page_load_time(self):
@ -117,14 +112,12 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
@override_settings(GOOGLE_ANALYTICS_SAMPLE_RATE=-1)
def test_exception_whenset_sample_rate_too_small(self):
context = Context()
self.assertRaises(AnalyticalException, GoogleAnalyticsNode().render,
context)
self.assertRaises(AnalyticalException, GoogleAnalyticsNode().render, context)
@override_settings(GOOGLE_ANALYTICS_SAMPLE_RATE=101)
def test_exception_when_set_sample_rate_too_large(self):
context = Context()
self.assertRaises(AnalyticalException, GoogleAnalyticsNode().render,
context)
self.assertRaises(AnalyticalException, GoogleAnalyticsNode().render, context)
@override_settings(GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE=0.0)
def test_set_site_speed_sample_rate_min(self):
@ -139,14 +132,12 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
@override_settings(GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE=-1)
def test_exception_whenset_site_speed_sample_rate_too_small(self):
context = Context()
self.assertRaises(AnalyticalException, GoogleAnalyticsNode().render,
context)
self.assertRaises(AnalyticalException, GoogleAnalyticsNode().render, context)
@override_settings(GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE=101)
def test_exception_when_set_site_speed_sample_rate_too_large(self):
context = Context()
self.assertRaises(AnalyticalException, GoogleAnalyticsNode().render,
context)
self.assertRaises(AnalyticalException, GoogleAnalyticsNode().render, context)
@override_settings(GOOGLE_ANALYTICS_SESSION_COOKIE_TIMEOUT=0)
def test_set_session_cookie_timeout_min(self):
@ -161,8 +152,7 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
@override_settings(GOOGLE_ANALYTICS_SESSION_COOKIE_TIMEOUT=-1)
def test_exception_when_set_session_cookie_timeout_too_small(self):
context = Context()
self.assertRaises(AnalyticalException, GoogleAnalyticsNode().render,
context)
self.assertRaises(AnalyticalException, GoogleAnalyticsNode().render, context)
@override_settings(GOOGLE_ANALYTICS_VISITOR_COOKIE_TIMEOUT=0)
def test_set_visitor_cookie_timeout_min(self):
@ -177,16 +167,14 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
@override_settings(GOOGLE_ANALYTICS_VISITOR_COOKIE_TIMEOUT=-1)
def test_exception_when_set_visitor_cookie_timeout_too_small(self):
context = Context()
self.assertRaises(AnalyticalException, GoogleAnalyticsNode().render,
context)
self.assertRaises(AnalyticalException, GoogleAnalyticsNode().render, context)
@override_settings(GOOGLE_ANALYTICS_PROPERTY_ID='UA-123456-7',
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_DOMAINS,
GOOGLE_ANALYTICS_DOMAIN=None,
ANALYTICAL_DOMAIN=None)
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_DOMAINS,
GOOGLE_ANALYTICS_DOMAIN=None,
ANALYTICAL_DOMAIN=None)
class NoDomainTestCase(TestCase):
def test_exception_without_domain(self):
context = Context()
self.assertRaises(AnalyticalException, GoogleAnalyticsNode().render,
context)
self.assertRaises(AnalyticalException, GoogleAnalyticsNode().render, context)

View file

@ -36,8 +36,9 @@ class GoSquaredTagTestCase(TagTestCase):
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
def test_auto_identify(self):
r = GoSquaredNode().render(Context({'user': User(username='test',
first_name='Test', last_name='User')}))
r = GoSquaredNode().render(Context({
'user': User(username='test', first_name='Test', last_name='User'),
}))
self.assertTrue('GoSquared.UserName = "Test User";' in r, r)
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)

View file

@ -19,13 +19,13 @@ class HubSpotTagTestCase(TagTestCase):
def test_tag(self):
r = self.render_tag('hubspot', 'hubspot')
self.assertTrue("n.id=i;n.src='//js.hs-analytics.net/analytics/'+(Math.ceil(new Date()/r)*r)+'/1234.js';"
in r, r)
self.assertTrue("n.id=i;n.src='//js.hs-analytics.net/analytics/'"
"+(Math.ceil(new Date()/r)*r)+'/1234.js';" in r, r)
def test_node(self):
r = HubSpotNode().render(Context())
self.assertTrue("n.id=i;n.src='//js.hs-analytics.net/analytics/'+(Math.ceil(new Date()/r)*r)+'/1234.js';"
in r, r)
self.assertTrue("n.id=i;n.src='//js.hs-analytics.net/analytics/'"
"+(Math.ceil(new Date()/r)*r)+'/1234.js';" in r, r)
@override_settings(HUBSPOT_PORTAL_ID=None)
def test_no_portal_id(self):

View file

@ -31,7 +31,7 @@ class IntercomTagTestCase(TagTestCase):
first_name='Firstname',
last_name='Lastname',
email="test@example.com",
date_joined=now)
date_joined=now),
}))
# Because the json isn't predictably ordered, we can't just test the whole thing verbatim.
self.assertEqual("""
@ -39,7 +39,7 @@ class IntercomTagTestCase(TagTestCase):
window.intercomSettings = {"app_id": "abc123xyz", "created_at": 1397074500, "email": "test@example.com", "name": "Firstname Lastname"};
</script>
<script>(function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',intercomSettings);}else{var d=document;var i=function(){i.c(arguments)};i.q=[];i.c=function(args){i.q.push(args)};w.Intercom=i;function l(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://static.intercomcdn.com/intercom.v1.js';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);}if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})()</script>
""", rendered_tag)
""", rendered_tag) # noqa
@override_settings(INTERCOM_APP_ID=None)
def test_no_account_number(self):
@ -51,13 +51,18 @@ class IntercomTagTestCase(TagTestCase):
def test_identify_name_email_and_created_at(self):
now = datetime.datetime(2014, 4, 9, 15, 15, 0)
r = IntercomNode().render(Context({'user': User(username='test',
first_name='Firstname', last_name='Lastname',
email="test@example.com", date_joined=now)}))
self.assertTrue(
"""window.intercomSettings = {"app_id": "abc123xyz", "created_at": 1397074500, "email": "test@example.com", "name": "Firstname Lastname"};"""\
in r
)
r = IntercomNode().render(Context({
'user': User(
username='test',
first_name='Firstname',
last_name='Lastname',
email="test@example.com",
date_joined=now),
}))
self.assertTrue('window.intercomSettings = {'
'"app_id": "abc123xyz", "created_at": 1397074500, '
'"email": "test@example.com", "name": "Firstname Lastname"'
'};' in r)
def test_custom(self):
r = IntercomNode().render(Context({
@ -68,10 +73,11 @@ class IntercomTagTestCase(TagTestCase):
def test_identify_name_and_email(self):
r = IntercomNode().render(Context({
'user': User(username='test',
first_name='Firstname',
last_name='Lastname',
email="test@example.com")
'user': User(
username='test',
first_name='Firstname',
last_name='Lastname',
email="test@example.com"),
}))
self.assertTrue('"email": "test@example.com", "name": "Firstname Lastname"' in r)
@ -80,13 +86,17 @@ class IntercomTagTestCase(TagTestCase):
self.assertTrue('"name": "test"' in r, r)
def test_no_identify_when_explicit_name(self):
r = IntercomNode().render(Context({'intercom_name': 'explicit',
'user': User(username='implicit')}))
r = IntercomNode().render(Context({
'intercom_name': 'explicit',
'user': User(username='implicit'),
}))
self.assertTrue('"name": "explicit"' in r, r)
def test_no_identify_when_explicit_email(self):
r = IntercomNode().render(Context({'intercom_email': 'explicit',
'user': User(username='implicit')}))
r = IntercomNode().render(Context({
'intercom_email': 'explicit',
'user': User(username='implicit'),
}))
self.assertTrue('"email": "explicit"' in r, r)
def test_disable_for_anonymous_users(self):

View file

@ -11,8 +11,7 @@ from analytical.tests.utils import TagTestCase
from analytical.utils import AnalyticalException
@override_settings(KISS_INSIGHTS_ACCOUNT_NUMBER='12345',
KISS_INSIGHTS_SITE_CODE='abc')
@override_settings(KISS_INSIGHTS_ACCOUNT_NUMBER='12345', KISS_INSIGHTS_SITE_CODE='abc')
class KissInsightsTagTestCase(TagTestCase):
"""
Tests for the ``kiss_insights`` template tag.
@ -53,6 +52,5 @@ class KissInsightsTagTestCase(TagTestCase):
self.assertFalse("_kiq.push(['identify', " in r, r)
def test_show_survey(self):
r = KissInsightsNode().render(
Context({'kiss_insights_show_survey': 1234}))
r = KissInsightsNode().render(Context({'kiss_insights_show_survey': 1234}))
self.assertTrue("_kiq.push(['showSurvey', 1234]);" in r, r)

View file

@ -12,8 +12,7 @@ from analytical.tests.utils import TagTestCase
from analytical.utils import AnalyticalException
@override_settings(KISS_METRICS_API_KEY='0123456789abcdef0123456789abcdef'
'01234567')
@override_settings(KISS_METRICS_API_KEY='0123456789abcdef0123456789abcdef01234567')
class KissMetricsTagTestCase(TagTestCase):
"""
Tests for the ``kiss_metrics`` template tag.
@ -21,25 +20,23 @@ class KissMetricsTagTestCase(TagTestCase):
def test_tag(self):
r = self.render_tag('kiss_metrics', 'kiss_metrics')
self.assertTrue("//doug1izaerwt3.cloudfront.net/0123456789abcdef012345"
"6789abcdef01234567.1.js" in r, r)
self.assertTrue("//doug1izaerwt3.cloudfront.net/"
"0123456789abcdef0123456789abcdef01234567.1.js" in r, r)
def test_node(self):
r = KissMetricsNode().render(Context())
self.assertTrue("//doug1izaerwt3.cloudfront.net/0123456789abcdef012345"
"6789abcdef01234567.1.js" in r, r)
self.assertTrue("//doug1izaerwt3.cloudfront.net/"
"0123456789abcdef0123456789abcdef01234567.1.js" in r, r)
@override_settings(KISS_METRICS_API_KEY=None)
def test_no_api_key(self):
self.assertRaises(AnalyticalException, KissMetricsNode)
@override_settings(KISS_METRICS_API_KEY='0123456789abcdef0123456789abcdef'
'0123456')
@override_settings(KISS_METRICS_API_KEY='0123456789abcdef0123456789abcdef0123456')
def test_api_key_too_short(self):
self.assertRaises(AnalyticalException, KissMetricsNode)
@override_settings(KISS_METRICS_API_KEY='0123456789abcdef0123456789abcdef'
'012345678')
@override_settings(KISS_METRICS_API_KEY='0123456789abcdef0123456789abcdef012345678')
def test_api_key_too_long(self):
self.assertRaises(AnalyticalException, KissMetricsNode)
@ -54,20 +51,23 @@ class KissMetricsTagTestCase(TagTestCase):
self.assertFalse("_kmq.push(['identify', " in r, r)
def test_event(self):
r = KissMetricsNode().render(Context({'kiss_metrics_event':
('test_event', {'prop1': 'val1', 'prop2': 'val2'})}))
r = KissMetricsNode().render(Context({
'kiss_metrics_event': ('test_event', {'prop1': 'val1', 'prop2': 'val2'}),
}))
self.assertTrue("_kmq.push(['record', 'test_event', "
'{"prop1": "val1", "prop2": "val2"}]);' in r, r)
'{"prop1": "val1", "prop2": "val2"}]);' in r, r)
def test_property(self):
r = KissMetricsNode().render(Context({'kiss_metrics_properties':
{'prop1': 'val1', 'prop2': 'val2'}}))
r = KissMetricsNode().render(Context({
'kiss_metrics_properties': {'prop1': 'val1', 'prop2': 'val2'},
}))
self.assertTrue("_kmq.push([\'set\', "
'{"prop1": "val1", "prop2": "val2"}]);' in r, r)
'{"prop1": "val1", "prop2": "val2"}]);' in r, r)
def test_alias(self):
r = KissMetricsNode().render(Context({'kiss_metrics_alias':
{'test': 'test_alias'}}))
r = KissMetricsNode().render(Context({
'kiss_metrics_alias': {'test': 'test_alias'},
}))
self.assertTrue("_kmq.push(['alias', 'test', 'test_alias']);" in r, r)
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])

View file

@ -20,15 +20,11 @@ class MixpanelTagTestCase(TagTestCase):
def test_tag(self):
r = self.render_tag('mixpanel', 'mixpanel')
self.assertIn(
"mixpanel.init('0123456789abcdef0123456789abcdef');", r,
)
self.assertIn("mixpanel.init('0123456789abcdef0123456789abcdef');", r)
def test_node(self):
r = MixpanelNode().render(Context())
self.assertIn(
"mixpanel.init('0123456789abcdef0123456789abcdef');", r,
)
self.assertIn("mixpanel.init('0123456789abcdef0123456789abcdef');", r)
@override_settings(MIXPANEL_API_TOKEN=None)
def test_no_token(self):
@ -53,8 +49,9 @@ class MixpanelTagTestCase(TagTestCase):
self.assertFalse("mixpanel.register_once({distinct_id:" in r, r)
def test_event(self):
r = MixpanelNode().render(Context({'mixpanel_event':
('test_event', {'prop1': 'val1', 'prop2': 'val2'})}))
r = MixpanelNode().render(Context({
'mixpanel_event': ('test_event', {'prop1': 'val1', 'prop2': 'val2'}),
}))
self.assertTrue("mixpanel.track('test_event', "
'{"prop1": "val1", "prop2": "val2"});' in r, r)

View file

@ -35,10 +35,11 @@ class OlarkTestCase(TagTestCase):
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
def test_identify(self):
r = OlarkNode().render(Context({'user':
User(username='test', first_name='Test', last_name='User')}))
r = OlarkNode().render(Context({
'user': User(username='test', first_name='Test', last_name='User'),
}))
self.assertTrue("olark('api.chat.updateVisitorNickname', "
"{snippet: 'Test User (test)'});" in r, r)
"{snippet: 'Test User (test)'});" in r, r)
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
def test_identify_anonymous_user(self):
@ -48,18 +49,19 @@ class OlarkTestCase(TagTestCase):
def test_nickname(self):
r = OlarkNode().render(Context({'olark_nickname': 'testnick'}))
self.assertTrue("olark('api.chat.updateVisitorNickname', "
"{snippet: 'testnick'});" in r, r)
"{snippet: 'testnick'});" in r, r)
def test_status_string(self):
r = OlarkNode().render(Context({'olark_status': 'teststatus'}))
self.assertTrue("olark('api.chat.updateVisitorStatus', "
'{snippet: "teststatus"});' in r, r)
'{snippet: "teststatus"});' in r, r)
def test_status_string_list(self):
r = OlarkNode().render(Context({'olark_status':
['teststatus1', 'teststatus2']}))
r = OlarkNode().render(Context({
'olark_status': ['teststatus1', 'teststatus2'],
}))
self.assertTrue("olark('api.chat.updateVisitorStatus', "
'{snippet: ["teststatus1", "teststatus2"]});' in r, r)
'{snippet: ["teststatus1", "teststatus2"]});' in r, r)
def test_messages(self):
messages = [
@ -88,5 +90,4 @@ class OlarkTestCase(TagTestCase):
vars = dict(('olark_%s' % m, m) for m in messages)
r = OlarkNode().render(Context(vars))
for m in messages:
self.assertTrue("olark.configure('locale.%s', \"%s\");" % (m, m)
in r, r)
self.assertTrue("olark.configure('locale.%s', \"%s\");" % (m, m) in r, r)

View file

@ -2,9 +2,6 @@
Tests for the Rating@Mail.ru template tags and filters.
"""
import re
from django.contrib.auth.models import User, AnonymousUser
from django.http import HttpRequest
from django.template import Context
from django.test.utils import override_settings

View file

@ -50,16 +50,19 @@ class SnapEngageTestCase(TagTestCase):
self.assertRaises(AnalyticalException, SnapEngageNode)
def test_no_button(self):
r = SnapEngageNode().render(Context({'snapengage_button': BUTTON_STYLE_NONE}))
self.assertTrue('SnapABug.init("ec329c69-0bf0-4db8-9b77-3f8150fb977e")'
in r, r)
r = SnapEngageNode().render(Context({
'snapengage_button': BUTTON_STYLE_NONE,
}))
self.assertTrue('SnapABug.init("ec329c69-0bf0-4db8-9b77-3f8150fb977e")' in r, r)
with override_settings(SNAPENGAGE_BUTTON=BUTTON_STYLE_NONE):
r = SnapEngageNode().render(Context())
self.assertTrue(
'SnapABug.init("ec329c69-0bf0-4db8-9b77-3f8150fb977e")' in r, r)
def test_live_button(self):
r = SnapEngageNode().render(Context({'snapengage_button': BUTTON_STYLE_LIVE}))
r = SnapEngageNode().render(Context({
'snapengage_button': BUTTON_STYLE_LIVE,
}))
self.assertTrue(
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0",'
'"55%",true);' in r, r)
@ -71,7 +74,8 @@ class SnapEngageTestCase(TagTestCase):
def test_custom_button(self):
r = SnapEngageNode().render(Context({
'snapengage_button': "http://www.example.com/button.png"}))
'snapengage_button': "http://www.example.com/button.png",
}))
self.assertTrue(
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0",'
'"55%");' in r, r)
@ -89,12 +93,12 @@ class SnapEngageTestCase(TagTestCase):
def test_button_location_right(self):
r = SnapEngageNode().render(Context({
'snapengage_button_location': BUTTON_LOCATION_RIGHT}))
'snapengage_button_location': BUTTON_LOCATION_RIGHT,
}))
self.assertTrue(
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","1",'
'"55%");' in r, r)
with override_settings(
SNAPENGAGE_BUTTON_LOCATION=BUTTON_LOCATION_RIGHT):
with override_settings(SNAPENGAGE_BUTTON_LOCATION=BUTTON_LOCATION_RIGHT):
r = SnapEngageNode().render(Context())
self.assertTrue(
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","1",'
@ -102,7 +106,8 @@ class SnapEngageTestCase(TagTestCase):
def test_button_location_top(self):
r = SnapEngageNode().render(Context({
'snapengage_button_location': BUTTON_LOCATION_TOP}))
'snapengage_button_location': BUTTON_LOCATION_TOP,
}))
self.assertTrue(
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","2",'
'"55%");' in r, r)
@ -114,7 +119,8 @@ class SnapEngageTestCase(TagTestCase):
def test_button_location_bottom(self):
r = SnapEngageNode().render(Context({
'snapengage_button_location': BUTTON_LOCATION_BOTTOM}))
'snapengage_button_location': BUTTON_LOCATION_BOTTOM,
}))
self.assertTrue(
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","3",'
'"55%");' in r, r)
@ -127,7 +133,8 @@ class SnapEngageTestCase(TagTestCase):
def test_button_offset(self):
r = SnapEngageNode().render(Context({
'snapengage_button_location_offset': "30%"}))
'snapengage_button_location_offset': "30%",
}))
self.assertTrue(
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0",'
'"30%");' in r, r)
@ -139,7 +146,8 @@ class SnapEngageTestCase(TagTestCase):
def test_button_effect(self):
r = SnapEngageNode().render(Context({
'snapengage_button_effect': "-4px"}))
'snapengage_button_effect': "-4px",
}))
self.assertTrue('SnapABug.setButtonEffect("-4px");' in r, r)
with override_settings(SNAPENGAGE_BUTTON_EFFECT="-4px"):
r = SnapEngageNode().render(Context())
@ -147,7 +155,8 @@ class SnapEngageTestCase(TagTestCase):
def test_form_position(self):
r = SnapEngageNode().render(Context({
'snapengage_form_position': FORM_POSITION_TOP_LEFT}))
'snapengage_form_position': FORM_POSITION_TOP_LEFT,
}))
self.assertTrue('SnapABug.setChatFormPosition("tl");' in r, r)
with override_settings(SNAPENGAGE_FORM_POSITION=FORM_POSITION_TOP_LEFT):
r = SnapEngageNode().render(Context())
@ -155,7 +164,8 @@ class SnapEngageTestCase(TagTestCase):
def test_form_top_position(self):
r = SnapEngageNode().render(Context({
'snapengage_form_top_position': 40}))
'snapengage_form_top_position': 40,
}))
self.assertTrue('SnapABug.setFormTopPosition(40);' in r, r)
with override_settings(SNAPENGAGE_FORM_TOP_POSITION=40):
r = SnapEngageNode().render(Context())
@ -178,7 +188,9 @@ class SnapEngageTestCase(TagTestCase):
self.assertTrue('SnapABug.setSecureConnexion();' in r, r)
def test_show_offline(self):
r = SnapEngageNode().render(Context({'snapengage_show_offline': False}))
r = SnapEngageNode().render(Context({
'snapengage_show_offline': False,
}))
self.assertTrue('SnapABug.allowOffline(false);' in r, r)
with override_settings(SNAPENGAGE_SHOW_OFFLINE=False):
r = SnapEngageNode().render(Context())
@ -190,15 +202,18 @@ class SnapEngageTestCase(TagTestCase):
self.assertTrue('SnapABug.allowProactiveChat(false);' in r, r)
def test_screenshot(self):
r = SnapEngageNode().render(Context({'snapengage_screenshots': False}))
r = SnapEngageNode().render(Context({
'snapengage_screenshots': False,
}))
self.assertTrue('SnapABug.allowScreenshot(false);' in r, r)
with override_settings(SNAPENGAGE_SCREENSHOTS=False):
r = SnapEngageNode().render(Context())
self.assertTrue('SnapABug.allowScreenshot(false);' in r, r)
def test_offline_screenshots(self):
r = SnapEngageNode().render(Context(
{'snapengage_offline_screenshots': False}))
r = SnapEngageNode().render(Context({
'snapengage_offline_screenshots': False,
}))
self.assertTrue('SnapABug.showScreenshotOption(false);' in r, r)
with override_settings(SNAPENGAGE_OFFLINE_SCREENSHOTS=False):
r = SnapEngageNode().render(Context())
@ -213,30 +228,35 @@ class SnapEngageTestCase(TagTestCase):
@override_settings(SNAPENGAGE_READONLY_EMAIL=False)
def test_email(self):
r = SnapEngageNode().render(Context({'snapengage_email':
'test@example.com'}))
r = SnapEngageNode().render(Context({
'snapengage_email': 'test@example.com',
}))
self.assertTrue('SnapABug.setUserEmail("test@example.com");' in r, r)
def test_email_readonly(self):
r = SnapEngageNode().render(Context({'snapengage_email':
'test@example.com', 'snapengage_readonly_email': True}))
self.assertTrue('SnapABug.setUserEmail("test@example.com",true);' in r,
r)
r = SnapEngageNode().render(Context({
'snapengage_email': 'test@example.com',
'snapengage_readonly_email': True,
}))
self.assertTrue('SnapABug.setUserEmail("test@example.com",true);' in r, r)
with override_settings(SNAPENGAGE_READONLY_EMAIL=True):
r = SnapEngageNode().render(Context({'snapengage_email':
'test@example.com'}))
self.assertTrue('SnapABug.setUserEmail("test@example.com",true);'
in r, r)
r = SnapEngageNode().render(Context({
'snapengage_email': 'test@example.com',
}))
self.assertTrue('SnapABug.setUserEmail("test@example.com",true);' in r, r)
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
def test_identify(self):
r = SnapEngageNode().render(Context({'user':
User(username='test', email='test@example.com')}))
r = SnapEngageNode().render(Context({
'user': User(username='test', email='test@example.com'),
}))
self.assertTrue('SnapABug.setUserEmail("test@example.com");' in r, r)
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
def test_identify_anonymous_user(self):
r = SnapEngageNode().render(Context({'user': AnonymousUser()}))
r = SnapEngageNode().render(Context({
'user': AnonymousUser(),
}))
self.assertFalse('SnapABug.setUserEmail(' in r, r)
def test_language(self):

View file

@ -2,8 +2,6 @@
Tests for the Spring Metrics template tags and filters.
"""
import re
from django.contrib.auth.models import User, AnonymousUser
from django.http import HttpRequest
from django.template import Context
@ -38,10 +36,10 @@ class SpringMetricsTagTestCase(TagTestCase):
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
def test_identify(self):
r = SpringMetricsNode().render(Context({'user':
User(email='test@test.com')}))
self.assertTrue("_springMetq.push(['setdata', "
"{'email': 'test@test.com'}]);" in r, r)
r = SpringMetricsNode().render(Context({
'user': User(email='test@test.com'),
}))
self.assertTrue("_springMetq.push(['setdata', {'email': 'test@test.com'}]);" in r, r)
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
def test_identify_anonymous_user(self):
@ -49,12 +47,12 @@ class SpringMetricsTagTestCase(TagTestCase):
self.assertFalse("_springMetq.push(['setdata', {'email':" in r, r)
def test_custom(self):
r = SpringMetricsNode().render(Context({'spring_metrics_var1': 'val1',
'spring_metrics_var2': 'val2'}))
self.assertTrue("_springMetq.push(['setdata', {'var1': 'val1'}]);" in r,
r)
self.assertTrue("_springMetq.push(['setdata', {'var2': 'val2'}]);" in r,
r)
r = SpringMetricsNode().render(Context({
'spring_metrics_var1': 'val1',
'spring_metrics_var2': 'val2',
}))
self.assertTrue("_springMetq.push(['setdata', {'var1': 'val1'}]);" in r, r)
self.assertTrue("_springMetq.push(['setdata', {'var2': 'val2'}]);" in r, r)
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
def test_render_internal_ip(self):

View file

@ -58,7 +58,7 @@ class UserVoiceTagTestCase(TagTestCase):
r = UserVoiceNode().render(Context(data))
self.assertIn("""UserVoice.push(['set', {"key1": "val2"}]);""", r)
def test_auto_trigger(self):
def test_auto_trigger_default(self):
r = UserVoiceNode().render(Context())
self.assertTrue("UserVoice.push(['addTrigger', {}]);" in r, r)

View file

@ -37,22 +37,26 @@ class WoopraTagTestCase(TagTestCase):
@override_settings(WOOPRA_IDLE_TIMEOUT=1234)
def test_idle_timeout(self):
r = WoopraNode().render(Context({}))
self.assertTrue('var woo_settings = {"domain": "example.com", '
'"idle_timeout": "1234"};' in r, r)
self.assertTrue('var woo_settings = '
'{"domain": "example.com", "idle_timeout": "1234"};' in r, r)
def test_custom(self):
r = WoopraNode().render(Context({'woopra_var1': 'val1',
'woopra_var2': 'val2'}))
self.assertTrue('var woo_visitor = {"var1": "val1", "var2": "val2"};'
in r, r)
r = WoopraNode().render(Context({
'woopra_var1': 'val1',
'woopra_var2': 'val2',
}))
self.assertTrue('var woo_visitor = {"var1": "val1", "var2": "val2"};' in r, r)
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
def test_identify_name_and_email(self):
r = WoopraNode().render(Context({'user': User(username='test',
first_name='Firstname', last_name='Lastname',
email="test@example.com")}))
self.assertTrue('var woo_visitor = {"email": "test@example.com", '
'"name": "Firstname Lastname"};' in r, r)
r = WoopraNode().render(Context({
'user': User(username='test',
first_name='Firstname',
last_name='Lastname',
email="test@example.com"),
}))
self.assertTrue('var woo_visitor = '
'{"email": "test@example.com", "name": "Firstname Lastname"};' in r, r)
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
def test_identify_username_no_email(self):
@ -61,14 +65,18 @@ class WoopraTagTestCase(TagTestCase):
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
def test_no_identify_when_explicit_name(self):
r = WoopraNode().render(Context({'woopra_name': 'explicit',
'user': User(username='implicit')}))
r = WoopraNode().render(Context({
'woopra_name': 'explicit',
'user': User(username='implicit'),
}))
self.assertTrue('var woo_visitor = {"name": "explicit"};' in r, r)
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
def test_no_identify_when_explicit_email(self):
r = WoopraNode().render(Context({'woopra_email': 'explicit',
'user': User(username='implicit')}))
r = WoopraNode().render(Context({
'woopra_email': 'explicit',
'user': User(username='implicit'),
}))
self.assertTrue('var woo_visitor = {"email": "explicit"};' in r, r)
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)

View file

@ -2,9 +2,7 @@
Tests for the Yandex.Metrica template tags and filters.
"""
import re
from django.contrib.auth.models import User, AnonymousUser
from django.http import HttpRequest
from django.template import Context
from django.test.utils import override_settings

View file

@ -30,11 +30,11 @@ class SettingDeletedTestCase(TestCase):
# available in python >= 3.2
if hasattr(self, 'assertRaisesRegex'):
with self.assertRaisesRegex(AnalyticalException, "^USER_ID setting is not set$"):
user_id = get_required_setting("USER_ID", "\d+", "invalid USER_ID")
get_required_setting("USER_ID", "\d+", "invalid USER_ID")
# available in python >= 2.7, deprecated in 3.2
elif hasattr(self, 'assertRaisesRegexp'):
with self.assertRaisesRegexp(AnalyticalException, "^USER_ID setting is not set$"):
user_id = get_required_setting("USER_ID", "\d+", "invalid USER_ID")
get_required_setting("USER_ID", "\d+", "invalid USER_ID")
else:
self.assertRaises(AnalyticalException,
get_required_setting, "USER_ID", "\d+", "invalid USER_ID")
@ -72,10 +72,9 @@ class GetDomainTestCase(TestCase):
# FIXME: enable Django apps dynamically and enable test again
#@with_apps('django.contrib.sites')
#@override_settings(TEST_DOMAIN=SETTING_DELETED,
# ANALYTICAL_DOMAIN=SETTING_DELETED)
#class GetDomainTestCaseWithSites(TestCase):
# @with_apps('django.contrib.sites')
# @override_settings(TEST_DOMAIN=SETTING_DELETED, ANALYTICAL_DOMAIN=SETTING_DELETED)
# class GetDomainTestCaseWithSites(TestCase):
# def test_get_domain_from_site(self):
# site = Site.objects.create(domain="example.com", name="test")
# with override_settings(SITE_ID=site.id):

View file

@ -9,7 +9,7 @@ import sys
sys.path.append(os.path.join(os.path.abspath('.'), '_ext'))
sys.path.append(os.path.dirname(os.path.abspath('.')))
import analytical
import analytical # noqa
# -- General configuration --------------------------------------------------

View file

@ -60,16 +60,16 @@ except ImportError:
"This is fine, unless you intend to run unit tests."
)
import analytical
import analytical as package # noqa
setup(
name='django-analytical',
version=analytical.__version__,
license=analytical.__license__,
version=package.__version__,
license=package.__license__,
description='Analytics service integration for Django projects',
long_description=read('README.rst'),
author=analytical.__author__,
author_email=analytical.__email__,
author=package.__author__,
author_email=package.__email__,
packages=[
'analytical',
'analytical.templatetags',
@ -84,6 +84,8 @@ setup(
'Framework :: Django :: 1.7',
'Framework :: Django :: 1.8',
'Framework :: Django :: 1.9',
# 'Framework :: Django :: 1.10',
# 'Framework :: Django :: 1.11',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
@ -93,10 +95,10 @@ setup(
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
# 'Programming Language :: Python :: 3.6',
],
platforms=['any'],
url='https://github.com/jcassee/django-analytical',

28
tox.ini
View file

@ -1,19 +1,39 @@
[tox]
envlist =
py{27,32,33,34}-django17,
py{27,32,33,34,35}-django18,
py{27,33,34}-django17
py{27,33,34,35}-django18
py{27,34,35}-django19
# py{27,34,35}-django110
# py{27,34,35,36}-django111
flake8
[testenv]
commands =
coverage run setup.py test
sh -c 'coveralls | true'
deps =
coverage==3.7.1
coverage
coveralls
django17: Django>=1.7,<1.8
django18: Django>=1.8,<1.9
django19: Django>=1.9,<1.10
virtualenv<14.0.0
django110: Django>=1.10,<1.11
django111: Django>=1.11,<2.0
passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH
whitelist_externals = sh
[testenv:flake8]
basepython = python2.7
deps = flake8
commands = flake8
[travis:env]
DJANGO =
1.7: django17
1.8: django18
1.9: django19
1.10: django110
1.11: django111
[flake8]
max-line-length = 100