mirror of
https://github.com/jazzband/django-analytical.git
synced 2026-03-16 22:20:25 +00:00
Applied isort and black to project
This commit is contained in:
parent
8cd75d9e60
commit
ad7f229a8c
66 changed files with 2069 additions and 1488 deletions
|
|
@ -3,45 +3,44 @@ Analytical template tags and filters.
|
|||
"""
|
||||
|
||||
import logging
|
||||
from importlib import import_module
|
||||
|
||||
from django import template
|
||||
from django.template import Node, TemplateSyntaxError
|
||||
from importlib import import_module
|
||||
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
TAG_LOCATIONS = ['head_top', 'head_bottom', 'body_top', 'body_bottom']
|
||||
TAG_POSITIONS = ['first', None, 'last']
|
||||
TAG_LOCATIONS = ["head_top", "head_bottom", "body_top", "body_bottom"]
|
||||
TAG_POSITIONS = ["first", None, "last"]
|
||||
TAG_MODULES = [
|
||||
'analytical.chartbeat',
|
||||
'analytical.clickmap',
|
||||
'analytical.clicky',
|
||||
'analytical.crazy_egg',
|
||||
'analytical.facebook_pixel',
|
||||
'analytical.gauges',
|
||||
'analytical.google_analytics',
|
||||
'analytical.google_analytics_js',
|
||||
'analytical.google_analytics_gtag',
|
||||
'analytical.gosquared',
|
||||
'analytical.hotjar',
|
||||
'analytical.hubspot',
|
||||
'analytical.intercom',
|
||||
'analytical.kiss_insights',
|
||||
'analytical.kiss_metrics',
|
||||
'analytical.luckyorange',
|
||||
'analytical.matomo',
|
||||
'analytical.mixpanel',
|
||||
'analytical.olark',
|
||||
'analytical.optimizely',
|
||||
'analytical.performable',
|
||||
'analytical.piwik',
|
||||
'analytical.rating_mailru',
|
||||
'analytical.snapengage',
|
||||
'analytical.spring_metrics',
|
||||
'analytical.uservoice',
|
||||
'analytical.woopra',
|
||||
'analytical.yandex_metrica',
|
||||
"analytical.chartbeat",
|
||||
"analytical.clickmap",
|
||||
"analytical.clicky",
|
||||
"analytical.crazy_egg",
|
||||
"analytical.facebook_pixel",
|
||||
"analytical.gauges",
|
||||
"analytical.google_analytics",
|
||||
"analytical.google_analytics_js",
|
||||
"analytical.google_analytics_gtag",
|
||||
"analytical.gosquared",
|
||||
"analytical.hotjar",
|
||||
"analytical.hubspot",
|
||||
"analytical.intercom",
|
||||
"analytical.kiss_insights",
|
||||
"analytical.kiss_metrics",
|
||||
"analytical.luckyorange",
|
||||
"analytical.matomo",
|
||||
"analytical.mixpanel",
|
||||
"analytical.olark",
|
||||
"analytical.optimizely",
|
||||
"analytical.performable",
|
||||
"analytical.piwik",
|
||||
"analytical.rating_mailru",
|
||||
"analytical.snapengage",
|
||||
"analytical.spring_metrics",
|
||||
"analytical.uservoice",
|
||||
"analytical.woopra",
|
||||
"analytical.yandex_metrica",
|
||||
]
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
@ -59,7 +58,7 @@ def _location_tag(location):
|
|||
|
||||
|
||||
for loc in TAG_LOCATIONS:
|
||||
register.tag('analytical_%s' % loc, _location_tag(loc))
|
||||
register.tag("analytical_%s" % loc, _location_tag(loc))
|
||||
|
||||
|
||||
class AnalyticalNode(Node):
|
||||
|
|
@ -83,13 +82,14 @@ def _load_template_nodes():
|
|||
except AnalyticalException as e:
|
||||
logger.debug("not loading tags from '%s': %s", path, e)
|
||||
for location in TAG_LOCATIONS:
|
||||
template_nodes[location] = sum((template_nodes[location][p]
|
||||
for p in TAG_POSITIONS), [])
|
||||
template_nodes[location] = sum(
|
||||
(template_nodes[location][p] for p in TAG_POSITIONS), []
|
||||
)
|
||||
return template_nodes
|
||||
|
||||
|
||||
def _import_tag_module(path):
|
||||
app_name, lib_name = path.rsplit('.', 1)
|
||||
app_name, lib_name = path.rsplit(".", 1)
|
||||
return import_module("%s.templatetags.%s" % (app_name, lib_name))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,11 +9,12 @@ from django.conf import settings
|
|||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import is_internal_ip, disable_html, get_required_setting
|
||||
from analytical.utils import disable_html, get_required_setting, is_internal_ip
|
||||
|
||||
|
||||
USER_ID_RE = re.compile(r'^\d+$')
|
||||
INIT_CODE = """<script type="text/javascript">var _sf_startpt=(new Date()).getTime()</script>"""
|
||||
USER_ID_RE = re.compile(r"^\d+$")
|
||||
INIT_CODE = (
|
||||
"""<script type="text/javascript">var _sf_startpt=(new Date()).getTime()</script>"""
|
||||
)
|
||||
SETUP_CODE = """
|
||||
<script type="text/javascript">
|
||||
var _sf_async_config=%(config)s;
|
||||
|
|
@ -34,7 +35,7 @@ SETUP_CODE = """
|
|||
})();
|
||||
</script>
|
||||
""" # noqa
|
||||
DOMAIN_CONTEXT_KEY = 'chartbeat_domain'
|
||||
DOMAIN_CONTEXT_KEY = "chartbeat_domain"
|
||||
|
||||
|
||||
register = Library()
|
||||
|
|
@ -77,24 +78,25 @@ 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")
|
||||
self.user_id = get_required_setting(
|
||||
"CHARTBEAT_USER_ID", USER_ID_RE, "must be (a string containing) a number"
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
config = {'uid': self.user_id}
|
||||
config = {"uid": self.user_id}
|
||||
domain = _get_domain(context)
|
||||
if domain is not None:
|
||||
config['domain'] = domain
|
||||
html = SETUP_CODE % {'config': json.dumps(config, sort_keys=True)}
|
||||
if is_internal_ip(context, 'CHARTBEAT'):
|
||||
html = disable_html(html, 'Chartbeat')
|
||||
config["domain"] = domain
|
||||
html = SETUP_CODE % {"config": json.dumps(config, sort_keys=True)}
|
||||
if is_internal_ip(context, "CHARTBEAT"):
|
||||
html = disable_html(html, "Chartbeat")
|
||||
return html
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
ChartbeatBottomNode() # ensure properly configured
|
||||
add_node('head_top', ChartbeatTopNode, 'first')
|
||||
add_node('body_bottom', ChartbeatBottomNode, 'last')
|
||||
add_node("head_top", ChartbeatTopNode, "first")
|
||||
add_node("body_bottom", ChartbeatBottomNode, "last")
|
||||
|
||||
|
||||
def _get_domain(context):
|
||||
|
|
@ -103,10 +105,11 @@ def _get_domain(context):
|
|||
if domain is not None:
|
||||
return domain
|
||||
else:
|
||||
if 'django.contrib.sites' not in settings.INSTALLED_APPS:
|
||||
if "django.contrib.sites" not in settings.INSTALLED_APPS:
|
||||
return
|
||||
elif getattr(settings, 'CHARTBEAT_AUTO_DOMAIN', True):
|
||||
elif getattr(settings, "CHARTBEAT_AUTO_DOMAIN", True):
|
||||
from django.contrib.sites.models import Site
|
||||
|
||||
try:
|
||||
return Site.objects.get_current().domain
|
||||
except (ImproperlyConfigured, Site.DoesNotExist): # pylint: disable=E1101
|
||||
|
|
|
|||
|
|
@ -6,10 +6,9 @@ import re
|
|||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import is_internal_ip, disable_html, get_required_setting
|
||||
from analytical.utils import disable_html, get_required_setting, is_internal_ip
|
||||
|
||||
|
||||
CLICKMAP_TRACKER_ID_RE = re.compile(r'^\w+$')
|
||||
CLICKMAP_TRACKER_ID_RE = re.compile(r"^\w+$")
|
||||
TRACKING_CODE = """
|
||||
<script type="text/javascript">
|
||||
var clickmapConfig = {tracker: '%(tracker_id)s', version:'2'};
|
||||
|
|
@ -43,17 +42,19 @@ def clickmap(parser, token):
|
|||
|
||||
class ClickmapNode(Node):
|
||||
def __init__(self):
|
||||
self.tracker_id = get_required_setting('CLICKMAP_TRACKER_ID',
|
||||
CLICKMAP_TRACKER_ID_RE,
|
||||
"must be an alphanumeric string")
|
||||
self.tracker_id = get_required_setting(
|
||||
"CLICKMAP_TRACKER_ID",
|
||||
CLICKMAP_TRACKER_ID_RE,
|
||||
"must be an alphanumeric string",
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
html = TRACKING_CODE % {'tracker_id': self.tracker_id}
|
||||
if is_internal_ip(context, 'CLICKMAP'):
|
||||
html = disable_html(html, 'Clickmap')
|
||||
html = TRACKING_CODE % {"tracker_id": self.tracker_id}
|
||||
if is_internal_ip(context, "CLICKMAP"):
|
||||
html = disable_html(html, "Clickmap")
|
||||
return html
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
ClickmapNode() # ensure properly configured
|
||||
add_node('body_bottom', ClickmapNode)
|
||||
add_node("body_bottom", ClickmapNode)
|
||||
|
|
|
|||
|
|
@ -7,11 +7,14 @@ import re
|
|||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import get_identity, is_internal_ip, disable_html, \
|
||||
get_required_setting
|
||||
from analytical.utils import (
|
||||
disable_html,
|
||||
get_identity,
|
||||
get_required_setting,
|
||||
is_internal_ip,
|
||||
)
|
||||
|
||||
|
||||
SITE_ID_RE = re.compile(r'^\d+$')
|
||||
SITE_ID_RE = re.compile(r"^\d+$")
|
||||
TRACKING_CODE = """
|
||||
<script type="text/javascript">
|
||||
var clicky = { log: function(){ return; }, goal: function(){ return; }};
|
||||
|
|
@ -50,29 +53,29 @@ 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")
|
||||
"CLICKY_SITE_ID", SITE_ID_RE, "must be a (string containing) a number"
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
custom = {}
|
||||
for dict_ in context:
|
||||
for var, val in dict_.items():
|
||||
if var.startswith('clicky_'):
|
||||
if var.startswith("clicky_"):
|
||||
custom[var[7:]] = val
|
||||
if 'username' not in custom.get('session', {}):
|
||||
identity = get_identity(context, 'clicky')
|
||||
if "username" not in custom.get("session", {}):
|
||||
identity = get_identity(context, "clicky")
|
||||
if identity is not None:
|
||||
custom.setdefault('session', {})['username'] = identity
|
||||
custom.setdefault("session", {})["username"] = identity
|
||||
|
||||
html = TRACKING_CODE % {
|
||||
'site_id': self.site_id,
|
||||
'custom': json.dumps(custom, sort_keys=True),
|
||||
"site_id": self.site_id,
|
||||
"custom": json.dumps(custom, sort_keys=True),
|
||||
}
|
||||
if is_internal_ip(context, 'CLICKY'):
|
||||
html = disable_html(html, 'Clicky')
|
||||
if is_internal_ip(context, "CLICKY"):
|
||||
html = disable_html(html, "Clicky")
|
||||
return html
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
ClickyNode() # ensure properly configured
|
||||
add_node('body_bottom', ClickyNode)
|
||||
add_node("body_bottom", ClickyNode)
|
||||
|
|
|
|||
|
|
@ -6,14 +6,16 @@ import re
|
|||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import is_internal_ip, disable_html, get_required_setting
|
||||
from analytical.utils import disable_html, get_required_setting, is_internal_ip
|
||||
|
||||
|
||||
ACCOUNT_NUMBER_RE = re.compile(r'^\d+$')
|
||||
SETUP_CODE = '<script type="text/javascript" src="{placeholder_url}">' \
|
||||
'</script>'.\
|
||||
format(placeholder_url='//dnn506yrbagrg.cloudfront.net/pages/scripts/'
|
||||
'%(account_nr_1)s/%(account_nr_2)s.js')
|
||||
ACCOUNT_NUMBER_RE = re.compile(r"^\d+$")
|
||||
SETUP_CODE = (
|
||||
'<script type="text/javascript" src="{placeholder_url}">'
|
||||
"</script>".format(
|
||||
placeholder_url="//dnn506yrbagrg.cloudfront.net/pages/scripts/"
|
||||
"%(account_nr_1)s/%(account_nr_2)s.js"
|
||||
)
|
||||
)
|
||||
USERVAR_CODE = "CE2.set(%(varnr)d, '%(value)s');"
|
||||
|
||||
|
||||
|
|
@ -38,29 +40,33 @@ def crazy_egg(parser, token):
|
|||
class CrazyEggNode(Node):
|
||||
def __init__(self):
|
||||
self.account_nr = get_required_setting(
|
||||
'CRAZY_EGG_ACCOUNT_NUMBER',
|
||||
ACCOUNT_NUMBER_RE, "must be (a string containing) a number"
|
||||
"CRAZY_EGG_ACCOUNT_NUMBER",
|
||||
ACCOUNT_NUMBER_RE,
|
||||
"must be (a string containing) a number",
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
html = SETUP_CODE % {
|
||||
'account_nr_1': self.account_nr[:4],
|
||||
'account_nr_2': self.account_nr[4:],
|
||||
"account_nr_1": self.account_nr[:4],
|
||||
"account_nr_2": self.account_nr[4:],
|
||||
}
|
||||
values = (context.get('crazy_egg_var%d' % i) for i in range(1, 6))
|
||||
values = (context.get("crazy_egg_var%d" % i) for i in range(1, 6))
|
||||
params = [(i, v) for i, v in enumerate(values, 1) if v is not None]
|
||||
if params:
|
||||
js = " ".join(USERVAR_CODE % {
|
||||
'varnr': varnr,
|
||||
'value': value,
|
||||
} for (varnr, value) in params)
|
||||
html = '%s\n' \
|
||||
'<script type="text/javascript">%s</script>' % (html, js)
|
||||
if is_internal_ip(context, 'CRAZY_EGG'):
|
||||
html = disable_html(html, 'Crazy Egg')
|
||||
js = " ".join(
|
||||
USERVAR_CODE
|
||||
% {
|
||||
"varnr": varnr,
|
||||
"value": value,
|
||||
}
|
||||
for (varnr, value) in params
|
||||
)
|
||||
html = "%s\n" '<script type="text/javascript">%s</script>' % (html, js)
|
||||
if is_internal_ip(context, "CRAZY_EGG"):
|
||||
html = disable_html(html, "Crazy Egg")
|
||||
return html
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
CrazyEggNode() # ensure properly configured
|
||||
add_node('body_bottom', CrazyEggNode)
|
||||
add_node("body_bottom", CrazyEggNode)
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@ import re
|
|||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import get_required_setting, is_internal_ip, disable_html
|
||||
|
||||
from analytical.utils import disable_html, get_required_setting, is_internal_ip
|
||||
|
||||
FACEBOOK_PIXEL_HEAD_CODE = """\
|
||||
<script>
|
||||
|
|
@ -61,17 +60,18 @@ class _FacebookPixelNode(Node):
|
|||
"""
|
||||
Base class: override and provide code_template.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.pixel_id = get_required_setting(
|
||||
'FACEBOOK_PIXEL_ID',
|
||||
re.compile(r'^\d+$'),
|
||||
"FACEBOOK_PIXEL_ID",
|
||||
re.compile(r"^\d+$"),
|
||||
"must be (a string containing) a number",
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
html = self.code_template % {'FACEBOOK_PIXEL_ID': self.pixel_id}
|
||||
if is_internal_ip(context, 'FACEBOOK_PIXEL'):
|
||||
return disable_html(html, 'Facebook Pixel')
|
||||
html = self.code_template % {"FACEBOOK_PIXEL_ID": self.pixel_id}
|
||||
if is_internal_ip(context, "FACEBOOK_PIXEL"):
|
||||
return disable_html(html, "Facebook Pixel")
|
||||
else:
|
||||
return html
|
||||
|
||||
|
|
@ -92,5 +92,5 @@ def contribute_to_analytical(add_node):
|
|||
# ensure properly configured
|
||||
FacebookPixelHeadNode()
|
||||
FacebookPixelBodyNode()
|
||||
add_node('head_bottom', FacebookPixelHeadNode)
|
||||
add_node('body_bottom', FacebookPixelBodyNode)
|
||||
add_node("head_bottom", FacebookPixelHeadNode)
|
||||
add_node("body_bottom", FacebookPixelBodyNode)
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ import re
|
|||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import is_internal_ip, disable_html, get_required_setting
|
||||
from analytical.utils import disable_html, get_required_setting, is_internal_ip
|
||||
|
||||
SITE_ID_RE = re.compile(r'[\da-f]+$')
|
||||
SITE_ID_RE = re.compile(r"[\da-f]+$")
|
||||
TRACKING_CODE = """
|
||||
<script type="text/javascript">
|
||||
var _gauges = _gauges || [];
|
||||
|
|
@ -46,16 +46,16 @@ def gauges(parser, token):
|
|||
class GaugesNode(Node):
|
||||
def __init__(self):
|
||||
self.site_id = get_required_setting(
|
||||
'GAUGES_SITE_ID', SITE_ID_RE,
|
||||
"must be a string looking like 'XXXXXXX'")
|
||||
"GAUGES_SITE_ID", SITE_ID_RE, "must be a string looking like 'XXXXXXX'"
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
html = TRACKING_CODE % {'site_id': self.site_id}
|
||||
if is_internal_ip(context, 'GAUGES'):
|
||||
html = disable_html(html, 'Gauges')
|
||||
html = TRACKING_CODE % {"site_id": self.site_id}
|
||||
if is_internal_ip(context, "GAUGES"):
|
||||
html = disable_html(html, "Gauges")
|
||||
return html
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
GaugesNode()
|
||||
add_node('head_bottom', GaugesNode)
|
||||
add_node("head_bottom", GaugesNode)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ SCOPE_VISITOR = 1
|
|||
SCOPE_SESSION = 2
|
||||
SCOPE_PAGE = 3
|
||||
|
||||
PROPERTY_ID_RE = re.compile(r'^UA-\d+-\d+$')
|
||||
PROPERTY_ID_RE = re.compile(r"^UA-\d+-\d+$")
|
||||
SETUP_CODE = """
|
||||
<script type="text/javascript">
|
||||
|
||||
|
|
@ -45,8 +45,9 @@ DOMAIN_CODE = "_gaq.push(['_setDomainName', '%s']);"
|
|||
NO_ALLOW_HASH_CODE = "_gaq.push(['_setAllowHash', false]);"
|
||||
TRACK_PAGE_VIEW = "_gaq.push(['_trackPageview']);"
|
||||
ALLOW_LINKER_CODE = "_gaq.push(['_setAllowLinker', true]);"
|
||||
CUSTOM_VAR_CODE = "_gaq.push(['_setCustomVar', %(index)s, '%(name)s', " \
|
||||
"'%(value)s', %(scope)s]);"
|
||||
CUSTOM_VAR_CODE = (
|
||||
"_gaq.push(['_setCustomVar', %(index)s, '%(name)s', " "'%(value)s', %(scope)s]);"
|
||||
)
|
||||
SITE_SPEED_CODE = "_gaq.push(['_trackPageLoadTime']);"
|
||||
ANONYMIZE_IP_CODE = "_gaq.push(['_gat._anonymizeIp']);"
|
||||
SAMPLE_RATE_CODE = "_gaq.push(['_setSampleRate', '%s']);"
|
||||
|
|
@ -54,10 +55,13 @@ SITE_SPEED_SAMPLE_RATE_CODE = "_gaq.push(['_setSiteSpeedSampleRate', '%s']);"
|
|||
SESSION_COOKIE_TIMEOUT_CODE = "_gaq.push(['_setSessionCookieTimeout', '%s']);"
|
||||
VISITOR_COOKIE_TIMEOUT_CODE = "_gaq.push(['_setVisitorCookieTimeout', '%s']);"
|
||||
DEFAULT_SOURCE = ("'https://ssl' : 'http://www'", "'.google-analytics.com/ga.js'")
|
||||
DISPLAY_ADVERTISING_SOURCE = ("'https://' : 'http://'", "'stats.g.doubleclick.net/dc.js'")
|
||||
DISPLAY_ADVERTISING_SOURCE = (
|
||||
"'https://' : 'http://'",
|
||||
"'stats.g.doubleclick.net/dc.js'",
|
||||
)
|
||||
|
||||
ZEROPLACES = decimal.Decimal('0')
|
||||
TWOPLACES = decimal.Decimal('0.01')
|
||||
ZEROPLACES = decimal.Decimal("0")
|
||||
TWOPLACES = decimal.Decimal("0.01")
|
||||
|
||||
register = Library()
|
||||
|
||||
|
|
@ -80,39 +84,43 @@ def google_analytics(parser, token):
|
|||
class GoogleAnalyticsNode(Node):
|
||||
def __init__(self):
|
||||
self.property_id = get_required_setting(
|
||||
'GOOGLE_ANALYTICS_PROPERTY_ID', PROPERTY_ID_RE,
|
||||
"must be a string looking like 'UA-XXXXXX-Y'")
|
||||
"GOOGLE_ANALYTICS_PROPERTY_ID",
|
||||
PROPERTY_ID_RE,
|
||||
"must be a string looking like 'UA-XXXXXX-Y'",
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
commands = self._get_domain_commands(context)
|
||||
commands.extend(self._get_custom_var_commands(context))
|
||||
commands.extend(self._get_other_commands(context))
|
||||
commands.append(TRACK_PAGE_VIEW)
|
||||
if getattr(settings, 'GOOGLE_ANALYTICS_DISPLAY_ADVERTISING', False):
|
||||
if getattr(settings, "GOOGLE_ANALYTICS_DISPLAY_ADVERTISING", False):
|
||||
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],
|
||||
"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')
|
||||
if is_internal_ip(context, "GOOGLE_ANALYTICS"):
|
||||
html = disable_html(html, "Google Analytics")
|
||||
return html
|
||||
|
||||
def _get_domain_commands(self, context):
|
||||
commands = []
|
||||
tracking_type = getattr(settings, 'GOOGLE_ANALYTICS_TRACKING_STYLE',
|
||||
TRACK_SINGLE_DOMAIN)
|
||||
tracking_type = getattr(
|
||||
settings, "GOOGLE_ANALYTICS_TRACKING_STYLE", TRACK_SINGLE_DOMAIN
|
||||
)
|
||||
if tracking_type == TRACK_SINGLE_DOMAIN:
|
||||
pass
|
||||
else:
|
||||
domain = get_domain(context, 'google_analytics')
|
||||
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:
|
||||
|
|
@ -120,9 +128,7 @@ class GoogleAnalyticsNode(Node):
|
|||
return commands
|
||||
|
||||
def _get_custom_var_commands(self, context):
|
||||
values = (
|
||||
context.get('google_analytics_var%s' % i) for i in range(1, 6)
|
||||
)
|
||||
values = (context.get("google_analytics_var%s" % i) for i in range(1, 6))
|
||||
params = [(i, v) for i, v in enumerate(values, 1) if v is not None]
|
||||
commands = []
|
||||
for index, var in params:
|
||||
|
|
@ -132,53 +138,69 @@ class GoogleAnalyticsNode(Node):
|
|||
scope = var[2]
|
||||
except IndexError:
|
||||
scope = SCOPE_PAGE
|
||||
commands.append(CUSTOM_VAR_CODE % {
|
||||
'index': index,
|
||||
'name': name,
|
||||
'value': value,
|
||||
'scope': scope,
|
||||
})
|
||||
commands.append(
|
||||
CUSTOM_VAR_CODE
|
||||
% {
|
||||
"index": index,
|
||||
"name": name,
|
||||
"value": value,
|
||||
"scope": scope,
|
||||
}
|
||||
)
|
||||
return commands
|
||||
|
||||
def _get_other_commands(self, context):
|
||||
commands = []
|
||||
if getattr(settings, 'GOOGLE_ANALYTICS_SITE_SPEED', False):
|
||||
if getattr(settings, "GOOGLE_ANALYTICS_SITE_SPEED", False):
|
||||
commands.append(SITE_SPEED_CODE)
|
||||
|
||||
if getattr(settings, 'GOOGLE_ANALYTICS_ANONYMIZE_IP', False):
|
||||
if getattr(settings, "GOOGLE_ANALYTICS_ANONYMIZE_IP", False):
|
||||
commands.append(ANONYMIZE_IP_CODE)
|
||||
|
||||
sampleRate = getattr(settings, 'GOOGLE_ANALYTICS_SAMPLE_RATE', False)
|
||||
sampleRate = getattr(settings, "GOOGLE_ANALYTICS_SAMPLE_RATE", False)
|
||||
if sampleRate is not False:
|
||||
value = decimal.Decimal(sampleRate)
|
||||
if not 0 <= value <= 100:
|
||||
raise AnalyticalException("'GOOGLE_ANALYTICS_SAMPLE_RATE' must be >= 0 and <= 100")
|
||||
raise AnalyticalException(
|
||||
"'GOOGLE_ANALYTICS_SAMPLE_RATE' must be >= 0 and <= 100"
|
||||
)
|
||||
commands.append(SAMPLE_RATE_CODE % value.quantize(TWOPLACES))
|
||||
|
||||
siteSpeedSampleRate = getattr(settings, 'GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE', False)
|
||||
siteSpeedSampleRate = getattr(
|
||||
settings, "GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE", False
|
||||
)
|
||||
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")
|
||||
"'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)
|
||||
sessionCookieTimeout = getattr(
|
||||
settings, "GOOGLE_ANALYTICS_SESSION_COOKIE_TIMEOUT", False
|
||||
)
|
||||
if sessionCookieTimeout is not False:
|
||||
value = decimal.Decimal(sessionCookieTimeout)
|
||||
if value < 0:
|
||||
raise AnalyticalException("'GOOGLE_ANALYTICS_SESSION_COOKIE_TIMEOUT' must be >= 0")
|
||||
raise AnalyticalException(
|
||||
"'GOOGLE_ANALYTICS_SESSION_COOKIE_TIMEOUT' must be >= 0"
|
||||
)
|
||||
commands.append(SESSION_COOKIE_TIMEOUT_CODE % value.quantize(ZEROPLACES))
|
||||
|
||||
visitorCookieTimeout = getattr(settings, 'GOOGLE_ANALYTICS_VISITOR_COOKIE_TIMEOUT', False)
|
||||
visitorCookieTimeout = getattr(
|
||||
settings, "GOOGLE_ANALYTICS_VISITOR_COOKIE_TIMEOUT", False
|
||||
)
|
||||
if visitorCookieTimeout is not False:
|
||||
value = decimal.Decimal(visitorCookieTimeout)
|
||||
if value < 0:
|
||||
raise AnalyticalException("'GOOGLE_ANALYTICS_VISITOR_COOKIE_TIMEOUT' must be >= 0")
|
||||
raise AnalyticalException(
|
||||
"'GOOGLE_ANALYTICS_VISITOR_COOKIE_TIMEOUT' must be >= 0"
|
||||
)
|
||||
commands.append(VISITOR_COOKIE_TIMEOUT_CODE % value.quantize(ZEROPLACES))
|
||||
return commands
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
GoogleAnalyticsNode() # ensure properly configured
|
||||
add_node('head_bottom', GoogleAnalyticsNode)
|
||||
add_node("head_bottom", GoogleAnalyticsNode)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@ from analytical.utils import (
|
|||
is_internal_ip,
|
||||
)
|
||||
|
||||
PROPERTY_ID_RE = re.compile(r'^UA-\d+-\d+$|^G-[a-zA-Z0-9]+$|^AW-[a-zA-Z0-9]+$|^DC-[a-zA-Z0-9]+$')
|
||||
PROPERTY_ID_RE = re.compile(
|
||||
r"^UA-\d+-\d+$|^G-[a-zA-Z0-9]+$|^AW-[a-zA-Z0-9]+$|^DC-[a-zA-Z0-9]+$"
|
||||
)
|
||||
SETUP_CODE = """
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id={property_id}"></script>
|
||||
<script>
|
||||
|
|
@ -49,30 +51,35 @@ def google_analytics_gtag(parser, token):
|
|||
class GoogleAnalyticsGTagNode(Node):
|
||||
def __init__(self):
|
||||
self.property_id = get_required_setting(
|
||||
'GOOGLE_ANALYTICS_GTAG_PROPERTY_ID', PROPERTY_ID_RE,
|
||||
'''must be a string looking like one of these patterns
|
||||
"GOOGLE_ANALYTICS_GTAG_PROPERTY_ID",
|
||||
PROPERTY_ID_RE,
|
||||
"""must be a string looking like one of these patterns
|
||||
('UA-XXXXXX-Y' , 'AW-XXXXXXXXXX',
|
||||
'G-XXXXXXXX', 'DC-XXXXXXXX')''')
|
||||
'G-XXXXXXXX', 'DC-XXXXXXXX')""",
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
other_fields = {}
|
||||
|
||||
identity = get_identity(context)
|
||||
if identity is not None:
|
||||
other_fields['user_id'] = identity
|
||||
other_fields["user_id"] = identity
|
||||
|
||||
extra = '\n'.join([
|
||||
GTAG_SET_CODE.format(key=key, value=value) for key, value in other_fields.items()
|
||||
])
|
||||
extra = "\n".join(
|
||||
[
|
||||
GTAG_SET_CODE.format(key=key, value=value)
|
||||
for key, value in other_fields.items()
|
||||
]
|
||||
)
|
||||
html = SETUP_CODE.format(
|
||||
property_id=self.property_id,
|
||||
extra=extra,
|
||||
)
|
||||
if is_internal_ip(context, 'GOOGLE_ANALYTICS'):
|
||||
html = disable_html(html, 'Google Analytics')
|
||||
if is_internal_ip(context, "GOOGLE_ANALYTICS"):
|
||||
html = disable_html(html, "Google Analytics")
|
||||
return html
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
GoogleAnalyticsGTagNode() # ensure properly configured
|
||||
add_node('head_top', GoogleAnalyticsGTagNode)
|
||||
add_node("head_top", GoogleAnalyticsGTagNode)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ Google Analytics template tags and filters, using the new analytics.js library.
|
|||
|
||||
import decimal
|
||||
import re
|
||||
|
||||
from django.conf import settings
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
|
|
@ -19,7 +20,7 @@ TRACK_SINGLE_DOMAIN = 1
|
|||
TRACK_MULTIPLE_SUBDOMAINS = 2
|
||||
TRACK_MULTIPLE_DOMAINS = 3
|
||||
|
||||
PROPERTY_ID_RE = re.compile(r'^UA-\d+-\d+$')
|
||||
PROPERTY_ID_RE = re.compile(r"^UA-\d+-\d+$")
|
||||
SETUP_CODE = """
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){{i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){{
|
||||
|
|
@ -56,16 +57,21 @@ def google_analytics_js(parser, token):
|
|||
class GoogleAnalyticsJsNode(Node):
|
||||
def __init__(self):
|
||||
self.property_id = get_required_setting(
|
||||
'GOOGLE_ANALYTICS_JS_PROPERTY_ID', PROPERTY_ID_RE,
|
||||
"must be a string looking like 'UA-XXXXXX-Y'")
|
||||
"GOOGLE_ANALYTICS_JS_PROPERTY_ID",
|
||||
PROPERTY_ID_RE,
|
||||
"must be a string looking like 'UA-XXXXXX-Y'",
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
import json
|
||||
|
||||
create_fields = self._get_domain_fields(context)
|
||||
create_fields.update(self._get_other_create_fields(context))
|
||||
commands = self._get_custom_var_commands(context)
|
||||
commands.extend(self._get_other_commands(context))
|
||||
display_features = getattr(settings, 'GOOGLE_ANALYTICS_DISPLAY_ADVERTISING', False)
|
||||
display_features = getattr(
|
||||
settings, "GOOGLE_ANALYTICS_DISPLAY_ADVERTISING", False
|
||||
)
|
||||
if display_features:
|
||||
commands.insert(0, REQUIRE_DISPLAY_FEATURES)
|
||||
|
||||
|
|
@ -74,56 +80,64 @@ class GoogleAnalyticsJsNode(Node):
|
|||
create_fields=json.dumps(create_fields),
|
||||
commands="".join(commands),
|
||||
)
|
||||
if is_internal_ip(context, 'GOOGLE_ANALYTICS'):
|
||||
html = disable_html(html, 'Google Analytics')
|
||||
if is_internal_ip(context, "GOOGLE_ANALYTICS"):
|
||||
html = disable_html(html, "Google Analytics")
|
||||
return html
|
||||
|
||||
def _get_domain_fields(self, context):
|
||||
domain_fields = {}
|
||||
tracking_type = getattr(settings, 'GOOGLE_ANALYTICS_TRACKING_STYLE', TRACK_SINGLE_DOMAIN)
|
||||
tracking_type = getattr(
|
||||
settings, "GOOGLE_ANALYTICS_TRACKING_STYLE", TRACK_SINGLE_DOMAIN
|
||||
)
|
||||
if tracking_type == TRACK_SINGLE_DOMAIN:
|
||||
pass
|
||||
else:
|
||||
domain = get_domain(context, 'google_analytics')
|
||||
domain = get_domain(context, "google_analytics")
|
||||
if domain is None:
|
||||
raise AnalyticalException(
|
||||
"tracking multiple domains with Google Analytics requires a domain name")
|
||||
domain_fields['legacyCookieDomain'] = domain
|
||||
"tracking multiple domains with Google Analytics requires a domain name"
|
||||
)
|
||||
domain_fields["legacyCookieDomain"] = domain
|
||||
if tracking_type == TRACK_MULTIPLE_DOMAINS:
|
||||
domain_fields['allowLinker'] = True
|
||||
domain_fields["allowLinker"] = True
|
||||
return domain_fields
|
||||
|
||||
def _get_other_create_fields(self, context):
|
||||
other_fields = {}
|
||||
|
||||
site_speed_sample_rate = getattr(settings, 'GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE', False)
|
||||
site_speed_sample_rate = getattr(
|
||||
settings, "GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE", False
|
||||
)
|
||||
if site_speed_sample_rate is not False:
|
||||
value = int(decimal.Decimal(site_speed_sample_rate))
|
||||
if not 0 <= value <= 100:
|
||||
raise AnalyticalException(
|
||||
"'GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE' must be >= 0 and <= 100")
|
||||
other_fields['siteSpeedSampleRate'] = value
|
||||
"'GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE' must be >= 0 and <= 100"
|
||||
)
|
||||
other_fields["siteSpeedSampleRate"] = value
|
||||
|
||||
sample_rate = getattr(settings, 'GOOGLE_ANALYTICS_SAMPLE_RATE', False)
|
||||
sample_rate = getattr(settings, "GOOGLE_ANALYTICS_SAMPLE_RATE", False)
|
||||
if sample_rate is not False:
|
||||
value = int(decimal.Decimal(sample_rate))
|
||||
if not 0 <= value <= 100:
|
||||
raise AnalyticalException("'GOOGLE_ANALYTICS_SAMPLE_RATE' must be >= 0 and <= 100")
|
||||
other_fields['sampleRate'] = value
|
||||
raise AnalyticalException(
|
||||
"'GOOGLE_ANALYTICS_SAMPLE_RATE' must be >= 0 and <= 100"
|
||||
)
|
||||
other_fields["sampleRate"] = value
|
||||
|
||||
cookie_expires = getattr(settings, 'GOOGLE_ANALYTICS_COOKIE_EXPIRATION', False)
|
||||
cookie_expires = getattr(settings, "GOOGLE_ANALYTICS_COOKIE_EXPIRATION", False)
|
||||
if cookie_expires is not False:
|
||||
value = int(decimal.Decimal(cookie_expires))
|
||||
if value < 0:
|
||||
raise AnalyticalException("'GOOGLE_ANALYTICS_COOKIE_EXPIRATION' must be >= 0")
|
||||
other_fields['cookieExpires'] = value
|
||||
raise AnalyticalException(
|
||||
"'GOOGLE_ANALYTICS_COOKIE_EXPIRATION' must be >= 0"
|
||||
)
|
||||
other_fields["cookieExpires"] = value
|
||||
|
||||
return other_fields
|
||||
|
||||
def _get_custom_var_commands(self, context):
|
||||
values = (
|
||||
context.get('google_analytics_var%s' % i) for i in range(1, 6)
|
||||
)
|
||||
values = (context.get("google_analytics_var%s" % i) for i in range(1, 6))
|
||||
params = [(i, v) for i, v in enumerate(values, 1) if v is not None]
|
||||
commands = []
|
||||
for _, var in params:
|
||||
|
|
@ -133,16 +147,18 @@ class GoogleAnalyticsJsNode(Node):
|
|||
float(value)
|
||||
except ValueError:
|
||||
value = f"'{value}'"
|
||||
commands.append(CUSTOM_VAR_CODE.format(
|
||||
name=name,
|
||||
value=value,
|
||||
))
|
||||
commands.append(
|
||||
CUSTOM_VAR_CODE.format(
|
||||
name=name,
|
||||
value=value,
|
||||
)
|
||||
)
|
||||
return commands
|
||||
|
||||
def _get_other_commands(self, context):
|
||||
commands = []
|
||||
|
||||
if getattr(settings, 'GOOGLE_ANALYTICS_ANONYMIZE_IP', False):
|
||||
if getattr(settings, "GOOGLE_ANALYTICS_ANONYMIZE_IP", False):
|
||||
commands.append(ANONYMIZE_IP_CODE)
|
||||
|
||||
return commands
|
||||
|
|
@ -150,4 +166,4 @@ class GoogleAnalyticsJsNode(Node):
|
|||
|
||||
def contribute_to_analytical(add_node):
|
||||
GoogleAnalyticsJsNode() # ensure properly configured
|
||||
add_node('head_bottom', GoogleAnalyticsJsNode)
|
||||
add_node("head_bottom", GoogleAnalyticsJsNode)
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@ import re
|
|||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import get_identity, \
|
||||
is_internal_ip, disable_html, get_required_setting
|
||||
from analytical.utils import (
|
||||
disable_html,
|
||||
get_identity,
|
||||
get_required_setting,
|
||||
is_internal_ip,
|
||||
)
|
||||
|
||||
|
||||
TOKEN_RE = re.compile(r'^\S+-\S+-\S+$')
|
||||
TOKEN_RE = re.compile(r"^\S+-\S+-\S+$")
|
||||
TRACKING_CODE = """
|
||||
<script type="text/javascript">
|
||||
var GoSquared={};
|
||||
|
|
@ -49,20 +52,22 @@ def gosquared(parser, token):
|
|||
class GoSquaredNode(Node):
|
||||
def __init__(self):
|
||||
self.site_token = get_required_setting(
|
||||
'GOSQUARED_SITE_TOKEN', TOKEN_RE,
|
||||
"must be a string looking like XXX-XXXXXX-X")
|
||||
"GOSQUARED_SITE_TOKEN",
|
||||
TOKEN_RE,
|
||||
"must be a string looking like XXX-XXXXXX-X",
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
configs = [TOKEN_CODE % self.site_token]
|
||||
identity = get_identity(context, 'gosquared', self._identify)
|
||||
identity = get_identity(context, "gosquared", self._identify)
|
||||
if identity:
|
||||
configs.append(IDENTIFY_CODE % identity)
|
||||
html = TRACKING_CODE % {
|
||||
'token': self.site_token,
|
||||
'config': ' '.join(configs),
|
||||
"token": self.site_token,
|
||||
"config": " ".join(configs),
|
||||
}
|
||||
if is_internal_ip(context, 'GOSQUARED'):
|
||||
html = disable_html(html, 'GoSquared')
|
||||
if is_internal_ip(context, "GOSQUARED"):
|
||||
html = disable_html(html, "GoSquared")
|
||||
return html
|
||||
|
||||
def _identify(self, user):
|
||||
|
|
@ -74,4 +79,4 @@ class GoSquaredNode(Node):
|
|||
|
||||
def contribute_to_analytical(add_node):
|
||||
GoSquaredNode() # ensure properly configured
|
||||
add_node('body_bottom', GoSquaredNode)
|
||||
add_node("body_bottom", GoSquaredNode)
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@ import re
|
|||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import get_required_setting, is_internal_ip, disable_html
|
||||
|
||||
from analytical.utils import disable_html, get_required_setting, is_internal_ip
|
||||
|
||||
HOTJAR_TRACKING_CODE = """\
|
||||
<script>
|
||||
|
|
@ -42,18 +41,17 @@ def hotjar(parser, token):
|
|||
|
||||
|
||||
class HotjarNode(Node):
|
||||
|
||||
def __init__(self):
|
||||
self.site_id = get_required_setting(
|
||||
'HOTJAR_SITE_ID',
|
||||
re.compile(r'^\d+$'),
|
||||
"HOTJAR_SITE_ID",
|
||||
re.compile(r"^\d+$"),
|
||||
"must be (a string containing) a number",
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
html = HOTJAR_TRACKING_CODE % {'HOTJAR_SITE_ID': self.site_id}
|
||||
if is_internal_ip(context, 'HOTJAR'):
|
||||
return disable_html(html, 'Hotjar')
|
||||
html = HOTJAR_TRACKING_CODE % {"HOTJAR_SITE_ID": self.site_id}
|
||||
if is_internal_ip(context, "HOTJAR"):
|
||||
return disable_html(html, "Hotjar")
|
||||
else:
|
||||
return html
|
||||
|
||||
|
|
@ -61,4 +59,4 @@ class HotjarNode(Node):
|
|||
def contribute_to_analytical(add_node):
|
||||
# ensure properly configured
|
||||
HotjarNode()
|
||||
add_node('head_bottom', HotjarNode)
|
||||
add_node("head_bottom", HotjarNode)
|
||||
|
|
|
|||
|
|
@ -6,10 +6,9 @@ import re
|
|||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import is_internal_ip, disable_html, get_required_setting
|
||||
from analytical.utils import disable_html, get_required_setting, is_internal_ip
|
||||
|
||||
|
||||
PORTAL_ID_RE = re.compile(r'^\d+$')
|
||||
PORTAL_ID_RE = re.compile(r"^\d+$")
|
||||
TRACKING_CODE = """
|
||||
<!-- Start of Async HubSpot Analytics Code -->
|
||||
<script type="text/javascript">
|
||||
|
|
@ -42,16 +41,17 @@ 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}
|
||||
if is_internal_ip(context, 'HUBSPOT'):
|
||||
html = disable_html(html, 'HubSpot')
|
||||
html = TRACKING_CODE % {"portal_id": self.portal_id}
|
||||
if is_internal_ip(context, "HUBSPOT"):
|
||||
html = disable_html(html, "HubSpot")
|
||||
return html
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
HubSpotNode() # ensure properly configured
|
||||
add_node('body_bottom', HubSpotNode)
|
||||
add_node("body_bottom", HubSpotNode)
|
||||
|
|
|
|||
|
|
@ -10,11 +10,16 @@ import re
|
|||
from django.conf import settings
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import disable_html, get_required_setting, \
|
||||
is_internal_ip, get_user_from_context, get_identity, \
|
||||
get_user_is_authenticated
|
||||
from analytical.utils import (
|
||||
disable_html,
|
||||
get_identity,
|
||||
get_required_setting,
|
||||
get_user_from_context,
|
||||
get_user_is_authenticated,
|
||||
is_internal_ip,
|
||||
)
|
||||
|
||||
APP_ID_RE = re.compile(r'[\da-z]+$')
|
||||
APP_ID_RE = re.compile(r"[\da-z]+$")
|
||||
TRACKING_CODE = """
|
||||
<script id="IntercomSettingsScriptTag">
|
||||
window.intercomSettings = %(settings_json)s;
|
||||
|
|
@ -32,7 +37,7 @@ def _hashable_bytes(data):
|
|||
if isinstance(data, bytes):
|
||||
return data
|
||||
elif isinstance(data, str):
|
||||
return data.encode('ascii') # Fail on anything non-ASCII.
|
||||
return data.encode("ascii") # Fail on anything non-ASCII.
|
||||
else:
|
||||
raise TypeError(data)
|
||||
|
||||
|
|
@ -43,7 +48,7 @@ def intercom_user_hash(data):
|
|||
|
||||
Return None if the `INTERCOM_HMAC_SECRET_KEY` setting is not configured.
|
||||
"""
|
||||
if getattr(settings, 'INTERCOM_HMAC_SECRET_KEY', None):
|
||||
if getattr(settings, "INTERCOM_HMAC_SECRET_KEY", None):
|
||||
return hmac.new(
|
||||
key=_hashable_bytes(settings.INTERCOM_HMAC_SECRET_KEY),
|
||||
msg=_hashable_bytes(data),
|
||||
|
|
@ -71,8 +76,8 @@ def intercom(parser, token):
|
|||
class IntercomNode(Node):
|
||||
def __init__(self):
|
||||
self.app_id = get_required_setting(
|
||||
'INTERCOM_APP_ID', APP_ID_RE,
|
||||
"must be a string looking like 'XXXXXXX'")
|
||||
"INTERCOM_APP_ID", APP_ID_RE, "must be a string looking like 'XXXXXXX'"
|
||||
)
|
||||
|
||||
def _identify(self, user):
|
||||
name = user.get_full_name()
|
||||
|
|
@ -84,47 +89,44 @@ class IntercomNode(Node):
|
|||
params = {}
|
||||
for dict_ in context:
|
||||
for var, val in dict_.items():
|
||||
if var.startswith('intercom_'):
|
||||
if var.startswith("intercom_"):
|
||||
params[var[9:]] = val
|
||||
|
||||
user = get_user_from_context(context)
|
||||
if user is not None and get_user_is_authenticated(user):
|
||||
if 'name' not in params:
|
||||
params['name'] = get_identity(
|
||||
context, 'intercom', self._identify, user)
|
||||
if 'email' not in params and user.email:
|
||||
params['email'] = user.email
|
||||
if "name" not in params:
|
||||
params["name"] = get_identity(context, "intercom", self._identify, user)
|
||||
if "email" not in params and user.email:
|
||||
params["email"] = user.email
|
||||
|
||||
params.setdefault('user_id', user.pk)
|
||||
params.setdefault("user_id", user.pk)
|
||||
|
||||
params['created_at'] = int(user.date_joined.timestamp())
|
||||
params["created_at"] = int(user.date_joined.timestamp())
|
||||
else:
|
||||
params['created_at'] = None
|
||||
params["created_at"] = None
|
||||
|
||||
# Generate a user_hash HMAC to verify the user's identity, if configured.
|
||||
# (If both user_id and email are present, the user_id field takes precedence.)
|
||||
# See:
|
||||
# https://www.intercom.com/help/configure-intercom-for-your-product-or-site/staying-secure/enable-identity-verification-on-your-web-product
|
||||
user_hash_data = params.get('user_id', params.get('email'))
|
||||
user_hash_data = params.get("user_id", params.get("email"))
|
||||
if user_hash_data:
|
||||
user_hash = intercom_user_hash(str(user_hash_data))
|
||||
if user_hash is not None:
|
||||
params.setdefault('user_hash', user_hash)
|
||||
params.setdefault("user_hash", user_hash)
|
||||
|
||||
return params
|
||||
|
||||
def render(self, context):
|
||||
params = self._get_custom_attrs(context)
|
||||
params["app_id"] = self.app_id
|
||||
html = TRACKING_CODE % {
|
||||
"settings_json": json.dumps(params, sort_keys=True)
|
||||
}
|
||||
html = TRACKING_CODE % {"settings_json": json.dumps(params, sort_keys=True)}
|
||||
|
||||
if is_internal_ip(context, 'INTERCOM'):
|
||||
html = disable_html(html, 'Intercom')
|
||||
if is_internal_ip(context, "INTERCOM"):
|
||||
html = disable_html(html, "Intercom")
|
||||
return html
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
IntercomNode()
|
||||
add_node('body_bottom', IntercomNode)
|
||||
add_node("body_bottom", IntercomNode)
|
||||
|
|
|
|||
|
|
@ -8,16 +8,15 @@ from django.template import Library, Node, TemplateSyntaxError
|
|||
|
||||
from analytical.utils import get_identity, get_required_setting
|
||||
|
||||
|
||||
ACCOUNT_NUMBER_RE = re.compile(r'^\d+$')
|
||||
SITE_CODE_RE = re.compile(r'^[\w]+$')
|
||||
ACCOUNT_NUMBER_RE = re.compile(r"^\d+$")
|
||||
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'
|
||||
SHOW_SURVEY_CONTEXT_KEY = "kiss_insights_show_survey"
|
||||
|
||||
|
||||
register = Library()
|
||||
|
|
@ -42,15 +41,19 @@ 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")
|
||||
"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_SITE_CODE",
|
||||
SITE_CODE_RE,
|
||||
"must be a string containing three characters",
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
commands = []
|
||||
identity = get_identity(context, 'kiss_insights')
|
||||
identity = get_identity(context, "kiss_insights")
|
||||
if identity is not None:
|
||||
commands.append(IDENTIFY_CODE % identity)
|
||||
try:
|
||||
|
|
@ -58,13 +61,13 @@ class KissInsightsNode(Node):
|
|||
except KeyError:
|
||||
pass
|
||||
html = SETUP_CODE % {
|
||||
'account_number': self.account_number,
|
||||
'site_code': self.site_code,
|
||||
'commands': " ".join(commands),
|
||||
"account_number": self.account_number,
|
||||
"site_code": self.site_code,
|
||||
"commands": " ".join(commands),
|
||||
}
|
||||
return html
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
KissInsightsNode() # ensure properly configured
|
||||
add_node('body_top', KissInsightsNode)
|
||||
add_node("body_top", KissInsightsNode)
|
||||
|
|
|
|||
|
|
@ -7,11 +7,14 @@ import re
|
|||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import is_internal_ip, disable_html, get_identity, \
|
||||
get_required_setting
|
||||
from analytical.utils import (
|
||||
disable_html,
|
||||
get_identity,
|
||||
get_required_setting,
|
||||
is_internal_ip,
|
||||
)
|
||||
|
||||
|
||||
API_KEY_RE = re.compile(r'^[0-9a-f]{40}$')
|
||||
API_KEY_RE = re.compile(r"^[0-9a-f]{40}$")
|
||||
TRACKING_CODE = """
|
||||
<script type="text/javascript">
|
||||
var _kmq = _kmq || [];
|
||||
|
|
@ -35,9 +38,9 @@ EVENT_CODE = "_kmq.push(['record', '%(name)s', %(properties)s]);"
|
|||
PROPERTY_CODE = "_kmq.push(['set', %(properties)s]);"
|
||||
ALIAS_CODE = "_kmq.push(['alias', '%s', '%s']);"
|
||||
|
||||
EVENT_CONTEXT_KEY = 'kiss_metrics_event'
|
||||
PROPERTY_CONTEXT_KEY = 'kiss_metrics_properties'
|
||||
ALIAS_CONTEXT_KEY = 'kiss_metrics_alias'
|
||||
EVENT_CONTEXT_KEY = "kiss_metrics_event"
|
||||
PROPERTY_CONTEXT_KEY = "kiss_metrics_properties"
|
||||
ALIAS_CONTEXT_KEY = "kiss_metrics_alias"
|
||||
|
||||
register = Library()
|
||||
|
||||
|
|
@ -60,12 +63,14 @@ 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")
|
||||
"KISS_METRICS_API_KEY",
|
||||
API_KEY_RE,
|
||||
"must be a string containing a 40-digit hexadecimal number",
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
commands = []
|
||||
identity = get_identity(context, 'kiss_metrics')
|
||||
identity = get_identity(context, "kiss_metrics")
|
||||
if identity is not None:
|
||||
commands.append(IDENTIFY_CODE % identity)
|
||||
try:
|
||||
|
|
@ -76,28 +81,34 @@ 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),
|
||||
})
|
||||
commands.append(
|
||||
PROPERTY_CODE
|
||||
% {
|
||||
"properties": json.dumps(properties, sort_keys=True),
|
||||
}
|
||||
)
|
||||
except KeyError:
|
||||
pass
|
||||
html = TRACKING_CODE % {
|
||||
'api_key': self.api_key,
|
||||
'commands': " ".join(commands),
|
||||
"api_key": self.api_key,
|
||||
"commands": " ".join(commands),
|
||||
}
|
||||
if is_internal_ip(context, 'KISS_METRICS'):
|
||||
html = disable_html(html, 'KISSmetrics')
|
||||
if is_internal_ip(context, "KISS_METRICS"):
|
||||
html = disable_html(html, "KISSmetrics")
|
||||
return html
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
KissMetricsNode() # ensure properly configured
|
||||
add_node('head_top', KissMetricsNode)
|
||||
add_node("head_top", KissMetricsNode)
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@ import re
|
|||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import get_required_setting, is_internal_ip, disable_html
|
||||
|
||||
from analytical.utils import disable_html, get_required_setting, is_internal_ip
|
||||
|
||||
LUCKYORANGE_TRACKING_CODE = """\
|
||||
<script type='text/javascript'>
|
||||
|
|
@ -40,18 +39,17 @@ def luckyorange(parser, token):
|
|||
|
||||
|
||||
class LuckyOrangeNode(Node):
|
||||
|
||||
def __init__(self):
|
||||
self.site_id = get_required_setting(
|
||||
'LUCKYORANGE_SITE_ID',
|
||||
re.compile(r'^\d+$'),
|
||||
"LUCKYORANGE_SITE_ID",
|
||||
re.compile(r"^\d+$"),
|
||||
"must be (a string containing) a number",
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
html = LUCKYORANGE_TRACKING_CODE % {'LUCKYORANGE_SITE_ID': self.site_id}
|
||||
if is_internal_ip(context, 'LUCKYORANGE'):
|
||||
return disable_html(html, 'Lucky Orange')
|
||||
html = LUCKYORANGE_TRACKING_CODE % {"LUCKYORANGE_SITE_ID": self.site_id}
|
||||
if is_internal_ip(context, "LUCKYORANGE"):
|
||||
return disable_html(html, "Lucky Orange")
|
||||
else:
|
||||
return html
|
||||
|
||||
|
|
@ -59,4 +57,4 @@ class LuckyOrangeNode(Node):
|
|||
def contribute_to_analytical(add_node):
|
||||
# ensure properly configured
|
||||
LuckyOrangeNode()
|
||||
add_node('head_bottom', LuckyOrangeNode)
|
||||
add_node("head_bottom", LuckyOrangeNode)
|
||||
|
|
|
|||
|
|
@ -2,22 +2,25 @@
|
|||
Matomo template tags and filters.
|
||||
"""
|
||||
|
||||
import re
|
||||
from collections import namedtuple
|
||||
from itertools import chain
|
||||
import re
|
||||
|
||||
from django.conf import settings
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import (is_internal_ip, disable_html,
|
||||
get_required_setting, get_identity)
|
||||
|
||||
from analytical.utils import (
|
||||
disable_html,
|
||||
get_identity,
|
||||
get_required_setting,
|
||||
is_internal_ip,
|
||||
)
|
||||
|
||||
# domain name (characters separated by a dot), optional port, optional URI path, no slash
|
||||
DOMAINPATH_RE = re.compile(r'^(([^./?#@:]+\.)*[^./?#@:]+)+(:[0-9]+)?(/[^/?#@:]+)*$')
|
||||
DOMAINPATH_RE = re.compile(r"^(([^./?#@:]+\.)*[^./?#@:]+)+(:[0-9]+)?(/[^/?#@:]+)*$")
|
||||
|
||||
# numeric ID
|
||||
SITEID_RE = re.compile(r'^\d+$')
|
||||
SITEID_RE = re.compile(r"^\d+$")
|
||||
|
||||
TRACKING_CODE = """
|
||||
<script type="text/javascript">
|
||||
|
|
@ -39,11 +42,11 @@ TRACKING_CODE = """
|
|||
|
||||
VARIABLE_CODE = '_paq.push(["setCustomVariable", %(index)s, "%(name)s", "%(value)s", "%(scope)s"]);' # noqa
|
||||
IDENTITY_CODE = '_paq.push(["setUserId", "%(userid)s"]);'
|
||||
DISABLE_COOKIES_CODE = '_paq.push([\'disableCookies\']);'
|
||||
DISABLE_COOKIES_CODE = "_paq.push(['disableCookies']);"
|
||||
|
||||
DEFAULT_SCOPE = 'page'
|
||||
DEFAULT_SCOPE = "page"
|
||||
|
||||
MatomoVar = namedtuple('MatomoVar', ('index', 'name', 'value', 'scope'))
|
||||
MatomoVar = namedtuple("MatomoVar", ("index", "name", "value", "scope"))
|
||||
|
||||
|
||||
register = Library()
|
||||
|
|
@ -72,45 +75,49 @@ def matomo(parser, token):
|
|||
|
||||
class MatomoNode(Node):
|
||||
def __init__(self):
|
||||
self.domain_path = \
|
||||
get_required_setting('MATOMO_DOMAIN_PATH', DOMAINPATH_RE,
|
||||
"must be a domain name, optionally followed "
|
||||
"by an URI path, no trailing slash (e.g. "
|
||||
"matomo.example.com or my.matomo.server/path)")
|
||||
self.site_id = \
|
||||
get_required_setting('MATOMO_SITE_ID', SITEID_RE,
|
||||
"must be a (string containing a) number")
|
||||
self.domain_path = get_required_setting(
|
||||
"MATOMO_DOMAIN_PATH",
|
||||
DOMAINPATH_RE,
|
||||
"must be a domain name, optionally followed "
|
||||
"by an URI path, no trailing slash (e.g. "
|
||||
"matomo.example.com or my.matomo.server/path)",
|
||||
)
|
||||
self.site_id = get_required_setting(
|
||||
"MATOMO_SITE_ID", SITEID_RE, "must be a (string containing a) number"
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
custom_variables = context.get('matomo_vars', ())
|
||||
custom_variables = context.get("matomo_vars", ())
|
||||
|
||||
complete_variables = (var if len(var) >= 4 else var + (DEFAULT_SCOPE,)
|
||||
for var in custom_variables)
|
||||
complete_variables = (
|
||||
var if len(var) >= 4 else var + (DEFAULT_SCOPE,) for var in custom_variables
|
||||
)
|
||||
|
||||
variables_code = (VARIABLE_CODE % MatomoVar(*var)._asdict()
|
||||
for var in complete_variables)
|
||||
variables_code = (
|
||||
VARIABLE_CODE % MatomoVar(*var)._asdict() for var in complete_variables
|
||||
)
|
||||
|
||||
commands = []
|
||||
if getattr(settings, 'MATOMO_DISABLE_COOKIES', False):
|
||||
if getattr(settings, "MATOMO_DISABLE_COOKIES", False):
|
||||
commands.append(DISABLE_COOKIES_CODE)
|
||||
|
||||
userid = get_identity(context, 'matomo')
|
||||
userid = get_identity(context, "matomo")
|
||||
if userid is not None:
|
||||
variables_code = chain(variables_code, (
|
||||
IDENTITY_CODE % {'userid': userid},
|
||||
))
|
||||
variables_code = chain(
|
||||
variables_code, (IDENTITY_CODE % {"userid": userid},)
|
||||
)
|
||||
|
||||
html = TRACKING_CODE % {
|
||||
'url': self.domain_path,
|
||||
'siteid': self.site_id,
|
||||
'variables': '\n '.join(variables_code),
|
||||
'commands': '\n '.join(commands)
|
||||
"url": self.domain_path,
|
||||
"siteid": self.site_id,
|
||||
"variables": "\n ".join(variables_code),
|
||||
"commands": "\n ".join(commands),
|
||||
}
|
||||
if is_internal_ip(context, 'MATOMO'):
|
||||
html = disable_html(html, 'Matomo')
|
||||
if is_internal_ip(context, "MATOMO"):
|
||||
html = disable_html(html, "Matomo")
|
||||
return html
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
MatomoNode() # ensure properly configured
|
||||
add_node('body_bottom', MatomoNode)
|
||||
add_node("body_bottom", MatomoNode)
|
||||
|
|
|
|||
|
|
@ -8,11 +8,14 @@ import re
|
|||
from django.template import Library, Node, TemplateSyntaxError
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from analytical.utils import is_internal_ip, disable_html, get_identity, \
|
||||
get_required_setting
|
||||
from analytical.utils import (
|
||||
disable_html,
|
||||
get_identity,
|
||||
get_required_setting,
|
||||
is_internal_ip,
|
||||
)
|
||||
|
||||
|
||||
MIXPANEL_API_TOKEN_RE = re.compile(r'^[0-9a-f]{32}$')
|
||||
MIXPANEL_API_TOKEN_RE = re.compile(r"^[0-9a-f]{32}$")
|
||||
TRACKING_CODE = """
|
||||
<script type="text/javascript">(function(e,b){if(!b.__SV){var a,f,i,g;window.mixpanel=b;a=e.createElement("script");a.type="text/javascript";a.async=!0;a.src=("https:"===e.location.protocol?"https:":"http:")+'//cdn.mxpnl.com/libs/mixpanel-2.2.min.js';f=e.getElementsByTagName("script")[0];f.parentNode.insertBefore(a,f);b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!==
|
||||
typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.toString=function(b){var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.toString=function(){return c.toString(1)+".people (stub)"};i="disable track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config people.set people.increment people.append people.track_charge people.clear_charges people.delete_user".split(" ");for(g=0;g<i.length;g++)f(c,i[g]);b._i.push([a,
|
||||
|
|
@ -24,7 +27,7 @@ e,d])};b.__SV=1.2}})(document,window.mixpanel||[]);
|
|||
IDENTIFY_CODE = "mixpanel.identify('%s');"
|
||||
IDENTIFY_PROPERTIES = "mixpanel.people.set(%s);"
|
||||
EVENT_CODE = "mixpanel.track('%(name)s', %(properties)s);"
|
||||
EVENT_CONTEXT_KEY = 'mixpanel_event'
|
||||
EVENT_CONTEXT_KEY = "mixpanel_event"
|
||||
|
||||
register = Library()
|
||||
|
||||
|
|
@ -46,35 +49,44 @@ def mixpanel(parser, token):
|
|||
class MixpanelNode(Node):
|
||||
def __init__(self):
|
||||
self._token = get_required_setting(
|
||||
'MIXPANEL_API_TOKEN', MIXPANEL_API_TOKEN_RE,
|
||||
"must be a string containing a 32-digit hexadecimal number")
|
||||
"MIXPANEL_API_TOKEN",
|
||||
MIXPANEL_API_TOKEN_RE,
|
||||
"must be a string containing a 32-digit hexadecimal number",
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
commands = []
|
||||
identity = get_identity(context, 'mixpanel')
|
||||
identity = get_identity(context, "mixpanel")
|
||||
if identity is not None:
|
||||
if isinstance(identity, dict):
|
||||
commands.append(IDENTIFY_CODE % identity.get('id', identity.get('username')))
|
||||
commands.append(IDENTIFY_PROPERTIES % json.dumps(identity, sort_keys=True))
|
||||
commands.append(
|
||||
IDENTIFY_CODE % identity.get("id", identity.get("username"))
|
||||
)
|
||||
commands.append(
|
||||
IDENTIFY_PROPERTIES % json.dumps(identity, sort_keys=True)
|
||||
)
|
||||
else:
|
||||
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),
|
||||
"token": self._token,
|
||||
"commands": " ".join(commands),
|
||||
}
|
||||
if is_internal_ip(context, 'MIXPANEL'):
|
||||
html = disable_html(html, 'Mixpanel')
|
||||
if is_internal_ip(context, "MIXPANEL"):
|
||||
html = disable_html(html, "Mixpanel")
|
||||
return mark_safe(html)
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
MixpanelNode() # ensure properly configured
|
||||
add_node('head_bottom', MixpanelNode)
|
||||
add_node("head_bottom", MixpanelNode)
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ from django.template import Library, Node, TemplateSyntaxError
|
|||
|
||||
from analytical.utils import get_identity, get_required_setting
|
||||
|
||||
|
||||
SITE_ID_RE = re.compile(r'^\d+-\d+-\d+-\d+$')
|
||||
SITE_ID_RE = re.compile(r"^\d+-\d+-\d+-\d+$")
|
||||
SETUP_CODE = """
|
||||
<script type='text/javascript'>
|
||||
/*{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}*/
|
||||
|
|
@ -18,23 +17,36 @@ SETUP_CODE = """
|
|||
</script>
|
||||
""" # noqa
|
||||
NICKNAME_CODE = "olark('api.chat.updateVisitorNickname', {snippet: '%s'});"
|
||||
NICKNAME_CONTEXT_KEY = 'olark_nickname'
|
||||
NICKNAME_CONTEXT_KEY = "olark_nickname"
|
||||
FULLNAME_CODE = "olark('api.visitor.updateFullName', {{fullName: '{0}'}});"
|
||||
FULLNAME_CONTEXT_KEY = 'olark_fullname'
|
||||
FULLNAME_CONTEXT_KEY = "olark_fullname"
|
||||
EMAIL_CODE = "olark('api.visitor.updateEmailAddress', {{emailAddress: '{0}'}});"
|
||||
EMAIL_CONTEXT_KEY = 'olark_email'
|
||||
EMAIL_CONTEXT_KEY = "olark_email"
|
||||
STATUS_CODE = "olark('api.chat.updateVisitorStatus', {snippet: %s});"
|
||||
STATUS_CONTEXT_KEY = 'olark_status'
|
||||
STATUS_CONTEXT_KEY = "olark_status"
|
||||
MESSAGE_CODE = "olark.configure('locale.%(key)s', \"%(msg)s\");"
|
||||
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",
|
||||
"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()
|
||||
|
|
@ -57,15 +69,17 @@ 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'")
|
||||
"OLARK_SITE_ID",
|
||||
SITE_ID_RE,
|
||||
"must be a string looking like 'XXXX-XXX-XX-XXXX'",
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
extra_code = []
|
||||
try:
|
||||
extra_code.append(NICKNAME_CODE % context[NICKNAME_CONTEXT_KEY])
|
||||
except KeyError:
|
||||
identity = get_identity(context, 'olark', self._get_nickname)
|
||||
identity = get_identity(context, "olark", self._get_nickname)
|
||||
if identity is not None:
|
||||
extra_code.append(NICKNAME_CODE % identity)
|
||||
try:
|
||||
|
|
@ -77,14 +91,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),
|
||||
"site_id": self.site_id,
|
||||
"extra_code": " ".join(extra_code),
|
||||
}
|
||||
return html
|
||||
|
||||
|
|
@ -99,13 +114,13 @@ class OlarkNode(Node):
|
|||
code = []
|
||||
for dict_ in context:
|
||||
for var, val in dict_.items():
|
||||
if var.startswith('olark_'):
|
||||
if var.startswith("olark_"):
|
||||
key = var[6:]
|
||||
if key in MESSAGE_KEYS:
|
||||
code.append(MESSAGE_CODE % {'key': key, 'msg': val})
|
||||
code.append(MESSAGE_CODE % {"key": key, "msg": val})
|
||||
return code
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
OlarkNode() # ensure properly configured
|
||||
add_node('body_bottom', OlarkNode)
|
||||
add_node("body_bottom", OlarkNode)
|
||||
|
|
|
|||
|
|
@ -6,10 +6,9 @@ import re
|
|||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import is_internal_ip, disable_html, get_required_setting
|
||||
from analytical.utils import disable_html, get_required_setting, is_internal_ip
|
||||
|
||||
|
||||
ACCOUNT_NUMBER_RE = re.compile(r'^\d+$')
|
||||
ACCOUNT_NUMBER_RE = re.compile(r"^\d+$")
|
||||
SETUP_CODE = """<script src="//cdn.optimizely.com/js/%(account_number)s.js"></script>"""
|
||||
|
||||
|
||||
|
|
@ -34,16 +33,18 @@ def optimizely(parser, token):
|
|||
class OptimizelyNode(Node):
|
||||
def __init__(self):
|
||||
self.account_number = get_required_setting(
|
||||
'OPTIMIZELY_ACCOUNT_NUMBER', ACCOUNT_NUMBER_RE,
|
||||
"must be a string looking like 'XXXXXXX'")
|
||||
"OPTIMIZELY_ACCOUNT_NUMBER",
|
||||
ACCOUNT_NUMBER_RE,
|
||||
"must be a string looking like 'XXXXXXX'",
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
html = SETUP_CODE % {'account_number': self.account_number}
|
||||
if is_internal_ip(context, 'OPTIMIZELY'):
|
||||
html = disable_html(html, 'Optimizely')
|
||||
html = SETUP_CODE % {"account_number": self.account_number}
|
||||
if is_internal_ip(context, "OPTIMIZELY"):
|
||||
html = disable_html(html, "Optimizely")
|
||||
return html
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
OptimizelyNode() # ensure properly configured
|
||||
add_node('head_top', OptimizelyNode)
|
||||
add_node("head_top", OptimizelyNode)
|
||||
|
|
|
|||
|
|
@ -7,11 +7,14 @@ import re
|
|||
from django.template import Library, Node, TemplateSyntaxError
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from analytical.utils import is_internal_ip, disable_html, get_identity, \
|
||||
get_required_setting
|
||||
from analytical.utils import (
|
||||
disable_html,
|
||||
get_identity,
|
||||
get_required_setting,
|
||||
is_internal_ip,
|
||||
)
|
||||
|
||||
|
||||
API_KEY_RE = re.compile(r'^\w+$')
|
||||
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
|
||||
|
|
@ -53,16 +56,16 @@ 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'")
|
||||
"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}
|
||||
identity = get_identity(context, 'performable')
|
||||
html = SETUP_CODE % {"api_key": self.api_key}
|
||||
identity = get_identity(context, "performable")
|
||||
if identity is not None:
|
||||
html = "%s%s" % (IDENTIFY_CODE % identity, html)
|
||||
if is_internal_ip(context, 'PERFORMABLE'):
|
||||
html = disable_html(html, 'Performable')
|
||||
if is_internal_ip(context, "PERFORMABLE"):
|
||||
html = disable_html(html, "Performable")
|
||||
return html
|
||||
|
||||
|
||||
|
|
@ -71,12 +74,15 @@ 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):
|
||||
PerformableNode() # ensure properly configured
|
||||
add_node('body_bottom', PerformableNode)
|
||||
add_node("body_bottom", PerformableNode)
|
||||
|
|
|
|||
|
|
@ -2,23 +2,26 @@
|
|||
Piwik template tags and filters.
|
||||
"""
|
||||
|
||||
import re
|
||||
import warnings
|
||||
from collections import namedtuple
|
||||
from itertools import chain
|
||||
import re
|
||||
|
||||
from django.conf import settings
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import (is_internal_ip, disable_html,
|
||||
get_required_setting, get_identity)
|
||||
|
||||
import warnings
|
||||
from analytical.utils import (
|
||||
disable_html,
|
||||
get_identity,
|
||||
get_required_setting,
|
||||
is_internal_ip,
|
||||
)
|
||||
|
||||
# domain name (characters separated by a dot), optional port, optional URI path, no slash
|
||||
DOMAINPATH_RE = re.compile(r'^(([^./?#@:]+\.)*[^./?#@:]+)+(:[0-9]+)?(/[^/?#@:]+)*$')
|
||||
DOMAINPATH_RE = re.compile(r"^(([^./?#@:]+\.)*[^./?#@:]+)+(:[0-9]+)?(/[^/?#@:]+)*$")
|
||||
|
||||
# numeric ID
|
||||
SITEID_RE = re.compile(r'^\d+$')
|
||||
SITEID_RE = re.compile(r"^\d+$")
|
||||
|
||||
TRACKING_CODE = """
|
||||
<script type="text/javascript">
|
||||
|
|
@ -40,11 +43,11 @@ TRACKING_CODE = """
|
|||
|
||||
VARIABLE_CODE = '_paq.push(["setCustomVariable", %(index)s, "%(name)s", "%(value)s", "%(scope)s"]);' # noqa
|
||||
IDENTITY_CODE = '_paq.push(["setUserId", "%(userid)s"]);'
|
||||
DISABLE_COOKIES_CODE = '_paq.push([\'disableCookies\']);'
|
||||
DISABLE_COOKIES_CODE = "_paq.push(['disableCookies']);"
|
||||
|
||||
DEFAULT_SCOPE = 'page'
|
||||
DEFAULT_SCOPE = "page"
|
||||
|
||||
PiwikVar = namedtuple('PiwikVar', ('index', 'name', 'value', 'scope'))
|
||||
PiwikVar = namedtuple("PiwikVar", ("index", "name", "value", "scope"))
|
||||
|
||||
|
||||
register = Library()
|
||||
|
|
@ -65,7 +68,9 @@ def piwik(parser, token):
|
|||
(default) or ``'visit'``. Index should be an integer and the
|
||||
other parameters should be strings.
|
||||
"""
|
||||
warnings.warn('The Piwik module is deprecated; use the Matomo module.', DeprecationWarning)
|
||||
warnings.warn(
|
||||
"The Piwik module is deprecated; use the Matomo module.", DeprecationWarning
|
||||
)
|
||||
bits = token.split_contents()
|
||||
if len(bits) > 1:
|
||||
raise TemplateSyntaxError("'%s' takes no arguments" % bits[0])
|
||||
|
|
@ -74,45 +79,49 @@ def piwik(parser, token):
|
|||
|
||||
class PiwikNode(Node):
|
||||
def __init__(self):
|
||||
self.domain_path = \
|
||||
get_required_setting('PIWIK_DOMAIN_PATH', DOMAINPATH_RE,
|
||||
"must be a domain name, optionally followed "
|
||||
"by an URI path, no trailing slash (e.g. "
|
||||
"piwik.example.com or my.piwik.server/path)")
|
||||
self.site_id = \
|
||||
get_required_setting('PIWIK_SITE_ID', SITEID_RE,
|
||||
"must be a (string containing a) number")
|
||||
self.domain_path = get_required_setting(
|
||||
"PIWIK_DOMAIN_PATH",
|
||||
DOMAINPATH_RE,
|
||||
"must be a domain name, optionally followed "
|
||||
"by an URI path, no trailing slash (e.g. "
|
||||
"piwik.example.com or my.piwik.server/path)",
|
||||
)
|
||||
self.site_id = get_required_setting(
|
||||
"PIWIK_SITE_ID", SITEID_RE, "must be a (string containing a) number"
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
custom_variables = context.get('piwik_vars', ())
|
||||
custom_variables = context.get("piwik_vars", ())
|
||||
|
||||
complete_variables = (var if len(var) >= 4 else var + (DEFAULT_SCOPE,)
|
||||
for var in custom_variables)
|
||||
complete_variables = (
|
||||
var if len(var) >= 4 else var + (DEFAULT_SCOPE,) for var in custom_variables
|
||||
)
|
||||
|
||||
variables_code = (VARIABLE_CODE % PiwikVar(*var)._asdict()
|
||||
for var in complete_variables)
|
||||
variables_code = (
|
||||
VARIABLE_CODE % PiwikVar(*var)._asdict() for var in complete_variables
|
||||
)
|
||||
|
||||
commands = []
|
||||
if getattr(settings, 'PIWIK_DISABLE_COOKIES', False):
|
||||
if getattr(settings, "PIWIK_DISABLE_COOKIES", False):
|
||||
commands.append(DISABLE_COOKIES_CODE)
|
||||
|
||||
userid = get_identity(context, 'piwik')
|
||||
userid = get_identity(context, "piwik")
|
||||
if userid is not None:
|
||||
variables_code = chain(variables_code, (
|
||||
IDENTITY_CODE % {'userid': userid},
|
||||
))
|
||||
variables_code = chain(
|
||||
variables_code, (IDENTITY_CODE % {"userid": userid},)
|
||||
)
|
||||
|
||||
html = TRACKING_CODE % {
|
||||
'url': self.domain_path,
|
||||
'siteid': self.site_id,
|
||||
'variables': '\n '.join(variables_code),
|
||||
'commands': '\n '.join(commands)
|
||||
"url": self.domain_path,
|
||||
"siteid": self.site_id,
|
||||
"variables": "\n ".join(variables_code),
|
||||
"commands": "\n ".join(commands),
|
||||
}
|
||||
if is_internal_ip(context, 'PIWIK'):
|
||||
html = disable_html(html, 'Piwik')
|
||||
if is_internal_ip(context, "PIWIK"):
|
||||
html = disable_html(html, "Piwik")
|
||||
return html
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
PiwikNode() # ensure properly configured
|
||||
add_node('body_bottom', PiwikNode)
|
||||
add_node("body_bottom", PiwikNode)
|
||||
|
|
|
|||
|
|
@ -6,11 +6,9 @@ import re
|
|||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import is_internal_ip, disable_html, \
|
||||
get_required_setting
|
||||
from analytical.utils import disable_html, get_required_setting, is_internal_ip
|
||||
|
||||
|
||||
COUNTER_ID_RE = re.compile(r'^\d{7}$')
|
||||
COUNTER_ID_RE = re.compile(r"^\d{7}$")
|
||||
COUNTER_CODE = """
|
||||
<script type="text/javascript">
|
||||
var _tmr = window._tmr || (window._tmr = []);
|
||||
|
|
@ -50,18 +48,20 @@ 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 % {
|
||||
'counter_id': self.counter_id,
|
||||
"counter_id": self.counter_id,
|
||||
}
|
||||
if is_internal_ip(context, 'RATING_MAILRU_METRICA'):
|
||||
html = disable_html(html, 'Rating@Mail.ru')
|
||||
if is_internal_ip(context, "RATING_MAILRU_METRICA"):
|
||||
html = disable_html(html, "Rating@Mail.ru")
|
||||
return html
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
RatingMailruNode() # ensure properly configured
|
||||
add_node('head_bottom', RatingMailruNode)
|
||||
add_node("head_bottom", RatingMailruNode)
|
||||
|
|
|
|||
|
|
@ -19,12 +19,14 @@ BUTTON_STYLE_NONE = 0
|
|||
BUTTON_STYLE_DEFAULT = 1
|
||||
BUTTON_STYLE_LIVE = 2
|
||||
|
||||
FORM_POSITION_TOP_LEFT = 'tl'
|
||||
FORM_POSITION_TOP_RIGHT = 'tr'
|
||||
FORM_POSITION_BOTTOM_LEFT = 'bl'
|
||||
FORM_POSITION_BOTTOM_RIGHT = 'br'
|
||||
FORM_POSITION_TOP_LEFT = "tl"
|
||||
FORM_POSITION_TOP_RIGHT = "tr"
|
||||
FORM_POSITION_BOTTOM_LEFT = "bl"
|
||||
FORM_POSITION_BOTTOM_RIGHT = "br"
|
||||
|
||||
WIDGET_ID_RE = re.compile(r'^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$')
|
||||
WIDGET_ID_RE = re.compile(
|
||||
r"^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$"
|
||||
)
|
||||
SETUP_CODE = """
|
||||
<script type="text/javascript">
|
||||
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">
|
||||
|
|
@ -32,20 +34,22 @@ SETUP_CODE = """
|
|||
</script>
|
||||
""" # noqa
|
||||
DOMAIN_CODE = 'SnapABug.setDomain("%s");'
|
||||
SECURE_CONNECTION_CODE = 'SnapABug.setSecureConnexion();'
|
||||
SECURE_CONNECTION_CODE = "SnapABug.setSecureConnexion();"
|
||||
INIT_CODE = 'SnapABug.init("%s");'
|
||||
ADDBUTTON_CODE = 'SnapABug.addButton("%(id)s","%(location)s","%(offset)s"%(dynamic_tail)s);'
|
||||
ADDBUTTON_CODE = (
|
||||
'SnapABug.addButton("%(id)s","%(location)s","%(offset)s"%(dynamic_tail)s);'
|
||||
)
|
||||
SETBUTTON_CODE = 'SnapABug.setButton("%s");'
|
||||
SETEMAIL_CODE = 'SnapABug.setUserEmail("%s"%s);'
|
||||
SETLOCALE_CODE = 'SnapABug.setLocale("%s");'
|
||||
FORM_POSITION_CODE = 'SnapABug.setChatFormPosition("%s");'
|
||||
FORM_TOP_POSITION_CODE = 'SnapABug.setFormTopPosition(%d);'
|
||||
FORM_TOP_POSITION_CODE = "SnapABug.setFormTopPosition(%d);"
|
||||
BUTTONEFFECT_CODE = 'SnapABug.setButtonEffect("%s");'
|
||||
DISABLE_OFFLINE_CODE = 'SnapABug.allowOffline(false);'
|
||||
DISABLE_SCREENSHOT_CODE = 'SnapABug.allowScreenshot(false);'
|
||||
DISABLE_OFFLINE_SCREENSHOT_CODE = 'SnapABug.showScreenshotOption(false);'
|
||||
DISABLE_PROACTIVE_CHAT_CODE = 'SnapABug.allowProactiveChat(false);'
|
||||
DISABLE_SOUNDS_CODE = 'SnapABug.allowChatSound(false);'
|
||||
DISABLE_OFFLINE_CODE = "SnapABug.allowOffline(false);"
|
||||
DISABLE_SCREENSHOT_CODE = "SnapABug.allowScreenshot(false);"
|
||||
DISABLE_OFFLINE_SCREENSHOT_CODE = "SnapABug.showScreenshotOption(false);"
|
||||
DISABLE_PROACTIVE_CHAT_CODE = "SnapABug.allowProactiveChat(false);"
|
||||
DISABLE_SOUNDS_CODE = "SnapABug.allowChatSound(false);"
|
||||
|
||||
register = Library()
|
||||
|
||||
|
|
@ -67,83 +71,95 @@ 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'")
|
||||
"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')
|
||||
domain = self._get_setting(context, "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)
|
||||
secure_connection = self._get_setting(
|
||||
context,
|
||||
"snapengage_secure_connection",
|
||||
"SNAPENGAGE_SECURE_CONNECTION",
|
||||
False,
|
||||
)
|
||||
if secure_connection:
|
||||
settings_code.append(SECURE_CONNECTION_CODE)
|
||||
|
||||
email = context.get('snapengage_email')
|
||||
email = context.get("snapengage_email")
|
||||
if email is None:
|
||||
email = get_identity(context, 'snapengage', lambda u: u.email)
|
||||
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):
|
||||
readonly_tail = ',true'
|
||||
if self._get_setting(
|
||||
context, "snapengage_readonly_email", "SNAPENGAGE_READONLY_EMAIL", False
|
||||
):
|
||||
readonly_tail = ",true"
|
||||
else:
|
||||
readonly_tail = ''
|
||||
readonly_tail = ""
|
||||
settings_code.append(SETEMAIL_CODE % (email, readonly_tail))
|
||||
|
||||
locale = self._get_setting(context, 'snapengage_locale',
|
||||
'SNAPENGAGE_LOCALE')
|
||||
locale = self._get_setting(context, "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')
|
||||
form_position = self._get_setting(
|
||||
context, "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')
|
||||
form_top_position = self._get_setting(
|
||||
context, "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)
|
||||
show_offline = self._get_setting(
|
||||
context, "snapengage_show_offline", "SNAPENGAGE_SHOW_OFFLINE", True
|
||||
)
|
||||
if not show_offline:
|
||||
settings_code.append(DISABLE_OFFLINE_CODE)
|
||||
|
||||
screenshots = self._get_setting(context, 'snapengage_screenshots',
|
||||
'SNAPENGAGE_SCREENSHOTS', True)
|
||||
screenshots = self._get_setting(
|
||||
context, "snapengage_screenshots", "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)
|
||||
offline_screenshots = self._get_setting(
|
||||
context,
|
||||
"snapengage_offline_screenshots",
|
||||
"SNAPENGAGE_OFFLINE_SCREENSHOTS",
|
||||
True,
|
||||
)
|
||||
if not offline_screenshots:
|
||||
settings_code.append(DISABLE_OFFLINE_SCREENSHOT_CODE)
|
||||
|
||||
if not context.get('snapengage_proactive_chat', True):
|
||||
if not context.get("snapengage_proactive_chat", True):
|
||||
settings_code.append(DISABLE_PROACTIVE_CHAT_CODE)
|
||||
|
||||
sounds = self._get_setting(context, 'snapengage_sounds',
|
||||
'SNAPENGAGE_SOUNDS', True)
|
||||
sounds = self._get_setting(
|
||||
context, "snapengage_sounds", "SNAPENGAGE_SOUNDS", True
|
||||
)
|
||||
if not sounds:
|
||||
settings_code.append(DISABLE_SOUNDS_CODE)
|
||||
|
||||
button_effect = self._get_setting(context, 'snapengage_button_effect',
|
||||
'SNAPENGAGE_BUTTON_EFFECT')
|
||||
button_effect = self._get_setting(
|
||||
context, "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)
|
||||
button = self._get_setting(
|
||||
context, "snapengage_button", "SNAPENGAGE_BUTTON", BUTTON_STYLE_DEFAULT
|
||||
)
|
||||
if button == BUTTON_STYLE_NONE:
|
||||
settings_code.append(INIT_CODE % self.widget_id)
|
||||
else:
|
||||
|
|
@ -152,21 +168,28 @@ class SnapEngageNode(Node):
|
|||
settings_code.append(SETBUTTON_CODE % button)
|
||||
button_location = self._get_setting(
|
||||
context,
|
||||
'snapengage_button_location', 'SNAPENGAGE_BUTTON_LOCATION',
|
||||
BUTTON_LOCATION_LEFT)
|
||||
"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 '',
|
||||
})
|
||||
"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),
|
||||
"widget_id": self.widget_id,
|
||||
"settings_code": " ".join(settings_code),
|
||||
}
|
||||
return html
|
||||
|
||||
|
|
@ -182,4 +205,4 @@ class SnapEngageNode(Node):
|
|||
|
||||
def contribute_to_analytical(add_node):
|
||||
SnapEngageNode() # ensure properly configured
|
||||
add_node('body_bottom', SnapEngageNode)
|
||||
add_node("body_bottom", SnapEngageNode)
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@ import re
|
|||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import get_identity, is_internal_ip, disable_html, \
|
||||
get_required_setting
|
||||
from analytical.utils import (
|
||||
disable_html,
|
||||
get_identity,
|
||||
get_required_setting,
|
||||
is_internal_ip,
|
||||
)
|
||||
|
||||
|
||||
TRACKING_ID_RE = re.compile(r'^[0-9a-f]+$')
|
||||
TRACKING_ID_RE = re.compile(r"^[0-9a-f]+$")
|
||||
TRACKING_CODE = """
|
||||
<script type='text/javascript'>
|
||||
var _springMetq = _springMetq || [];
|
||||
|
|
@ -50,39 +53,40 @@ def spring_metrics(parser, token):
|
|||
class SpringMetricsNode(Node):
|
||||
def __init__(self):
|
||||
self.tracking_id = get_required_setting(
|
||||
'SPRING_METRICS_TRACKING_ID',
|
||||
TRACKING_ID_RE, "must be a hexadecimal string")
|
||||
"SPRING_METRICS_TRACKING_ID", TRACKING_ID_RE, "must be a hexadecimal string"
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
custom = {}
|
||||
for dict_ in context:
|
||||
for var, val in dict_.items():
|
||||
if var.startswith('spring_metrics_'):
|
||||
if var.startswith("spring_metrics_"):
|
||||
custom[var[15:]] = val
|
||||
if 'email' not in custom:
|
||||
identity = get_identity(context, 'spring_metrics',
|
||||
lambda u: u.email)
|
||||
if "email" not in custom:
|
||||
identity = get_identity(context, "spring_metrics", lambda u: u.email)
|
||||
if identity is not None:
|
||||
custom['email'] = identity
|
||||
custom["email"] = identity
|
||||
|
||||
html = TRACKING_CODE % {
|
||||
'tracking_id': self.tracking_id,
|
||||
'custom_commands': self._generate_custom_javascript(custom),
|
||||
"tracking_id": self.tracking_id,
|
||||
"custom_commands": self._generate_custom_javascript(custom),
|
||||
}
|
||||
if is_internal_ip(context, 'SPRING_METRICS'):
|
||||
html = disable_html(html, 'Spring Metrics')
|
||||
if is_internal_ip(context, "SPRING_METRICS"):
|
||||
html = disable_html(html, "Spring Metrics")
|
||||
return html
|
||||
|
||||
def _generate_custom_javascript(self, params):
|
||||
commands = []
|
||||
convert = params.pop('convert', None)
|
||||
convert = params.pop("convert", None)
|
||||
if convert is not None:
|
||||
commands.append("_springMetq.push(['convert', '%s'])" % convert)
|
||||
commands.extend("_springMetq.push(['setdata', {'%s': '%s'}]);"
|
||||
% (var, val) for var, val in params.items())
|
||||
commands.extend(
|
||||
"_springMetq.push(['setdata', {'%s': '%s'}]);" % (var, val)
|
||||
for var, val in params.items()
|
||||
)
|
||||
return " ".join(commands)
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
SpringMetricsNode() # ensure properly configured
|
||||
add_node('head_bottom', SpringMetricsNode)
|
||||
add_node("head_bottom", SpringMetricsNode)
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ import re
|
|||
|
||||
from django.conf import settings
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
from analytical.utils import get_required_setting, get_identity
|
||||
|
||||
from analytical.utils import get_identity, get_required_setting
|
||||
|
||||
WIDGET_KEY_RE = re.compile(r'^[a-zA-Z0-9]*$')
|
||||
WIDGET_KEY_RE = re.compile(r"^[a-zA-Z0-9]*$")
|
||||
TRACKING_CODE = """
|
||||
<script type="text/javascript">
|
||||
|
||||
|
|
@ -48,39 +48,43 @@ 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")
|
||||
"USERVOICE_WIDGET_KEY", WIDGET_KEY_RE, "must be an alphanumeric string"
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
widget_key = context.get('uservoice_widget_key')
|
||||
widget_key = context.get("uservoice_widget_key")
|
||||
if not widget_key:
|
||||
widget_key = self.default_widget_key
|
||||
if not widget_key:
|
||||
return ''
|
||||
return ""
|
||||
# default
|
||||
options = {}
|
||||
options.update(getattr(settings, 'USERVOICE_WIDGET_OPTIONS', {}))
|
||||
options.update(context.get('uservoice_widget_options', {}))
|
||||
options.update(getattr(settings, "USERVOICE_WIDGET_OPTIONS", {}))
|
||||
options.update(context.get("uservoice_widget_options", {}))
|
||||
|
||||
identity = get_identity(context, 'uservoice', self._identify)
|
||||
identity = get_identity(context, "uservoice", self._identify)
|
||||
if identity:
|
||||
identity = IDENTITY % {'options': json.dumps(identity, sort_keys=True)}
|
||||
identity = IDENTITY % {"options": json.dumps(identity, sort_keys=True)}
|
||||
|
||||
trigger = context.get('uservoice_add_trigger',
|
||||
getattr(settings, 'USERVOICE_ADD_TRIGGER', True))
|
||||
trigger = context.get(
|
||||
"uservoice_add_trigger", getattr(settings, "USERVOICE_ADD_TRIGGER", True)
|
||||
)
|
||||
|
||||
html = TRACKING_CODE % {'widget_key': widget_key,
|
||||
'options': json.dumps(options, sort_keys=True),
|
||||
'trigger': TRIGGER if trigger else '',
|
||||
'identity': identity if identity else ''}
|
||||
html = TRACKING_CODE % {
|
||||
"widget_key": widget_key,
|
||||
"options": json.dumps(options, sort_keys=True),
|
||||
"trigger": TRIGGER if trigger else "",
|
||||
"identity": identity if identity else "",
|
||||
}
|
||||
return html
|
||||
|
||||
def _identify(self, user):
|
||||
name = user.get_full_name()
|
||||
if not name:
|
||||
name = user.username
|
||||
return {'name': name, 'email': user.email}
|
||||
return {"name": name, "email": user.email}
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
UserVoiceNode() # ensure properly configured
|
||||
add_node('body_bottom', UserVoiceNode)
|
||||
add_node("body_bottom", UserVoiceNode)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ from analytical.utils import (
|
|||
is_internal_ip,
|
||||
)
|
||||
|
||||
DOMAIN_RE = re.compile(r'^\S+$')
|
||||
DOMAIN_RE = re.compile(r"^\S+$")
|
||||
TRACKING_CODE = """
|
||||
<script type="text/javascript">
|
||||
var woo_settings = %(settings)s;
|
||||
|
|
@ -49,25 +49,25 @@ def woopra(parser, token):
|
|||
class WoopraNode(Node):
|
||||
def __init__(self):
|
||||
self.domain = get_required_setting(
|
||||
'WOOPRA_DOMAIN', DOMAIN_RE,
|
||||
"must be a domain name")
|
||||
"WOOPRA_DOMAIN", DOMAIN_RE, "must be a domain name"
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
settings = self._get_settings(context)
|
||||
visitor = self._get_visitor(context)
|
||||
|
||||
html = TRACKING_CODE % {
|
||||
'settings': json.dumps(settings, sort_keys=True),
|
||||
'visitor': json.dumps(visitor, sort_keys=True),
|
||||
"settings": json.dumps(settings, sort_keys=True),
|
||||
"visitor": json.dumps(visitor, sort_keys=True),
|
||||
}
|
||||
if is_internal_ip(context, 'WOOPRA'):
|
||||
html = disable_html(html, 'Woopra')
|
||||
if is_internal_ip(context, "WOOPRA"):
|
||||
html = disable_html(html, "Woopra")
|
||||
return html
|
||||
|
||||
def _get_settings(self, context):
|
||||
variables = {'domain': self.domain}
|
||||
variables = {"domain": self.domain}
|
||||
try:
|
||||
variables['idle_timeout'] = str(settings.WOOPRA_IDLE_TIMEOUT)
|
||||
variables["idle_timeout"] = str(settings.WOOPRA_IDLE_TIMEOUT)
|
||||
except AttributeError:
|
||||
pass
|
||||
return variables
|
||||
|
|
@ -76,15 +76,14 @@ class WoopraNode(Node):
|
|||
params = {}
|
||||
for dict_ in context:
|
||||
for var, val in dict_.items():
|
||||
if var.startswith('woopra_'):
|
||||
if var.startswith("woopra_"):
|
||||
params[var[7:]] = val
|
||||
if 'name' not in params and 'email' not in params:
|
||||
if "name" not in params and "email" not in params:
|
||||
user = get_user_from_context(context)
|
||||
if user is not None and get_user_is_authenticated(user):
|
||||
params['name'] = get_identity(
|
||||
context, 'woopra', self._identify, user)
|
||||
params["name"] = get_identity(context, "woopra", self._identify, user)
|
||||
if user.email:
|
||||
params['email'] = user.email
|
||||
params["email"] = user.email
|
||||
return params
|
||||
|
||||
def _identify(self, user):
|
||||
|
|
@ -96,4 +95,4 @@ class WoopraNode(Node):
|
|||
|
||||
def contribute_to_analytical(add_node):
|
||||
WoopraNode() # ensure properly configured
|
||||
add_node('head_bottom', WoopraNode)
|
||||
add_node("head_bottom", WoopraNode)
|
||||
|
|
|
|||
|
|
@ -8,11 +8,9 @@ import re
|
|||
from django.conf import settings
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from analytical.utils import is_internal_ip, disable_html, \
|
||||
get_required_setting
|
||||
from analytical.utils import disable_html, get_required_setting, is_internal_ip
|
||||
|
||||
|
||||
COUNTER_ID_RE = re.compile(r'^\d{8}$')
|
||||
COUNTER_ID_RE = re.compile(r"^\d{8}$")
|
||||
COUNTER_CODE = """
|
||||
<script type="text/javascript">
|
||||
(function (d, w, c) {
|
||||
|
|
@ -59,33 +57,35 @@ def yandex_metrica(parser, token):
|
|||
class YandexMetricaNode(Node):
|
||||
def __init__(self):
|
||||
self.counter_id = get_required_setting(
|
||||
'YANDEX_METRICA_COUNTER_ID', COUNTER_ID_RE,
|
||||
"must be (a string containing) a number'")
|
||||
"YANDEX_METRICA_COUNTER_ID",
|
||||
COUNTER_ID_RE,
|
||||
"must be (a string containing) a number'",
|
||||
)
|
||||
|
||||
def render(self, context):
|
||||
options = {
|
||||
'id': int(self.counter_id),
|
||||
'clickmap': True,
|
||||
'trackLinks': True,
|
||||
'accurateTrackBounce': True
|
||||
"id": int(self.counter_id),
|
||||
"clickmap": True,
|
||||
"trackLinks": True,
|
||||
"accurateTrackBounce": True,
|
||||
}
|
||||
if getattr(settings, 'YANDEX_METRICA_WEBVISOR', False):
|
||||
options['webvisor'] = True
|
||||
if getattr(settings, 'YANDEX_METRICA_TRACKHASH', False):
|
||||
options['trackHash'] = True
|
||||
if getattr(settings, 'YANDEX_METRICA_NOINDEX', False):
|
||||
options['ut'] = 'noindex'
|
||||
if getattr(settings, 'YANDEX_METRICA_ECOMMERCE', False):
|
||||
options['ecommerce'] = 'dataLayer'
|
||||
if getattr(settings, "YANDEX_METRICA_WEBVISOR", False):
|
||||
options["webvisor"] = True
|
||||
if getattr(settings, "YANDEX_METRICA_TRACKHASH", False):
|
||||
options["trackHash"] = True
|
||||
if getattr(settings, "YANDEX_METRICA_NOINDEX", False):
|
||||
options["ut"] = "noindex"
|
||||
if getattr(settings, "YANDEX_METRICA_ECOMMERCE", False):
|
||||
options["ecommerce"] = "dataLayer"
|
||||
html = COUNTER_CODE % {
|
||||
'counter_id': self.counter_id,
|
||||
'options': json.dumps(options),
|
||||
"counter_id": self.counter_id,
|
||||
"options": json.dumps(options),
|
||||
}
|
||||
if is_internal_ip(context, 'YANDEX_METRICA'):
|
||||
html = disable_html(html, 'Yandex.Metrica')
|
||||
if is_internal_ip(context, "YANDEX_METRICA"):
|
||||
html = disable_html(html, "Yandex.Metrica")
|
||||
return html
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
YandexMetricaNode() # ensure properly configured
|
||||
add_node('head_bottom', YandexMetricaNode)
|
||||
add_node("head_bottom", YandexMetricaNode)
|
||||
|
|
|
|||
|
|
@ -5,9 +5,7 @@ Utility function for django-analytical.
|
|||
from django.conf import settings
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
||||
|
||||
HTML_COMMENT = "<!-- %(service)s disabled on internal IP " \
|
||||
"address\n%(html)s\n-->"
|
||||
HTML_COMMENT = "<!-- %(service)s disabled on internal IP " "address\n%(html)s\n-->"
|
||||
|
||||
|
||||
def get_required_setting(setting, value_re, invalid_msg):
|
||||
|
|
@ -25,8 +23,9 @@ def get_required_setting(setting, value_re, invalid_msg):
|
|||
raise AnalyticalException("%s setting is not set" % setting)
|
||||
value = str(value)
|
||||
if not value_re.search(value):
|
||||
raise AnalyticalException("%s setting: %s: '%s'"
|
||||
% (setting, invalid_msg, value))
|
||||
raise AnalyticalException(
|
||||
"%s setting: %s: '%s'" % (setting, invalid_msg, value)
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
|
|
@ -38,11 +37,11 @@ def get_user_from_context(context):
|
|||
`None` is returned.
|
||||
"""
|
||||
try:
|
||||
return context['user']
|
||||
return context["user"]
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
request = context['request']
|
||||
request = context["request"]
|
||||
return request.user
|
||||
except (KeyError, AttributeError):
|
||||
pass
|
||||
|
|
@ -73,14 +72,14 @@ def get_identity(context, prefix=None, identity_func=None, user=None):
|
|||
"""
|
||||
if prefix is not None:
|
||||
try:
|
||||
return context['%s_identity' % prefix]
|
||||
return context["%s_identity" % prefix]
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
return context['analytical_identity']
|
||||
return context["analytical_identity"]
|
||||
except KeyError:
|
||||
pass
|
||||
if getattr(settings, 'ANALYTICAL_AUTO_IDENTIFY', True):
|
||||
if getattr(settings, "ANALYTICAL_AUTO_IDENTIFY", True):
|
||||
try:
|
||||
if user is None:
|
||||
user = get_user_from_context(context)
|
||||
|
|
@ -103,16 +102,17 @@ def get_domain(context, prefix):
|
|||
If no explicit domain is found in either the context or the
|
||||
settings, try to get the domain from the contrib sites framework.
|
||||
"""
|
||||
domain = context.get('%s_domain' % prefix)
|
||||
domain = context.get("%s_domain" % prefix)
|
||||
if domain is None:
|
||||
domain = context.get('analytical_domain')
|
||||
domain = context.get("analytical_domain")
|
||||
if domain is None:
|
||||
domain = getattr(settings, '%s_DOMAIN' % prefix.upper(), None)
|
||||
domain = getattr(settings, "%s_DOMAIN" % prefix.upper(), None)
|
||||
if domain is None:
|
||||
domain = getattr(settings, 'ANALYTICAL_DOMAIN', None)
|
||||
domain = getattr(settings, "ANALYTICAL_DOMAIN", None)
|
||||
if domain is None:
|
||||
if 'django.contrib.sites' in settings.INSTALLED_APPS:
|
||||
if "django.contrib.sites" in settings.INSTALLED_APPS:
|
||||
from django.contrib.sites.models import Site
|
||||
|
||||
try:
|
||||
domain = Site.objects.get_current().domain
|
||||
except (ImproperlyConfigured, Site.DoesNotExist):
|
||||
|
|
@ -129,20 +129,20 @@ def is_internal_ip(context, prefix=None):
|
|||
different notions of internal addresses.
|
||||
"""
|
||||
try:
|
||||
request = context['request']
|
||||
remote_ip = request.META.get('HTTP_X_FORWARDED_FOR', '')
|
||||
request = context["request"]
|
||||
remote_ip = request.META.get("HTTP_X_FORWARDED_FOR", "")
|
||||
if not remote_ip:
|
||||
remote_ip = request.META.get('REMOTE_ADDR', '')
|
||||
remote_ip = request.META.get("REMOTE_ADDR", "")
|
||||
if not remote_ip:
|
||||
return False
|
||||
|
||||
internal_ips = None
|
||||
if prefix is not None:
|
||||
internal_ips = getattr(settings, '%s_INTERNAL_IPS' % prefix, None)
|
||||
internal_ips = getattr(settings, "%s_INTERNAL_IPS" % prefix, None)
|
||||
if internal_ips is None:
|
||||
internal_ips = getattr(settings, 'ANALYTICAL_INTERNAL_IPS', None)
|
||||
internal_ips = getattr(settings, "ANALYTICAL_INTERNAL_IPS", None)
|
||||
if internal_ips is None:
|
||||
internal_ips = getattr(settings, 'INTERNAL_IPS', None)
|
||||
internal_ips = getattr(settings, "INTERNAL_IPS", None)
|
||||
|
||||
return remote_ip in (internal_ips or [])
|
||||
except (KeyError, AttributeError):
|
||||
|
|
@ -155,7 +155,7 @@ def disable_html(html, service):
|
|||
|
||||
The `service` argument is used to display a friendly message.
|
||||
"""
|
||||
return HTML_COMMENT % {'html': html, 'service': service}
|
||||
return HTML_COMMENT % {"html": html, "service": service}
|
||||
|
||||
|
||||
class AnalyticalException(Exception):
|
||||
|
|
@ -163,4 +163,5 @@ class AnalyticalException(Exception):
|
|||
Raised when an exception occurs in any django-analytical code that should
|
||||
be silenced in templates.
|
||||
"""
|
||||
|
||||
silent_variable_failure = True
|
||||
|
|
|
|||
|
|
@ -8,3 +8,6 @@ upload-dir = build/docs/html
|
|||
|
||||
[tool:pytest]
|
||||
DJANGO_SETTINGS_MODULE = tests.testproject.settings
|
||||
|
||||
[isort]
|
||||
profile = black
|
||||
58
setup.py
58
setup.py
|
|
@ -10,46 +10,46 @@ def read_file(fname):
|
|||
|
||||
|
||||
setup(
|
||||
name='django-analytical',
|
||||
name="django-analytical",
|
||||
version=package.__version__,
|
||||
license=package.__license__,
|
||||
description=package.__doc__.strip(),
|
||||
long_description=read_file('README.rst'),
|
||||
long_description_content_type='text/x-rst',
|
||||
long_description=read_file("README.rst"),
|
||||
long_description_content_type="text/x-rst",
|
||||
author=package.__author__,
|
||||
author_email=package.__email__,
|
||||
packages=[
|
||||
'analytical',
|
||||
'analytical.templatetags',
|
||||
"analytical",
|
||||
"analytical.templatetags",
|
||||
],
|
||||
keywords=[
|
||||
'django',
|
||||
'analytics',
|
||||
"django",
|
||||
"analytics",
|
||||
],
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Web Environment',
|
||||
'Framework :: Django',
|
||||
'Framework :: Django :: 2.2',
|
||||
'Framework :: Django :: 3.0',
|
||||
'Framework :: Django :: 3.1',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Environment :: Web Environment",
|
||||
"Framework :: Django",
|
||||
"Framework :: Django :: 2.2",
|
||||
"Framework :: Django :: 3.0",
|
||||
"Framework :: Django :: 3.1",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Operating System :: OS Independent",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Topic :: Internet :: WWW/HTTP",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
],
|
||||
python_requires='>=3.6',
|
||||
platforms=['any'],
|
||||
url='https://github.com/jazzband/django-analytical',
|
||||
download_url='https://github.com/jazzband/django-analytical/archive/master.zip',
|
||||
python_requires=">=3.6",
|
||||
platforms=["any"],
|
||||
url="https://github.com/jazzband/django-analytical",
|
||||
download_url="https://github.com/jazzband/django-analytical/archive/master.zip",
|
||||
project_urls={
|
||||
'Documentation': 'https://django-analytical.readthedocs.io/',
|
||||
"Documentation": "https://django-analytical.readthedocs.io/",
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,29 +3,29 @@ django-analytical testing settings.
|
|||
"""
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': ':memory:',
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.sqlite3",
|
||||
"NAME": ":memory:",
|
||||
}
|
||||
}
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.sites',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.auth',
|
||||
'analytical',
|
||||
"django.contrib.sites",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.auth",
|
||||
"analytical",
|
||||
]
|
||||
|
||||
SECRET_KEY = 'testing'
|
||||
SECRET_KEY = "testing"
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
)
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'APP_DIRS': True,
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"APP_DIRS": True,
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ from django.template import Library, Node, TemplateSyntaxError
|
|||
|
||||
from analytical.templatetags.analytical import TAG_LOCATIONS
|
||||
|
||||
|
||||
register = Library()
|
||||
|
||||
|
||||
|
|
@ -14,6 +13,7 @@ def _location_node(location):
|
|||
class DummyNode(Node):
|
||||
def render(self, context):
|
||||
return "<!-- dummy_%s -->" % location
|
||||
|
||||
return DummyNode
|
||||
|
||||
|
||||
|
|
@ -26,11 +26,12 @@ def _location_tag(location):
|
|||
if len(bits) > 1:
|
||||
raise TemplateSyntaxError("'%s' tag takes no arguments" % bits[0])
|
||||
return _location_nodes[location]
|
||||
|
||||
return dummy_tag
|
||||
|
||||
|
||||
for loc in TAG_LOCATIONS:
|
||||
register.tag('dummy_%s' % loc, _location_tag(loc))
|
||||
register.tag("dummy_%s" % loc, _location_tag(loc))
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node_cls):
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ Tests for the generic template tags and filters.
|
|||
"""
|
||||
|
||||
from django.template import Context, Template
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags import analytical
|
||||
from utils import TagTestCase
|
||||
|
||||
|
||||
class AnalyticsTagTestCase(TagTestCase):
|
||||
|
|
@ -16,7 +16,7 @@ class AnalyticsTagTestCase(TagTestCase):
|
|||
def setUp(self):
|
||||
super().setUp()
|
||||
self._tag_modules = analytical.TAG_MODULES
|
||||
analytical.TAG_MODULES = ['tests.testproject.dummy']
|
||||
analytical.TAG_MODULES = ["tests.testproject.dummy"]
|
||||
analytical.template_nodes = analytical._load_template_nodes()
|
||||
|
||||
def tearDown(self):
|
||||
|
|
@ -31,6 +31,6 @@ class AnalyticsTagTestCase(TagTestCase):
|
|||
return t.render(Context(vars))
|
||||
|
||||
def test_location_tags(self):
|
||||
for loc in ['head_top', 'head_bottom', 'body_top', 'body_bottom']:
|
||||
for loc in ["head_top", "head_bottom", "body_top", "body_bottom"]:
|
||||
r = self.render_location_tag(loc)
|
||||
self.assertTrue('dummy_%s' % loc in r, r)
|
||||
self.assertTrue("dummy_%s" % loc in r, r)
|
||||
|
|
|
|||
|
|
@ -8,39 +8,46 @@ from django.http import HttpRequest
|
|||
from django.template import Context
|
||||
from django.test import TestCase
|
||||
from django.test.utils import override_settings
|
||||
|
||||
from analytical.templatetags.chartbeat import ChartbeatTopNode, \
|
||||
ChartbeatBottomNode
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.chartbeat import ChartbeatBottomNode, ChartbeatTopNode
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(CHARTBEAT_USER_ID='12345')
|
||||
@override_settings(CHARTBEAT_USER_ID="12345")
|
||||
class ChartbeatTagTestCaseNoSites(TestCase):
|
||||
def test_rendering_setup_no_site(self):
|
||||
r = ChartbeatBottomNode().render(Context())
|
||||
self.assertTrue('var _sf_async_config={"uid": "12345"};' in r, r)
|
||||
|
||||
|
||||
@override_settings(INSTALLED_APPS=(
|
||||
'analytical',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
))
|
||||
@override_settings(CHARTBEAT_USER_ID='12345')
|
||||
@override_settings(
|
||||
INSTALLED_APPS=(
|
||||
"analytical",
|
||||
"django.contrib.sites",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
)
|
||||
)
|
||||
@override_settings(CHARTBEAT_USER_ID="12345")
|
||||
class ChartbeatTagTestCaseWithSites(TestCase):
|
||||
def setUp(self):
|
||||
from django.core.management import call_command
|
||||
|
||||
call_command("migrate", verbosity=0)
|
||||
|
||||
def test_rendering_setup_site(self):
|
||||
from django.contrib.sites.models import Site
|
||||
|
||||
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):
|
||||
|
|
@ -53,48 +60,65 @@ class ChartbeatTagTestCaseWithSites(TestCase):
|
|||
self.assertTrue('var _sf_async_config={"uid": "12345"};' in r, r)
|
||||
|
||||
|
||||
@override_settings(CHARTBEAT_USER_ID='12345')
|
||||
@override_settings(CHARTBEAT_USER_ID="12345")
|
||||
class ChartbeatTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``chartbeat`` template tag.
|
||||
"""
|
||||
|
||||
def test_top_tag(self):
|
||||
r = self.render_tag('chartbeat', 'chartbeat_top', {'chartbeat_domain': "test.com"})
|
||||
self.assertTrue('var _sf_startpt=(new Date()).getTime()' in r, r)
|
||||
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"})
|
||||
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)
|
||||
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",
|
||||
}))
|
||||
self.assertTrue('var _sf_startpt=(new Date()).getTime()' in r, r)
|
||||
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",
|
||||
}))
|
||||
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)
|
||||
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):
|
||||
self.assertRaises(AnalyticalException, ChartbeatBottomNode)
|
||||
|
||||
@override_settings(CHARTBEAT_USER_ID='123abc')
|
||||
@override_settings(CHARTBEAT_USER_ID="123abc")
|
||||
def test_wrong_user_id(self):
|
||||
self.assertRaises(AnalyticalException, ChartbeatBottomNode)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = ChartbeatBottomNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Chartbeat disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(
|
||||
r.startswith("<!-- Chartbeat disabled on internal IP address"), r
|
||||
)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
|
|
|||
|
|
@ -5,20 +5,20 @@ Tests for the Clickmap template tags and filters.
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.clickmap import ClickmapNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(CLICKMAP_TRACKER_ID='12345ABC')
|
||||
@override_settings(CLICKMAP_TRACKER_ID="12345ABC")
|
||||
class ClickmapTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``clickmap`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('clickmap', 'clickmap')
|
||||
r = self.render_tag("clickmap", "clickmap")
|
||||
self.assertTrue("tracker: '12345ABC', version:'2'};" in r, r)
|
||||
|
||||
def test_node(self):
|
||||
|
|
@ -29,16 +29,17 @@ class ClickmapTagTestCase(TagTestCase):
|
|||
def test_no_site_id(self):
|
||||
self.assertRaises(AnalyticalException, ClickmapNode)
|
||||
|
||||
@override_settings(CLICKMAP_TRACKER_ID='ab#c')
|
||||
@override_settings(CLICKMAP_TRACKER_ID="ab#c")
|
||||
def test_wrong_site_id(self):
|
||||
self.assertRaises(AnalyticalException, ClickmapNode)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = ClickmapNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Clickmap disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(
|
||||
r.startswith("<!-- Clickmap disabled on internal IP address"), r
|
||||
)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
|
|
|||
|
|
@ -4,65 +4,71 @@ Tests for the Clicky template tags and filters.
|
|||
|
||||
import re
|
||||
|
||||
from django.contrib.auth.models import User, AnonymousUser
|
||||
from django.contrib.auth.models import AnonymousUser, User
|
||||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.clicky import ClickyNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(CLICKY_SITE_ID='12345678')
|
||||
@override_settings(CLICKY_SITE_ID="12345678")
|
||||
class ClickyTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``clicky`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('clicky', 'clicky')
|
||||
self.assertTrue('clicky_site_ids.push(12345678);' in r, r)
|
||||
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)
|
||||
|
||||
def test_node(self):
|
||||
r = ClickyNode().render(Context({}))
|
||||
self.assertTrue('clicky_site_ids.push(12345678);' in r, r)
|
||||
self.assertTrue("clicky_site_ids.push(12345678);" 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):
|
||||
self.assertRaises(AnalyticalException, ClickyNode)
|
||||
|
||||
@override_settings(CLICKY_SITE_ID='123abc')
|
||||
@override_settings(CLICKY_SITE_ID="123abc")
|
||||
def test_wrong_site_id(self):
|
||||
self.assertRaises(AnalyticalException, ClickyNode)
|
||||
|
||||
@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)
|
||||
r = ClickyNode().render(Context({"user": User(username="test")}))
|
||||
self.assertTrue(
|
||||
'var clicky_custom = {"session": {"username": "test"}};' in r, r
|
||||
)
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_identify_anonymous_user(self):
|
||||
r = ClickyNode().render(Context({'user': AnonymousUser()}))
|
||||
r = ClickyNode().render(Context({"user": AnonymousUser()}))
|
||||
self.assertFalse('var clicky_custom = {"session": {"username":' in r, r)
|
||||
|
||||
def test_custom(self):
|
||||
r = ClickyNode().render(Context({
|
||||
'clicky_var1': 'val1',
|
||||
'clicky_var2': 'val2',
|
||||
}))
|
||||
r = ClickyNode().render(
|
||||
Context(
|
||||
{
|
||||
"clicky_var1": "val1",
|
||||
"clicky_var2": "val2",
|
||||
}
|
||||
)
|
||||
)
|
||||
self.assertTrue(
|
||||
re.search(r'var clicky_custom = {.*"var1": "val1", "var2": "val2".*};', r),
|
||||
r)
|
||||
r,
|
||||
)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = ClickyNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Clicky disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(r.startswith("<!-- Clicky disabled on internal IP address"), r)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
|
|
|||
|
|
@ -5,46 +5,47 @@ Tests for the Crazy Egg template tags and filters.
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.crazy_egg import CrazyEggNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(CRAZY_EGG_ACCOUNT_NUMBER='12345678')
|
||||
@override_settings(CRAZY_EGG_ACCOUNT_NUMBER="12345678")
|
||||
class CrazyEggTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``crazy_egg`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('crazy_egg', 'crazy_egg')
|
||||
self.assertTrue('/1234/5678.js' in r, r)
|
||||
r = self.render_tag("crazy_egg", "crazy_egg")
|
||||
self.assertTrue("/1234/5678.js" in r, r)
|
||||
|
||||
def test_node(self):
|
||||
r = CrazyEggNode().render(Context())
|
||||
self.assertTrue('/1234/5678.js' in r, r)
|
||||
self.assertTrue("/1234/5678.js" in r, r)
|
||||
|
||||
@override_settings(CRAZY_EGG_ACCOUNT_NUMBER=None)
|
||||
def test_no_account_number(self):
|
||||
self.assertRaises(AnalyticalException, CrazyEggNode)
|
||||
|
||||
@override_settings(CRAZY_EGG_ACCOUNT_NUMBER='123abc')
|
||||
@override_settings(CRAZY_EGG_ACCOUNT_NUMBER="123abc")
|
||||
def test_wrong_account_number(self):
|
||||
self.assertRaises(AnalyticalException, CrazyEggNode)
|
||||
|
||||
def test_uservars(self):
|
||||
context = Context({'crazy_egg_var1': 'foo', 'crazy_egg_var2': 'bar'})
|
||||
context = Context({"crazy_egg_var1": "foo", "crazy_egg_var2": "bar"})
|
||||
r = CrazyEggNode().render(context)
|
||||
self.assertTrue("CE2.set(1, 'foo');" in r, r)
|
||||
self.assertTrue("CE2.set(2, 'bar');" in r, r)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = CrazyEggNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Crazy Egg disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(
|
||||
r.startswith("<!-- Crazy Egg disabled on internal IP address"), r
|
||||
)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
|
|
|||
|
|
@ -4,13 +4,15 @@ Tests for the Facebook Pixel template tags.
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context, Template, TemplateSyntaxError
|
||||
from django.test import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.analytical import _load_template_nodes
|
||||
from analytical.templatetags.facebook_pixel import FacebookPixelHeadNode, FacebookPixelBodyNode
|
||||
from utils import TagTestCase
|
||||
from analytical.templatetags.facebook_pixel import (
|
||||
FacebookPixelBodyNode,
|
||||
FacebookPixelHeadNode,
|
||||
)
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
expected_head_html = """\
|
||||
<script>
|
||||
!function(f,b,e,v,n,t,s)
|
||||
|
|
@ -34,13 +36,13 @@ expected_body_html = """\
|
|||
"""
|
||||
|
||||
|
||||
@override_settings(FACEBOOK_PIXEL_ID='1234567890')
|
||||
@override_settings(FACEBOOK_PIXEL_ID="1234567890")
|
||||
class FacebookPixelTagTestCase(TagTestCase):
|
||||
|
||||
maxDiff = None
|
||||
|
||||
def test_head_tag(self):
|
||||
html = self.render_tag('facebook_pixel', 'facebook_pixel_head')
|
||||
html = self.render_tag("facebook_pixel", "facebook_pixel_head")
|
||||
self.assertEqual(expected_head_html, html)
|
||||
|
||||
def test_head_node(self):
|
||||
|
|
@ -48,7 +50,7 @@ class FacebookPixelTagTestCase(TagTestCase):
|
|||
self.assertEqual(expected_head_html, html)
|
||||
|
||||
def test_body_tag(self):
|
||||
html = self.render_tag('facebook_pixel', 'facebook_pixel_body')
|
||||
html = self.render_tag("facebook_pixel", "facebook_pixel_body")
|
||||
self.assertEqual(expected_body_html, html)
|
||||
|
||||
def test_body_node(self):
|
||||
|
|
@ -59,41 +61,59 @@ class FacebookPixelTagTestCase(TagTestCase):
|
|||
self.assertRaisesRegex(
|
||||
TemplateSyntaxError,
|
||||
r"^'facebook_pixel_head' takes no arguments$",
|
||||
lambda: (Template('{% load facebook_pixel %}{% facebook_pixel_head "arg" %}')
|
||||
.render(Context({}))),
|
||||
lambda: (
|
||||
Template(
|
||||
'{% load facebook_pixel %}{% facebook_pixel_head "arg" %}'
|
||||
).render(Context({}))
|
||||
),
|
||||
)
|
||||
self.assertRaisesRegex(
|
||||
TemplateSyntaxError,
|
||||
r"^'facebook_pixel_body' takes no arguments$",
|
||||
lambda: (Template('{% load facebook_pixel %}{% facebook_pixel_body "arg" %}')
|
||||
.render(Context({}))),
|
||||
lambda: (
|
||||
Template(
|
||||
'{% load facebook_pixel %}{% facebook_pixel_body "arg" %}'
|
||||
).render(Context({}))
|
||||
),
|
||||
)
|
||||
|
||||
@override_settings(FACEBOOK_PIXEL_ID=None)
|
||||
def test_no_id(self):
|
||||
expected_pattern = r'^FACEBOOK_PIXEL_ID setting is not set$'
|
||||
self.assertRaisesRegex(AnalyticalException, expected_pattern, FacebookPixelHeadNode)
|
||||
self.assertRaisesRegex(AnalyticalException, expected_pattern, FacebookPixelBodyNode)
|
||||
expected_pattern = r"^FACEBOOK_PIXEL_ID setting is not set$"
|
||||
self.assertRaisesRegex(
|
||||
AnalyticalException, expected_pattern, FacebookPixelHeadNode
|
||||
)
|
||||
self.assertRaisesRegex(
|
||||
AnalyticalException, expected_pattern, FacebookPixelBodyNode
|
||||
)
|
||||
|
||||
@override_settings(FACEBOOK_PIXEL_ID='invalid')
|
||||
@override_settings(FACEBOOK_PIXEL_ID="invalid")
|
||||
def test_invalid_id(self):
|
||||
expected_pattern = (
|
||||
r"^FACEBOOK_PIXEL_ID setting: must be \(a string containing\) a number: 'invalid'$")
|
||||
self.assertRaisesRegex(AnalyticalException, expected_pattern, FacebookPixelHeadNode)
|
||||
self.assertRaisesRegex(AnalyticalException, expected_pattern, FacebookPixelBodyNode)
|
||||
r"^FACEBOOK_PIXEL_ID setting: must be"
|
||||
r" \(a string containing\) a number: 'invalid'$"
|
||||
)
|
||||
self.assertRaisesRegex(
|
||||
AnalyticalException, expected_pattern, FacebookPixelHeadNode
|
||||
)
|
||||
self.assertRaisesRegex(
|
||||
AnalyticalException, expected_pattern, FacebookPixelBodyNode
|
||||
)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
request = HttpRequest()
|
||||
request.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': request})
|
||||
request.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": request})
|
||||
|
||||
def _disabled(html):
|
||||
return '\n'.join([
|
||||
'<!-- Facebook Pixel disabled on internal IP address',
|
||||
html,
|
||||
'-->',
|
||||
])
|
||||
return "\n".join(
|
||||
[
|
||||
"<!-- Facebook Pixel disabled on internal IP address",
|
||||
html,
|
||||
"-->",
|
||||
]
|
||||
)
|
||||
|
||||
head_html = FacebookPixelHeadNode().render(context)
|
||||
self.assertEqual(_disabled(expected_head_html), head_html)
|
||||
|
|
@ -106,9 +126,12 @@ class FacebookPixelTagTestCase(TagTestCase):
|
|||
`facebook_pixel.contribute_to_analytical` registers the head and body nodes.
|
||||
"""
|
||||
template_nodes = _load_template_nodes()
|
||||
self.assertEqual({
|
||||
'head_top': [],
|
||||
'head_bottom': [FacebookPixelHeadNode],
|
||||
'body_top': [],
|
||||
'body_bottom': [FacebookPixelBodyNode],
|
||||
}, template_nodes)
|
||||
self.assertEqual(
|
||||
{
|
||||
"head_top": [],
|
||||
"head_bottom": [FacebookPixelHeadNode],
|
||||
"body_top": [],
|
||||
"body_bottom": [FacebookPixelBodyNode],
|
||||
},
|
||||
template_nodes,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,20 +5,21 @@ Tests for the Gauges template tags and filters.
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.gauges import GaugesNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(GAUGES_SITE_ID='1234567890abcdef0123456789')
|
||||
@override_settings(GAUGES_SITE_ID="1234567890abcdef0123456789")
|
||||
class GaugesTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``gauges`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
self.assertEqual("""
|
||||
self.assertEqual(
|
||||
"""
|
||||
<script type="text/javascript">
|
||||
var _gauges = _gauges || [];
|
||||
(function() {
|
||||
|
|
@ -32,11 +33,13 @@ 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(
|
||||
"""
|
||||
"""
|
||||
<script type="text/javascript">
|
||||
var _gauges = _gauges || [];
|
||||
(function() {
|
||||
|
|
@ -50,22 +53,23 @@ 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):
|
||||
self.assertRaises(AnalyticalException, GaugesNode)
|
||||
|
||||
@override_settings(GAUGES_SITE_ID='123abQ')
|
||||
@override_settings(GAUGES_SITE_ID="123abQ")
|
||||
def test_wrong_account_number(self):
|
||||
self.assertRaises(AnalyticalException, GaugesNode)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = GaugesNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Gauges disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(r.startswith("<!-- Gauges disabled on internal IP address"), r)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
|
|
|||
|
|
@ -5,23 +5,31 @@ Tests for the Google Analytics template tags and filters.
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase, TestCase
|
||||
|
||||
from analytical.templatetags.google_analytics import GoogleAnalyticsNode, \
|
||||
TRACK_SINGLE_DOMAIN, TRACK_MULTIPLE_DOMAINS, TRACK_MULTIPLE_SUBDOMAINS,\
|
||||
SCOPE_VISITOR, SCOPE_SESSION, SCOPE_PAGE
|
||||
from utils import TestCase, TagTestCase
|
||||
from analytical.templatetags.google_analytics import (
|
||||
SCOPE_PAGE,
|
||||
SCOPE_SESSION,
|
||||
SCOPE_VISITOR,
|
||||
TRACK_MULTIPLE_DOMAINS,
|
||||
TRACK_MULTIPLE_SUBDOMAINS,
|
||||
TRACK_SINGLE_DOMAIN,
|
||||
GoogleAnalyticsNode,
|
||||
)
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_PROPERTY_ID='UA-123456-7',
|
||||
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_SINGLE_DOMAIN)
|
||||
@override_settings(
|
||||
GOOGLE_ANALYTICS_PROPERTY_ID="UA-123456-7",
|
||||
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_SINGLE_DOMAIN,
|
||||
)
|
||||
class GoogleAnalyticsTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``google_analytics`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('google_analytics', 'google_analytics')
|
||||
r = self.render_tag("google_analytics", "google_analytics")
|
||||
self.assertTrue("_gaq.push(['_setAccount', 'UA-123456-7']);" in r, r)
|
||||
self.assertTrue("_gaq.push(['_trackPageview']);" in r, r)
|
||||
|
||||
|
|
@ -34,19 +42,23 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
def test_no_property_id(self):
|
||||
self.assertRaises(AnalyticalException, GoogleAnalyticsNode)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_PROPERTY_ID='wrong')
|
||||
@override_settings(GOOGLE_ANALYTICS_PROPERTY_ID="wrong")
|
||||
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')
|
||||
@override_settings(
|
||||
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_DOMAINS,
|
||||
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)
|
||||
|
|
@ -54,12 +66,14 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
self.assertTrue("_gaq.push(['_setAllowLinker', true]);" in r, r)
|
||||
|
||||
def test_custom_vars(self):
|
||||
context = Context({
|
||||
'google_analytics_var1': ('test1', 'foo'),
|
||||
'google_analytics_var2': ('test2', 'bar', SCOPE_VISITOR),
|
||||
'google_analytics_var4': ('test4', 'baz', SCOPE_SESSION),
|
||||
'google_analytics_var5': ('test5', 'qux', SCOPE_PAGE),
|
||||
})
|
||||
context = Context(
|
||||
{
|
||||
"google_analytics_var1": ("test1", "foo"),
|
||||
"google_analytics_var2": ("test2", "bar", SCOPE_VISITOR),
|
||||
"google_analytics_var4": ("test4", "baz", SCOPE_SESSION),
|
||||
"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)
|
||||
|
|
@ -79,21 +93,22 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
r = GoogleAnalyticsNode().render(Context())
|
||||
self.assertTrue("stats.g.doubleclick.net/dc.js" in r, r)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = GoogleAnalyticsNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Google Analytics disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(
|
||||
r.startswith("<!-- Google Analytics disabled on internal IP address"), r
|
||||
)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_ANONYMIZE_IP=True)
|
||||
def test_anonymize_ip(self):
|
||||
r = GoogleAnalyticsNode().render(Context())
|
||||
self.assertTrue("_gaq.push(['_gat._anonymizeIp']);" in r, r)
|
||||
self.assertTrue(r.index('_gat._anonymizeIp') < r.index('_trackPageview'), r)
|
||||
self.assertTrue(r.index("_gat._anonymizeIp") < r.index("_trackPageview"), r)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_ANONYMIZE_IP=False)
|
||||
def test_anonymize_ip_not_present(self):
|
||||
|
|
@ -105,7 +120,7 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
r = GoogleAnalyticsNode().render(Context())
|
||||
self.assertTrue("_gaq.push(['_setSampleRate', '0.00']);" in r, r)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_SAMPLE_RATE='100.00')
|
||||
@override_settings(GOOGLE_ANALYTICS_SAMPLE_RATE="100.00")
|
||||
def test_set_sample_rate_max(self):
|
||||
r = GoogleAnalyticsNode().render(Context())
|
||||
self.assertTrue("_gaq.push(['_setSampleRate', '100.00']);" in r, r)
|
||||
|
|
@ -125,7 +140,7 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
r = GoogleAnalyticsNode().render(Context())
|
||||
self.assertTrue("_gaq.push(['_setSiteSpeedSampleRate', '0.00']);" in r, r)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE='100.00')
|
||||
@override_settings(GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE="100.00")
|
||||
def test_set_site_speed_sample_rate_max(self):
|
||||
r = GoogleAnalyticsNode().render(Context())
|
||||
self.assertTrue("_gaq.push(['_setSiteSpeedSampleRate', '100.00']);" in r, r)
|
||||
|
|
@ -145,7 +160,7 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
r = GoogleAnalyticsNode().render(Context())
|
||||
self.assertTrue("_gaq.push(['_setSessionCookieTimeout', '0']);" in r, r)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_SESSION_COOKIE_TIMEOUT='10000')
|
||||
@override_settings(GOOGLE_ANALYTICS_SESSION_COOKIE_TIMEOUT="10000")
|
||||
def test_set_session_cookie_timeout_as_string(self):
|
||||
r = GoogleAnalyticsNode().render(Context())
|
||||
self.assertTrue("_gaq.push(['_setSessionCookieTimeout', '10000']);" in r, r)
|
||||
|
|
@ -160,7 +175,7 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
r = GoogleAnalyticsNode().render(Context())
|
||||
self.assertTrue("_gaq.push(['_setVisitorCookieTimeout', '0']);" in r, r)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_VISITOR_COOKIE_TIMEOUT='10000')
|
||||
@override_settings(GOOGLE_ANALYTICS_VISITOR_COOKIE_TIMEOUT="10000")
|
||||
def test_set_visitor_cookie_timeout_as_string(self):
|
||||
r = GoogleAnalyticsNode().render(Context())
|
||||
self.assertTrue("_gaq.push(['_setVisitorCookieTimeout', '10000']);" in r, r)
|
||||
|
|
@ -171,10 +186,12 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
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)
|
||||
@override_settings(
|
||||
GOOGLE_ANALYTICS_PROPERTY_ID="UA-123456-7",
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -6,23 +6,25 @@ from django.contrib.auth.models import User
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.google_analytics_gtag import GoogleAnalyticsGTagNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID='UA-123456-7')
|
||||
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID="UA-123456-7")
|
||||
class GoogleAnalyticsTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``google_analytics_js`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('google_analytics_gtag', 'google_analytics_gtag')
|
||||
r = self.render_tag("google_analytics_gtag", "google_analytics_gtag")
|
||||
self.assertTrue(
|
||||
'<script async src="https://www.googletagmanager.com/gtag/js?id=UA-123456-7"></script>'
|
||||
in r, r)
|
||||
in r,
|
||||
r,
|
||||
)
|
||||
self.assertTrue("gtag('js', new Date());" in r, r)
|
||||
self.assertTrue("gtag('config', 'UA-123456-7');" in r, r)
|
||||
|
||||
|
|
@ -30,7 +32,9 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
r = GoogleAnalyticsGTagNode().render(Context())
|
||||
self.assertTrue(
|
||||
'<script async src="https://www.googletagmanager.com/gtag/js?id=UA-123456-7"></script>'
|
||||
in r, r)
|
||||
in r,
|
||||
r,
|
||||
)
|
||||
self.assertTrue("gtag('js', new Date());" in r, r)
|
||||
self.assertTrue("gtag('config', 'UA-123456-7');" in r, r)
|
||||
|
||||
|
|
@ -38,51 +42,64 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
|||
def test_no_property_id(self):
|
||||
self.assertRaises(AnalyticalException, GoogleAnalyticsGTagNode)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID='wrong')
|
||||
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID="wrong")
|
||||
def test_wrong_property_id(self):
|
||||
self.assertRaises(AnalyticalException, GoogleAnalyticsGTagNode)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = GoogleAnalyticsGTagNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Google Analytics disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(
|
||||
r.startswith("<!-- Google Analytics disabled on internal IP address"), r
|
||||
)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_identify(self):
|
||||
r = GoogleAnalyticsGTagNode().render(Context({'user': User(username='test')}))
|
||||
r = GoogleAnalyticsGTagNode().render(Context({"user": User(username="test")}))
|
||||
self.assertTrue("gtag('set', {'user_id': 'test'});" in r, r)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID='G-12345678')
|
||||
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID="G-12345678")
|
||||
def test_tag_with_measurement_id(self):
|
||||
r = self.render_tag('google_analytics_gtag', 'google_analytics_gtag')
|
||||
r = self.render_tag("google_analytics_gtag", "google_analytics_gtag")
|
||||
self.assertTrue(
|
||||
('<script async src="https://www.googletagmanager.com/gtag/' +
|
||||
'js?id=G-12345678"></script>')
|
||||
in r, r)
|
||||
(
|
||||
'<script async src="https://www.googletagmanager.com/gtag/'
|
||||
+ 'js?id=G-12345678"></script>'
|
||||
)
|
||||
in r,
|
||||
r,
|
||||
)
|
||||
self.assertTrue("gtag('js', new Date());" in r, r)
|
||||
self.assertTrue("gtag('config', 'G-12345678');" in r, r)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID='AW-1234567890')
|
||||
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID="AW-1234567890")
|
||||
def test_tag_with_conversion_id(self):
|
||||
r = self.render_tag('google_analytics_gtag', 'google_analytics_gtag')
|
||||
r = self.render_tag("google_analytics_gtag", "google_analytics_gtag")
|
||||
self.assertTrue(
|
||||
('<script async src="https://www.googletagmanager.com/gtag/' +
|
||||
'js?id=AW-1234567890"></script>')
|
||||
in r, r)
|
||||
(
|
||||
'<script async src="https://www.googletagmanager.com/gtag/'
|
||||
+ 'js?id=AW-1234567890"></script>'
|
||||
)
|
||||
in r,
|
||||
r,
|
||||
)
|
||||
self.assertTrue("gtag('js', new Date());" in r, r)
|
||||
self.assertTrue("gtag('config', 'AW-1234567890');" in r, r)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID='DC-12345678')
|
||||
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID="DC-12345678")
|
||||
def test_tag_with_advertiser_id(self):
|
||||
r = self.render_tag('google_analytics_gtag', 'google_analytics_gtag')
|
||||
r = self.render_tag("google_analytics_gtag", "google_analytics_gtag")
|
||||
self.assertTrue(
|
||||
('<script async src="https://www.googletagmanager.com/gtag/' +
|
||||
'js?id=DC-12345678"></script>')
|
||||
in r, r)
|
||||
(
|
||||
'<script async src="https://www.googletagmanager.com/gtag/'
|
||||
+ 'js?id=DC-12345678"></script>'
|
||||
)
|
||||
in r,
|
||||
r,
|
||||
)
|
||||
self.assertTrue("gtag('js', new Date());" in r, r)
|
||||
self.assertTrue("gtag('config', 'DC-12345678');" in r, r)
|
||||
|
|
|
|||
|
|
@ -5,35 +5,49 @@ Tests for the Google Analytics template tags and filters, using the new analytic
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase, TestCase
|
||||
|
||||
from analytical.templatetags.google_analytics_js import GoogleAnalyticsJsNode, \
|
||||
TRACK_SINGLE_DOMAIN, TRACK_MULTIPLE_DOMAINS, TRACK_MULTIPLE_SUBDOMAINS
|
||||
from utils import TestCase, TagTestCase
|
||||
from analytical.templatetags.google_analytics_js import (
|
||||
TRACK_MULTIPLE_DOMAINS,
|
||||
TRACK_MULTIPLE_SUBDOMAINS,
|
||||
TRACK_SINGLE_DOMAIN,
|
||||
GoogleAnalyticsJsNode,
|
||||
)
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_JS_PROPERTY_ID='UA-123456-7',
|
||||
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_SINGLE_DOMAIN)
|
||||
@override_settings(
|
||||
GOOGLE_ANALYTICS_JS_PROPERTY_ID="UA-123456-7",
|
||||
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_SINGLE_DOMAIN,
|
||||
)
|
||||
class GoogleAnalyticsTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``google_analytics_js`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('google_analytics_js', 'google_analytics_js')
|
||||
self.assertTrue("""(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
r = self.render_tag("google_analytics_js", "google_analytics_js")
|
||||
self.assertTrue(
|
||||
"""(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');""" in r, r)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');"""
|
||||
in r,
|
||||
r,
|
||||
)
|
||||
self.assertTrue("ga('create', 'UA-123456-7', 'auto', {});" in r, r)
|
||||
self.assertTrue("ga('send', 'pageview');" in r, r)
|
||||
|
||||
def test_node(self):
|
||||
r = GoogleAnalyticsJsNode().render(Context())
|
||||
self.assertTrue("""(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
self.assertTrue(
|
||||
"""(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');""" in r, r)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');"""
|
||||
in r,
|
||||
r,
|
||||
)
|
||||
self.assertTrue("ga('create', 'UA-123456-7', 'auto', {});" in r, r)
|
||||
self.assertTrue("ga('send', 'pageview');" in r, r)
|
||||
|
||||
|
|
@ -41,32 +55,41 @@ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|||
def test_no_property_id(self):
|
||||
self.assertRaises(AnalyticalException, GoogleAnalyticsJsNode)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_JS_PROPERTY_ID='wrong')
|
||||
@override_settings(GOOGLE_ANALYTICS_JS_PROPERTY_ID="wrong")
|
||||
def test_wrong_property_id(self):
|
||||
self.assertRaises(AnalyticalException, GoogleAnalyticsJsNode)
|
||||
|
||||
@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 = GoogleAnalyticsJsNode().render(Context())
|
||||
self.assertTrue(
|
||||
"""ga('create', 'UA-123456-7', 'auto', {"legacyCookieDomain": "example.com"}""" in r, r)
|
||||
"""ga('create', 'UA-123456-7', 'auto', {"legacyCookieDomain": "example.com"}"""
|
||||
in r,
|
||||
r,
|
||||
)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_DOMAINS,
|
||||
GOOGLE_ANALYTICS_DOMAIN='example.com')
|
||||
@override_settings(
|
||||
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_DOMAINS,
|
||||
GOOGLE_ANALYTICS_DOMAIN="example.com",
|
||||
)
|
||||
def test_track_multiple_domains(self):
|
||||
r = GoogleAnalyticsJsNode().render(Context())
|
||||
self.assertTrue("ga('create', 'UA-123456-7', 'auto', {" in r, r)
|
||||
self.assertTrue('"legacyCookieDomain": "example.com"' in r, r)
|
||||
self.assertTrue('"allowLinker\": true' in r, r)
|
||||
self.assertTrue('"allowLinker": true' in r, r)
|
||||
|
||||
def test_custom_vars(self):
|
||||
context = Context({
|
||||
'google_analytics_var1': ('test1', 'foo'),
|
||||
'google_analytics_var2': ('test2', 'bar'),
|
||||
'google_analytics_var4': ('test4', 1),
|
||||
'google_analytics_var5': ('test5', 2.2),
|
||||
})
|
||||
context = Context(
|
||||
{
|
||||
"google_analytics_var1": ("test1", "foo"),
|
||||
"google_analytics_var2": ("test2", "bar"),
|
||||
"google_analytics_var4": ("test4", 1),
|
||||
"google_analytics_var5": ("test5", 2.2),
|
||||
}
|
||||
)
|
||||
r = GoogleAnalyticsJsNode().render(context)
|
||||
self.assertTrue("ga('set', 'test1', 'foo');" in r, r)
|
||||
self.assertTrue("ga('set', 'test2', 'bar');" in r, r)
|
||||
|
|
@ -76,19 +99,24 @@ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|||
def test_display_advertising(self):
|
||||
with override_settings(GOOGLE_ANALYTICS_DISPLAY_ADVERTISING=True):
|
||||
r = GoogleAnalyticsJsNode().render(Context())
|
||||
self.assertTrue("""ga('create', 'UA-123456-7', 'auto', {});
|
||||
self.assertTrue(
|
||||
"""ga('create', 'UA-123456-7', 'auto', {});
|
||||
ga('require', 'displayfeatures');
|
||||
ga('send', 'pageview');""" in r, r)
|
||||
ga('send', 'pageview');"""
|
||||
in r,
|
||||
r,
|
||||
)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = GoogleAnalyticsJsNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Google Analytics disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(
|
||||
r.startswith("<!-- Google Analytics disabled on internal IP address"), r
|
||||
)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_ANONYMIZE_IP=True)
|
||||
def test_anonymize_ip(self):
|
||||
|
|
@ -103,12 +131,16 @@ ga('send', 'pageview');""" in r, r)
|
|||
@override_settings(GOOGLE_ANALYTICS_SAMPLE_RATE=0.0)
|
||||
def test_set_sample_rate_min(self):
|
||||
r = GoogleAnalyticsJsNode().render(Context())
|
||||
self.assertTrue("""ga('create', 'UA-123456-7', 'auto', {"sampleRate": 0});""" in r, r)
|
||||
self.assertTrue(
|
||||
"""ga('create', 'UA-123456-7', 'auto', {"sampleRate": 0});""" in r, r
|
||||
)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_SAMPLE_RATE='100.00')
|
||||
@override_settings(GOOGLE_ANALYTICS_SAMPLE_RATE="100.00")
|
||||
def test_set_sample_rate_max(self):
|
||||
r = GoogleAnalyticsJsNode().render(Context())
|
||||
self.assertTrue("""ga('create', 'UA-123456-7', 'auto', {"sampleRate": 100});""" in r, r)
|
||||
self.assertTrue(
|
||||
"""ga('create', 'UA-123456-7', 'auto', {"sampleRate": 100});""" in r, r
|
||||
)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_SAMPLE_RATE=-1)
|
||||
def test_exception_whenset_sample_rate_too_small(self):
|
||||
|
|
@ -124,13 +156,18 @@ ga('send', 'pageview');""" in r, r)
|
|||
def test_set_site_speed_sample_rate_min(self):
|
||||
r = GoogleAnalyticsJsNode().render(Context())
|
||||
self.assertTrue(
|
||||
"""ga('create', 'UA-123456-7', 'auto', {"siteSpeedSampleRate": 0});""" in r, r)
|
||||
"""ga('create', 'UA-123456-7', 'auto', {"siteSpeedSampleRate": 0});""" in r,
|
||||
r,
|
||||
)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE='100.00')
|
||||
@override_settings(GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE="100.00")
|
||||
def test_set_site_speed_sample_rate_max(self):
|
||||
r = GoogleAnalyticsJsNode().render(Context())
|
||||
self.assertTrue(
|
||||
"""ga('create', 'UA-123456-7', 'auto', {"siteSpeedSampleRate": 100});""" in r, r)
|
||||
"""ga('create', 'UA-123456-7', 'auto', {"siteSpeedSampleRate": 100});"""
|
||||
in r,
|
||||
r,
|
||||
)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE=-1)
|
||||
def test_exception_whenset_site_speed_sample_rate_too_small(self):
|
||||
|
|
@ -145,13 +182,16 @@ ga('send', 'pageview');""" in r, r)
|
|||
@override_settings(GOOGLE_ANALYTICS_COOKIE_EXPIRATION=0)
|
||||
def test_set_cookie_expiration_min(self):
|
||||
r = GoogleAnalyticsJsNode().render(Context())
|
||||
self.assertTrue("""ga('create', 'UA-123456-7', 'auto', {"cookieExpires": 0});""" in r, r)
|
||||
self.assertTrue(
|
||||
"""ga('create', 'UA-123456-7', 'auto', {"cookieExpires": 0});""" in r, r
|
||||
)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_COOKIE_EXPIRATION='10000')
|
||||
@override_settings(GOOGLE_ANALYTICS_COOKIE_EXPIRATION="10000")
|
||||
def test_set_cookie_expiration_as_string(self):
|
||||
r = GoogleAnalyticsJsNode().render(Context())
|
||||
self.assertTrue(
|
||||
"""ga('create', 'UA-123456-7', 'auto', {"cookieExpires": 10000});""" in r, r)
|
||||
"""ga('create', 'UA-123456-7', 'auto', {"cookieExpires": 10000});""" in r, r
|
||||
)
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_COOKIE_EXPIRATION=-1)
|
||||
def test_exception_when_set_cookie_expiration_too_small(self):
|
||||
|
|
@ -159,10 +199,12 @@ ga('send', 'pageview');""" in r, r)
|
|||
self.assertRaises(AnalyticalException, GoogleAnalyticsJsNode().render, context)
|
||||
|
||||
|
||||
@override_settings(GOOGLE_ANALYTICS_JS_PROPERTY_ID='UA-123456-7',
|
||||
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_DOMAINS,
|
||||
GOOGLE_ANALYTICS_DOMAIN=None,
|
||||
ANALYTICAL_DOMAIN=None)
|
||||
@override_settings(
|
||||
GOOGLE_ANALYTICS_JS_PROPERTY_ID="UA-123456-7",
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -2,24 +2,24 @@
|
|||
Tests for the GoSquared template tags and filters.
|
||||
"""
|
||||
|
||||
from django.contrib.auth.models import User, AnonymousUser
|
||||
from django.contrib.auth.models import AnonymousUser, User
|
||||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.gosquared import GoSquaredNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(GOSQUARED_SITE_TOKEN='ABC-123456-D')
|
||||
@override_settings(GOSQUARED_SITE_TOKEN="ABC-123456-D")
|
||||
class GoSquaredTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``gosquared`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('gosquared', 'gosquared')
|
||||
r = self.render_tag("gosquared", "gosquared")
|
||||
self.assertTrue('GoSquared.acct = "ABC-123456-D";' in r, r)
|
||||
|
||||
def test_node(self):
|
||||
|
|
@ -30,36 +30,45 @@ class GoSquaredTagTestCase(TagTestCase):
|
|||
def test_no_token(self):
|
||||
self.assertRaises(AnalyticalException, GoSquaredNode)
|
||||
|
||||
@override_settings(GOSQUARED_SITE_TOKEN='this is not a token')
|
||||
@override_settings(GOSQUARED_SITE_TOKEN="this is not a token")
|
||||
def test_wrong_token(self):
|
||||
self.assertRaises(AnalyticalException, GoSquaredNode)
|
||||
|
||||
@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)
|
||||
def test_manual_identify(self):
|
||||
r = GoSquaredNode().render(Context({
|
||||
'user': User(username='test', first_name='Test', last_name='User'),
|
||||
'gosquared_identity': 'test_identity',
|
||||
}))
|
||||
r = GoSquaredNode().render(
|
||||
Context(
|
||||
{
|
||||
"user": User(username="test", first_name="Test", last_name="User"),
|
||||
"gosquared_identity": "test_identity",
|
||||
}
|
||||
)
|
||||
)
|
||||
self.assertTrue('GoSquared.UserName = "test_identity";' in r, r)
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_identify_anonymous_user(self):
|
||||
r = GoSquaredNode().render(Context({'user': AnonymousUser()}))
|
||||
self.assertFalse('GoSquared.UserName = ' in r, r)
|
||||
r = GoSquaredNode().render(Context({"user": AnonymousUser()}))
|
||||
self.assertFalse("GoSquared.UserName = " in r, r)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = GoSquaredNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- GoSquared disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(
|
||||
r.startswith("<!-- GoSquared disabled on internal IP address"), r
|
||||
)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
|
|
|||
|
|
@ -4,13 +4,12 @@ Tests for the Hotjar template tags.
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context, Template, TemplateSyntaxError
|
||||
from django.test import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.analytical import _load_template_nodes
|
||||
from analytical.templatetags.hotjar import HotjarNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
expected_html = """\
|
||||
<script>
|
||||
(function(h,o,t,j,a,r){
|
||||
|
|
@ -25,13 +24,13 @@ expected_html = """\
|
|||
"""
|
||||
|
||||
|
||||
@override_settings(HOTJAR_SITE_ID='123456789')
|
||||
@override_settings(HOTJAR_SITE_ID="123456789")
|
||||
class HotjarTagTestCase(TagTestCase):
|
||||
|
||||
maxDiff = None
|
||||
|
||||
def test_tag(self):
|
||||
html = self.render_tag('hotjar', 'hotjar')
|
||||
html = self.render_tag("hotjar", "hotjar")
|
||||
self.assertEqual(expected_html, html)
|
||||
|
||||
def test_node(self):
|
||||
|
|
@ -42,33 +41,38 @@ class HotjarTagTestCase(TagTestCase):
|
|||
self.assertRaisesRegex(
|
||||
TemplateSyntaxError,
|
||||
r"^'hotjar' takes no arguments$",
|
||||
lambda: (Template('{% load hotjar %}{% hotjar "arg" %}')
|
||||
.render(Context({}))),
|
||||
lambda: (
|
||||
Template('{% load hotjar %}{% hotjar "arg" %}').render(Context({}))
|
||||
),
|
||||
)
|
||||
|
||||
@override_settings(HOTJAR_SITE_ID=None)
|
||||
def test_no_id(self):
|
||||
expected_pattern = r'^HOTJAR_SITE_ID setting is not set$'
|
||||
expected_pattern = r"^HOTJAR_SITE_ID setting is not set$"
|
||||
self.assertRaisesRegex(AnalyticalException, expected_pattern, HotjarNode)
|
||||
|
||||
@override_settings(HOTJAR_SITE_ID='invalid')
|
||||
@override_settings(HOTJAR_SITE_ID="invalid")
|
||||
def test_invalid_id(self):
|
||||
expected_pattern = (
|
||||
r"^HOTJAR_SITE_ID setting: must be \(a string containing\) a number: 'invalid'$")
|
||||
r"^HOTJAR_SITE_ID setting: must be "
|
||||
r"\(a string containing\) a number: 'invalid'$"
|
||||
)
|
||||
self.assertRaisesRegex(AnalyticalException, expected_pattern, HotjarNode)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
request = HttpRequest()
|
||||
request.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': request})
|
||||
request.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": request})
|
||||
|
||||
actual_html = HotjarNode().render(context)
|
||||
disabled_html = '\n'.join([
|
||||
'<!-- Hotjar disabled on internal IP address',
|
||||
disabled_html = "\n".join(
|
||||
[
|
||||
"<!-- Hotjar disabled on internal IP address",
|
||||
expected_html,
|
||||
'-->',
|
||||
])
|
||||
"-->",
|
||||
]
|
||||
)
|
||||
self.assertEqual(disabled_html, actual_html)
|
||||
|
||||
def test_contribute_to_analytical(self):
|
||||
|
|
@ -76,9 +80,12 @@ class HotjarTagTestCase(TagTestCase):
|
|||
`hotjar.contribute_to_analytical` registers the head and body nodes.
|
||||
"""
|
||||
template_nodes = _load_template_nodes()
|
||||
self.assertEqual({
|
||||
'head_top': [],
|
||||
'head_bottom': [HotjarNode],
|
||||
'body_top': [],
|
||||
'body_bottom': [],
|
||||
}, template_nodes)
|
||||
self.assertEqual(
|
||||
{
|
||||
"head_top": [],
|
||||
"head_bottom": [HotjarNode],
|
||||
"body_top": [],
|
||||
"body_bottom": [],
|
||||
},
|
||||
template_nodes,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,41 +5,47 @@ Tests for the HubSpot template tags and filters.
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.hubspot import HubSpotNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(HUBSPOT_PORTAL_ID='1234')
|
||||
@override_settings(HUBSPOT_PORTAL_ID="1234")
|
||||
class HubSpotTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``hubspot`` template tag.
|
||||
"""
|
||||
|
||||
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)
|
||||
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,
|
||||
)
|
||||
|
||||
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):
|
||||
self.assertRaises(AnalyticalException, HubSpotNode)
|
||||
|
||||
@override_settings(HUBSPOT_PORTAL_ID='wrong')
|
||||
@override_settings(HUBSPOT_PORTAL_ID="wrong")
|
||||
def test_wrong_portal_id(self):
|
||||
self.assertRaises(AnalyticalException, HubSpotNode)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = HubSpotNode().render(context)
|
||||
self.assertTrue(r.startswith('<!-- HubSpot disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(r.startswith("<!-- HubSpot disabled on internal IP address"), r)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ from django.contrib.auth.models import User
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.intercom import IntercomNode, intercom_user_hash
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
|
|
@ -21,152 +21,201 @@ class IntercomTagTestCase(TagTestCase):
|
|||
"""
|
||||
|
||||
def test_tag(self):
|
||||
rendered_tag = self.render_tag('intercom', 'intercom')
|
||||
self.assertTrue(rendered_tag.strip().startswith('<script id="IntercomSettingsScriptTag">'))
|
||||
rendered_tag = self.render_tag("intercom", "intercom")
|
||||
self.assertTrue(
|
||||
rendered_tag.strip().startswith('<script id="IntercomSettingsScriptTag">')
|
||||
)
|
||||
|
||||
def test_node(self):
|
||||
now = datetime.datetime(2014, 4, 9, 15, 15, 0)
|
||||
user = User.objects.create(
|
||||
username='test',
|
||||
first_name='Firstname',
|
||||
last_name='Lastname',
|
||||
username="test",
|
||||
first_name="Firstname",
|
||||
last_name="Lastname",
|
||||
email="test@example.com",
|
||||
date_joined=now,
|
||||
)
|
||||
rendered_tag = IntercomNode().render(Context({'user': user}))
|
||||
rendered_tag = IntercomNode().render(Context({"user": user}))
|
||||
# Because the json isn't predictably ordered, we can't just test the whole thing verbatim.
|
||||
self.assertEqual("""
|
||||
self.assertEqual(
|
||||
"""
|
||||
<script id="IntercomSettingsScriptTag">
|
||||
window.intercomSettings = {"app_id": "abc123xyz", "created_at": 1397074500, "email": "test@example.com", "name": "Firstname Lastname", "user_id": %(user_id)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>
|
||||
""" % {'user_id': user.pk}, rendered_tag) # noqa
|
||||
""" # noqa
|
||||
% {"user_id": user.pk},
|
||||
rendered_tag,
|
||||
)
|
||||
|
||||
@override_settings(INTERCOM_APP_ID=None)
|
||||
def test_no_account_number(self):
|
||||
self.assertRaises(AnalyticalException, IntercomNode)
|
||||
|
||||
@override_settings(INTERCOM_APP_ID='123abQ')
|
||||
@override_settings(INTERCOM_APP_ID="123abQ")
|
||||
def test_wrong_account_number(self):
|
||||
self.assertRaises(AnalyticalException, IntercomNode)
|
||||
|
||||
def test_identify_name_email_and_created_at(self):
|
||||
now = datetime.datetime(2014, 4, 9, 15, 15, 0)
|
||||
user = User.objects.create(
|
||||
username='test',
|
||||
first_name='Firstname',
|
||||
last_name='Lastname',
|
||||
username="test",
|
||||
first_name="Firstname",
|
||||
last_name="Lastname",
|
||||
email="test@example.com",
|
||||
date_joined=now,
|
||||
)
|
||||
r = IntercomNode().render(Context({
|
||||
'user': user,
|
||||
}))
|
||||
self.assertTrue('window.intercomSettings = {'
|
||||
'"app_id": "abc123xyz", "created_at": 1397074500, '
|
||||
'"email": "test@example.com", "name": "Firstname Lastname", '
|
||||
'"user_id": %(user_id)s'
|
||||
'};' % {'user_id': user.pk} in r, msg=r)
|
||||
r = IntercomNode().render(
|
||||
Context(
|
||||
{
|
||||
"user": user,
|
||||
}
|
||||
)
|
||||
)
|
||||
self.assertTrue(
|
||||
"window.intercomSettings = {"
|
||||
'"app_id": "abc123xyz", "created_at": 1397074500, '
|
||||
'"email": "test@example.com", "name": "Firstname Lastname", '
|
||||
'"user_id": %(user_id)s'
|
||||
"};" % {"user_id": user.pk} in r,
|
||||
msg=r,
|
||||
)
|
||||
|
||||
def test_custom(self):
|
||||
r = IntercomNode().render(Context({
|
||||
'intercom_var1': 'val1',
|
||||
'intercom_var2': 'val2'
|
||||
}))
|
||||
r = IntercomNode().render(
|
||||
Context({"intercom_var1": "val1", "intercom_var2": "val2"})
|
||||
)
|
||||
self.assertTrue('var1": "val1", "var2": "val2"' in r)
|
||||
|
||||
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"),
|
||||
}))
|
||||
self.assertTrue('"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",
|
||||
),
|
||||
}
|
||||
)
|
||||
)
|
||||
self.assertTrue(
|
||||
'"email": "test@example.com", "name": "Firstname Lastname"' in r
|
||||
)
|
||||
|
||||
def test_identify_username_no_email(self):
|
||||
r = IntercomNode().render(Context({'user': User(username='test')}))
|
||||
r = IntercomNode().render(Context({"user": User(username="test")}))
|
||||
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)
|
||||
|
||||
@override_settings(INTERCOM_HMAC_SECRET_KEY='secret')
|
||||
@override_settings(INTERCOM_HMAC_SECRET_KEY="secret")
|
||||
def test_user_hash__without_user_details(self):
|
||||
"""
|
||||
No `user_hash` without `user_id` or `email`.
|
||||
"""
|
||||
attrs = IntercomNode()._get_custom_attrs(Context())
|
||||
self.assertEqual({
|
||||
'created_at': None,
|
||||
}, attrs)
|
||||
self.assertEqual(
|
||||
{
|
||||
"created_at": None,
|
||||
},
|
||||
attrs,
|
||||
)
|
||||
|
||||
@override_settings(INTERCOM_HMAC_SECRET_KEY='secret')
|
||||
@override_settings(INTERCOM_HMAC_SECRET_KEY="secret")
|
||||
def test_user_hash__with_user(self):
|
||||
"""
|
||||
'user_hash' of default `user_id`.
|
||||
"""
|
||||
user = User.objects.create(
|
||||
email='test@example.com',
|
||||
email="test@example.com",
|
||||
) # type: User
|
||||
attrs = IntercomNode()._get_custom_attrs(Context({'user': user}))
|
||||
self.assertEqual({
|
||||
'created_at': int(user.date_joined.timestamp()),
|
||||
'email': 'test@example.com',
|
||||
'name': '',
|
||||
'user_hash': intercom_user_hash(str(user.pk)),
|
||||
'user_id': user.pk,
|
||||
}, attrs)
|
||||
attrs = IntercomNode()._get_custom_attrs(Context({"user": user}))
|
||||
self.assertEqual(
|
||||
{
|
||||
"created_at": int(user.date_joined.timestamp()),
|
||||
"email": "test@example.com",
|
||||
"name": "",
|
||||
"user_hash": intercom_user_hash(str(user.pk)),
|
||||
"user_id": user.pk,
|
||||
},
|
||||
attrs,
|
||||
)
|
||||
|
||||
@override_settings(INTERCOM_HMAC_SECRET_KEY='secret')
|
||||
@override_settings(INTERCOM_HMAC_SECRET_KEY="secret")
|
||||
def test_user_hash__with_explicit_user_id(self):
|
||||
"""
|
||||
'user_hash' of context-provided `user_id`.
|
||||
"""
|
||||
attrs = IntercomNode()._get_custom_attrs(Context({
|
||||
'intercom_email': 'test@example.com',
|
||||
'intercom_user_id': '5',
|
||||
}))
|
||||
self.assertEqual({
|
||||
'created_at': None,
|
||||
'email': 'test@example.com',
|
||||
# HMAC for user_id:
|
||||
'user_hash': 'd3123a7052b42272d9b520235008c248a5aff3221cc0c530b754702ad91ab102',
|
||||
'user_id': '5',
|
||||
}, attrs)
|
||||
attrs = IntercomNode()._get_custom_attrs(
|
||||
Context(
|
||||
{
|
||||
"intercom_email": "test@example.com",
|
||||
"intercom_user_id": "5",
|
||||
}
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
{
|
||||
"created_at": None,
|
||||
"email": "test@example.com",
|
||||
# HMAC for user_id:
|
||||
"user_hash": "d3123a7052b42272d9b520235008c248a5aff3221cc0c530b754702ad91ab102",
|
||||
"user_id": "5",
|
||||
},
|
||||
attrs,
|
||||
)
|
||||
|
||||
@override_settings(INTERCOM_HMAC_SECRET_KEY='secret')
|
||||
@override_settings(INTERCOM_HMAC_SECRET_KEY="secret")
|
||||
def test_user_hash__with_explicit_email(self):
|
||||
"""
|
||||
'user_hash' of context-provided `email`.
|
||||
"""
|
||||
attrs = IntercomNode()._get_custom_attrs(Context({
|
||||
'intercom_email': 'test@example.com',
|
||||
}))
|
||||
self.assertEqual({
|
||||
'created_at': None,
|
||||
'email': 'test@example.com',
|
||||
# HMAC for email:
|
||||
'user_hash': '49e43229ee99dca2565241719b8341b04e71dd4de0628f991b5bea30a526e153',
|
||||
}, attrs)
|
||||
attrs = IntercomNode()._get_custom_attrs(
|
||||
Context(
|
||||
{
|
||||
"intercom_email": "test@example.com",
|
||||
}
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
{
|
||||
"created_at": None,
|
||||
"email": "test@example.com",
|
||||
# HMAC for email:
|
||||
"user_hash": "49e43229ee99dca2565241719b8341b04e71dd4de0628f991b5bea30a526e153",
|
||||
},
|
||||
attrs,
|
||||
)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = IntercomNode().render(context)
|
||||
self.assertTrue(r.startswith('<!-- Intercom disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(
|
||||
r.startswith("<!-- Intercom disabled on internal IP address"), r
|
||||
)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
|
|
|||
|
|
@ -2,23 +2,23 @@
|
|||
Tests for the KISSinsights template tags and filters.
|
||||
"""
|
||||
|
||||
from django.contrib.auth.models import User, AnonymousUser
|
||||
from django.contrib.auth.models import AnonymousUser, User
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.kiss_insights import KissInsightsNode
|
||||
from 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.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('kiss_insights', 'kiss_insights')
|
||||
r = self.render_tag("kiss_insights", "kiss_insights")
|
||||
self.assertTrue("//s3.amazonaws.com/ki.js/12345/abc.js" in r, r)
|
||||
|
||||
def test_node(self):
|
||||
|
|
@ -33,24 +33,24 @@ class KissInsightsTagTestCase(TagTestCase):
|
|||
def test_no_site_code(self):
|
||||
self.assertRaises(AnalyticalException, KissInsightsNode)
|
||||
|
||||
@override_settings(KISS_INSIGHTS_ACCOUNT_NUMBER='abcde')
|
||||
@override_settings(KISS_INSIGHTS_ACCOUNT_NUMBER="abcde")
|
||||
def test_wrong_account_number(self):
|
||||
self.assertRaises(AnalyticalException, KissInsightsNode)
|
||||
|
||||
@override_settings(KISS_INSIGHTS_SITE_CODE='abc def')
|
||||
@override_settings(KISS_INSIGHTS_SITE_CODE="abc def")
|
||||
def test_wrong_site_id(self):
|
||||
self.assertRaises(AnalyticalException, KissInsightsNode)
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_identify(self):
|
||||
r = KissInsightsNode().render(Context({'user': User(username='test')}))
|
||||
r = KissInsightsNode().render(Context({"user": User(username="test")}))
|
||||
self.assertTrue("_kiq.push(['identify', 'test']);" in r, r)
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_identify_anonymous_user(self):
|
||||
r = KissInsightsNode().render(Context({'user': AnonymousUser()}))
|
||||
r = KissInsightsNode().render(Context({"user": AnonymousUser()}))
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -2,80 +2,106 @@
|
|||
Tests for the KISSmetrics tags and filters.
|
||||
"""
|
||||
|
||||
from django.contrib.auth.models import User, AnonymousUser
|
||||
from django.contrib.auth.models import AnonymousUser, User
|
||||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.kiss_metrics import KissMetricsNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(KISS_METRICS_API_KEY='0123456789abcdef0123456789abcdef01234567')
|
||||
@override_settings(KISS_METRICS_API_KEY="0123456789abcdef0123456789abcdef01234567")
|
||||
class KissMetricsTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``kiss_metrics`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('kiss_metrics', 'kiss_metrics')
|
||||
self.assertTrue("//doug1izaerwt3.cloudfront.net/"
|
||||
"0123456789abcdef0123456789abcdef01234567.1.js" in r, r)
|
||||
r = self.render_tag("kiss_metrics", "kiss_metrics")
|
||||
self.assertTrue(
|
||||
"//doug1izaerwt3.cloudfront.net/"
|
||||
"0123456789abcdef0123456789abcdef01234567.1.js" in r,
|
||||
r,
|
||||
)
|
||||
|
||||
def test_node(self):
|
||||
r = KissMetricsNode().render(Context())
|
||||
self.assertTrue("//doug1izaerwt3.cloudfront.net/"
|
||||
"0123456789abcdef0123456789abcdef01234567.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='0123456789abcdef0123456789abcdef0123456')
|
||||
@override_settings(KISS_METRICS_API_KEY="0123456789abcdef0123456789abcdef0123456")
|
||||
def test_api_key_too_short(self):
|
||||
self.assertRaises(AnalyticalException, KissMetricsNode)
|
||||
|
||||
@override_settings(KISS_METRICS_API_KEY='0123456789abcdef0123456789abcdef012345678')
|
||||
@override_settings(KISS_METRICS_API_KEY="0123456789abcdef0123456789abcdef012345678")
|
||||
def test_api_key_too_long(self):
|
||||
self.assertRaises(AnalyticalException, KissMetricsNode)
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_identify(self):
|
||||
r = KissMetricsNode().render(Context({'user': User(username='test')}))
|
||||
r = KissMetricsNode().render(Context({"user": User(username="test")}))
|
||||
self.assertTrue("_kmq.push(['identify', 'test']);" in r, r)
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_identify_anonymous_user(self):
|
||||
r = KissMetricsNode().render(Context({'user': AnonymousUser()}))
|
||||
r = KissMetricsNode().render(Context({"user": AnonymousUser()}))
|
||||
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'}),
|
||||
}))
|
||||
self.assertTrue("_kmq.push(['record', 'test_event', "
|
||||
'{"prop1": "val1", "prop2": "val2"}]);' in r, r)
|
||||
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,
|
||||
)
|
||||
|
||||
def test_property(self):
|
||||
r = KissMetricsNode().render(Context({
|
||||
'kiss_metrics_properties': {'prop1': 'val1', 'prop2': 'val2'},
|
||||
}))
|
||||
self.assertTrue("_kmq.push([\'set\', "
|
||||
'{"prop1": "val1", "prop2": "val2"}]);' in r, r)
|
||||
r = KissMetricsNode().render(
|
||||
Context(
|
||||
{
|
||||
"kiss_metrics_properties": {"prop1": "val1", "prop2": "val2"},
|
||||
}
|
||||
)
|
||||
)
|
||||
self.assertTrue(
|
||||
"_kmq.push(['set', " '{"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'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = KissMetricsNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- KISSmetrics disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(
|
||||
r.startswith("<!-- KISSmetrics disabled on internal IP address"), r
|
||||
)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
|
|
|||
|
|
@ -4,13 +4,12 @@ Tests for the Lucky Orange template tags.
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context, Template, TemplateSyntaxError
|
||||
from django.test import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.analytical import _load_template_nodes
|
||||
from analytical.templatetags.luckyorange import LuckyOrangeNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
expected_html = """\
|
||||
<script type='text/javascript'>
|
||||
window.__lo_site_id = 123456;
|
||||
|
|
@ -23,13 +22,13 @@ window.__lo_site_id = 123456;
|
|||
"""
|
||||
|
||||
|
||||
@override_settings(LUCKYORANGE_SITE_ID='123456')
|
||||
@override_settings(LUCKYORANGE_SITE_ID="123456")
|
||||
class LuckyOrangeTagTestCase(TagTestCase):
|
||||
|
||||
maxDiff = None
|
||||
|
||||
def test_tag(self):
|
||||
html = self.render_tag('luckyorange', 'luckyorange')
|
||||
html = self.render_tag("luckyorange", "luckyorange")
|
||||
self.assertEqual(expected_html, html)
|
||||
|
||||
def test_node(self):
|
||||
|
|
@ -40,33 +39,40 @@ class LuckyOrangeTagTestCase(TagTestCase):
|
|||
self.assertRaisesRegex(
|
||||
TemplateSyntaxError,
|
||||
r"^'luckyorange' takes no arguments$",
|
||||
lambda: (Template('{% load luckyorange %}{% luckyorange "arg" %}')
|
||||
.render(Context({}))),
|
||||
lambda: (
|
||||
Template('{% load luckyorange %}{% luckyorange "arg" %}').render(
|
||||
Context({})
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
@override_settings(LUCKYORANGE_SITE_ID=None)
|
||||
def test_no_id(self):
|
||||
expected_pattern = r'^LUCKYORANGE_SITE_ID setting is not set$'
|
||||
expected_pattern = r"^LUCKYORANGE_SITE_ID setting is not set$"
|
||||
self.assertRaisesRegex(AnalyticalException, expected_pattern, LuckyOrangeNode)
|
||||
|
||||
@override_settings(LUCKYORANGE_SITE_ID='invalid')
|
||||
@override_settings(LUCKYORANGE_SITE_ID="invalid")
|
||||
def test_invalid_id(self):
|
||||
expected_pattern = (
|
||||
r"^LUCKYORANGE_SITE_ID setting: must be \(a string containing\) a number: 'invalid'$")
|
||||
r"^LUCKYORANGE_SITE_ID setting: must be "
|
||||
r"\(a string containing\) a number: 'invalid'$"
|
||||
)
|
||||
self.assertRaisesRegex(AnalyticalException, expected_pattern, LuckyOrangeNode)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
request = HttpRequest()
|
||||
request.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': request})
|
||||
request.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": request})
|
||||
|
||||
actual_html = LuckyOrangeNode().render(context)
|
||||
disabled_html = '\n'.join([
|
||||
'<!-- Lucky Orange disabled on internal IP address',
|
||||
disabled_html = "\n".join(
|
||||
[
|
||||
"<!-- Lucky Orange disabled on internal IP address",
|
||||
expected_html,
|
||||
'-->',
|
||||
])
|
||||
"-->",
|
||||
]
|
||||
)
|
||||
self.assertEqual(disabled_html, actual_html)
|
||||
|
||||
def test_contribute_to_analytical(self):
|
||||
|
|
@ -74,9 +80,12 @@ class LuckyOrangeTagTestCase(TagTestCase):
|
|||
`luckyorange.contribute_to_analytical` registers the head and body nodes.
|
||||
"""
|
||||
template_nodes = _load_template_nodes()
|
||||
self.assertEqual({
|
||||
'head_top': [],
|
||||
'head_bottom': [LuckyOrangeNode],
|
||||
'body_top': [],
|
||||
'body_bottom': [],
|
||||
}, template_nodes)
|
||||
self.assertEqual(
|
||||
{
|
||||
"head_top": [],
|
||||
"head_bottom": [LuckyOrangeNode],
|
||||
"body_top": [],
|
||||
"body_bottom": [],
|
||||
},
|
||||
template_nodes,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,48 +6,45 @@ from django.contrib.auth.models import User
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.matomo import MatomoNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(MATOMO_DOMAIN_PATH='example.com', MATOMO_SITE_ID='345')
|
||||
@override_settings(MATOMO_DOMAIN_PATH="example.com", MATOMO_SITE_ID="345")
|
||||
class MatomoTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``matomo`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('matomo', 'matomo')
|
||||
r = self.render_tag("matomo", "matomo")
|
||||
self.assertTrue('"//example.com/"' in r, r)
|
||||
self.assertTrue("_paq.push(['setSiteId', 345]);" in r, r)
|
||||
self.assertTrue('img src="//example.com/piwik.php?idsite=345"'
|
||||
in r, r)
|
||||
self.assertTrue('img src="//example.com/piwik.php?idsite=345"' in r, r)
|
||||
|
||||
def test_node(self):
|
||||
r = MatomoNode().render(Context({}))
|
||||
self.assertTrue('"//example.com/";' in r, r)
|
||||
self.assertTrue("_paq.push(['setSiteId', 345]);" in r, r)
|
||||
self.assertTrue('img src="//example.com/piwik.php?idsite=345"'
|
||||
in r, r)
|
||||
self.assertTrue('img src="//example.com/piwik.php?idsite=345"' in r, r)
|
||||
|
||||
@override_settings(MATOMO_DOMAIN_PATH='example.com/matomo',
|
||||
MATOMO_SITE_ID='345')
|
||||
@override_settings(MATOMO_DOMAIN_PATH="example.com/matomo", MATOMO_SITE_ID="345")
|
||||
def test_domain_path_valid(self):
|
||||
r = self.render_tag('matomo', 'matomo')
|
||||
r = self.render_tag("matomo", "matomo")
|
||||
self.assertTrue('"//example.com/matomo/"' in r, r)
|
||||
|
||||
@override_settings(MATOMO_DOMAIN_PATH='example.com:1234',
|
||||
MATOMO_SITE_ID='345')
|
||||
@override_settings(MATOMO_DOMAIN_PATH="example.com:1234", MATOMO_SITE_ID="345")
|
||||
def test_domain_port_valid(self):
|
||||
r = self.render_tag('matomo', 'matomo')
|
||||
r = self.render_tag("matomo", "matomo")
|
||||
self.assertTrue('"//example.com:1234/";' in r, r)
|
||||
|
||||
@override_settings(MATOMO_DOMAIN_PATH='example.com:1234/matomo',
|
||||
MATOMO_SITE_ID='345')
|
||||
@override_settings(
|
||||
MATOMO_DOMAIN_PATH="example.com:1234/matomo", MATOMO_SITE_ID="345"
|
||||
)
|
||||
def test_domain_port_path_valid(self):
|
||||
r = self.render_tag('matomo', 'matomo')
|
||||
r = self.render_tag("matomo", "matomo")
|
||||
self.assertTrue('"//example.com:1234/matomo/"' in r, r)
|
||||
|
||||
@override_settings(MATOMO_DOMAIN_PATH=None)
|
||||
|
|
@ -58,91 +55,98 @@ class MatomoTagTestCase(TagTestCase):
|
|||
def test_no_siteid(self):
|
||||
self.assertRaises(AnalyticalException, MatomoNode)
|
||||
|
||||
@override_settings(MATOMO_SITE_ID='x')
|
||||
@override_settings(MATOMO_SITE_ID="x")
|
||||
def test_siteid_not_a_number(self):
|
||||
self.assertRaises(AnalyticalException, MatomoNode)
|
||||
|
||||
@override_settings(MATOMO_DOMAIN_PATH='http://www.example.com')
|
||||
@override_settings(MATOMO_DOMAIN_PATH="http://www.example.com")
|
||||
def test_domain_protocol_invalid(self):
|
||||
self.assertRaises(AnalyticalException, MatomoNode)
|
||||
|
||||
@override_settings(MATOMO_DOMAIN_PATH='example.com/')
|
||||
@override_settings(MATOMO_DOMAIN_PATH="example.com/")
|
||||
def test_domain_slash_invalid(self):
|
||||
self.assertRaises(AnalyticalException, MatomoNode)
|
||||
|
||||
@override_settings(MATOMO_DOMAIN_PATH='example.com:123:456')
|
||||
@override_settings(MATOMO_DOMAIN_PATH="example.com:123:456")
|
||||
def test_domain_multi_port(self):
|
||||
self.assertRaises(AnalyticalException, MatomoNode)
|
||||
|
||||
@override_settings(MATOMO_DOMAIN_PATH='example.com:')
|
||||
@override_settings(MATOMO_DOMAIN_PATH="example.com:")
|
||||
def test_domain_incomplete_port(self):
|
||||
self.assertRaises(AnalyticalException, MatomoNode)
|
||||
|
||||
@override_settings(MATOMO_DOMAIN_PATH='example.com:/matomo')
|
||||
@override_settings(MATOMO_DOMAIN_PATH="example.com:/matomo")
|
||||
def test_domain_uri_incomplete_port(self):
|
||||
self.assertRaises(AnalyticalException, MatomoNode)
|
||||
|
||||
@override_settings(MATOMO_DOMAIN_PATH='example.com:12df')
|
||||
@override_settings(MATOMO_DOMAIN_PATH="example.com:12df")
|
||||
def test_domain_port_invalid(self):
|
||||
self.assertRaises(AnalyticalException, MatomoNode)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = MatomoNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Matomo disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(r.startswith("<!-- Matomo disabled on internal IP address"), r)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
||||
def test_uservars(self):
|
||||
context = Context({'matomo_vars': [(1, 'foo', 'foo_val'),
|
||||
(2, 'bar', 'bar_val', 'page'),
|
||||
(3, 'spam', 'spam_val', 'visit')]})
|
||||
context = Context(
|
||||
{
|
||||
"matomo_vars": [
|
||||
(1, "foo", "foo_val"),
|
||||
(2, "bar", "bar_val", "page"),
|
||||
(3, "spam", "spam_val", "visit"),
|
||||
]
|
||||
}
|
||||
)
|
||||
r = MatomoNode().render(context)
|
||||
msg = 'Incorrect Matomo custom variable rendering. Expected:\n%s\nIn:\n%s'
|
||||
for var_code in ['_paq.push(["setCustomVariable", 1, "foo", "foo_val", "page"]);',
|
||||
'_paq.push(["setCustomVariable", 2, "bar", "bar_val", "page"]);',
|
||||
'_paq.push(["setCustomVariable", 3, "spam", "spam_val", "visit"]);']:
|
||||
msg = "Incorrect Matomo custom variable rendering. Expected:\n%s\nIn:\n%s"
|
||||
for var_code in [
|
||||
'_paq.push(["setCustomVariable", 1, "foo", "foo_val", "page"]);',
|
||||
'_paq.push(["setCustomVariable", 2, "bar", "bar_val", "page"]);',
|
||||
'_paq.push(["setCustomVariable", 3, "spam", "spam_val", "visit"]);',
|
||||
]:
|
||||
self.assertIn(var_code, r, msg % (var_code, r))
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_default_usertrack(self):
|
||||
context = Context({
|
||||
'user': User(username='BDFL', first_name='Guido', last_name='van Rossum')
|
||||
})
|
||||
context = Context(
|
||||
{"user": User(username="BDFL", first_name="Guido", last_name="van Rossum")}
|
||||
)
|
||||
r = MatomoNode().render(context)
|
||||
msg = 'Incorrect Matomo user tracking rendering.\nNot found:\n%s\nIn:\n%s'
|
||||
msg = "Incorrect Matomo user tracking rendering.\nNot found:\n%s\nIn:\n%s"
|
||||
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
||||
self.assertIn(var_code, r, msg % (var_code, r))
|
||||
|
||||
def test_matomo_usertrack(self):
|
||||
context = Context({
|
||||
'matomo_identity': 'BDFL'
|
||||
})
|
||||
context = Context({"matomo_identity": "BDFL"})
|
||||
r = MatomoNode().render(context)
|
||||
msg = 'Incorrect Matomo user tracking rendering.\nNot found:\n%s\nIn:\n%s'
|
||||
msg = "Incorrect Matomo user tracking rendering.\nNot found:\n%s\nIn:\n%s"
|
||||
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
||||
self.assertIn(var_code, r, msg % (var_code, r))
|
||||
|
||||
def test_analytical_usertrack(self):
|
||||
context = Context({
|
||||
'analytical_identity': 'BDFL'
|
||||
})
|
||||
context = Context({"analytical_identity": "BDFL"})
|
||||
r = MatomoNode().render(context)
|
||||
msg = 'Incorrect Matomo user tracking rendering.\nNot found:\n%s\nIn:\n%s'
|
||||
msg = "Incorrect Matomo user tracking rendering.\nNot found:\n%s\nIn:\n%s"
|
||||
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
||||
self.assertIn(var_code, r, msg % (var_code, r))
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_disable_usertrack(self):
|
||||
context = Context({
|
||||
'user': User(username='BDFL', first_name='Guido', last_name='van Rossum'),
|
||||
'matomo_identity': None
|
||||
})
|
||||
context = Context(
|
||||
{
|
||||
"user": User(
|
||||
username="BDFL", first_name="Guido", last_name="van Rossum"
|
||||
),
|
||||
"matomo_identity": None,
|
||||
}
|
||||
)
|
||||
r = MatomoNode().render(context)
|
||||
msg = 'Incorrect Matomo user tracking rendering.\nFound:\n%s\nIn:\n%s'
|
||||
msg = "Incorrect Matomo user tracking rendering.\nFound:\n%s\nIn:\n%s"
|
||||
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
||||
self.assertNotIn(var_code, r, msg % (var_code, r))
|
||||
|
||||
|
|
|
|||
|
|
@ -2,24 +2,24 @@
|
|||
Tests for the Mixpanel tags and filters.
|
||||
"""
|
||||
|
||||
from django.contrib.auth.models import User, AnonymousUser
|
||||
from django.contrib.auth.models import AnonymousUser, User
|
||||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.mixpanel import MixpanelNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(MIXPANEL_API_TOKEN='0123456789abcdef0123456789abcdef')
|
||||
@override_settings(MIXPANEL_API_TOKEN="0123456789abcdef0123456789abcdef")
|
||||
class MixpanelTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``mixpanel`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('mixpanel', 'mixpanel')
|
||||
r = self.render_tag("mixpanel", "mixpanel")
|
||||
self.assertIn("mixpanel.init('0123456789abcdef0123456789abcdef');", r)
|
||||
|
||||
def test_node(self):
|
||||
|
|
@ -30,37 +30,47 @@ class MixpanelTagTestCase(TagTestCase):
|
|||
def test_no_token(self):
|
||||
self.assertRaises(AnalyticalException, MixpanelNode)
|
||||
|
||||
@override_settings(MIXPANEL_API_TOKEN='0123456789abcdef0123456789abcdef0')
|
||||
@override_settings(MIXPANEL_API_TOKEN="0123456789abcdef0123456789abcdef0")
|
||||
def test_token_too_long(self):
|
||||
self.assertRaises(AnalyticalException, MixpanelNode)
|
||||
|
||||
@override_settings(MIXPANEL_API_TOKEN='0123456789abcdef0123456789abcde')
|
||||
@override_settings(MIXPANEL_API_TOKEN="0123456789abcdef0123456789abcde")
|
||||
def test_token_too_short(self):
|
||||
self.assertRaises(AnalyticalException, MixpanelNode)
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_identify(self):
|
||||
r = MixpanelNode().render(Context({'user': User(username='test')}))
|
||||
r = MixpanelNode().render(Context({"user": User(username="test")}))
|
||||
self.assertIn("mixpanel.identify('test');", r)
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_identify_anonymous_user(self):
|
||||
r = MixpanelNode().render(Context({'user': AnonymousUser()}))
|
||||
r = MixpanelNode().render(Context({"user": AnonymousUser()}))
|
||||
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'}),
|
||||
}))
|
||||
self.assertTrue("mixpanel.track('test_event', "
|
||||
'{"prop1": "val1", "prop2": "val2"});' in r, r)
|
||||
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,
|
||||
)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = MixpanelNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Mixpanel disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(
|
||||
r.startswith("<!-- Mixpanel disabled on internal IP address"), r
|
||||
)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
|
|
|||
|
|
@ -2,23 +2,23 @@
|
|||
Tests for the Olark template tags and filters.
|
||||
"""
|
||||
|
||||
from django.contrib.auth.models import User, AnonymousUser
|
||||
from django.contrib.auth.models import AnonymousUser, User
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.olark import OlarkNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(OLARK_SITE_ID='1234-567-89-0123')
|
||||
@override_settings(OLARK_SITE_ID="1234-567-89-0123")
|
||||
class OlarkTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``olark`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('olark', 'olark')
|
||||
r = self.render_tag("olark", "olark")
|
||||
self.assertTrue("olark.identify('1234-567-89-0123');" in r, r)
|
||||
|
||||
def test_node(self):
|
||||
|
|
@ -29,39 +29,55 @@ class OlarkTestCase(TagTestCase):
|
|||
def test_no_site_id(self):
|
||||
self.assertRaises(AnalyticalException, OlarkNode)
|
||||
|
||||
@override_settings(OLARK_SITE_ID='1234-567-8901234')
|
||||
@override_settings(OLARK_SITE_ID="1234-567-8901234")
|
||||
def test_wrong_site_id(self):
|
||||
self.assertRaises(AnalyticalException, OlarkNode)
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_identify(self):
|
||||
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)
|
||||
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,
|
||||
)
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_identify_anonymous_user(self):
|
||||
r = OlarkNode().render(Context({'user': AnonymousUser()}))
|
||||
r = OlarkNode().render(Context({"user": AnonymousUser()}))
|
||||
self.assertFalse("olark('api.chat.updateVisitorNickname', " in r, r)
|
||||
|
||||
def test_nickname(self):
|
||||
r = OlarkNode().render(Context({'olark_nickname': 'testnick'}))
|
||||
self.assertTrue("olark('api.chat.updateVisitorNickname', "
|
||||
"{snippet: 'testnick'});" in r, r)
|
||||
r = OlarkNode().render(Context({"olark_nickname": "testnick"}))
|
||||
self.assertTrue(
|
||||
"olark('api.chat.updateVisitorNickname', " "{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)
|
||||
r = OlarkNode().render(Context({"olark_status": "teststatus"}))
|
||||
self.assertTrue(
|
||||
"olark('api.chat.updateVisitorStatus', " '{snippet: "teststatus"});' in r, r
|
||||
)
|
||||
|
||||
def test_status_string_list(self):
|
||||
r = OlarkNode().render(Context({
|
||||
'olark_status': ['teststatus1', 'teststatus2'],
|
||||
}))
|
||||
self.assertTrue("olark('api.chat.updateVisitorStatus', "
|
||||
'{snippet: ["teststatus1", "teststatus2"]});' in r, r)
|
||||
r = OlarkNode().render(
|
||||
Context(
|
||||
{
|
||||
"olark_status": ["teststatus1", "teststatus2"],
|
||||
}
|
||||
)
|
||||
)
|
||||
self.assertTrue(
|
||||
"olark('api.chat.updateVisitorStatus', "
|
||||
'{snippet: ["teststatus1", "teststatus2"]});' in r,
|
||||
r,
|
||||
)
|
||||
|
||||
def test_messages(self):
|
||||
messages = [
|
||||
|
|
@ -87,7 +103,7 @@ class OlarkTestCase(TagTestCase):
|
|||
"introduction_messages",
|
||||
"introduction_submit_button_text",
|
||||
]
|
||||
vars = {'olark_%s' % m: m for m in messages}
|
||||
vars = {"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)
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ Tests for the Optimizely template tags and filters.
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.optimizely import OptimizelyNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(OPTIMIZELY_ACCOUNT_NUMBER='1234567')
|
||||
@override_settings(OPTIMIZELY_ACCOUNT_NUMBER="1234567")
|
||||
class OptimizelyTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``optimizely`` template tag.
|
||||
|
|
@ -19,28 +19,31 @@ class OptimizelyTagTestCase(TagTestCase):
|
|||
|
||||
def test_tag(self):
|
||||
self.assertEqual(
|
||||
'<script src="//cdn.optimizely.com/js/1234567.js"></script>',
|
||||
self.render_tag('optimizely', 'optimizely'))
|
||||
'<script src="//cdn.optimizely.com/js/1234567.js"></script>',
|
||||
self.render_tag("optimizely", "optimizely"),
|
||||
)
|
||||
|
||||
def test_node(self):
|
||||
self.assertEqual(
|
||||
'<script src="//cdn.optimizely.com/js/1234567.js"></script>',
|
||||
OptimizelyNode().render(Context()))
|
||||
'<script src="//cdn.optimizely.com/js/1234567.js"></script>',
|
||||
OptimizelyNode().render(Context()),
|
||||
)
|
||||
|
||||
@override_settings(OPTIMIZELY_ACCOUNT_NUMBER=None)
|
||||
def test_no_account_number(self):
|
||||
self.assertRaises(AnalyticalException, OptimizelyNode)
|
||||
|
||||
@override_settings(OPTIMIZELY_ACCOUNT_NUMBER='123abc')
|
||||
@override_settings(OPTIMIZELY_ACCOUNT_NUMBER="123abc")
|
||||
def test_wrong_account_number(self):
|
||||
self.assertRaises(AnalyticalException, OptimizelyNode)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = OptimizelyNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Optimizely disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(
|
||||
r.startswith("<!-- Optimizely disabled on internal IP address"), r
|
||||
)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
|
|
|||
|
|
@ -2,56 +2,57 @@
|
|||
Tests for the Performable template tags and filters.
|
||||
"""
|
||||
|
||||
from django.contrib.auth.models import User, AnonymousUser
|
||||
from django.contrib.auth.models import AnonymousUser, User
|
||||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.performable import PerformableNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(PERFORMABLE_API_KEY='123ABC')
|
||||
@override_settings(PERFORMABLE_API_KEY="123ABC")
|
||||
class PerformableTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``performable`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('performable', 'performable')
|
||||
self.assertTrue('/performable/pax/123ABC.js' in r, r)
|
||||
r = self.render_tag("performable", "performable")
|
||||
self.assertTrue("/performable/pax/123ABC.js" in r, r)
|
||||
|
||||
def test_node(self):
|
||||
r = PerformableNode().render(Context())
|
||||
self.assertTrue('/performable/pax/123ABC.js' in r, r)
|
||||
self.assertTrue("/performable/pax/123ABC.js" in r, r)
|
||||
|
||||
@override_settings(PERFORMABLE_API_KEY=None)
|
||||
def test_no_api_key(self):
|
||||
self.assertRaises(AnalyticalException, PerformableNode)
|
||||
|
||||
@override_settings(PERFORMABLE_API_KEY='123 ABC')
|
||||
@override_settings(PERFORMABLE_API_KEY="123 ABC")
|
||||
def test_wrong_account_number(self):
|
||||
self.assertRaises(AnalyticalException, PerformableNode)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = PerformableNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Performable disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(
|
||||
r.startswith("<!-- Performable disabled on internal IP address"), r
|
||||
)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_identify(self):
|
||||
r = PerformableNode().render(Context({'user': User(username='test')}))
|
||||
r = PerformableNode().render(Context({"user": User(username="test")}))
|
||||
self.assertTrue('_paq.push(["identify", {identity: "test"}]);' in r, r)
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_identify_anonymous_user(self):
|
||||
r = PerformableNode().render(Context({'user': AnonymousUser()}))
|
||||
r = PerformableNode().render(Context({"user": AnonymousUser()}))
|
||||
self.assertFalse('_paq.push(["identify", ' in r, r)
|
||||
|
||||
|
||||
|
|
@ -61,11 +62,9 @@ class PerformableEmbedTagTestCase(TagTestCase):
|
|||
"""
|
||||
|
||||
def test_tag(self):
|
||||
domain = 'example.com'
|
||||
page = 'test'
|
||||
domain = "example.com"
|
||||
page = "test"
|
||||
tag = self.render_tag(
|
||||
'performable', 'performable_embed "%s" "%s"' % (domain, page)
|
||||
)
|
||||
self.assertIn(
|
||||
"$f.initialize({'host': 'example.com', 'page': 'test'});", tag
|
||||
"performable", 'performable_embed "%s" "%s"' % (domain, page)
|
||||
)
|
||||
self.assertIn("$f.initialize({'host': 'example.com', 'page': 'test'});", tag)
|
||||
|
|
|
|||
|
|
@ -6,48 +6,43 @@ from django.contrib.auth.models import User
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.piwik import PiwikNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(PIWIK_DOMAIN_PATH='example.com', PIWIK_SITE_ID='345')
|
||||
@override_settings(PIWIK_DOMAIN_PATH="example.com", PIWIK_SITE_ID="345")
|
||||
class PiwikTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``piwik`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('piwik', 'piwik')
|
||||
r = self.render_tag("piwik", "piwik")
|
||||
self.assertTrue('"//example.com/"' in r, r)
|
||||
self.assertTrue("_paq.push(['setSiteId', 345]);" in r, r)
|
||||
self.assertTrue('img src="//example.com/piwik.php?idsite=345"'
|
||||
in r, r)
|
||||
self.assertTrue('img src="//example.com/piwik.php?idsite=345"' in r, r)
|
||||
|
||||
def test_node(self):
|
||||
r = PiwikNode().render(Context({}))
|
||||
self.assertTrue('"//example.com/";' in r, r)
|
||||
self.assertTrue("_paq.push(['setSiteId', 345]);" in r, r)
|
||||
self.assertTrue('img src="//example.com/piwik.php?idsite=345"'
|
||||
in r, r)
|
||||
self.assertTrue('img src="//example.com/piwik.php?idsite=345"' in r, r)
|
||||
|
||||
@override_settings(PIWIK_DOMAIN_PATH='example.com/piwik',
|
||||
PIWIK_SITE_ID='345')
|
||||
@override_settings(PIWIK_DOMAIN_PATH="example.com/piwik", PIWIK_SITE_ID="345")
|
||||
def test_domain_path_valid(self):
|
||||
r = self.render_tag('piwik', 'piwik')
|
||||
r = self.render_tag("piwik", "piwik")
|
||||
self.assertTrue('"//example.com/piwik/"' in r, r)
|
||||
|
||||
@override_settings(PIWIK_DOMAIN_PATH='example.com:1234',
|
||||
PIWIK_SITE_ID='345')
|
||||
@override_settings(PIWIK_DOMAIN_PATH="example.com:1234", PIWIK_SITE_ID="345")
|
||||
def test_domain_port_valid(self):
|
||||
r = self.render_tag('piwik', 'piwik')
|
||||
r = self.render_tag("piwik", "piwik")
|
||||
self.assertTrue('"//example.com:1234/";' in r, r)
|
||||
|
||||
@override_settings(PIWIK_DOMAIN_PATH='example.com:1234/piwik',
|
||||
PIWIK_SITE_ID='345')
|
||||
@override_settings(PIWIK_DOMAIN_PATH="example.com:1234/piwik", PIWIK_SITE_ID="345")
|
||||
def test_domain_port_path_valid(self):
|
||||
r = self.render_tag('piwik', 'piwik')
|
||||
r = self.render_tag("piwik", "piwik")
|
||||
self.assertTrue('"//example.com:1234/piwik/"' in r, r)
|
||||
|
||||
@override_settings(PIWIK_DOMAIN_PATH=None)
|
||||
|
|
@ -58,91 +53,98 @@ class PiwikTagTestCase(TagTestCase):
|
|||
def test_no_siteid(self):
|
||||
self.assertRaises(AnalyticalException, PiwikNode)
|
||||
|
||||
@override_settings(PIWIK_SITE_ID='x')
|
||||
@override_settings(PIWIK_SITE_ID="x")
|
||||
def test_siteid_not_a_number(self):
|
||||
self.assertRaises(AnalyticalException, PiwikNode)
|
||||
|
||||
@override_settings(PIWIK_DOMAIN_PATH='http://www.example.com')
|
||||
@override_settings(PIWIK_DOMAIN_PATH="http://www.example.com")
|
||||
def test_domain_protocol_invalid(self):
|
||||
self.assertRaises(AnalyticalException, PiwikNode)
|
||||
|
||||
@override_settings(PIWIK_DOMAIN_PATH='example.com/')
|
||||
@override_settings(PIWIK_DOMAIN_PATH="example.com/")
|
||||
def test_domain_slash_invalid(self):
|
||||
self.assertRaises(AnalyticalException, PiwikNode)
|
||||
|
||||
@override_settings(PIWIK_DOMAIN_PATH='example.com:123:456')
|
||||
@override_settings(PIWIK_DOMAIN_PATH="example.com:123:456")
|
||||
def test_domain_multi_port(self):
|
||||
self.assertRaises(AnalyticalException, PiwikNode)
|
||||
|
||||
@override_settings(PIWIK_DOMAIN_PATH='example.com:')
|
||||
@override_settings(PIWIK_DOMAIN_PATH="example.com:")
|
||||
def test_domain_incomplete_port(self):
|
||||
self.assertRaises(AnalyticalException, PiwikNode)
|
||||
|
||||
@override_settings(PIWIK_DOMAIN_PATH='example.com:/piwik')
|
||||
@override_settings(PIWIK_DOMAIN_PATH="example.com:/piwik")
|
||||
def test_domain_uri_incomplete_port(self):
|
||||
self.assertRaises(AnalyticalException, PiwikNode)
|
||||
|
||||
@override_settings(PIWIK_DOMAIN_PATH='example.com:12df')
|
||||
@override_settings(PIWIK_DOMAIN_PATH="example.com:12df")
|
||||
def test_domain_port_invalid(self):
|
||||
self.assertRaises(AnalyticalException, PiwikNode)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = PiwikNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Piwik disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(r.startswith("<!-- Piwik disabled on internal IP address"), r)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
||||
def test_uservars(self):
|
||||
context = Context({'piwik_vars': [(1, 'foo', 'foo_val'),
|
||||
(2, 'bar', 'bar_val', 'page'),
|
||||
(3, 'spam', 'spam_val', 'visit')]})
|
||||
context = Context(
|
||||
{
|
||||
"piwik_vars": [
|
||||
(1, "foo", "foo_val"),
|
||||
(2, "bar", "bar_val", "page"),
|
||||
(3, "spam", "spam_val", "visit"),
|
||||
]
|
||||
}
|
||||
)
|
||||
r = PiwikNode().render(context)
|
||||
msg = 'Incorrect Piwik custom variable rendering. Expected:\n%s\nIn:\n%s'
|
||||
for var_code in ['_paq.push(["setCustomVariable", 1, "foo", "foo_val", "page"]);',
|
||||
'_paq.push(["setCustomVariable", 2, "bar", "bar_val", "page"]);',
|
||||
'_paq.push(["setCustomVariable", 3, "spam", "spam_val", "visit"]);']:
|
||||
msg = "Incorrect Piwik custom variable rendering. Expected:\n%s\nIn:\n%s"
|
||||
for var_code in [
|
||||
'_paq.push(["setCustomVariable", 1, "foo", "foo_val", "page"]);',
|
||||
'_paq.push(["setCustomVariable", 2, "bar", "bar_val", "page"]);',
|
||||
'_paq.push(["setCustomVariable", 3, "spam", "spam_val", "visit"]);',
|
||||
]:
|
||||
self.assertIn(var_code, r, msg % (var_code, r))
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_default_usertrack(self):
|
||||
context = Context({
|
||||
'user': User(username='BDFL', first_name='Guido', last_name='van Rossum')
|
||||
})
|
||||
context = Context(
|
||||
{"user": User(username="BDFL", first_name="Guido", last_name="van Rossum")}
|
||||
)
|
||||
r = PiwikNode().render(context)
|
||||
msg = 'Incorrect Piwik user tracking rendering.\nNot found:\n%s\nIn:\n%s'
|
||||
msg = "Incorrect Piwik user tracking rendering.\nNot found:\n%s\nIn:\n%s"
|
||||
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
||||
self.assertIn(var_code, r, msg % (var_code, r))
|
||||
|
||||
def test_piwik_usertrack(self):
|
||||
context = Context({
|
||||
'piwik_identity': 'BDFL'
|
||||
})
|
||||
context = Context({"piwik_identity": "BDFL"})
|
||||
r = PiwikNode().render(context)
|
||||
msg = 'Incorrect Piwik user tracking rendering.\nNot found:\n%s\nIn:\n%s'
|
||||
msg = "Incorrect Piwik user tracking rendering.\nNot found:\n%s\nIn:\n%s"
|
||||
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
||||
self.assertIn(var_code, r, msg % (var_code, r))
|
||||
|
||||
def test_analytical_usertrack(self):
|
||||
context = Context({
|
||||
'analytical_identity': 'BDFL'
|
||||
})
|
||||
context = Context({"analytical_identity": "BDFL"})
|
||||
r = PiwikNode().render(context)
|
||||
msg = 'Incorrect Piwik user tracking rendering.\nNot found:\n%s\nIn:\n%s'
|
||||
msg = "Incorrect Piwik user tracking rendering.\nNot found:\n%s\nIn:\n%s"
|
||||
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
||||
self.assertIn(var_code, r, msg % (var_code, r))
|
||||
|
||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
def test_disable_usertrack(self):
|
||||
context = Context({
|
||||
'user': User(username='BDFL', first_name='Guido', last_name='van Rossum'),
|
||||
'piwik_identity': None
|
||||
})
|
||||
context = Context(
|
||||
{
|
||||
"user": User(
|
||||
username="BDFL", first_name="Guido", last_name="van Rossum"
|
||||
),
|
||||
"piwik_identity": None,
|
||||
}
|
||||
)
|
||||
r = PiwikNode().render(context)
|
||||
msg = 'Incorrect Piwik user tracking rendering.\nFound:\n%s\nIn:\n%s'
|
||||
msg = "Incorrect Piwik user tracking rendering.\nFound:\n%s\nIn:\n%s"
|
||||
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
||||
self.assertNotIn(var_code, r, msg % (var_code, r))
|
||||
|
||||
|
|
|
|||
|
|
@ -5,20 +5,20 @@ Tests for the Rating@Mail.ru template tags and filters.
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.rating_mailru import RatingMailruNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(RATING_MAILRU_COUNTER_ID='1234567')
|
||||
@override_settings(RATING_MAILRU_COUNTER_ID="1234567")
|
||||
class RatingMailruTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``rating_mailru`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('rating_mailru', 'rating_mailru')
|
||||
r = self.render_tag("rating_mailru", "rating_mailru")
|
||||
self.assertTrue("counter?id=1234567;js=na" in r, r)
|
||||
|
||||
def test_node(self):
|
||||
|
|
@ -29,16 +29,17 @@ class RatingMailruTagTestCase(TagTestCase):
|
|||
def test_no_site_id(self):
|
||||
self.assertRaises(AnalyticalException, RatingMailruNode)
|
||||
|
||||
@override_settings(RATING_MAILRU_COUNTER_ID='1234abc')
|
||||
@override_settings(RATING_MAILRU_COUNTER_ID="1234abc")
|
||||
def test_wrong_site_id(self):
|
||||
self.assertRaises(AnalyticalException, RatingMailruNode)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = RatingMailruNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Rating@Mail.ru disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(
|
||||
r.startswith("<!-- Rating@Mail.ru disabled on internal IP address"), r
|
||||
)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
|
|
|||
|
|
@ -2,20 +2,26 @@
|
|||
Tests for the SnapEngage template tags and filters.
|
||||
"""
|
||||
|
||||
from django.contrib.auth.models import User, AnonymousUser
|
||||
from django.contrib.auth.models import AnonymousUser, User
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from django.utils import translation
|
||||
|
||||
from analytical.templatetags.snapengage import SnapEngageNode, \
|
||||
BUTTON_STYLE_LIVE, BUTTON_STYLE_DEFAULT, BUTTON_STYLE_NONE, \
|
||||
BUTTON_LOCATION_LEFT, BUTTON_LOCATION_RIGHT, BUTTON_LOCATION_TOP, \
|
||||
BUTTON_LOCATION_BOTTOM, FORM_POSITION_TOP_LEFT
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.snapengage import (
|
||||
BUTTON_LOCATION_BOTTOM,
|
||||
BUTTON_LOCATION_LEFT,
|
||||
BUTTON_LOCATION_RIGHT,
|
||||
BUTTON_LOCATION_TOP,
|
||||
BUTTON_STYLE_DEFAULT,
|
||||
BUTTON_STYLE_LIVE,
|
||||
BUTTON_STYLE_NONE,
|
||||
FORM_POSITION_TOP_LEFT,
|
||||
SnapEngageNode,
|
||||
)
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
WIDGET_ID = 'ec329c69-0bf0-4db8-9b77-3f8150fb977e'
|
||||
WIDGET_ID = "ec329c69-0bf0-4db8-9b77-3f8150fb977e"
|
||||
|
||||
|
||||
@override_settings(
|
||||
|
|
@ -30,246 +36,343 @@ class SnapEngageTestCase(TagTestCase):
|
|||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('snapengage', 'snapengage')
|
||||
r = self.render_tag("snapengage", "snapengage")
|
||||
self.assertTrue(
|
||||
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0",'
|
||||
'"55%");' in r, r)
|
||||
'"55%");' in r,
|
||||
r,
|
||||
)
|
||||
|
||||
def test_node(self):
|
||||
r = SnapEngageNode().render(Context())
|
||||
self.assertTrue(
|
||||
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0",'
|
||||
'"55%");' in r, r)
|
||||
'"55%");' in r,
|
||||
r,
|
||||
)
|
||||
|
||||
@override_settings(SNAPENGAGE_WIDGET_ID=None)
|
||||
def test_no_site_id(self):
|
||||
self.assertRaises(AnalyticalException, SnapEngageNode)
|
||||
|
||||
@override_settings(SNAPENGAGE_WIDGET_ID='abc')
|
||||
@override_settings(SNAPENGAGE_WIDGET_ID="abc")
|
||||
def test_wrong_site_id(self):
|
||||
self.assertRaises(AnalyticalException, SnapEngageNode)
|
||||
|
||||
def test_no_button(self):
|
||||
r = SnapEngageNode().render(Context({
|
||||
'snapengage_button': BUTTON_STYLE_NONE,
|
||||
}))
|
||||
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)
|
||||
'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)
|
||||
'"55%",true);' in r,
|
||||
r,
|
||||
)
|
||||
with override_settings(SNAPENGAGE_BUTTON=BUTTON_STYLE_LIVE):
|
||||
r = SnapEngageNode().render(Context())
|
||||
self.assertTrue(
|
||||
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0",'
|
||||
'"55%",true);' in r, r)
|
||||
'"55%",true);' in r,
|
||||
r,
|
||||
)
|
||||
|
||||
def test_custom_button(self):
|
||||
r = SnapEngageNode().render(Context({
|
||||
'snapengage_button': "http://www.example.com/button.png",
|
||||
}))
|
||||
r = SnapEngageNode().render(
|
||||
Context(
|
||||
{
|
||||
"snapengage_button": "http://www.example.com/button.png",
|
||||
}
|
||||
)
|
||||
)
|
||||
self.assertTrue(
|
||||
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0",'
|
||||
'"55%");' in r, r)
|
||||
'"55%");' in r,
|
||||
r,
|
||||
)
|
||||
self.assertTrue(
|
||||
'SnapABug.setButton("http://www.example.com/button.png");' in r, r)
|
||||
with override_settings(
|
||||
SNAPENGAGE_BUTTON="http://www.example.com/button.png"):
|
||||
'SnapABug.setButton("http://www.example.com/button.png");' in r, r
|
||||
)
|
||||
with override_settings(SNAPENGAGE_BUTTON="http://www.example.com/button.png"):
|
||||
r = SnapEngageNode().render(Context())
|
||||
self.assertTrue(
|
||||
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0",'
|
||||
'"55%");' in r, r)
|
||||
'"55%");' in r,
|
||||
r,
|
||||
)
|
||||
self.assertTrue(
|
||||
'SnapABug.setButton("http://www.example.com/button.png");' in r,
|
||||
r)
|
||||
'SnapABug.setButton("http://www.example.com/button.png");' in r, r
|
||||
)
|
||||
|
||||
def test_button_location_right(self):
|
||||
r = SnapEngageNode().render(Context({
|
||||
'snapengage_button_location': BUTTON_LOCATION_RIGHT,
|
||||
}))
|
||||
r = SnapEngageNode().render(
|
||||
Context(
|
||||
{
|
||||
"snapengage_button_location": BUTTON_LOCATION_RIGHT,
|
||||
}
|
||||
)
|
||||
)
|
||||
self.assertTrue(
|
||||
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","1",'
|
||||
'"55%");' in r, r)
|
||||
'"55%");' in r,
|
||||
r,
|
||||
)
|
||||
with override_settings(SNAPENGAGE_BUTTON_LOCATION=BUTTON_LOCATION_RIGHT):
|
||||
r = SnapEngageNode().render(Context())
|
||||
self.assertTrue(
|
||||
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","1",'
|
||||
'"55%");' in r, r)
|
||||
'"55%");' in r,
|
||||
r,
|
||||
)
|
||||
|
||||
def test_button_location_top(self):
|
||||
r = SnapEngageNode().render(Context({
|
||||
'snapengage_button_location': BUTTON_LOCATION_TOP,
|
||||
}))
|
||||
r = SnapEngageNode().render(
|
||||
Context(
|
||||
{
|
||||
"snapengage_button_location": BUTTON_LOCATION_TOP,
|
||||
}
|
||||
)
|
||||
)
|
||||
self.assertTrue(
|
||||
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","2",'
|
||||
'"55%");' in r, r)
|
||||
'"55%");' in r,
|
||||
r,
|
||||
)
|
||||
with override_settings(SNAPENGAGE_BUTTON_LOCATION=BUTTON_LOCATION_TOP):
|
||||
r = SnapEngageNode().render(Context())
|
||||
self.assertTrue(
|
||||
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","2",'
|
||||
'"55%");' in r, r)
|
||||
'"55%");' in r,
|
||||
r,
|
||||
)
|
||||
|
||||
def test_button_location_bottom(self):
|
||||
r = SnapEngageNode().render(Context({
|
||||
'snapengage_button_location': BUTTON_LOCATION_BOTTOM,
|
||||
}))
|
||||
r = SnapEngageNode().render(
|
||||
Context(
|
||||
{
|
||||
"snapengage_button_location": BUTTON_LOCATION_BOTTOM,
|
||||
}
|
||||
)
|
||||
)
|
||||
self.assertTrue(
|
||||
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","3",'
|
||||
'"55%");' in r, r)
|
||||
with override_settings(
|
||||
SNAPENGAGE_BUTTON_LOCATION=BUTTON_LOCATION_BOTTOM):
|
||||
'"55%");' in r,
|
||||
r,
|
||||
)
|
||||
with override_settings(SNAPENGAGE_BUTTON_LOCATION=BUTTON_LOCATION_BOTTOM):
|
||||
r = SnapEngageNode().render(Context())
|
||||
self.assertTrue(
|
||||
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","3",'
|
||||
'"55%");' in r, r)
|
||||
'"55%");' in r,
|
||||
r,
|
||||
)
|
||||
|
||||
def test_button_offset(self):
|
||||
r = SnapEngageNode().render(Context({
|
||||
'snapengage_button_location_offset': "30%",
|
||||
}))
|
||||
r = SnapEngageNode().render(
|
||||
Context(
|
||||
{
|
||||
"snapengage_button_location_offset": "30%",
|
||||
}
|
||||
)
|
||||
)
|
||||
self.assertTrue(
|
||||
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0",'
|
||||
'"30%");' in r, r)
|
||||
'"30%");' in r,
|
||||
r,
|
||||
)
|
||||
with override_settings(SNAPENGAGE_BUTTON_LOCATION_OFFSET="30%"):
|
||||
r = SnapEngageNode().render(Context())
|
||||
self.assertTrue(
|
||||
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0",'
|
||||
'"30%");' in r, r)
|
||||
'"30%");' in r,
|
||||
r,
|
||||
)
|
||||
|
||||
def test_button_effect(self):
|
||||
r = SnapEngageNode().render(Context({
|
||||
'snapengage_button_effect': "-4px",
|
||||
}))
|
||||
r = SnapEngageNode().render(
|
||||
Context(
|
||||
{
|
||||
"snapengage_button_effect": "-4px",
|
||||
}
|
||||
)
|
||||
)
|
||||
self.assertTrue('SnapABug.setButtonEffect("-4px");' in r, r)
|
||||
with override_settings(SNAPENGAGE_BUTTON_EFFECT="-4px"):
|
||||
r = SnapEngageNode().render(Context())
|
||||
self.assertTrue('SnapABug.setButtonEffect("-4px");' in r, r)
|
||||
|
||||
def test_form_position(self):
|
||||
r = SnapEngageNode().render(Context({
|
||||
'snapengage_form_position': FORM_POSITION_TOP_LEFT,
|
||||
}))
|
||||
r = SnapEngageNode().render(
|
||||
Context(
|
||||
{
|
||||
"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())
|
||||
self.assertTrue('SnapABug.setChatFormPosition("tl");' in r, r)
|
||||
|
||||
def test_form_top_position(self):
|
||||
r = SnapEngageNode().render(Context({
|
||||
'snapengage_form_top_position': 40,
|
||||
}))
|
||||
self.assertTrue('SnapABug.setFormTopPosition(40);' in r, r)
|
||||
r = SnapEngageNode().render(
|
||||
Context(
|
||||
{
|
||||
"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())
|
||||
self.assertTrue('SnapABug.setFormTopPosition(40);' in r, r)
|
||||
self.assertTrue("SnapABug.setFormTopPosition(40);" in r, r)
|
||||
|
||||
def test_domain(self):
|
||||
r = SnapEngageNode().render(Context({
|
||||
'snapengage_domain': "example.com"}))
|
||||
r = SnapEngageNode().render(Context({"snapengage_domain": "example.com"}))
|
||||
self.assertTrue('SnapABug.setDomain("example.com");' in r, r)
|
||||
with override_settings(SNAPENGAGE_DOMAIN="example.com"):
|
||||
r = SnapEngageNode().render(Context())
|
||||
self.assertTrue('SnapABug.setDomain("example.com");' in r, r)
|
||||
|
||||
def test_secure_connection(self):
|
||||
r = SnapEngageNode().render(Context({
|
||||
'snapengage_secure_connection': True}))
|
||||
self.assertTrue('SnapABug.setSecureConnexion();' in r, r)
|
||||
r = SnapEngageNode().render(Context({"snapengage_secure_connection": True}))
|
||||
self.assertTrue("SnapABug.setSecureConnexion();" in r, r)
|
||||
with override_settings(SNAPENGAGE_SECURE_CONNECTION=True):
|
||||
r = SnapEngageNode().render(Context())
|
||||
self.assertTrue('SnapABug.setSecureConnexion();' in r, r)
|
||||
self.assertTrue("SnapABug.setSecureConnexion();" in r, r)
|
||||
|
||||
def test_show_offline(self):
|
||||
r = SnapEngageNode().render(Context({
|
||||
'snapengage_show_offline': False,
|
||||
}))
|
||||
self.assertTrue('SnapABug.allowOffline(false);' in r, r)
|
||||
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())
|
||||
self.assertTrue('SnapABug.allowOffline(false);' in r, r)
|
||||
self.assertTrue("SnapABug.allowOffline(false);" in r, r)
|
||||
|
||||
def test_proactive_chat(self):
|
||||
r = SnapEngageNode().render(Context({
|
||||
'snapengage_proactive_chat': False}))
|
||||
self.assertTrue('SnapABug.allowProactiveChat(false);' in r, r)
|
||||
r = SnapEngageNode().render(Context({"snapengage_proactive_chat": False}))
|
||||
self.assertTrue("SnapABug.allowProactiveChat(false);" in r, r)
|
||||
|
||||
def test_screenshot(self):
|
||||
r = SnapEngageNode().render(Context({
|
||||
'snapengage_screenshots': False,
|
||||
}))
|
||||
self.assertTrue('SnapABug.allowScreenshot(false);' in r, r)
|
||||
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)
|
||||
self.assertTrue("SnapABug.allowScreenshot(false);" in r, r)
|
||||
|
||||
def test_offline_screenshots(self):
|
||||
r = SnapEngageNode().render(Context({
|
||||
'snapengage_offline_screenshots': False,
|
||||
}))
|
||||
self.assertTrue('SnapABug.showScreenshotOption(false);' in r, r)
|
||||
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())
|
||||
self.assertTrue('SnapABug.showScreenshotOption(false);' in r, r)
|
||||
self.assertTrue("SnapABug.showScreenshotOption(false);" in r, r)
|
||||
|
||||
def test_sounds(self):
|
||||
r = SnapEngageNode().render(Context({'snapengage_sounds': False}))
|
||||
self.assertTrue('SnapABug.allowChatSound(false);' in r, r)
|
||||
r = SnapEngageNode().render(Context({"snapengage_sounds": False}))
|
||||
self.assertTrue("SnapABug.allowChatSound(false);" in r, r)
|
||||
with override_settings(SNAPENGAGE_SOUNDS=False):
|
||||
r = SnapEngageNode().render(Context())
|
||||
self.assertTrue('SnapABug.allowChatSound(false);' in r, r)
|
||||
self.assertTrue("SnapABug.allowChatSound(false);" in r, r)
|
||||
|
||||
@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,
|
||||
}))
|
||||
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',
|
||||
}))
|
||||
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(),
|
||||
}))
|
||||
self.assertFalse('SnapABug.setUserEmail(' in r, r)
|
||||
r = SnapEngageNode().render(
|
||||
Context(
|
||||
{
|
||||
"user": AnonymousUser(),
|
||||
}
|
||||
)
|
||||
)
|
||||
self.assertFalse("SnapABug.setUserEmail(" in r, r)
|
||||
|
||||
def test_language(self):
|
||||
r = SnapEngageNode().render(Context({'snapengage_locale': 'fr'}))
|
||||
r = SnapEngageNode().render(Context({"snapengage_locale": "fr"}))
|
||||
self.assertTrue('SnapABug.setLocale("fr");' in r, r)
|
||||
with override_settings(SNAPENGAGE_LOCALE='fr'):
|
||||
with override_settings(SNAPENGAGE_LOCALE="fr"):
|
||||
r = SnapEngageNode().render(Context())
|
||||
self.assertTrue('SnapABug.setLocale("fr");' in r, r)
|
||||
|
||||
def test_automatic_language(self):
|
||||
real_get_language = translation.get_language
|
||||
try:
|
||||
translation.get_language = lambda: 'fr-ca'
|
||||
translation.get_language = lambda: "fr-ca"
|
||||
r = SnapEngageNode().render(Context())
|
||||
self.assertTrue('SnapABug.setLocale("fr_CA");' in r, r)
|
||||
finally:
|
||||
|
|
|
|||
|
|
@ -2,24 +2,24 @@
|
|||
Tests for the Spring Metrics template tags and filters.
|
||||
"""
|
||||
|
||||
from django.contrib.auth.models import User, AnonymousUser
|
||||
from django.contrib.auth.models import AnonymousUser, User
|
||||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.spring_metrics import SpringMetricsNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(SPRING_METRICS_TRACKING_ID='12345678')
|
||||
@override_settings(SPRING_METRICS_TRACKING_ID="12345678")
|
||||
class SpringMetricsTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``spring_metrics`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('spring_metrics', 'spring_metrics')
|
||||
r = self.render_tag("spring_metrics", "spring_metrics")
|
||||
self.assertTrue("_springMetq.push(['id', '12345678']);" in r, r)
|
||||
|
||||
def test_node(self):
|
||||
|
|
@ -30,36 +30,47 @@ class SpringMetricsTagTestCase(TagTestCase):
|
|||
def test_no_site_id(self):
|
||||
self.assertRaises(AnalyticalException, SpringMetricsNode)
|
||||
|
||||
@override_settings(SPRING_METRICS_TRACKING_ID='123xyz')
|
||||
@override_settings(SPRING_METRICS_TRACKING_ID="123xyz")
|
||||
def test_wrong_site_id(self):
|
||||
self.assertRaises(AnalyticalException, SpringMetricsNode)
|
||||
|
||||
@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):
|
||||
r = SpringMetricsNode().render(Context({'user': AnonymousUser()}))
|
||||
r = SpringMetricsNode().render(Context({"user": AnonymousUser()}))
|
||||
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',
|
||||
}))
|
||||
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'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = SpringMetricsNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Spring Metrics disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(
|
||||
r.startswith("<!-- Spring Metrics disabled on internal IP address"), r
|
||||
)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ Tests for the UserVoice tags and filters.
|
|||
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.uservoice import UserVoiceNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(USERVOICE_WIDGET_KEY='abcdefghijklmnopqrst')
|
||||
@override_settings(USERVOICE_WIDGET_KEY="abcdefghijklmnopqrst")
|
||||
class UserVoiceTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``uservoice`` template tag.
|
||||
|
|
@ -27,34 +27,34 @@ class UserVoiceTagTestCase(TagTestCase):
|
|||
self.assertIn("widget.uservoice.com/abcdefghijklmnopqrst.js", r)
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('uservoice', 'uservoice')
|
||||
r = self.render_tag("uservoice", "uservoice")
|
||||
self.assertIn("widget.uservoice.com/abcdefghijklmnopqrst.js", r)
|
||||
|
||||
@override_settings(USERVOICE_WIDGET_KEY=None)
|
||||
def test_no_key(self):
|
||||
self.assertRaises(AnalyticalException, UserVoiceNode)
|
||||
|
||||
@override_settings(USERVOICE_WIDGET_KEY='abcdefgh ijklmnopqrst')
|
||||
@override_settings(USERVOICE_WIDGET_KEY="abcdefgh ijklmnopqrst")
|
||||
def test_invalid_key(self):
|
||||
self.assertRaises(AnalyticalException, UserVoiceNode)
|
||||
|
||||
@override_settings(USERVOICE_WIDGET_KEY='')
|
||||
@override_settings(USERVOICE_WIDGET_KEY="")
|
||||
def test_empty_key(self):
|
||||
self.assertRaises(AnalyticalException, UserVoiceNode)
|
||||
|
||||
def test_overridden_key(self):
|
||||
vars = {'uservoice_widget_key': 'defghijklmnopqrstuvw'}
|
||||
vars = {"uservoice_widget_key": "defghijklmnopqrstuvw"}
|
||||
r = UserVoiceNode().render(Context(vars))
|
||||
self.assertIn("widget.uservoice.com/defghijklmnopqrstuvw.js", r)
|
||||
|
||||
@override_settings(USERVOICE_WIDGET_OPTIONS={'key1': 'val1'})
|
||||
@override_settings(USERVOICE_WIDGET_OPTIONS={"key1": "val1"})
|
||||
def test_options(self):
|
||||
r = UserVoiceNode().render(Context())
|
||||
self.assertIn("""UserVoice.push(['set', {"key1": "val1"}]);""", r)
|
||||
|
||||
@override_settings(USERVOICE_WIDGET_OPTIONS={'key1': 'val1'})
|
||||
@override_settings(USERVOICE_WIDGET_OPTIONS={"key1": "val1"})
|
||||
def test_override_options(self):
|
||||
data = {'uservoice_widget_options': {'key1': 'val2'}}
|
||||
data = {"uservoice_widget_options": {"key1": "val2"}}
|
||||
r = UserVoiceNode().render(Context(data))
|
||||
self.assertIn("""UserVoice.push(['set', {"key1": "val2"}]);""", r)
|
||||
|
||||
|
|
@ -69,5 +69,5 @@ class UserVoiceTagTestCase(TagTestCase):
|
|||
|
||||
@override_settings(USERVOICE_ADD_TRIGGER=False)
|
||||
def test_auto_trigger_custom_win(self):
|
||||
r = UserVoiceNode().render(Context({'uservoice_add_trigger': True}))
|
||||
r = UserVoiceNode().render(Context({"uservoice_add_trigger": True}))
|
||||
self.assertTrue("UserVoice.push(['addTrigger', {}]);" in r, r)
|
||||
|
|
|
|||
|
|
@ -2,24 +2,24 @@
|
|||
Tests for the Woopra template tags and filters.
|
||||
"""
|
||||
|
||||
from django.contrib.auth.models import User, AnonymousUser
|
||||
from django.contrib.auth.models import AnonymousUser, User
|
||||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.woopra import WoopraNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(WOOPRA_DOMAIN='example.com')
|
||||
@override_settings(WOOPRA_DOMAIN="example.com")
|
||||
class WoopraTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``woopra`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('woopra', 'woopra')
|
||||
r = self.render_tag("woopra", "woopra")
|
||||
self.assertTrue('var woo_settings = {"domain": "example.com"};' in r, r)
|
||||
|
||||
def test_node(self):
|
||||
|
|
@ -30,66 +30,89 @@ class WoopraTagTestCase(TagTestCase):
|
|||
def test_no_domain(self):
|
||||
self.assertRaises(AnalyticalException, WoopraNode)
|
||||
|
||||
@override_settings(WOOPRA_DOMAIN='this is not a domain')
|
||||
@override_settings(WOOPRA_DOMAIN="this is not a domain")
|
||||
def test_wrong_domain(self):
|
||||
self.assertRaises(AnalyticalException, WoopraNode)
|
||||
|
||||
@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',
|
||||
}))
|
||||
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):
|
||||
r = WoopraNode().render(Context({'user': User(username='test')}))
|
||||
r = WoopraNode().render(Context({"user": User(username="test")}))
|
||||
self.assertTrue('var woo_visitor = {"name": "test"};' in r, r)
|
||||
|
||||
@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)
|
||||
def test_identify_anonymous_user(self):
|
||||
r = WoopraNode().render(Context({'user': AnonymousUser()}))
|
||||
self.assertTrue('var woo_visitor = {};' in r, r)
|
||||
r = WoopraNode().render(Context({"user": AnonymousUser()}))
|
||||
self.assertTrue("var woo_visitor = {};" in r, r)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = WoopraNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Woopra disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(r.startswith("<!-- Woopra disabled on internal IP address"), r)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
|
|
|||
|
|
@ -6,20 +6,20 @@ Tests for the Yandex.Metrica template tags and filters.
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TagTestCase
|
||||
|
||||
from analytical.templatetags.yandex_metrica import YandexMetricaNode
|
||||
from utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
@override_settings(YANDEX_METRICA_COUNTER_ID='12345678')
|
||||
@override_settings(YANDEX_METRICA_COUNTER_ID="12345678")
|
||||
class YandexMetricaTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``yandex_metrica`` template tag.
|
||||
"""
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('yandex_metrica', 'yandex_metrica')
|
||||
r = self.render_tag("yandex_metrica", "yandex_metrica")
|
||||
self.assertTrue("w.yaCounter12345678 = new Ya.Metrika" in r, r)
|
||||
|
||||
def test_node(self):
|
||||
|
|
@ -30,16 +30,17 @@ class YandexMetricaTagTestCase(TagTestCase):
|
|||
def test_no_site_id(self):
|
||||
self.assertRaises(AnalyticalException, YandexMetricaNode)
|
||||
|
||||
@override_settings(YANDEX_METRICA_COUNTER_ID='1234abcd')
|
||||
@override_settings(YANDEX_METRICA_COUNTER_ID="1234abcd")
|
||||
def test_wrong_site_id(self):
|
||||
self.assertRaises(AnalyticalException, YandexMetricaNode)
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
r = YandexMetricaNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Yandex.Metrica disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
self.assertTrue(
|
||||
r.startswith("<!-- Yandex.Metrica disabled on internal IP address"), r
|
||||
)
|
||||
self.assertTrue(r.endswith("-->"), r)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ from django.db import models
|
|||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
from django.test.utils import override_settings
|
||||
from utils import TestCase
|
||||
|
||||
from analytical.utils import (
|
||||
AnalyticalException,
|
||||
|
|
@ -16,54 +17,54 @@ from analytical.utils import (
|
|||
get_required_setting,
|
||||
is_internal_ip,
|
||||
)
|
||||
from utils import TestCase
|
||||
|
||||
|
||||
class SettingDeletedTestCase(TestCase):
|
||||
|
||||
@override_settings(USER_ID=None)
|
||||
def test_get_required_setting(self):
|
||||
"""
|
||||
Make sure using get_required_setting fails in the right place.
|
||||
"""
|
||||
|
||||
with self.assertRaisesRegex(AnalyticalException, "^USER_ID setting is not set$"):
|
||||
with self.assertRaisesRegex(
|
||||
AnalyticalException, "^USER_ID setting is not set$"
|
||||
):
|
||||
get_required_setting("USER_ID", r"\d+", "invalid USER_ID")
|
||||
|
||||
|
||||
class MyUser(AbstractBaseUser):
|
||||
identity = models.CharField(max_length=50)
|
||||
USERNAME_FIELD = 'identity'
|
||||
USERNAME_FIELD = "identity"
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
app_label = 'testapp'
|
||||
app_label = "testapp"
|
||||
|
||||
|
||||
class GetIdentityTestCase(TestCase):
|
||||
def test_custom_username_field(self):
|
||||
get_id = get_identity(Context({}), user=MyUser(identity='fake_id'))
|
||||
self.assertEqual(get_id, 'fake_id')
|
||||
get_id = get_identity(Context({}), user=MyUser(identity="fake_id"))
|
||||
self.assertEqual(get_id, "fake_id")
|
||||
|
||||
|
||||
@override_settings(ANALYTICAL_DOMAIN="example.org")
|
||||
class GetDomainTestCase(TestCase):
|
||||
def test_get_service_domain_from_context(self):
|
||||
context = Context({'test_domain': 'example.com'})
|
||||
self.assertEqual(get_domain(context, 'test'), 'example.com')
|
||||
context = Context({"test_domain": "example.com"})
|
||||
self.assertEqual(get_domain(context, "test"), "example.com")
|
||||
|
||||
def test_get_analytical_domain_from_context(self):
|
||||
context = Context({'analytical_domain': 'example.com'})
|
||||
self.assertEqual(get_domain(context, 'test'), 'example.com')
|
||||
context = Context({"analytical_domain": "example.com"})
|
||||
self.assertEqual(get_domain(context, "test"), "example.com")
|
||||
|
||||
@override_settings(TEST_DOMAIN="example.net")
|
||||
def test_get_service_domain_from_settings(self):
|
||||
context = Context()
|
||||
self.assertEqual(get_domain(context, 'test'), 'example.net')
|
||||
self.assertEqual(get_domain(context, "test"), "example.net")
|
||||
|
||||
def test_get_analytical_domain_from_settings(self):
|
||||
context = Context()
|
||||
self.assertEqual(get_domain(context, 'test'), 'example.org')
|
||||
self.assertEqual(get_domain(context, "test"), "example.org")
|
||||
|
||||
|
||||
# FIXME: enable Django apps dynamically and enable test again
|
||||
|
|
@ -78,51 +79,50 @@ class GetDomainTestCase(TestCase):
|
|||
|
||||
|
||||
class InternalIpTestCase(TestCase):
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_no_internal_ip(self):
|
||||
context = Context()
|
||||
self.assertFalse(is_internal_ip(context))
|
||||
|
||||
@override_settings(INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(INTERNAL_IPS=["1.1.1.1"])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=[])
|
||||
def test_render_analytical_internal_ips_override_when_empty(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
self.assertFalse(is_internal_ip(context))
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
self.assertTrue(is_internal_ip(context))
|
||||
|
||||
@override_settings(TEST_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(TEST_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_prefix_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
self.assertTrue(is_internal_ip(context, 'TEST'))
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
self.assertTrue(is_internal_ip(context, "TEST"))
|
||||
|
||||
@override_settings(INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip_fallback(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
self.assertTrue(is_internal_ip(context))
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_internal_ip_forwarded_for(self):
|
||||
req = HttpRequest()
|
||||
req.META['HTTP_X_FORWARDED_FOR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
req.META["HTTP_X_FORWARDED_FOR"] = "1.1.1.1"
|
||||
context = Context({"request": req})
|
||||
self.assertTrue(is_internal_ip(context))
|
||||
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
@override_settings(ANALYTICAL_INTERNAL_IPS=["1.1.1.1"])
|
||||
def test_render_different_internal_ip(self):
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '2.2.2.2'
|
||||
context = Context({'request': req})
|
||||
req.META["REMOTE_ADDR"] = "2.2.2.2"
|
||||
context = Context({"request": req})
|
||||
self.assertFalse(is_internal_ip(context))
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Testing utilities.
|
||||
"""
|
||||
|
||||
from django.template import Template, Context, RequestContext
|
||||
from django.template import Context, RequestContext, Template
|
||||
from django.test.testcases import TestCase
|
||||
|
||||
|
||||
|
|
|
|||
15
tox.ini
15
tox.ini
|
|
@ -2,7 +2,7 @@
|
|||
envlist =
|
||||
# Python/Django combinations that are officially supported
|
||||
py{36,37,38,39}-django{22,30,31}
|
||||
py37-{flake8,bandit,readme,docs}
|
||||
py37-{lint,bandit,readme,docs}
|
||||
|
||||
[testenv]
|
||||
description = Unit tests
|
||||
|
|
@ -36,10 +36,17 @@ deps = sphinx
|
|||
commands = sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html
|
||||
whitelist_externals = make
|
||||
|
||||
[testenv:py37-flake8]
|
||||
[testenv:py37-lint]
|
||||
description = Static code analysis and code style
|
||||
deps = flake8
|
||||
commands = flake8
|
||||
skip_install = True
|
||||
deps =
|
||||
flake8
|
||||
isort
|
||||
black
|
||||
commands =
|
||||
flake8
|
||||
isort tests setup.py analytical --check --diff
|
||||
black tests setup.py analytical --check
|
||||
|
||||
[testenv:py37-readme]
|
||||
description = Ensure README renders on PyPI
|
||||
|
|
|
|||
Loading…
Reference in a new issue