mirror of
https://github.com/jazzband/django-analytical.git
synced 2026-03-16 22:20:25 +00:00
Reformat code using Ruff
This commit is contained in:
parent
82fbbeb6b2
commit
a112ec445f
59 changed files with 1055 additions and 604 deletions
|
|
@ -66,7 +66,7 @@ class AnalyticalNode(Node):
|
||||||
self.nodes = [node_cls() for node_cls in template_nodes[location]]
|
self.nodes = [node_cls() for node_cls in template_nodes[location]]
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
return "".join([node.render(context) for node in self.nodes])
|
return ''.join([node.render(context) for node in self.nodes])
|
||||||
|
|
||||||
|
|
||||||
def _load_template_nodes():
|
def _load_template_nodes():
|
||||||
|
|
@ -82,14 +82,15 @@ def _load_template_nodes():
|
||||||
except AnalyticalException as e:
|
except AnalyticalException as e:
|
||||||
logger.debug("not loading tags from '%s': %s", path, e)
|
logger.debug("not loading tags from '%s': %s", path, e)
|
||||||
for location in TAG_LOCATIONS:
|
for location in TAG_LOCATIONS:
|
||||||
template_nodes[location] = sum((template_nodes[location][p]
|
template_nodes[location] = sum(
|
||||||
for p in TAG_POSITIONS), [])
|
(template_nodes[location][p] for p in TAG_POSITIONS), []
|
||||||
|
)
|
||||||
return template_nodes
|
return template_nodes
|
||||||
|
|
||||||
|
|
||||||
def _import_tag_module(path):
|
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))
|
return import_module('%s.templatetags.%s' % (app_name, lib_name))
|
||||||
|
|
||||||
|
|
||||||
template_nodes = _load_template_nodes()
|
template_nodes = _load_template_nodes()
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,9 @@ from django.template import Library, Node, TemplateSyntaxError
|
||||||
from analytical.utils import disable_html, get_required_setting, is_internal_ip
|
from analytical.utils import disable_html, get_required_setting, is_internal_ip
|
||||||
|
|
||||||
USER_ID_RE = re.compile(r'^\d+$')
|
USER_ID_RE = re.compile(r'^\d+$')
|
||||||
INIT_CODE = """<script type="text/javascript">var _sf_startpt=(new Date()).getTime()</script>"""
|
INIT_CODE = (
|
||||||
|
"""<script type="text/javascript">var _sf_startpt=(new Date()).getTime()</script>"""
|
||||||
|
)
|
||||||
SETUP_CODE = """
|
SETUP_CODE = """
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var _sf_async_config=%(config)s;
|
var _sf_async_config=%(config)s;
|
||||||
|
|
@ -55,7 +57,7 @@ def chartbeat_top(parser, token):
|
||||||
class ChartbeatTopNode(Node):
|
class ChartbeatTopNode(Node):
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
if is_internal_ip(context):
|
if is_internal_ip(context):
|
||||||
return disable_html(INIT_CODE, "Chartbeat")
|
return disable_html(INIT_CODE, 'Chartbeat')
|
||||||
return INIT_CODE
|
return INIT_CODE
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -76,8 +78,9 @@ def chartbeat_bottom(parser, token):
|
||||||
|
|
||||||
class ChartbeatBottomNode(Node):
|
class ChartbeatBottomNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.user_id = get_required_setting('CHARTBEAT_USER_ID', USER_ID_RE,
|
self.user_id = get_required_setting(
|
||||||
"must be (a string containing) a number")
|
'CHARTBEAT_USER_ID', USER_ID_RE, 'must be (a string containing) a number'
|
||||||
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
config = {'uid': self.user_id}
|
config = {'uid': self.user_id}
|
||||||
|
|
@ -106,6 +109,7 @@ def _get_domain(context):
|
||||||
return
|
return
|
||||||
elif getattr(settings, 'CHARTBEAT_AUTO_DOMAIN', True):
|
elif getattr(settings, 'CHARTBEAT_AUTO_DOMAIN', True):
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return Site.objects.get_current().domain
|
return Site.objects.get_current().domain
|
||||||
except (ImproperlyConfigured, Site.DoesNotExist): # pylint: disable=E1101
|
except (ImproperlyConfigured, Site.DoesNotExist): # pylint: disable=E1101
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,11 @@ def clickmap(parser, token):
|
||||||
|
|
||||||
class ClickmapNode(Node):
|
class ClickmapNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.tracker_id = get_required_setting('CLICKMAP_TRACKER_ID',
|
self.tracker_id = get_required_setting(
|
||||||
CLICKMAP_TRACKER_ID_RE,
|
'CLICKMAP_TRACKER_ID',
|
||||||
"must be an alphanumeric string")
|
CLICKMAP_TRACKER_ID_RE,
|
||||||
|
'must be an alphanumeric string',
|
||||||
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
html = TRACKING_CODE % {'tracker_id': self.tracker_id}
|
html = TRACKING_CODE % {'tracker_id': self.tracker_id}
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,8 @@ def clicky(parser, token):
|
||||||
class ClickyNode(Node):
|
class ClickyNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.site_id = get_required_setting(
|
self.site_id = get_required_setting(
|
||||||
'CLICKY_SITE_ID', SITE_ID_RE,
|
'CLICKY_SITE_ID', SITE_ID_RE, 'must be a (string containing) a number'
|
||||||
"must be a (string containing) a number")
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
custom = {}
|
custom = {}
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,10 @@ from django.template import Library, Node, TemplateSyntaxError
|
||||||
from analytical.utils import disable_html, get_required_setting, is_internal_ip
|
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 type="text/javascript" src="{placeholder_url}">' \
|
SETUP_CODE = '<script type="text/javascript" src="{placeholder_url}"></script>'.format(
|
||||||
'</script>'.\
|
placeholder_url='//dnn506yrbagrg.cloudfront.net/pages/scripts/'
|
||||||
format(placeholder_url='//dnn506yrbagrg.cloudfront.net/pages/scripts/'
|
'%(account_nr_1)s/%(account_nr_2)s.js'
|
||||||
'%(account_nr_1)s/%(account_nr_2)s.js')
|
)
|
||||||
USERVAR_CODE = "CE2.set(%(varnr)d, '%(value)s');"
|
USERVAR_CODE = "CE2.set(%(varnr)d, '%(value)s');"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -38,7 +38,8 @@ class CrazyEggNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.account_nr = get_required_setting(
|
self.account_nr = get_required_setting(
|
||||||
'CRAZY_EGG_ACCOUNT_NUMBER',
|
'CRAZY_EGG_ACCOUNT_NUMBER',
|
||||||
ACCOUNT_NUMBER_RE, "must be (a string containing) a number"
|
ACCOUNT_NUMBER_RE,
|
||||||
|
'must be (a string containing) a number',
|
||||||
)
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
|
|
@ -49,12 +50,15 @@ class CrazyEggNode(Node):
|
||||||
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]
|
params = [(i, v) for i, v in enumerate(values, 1) if v is not None]
|
||||||
if params:
|
if params:
|
||||||
js = " ".join(USERVAR_CODE % {
|
js = ' '.join(
|
||||||
'varnr': varnr,
|
USERVAR_CODE
|
||||||
'value': value,
|
% {
|
||||||
} for (varnr, value) in params)
|
'varnr': varnr,
|
||||||
html = '%s\n' \
|
'value': value,
|
||||||
'<script type="text/javascript">%s</script>' % (html, js)
|
}
|
||||||
|
for (varnr, value) in params
|
||||||
|
)
|
||||||
|
html = '%s\n<script type="text/javascript">%s</script>' % (html, js)
|
||||||
if is_internal_ip(context, 'CRAZY_EGG'):
|
if is_internal_ip(context, 'CRAZY_EGG'):
|
||||||
html = disable_html(html, 'Crazy Egg')
|
html = disable_html(html, 'Crazy Egg')
|
||||||
return html
|
return html
|
||||||
|
|
|
||||||
|
|
@ -60,11 +60,12 @@ class _FacebookPixelNode(Node):
|
||||||
"""
|
"""
|
||||||
Base class: override and provide code_template.
|
Base class: override and provide code_template.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.pixel_id = get_required_setting(
|
self.pixel_id = get_required_setting(
|
||||||
'FACEBOOK_PIXEL_ID',
|
'FACEBOOK_PIXEL_ID',
|
||||||
re.compile(r'^\d+$'),
|
re.compile(r'^\d+$'),
|
||||||
"must be (a string containing) a number",
|
'must be (a string containing) a number',
|
||||||
)
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
|
|
|
||||||
|
|
@ -46,8 +46,8 @@ def gauges(parser, token):
|
||||||
class GaugesNode(Node):
|
class GaugesNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.site_id = get_required_setting(
|
self.site_id = get_required_setting(
|
||||||
'GAUGES_SITE_ID', SITE_ID_RE,
|
'GAUGES_SITE_ID', SITE_ID_RE, "must be a string looking like 'XXXXXXX'"
|
||||||
"must be a string looking like 'XXXXXXX'")
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
html = TRACKING_CODE % {'site_id': self.site_id}
|
html = TRACKING_CODE % {'site_id': self.site_id}
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,9 @@ DOMAIN_CODE = "_gaq.push(['_setDomainName', '%s']);"
|
||||||
NO_ALLOW_HASH_CODE = "_gaq.push(['_setAllowHash', false]);"
|
NO_ALLOW_HASH_CODE = "_gaq.push(['_setAllowHash', false]);"
|
||||||
TRACK_PAGE_VIEW = "_gaq.push(['_trackPageview']);"
|
TRACK_PAGE_VIEW = "_gaq.push(['_trackPageview']);"
|
||||||
ALLOW_LINKER_CODE = "_gaq.push(['_setAllowLinker', true]);"
|
ALLOW_LINKER_CODE = "_gaq.push(['_setAllowLinker', true]);"
|
||||||
CUSTOM_VAR_CODE = "_gaq.push(['_setCustomVar', %(index)s, '%(name)s', " \
|
CUSTOM_VAR_CODE = (
|
||||||
"'%(value)s', %(scope)s]);"
|
"_gaq.push(['_setCustomVar', %(index)s, '%(name)s', '%(value)s', %(scope)s]);"
|
||||||
|
)
|
||||||
SITE_SPEED_CODE = "_gaq.push(['_trackPageLoadTime']);"
|
SITE_SPEED_CODE = "_gaq.push(['_trackPageLoadTime']);"
|
||||||
ANONYMIZE_IP_CODE = "_gaq.push(['_gat._anonymizeIp']);"
|
ANONYMIZE_IP_CODE = "_gaq.push(['_gat._anonymizeIp']);"
|
||||||
SAMPLE_RATE_CODE = "_gaq.push(['_setSampleRate', '%s']);"
|
SAMPLE_RATE_CODE = "_gaq.push(['_setSampleRate', '%s']);"
|
||||||
|
|
@ -54,7 +55,10 @@ SITE_SPEED_SAMPLE_RATE_CODE = "_gaq.push(['_setSiteSpeedSampleRate', '%s']);"
|
||||||
SESSION_COOKIE_TIMEOUT_CODE = "_gaq.push(['_setSessionCookieTimeout', '%s']);"
|
SESSION_COOKIE_TIMEOUT_CODE = "_gaq.push(['_setSessionCookieTimeout', '%s']);"
|
||||||
VISITOR_COOKIE_TIMEOUT_CODE = "_gaq.push(['_setVisitorCookieTimeout', '%s']);"
|
VISITOR_COOKIE_TIMEOUT_CODE = "_gaq.push(['_setVisitorCookieTimeout', '%s']);"
|
||||||
DEFAULT_SOURCE = ("'https://ssl' : 'http://www'", "'.google-analytics.com/ga.js'")
|
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')
|
ZEROPLACES = decimal.Decimal('0')
|
||||||
TWOPLACES = decimal.Decimal('0.01')
|
TWOPLACES = decimal.Decimal('0.01')
|
||||||
|
|
@ -80,8 +84,10 @@ def google_analytics(parser, token):
|
||||||
class GoogleAnalyticsNode(Node):
|
class GoogleAnalyticsNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.property_id = get_required_setting(
|
self.property_id = get_required_setting(
|
||||||
'GOOGLE_ANALYTICS_PROPERTY_ID', PROPERTY_ID_RE,
|
'GOOGLE_ANALYTICS_PROPERTY_ID',
|
||||||
"must be a string looking like 'UA-XXXXXX-Y'")
|
PROPERTY_ID_RE,
|
||||||
|
"must be a string looking like 'UA-XXXXXX-Y'",
|
||||||
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
commands = self._get_domain_commands(context)
|
commands = self._get_domain_commands(context)
|
||||||
|
|
@ -94,7 +100,7 @@ class GoogleAnalyticsNode(Node):
|
||||||
source = DEFAULT_SOURCE
|
source = DEFAULT_SOURCE
|
||||||
html = SETUP_CODE % {
|
html = SETUP_CODE % {
|
||||||
'property_id': self.property_id,
|
'property_id': self.property_id,
|
||||||
'commands': " ".join(commands),
|
'commands': ' '.join(commands),
|
||||||
'source_scheme': source[0],
|
'source_scheme': source[0],
|
||||||
'source_url': source[1],
|
'source_url': source[1],
|
||||||
}
|
}
|
||||||
|
|
@ -104,15 +110,17 @@ class GoogleAnalyticsNode(Node):
|
||||||
|
|
||||||
def _get_domain_commands(self, context):
|
def _get_domain_commands(self, context):
|
||||||
commands = []
|
commands = []
|
||||||
tracking_type = getattr(settings, 'GOOGLE_ANALYTICS_TRACKING_STYLE',
|
tracking_type = getattr(
|
||||||
TRACK_SINGLE_DOMAIN)
|
settings, 'GOOGLE_ANALYTICS_TRACKING_STYLE', TRACK_SINGLE_DOMAIN
|
||||||
|
)
|
||||||
if tracking_type == TRACK_SINGLE_DOMAIN:
|
if tracking_type == TRACK_SINGLE_DOMAIN:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
domain = get_domain(context, 'google_analytics')
|
domain = get_domain(context, 'google_analytics')
|
||||||
if domain is None:
|
if domain is None:
|
||||||
raise AnalyticalException(
|
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(DOMAIN_CODE % domain)
|
||||||
commands.append(NO_ALLOW_HASH_CODE)
|
commands.append(NO_ALLOW_HASH_CODE)
|
||||||
if tracking_type == TRACK_MULTIPLE_DOMAINS:
|
if tracking_type == TRACK_MULTIPLE_DOMAINS:
|
||||||
|
|
@ -120,9 +128,7 @@ class GoogleAnalyticsNode(Node):
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
def _get_custom_var_commands(self, context):
|
def _get_custom_var_commands(self, context):
|
||||||
values = (
|
values = (context.get('google_analytics_var%s' % i) for i in range(1, 6))
|
||||||
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]
|
params = [(i, v) for i, v in enumerate(values, 1) if v is not None]
|
||||||
commands = []
|
commands = []
|
||||||
for index, var in params:
|
for index, var in params:
|
||||||
|
|
@ -132,12 +138,15 @@ class GoogleAnalyticsNode(Node):
|
||||||
scope = var[2]
|
scope = var[2]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
scope = SCOPE_PAGE
|
scope = SCOPE_PAGE
|
||||||
commands.append(CUSTOM_VAR_CODE % {
|
commands.append(
|
||||||
'index': index,
|
CUSTOM_VAR_CODE
|
||||||
'name': name,
|
% {
|
||||||
'value': value,
|
'index': index,
|
||||||
'scope': scope,
|
'name': name,
|
||||||
})
|
'value': value,
|
||||||
|
'scope': scope,
|
||||||
|
}
|
||||||
|
)
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
def _get_other_commands(self, context):
|
def _get_other_commands(self, context):
|
||||||
|
|
@ -152,29 +161,42 @@ class GoogleAnalyticsNode(Node):
|
||||||
if sampleRate is not False:
|
if sampleRate is not False:
|
||||||
value = decimal.Decimal(sampleRate)
|
value = decimal.Decimal(sampleRate)
|
||||||
if not 0 <= value <= 100:
|
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))
|
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:
|
if siteSpeedSampleRate is not False:
|
||||||
value = decimal.Decimal(siteSpeedSampleRate)
|
value = decimal.Decimal(siteSpeedSampleRate)
|
||||||
if not 0 <= value <= 100:
|
if not 0 <= value <= 100:
|
||||||
raise AnalyticalException(
|
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))
|
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:
|
if sessionCookieTimeout is not False:
|
||||||
value = decimal.Decimal(sessionCookieTimeout)
|
value = decimal.Decimal(sessionCookieTimeout)
|
||||||
if value < 0:
|
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))
|
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:
|
if visitorCookieTimeout is not False:
|
||||||
value = decimal.Decimal(visitorCookieTimeout)
|
value = decimal.Decimal(visitorCookieTimeout)
|
||||||
if value < 0:
|
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))
|
commands.append(VISITOR_COOKIE_TIMEOUT_CODE % value.quantize(ZEROPLACES))
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,9 @@ from analytical.utils import (
|
||||||
is_internal_ip,
|
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 = """
|
SETUP_CODE = """
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id={property_id}"></script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id={property_id}"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -49,10 +51,12 @@ def google_analytics_gtag(parser, token):
|
||||||
class GoogleAnalyticsGTagNode(Node):
|
class GoogleAnalyticsGTagNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.property_id = get_required_setting(
|
self.property_id = get_required_setting(
|
||||||
'GOOGLE_ANALYTICS_GTAG_PROPERTY_ID', PROPERTY_ID_RE,
|
'GOOGLE_ANALYTICS_GTAG_PROPERTY_ID',
|
||||||
'''must be a string looking like one of these patterns
|
PROPERTY_ID_RE,
|
||||||
|
"""must be a string looking like one of these patterns
|
||||||
('UA-XXXXXX-Y' , 'AW-XXXXXXXXXX',
|
('UA-XXXXXX-Y' , 'AW-XXXXXXXXXX',
|
||||||
'G-XXXXXXXX', 'DC-XXXXXXXX')''')
|
'G-XXXXXXXX', 'DC-XXXXXXXX')""",
|
||||||
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
other_fields = {}
|
other_fields = {}
|
||||||
|
|
@ -61,9 +65,12 @@ class GoogleAnalyticsGTagNode(Node):
|
||||||
if identity is not None:
|
if identity is not None:
|
||||||
other_fields['user_id'] = identity
|
other_fields['user_id'] = identity
|
||||||
|
|
||||||
extra = '\n'.join([
|
extra = '\n'.join(
|
||||||
GTAG_SET_CODE.format(key=key, value=value) for key, value in other_fields.items()
|
[
|
||||||
])
|
GTAG_SET_CODE.format(key=key, value=value)
|
||||||
|
for key, value in other_fields.items()
|
||||||
|
]
|
||||||
|
)
|
||||||
html = SETUP_CODE.format(
|
html = SETUP_CODE.format(
|
||||||
property_id=self.property_id,
|
property_id=self.property_id,
|
||||||
extra=extra,
|
extra=extra,
|
||||||
|
|
|
||||||
|
|
@ -57,29 +57,34 @@ def google_analytics_js(parser, token):
|
||||||
class GoogleAnalyticsJsNode(Node):
|
class GoogleAnalyticsJsNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.property_id = get_required_setting(
|
self.property_id = get_required_setting(
|
||||||
'GOOGLE_ANALYTICS_JS_PROPERTY_ID', PROPERTY_ID_RE,
|
'GOOGLE_ANALYTICS_JS_PROPERTY_ID',
|
||||||
"must be a string looking like 'UA-XXXXXX-Y'")
|
PROPERTY_ID_RE,
|
||||||
|
"must be a string looking like 'UA-XXXXXX-Y'",
|
||||||
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
import json
|
import json
|
||||||
|
|
||||||
create_fields = self._get_domain_fields(context)
|
create_fields = self._get_domain_fields(context)
|
||||||
create_fields.update(self._get_other_create_fields(context))
|
create_fields.update(self._get_other_create_fields(context))
|
||||||
commands = self._get_custom_var_commands(context)
|
commands = self._get_custom_var_commands(context)
|
||||||
commands.extend(self._get_other_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:
|
if display_features:
|
||||||
commands.insert(0, REQUIRE_DISPLAY_FEATURES)
|
commands.insert(0, REQUIRE_DISPLAY_FEATURES)
|
||||||
|
|
||||||
js_source = getattr(
|
js_source = getattr(
|
||||||
settings,
|
settings,
|
||||||
'GOOGLE_ANALYTICS_JS_SOURCE',
|
'GOOGLE_ANALYTICS_JS_SOURCE',
|
||||||
'https://www.google-analytics.com/analytics.js'
|
'https://www.google-analytics.com/analytics.js',
|
||||||
)
|
)
|
||||||
|
|
||||||
html = SETUP_CODE.format(
|
html = SETUP_CODE.format(
|
||||||
property_id=self.property_id,
|
property_id=self.property_id,
|
||||||
create_fields=json.dumps(create_fields),
|
create_fields=json.dumps(create_fields),
|
||||||
commands="".join(commands),
|
commands=''.join(commands),
|
||||||
js_source=js_source,
|
js_source=js_source,
|
||||||
)
|
)
|
||||||
if is_internal_ip(context, 'GOOGLE_ANALYTICS'):
|
if is_internal_ip(context, 'GOOGLE_ANALYTICS'):
|
||||||
|
|
@ -88,14 +93,17 @@ class GoogleAnalyticsJsNode(Node):
|
||||||
|
|
||||||
def _get_domain_fields(self, context):
|
def _get_domain_fields(self, context):
|
||||||
domain_fields = {}
|
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:
|
if tracking_type == TRACK_SINGLE_DOMAIN:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
domain = get_domain(context, 'google_analytics')
|
domain = get_domain(context, 'google_analytics')
|
||||||
if domain is None:
|
if domain is None:
|
||||||
raise AnalyticalException(
|
raise AnalyticalException(
|
||||||
"tracking multiple domains with Google Analytics requires a domain name")
|
'tracking multiple domains with Google Analytics requires a domain name'
|
||||||
|
)
|
||||||
domain_fields['legacyCookieDomain'] = domain
|
domain_fields['legacyCookieDomain'] = domain
|
||||||
if tracking_type == TRACK_MULTIPLE_DOMAINS:
|
if tracking_type == TRACK_MULTIPLE_DOMAINS:
|
||||||
domain_fields['allowLinker'] = True
|
domain_fields['allowLinker'] = True
|
||||||
|
|
@ -104,34 +112,39 @@ class GoogleAnalyticsJsNode(Node):
|
||||||
def _get_other_create_fields(self, context):
|
def _get_other_create_fields(self, context):
|
||||||
other_fields = {}
|
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:
|
if site_speed_sample_rate is not False:
|
||||||
value = int(decimal.Decimal(site_speed_sample_rate))
|
value = int(decimal.Decimal(site_speed_sample_rate))
|
||||||
if not 0 <= value <= 100:
|
if not 0 <= value <= 100:
|
||||||
raise AnalyticalException(
|
raise AnalyticalException(
|
||||||
"'GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE' must be >= 0 and <= 100")
|
"'GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE' must be >= 0 and <= 100"
|
||||||
|
)
|
||||||
other_fields['siteSpeedSampleRate'] = value
|
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:
|
if sample_rate is not False:
|
||||||
value = int(decimal.Decimal(sample_rate))
|
value = int(decimal.Decimal(sample_rate))
|
||||||
if not 0 <= value <= 100:
|
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"
|
||||||
|
)
|
||||||
other_fields['sampleRate'] = value
|
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:
|
if cookie_expires is not False:
|
||||||
value = int(decimal.Decimal(cookie_expires))
|
value = int(decimal.Decimal(cookie_expires))
|
||||||
if value < 0:
|
if value < 0:
|
||||||
raise AnalyticalException("'GOOGLE_ANALYTICS_COOKIE_EXPIRATION' must be >= 0")
|
raise AnalyticalException(
|
||||||
|
"'GOOGLE_ANALYTICS_COOKIE_EXPIRATION' must be >= 0"
|
||||||
|
)
|
||||||
other_fields['cookieExpires'] = value
|
other_fields['cookieExpires'] = value
|
||||||
|
|
||||||
return other_fields
|
return other_fields
|
||||||
|
|
||||||
def _get_custom_var_commands(self, context):
|
def _get_custom_var_commands(self, context):
|
||||||
values = (
|
values = (context.get('google_analytics_var%s' % i) for i in range(1, 6))
|
||||||
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]
|
params = [(i, v) for i, v in enumerate(values, 1) if v is not None]
|
||||||
commands = []
|
commands = []
|
||||||
for _, var in params:
|
for _, var in params:
|
||||||
|
|
@ -141,10 +154,12 @@ class GoogleAnalyticsJsNode(Node):
|
||||||
float(value)
|
float(value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
value = f"'{value}'"
|
value = f"'{value}'"
|
||||||
commands.append(CUSTOM_VAR_CODE.format(
|
commands.append(
|
||||||
name=name,
|
CUSTOM_VAR_CODE.format(
|
||||||
value=value,
|
name=name,
|
||||||
))
|
value=value,
|
||||||
|
)
|
||||||
|
)
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
def _get_other_commands(self, context):
|
def _get_other_commands(self, context):
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,10 @@ def gosquared(parser, token):
|
||||||
class GoSquaredNode(Node):
|
class GoSquaredNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.site_token = get_required_setting(
|
self.site_token = get_required_setting(
|
||||||
'GOSQUARED_SITE_TOKEN', TOKEN_RE,
|
'GOSQUARED_SITE_TOKEN',
|
||||||
"must be a string looking like XXX-XXXXXX-X")
|
TOKEN_RE,
|
||||||
|
'must be a string looking like XXX-XXXXXX-X',
|
||||||
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
configs = [TOKEN_CODE % self.site_token]
|
configs = [TOKEN_CODE % self.site_token]
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ TRACKING_CODE = """
|
||||||
heap.load("%(tracker_id)s");
|
heap.load("%(tracker_id)s");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
""" # noqa
|
""" # noqa
|
||||||
|
|
||||||
register = Library()
|
register = Library()
|
||||||
|
|
||||||
|
|
@ -41,9 +41,9 @@ def heap(parser, token):
|
||||||
|
|
||||||
class HeapNode(Node):
|
class HeapNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.tracker_id = get_required_setting('HEAP_TRACKER_ID',
|
self.tracker_id = get_required_setting(
|
||||||
HEAP_TRACKER_ID_RE,
|
'HEAP_TRACKER_ID', HEAP_TRACKER_ID_RE, 'must be an numeric string'
|
||||||
"must be an numeric string")
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
html = TRACKING_CODE % {'tracker_id': self.tracker_id}
|
html = TRACKING_CODE % {'tracker_id': self.tracker_id}
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,11 @@ def hotjar(parser, token):
|
||||||
|
|
||||||
|
|
||||||
class HotjarNode(Node):
|
class HotjarNode(Node):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.site_id = get_required_setting(
|
self.site_id = get_required_setting(
|
||||||
'HOTJAR_SITE_ID',
|
'HOTJAR_SITE_ID',
|
||||||
re.compile(r'^\d+$'),
|
re.compile(r'^\d+$'),
|
||||||
"must be (a string containing) a number",
|
'must be (a string containing) a number',
|
||||||
)
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,9 @@ def hubspot(parser, token):
|
||||||
|
|
||||||
class HubSpotNode(Node):
|
class HubSpotNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.portal_id = get_required_setting('HUBSPOT_PORTAL_ID', PORTAL_ID_RE,
|
self.portal_id = get_required_setting(
|
||||||
"must be a (string containing a) number")
|
'HUBSPOT_PORTAL_ID', PORTAL_ID_RE, 'must be a (string containing a) number'
|
||||||
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
html = TRACKING_CODE % {'portal_id': self.portal_id}
|
html = TRACKING_CODE % {'portal_id': self.portal_id}
|
||||||
|
|
|
||||||
|
|
@ -76,8 +76,8 @@ def intercom(parser, token):
|
||||||
class IntercomNode(Node):
|
class IntercomNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.app_id = get_required_setting(
|
self.app_id = get_required_setting(
|
||||||
'INTERCOM_APP_ID', APP_ID_RE,
|
'INTERCOM_APP_ID', APP_ID_RE, "must be a string looking like 'XXXXXXX'"
|
||||||
"must be a string looking like 'XXXXXXX'")
|
)
|
||||||
|
|
||||||
def _identify(self, user):
|
def _identify(self, user):
|
||||||
name = user.get_full_name()
|
name = user.get_full_name()
|
||||||
|
|
@ -95,8 +95,7 @@ class IntercomNode(Node):
|
||||||
user = get_user_from_context(context)
|
user = get_user_from_context(context)
|
||||||
if user is not None and get_user_is_authenticated(user):
|
if user is not None and get_user_is_authenticated(user):
|
||||||
if 'name' not in params:
|
if 'name' not in params:
|
||||||
params['name'] = get_identity(
|
params['name'] = get_identity(context, 'intercom', self._identify, user)
|
||||||
context, 'intercom', self._identify, user)
|
|
||||||
if 'email' not in params and user.email:
|
if 'email' not in params and user.email:
|
||||||
params['email'] = user.email
|
params['email'] = user.email
|
||||||
|
|
||||||
|
|
@ -120,10 +119,8 @@ class IntercomNode(Node):
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
params = self._get_custom_attrs(context)
|
params = self._get_custom_attrs(context)
|
||||||
params["app_id"] = self.app_id
|
params['app_id'] = self.app_id
|
||||||
html = TRACKING_CODE % {
|
html = TRACKING_CODE % {'settings_json': json.dumps(params, sort_keys=True)}
|
||||||
"settings_json": json.dumps(params, sort_keys=True)
|
|
||||||
}
|
|
||||||
|
|
||||||
if is_internal_ip(context, 'INTERCOM'):
|
if is_internal_ip(context, 'INTERCOM'):
|
||||||
html = disable_html(html, 'Intercom')
|
html = disable_html(html, 'Intercom')
|
||||||
|
|
|
||||||
|
|
@ -41,11 +41,15 @@ def kiss_insights(parser, token):
|
||||||
class KissInsightsNode(Node):
|
class KissInsightsNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.account_number = get_required_setting(
|
self.account_number = get_required_setting(
|
||||||
'KISS_INSIGHTS_ACCOUNT_NUMBER', ACCOUNT_NUMBER_RE,
|
'KISS_INSIGHTS_ACCOUNT_NUMBER',
|
||||||
"must be (a string containing) a number")
|
ACCOUNT_NUMBER_RE,
|
||||||
|
'must be (a string containing) a number',
|
||||||
|
)
|
||||||
self.site_code = get_required_setting(
|
self.site_code = get_required_setting(
|
||||||
'KISS_INSIGHTS_SITE_CODE', SITE_CODE_RE,
|
'KISS_INSIGHTS_SITE_CODE',
|
||||||
"must be a string containing three characters")
|
SITE_CODE_RE,
|
||||||
|
'must be a string containing three characters',
|
||||||
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
commands = []
|
commands = []
|
||||||
|
|
@ -59,7 +63,7 @@ class KissInsightsNode(Node):
|
||||||
html = SETUP_CODE % {
|
html = SETUP_CODE % {
|
||||||
'account_number': self.account_number,
|
'account_number': self.account_number,
|
||||||
'site_code': self.site_code,
|
'site_code': self.site_code,
|
||||||
'commands': " ".join(commands),
|
'commands': ' '.join(commands),
|
||||||
}
|
}
|
||||||
return html
|
return html
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,10 @@ def kiss_metrics(parser, token):
|
||||||
class KissMetricsNode(Node):
|
class KissMetricsNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.api_key = get_required_setting(
|
self.api_key = get_required_setting(
|
||||||
'KISS_METRICS_API_KEY', API_KEY_RE,
|
'KISS_METRICS_API_KEY',
|
||||||
"must be a string containing a 40-digit hexadecimal number")
|
API_KEY_RE,
|
||||||
|
'must be a string containing a 40-digit hexadecimal number',
|
||||||
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
commands = []
|
commands = []
|
||||||
|
|
@ -79,22 +81,28 @@ class KissMetricsNode(Node):
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
name, properties = context[EVENT_CONTEXT_KEY]
|
name, properties = context[EVENT_CONTEXT_KEY]
|
||||||
commands.append(EVENT_CODE % {
|
commands.append(
|
||||||
'name': name,
|
EVENT_CODE
|
||||||
'properties': json.dumps(properties, sort_keys=True),
|
% {
|
||||||
})
|
'name': name,
|
||||||
|
'properties': json.dumps(properties, sort_keys=True),
|
||||||
|
}
|
||||||
|
)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
properties = context[PROPERTY_CONTEXT_KEY]
|
properties = context[PROPERTY_CONTEXT_KEY]
|
||||||
commands.append(PROPERTY_CODE % {
|
commands.append(
|
||||||
'properties': json.dumps(properties, sort_keys=True),
|
PROPERTY_CODE
|
||||||
})
|
% {
|
||||||
|
'properties': json.dumps(properties, sort_keys=True),
|
||||||
|
}
|
||||||
|
)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
html = TRACKING_CODE % {
|
html = TRACKING_CODE % {
|
||||||
'api_key': self.api_key,
|
'api_key': self.api_key,
|
||||||
'commands': " ".join(commands),
|
'commands': ' '.join(commands),
|
||||||
}
|
}
|
||||||
if is_internal_ip(context, 'KISS_METRICS'):
|
if is_internal_ip(context, 'KISS_METRICS'):
|
||||||
html = disable_html(html, 'KISSmetrics')
|
html = disable_html(html, 'KISSmetrics')
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,11 @@ def luckyorange(parser, token):
|
||||||
|
|
||||||
|
|
||||||
class LuckyOrangeNode(Node):
|
class LuckyOrangeNode(Node):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.site_id = get_required_setting(
|
self.site_id = get_required_setting(
|
||||||
'LUCKYORANGE_SITE_ID',
|
'LUCKYORANGE_SITE_ID',
|
||||||
re.compile(r'^\d+$'),
|
re.compile(r'^\d+$'),
|
||||||
"must be (a string containing) a number",
|
'must be (a string containing) a number',
|
||||||
)
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,11 @@ TRACKING_CODE = """
|
||||||
<noscript><p><img src="//%(url)s/matomo.php?idsite=%(siteid)s" style="border:0;" alt="" /></p></noscript>
|
<noscript><p><img src="//%(url)s/matomo.php?idsite=%(siteid)s" style="border:0;" alt="" /></p></noscript>
|
||||||
""" # noqa
|
""" # noqa
|
||||||
|
|
||||||
VARIABLE_CODE = '_paq.push(["setCustomVariable", %(index)s, "%(name)s", "%(value)s", "%(scope)s"]);' # noqa
|
VARIABLE_CODE = (
|
||||||
|
'_paq.push(["setCustomVariable", %(index)s, "%(name)s", "%(value)s", "%(scope)s"]);' # noqa
|
||||||
|
)
|
||||||
IDENTITY_CODE = '_paq.push(["setUserId", "%(userid)s"]);'
|
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'
|
||||||
|
|
||||||
|
|
@ -75,23 +77,27 @@ def matomo(parser, token):
|
||||||
|
|
||||||
class MatomoNode(Node):
|
class MatomoNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.domain_path = \
|
self.domain_path = get_required_setting(
|
||||||
get_required_setting('MATOMO_DOMAIN_PATH', DOMAINPATH_RE,
|
'MATOMO_DOMAIN_PATH',
|
||||||
"must be a domain name, optionally followed "
|
DOMAINPATH_RE,
|
||||||
"by an URI path, no trailing slash (e.g. "
|
'must be a domain name, optionally followed '
|
||||||
"matomo.example.com or my.matomo.server/path)")
|
'by an URI path, no trailing slash (e.g. '
|
||||||
self.site_id = \
|
'matomo.example.com or my.matomo.server/path)',
|
||||||
get_required_setting('MATOMO_SITE_ID', SITEID_RE,
|
)
|
||||||
"must be a (string containing a) number")
|
self.site_id = get_required_setting(
|
||||||
|
'MATOMO_SITE_ID', SITEID_RE, 'must be a (string containing a) number'
|
||||||
|
)
|
||||||
|
|
||||||
def render(self, context):
|
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,)
|
complete_variables = (
|
||||||
for var in custom_variables)
|
var if len(var) >= 4 else var + (DEFAULT_SCOPE,) for var in custom_variables
|
||||||
|
)
|
||||||
|
|
||||||
variables_code = (VARIABLE_CODE % MatomoVar(*var)._asdict()
|
variables_code = (
|
||||||
for var in complete_variables)
|
VARIABLE_CODE % MatomoVar(*var)._asdict() for var in complete_variables
|
||||||
|
)
|
||||||
|
|
||||||
commands = []
|
commands = []
|
||||||
if getattr(settings, 'MATOMO_DISABLE_COOKIES', False):
|
if getattr(settings, 'MATOMO_DISABLE_COOKIES', False):
|
||||||
|
|
@ -99,15 +105,15 @@ class MatomoNode(Node):
|
||||||
|
|
||||||
userid = get_identity(context, 'matomo')
|
userid = get_identity(context, 'matomo')
|
||||||
if userid is not None:
|
if userid is not None:
|
||||||
variables_code = chain(variables_code, (
|
variables_code = chain(
|
||||||
IDENTITY_CODE % {'userid': userid},
|
variables_code, (IDENTITY_CODE % {'userid': userid},)
|
||||||
))
|
)
|
||||||
|
|
||||||
html = TRACKING_CODE % {
|
html = TRACKING_CODE % {
|
||||||
'url': self.domain_path,
|
'url': self.domain_path,
|
||||||
'siteid': self.site_id,
|
'siteid': self.site_id,
|
||||||
'variables': '\n '.join(variables_code),
|
'variables': '\n '.join(variables_code),
|
||||||
'commands': '\n '.join(commands)
|
'commands': '\n '.join(commands),
|
||||||
}
|
}
|
||||||
if is_internal_ip(context, 'MATOMO'):
|
if is_internal_ip(context, 'MATOMO'):
|
||||||
html = disable_html(html, 'Matomo')
|
html = disable_html(html, 'Matomo')
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ e,d])};b.__SV=1.2}})(document,window.mixpanel||[]);
|
||||||
</script>
|
</script>
|
||||||
""" # noqa
|
""" # noqa
|
||||||
IDENTIFY_CODE = "mixpanel.identify('%s');"
|
IDENTIFY_CODE = "mixpanel.identify('%s');"
|
||||||
IDENTIFY_PROPERTIES = "mixpanel.people.set(%s);"
|
IDENTIFY_PROPERTIES = 'mixpanel.people.set(%s);'
|
||||||
EVENT_CODE = "mixpanel.track('%(name)s', %(properties)s);"
|
EVENT_CODE = "mixpanel.track('%(name)s', %(properties)s);"
|
||||||
EVENT_CONTEXT_KEY = 'mixpanel_event'
|
EVENT_CONTEXT_KEY = 'mixpanel_event'
|
||||||
|
|
||||||
|
|
@ -49,29 +49,38 @@ def mixpanel(parser, token):
|
||||||
class MixpanelNode(Node):
|
class MixpanelNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._token = get_required_setting(
|
self._token = get_required_setting(
|
||||||
'MIXPANEL_API_TOKEN', MIXPANEL_API_TOKEN_RE,
|
'MIXPANEL_API_TOKEN',
|
||||||
"must be a string containing a 32-digit hexadecimal number")
|
MIXPANEL_API_TOKEN_RE,
|
||||||
|
'must be a string containing a 32-digit hexadecimal number',
|
||||||
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
commands = []
|
commands = []
|
||||||
identity = get_identity(context, 'mixpanel')
|
identity = get_identity(context, 'mixpanel')
|
||||||
if identity is not None:
|
if identity is not None:
|
||||||
if isinstance(identity, dict):
|
if isinstance(identity, dict):
|
||||||
commands.append(IDENTIFY_CODE % identity.get('id', identity.get('username')))
|
commands.append(
|
||||||
commands.append(IDENTIFY_PROPERTIES % json.dumps(identity, sort_keys=True))
|
IDENTIFY_CODE % identity.get('id', identity.get('username'))
|
||||||
|
)
|
||||||
|
commands.append(
|
||||||
|
IDENTIFY_PROPERTIES % json.dumps(identity, sort_keys=True)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
commands.append(IDENTIFY_CODE % identity)
|
commands.append(IDENTIFY_CODE % identity)
|
||||||
try:
|
try:
|
||||||
name, properties = context[EVENT_CONTEXT_KEY]
|
name, properties = context[EVENT_CONTEXT_KEY]
|
||||||
commands.append(EVENT_CODE % {
|
commands.append(
|
||||||
'name': name,
|
EVENT_CODE
|
||||||
'properties': json.dumps(properties, sort_keys=True),
|
% {
|
||||||
})
|
'name': name,
|
||||||
|
'properties': json.dumps(properties, sort_keys=True),
|
||||||
|
}
|
||||||
|
)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
html = TRACKING_CODE % {
|
html = TRACKING_CODE % {
|
||||||
'token': self._token,
|
'token': self._token,
|
||||||
'commands': " ".join(commands),
|
'commands': ' '.join(commands),
|
||||||
}
|
}
|
||||||
if is_internal_ip(context, 'MIXPANEL'):
|
if is_internal_ip(context, 'MIXPANEL'):
|
||||||
html = disable_html(html, 'Mixpanel')
|
html = disable_html(html, 'Mixpanel')
|
||||||
|
|
|
||||||
|
|
@ -24,16 +24,29 @@ 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_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_CODE = 'olark.configure(\'locale.%(key)s\', "%(msg)s");'
|
||||||
MESSAGE_KEYS = {
|
MESSAGE_KEYS = {
|
||||||
"welcome_title", "chatting_title", "unavailable_title",
|
'welcome_title',
|
||||||
"busy_title", "away_message", "loading_title", "welcome_message",
|
'chatting_title',
|
||||||
"busy_message", "chat_input_text", "name_input_text",
|
'unavailable_title',
|
||||||
"email_input_text", "offline_note_message", "send_button_text",
|
'busy_title',
|
||||||
"offline_note_thankyou_text", "offline_note_error_text",
|
'away_message',
|
||||||
"offline_note_sending_text", "operator_is_typing_text",
|
'loading_title',
|
||||||
"operator_has_stopped_typing_text", "introduction_error_text",
|
'welcome_message',
|
||||||
"introduction_messages", "introduction_submit_button_text",
|
'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()
|
register = Library()
|
||||||
|
|
@ -56,8 +69,10 @@ def olark(parser, token):
|
||||||
class OlarkNode(Node):
|
class OlarkNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.site_id = get_required_setting(
|
self.site_id = get_required_setting(
|
||||||
'OLARK_SITE_ID', SITE_ID_RE,
|
'OLARK_SITE_ID',
|
||||||
"must be a string looking like 'XXXX-XXX-XX-XXXX'")
|
SITE_ID_RE,
|
||||||
|
"must be a string looking like 'XXXX-XXX-XX-XXXX'",
|
||||||
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
extra_code = []
|
extra_code = []
|
||||||
|
|
@ -76,21 +91,22 @@ class OlarkNode(Node):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
extra_code.append(STATUS_CODE % json.dumps(context[STATUS_CONTEXT_KEY],
|
extra_code.append(
|
||||||
sort_keys=True))
|
STATUS_CODE % json.dumps(context[STATUS_CONTEXT_KEY], sort_keys=True)
|
||||||
|
)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
extra_code.extend(self._get_configuration(context))
|
extra_code.extend(self._get_configuration(context))
|
||||||
html = SETUP_CODE % {
|
html = SETUP_CODE % {
|
||||||
'site_id': self.site_id,
|
'site_id': self.site_id,
|
||||||
'extra_code': " ".join(extra_code),
|
'extra_code': ' '.join(extra_code),
|
||||||
}
|
}
|
||||||
return html
|
return html
|
||||||
|
|
||||||
def _get_nickname(self, user):
|
def _get_nickname(self, user):
|
||||||
name = user.get_full_name()
|
name = user.get_full_name()
|
||||||
if name:
|
if name:
|
||||||
return "%s (%s)" % (name, user.username)
|
return '%s (%s)' % (name, user.username)
|
||||||
else:
|
else:
|
||||||
return user.username
|
return user.username
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,10 @@ def optimizely(parser, token):
|
||||||
class OptimizelyNode(Node):
|
class OptimizelyNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.account_number = get_required_setting(
|
self.account_number = get_required_setting(
|
||||||
'OPTIMIZELY_ACCOUNT_NUMBER', ACCOUNT_NUMBER_RE,
|
'OPTIMIZELY_ACCOUNT_NUMBER',
|
||||||
"must be a string looking like 'XXXXXXX'")
|
ACCOUNT_NUMBER_RE,
|
||||||
|
"must be a string looking like 'XXXXXXX'",
|
||||||
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
html = SETUP_CODE % {'account_number': self.account_number}
|
html = SETUP_CODE % {'account_number': self.account_number}
|
||||||
|
|
|
||||||
|
|
@ -56,14 +56,14 @@ def performable(parser, token):
|
||||||
class PerformableNode(Node):
|
class PerformableNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.api_key = get_required_setting(
|
self.api_key = get_required_setting(
|
||||||
'PERFORMABLE_API_KEY', API_KEY_RE,
|
'PERFORMABLE_API_KEY', API_KEY_RE, "must be a string looking like 'XXXXX'"
|
||||||
"must be a string looking like 'XXXXX'")
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
html = SETUP_CODE % {'api_key': self.api_key}
|
html = SETUP_CODE % {'api_key': self.api_key}
|
||||||
identity = get_identity(context, 'performable')
|
identity = get_identity(context, 'performable')
|
||||||
if identity is not None:
|
if identity is not None:
|
||||||
html = "%s%s" % (IDENTIFY_CODE % identity, html)
|
html = '%s%s' % (IDENTIFY_CODE % identity, html)
|
||||||
if is_internal_ip(context, 'PERFORMABLE'):
|
if is_internal_ip(context, 'PERFORMABLE'):
|
||||||
html = disable_html(html, 'Performable')
|
html = disable_html(html, 'Performable')
|
||||||
return html
|
return html
|
||||||
|
|
@ -74,10 +74,13 @@ def performable_embed(hostname, page_id):
|
||||||
"""
|
"""
|
||||||
Include a Performable landing page.
|
Include a Performable landing page.
|
||||||
"""
|
"""
|
||||||
return mark_safe(EMBED_CODE % {
|
return mark_safe(
|
||||||
'hostname': hostname,
|
EMBED_CODE
|
||||||
'page_id': page_id,
|
% {
|
||||||
})
|
'hostname': hostname,
|
||||||
|
'page_id': page_id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def contribute_to_analytical(add_node):
|
def contribute_to_analytical(add_node):
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,10 @@ def rating_mailru(parser, token):
|
||||||
class RatingMailruNode(Node):
|
class RatingMailruNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.counter_id = get_required_setting(
|
self.counter_id = get_required_setting(
|
||||||
'RATING_MAILRU_COUNTER_ID', COUNTER_ID_RE,
|
'RATING_MAILRU_COUNTER_ID',
|
||||||
"must be (a string containing) a number'")
|
COUNTER_ID_RE,
|
||||||
|
"must be (a string containing) a number'",
|
||||||
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
html = COUNTER_CODE % {
|
html = COUNTER_CODE % {
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,9 @@ FORM_POSITION_TOP_RIGHT = 'tr'
|
||||||
FORM_POSITION_BOTTOM_LEFT = 'bl'
|
FORM_POSITION_BOTTOM_LEFT = 'bl'
|
||||||
FORM_POSITION_BOTTOM_RIGHT = 'br'
|
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 = """
|
SETUP_CODE = """
|
||||||
<script type="text/javascript">
|
<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">
|
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">
|
||||||
|
|
@ -34,7 +36,9 @@ SETUP_CODE = """
|
||||||
DOMAIN_CODE = 'SnapABug.setDomain("%s");'
|
DOMAIN_CODE = 'SnapABug.setDomain("%s");'
|
||||||
SECURE_CONNECTION_CODE = 'SnapABug.setSecureConnexion();'
|
SECURE_CONNECTION_CODE = 'SnapABug.setSecureConnexion();'
|
||||||
INIT_CODE = 'SnapABug.init("%s");'
|
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");'
|
SETBUTTON_CODE = 'SnapABug.setButton("%s");'
|
||||||
SETEMAIL_CODE = 'SnapABug.setUserEmail("%s"%s);'
|
SETEMAIL_CODE = 'SnapABug.setUserEmail("%s"%s);'
|
||||||
SETLOCALE_CODE = 'SnapABug.setLocale("%s");'
|
SETLOCALE_CODE = 'SnapABug.setLocale("%s");'
|
||||||
|
|
@ -67,21 +71,24 @@ def snapengage(parser, token):
|
||||||
class SnapEngageNode(Node):
|
class SnapEngageNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.widget_id = get_required_setting(
|
self.widget_id = get_required_setting(
|
||||||
'SNAPENGAGE_WIDGET_ID', WIDGET_ID_RE,
|
'SNAPENGAGE_WIDGET_ID',
|
||||||
"must be a string looking like this: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'")
|
WIDGET_ID_RE,
|
||||||
|
"must be a string looking like this: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'",
|
||||||
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
settings_code = []
|
settings_code = []
|
||||||
|
|
||||||
domain = self._get_setting(context, 'snapengage_domain',
|
domain = self._get_setting(context, 'snapengage_domain', 'SNAPENGAGE_DOMAIN')
|
||||||
'SNAPENGAGE_DOMAIN')
|
|
||||||
if domain is not None:
|
if domain is not None:
|
||||||
settings_code.append(DOMAIN_CODE % domain)
|
settings_code.append(DOMAIN_CODE % domain)
|
||||||
|
|
||||||
secure_connection = self._get_setting(context,
|
secure_connection = self._get_setting(
|
||||||
'snapengage_secure_connection',
|
context,
|
||||||
'SNAPENGAGE_SECURE_CONNECTION',
|
'snapengage_secure_connection',
|
||||||
False)
|
'SNAPENGAGE_SECURE_CONNECTION',
|
||||||
|
False,
|
||||||
|
)
|
||||||
if secure_connection:
|
if secure_connection:
|
||||||
settings_code.append(SECURE_CONNECTION_CODE)
|
settings_code.append(SECURE_CONNECTION_CODE)
|
||||||
|
|
||||||
|
|
@ -89,61 +96,70 @@ class SnapEngageNode(Node):
|
||||||
if email is None:
|
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 email is not None:
|
||||||
if self._get_setting(context, 'snapengage_readonly_email',
|
if self._get_setting(
|
||||||
'SNAPENGAGE_READONLY_EMAIL', False):
|
context, 'snapengage_readonly_email', 'SNAPENGAGE_READONLY_EMAIL', False
|
||||||
|
):
|
||||||
readonly_tail = ',true'
|
readonly_tail = ',true'
|
||||||
else:
|
else:
|
||||||
readonly_tail = ''
|
readonly_tail = ''
|
||||||
settings_code.append(SETEMAIL_CODE % (email, readonly_tail))
|
settings_code.append(SETEMAIL_CODE % (email, readonly_tail))
|
||||||
|
|
||||||
locale = self._get_setting(context, 'snapengage_locale',
|
locale = self._get_setting(context, 'snapengage_locale', 'SNAPENGAGE_LOCALE')
|
||||||
'SNAPENGAGE_LOCALE')
|
|
||||||
if locale is None:
|
if locale is None:
|
||||||
locale = translation.to_locale(translation.get_language())
|
locale = translation.to_locale(translation.get_language())
|
||||||
settings_code.append(SETLOCALE_CODE % locale)
|
settings_code.append(SETLOCALE_CODE % locale)
|
||||||
|
|
||||||
form_position = self._get_setting(context,
|
form_position = self._get_setting(
|
||||||
'snapengage_form_position', 'SNAPENGAGE_FORM_POSITION')
|
context, 'snapengage_form_position', 'SNAPENGAGE_FORM_POSITION'
|
||||||
|
)
|
||||||
if form_position is not None:
|
if form_position is not None:
|
||||||
settings_code.append(FORM_POSITION_CODE % form_position)
|
settings_code.append(FORM_POSITION_CODE % form_position)
|
||||||
|
|
||||||
form_top_position = self._get_setting(context,
|
form_top_position = self._get_setting(
|
||||||
'snapengage_form_top_position',
|
context, 'snapengage_form_top_position', 'SNAPENGAGE_FORM_TOP_POSITION'
|
||||||
'SNAPENGAGE_FORM_TOP_POSITION')
|
)
|
||||||
if form_top_position is not None:
|
if form_top_position is not None:
|
||||||
settings_code.append(FORM_TOP_POSITION_CODE % form_top_position)
|
settings_code.append(FORM_TOP_POSITION_CODE % form_top_position)
|
||||||
|
|
||||||
show_offline = self._get_setting(context, 'snapengage_show_offline',
|
show_offline = self._get_setting(
|
||||||
'SNAPENGAGE_SHOW_OFFLINE', True)
|
context, 'snapengage_show_offline', 'SNAPENGAGE_SHOW_OFFLINE', True
|
||||||
|
)
|
||||||
if not show_offline:
|
if not show_offline:
|
||||||
settings_code.append(DISABLE_OFFLINE_CODE)
|
settings_code.append(DISABLE_OFFLINE_CODE)
|
||||||
|
|
||||||
screenshots = self._get_setting(context, 'snapengage_screenshots',
|
screenshots = self._get_setting(
|
||||||
'SNAPENGAGE_SCREENSHOTS', True)
|
context, 'snapengage_screenshots', 'SNAPENGAGE_SCREENSHOTS', True
|
||||||
|
)
|
||||||
if not screenshots:
|
if not screenshots:
|
||||||
settings_code.append(DISABLE_SCREENSHOT_CODE)
|
settings_code.append(DISABLE_SCREENSHOT_CODE)
|
||||||
|
|
||||||
offline_screenshots = self._get_setting(context,
|
offline_screenshots = self._get_setting(
|
||||||
'snapengage_offline_screenshots',
|
context,
|
||||||
'SNAPENGAGE_OFFLINE_SCREENSHOTS', True)
|
'snapengage_offline_screenshots',
|
||||||
|
'SNAPENGAGE_OFFLINE_SCREENSHOTS',
|
||||||
|
True,
|
||||||
|
)
|
||||||
if not offline_screenshots:
|
if not offline_screenshots:
|
||||||
settings_code.append(DISABLE_OFFLINE_SCREENSHOT_CODE)
|
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)
|
settings_code.append(DISABLE_PROACTIVE_CHAT_CODE)
|
||||||
|
|
||||||
sounds = self._get_setting(context, 'snapengage_sounds',
|
sounds = self._get_setting(
|
||||||
'SNAPENGAGE_SOUNDS', True)
|
context, 'snapengage_sounds', 'SNAPENGAGE_SOUNDS', True
|
||||||
|
)
|
||||||
if not sounds:
|
if not sounds:
|
||||||
settings_code.append(DISABLE_SOUNDS_CODE)
|
settings_code.append(DISABLE_SOUNDS_CODE)
|
||||||
|
|
||||||
button_effect = self._get_setting(context, 'snapengage_button_effect',
|
button_effect = self._get_setting(
|
||||||
'SNAPENGAGE_BUTTON_EFFECT')
|
context, 'snapengage_button_effect', 'SNAPENGAGE_BUTTON_EFFECT'
|
||||||
|
)
|
||||||
if button_effect is not None:
|
if button_effect is not None:
|
||||||
settings_code.append(BUTTONEFFECT_CODE % button_effect)
|
settings_code.append(BUTTONEFFECT_CODE % button_effect)
|
||||||
|
|
||||||
button = self._get_setting(context, 'snapengage_button',
|
button = self._get_setting(
|
||||||
'SNAPENGAGE_BUTTON', BUTTON_STYLE_DEFAULT)
|
context, 'snapengage_button', 'SNAPENGAGE_BUTTON', BUTTON_STYLE_DEFAULT
|
||||||
|
)
|
||||||
if button == BUTTON_STYLE_NONE:
|
if button == BUTTON_STYLE_NONE:
|
||||||
settings_code.append(INIT_CODE % self.widget_id)
|
settings_code.append(INIT_CODE % self.widget_id)
|
||||||
else:
|
else:
|
||||||
|
|
@ -152,21 +168,28 @@ class SnapEngageNode(Node):
|
||||||
settings_code.append(SETBUTTON_CODE % button)
|
settings_code.append(SETBUTTON_CODE % button)
|
||||||
button_location = self._get_setting(
|
button_location = self._get_setting(
|
||||||
context,
|
context,
|
||||||
'snapengage_button_location', 'SNAPENGAGE_BUTTON_LOCATION',
|
'snapengage_button_location',
|
||||||
BUTTON_LOCATION_LEFT)
|
'SNAPENGAGE_BUTTON_LOCATION',
|
||||||
|
BUTTON_LOCATION_LEFT,
|
||||||
|
)
|
||||||
button_offset = self._get_setting(
|
button_offset = self._get_setting(
|
||||||
context,
|
context,
|
||||||
'snapengage_button_location_offset',
|
'snapengage_button_location_offset',
|
||||||
'SNAPENGAGE_BUTTON_LOCATION_OFFSET', '55%')
|
'SNAPENGAGE_BUTTON_LOCATION_OFFSET',
|
||||||
settings_code.append(ADDBUTTON_CODE % {
|
'55%',
|
||||||
'id': self.widget_id,
|
)
|
||||||
'location': button_location,
|
settings_code.append(
|
||||||
'offset': button_offset,
|
ADDBUTTON_CODE
|
||||||
'dynamic_tail': ',true' if (button == BUTTON_STYLE_LIVE) else '',
|
% {
|
||||||
})
|
'id': self.widget_id,
|
||||||
|
'location': button_location,
|
||||||
|
'offset': button_offset,
|
||||||
|
'dynamic_tail': ',true' if (button == BUTTON_STYLE_LIVE) else '',
|
||||||
|
}
|
||||||
|
)
|
||||||
html = SETUP_CODE % {
|
html = SETUP_CODE % {
|
||||||
'widget_id': self.widget_id,
|
'widget_id': self.widget_id,
|
||||||
'settings_code': " ".join(settings_code),
|
'settings_code': ' '.join(settings_code),
|
||||||
}
|
}
|
||||||
return html
|
return html
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,8 @@ def spring_metrics(parser, token):
|
||||||
class SpringMetricsNode(Node):
|
class SpringMetricsNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.tracking_id = get_required_setting(
|
self.tracking_id = get_required_setting(
|
||||||
'SPRING_METRICS_TRACKING_ID',
|
'SPRING_METRICS_TRACKING_ID', TRACKING_ID_RE, 'must be a hexadecimal string'
|
||||||
TRACKING_ID_RE, "must be a hexadecimal string")
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
custom = {}
|
custom = {}
|
||||||
|
|
@ -63,8 +63,7 @@ class SpringMetricsNode(Node):
|
||||||
if var.startswith('spring_metrics_'):
|
if var.startswith('spring_metrics_'):
|
||||||
custom[var[15:]] = val
|
custom[var[15:]] = val
|
||||||
if 'email' not in custom:
|
if 'email' not in custom:
|
||||||
identity = get_identity(context, 'spring_metrics',
|
identity = get_identity(context, 'spring_metrics', lambda u: u.email)
|
||||||
lambda u: u.email)
|
|
||||||
if identity is not None:
|
if identity is not None:
|
||||||
custom['email'] = identity
|
custom['email'] = identity
|
||||||
|
|
||||||
|
|
@ -81,9 +80,11 @@ class SpringMetricsNode(Node):
|
||||||
convert = params.pop('convert', None)
|
convert = params.pop('convert', None)
|
||||||
if convert is not None:
|
if convert is not None:
|
||||||
commands.append("_springMetq.push(['convert', '%s'])" % convert)
|
commands.append("_springMetq.push(['convert', '%s'])" % convert)
|
||||||
commands.extend("_springMetq.push(['setdata', {'%s': '%s'}]);"
|
commands.extend(
|
||||||
% (var, val) for var, val in params.items())
|
"_springMetq.push(['setdata', {'%s': '%s'}]);" % (var, val)
|
||||||
return " ".join(commands)
|
for var, val in params.items()
|
||||||
|
)
|
||||||
|
return ' '.join(commands)
|
||||||
|
|
||||||
|
|
||||||
def contribute_to_analytical(add_node):
|
def contribute_to_analytical(add_node):
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,8 @@ def uservoice(parser, token):
|
||||||
class UserVoiceNode(Node):
|
class UserVoiceNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.default_widget_key = get_required_setting(
|
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):
|
def render(self, context):
|
||||||
widget_key = context.get('uservoice_widget_key')
|
widget_key = context.get('uservoice_widget_key')
|
||||||
|
|
@ -65,13 +66,16 @@ class UserVoiceNode(Node):
|
||||||
if identity:
|
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',
|
trigger = context.get(
|
||||||
getattr(settings, 'USERVOICE_ADD_TRIGGER', True))
|
'uservoice_add_trigger', getattr(settings, 'USERVOICE_ADD_TRIGGER', True)
|
||||||
|
)
|
||||||
|
|
||||||
html = TRACKING_CODE % {'widget_key': widget_key,
|
html = TRACKING_CODE % {
|
||||||
'options': json.dumps(options, sort_keys=True),
|
'widget_key': widget_key,
|
||||||
'trigger': TRIGGER if trigger else '',
|
'options': json.dumps(options, sort_keys=True),
|
||||||
'identity': identity if identity else ''}
|
'trigger': TRIGGER if trigger else '',
|
||||||
|
'identity': identity if identity else '',
|
||||||
|
}
|
||||||
return html
|
return html
|
||||||
|
|
||||||
def _identify(self, user):
|
def _identify(self, user):
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,8 @@ def woopra(parser, token):
|
||||||
class WoopraNode(Node):
|
class WoopraNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.domain = get_required_setting(
|
self.domain = get_required_setting(
|
||||||
'WOOPRA_DOMAIN', DOMAIN_RE,
|
'WOOPRA_DOMAIN', DOMAIN_RE, 'must be a domain name'
|
||||||
"must be a domain name")
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
settings = self._get_settings(context)
|
settings = self._get_settings(context)
|
||||||
|
|
@ -81,8 +81,7 @@ class WoopraNode(Node):
|
||||||
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)
|
user = get_user_from_context(context)
|
||||||
if user is not None and get_user_is_authenticated(user):
|
if user is not None and get_user_is_authenticated(user):
|
||||||
params['name'] = get_identity(
|
params['name'] = get_identity(context, 'woopra', self._identify, user)
|
||||||
context, 'woopra', self._identify, user)
|
|
||||||
if user.email:
|
if user.email:
|
||||||
params['email'] = user.email
|
params['email'] = user.email
|
||||||
return params
|
return params
|
||||||
|
|
|
||||||
|
|
@ -57,15 +57,17 @@ def yandex_metrica(parser, token):
|
||||||
class YandexMetricaNode(Node):
|
class YandexMetricaNode(Node):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.counter_id = get_required_setting(
|
self.counter_id = get_required_setting(
|
||||||
'YANDEX_METRICA_COUNTER_ID', COUNTER_ID_RE,
|
'YANDEX_METRICA_COUNTER_ID',
|
||||||
"must be (a string containing) a number'")
|
COUNTER_ID_RE,
|
||||||
|
"must be (a string containing) a number'",
|
||||||
|
)
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
options = {
|
options = {
|
||||||
'id': int(self.counter_id),
|
'id': int(self.counter_id),
|
||||||
'clickmap': True,
|
'clickmap': True,
|
||||||
'trackLinks': True,
|
'trackLinks': True,
|
||||||
'accurateTrackBounce': True
|
'accurateTrackBounce': True,
|
||||||
}
|
}
|
||||||
if getattr(settings, 'YANDEX_METRICA_WEBVISOR', False):
|
if getattr(settings, 'YANDEX_METRICA_WEBVISOR', False):
|
||||||
options['webvisor'] = True
|
options['webvisor'] = True
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,7 @@ Utility function for django-analytical.
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
|
||||||
HTML_COMMENT = "<!-- %(service)s disabled on internal IP " \
|
HTML_COMMENT = '<!-- %(service)s disabled on internal IP address\n%(html)s\n-->'
|
||||||
"address\n%(html)s\n-->"
|
|
||||||
|
|
||||||
|
|
||||||
def get_required_setting(setting, value_re, invalid_msg):
|
def get_required_setting(setting, value_re, invalid_msg):
|
||||||
|
|
@ -19,13 +18,14 @@ def get_required_setting(setting, value_re, invalid_msg):
|
||||||
try:
|
try:
|
||||||
value = getattr(settings, setting)
|
value = getattr(settings, setting)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise AnalyticalException("%s setting: not found" % setting)
|
raise AnalyticalException('%s setting: not found' % setting)
|
||||||
if not value:
|
if not value:
|
||||||
raise AnalyticalException("%s setting is not set" % setting)
|
raise AnalyticalException('%s setting is not set' % setting)
|
||||||
value = str(value)
|
value = str(value)
|
||||||
if not value_re.search(value):
|
if not value_re.search(value):
|
||||||
raise AnalyticalException("%s setting: %s: '%s'"
|
raise AnalyticalException(
|
||||||
% (setting, invalid_msg, value))
|
"%s setting: %s: '%s'" % (setting, invalid_msg, value)
|
||||||
|
)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -112,6 +112,7 @@ def get_domain(context, prefix):
|
||||||
if domain is 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
|
from django.contrib.sites.models import Site
|
||||||
|
|
||||||
try:
|
try:
|
||||||
domain = Site.objects.get_current().domain
|
domain = Site.objects.get_current().domain
|
||||||
except (ImproperlyConfigured, Site.DoesNotExist):
|
except (ImproperlyConfigured, Site.DoesNotExist):
|
||||||
|
|
@ -162,4 +163,5 @@ class AnalyticalException(Exception):
|
||||||
Raised when an exception occurs in any django-analytical code that should
|
Raised when an exception occurs in any django-analytical code that should
|
||||||
be silenced in templates.
|
be silenced in templates.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
silent_variable_failure = True
|
silent_variable_failure = True
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,21 @@
|
||||||
def setup(app):
|
def setup(app):
|
||||||
app.add_crossref_type(
|
app.add_crossref_type(
|
||||||
directivename="setting",
|
directivename='setting',
|
||||||
rolename="setting",
|
rolename='setting',
|
||||||
indextemplate="pair: %s; setting",
|
indextemplate='pair: %s; setting',
|
||||||
)
|
)
|
||||||
app.add_crossref_type(
|
app.add_crossref_type(
|
||||||
directivename="templatetag",
|
directivename='templatetag',
|
||||||
rolename="ttag",
|
rolename='ttag',
|
||||||
indextemplate="pair: %s; template tag"
|
indextemplate='pair: %s; template tag',
|
||||||
)
|
)
|
||||||
app.add_crossref_type(
|
app.add_crossref_type(
|
||||||
directivename="templatefilter",
|
directivename='templatefilter',
|
||||||
rolename="tfilter",
|
rolename='tfilter',
|
||||||
indextemplate="pair: %s; template filter"
|
indextemplate='pair: %s; template filter',
|
||||||
)
|
)
|
||||||
app.add_crossref_type(
|
app.add_crossref_type(
|
||||||
directivename="fieldlookup",
|
directivename='fieldlookup',
|
||||||
rolename="lookup",
|
rolename='lookup',
|
||||||
indextemplate="pair: %s; field lookup type",
|
indextemplate='pair: %s; field lookup type',
|
||||||
)
|
)
|
||||||
|
|
|
||||||
15
docs/conf.py
15
docs/conf.py
|
|
@ -29,8 +29,10 @@ pygments_style = 'sphinx'
|
||||||
|
|
||||||
intersphinx_mapping = {
|
intersphinx_mapping = {
|
||||||
'python': ('http://docs.python.org/3.13', None),
|
'python': ('http://docs.python.org/3.13', None),
|
||||||
'django': ('http://docs.djangoproject.com/en/stable',
|
'django': (
|
||||||
'http://docs.djangoproject.com/en/stable/_objects/'),
|
'http://docs.djangoproject.com/en/stable',
|
||||||
|
'http://docs.djangoproject.com/en/stable/_objects/',
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -43,6 +45,11 @@ htmlhelp_basename = 'analyticaldoc'
|
||||||
# -- Options for LaTeX output -----------------------------------------------
|
# -- Options for LaTeX output -----------------------------------------------
|
||||||
|
|
||||||
latex_documents = [
|
latex_documents = [
|
||||||
('index', 'django-analytical.tex', 'Documentation for django-analytical',
|
(
|
||||||
'Joost Cassee', 'manual'),
|
'index',
|
||||||
|
'django-analytical.tex',
|
||||||
|
'Documentation for django-analytical',
|
||||||
|
'Joost Cassee',
|
||||||
|
'manual',
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ register = Library()
|
||||||
def _location_node(location):
|
def _location_node(location):
|
||||||
class DummyNode(Node):
|
class DummyNode(Node):
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
return "<!-- dummy_%s -->" % location
|
return '<!-- dummy_%s -->' % location
|
||||||
|
|
||||||
return DummyNode
|
return DummyNode
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -25,6 +26,7 @@ def _location_tag(location):
|
||||||
if len(bits) > 1:
|
if len(bits) > 1:
|
||||||
raise TemplateSyntaxError("'%s' tag takes no arguments" % bits[0])
|
raise TemplateSyntaxError("'%s' tag takes no arguments" % bits[0])
|
||||||
return _location_nodes[location]
|
return _location_nodes[location]
|
||||||
|
|
||||||
return dummy_tag
|
return dummy_tag
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ class AnalyticsTagTestCase(TagTestCase):
|
||||||
def render_location_tag(self, location, vars=None):
|
def render_location_tag(self, location, vars=None):
|
||||||
if vars is None:
|
if vars is None:
|
||||||
vars = {}
|
vars = {}
|
||||||
t = Template("{%% load analytical %%}{%% analytical_%s %%}" % location)
|
t = Template('{%% load analytical %%}{%% analytical_%s %%}' % location)
|
||||||
return t.render(Context(vars))
|
return t.render(Context(vars))
|
||||||
|
|
||||||
def test_location_tags(self):
|
def test_location_tags(self):
|
||||||
|
|
|
||||||
|
|
@ -22,21 +22,25 @@ class ChartbeatTagTestCaseNoSites(TestCase):
|
||||||
self.assertTrue('var _sf_async_config={"uid": "12345"};' in r, r)
|
self.assertTrue('var _sf_async_config={"uid": "12345"};' in r, r)
|
||||||
|
|
||||||
|
|
||||||
@override_settings(INSTALLED_APPS=(
|
@override_settings(
|
||||||
'analytical',
|
INSTALLED_APPS=(
|
||||||
'django.contrib.sites',
|
'analytical',
|
||||||
'django.contrib.auth',
|
'django.contrib.sites',
|
||||||
'django.contrib.contenttypes',
|
'django.contrib.auth',
|
||||||
))
|
'django.contrib.contenttypes',
|
||||||
|
)
|
||||||
|
)
|
||||||
@override_settings(CHARTBEAT_USER_ID='12345')
|
@override_settings(CHARTBEAT_USER_ID='12345')
|
||||||
class ChartbeatTagTestCaseWithSites(TestCase):
|
class ChartbeatTagTestCaseWithSites(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
call_command("migrate", verbosity=0)
|
|
||||||
|
call_command('migrate', verbosity=0)
|
||||||
|
|
||||||
def test_rendering_setup_site(self):
|
def test_rendering_setup_site(self):
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
site = Site.objects.create(domain="test.com", name="test")
|
|
||||||
|
site = Site.objects.create(domain='test.com', name='test')
|
||||||
with override_settings(SITE_ID=site.id):
|
with override_settings(SITE_ID=site.id):
|
||||||
r = ChartbeatBottomNode().render(Context())
|
r = ChartbeatBottomNode().render(Context())
|
||||||
assert re.search('var _sf_async_config={.*"uid": "12345".*};', r)
|
assert re.search('var _sf_async_config={.*"uid": "12345".*};', r)
|
||||||
|
|
@ -60,24 +64,36 @@ class ChartbeatTagTestCase(TagTestCase):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_top_tag(self):
|
def test_top_tag(self):
|
||||||
r = self.render_tag('chartbeat', 'chartbeat_top', {'chartbeat_domain': "test.com"})
|
r = self.render_tag(
|
||||||
|
'chartbeat', 'chartbeat_top', {'chartbeat_domain': 'test.com'}
|
||||||
|
)
|
||||||
assert 'var _sf_startpt=(new Date()).getTime()' in r
|
assert 'var _sf_startpt=(new Date()).getTime()' in r
|
||||||
|
|
||||||
def test_bottom_tag(self):
|
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'}
|
||||||
|
)
|
||||||
assert re.search('var _sf_async_config={.*"uid": "12345".*};', r)
|
assert re.search('var _sf_async_config={.*"uid": "12345".*};', r)
|
||||||
assert re.search('var _sf_async_config={.*"domain": "test.com".*};', r)
|
assert re.search('var _sf_async_config={.*"domain": "test.com".*};', r)
|
||||||
|
|
||||||
def test_top_node(self):
|
def test_top_node(self):
|
||||||
r = ChartbeatTopNode().render(Context({
|
r = ChartbeatTopNode().render(
|
||||||
'chartbeat_domain': "test.com",
|
Context(
|
||||||
}))
|
{
|
||||||
|
'chartbeat_domain': 'test.com',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'var _sf_startpt=(new Date()).getTime()' in r
|
assert 'var _sf_startpt=(new Date()).getTime()' in r
|
||||||
|
|
||||||
def test_bottom_node(self):
|
def test_bottom_node(self):
|
||||||
r = ChartbeatBottomNode().render(Context({
|
r = ChartbeatBottomNode().render(
|
||||||
'chartbeat_domain': "test.com",
|
Context(
|
||||||
}))
|
{
|
||||||
|
'chartbeat_domain': 'test.com',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert re.search('var _sf_async_config={.*"uid": "12345".*};', r)
|
assert re.search('var _sf_async_config={.*"uid": "12345".*};', r)
|
||||||
assert re.search('var _sf_async_config={.*"domain": "test.com".*};', r)
|
assert re.search('var _sf_async_config={.*"domain": "test.com".*};', r)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,11 +52,17 @@ class ClickyTagTestCase(TagTestCase):
|
||||||
assert 'var clicky_custom = {"session": {"username":' not in r
|
assert 'var clicky_custom = {"session": {"username":' not in r
|
||||||
|
|
||||||
def test_custom(self):
|
def test_custom(self):
|
||||||
r = ClickyNode().render(Context({
|
r = ClickyNode().render(
|
||||||
'clicky_var1': 'val1',
|
Context(
|
||||||
'clicky_var2': 'val2',
|
{
|
||||||
}))
|
'clicky_var1': 'val1',
|
||||||
assert re.search(r'var clicky_custom = {.*"var1": "val1", "var2": "val2".*};', r)
|
'clicky_var2': 'val2',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert re.search(
|
||||||
|
r'var clicky_custom = {.*"var1": "val1", "var2": "val2".*};', 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):
|
def test_render_internal_ip(self):
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Tests for the Facebook Pixel template tags.
|
Tests for the Facebook Pixel template tags.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
from django.template import Context, Template, TemplateSyntaxError
|
from django.template import Context, Template, TemplateSyntaxError
|
||||||
|
|
@ -39,7 +40,6 @@ expected_body_html = """\
|
||||||
|
|
||||||
@override_settings(FACEBOOK_PIXEL_ID='1234567890')
|
@override_settings(FACEBOOK_PIXEL_ID='1234567890')
|
||||||
class FacebookPixelTagTestCase(TagTestCase):
|
class FacebookPixelTagTestCase(TagTestCase):
|
||||||
|
|
||||||
maxDiff = None
|
maxDiff = None
|
||||||
|
|
||||||
def test_head_tag(self):
|
def test_head_tag(self):
|
||||||
|
|
@ -60,11 +60,15 @@ class FacebookPixelTagTestCase(TagTestCase):
|
||||||
|
|
||||||
def test_tags_take_no_args(self):
|
def test_tags_take_no_args(self):
|
||||||
template = '{%% load facebook_pixel %%}{%% facebook_pixel_%s "arg" %%}'
|
template = '{%% load facebook_pixel %%}{%% facebook_pixel_%s "arg" %%}'
|
||||||
with pytest.raises(TemplateSyntaxError, match="'facebook_pixel_head' takes no arguments"):
|
with pytest.raises(
|
||||||
Template(template % "head").render(Context({}))
|
TemplateSyntaxError, match="'facebook_pixel_head' takes no arguments"
|
||||||
|
):
|
||||||
|
Template(template % 'head').render(Context({}))
|
||||||
|
|
||||||
with pytest.raises(TemplateSyntaxError, match="'facebook_pixel_body' takes no arguments"):
|
with pytest.raises(
|
||||||
Template(template % "body").render(Context({}))
|
TemplateSyntaxError, match="'facebook_pixel_body' takes no arguments"
|
||||||
|
):
|
||||||
|
Template(template % 'body').render(Context({}))
|
||||||
|
|
||||||
@override_settings(FACEBOOK_PIXEL_ID=None)
|
@override_settings(FACEBOOK_PIXEL_ID=None)
|
||||||
def test_no_id(self):
|
def test_no_id(self):
|
||||||
|
|
@ -76,9 +80,7 @@ class FacebookPixelTagTestCase(TagTestCase):
|
||||||
|
|
||||||
@override_settings(FACEBOOK_PIXEL_ID='invalid')
|
@override_settings(FACEBOOK_PIXEL_ID='invalid')
|
||||||
def test_invalid_id(self):
|
def test_invalid_id(self):
|
||||||
expected_pattern = (
|
expected_pattern = r"FACEBOOK_PIXEL_ID setting: must be \(a string containing\) a number: 'invalid'$"
|
||||||
r"FACEBOOK_PIXEL_ID setting: must be \(a string containing\) a number: 'invalid'$"
|
|
||||||
)
|
|
||||||
with pytest.raises(AnalyticalException, match=expected_pattern):
|
with pytest.raises(AnalyticalException, match=expected_pattern):
|
||||||
FacebookPixelHeadNode()
|
FacebookPixelHeadNode()
|
||||||
with pytest.raises(AnalyticalException, match=expected_pattern):
|
with pytest.raises(AnalyticalException, match=expected_pattern):
|
||||||
|
|
@ -91,11 +93,13 @@ class FacebookPixelTagTestCase(TagTestCase):
|
||||||
context = Context({'request': request})
|
context = Context({'request': request})
|
||||||
|
|
||||||
def _disabled(html):
|
def _disabled(html):
|
||||||
return '\n'.join([
|
return '\n'.join(
|
||||||
'<!-- Facebook Pixel disabled on internal IP address',
|
[
|
||||||
html,
|
'<!-- Facebook Pixel disabled on internal IP address',
|
||||||
'-->',
|
html,
|
||||||
])
|
'-->',
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
head_html = FacebookPixelHeadNode().render(context)
|
head_html = FacebookPixelHeadNode().render(context)
|
||||||
assert _disabled(expected_head_html) == head_html
|
assert _disabled(expected_head_html) == head_html
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,9 @@ class GaugesTagTestCase(TagTestCase):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_tag(self):
|
def test_tag(self):
|
||||||
assert self.render_tag('gauges', 'gauges') == """
|
assert (
|
||||||
|
self.render_tag('gauges', 'gauges')
|
||||||
|
== """
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var _gauges = _gauges || [];
|
var _gauges = _gauges || [];
|
||||||
(function() {
|
(function() {
|
||||||
|
|
@ -34,9 +36,12 @@ class GaugesTagTestCase(TagTestCase):
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
"""
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
def test_node(self):
|
def test_node(self):
|
||||||
assert GaugesNode().render(Context()) == """
|
assert (
|
||||||
|
GaugesNode().render(Context())
|
||||||
|
== """
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var _gauges = _gauges || [];
|
var _gauges = _gauges || [];
|
||||||
(function() {
|
(function() {
|
||||||
|
|
@ -51,6 +56,7 @@ class GaugesTagTestCase(TagTestCase):
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
"""
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
@override_settings(GAUGES_SITE_ID=None)
|
@override_settings(GAUGES_SITE_ID=None)
|
||||||
def test_no_account_number(self):
|
def test_no_account_number(self):
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,10 @@ from analytical.templatetags.google_analytics import (
|
||||||
from analytical.utils import AnalyticalException
|
from analytical.utils import AnalyticalException
|
||||||
|
|
||||||
|
|
||||||
@override_settings(GOOGLE_ANALYTICS_PROPERTY_ID='UA-123456-7',
|
@override_settings(
|
||||||
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_SINGLE_DOMAIN)
|
GOOGLE_ANALYTICS_PROPERTY_ID='UA-123456-7',
|
||||||
|
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_SINGLE_DOMAIN,
|
||||||
|
)
|
||||||
class GoogleAnalyticsTagTestCase(TagTestCase):
|
class GoogleAnalyticsTagTestCase(TagTestCase):
|
||||||
"""
|
"""
|
||||||
Tests for the ``google_analytics`` template tag.
|
Tests for the ``google_analytics`` template tag.
|
||||||
|
|
@ -47,15 +49,19 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
||||||
with pytest.raises(AnalyticalException):
|
with pytest.raises(AnalyticalException):
|
||||||
GoogleAnalyticsNode()
|
GoogleAnalyticsNode()
|
||||||
|
|
||||||
@override_settings(GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_SUBDOMAINS,
|
@override_settings(
|
||||||
GOOGLE_ANALYTICS_DOMAIN='example.com')
|
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_SUBDOMAINS,
|
||||||
|
GOOGLE_ANALYTICS_DOMAIN='example.com',
|
||||||
|
)
|
||||||
def test_track_multiple_subdomains(self):
|
def test_track_multiple_subdomains(self):
|
||||||
r = GoogleAnalyticsNode().render(Context())
|
r = GoogleAnalyticsNode().render(Context())
|
||||||
assert "_gaq.push(['_setDomainName', 'example.com']);" in r
|
assert "_gaq.push(['_setDomainName', 'example.com']);" in r
|
||||||
assert "_gaq.push(['_setAllowHash', false]);" in r
|
assert "_gaq.push(['_setAllowHash', false]);" in r
|
||||||
|
|
||||||
@override_settings(GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_DOMAINS,
|
@override_settings(
|
||||||
GOOGLE_ANALYTICS_DOMAIN='example.com')
|
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_DOMAINS,
|
||||||
|
GOOGLE_ANALYTICS_DOMAIN='example.com',
|
||||||
|
)
|
||||||
def test_track_multiple_domains(self):
|
def test_track_multiple_domains(self):
|
||||||
r = GoogleAnalyticsNode().render(Context())
|
r = GoogleAnalyticsNode().render(Context())
|
||||||
assert "_gaq.push(['_setDomainName', 'example.com']);" in r
|
assert "_gaq.push(['_setDomainName', 'example.com']);" in r
|
||||||
|
|
@ -63,12 +69,14 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
||||||
assert "_gaq.push(['_setAllowLinker', true]);" in r
|
assert "_gaq.push(['_setAllowLinker', true]);" in r
|
||||||
|
|
||||||
def test_custom_vars(self):
|
def test_custom_vars(self):
|
||||||
context = Context({
|
context = Context(
|
||||||
'google_analytics_var1': ('test1', 'foo'),
|
{
|
||||||
'google_analytics_var2': ('test2', 'bar', SCOPE_VISITOR),
|
'google_analytics_var1': ('test1', 'foo'),
|
||||||
'google_analytics_var4': ('test4', 'baz', SCOPE_SESSION),
|
'google_analytics_var2': ('test2', 'bar', SCOPE_VISITOR),
|
||||||
'google_analytics_var5': ('test5', 'qux', SCOPE_PAGE),
|
'google_analytics_var4': ('test4', 'baz', SCOPE_SESSION),
|
||||||
})
|
'google_analytics_var5': ('test5', 'qux', SCOPE_PAGE),
|
||||||
|
}
|
||||||
|
)
|
||||||
r = GoogleAnalyticsNode().render(context)
|
r = GoogleAnalyticsNode().render(context)
|
||||||
assert "_gaq.push(['_setCustomVar', 1, 'test1', 'foo', 3]);" in r
|
assert "_gaq.push(['_setCustomVar', 1, 'test1', 'foo', 3]);" in r
|
||||||
assert "_gaq.push(['_setCustomVar', 2, 'test2', 'bar', 1]);" in r
|
assert "_gaq.push(['_setCustomVar', 2, 'test2', 'bar', 1]);" in r
|
||||||
|
|
@ -83,10 +91,10 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
||||||
def test_display_advertising(self):
|
def test_display_advertising(self):
|
||||||
with override_settings(GOOGLE_ANALYTICS_DISPLAY_ADVERTISING=False):
|
with override_settings(GOOGLE_ANALYTICS_DISPLAY_ADVERTISING=False):
|
||||||
r = GoogleAnalyticsNode().render(Context())
|
r = GoogleAnalyticsNode().render(Context())
|
||||||
assert "google-analytics.com/ga.js" in r
|
assert 'google-analytics.com/ga.js' in r
|
||||||
with override_settings(GOOGLE_ANALYTICS_DISPLAY_ADVERTISING=True):
|
with override_settings(GOOGLE_ANALYTICS_DISPLAY_ADVERTISING=True):
|
||||||
r = GoogleAnalyticsNode().render(Context())
|
r = GoogleAnalyticsNode().render(Context())
|
||||||
assert "stats.g.doubleclick.net/dc.js" in r
|
assert 'stats.g.doubleclick.net/dc.js' in 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):
|
def test_render_internal_ip(self):
|
||||||
|
|
@ -185,10 +193,12 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
||||||
GoogleAnalyticsNode().render(context)
|
GoogleAnalyticsNode().render(context)
|
||||||
|
|
||||||
|
|
||||||
@override_settings(GOOGLE_ANALYTICS_PROPERTY_ID='UA-123456-7',
|
@override_settings(
|
||||||
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_DOMAINS,
|
GOOGLE_ANALYTICS_PROPERTY_ID='UA-123456-7',
|
||||||
GOOGLE_ANALYTICS_DOMAIN=None,
|
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_DOMAINS,
|
||||||
ANALYTICAL_DOMAIN=None)
|
GOOGLE_ANALYTICS_DOMAIN=None,
|
||||||
|
ANALYTICAL_DOMAIN=None,
|
||||||
|
)
|
||||||
class NoDomainTestCase(TestCase):
|
class NoDomainTestCase(TestCase):
|
||||||
def test_exception_without_domain(self):
|
def test_exception_without_domain(self):
|
||||||
context = Context()
|
context = Context()
|
||||||
|
|
|
||||||
|
|
@ -64,21 +64,29 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
||||||
The user_id variable must be set according to
|
The user_id variable must be set according to
|
||||||
google_analytics_gtag_identity variable in the context.
|
google_analytics_gtag_identity variable in the context.
|
||||||
"""
|
"""
|
||||||
r = GoogleAnalyticsGTagNode().render(Context({
|
r = GoogleAnalyticsGTagNode().render(
|
||||||
'google_analytics_gtag_identity': 'foo_gtag_identity',
|
Context(
|
||||||
'analytical_identity': 'bar_analytical_identity',
|
{
|
||||||
'user': User(username='test'),
|
'google_analytics_gtag_identity': 'foo_gtag_identity',
|
||||||
}))
|
'analytical_identity': 'bar_analytical_identity',
|
||||||
|
'user': User(username='test'),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert "gtag('set', {'user_id': 'foo_gtag_identity'});" in r
|
assert "gtag('set', {'user_id': 'foo_gtag_identity'});" in r
|
||||||
|
|
||||||
def test_identity_context_general(self):
|
def test_identity_context_general(self):
|
||||||
"""
|
"""
|
||||||
The user_id variable must be set according to analytical_identity variable in the context.
|
The user_id variable must be set according to analytical_identity variable in the context.
|
||||||
"""
|
"""
|
||||||
r = GoogleAnalyticsGTagNode().render(Context({
|
r = GoogleAnalyticsGTagNode().render(
|
||||||
'analytical_identity': 'bar_analytical_identity',
|
Context(
|
||||||
'user': User(username='test'),
|
{
|
||||||
}))
|
'analytical_identity': 'bar_analytical_identity',
|
||||||
|
'user': User(username='test'),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert "gtag('set', {'user_id': 'bar_analytical_identity'});" in r
|
assert "gtag('set', {'user_id': 'bar_analytical_identity'});" in r
|
||||||
|
|
||||||
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID='G-12345678')
|
@override_settings(GOOGLE_ANALYTICS_GTAG_PROPERTY_ID='G-12345678')
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,10 @@ from analytical.templatetags.google_analytics_js import (
|
||||||
from analytical.utils import AnalyticalException
|
from analytical.utils import AnalyticalException
|
||||||
|
|
||||||
|
|
||||||
@override_settings(GOOGLE_ANALYTICS_JS_PROPERTY_ID='UA-123456-7',
|
@override_settings(
|
||||||
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_SINGLE_DOMAIN)
|
GOOGLE_ANALYTICS_JS_PROPERTY_ID='UA-123456-7',
|
||||||
|
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_SINGLE_DOMAIN,
|
||||||
|
)
|
||||||
class GoogleAnalyticsTagTestCase(TagTestCase):
|
class GoogleAnalyticsTagTestCase(TagTestCase):
|
||||||
"""
|
"""
|
||||||
Tests for the ``google_analytics_js`` template tag.
|
Tests for the ``google_analytics_js`` template tag.
|
||||||
|
|
@ -26,19 +28,25 @@ class GoogleAnalyticsTagTestCase(TagTestCase):
|
||||||
|
|
||||||
def test_tag(self):
|
def test_tag(self):
|
||||||
r = self.render_tag('google_analytics_js', 'google_analytics_js')
|
r = self.render_tag('google_analytics_js', 'google_analytics_js')
|
||||||
assert """(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
assert (
|
||||||
|
"""(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),
|
(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)
|
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
|
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');"""
|
||||||
|
in r
|
||||||
|
)
|
||||||
assert "ga('create', 'UA-123456-7', 'auto', {});" in r
|
assert "ga('create', 'UA-123456-7', 'auto', {});" in r
|
||||||
assert "ga('send', 'pageview');" in r
|
assert "ga('send', 'pageview');" in r
|
||||||
|
|
||||||
def test_node(self):
|
def test_node(self):
|
||||||
r = GoogleAnalyticsJsNode().render(Context())
|
r = GoogleAnalyticsJsNode().render(Context())
|
||||||
assert """(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
assert (
|
||||||
|
"""(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),
|
(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)
|
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
|
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');"""
|
||||||
|
in r
|
||||||
|
)
|
||||||
assert "ga('create', 'UA-123456-7', 'auto', {});" in r
|
assert "ga('create', 'UA-123456-7', 'auto', {});" in r
|
||||||
assert "ga('send', 'pageview');" in r
|
assert "ga('send', 'pageview');" in r
|
||||||
|
|
||||||
|
|
@ -52,27 +60,36 @@ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||||
with pytest.raises(AnalyticalException):
|
with pytest.raises(AnalyticalException):
|
||||||
GoogleAnalyticsJsNode()
|
GoogleAnalyticsJsNode()
|
||||||
|
|
||||||
@override_settings(GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_SUBDOMAINS,
|
@override_settings(
|
||||||
GOOGLE_ANALYTICS_DOMAIN='example.com')
|
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_SUBDOMAINS,
|
||||||
|
GOOGLE_ANALYTICS_DOMAIN='example.com',
|
||||||
|
)
|
||||||
def test_track_multiple_subdomains(self):
|
def test_track_multiple_subdomains(self):
|
||||||
r = GoogleAnalyticsJsNode().render(Context())
|
r = GoogleAnalyticsJsNode().render(Context())
|
||||||
assert """ga('create', 'UA-123456-7', 'auto', {"legacyCookieDomain": "example.com"}""" in r
|
assert (
|
||||||
|
"""ga('create', 'UA-123456-7', 'auto', {"legacyCookieDomain": "example.com"}"""
|
||||||
|
in r
|
||||||
|
)
|
||||||
|
|
||||||
@override_settings(GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_DOMAINS,
|
@override_settings(
|
||||||
GOOGLE_ANALYTICS_DOMAIN='example.com')
|
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_DOMAINS,
|
||||||
|
GOOGLE_ANALYTICS_DOMAIN='example.com',
|
||||||
|
)
|
||||||
def test_track_multiple_domains(self):
|
def test_track_multiple_domains(self):
|
||||||
r = GoogleAnalyticsJsNode().render(Context())
|
r = GoogleAnalyticsJsNode().render(Context())
|
||||||
assert "ga('create', 'UA-123456-7', 'auto', {" in r
|
assert "ga('create', 'UA-123456-7', 'auto', {" in r
|
||||||
assert '"legacyCookieDomain": "example.com"' in r
|
assert '"legacyCookieDomain": "example.com"' in r
|
||||||
assert '"allowLinker\": true' in r
|
assert '"allowLinker": true' in r
|
||||||
|
|
||||||
def test_custom_vars(self):
|
def test_custom_vars(self):
|
||||||
context = Context({
|
context = Context(
|
||||||
'google_analytics_var1': ('test1', 'foo'),
|
{
|
||||||
'google_analytics_var2': ('test2', 'bar'),
|
'google_analytics_var1': ('test1', 'foo'),
|
||||||
'google_analytics_var4': ('test4', 1),
|
'google_analytics_var2': ('test2', 'bar'),
|
||||||
'google_analytics_var5': ('test5', 2.2),
|
'google_analytics_var4': ('test4', 1),
|
||||||
})
|
'google_analytics_var5': ('test5', 2.2),
|
||||||
|
}
|
||||||
|
)
|
||||||
r = GoogleAnalyticsJsNode().render(context)
|
r = GoogleAnalyticsJsNode().render(context)
|
||||||
assert "ga('set', 'test1', 'foo');" in r
|
assert "ga('set', 'test1', 'foo');" in r
|
||||||
assert "ga('set', 'test2', 'bar');" in r
|
assert "ga('set', 'test2', 'bar');" in r
|
||||||
|
|
@ -82,9 +99,12 @@ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||||
def test_display_advertising(self):
|
def test_display_advertising(self):
|
||||||
with override_settings(GOOGLE_ANALYTICS_DISPLAY_ADVERTISING=True):
|
with override_settings(GOOGLE_ANALYTICS_DISPLAY_ADVERTISING=True):
|
||||||
r = GoogleAnalyticsJsNode().render(Context())
|
r = GoogleAnalyticsJsNode().render(Context())
|
||||||
assert """ga('create', 'UA-123456-7', 'auto', {});
|
assert (
|
||||||
|
"""ga('create', 'UA-123456-7', 'auto', {});
|
||||||
ga('require', 'displayfeatures');
|
ga('require', 'displayfeatures');
|
||||||
ga('send', 'pageview');""" in r
|
ga('send', 'pageview');"""
|
||||||
|
in 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):
|
def test_render_internal_ip(self):
|
||||||
|
|
@ -92,8 +112,7 @@ ga('send', 'pageview');""" in r
|
||||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||||
context = Context({'request': req})
|
context = Context({'request': req})
|
||||||
r = GoogleAnalyticsJsNode().render(context)
|
r = GoogleAnalyticsJsNode().render(context)
|
||||||
assert r.startswith(
|
assert r.startswith('<!-- Google Analytics disabled on internal IP address')
|
||||||
'<!-- Google Analytics disabled on internal IP address')
|
|
||||||
assert r.endswith('-->')
|
assert r.endswith('-->')
|
||||||
|
|
||||||
@override_settings(GOOGLE_ANALYTICS_ANONYMIZE_IP=True)
|
@override_settings(GOOGLE_ANALYTICS_ANONYMIZE_IP=True)
|
||||||
|
|
@ -131,12 +150,17 @@ ga('send', 'pageview');""" in r
|
||||||
@override_settings(GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE=0.0)
|
@override_settings(GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE=0.0)
|
||||||
def test_set_site_speed_sample_rate_min(self):
|
def test_set_site_speed_sample_rate_min(self):
|
||||||
r = GoogleAnalyticsJsNode().render(Context())
|
r = GoogleAnalyticsJsNode().render(Context())
|
||||||
assert """ga('create', 'UA-123456-7', 'auto', {"siteSpeedSampleRate": 0});""" in r
|
assert (
|
||||||
|
"""ga('create', 'UA-123456-7', 'auto', {"siteSpeedSampleRate": 0});""" in 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):
|
def test_set_site_speed_sample_rate_max(self):
|
||||||
r = GoogleAnalyticsJsNode().render(Context())
|
r = GoogleAnalyticsJsNode().render(Context())
|
||||||
assert """ga('create', 'UA-123456-7', 'auto', {"siteSpeedSampleRate": 100});""" in r
|
assert (
|
||||||
|
"""ga('create', 'UA-123456-7', 'auto', {"siteSpeedSampleRate": 100});"""
|
||||||
|
in r
|
||||||
|
)
|
||||||
|
|
||||||
@override_settings(GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE=-1)
|
@override_settings(GOOGLE_ANALYTICS_SITE_SPEED_SAMPLE_RATE=-1)
|
||||||
def test_exception_whenset_site_speed_sample_rate_too_small(self):
|
def test_exception_whenset_site_speed_sample_rate_too_small(self):
|
||||||
|
|
@ -167,10 +191,12 @@ ga('send', 'pageview');""" in r
|
||||||
GoogleAnalyticsJsNode().render(context)
|
GoogleAnalyticsJsNode().render(context)
|
||||||
|
|
||||||
|
|
||||||
@override_settings(GOOGLE_ANALYTICS_JS_PROPERTY_ID='UA-123456-7',
|
@override_settings(
|
||||||
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_DOMAINS,
|
GOOGLE_ANALYTICS_JS_PROPERTY_ID='UA-123456-7',
|
||||||
GOOGLE_ANALYTICS_DOMAIN=None,
|
GOOGLE_ANALYTICS_TRACKING_STYLE=TRACK_MULTIPLE_DOMAINS,
|
||||||
ANALYTICAL_DOMAIN=None)
|
GOOGLE_ANALYTICS_DOMAIN=None,
|
||||||
|
ANALYTICAL_DOMAIN=None,
|
||||||
|
)
|
||||||
class NoDomainTestCase(TestCase):
|
class NoDomainTestCase(TestCase):
|
||||||
def test_exception_without_domain(self):
|
def test_exception_without_domain(self):
|
||||||
context = Context()
|
context = Context()
|
||||||
|
|
|
||||||
|
|
@ -39,17 +39,25 @@ class GoSquaredTagTestCase(TagTestCase):
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||||
def test_auto_identify(self):
|
def test_auto_identify(self):
|
||||||
r = GoSquaredNode().render(Context({
|
r = GoSquaredNode().render(
|
||||||
'user': User(username='test', first_name='Test', last_name='User'),
|
Context(
|
||||||
}))
|
{
|
||||||
|
'user': User(username='test', first_name='Test', last_name='User'),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'GoSquared.UserName = "Test User";' in r
|
assert 'GoSquared.UserName = "Test User";' in r
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||||
def test_manual_identify(self):
|
def test_manual_identify(self):
|
||||||
r = GoSquaredNode().render(Context({
|
r = GoSquaredNode().render(
|
||||||
'user': User(username='test', first_name='Test', last_name='User'),
|
Context(
|
||||||
'gosquared_identity': 'test_identity',
|
{
|
||||||
}))
|
'user': User(username='test', first_name='Test', last_name='User'),
|
||||||
|
'gosquared_identity': 'test_identity',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'GoSquared.UserName = "test_identity";' in r
|
assert 'GoSquared.UserName = "test_identity";' in r
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,11 @@ class HeapTagTestCase(TagTestCase):
|
||||||
|
|
||||||
def test_tag(self):
|
def test_tag(self):
|
||||||
r = self.render_tag('heap', 'heap')
|
r = self.render_tag('heap', 'heap')
|
||||||
assert "123456789" in r
|
assert '123456789' in r
|
||||||
|
|
||||||
def test_node(self):
|
def test_node(self):
|
||||||
r = HeapNode().render(Context({}))
|
r = HeapNode().render(Context({}))
|
||||||
assert "123456789" in r
|
assert '123456789' in r
|
||||||
|
|
||||||
def test_tags_take_no_args(self):
|
def test_tags_take_no_args(self):
|
||||||
with pytest.raises(TemplateSyntaxError, match="'heap' takes no arguments"):
|
with pytest.raises(TemplateSyntaxError, match="'heap' takes no arguments"):
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Tests for the Hotjar template tags.
|
Tests for the Hotjar template tags.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
from django.template import Context, Template, TemplateSyntaxError
|
from django.template import Context, Template, TemplateSyntaxError
|
||||||
|
|
@ -27,7 +28,6 @@ expected_html = """\
|
||||||
|
|
||||||
@override_settings(HOTJAR_SITE_ID='123456789')
|
@override_settings(HOTJAR_SITE_ID='123456789')
|
||||||
class HotjarTagTestCase(TagTestCase):
|
class HotjarTagTestCase(TagTestCase):
|
||||||
|
|
||||||
maxDiff = None
|
maxDiff = None
|
||||||
|
|
||||||
def test_tag(self):
|
def test_tag(self):
|
||||||
|
|
@ -44,13 +44,14 @@ class HotjarTagTestCase(TagTestCase):
|
||||||
|
|
||||||
@override_settings(HOTJAR_SITE_ID=None)
|
@override_settings(HOTJAR_SITE_ID=None)
|
||||||
def test_no_id(self):
|
def test_no_id(self):
|
||||||
with pytest.raises(AnalyticalException, match="HOTJAR_SITE_ID setting is not set"):
|
with pytest.raises(
|
||||||
|
AnalyticalException, match='HOTJAR_SITE_ID setting is not set'
|
||||||
|
):
|
||||||
HotjarNode()
|
HotjarNode()
|
||||||
|
|
||||||
@override_settings(HOTJAR_SITE_ID='invalid')
|
@override_settings(HOTJAR_SITE_ID='invalid')
|
||||||
def test_invalid_id(self):
|
def test_invalid_id(self):
|
||||||
expected_pattern = (
|
expected_pattern = r"^HOTJAR_SITE_ID setting: must be \(a string containing\) a number: 'invalid'$"
|
||||||
r"^HOTJAR_SITE_ID setting: must be \(a string containing\) a number: 'invalid'$")
|
|
||||||
with pytest.raises(AnalyticalException, match=expected_pattern):
|
with pytest.raises(AnalyticalException, match=expected_pattern):
|
||||||
HotjarNode()
|
HotjarNode()
|
||||||
|
|
||||||
|
|
@ -61,11 +62,13 @@ class HotjarTagTestCase(TagTestCase):
|
||||||
context = Context({'request': request})
|
context = Context({'request': request})
|
||||||
|
|
||||||
actual_html = HotjarNode().render(context)
|
actual_html = HotjarNode().render(context)
|
||||||
disabled_html = '\n'.join([
|
disabled_html = '\n'.join(
|
||||||
|
[
|
||||||
'<!-- Hotjar disabled on internal IP address',
|
'<!-- Hotjar disabled on internal IP address',
|
||||||
expected_html,
|
expected_html,
|
||||||
'-->',
|
'-->',
|
||||||
])
|
]
|
||||||
|
)
|
||||||
assert disabled_html == actual_html
|
assert disabled_html == actual_html
|
||||||
|
|
||||||
def test_contribute_to_analytical(self):
|
def test_contribute_to_analytical(self):
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ from analytical.templatetags.intercom import IntercomNode, intercom_user_hash
|
||||||
from analytical.utils import AnalyticalException
|
from analytical.utils import AnalyticalException
|
||||||
|
|
||||||
|
|
||||||
@override_settings(INTERCOM_APP_ID="abc123xyz")
|
@override_settings(INTERCOM_APP_ID='abc123xyz')
|
||||||
class IntercomTagTestCase(TagTestCase):
|
class IntercomTagTestCase(TagTestCase):
|
||||||
"""
|
"""
|
||||||
Tests for the ``intercom`` template tag.
|
Tests for the ``intercom`` template tag.
|
||||||
|
|
@ -23,7 +23,9 @@ class IntercomTagTestCase(TagTestCase):
|
||||||
|
|
||||||
def test_tag(self):
|
def test_tag(self):
|
||||||
rendered_tag = self.render_tag('intercom', 'intercom')
|
rendered_tag = self.render_tag('intercom', 'intercom')
|
||||||
assert rendered_tag.strip().startswith('<script id="IntercomSettingsScriptTag">')
|
assert rendered_tag.strip().startswith(
|
||||||
|
'<script id="IntercomSettingsScriptTag">'
|
||||||
|
)
|
||||||
|
|
||||||
def test_node(self):
|
def test_node(self):
|
||||||
now = datetime.datetime(2014, 4, 9, 15, 15, 0)
|
now = datetime.datetime(2014, 4, 9, 15, 15, 0)
|
||||||
|
|
@ -31,17 +33,21 @@ class IntercomTagTestCase(TagTestCase):
|
||||||
username='test',
|
username='test',
|
||||||
first_name='Firstname',
|
first_name='Firstname',
|
||||||
last_name='Lastname',
|
last_name='Lastname',
|
||||||
email="test@example.com",
|
email='test@example.com',
|
||||||
date_joined=now,
|
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.
|
# Because the json isn't predictably ordered, we can't just test the whole thing verbatim.
|
||||||
assert rendered_tag == """
|
assert (
|
||||||
|
rendered_tag
|
||||||
|
== """
|
||||||
<script id="IntercomSettingsScriptTag">
|
<script id="IntercomSettingsScriptTag">
|
||||||
window.intercomSettings = {"app_id": "abc123xyz", "created_at": 1397074500, "email": "test@example.com", "name": "Firstname Lastname", "user_id": %(user_id)s};
|
window.intercomSettings = {"app_id": "abc123xyz", "created_at": 1397074500, "email": "test@example.com", "name": "Firstname Lastname", "user_id": %(user_id)s};
|
||||||
</script>
|
</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>
|
<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} # noqa
|
"""
|
||||||
|
% {'user_id': user.pk}
|
||||||
|
) # noqa
|
||||||
|
|
||||||
@override_settings(INTERCOM_APP_ID=None)
|
@override_settings(INTERCOM_APP_ID=None)
|
||||||
def test_no_account_number(self):
|
def test_no_account_number(self):
|
||||||
|
|
@ -59,32 +65,40 @@ class IntercomTagTestCase(TagTestCase):
|
||||||
username='test',
|
username='test',
|
||||||
first_name='Firstname',
|
first_name='Firstname',
|
||||||
last_name='Lastname',
|
last_name='Lastname',
|
||||||
email="test@example.com",
|
email='test@example.com',
|
||||||
date_joined=now,
|
date_joined=now,
|
||||||
)
|
)
|
||||||
r = IntercomNode().render(Context({
|
r = IntercomNode().render(
|
||||||
'user': user,
|
Context(
|
||||||
}))
|
{
|
||||||
|
'user': user,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert (
|
assert (
|
||||||
'window.intercomSettings = {"app_id": "abc123xyz", "created_at": 1397074500, '
|
'window.intercomSettings = {"app_id": "abc123xyz", "created_at": 1397074500, '
|
||||||
f'"email": "test@example.com", "name": "Firstname Lastname", "user_id": {user.pk}}};'
|
f'"email": "test@example.com", "name": "Firstname Lastname", "user_id": {user.pk}}};'
|
||||||
) in r
|
) in r
|
||||||
|
|
||||||
def test_custom(self):
|
def test_custom(self):
|
||||||
r = IntercomNode().render(Context({
|
r = IntercomNode().render(
|
||||||
'intercom_var1': 'val1',
|
Context({'intercom_var1': 'val1', 'intercom_var2': 'val2'})
|
||||||
'intercom_var2': 'val2'
|
)
|
||||||
}))
|
|
||||||
assert 'var1": "val1", "var2": "val2"' in r
|
assert 'var1": "val1", "var2": "val2"' in r
|
||||||
|
|
||||||
def test_identify_name_and_email(self):
|
def test_identify_name_and_email(self):
|
||||||
r = IntercomNode().render(Context({
|
r = IntercomNode().render(
|
||||||
'user': User(
|
Context(
|
||||||
username='test',
|
{
|
||||||
first_name='Firstname',
|
'user': User(
|
||||||
last_name='Lastname',
|
username='test',
|
||||||
email="test@example.com"),
|
first_name='Firstname',
|
||||||
}))
|
last_name='Lastname',
|
||||||
|
email='test@example.com',
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert '"email": "test@example.com", "name": "Firstname Lastname"' in r
|
assert '"email": "test@example.com", "name": "Firstname Lastname"' in r
|
||||||
|
|
||||||
def test_identify_username_no_email(self):
|
def test_identify_username_no_email(self):
|
||||||
|
|
@ -92,17 +106,25 @@ class IntercomTagTestCase(TagTestCase):
|
||||||
assert '"name": "test"' in r, r
|
assert '"name": "test"' in r, r
|
||||||
|
|
||||||
def test_no_identify_when_explicit_name(self):
|
def test_no_identify_when_explicit_name(self):
|
||||||
r = IntercomNode().render(Context({
|
r = IntercomNode().render(
|
||||||
'intercom_name': 'explicit',
|
Context(
|
||||||
'user': User(username='implicit'),
|
{
|
||||||
}))
|
'intercom_name': 'explicit',
|
||||||
|
'user': User(username='implicit'),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert '"name": "explicit"' in r, r
|
assert '"name": "explicit"' in r, r
|
||||||
|
|
||||||
def test_no_identify_when_explicit_email(self):
|
def test_no_identify_when_explicit_email(self):
|
||||||
r = IntercomNode().render(Context({
|
r = IntercomNode().render(
|
||||||
'intercom_email': 'explicit',
|
Context(
|
||||||
'user': User(username='implicit'),
|
{
|
||||||
}))
|
'intercom_email': 'explicit',
|
||||||
|
'user': User(username='implicit'),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert '"email": "explicit"' in r, r
|
assert '"email": "explicit"' in r, r
|
||||||
|
|
||||||
@override_settings(INTERCOM_HMAC_SECRET_KEY='secret')
|
@override_settings(INTERCOM_HMAC_SECRET_KEY='secret')
|
||||||
|
|
@ -135,10 +157,14 @@ class IntercomTagTestCase(TagTestCase):
|
||||||
"""
|
"""
|
||||||
'user_hash' of context-provided `user_id`.
|
'user_hash' of context-provided `user_id`.
|
||||||
"""
|
"""
|
||||||
attrs = IntercomNode()._get_custom_attrs(Context({
|
attrs = IntercomNode()._get_custom_attrs(
|
||||||
'intercom_email': 'test@example.com',
|
Context(
|
||||||
'intercom_user_id': '5',
|
{
|
||||||
}))
|
'intercom_email': 'test@example.com',
|
||||||
|
'intercom_user_id': '5',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert attrs == {
|
assert attrs == {
|
||||||
'created_at': None,
|
'created_at': None,
|
||||||
'email': 'test@example.com',
|
'email': 'test@example.com',
|
||||||
|
|
@ -152,9 +178,13 @@ class IntercomTagTestCase(TagTestCase):
|
||||||
"""
|
"""
|
||||||
'user_hash' of context-provided `email`.
|
'user_hash' of context-provided `email`.
|
||||||
"""
|
"""
|
||||||
attrs = IntercomNode()._get_custom_attrs(Context({
|
attrs = IntercomNode()._get_custom_attrs(
|
||||||
'intercom_email': 'test@example.com',
|
Context(
|
||||||
}))
|
{
|
||||||
|
'intercom_email': 'test@example.com',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert attrs == {
|
assert attrs == {
|
||||||
'created_at': None,
|
'created_at': None,
|
||||||
'email': 'test@example.com',
|
'email': 'test@example.com',
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,11 @@ class KissInsightsTagTestCase(TagTestCase):
|
||||||
|
|
||||||
def test_tag(self):
|
def test_tag(self):
|
||||||
r = self.render_tag('kiss_insights', 'kiss_insights')
|
r = self.render_tag('kiss_insights', 'kiss_insights')
|
||||||
assert "//s3.amazonaws.com/ki.js/12345/abc.js" in r
|
assert '//s3.amazonaws.com/ki.js/12345/abc.js' in r
|
||||||
|
|
||||||
def test_node(self):
|
def test_node(self):
|
||||||
r = KissInsightsNode().render(Context())
|
r = KissInsightsNode().render(Context())
|
||||||
assert "//s3.amazonaws.com/ki.js/12345/abc.js" in r
|
assert '//s3.amazonaws.com/ki.js/12345/abc.js' in r
|
||||||
|
|
||||||
@override_settings(KISS_INSIGHTS_ACCOUNT_NUMBER=None)
|
@override_settings(KISS_INSIGHTS_ACCOUNT_NUMBER=None)
|
||||||
def test_no_account_number(self):
|
def test_no_account_number(self):
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,17 @@ class KissMetricsTagTestCase(TagTestCase):
|
||||||
|
|
||||||
def test_tag(self):
|
def test_tag(self):
|
||||||
r = self.render_tag('kiss_metrics', 'kiss_metrics')
|
r = self.render_tag('kiss_metrics', 'kiss_metrics')
|
||||||
assert "//doug1izaerwt3.cloudfront.net/0123456789abcdef0123456789abcdef01234567.1.js" in r
|
assert (
|
||||||
|
'//doug1izaerwt3.cloudfront.net/0123456789abcdef0123456789abcdef01234567.1.js'
|
||||||
|
in r
|
||||||
|
)
|
||||||
|
|
||||||
def test_node(self):
|
def test_node(self):
|
||||||
r = KissMetricsNode().render(Context())
|
r = KissMetricsNode().render(Context())
|
||||||
assert "//doug1izaerwt3.cloudfront.net/0123456789abcdef0123456789abcdef01234567.1.js" in r
|
assert (
|
||||||
|
'//doug1izaerwt3.cloudfront.net/0123456789abcdef0123456789abcdef01234567.1.js'
|
||||||
|
in r
|
||||||
|
)
|
||||||
|
|
||||||
@override_settings(KISS_METRICS_API_KEY=None)
|
@override_settings(KISS_METRICS_API_KEY=None)
|
||||||
def test_no_api_key(self):
|
def test_no_api_key(self):
|
||||||
|
|
@ -53,22 +59,37 @@ class KissMetricsTagTestCase(TagTestCase):
|
||||||
assert "_kmq.push(['identify', " not in r
|
assert "_kmq.push(['identify', " not in r
|
||||||
|
|
||||||
def test_event(self):
|
def test_event(self):
|
||||||
r = KissMetricsNode().render(Context({
|
r = KissMetricsNode().render(
|
||||||
'kiss_metrics_event': ('test_event', {'prop1': 'val1', 'prop2': 'val2'}),
|
Context(
|
||||||
}))
|
{
|
||||||
|
'kiss_metrics_event': (
|
||||||
|
'test_event',
|
||||||
|
{'prop1': 'val1', 'prop2': 'val2'},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert "_kmq.push(['record', 'test_event', "
|
assert "_kmq.push(['record', 'test_event', "
|
||||||
'{"prop1": "val1", "prop2": "val2"}]);' in r
|
'{"prop1": "val1", "prop2": "val2"}]);' in r
|
||||||
|
|
||||||
def test_property(self):
|
def test_property(self):
|
||||||
r = KissMetricsNode().render(Context({
|
r = KissMetricsNode().render(
|
||||||
'kiss_metrics_properties': {'prop1': 'val1', 'prop2': 'val2'},
|
Context(
|
||||||
}))
|
{
|
||||||
|
'kiss_metrics_properties': {'prop1': 'val1', 'prop2': 'val2'},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert '_kmq.push([\'set\', {"prop1": "val1", "prop2": "val2"}]);' in r
|
assert '_kmq.push([\'set\', {"prop1": "val1", "prop2": "val2"}]);' in r
|
||||||
|
|
||||||
def test_alias(self):
|
def test_alias(self):
|
||||||
r = KissMetricsNode().render(Context({
|
r = KissMetricsNode().render(
|
||||||
'kiss_metrics_alias': {'test': 'test_alias'},
|
Context(
|
||||||
}))
|
{
|
||||||
|
'kiss_metrics_alias': {'test': 'test_alias'},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert "_kmq.push(['alias', 'test', 'test_alias']);" in r
|
assert "_kmq.push(['alias', 'test', 'test_alias']);" in r
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
@override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Tests for the Lucky Orange template tags.
|
Tests for the Lucky Orange template tags.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
from django.template import Context, Template, TemplateSyntaxError
|
from django.template import Context, Template, TemplateSyntaxError
|
||||||
|
|
@ -25,7 +26,6 @@ window.__lo_site_id = 123456;
|
||||||
|
|
||||||
@override_settings(LUCKYORANGE_SITE_ID='123456')
|
@override_settings(LUCKYORANGE_SITE_ID='123456')
|
||||||
class LuckyOrangeTagTestCase(TagTestCase):
|
class LuckyOrangeTagTestCase(TagTestCase):
|
||||||
|
|
||||||
maxDiff = None
|
maxDiff = None
|
||||||
|
|
||||||
def test_tag(self):
|
def test_tag(self):
|
||||||
|
|
@ -37,18 +37,23 @@ class LuckyOrangeTagTestCase(TagTestCase):
|
||||||
assert expected_html == html
|
assert expected_html == html
|
||||||
|
|
||||||
def test_tags_take_no_args(self):
|
def test_tags_take_no_args(self):
|
||||||
with pytest.raises(TemplateSyntaxError, match="'luckyorange' takes no arguments"):
|
with pytest.raises(
|
||||||
Template('{% load luckyorange %}{% luckyorange "arg" %}').render(Context({}))
|
TemplateSyntaxError, match="'luckyorange' takes no arguments"
|
||||||
|
):
|
||||||
|
Template('{% load luckyorange %}{% luckyorange "arg" %}').render(
|
||||||
|
Context({})
|
||||||
|
)
|
||||||
|
|
||||||
@override_settings(LUCKYORANGE_SITE_ID=None)
|
@override_settings(LUCKYORANGE_SITE_ID=None)
|
||||||
def test_no_id(self):
|
def test_no_id(self):
|
||||||
with pytest.raises(AnalyticalException, match="LUCKYORANGE_SITE_ID setting is not set"):
|
with pytest.raises(
|
||||||
|
AnalyticalException, match='LUCKYORANGE_SITE_ID setting is not set'
|
||||||
|
):
|
||||||
LuckyOrangeNode()
|
LuckyOrangeNode()
|
||||||
|
|
||||||
@override_settings(LUCKYORANGE_SITE_ID='invalid')
|
@override_settings(LUCKYORANGE_SITE_ID='invalid')
|
||||||
def test_invalid_id(self):
|
def test_invalid_id(self):
|
||||||
expected_pattern = (
|
expected_pattern = r"^LUCKYORANGE_SITE_ID setting: must be \(a string containing\) a number: 'invalid'$"
|
||||||
r"^LUCKYORANGE_SITE_ID setting: must be \(a string containing\) a number: 'invalid'$")
|
|
||||||
with pytest.raises(AnalyticalException, match=expected_pattern):
|
with pytest.raises(AnalyticalException, match=expected_pattern):
|
||||||
LuckyOrangeNode()
|
LuckyOrangeNode()
|
||||||
|
|
||||||
|
|
@ -59,11 +64,13 @@ class LuckyOrangeTagTestCase(TagTestCase):
|
||||||
context = Context({'request': request})
|
context = Context({'request': request})
|
||||||
|
|
||||||
actual_html = LuckyOrangeNode().render(context)
|
actual_html = LuckyOrangeNode().render(context)
|
||||||
disabled_html = '\n'.join([
|
disabled_html = '\n'.join(
|
||||||
|
[
|
||||||
'<!-- Lucky Orange disabled on internal IP address',
|
'<!-- Lucky Orange disabled on internal IP address',
|
||||||
expected_html,
|
expected_html,
|
||||||
'-->',
|
'-->',
|
||||||
])
|
]
|
||||||
|
)
|
||||||
assert disabled_html == actual_html
|
assert disabled_html == actual_html
|
||||||
|
|
||||||
def test_contribute_to_analytical(self):
|
def test_contribute_to_analytical(self):
|
||||||
|
|
|
||||||
|
|
@ -31,20 +31,19 @@ class MatomoTagTestCase(TagTestCase):
|
||||||
assert "_paq.push(['setSiteId', 345]);" in r
|
assert "_paq.push(['setSiteId', 345]);" in r
|
||||||
assert 'img src="//example.com/matomo.php?idsite=345"' in r
|
assert 'img src="//example.com/matomo.php?idsite=345"' in r
|
||||||
|
|
||||||
@override_settings(MATOMO_DOMAIN_PATH='example.com/matomo',
|
@override_settings(MATOMO_DOMAIN_PATH='example.com/matomo', MATOMO_SITE_ID='345')
|
||||||
MATOMO_SITE_ID='345')
|
|
||||||
def test_domain_path_valid(self):
|
def test_domain_path_valid(self):
|
||||||
r = self.render_tag('matomo', 'matomo')
|
r = self.render_tag('matomo', 'matomo')
|
||||||
assert '"//example.com/matomo/"' in r
|
assert '"//example.com/matomo/"' in r
|
||||||
|
|
||||||
@override_settings(MATOMO_DOMAIN_PATH='example.com:1234',
|
@override_settings(MATOMO_DOMAIN_PATH='example.com:1234', MATOMO_SITE_ID='345')
|
||||||
MATOMO_SITE_ID='345')
|
|
||||||
def test_domain_port_valid(self):
|
def test_domain_port_valid(self):
|
||||||
r = self.render_tag('matomo', 'matomo')
|
r = self.render_tag('matomo', 'matomo')
|
||||||
assert '"//example.com:1234/";' in r
|
assert '"//example.com:1234/";' in r
|
||||||
|
|
||||||
@override_settings(MATOMO_DOMAIN_PATH='example.com:1234/matomo',
|
@override_settings(
|
||||||
MATOMO_SITE_ID='345')
|
MATOMO_DOMAIN_PATH='example.com:1234/matomo', MATOMO_SITE_ID='345'
|
||||||
|
)
|
||||||
def test_domain_port_path_valid(self):
|
def test_domain_port_path_valid(self):
|
||||||
r = self.render_tag('matomo', 'matomo')
|
r = self.render_tag('matomo', 'matomo')
|
||||||
assert '"//example.com:1234/matomo/"' in r
|
assert '"//example.com:1234/matomo/"' in r
|
||||||
|
|
@ -104,46 +103,54 @@ class MatomoTagTestCase(TagTestCase):
|
||||||
assert r.endswith('-->')
|
assert r.endswith('-->')
|
||||||
|
|
||||||
def test_uservars(self):
|
def test_uservars(self):
|
||||||
context = Context({'matomo_vars': [(1, 'foo', 'foo_val'),
|
context = Context(
|
||||||
(2, 'bar', 'bar_val', 'page'),
|
{
|
||||||
(3, 'spam', 'spam_val', 'visit')]})
|
'matomo_vars': [
|
||||||
|
(1, 'foo', 'foo_val'),
|
||||||
|
(2, 'bar', 'bar_val', 'page'),
|
||||||
|
(3, 'spam', 'spam_val', 'visit'),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)
|
||||||
r = MatomoNode().render(context)
|
r = MatomoNode().render(context)
|
||||||
for var_code in ['_paq.push(["setCustomVariable", 1, "foo", "foo_val", "page"]);',
|
for var_code in [
|
||||||
'_paq.push(["setCustomVariable", 2, "bar", "bar_val", "page"]);',
|
'_paq.push(["setCustomVariable", 1, "foo", "foo_val", "page"]);',
|
||||||
'_paq.push(["setCustomVariable", 3, "spam", "spam_val", "visit"]);']:
|
'_paq.push(["setCustomVariable", 2, "bar", "bar_val", "page"]);',
|
||||||
|
'_paq.push(["setCustomVariable", 3, "spam", "spam_val", "visit"]);',
|
||||||
|
]:
|
||||||
assert var_code in r
|
assert var_code in r
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||||
def test_default_usertrack(self):
|
def test_default_usertrack(self):
|
||||||
context = Context({
|
context = Context(
|
||||||
'user': User(username='BDFL', first_name='Guido', last_name='van Rossum')
|
{'user': User(username='BDFL', first_name='Guido', last_name='van Rossum')}
|
||||||
})
|
)
|
||||||
r = MatomoNode().render(context)
|
r = MatomoNode().render(context)
|
||||||
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
||||||
assert var_code in r
|
assert var_code in r
|
||||||
|
|
||||||
def test_matomo_usertrack(self):
|
def test_matomo_usertrack(self):
|
||||||
context = Context({
|
context = Context({'matomo_identity': 'BDFL'})
|
||||||
'matomo_identity': 'BDFL'
|
|
||||||
})
|
|
||||||
r = MatomoNode().render(context)
|
r = MatomoNode().render(context)
|
||||||
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
||||||
assert var_code in r
|
assert var_code in r
|
||||||
|
|
||||||
def test_analytical_usertrack(self):
|
def test_analytical_usertrack(self):
|
||||||
context = Context({
|
context = Context({'analytical_identity': 'BDFL'})
|
||||||
'analytical_identity': 'BDFL'
|
|
||||||
})
|
|
||||||
r = MatomoNode().render(context)
|
r = MatomoNode().render(context)
|
||||||
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
||||||
assert var_code in r
|
assert var_code in r
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||||
def test_disable_usertrack(self):
|
def test_disable_usertrack(self):
|
||||||
context = Context({
|
context = Context(
|
||||||
'user': User(username='BDFL', first_name='Guido', last_name='van Rossum'),
|
{
|
||||||
'matomo_identity': None
|
'user': User(
|
||||||
})
|
username='BDFL', first_name='Guido', last_name='van Rossum'
|
||||||
|
),
|
||||||
|
'matomo_identity': None,
|
||||||
|
}
|
||||||
|
)
|
||||||
r = MatomoNode().render(context)
|
r = MatomoNode().render(context)
|
||||||
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
var_code = '_paq.push(["setUserId", "BDFL"]);'
|
||||||
assert var_code not in r
|
assert var_code not in r
|
||||||
|
|
|
||||||
|
|
@ -50,12 +50,19 @@ class MixpanelTagTestCase(TagTestCase):
|
||||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||||
def test_identify_anonymous_user(self):
|
def test_identify_anonymous_user(self):
|
||||||
r = MixpanelNode().render(Context({'user': AnonymousUser()}))
|
r = MixpanelNode().render(Context({'user': AnonymousUser()}))
|
||||||
assert "mixpanel.register_once({distinct_id:" not in r
|
assert 'mixpanel.register_once({distinct_id:' not in r
|
||||||
|
|
||||||
def test_event(self):
|
def test_event(self):
|
||||||
r = MixpanelNode().render(Context({
|
r = MixpanelNode().render(
|
||||||
'mixpanel_event': ('test_event', {'prop1': 'val1', 'prop2': 'val2'}),
|
Context(
|
||||||
}))
|
{
|
||||||
|
'mixpanel_event': (
|
||||||
|
'test_event',
|
||||||
|
{'prop1': 'val1', 'prop2': 'val2'},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert "mixpanel.track('test_event', "
|
assert "mixpanel.track('test_event', "
|
||||||
'{"prop1": "val1", "prop2": "val2"});' in r
|
'{"prop1": "val1", "prop2": "val2"});' in r
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,17 @@ class OlarkTestCase(TagTestCase):
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||||
def test_identify(self):
|
def test_identify(self):
|
||||||
r = OlarkNode().render(Context({
|
r = OlarkNode().render(
|
||||||
'user': User(username='test', first_name='Test', last_name='User'),
|
Context(
|
||||||
}))
|
{
|
||||||
assert "olark('api.chat.updateVisitorNickname', {snippet: 'Test User (test)'});" in r
|
'user': User(username='test', first_name='Test', last_name='User'),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
"olark('api.chat.updateVisitorNickname', {snippet: 'Test User (test)'});"
|
||||||
|
in r
|
||||||
|
)
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||||
def test_identify_anonymous_user(self):
|
def test_identify_anonymous_user(self):
|
||||||
|
|
@ -58,37 +65,41 @@ class OlarkTestCase(TagTestCase):
|
||||||
'{snippet: "teststatus"});' in r
|
'{snippet: "teststatus"});' in r
|
||||||
|
|
||||||
def test_status_string_list(self):
|
def test_status_string_list(self):
|
||||||
r = OlarkNode().render(Context({
|
r = OlarkNode().render(
|
||||||
'olark_status': ['teststatus1', 'teststatus2'],
|
Context(
|
||||||
}))
|
{
|
||||||
|
'olark_status': ['teststatus1', 'teststatus2'],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert "olark('api.chat.updateVisitorStatus', "
|
assert "olark('api.chat.updateVisitorStatus', "
|
||||||
'{snippet: ["teststatus1", "teststatus2"]});' in r
|
'{snippet: ["teststatus1", "teststatus2"]});' in r
|
||||||
|
|
||||||
def test_messages(self):
|
def test_messages(self):
|
||||||
messages = [
|
messages = [
|
||||||
"welcome_title",
|
'welcome_title',
|
||||||
"chatting_title",
|
'chatting_title',
|
||||||
"unavailable_title",
|
'unavailable_title',
|
||||||
"busy_title",
|
'busy_title',
|
||||||
"away_message",
|
'away_message',
|
||||||
"loading_title",
|
'loading_title',
|
||||||
"welcome_message",
|
'welcome_message',
|
||||||
"busy_message",
|
'busy_message',
|
||||||
"chat_input_text",
|
'chat_input_text',
|
||||||
"name_input_text",
|
'name_input_text',
|
||||||
"email_input_text",
|
'email_input_text',
|
||||||
"offline_note_message",
|
'offline_note_message',
|
||||||
"send_button_text",
|
'send_button_text',
|
||||||
"offline_note_thankyou_text",
|
'offline_note_thankyou_text',
|
||||||
"offline_note_error_text",
|
'offline_note_error_text',
|
||||||
"offline_note_sending_text",
|
'offline_note_sending_text',
|
||||||
"operator_is_typing_text",
|
'operator_is_typing_text',
|
||||||
"operator_has_stopped_typing_text",
|
'operator_has_stopped_typing_text',
|
||||||
"introduction_error_text",
|
'introduction_error_text',
|
||||||
"introduction_messages",
|
'introduction_messages',
|
||||||
"introduction_submit_button_text",
|
'introduction_submit_button_text',
|
||||||
]
|
]
|
||||||
vars = {f'olark_{m}': m for m in messages}
|
vars = {f'olark_{m}': m for m in messages}
|
||||||
r = OlarkNode().render(Context(vars))
|
r = OlarkNode().render(Context(vars))
|
||||||
for m in messages:
|
for m in messages:
|
||||||
assert f"olark.configure('locale.{m}', \"{m}\");" in r
|
assert f'olark.configure(\'locale.{m}\', "{m}");' in r
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,11 @@ class RatingMailruTagTestCase(TagTestCase):
|
||||||
|
|
||||||
def test_tag(self):
|
def test_tag(self):
|
||||||
r = self.render_tag('rating_mailru', 'rating_mailru')
|
r = self.render_tag('rating_mailru', 'rating_mailru')
|
||||||
assert "counter?id=1234567;js=na" in r
|
assert 'counter?id=1234567;js=na' in r
|
||||||
|
|
||||||
def test_node(self):
|
def test_node(self):
|
||||||
r = RatingMailruNode().render(Context({}))
|
r = RatingMailruNode().render(Context({}))
|
||||||
assert "counter?id=1234567;js=na" in r
|
assert 'counter?id=1234567;js=na' in r
|
||||||
|
|
||||||
@override_settings(RATING_MAILRU_COUNTER_ID=None)
|
@override_settings(RATING_MAILRU_COUNTER_ID=None)
|
||||||
def test_no_site_id(self):
|
def test_no_site_id(self):
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ WIDGET_ID = 'ec329c69-0bf0-4db8-9b77-3f8150fb977e'
|
||||||
SNAPENGAGE_WIDGET_ID=WIDGET_ID,
|
SNAPENGAGE_WIDGET_ID=WIDGET_ID,
|
||||||
SNAPENGAGE_BUTTON=BUTTON_STYLE_DEFAULT,
|
SNAPENGAGE_BUTTON=BUTTON_STYLE_DEFAULT,
|
||||||
SNAPENGAGE_BUTTON_LOCATION=BUTTON_LOCATION_LEFT,
|
SNAPENGAGE_BUTTON_LOCATION=BUTTON_LOCATION_LEFT,
|
||||||
SNAPENGAGE_BUTTON_OFFSET="55%",
|
SNAPENGAGE_BUTTON_OFFSET='55%',
|
||||||
)
|
)
|
||||||
class SnapEngageTestCase(TagTestCase):
|
class SnapEngageTestCase(TagTestCase):
|
||||||
"""
|
"""
|
||||||
|
|
@ -38,11 +38,15 @@ class SnapEngageTestCase(TagTestCase):
|
||||||
|
|
||||||
def test_tag(self):
|
def test_tag(self):
|
||||||
r = self.render_tag('snapengage', 'snapengage')
|
r = self.render_tag('snapengage', 'snapengage')
|
||||||
assert 'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0","55%");' in r
|
assert (
|
||||||
|
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0","55%");' in r
|
||||||
|
)
|
||||||
|
|
||||||
def test_node(self):
|
def test_node(self):
|
||||||
r = SnapEngageNode().render(Context())
|
r = SnapEngageNode().render(Context())
|
||||||
assert 'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0","55%");' in r
|
assert (
|
||||||
|
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0","55%");' in r
|
||||||
|
)
|
||||||
|
|
||||||
@override_settings(SNAPENGAGE_WIDGET_ID=None)
|
@override_settings(SNAPENGAGE_WIDGET_ID=None)
|
||||||
def test_no_site_id(self):
|
def test_no_site_id(self):
|
||||||
|
|
@ -55,142 +59,220 @@ class SnapEngageTestCase(TagTestCase):
|
||||||
SnapEngageNode()
|
SnapEngageNode()
|
||||||
|
|
||||||
def test_no_button(self):
|
def test_no_button(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'snapengage_button': BUTTON_STYLE_NONE,
|
Context(
|
||||||
}))
|
{
|
||||||
|
'snapengage_button': BUTTON_STYLE_NONE,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'SnapABug.init("ec329c69-0bf0-4db8-9b77-3f8150fb977e")' in r
|
assert 'SnapABug.init("ec329c69-0bf0-4db8-9b77-3f8150fb977e")' in r
|
||||||
with override_settings(SNAPENGAGE_BUTTON=BUTTON_STYLE_NONE):
|
with override_settings(SNAPENGAGE_BUTTON=BUTTON_STYLE_NONE):
|
||||||
r = SnapEngageNode().render(Context())
|
r = SnapEngageNode().render(Context())
|
||||||
assert 'SnapABug.init("ec329c69-0bf0-4db8-9b77-3f8150fb977e")' in r
|
assert 'SnapABug.init("ec329c69-0bf0-4db8-9b77-3f8150fb977e")' in r
|
||||||
|
|
||||||
def test_live_button(self):
|
def test_live_button(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'snapengage_button': BUTTON_STYLE_LIVE,
|
Context(
|
||||||
}))
|
{
|
||||||
assert 'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0","55%",true);' in r
|
'snapengage_button': BUTTON_STYLE_LIVE,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0","55%",true);'
|
||||||
|
in r
|
||||||
|
)
|
||||||
with override_settings(SNAPENGAGE_BUTTON=BUTTON_STYLE_LIVE):
|
with override_settings(SNAPENGAGE_BUTTON=BUTTON_STYLE_LIVE):
|
||||||
r = SnapEngageNode().render(Context())
|
r = SnapEngageNode().render(Context())
|
||||||
assert 'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0","55%",true);' in r
|
assert (
|
||||||
|
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0","55%",true);'
|
||||||
|
in r
|
||||||
|
)
|
||||||
|
|
||||||
def test_custom_button(self):
|
def test_custom_button(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'snapengage_button': "http://www.example.com/button.png",
|
Context(
|
||||||
}))
|
{
|
||||||
assert 'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0","55%");' in r
|
'snapengage_button': 'http://www.example.com/button.png',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0","55%");' in r
|
||||||
|
)
|
||||||
assert 'SnapABug.setButton("http://www.example.com/button.png");' in r
|
assert 'SnapABug.setButton("http://www.example.com/button.png");' in r
|
||||||
with override_settings(
|
with override_settings(SNAPENGAGE_BUTTON='http://www.example.com/button.png'):
|
||||||
SNAPENGAGE_BUTTON="http://www.example.com/button.png"):
|
|
||||||
r = SnapEngageNode().render(Context())
|
r = SnapEngageNode().render(Context())
|
||||||
assert 'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0","55%");' in r
|
assert (
|
||||||
|
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0","55%");'
|
||||||
|
in r
|
||||||
|
)
|
||||||
assert 'SnapABug.setButton("http://www.example.com/button.png");' in r
|
assert 'SnapABug.setButton("http://www.example.com/button.png");' in r
|
||||||
|
|
||||||
def test_button_location_right(self):
|
def test_button_location_right(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'snapengage_button_location': BUTTON_LOCATION_RIGHT,
|
Context(
|
||||||
}))
|
{
|
||||||
assert 'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","1","55%");' in r
|
'snapengage_button_location': BUTTON_LOCATION_RIGHT,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","1","55%");' in r
|
||||||
|
)
|
||||||
with override_settings(SNAPENGAGE_BUTTON_LOCATION=BUTTON_LOCATION_RIGHT):
|
with override_settings(SNAPENGAGE_BUTTON_LOCATION=BUTTON_LOCATION_RIGHT):
|
||||||
r = SnapEngageNode().render(Context())
|
r = SnapEngageNode().render(Context())
|
||||||
assert 'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","1","55%");' in r
|
assert (
|
||||||
|
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","1","55%");'
|
||||||
|
in r
|
||||||
|
)
|
||||||
|
|
||||||
def test_button_location_top(self):
|
def test_button_location_top(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'snapengage_button_location': BUTTON_LOCATION_TOP,
|
Context(
|
||||||
}))
|
{
|
||||||
assert 'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","2","55%");' in r
|
'snapengage_button_location': BUTTON_LOCATION_TOP,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","2","55%");' in r
|
||||||
|
)
|
||||||
with override_settings(SNAPENGAGE_BUTTON_LOCATION=BUTTON_LOCATION_TOP):
|
with override_settings(SNAPENGAGE_BUTTON_LOCATION=BUTTON_LOCATION_TOP):
|
||||||
r = SnapEngageNode().render(Context())
|
r = SnapEngageNode().render(Context())
|
||||||
assert 'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","2","55%");' in r
|
assert (
|
||||||
|
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","2","55%");'
|
||||||
|
in r
|
||||||
|
)
|
||||||
|
|
||||||
def test_button_location_bottom(self):
|
def test_button_location_bottom(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'snapengage_button_location': BUTTON_LOCATION_BOTTOM,
|
Context(
|
||||||
}))
|
{
|
||||||
assert 'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","3","55%");' in r
|
'snapengage_button_location': BUTTON_LOCATION_BOTTOM,
|
||||||
with override_settings(
|
}
|
||||||
SNAPENGAGE_BUTTON_LOCATION=BUTTON_LOCATION_BOTTOM):
|
)
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","3","55%");' in r
|
||||||
|
)
|
||||||
|
with override_settings(SNAPENGAGE_BUTTON_LOCATION=BUTTON_LOCATION_BOTTOM):
|
||||||
r = SnapEngageNode().render(Context())
|
r = SnapEngageNode().render(Context())
|
||||||
assert 'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","3","55%");' in r
|
assert (
|
||||||
|
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","3","55%");'
|
||||||
|
in r
|
||||||
|
)
|
||||||
|
|
||||||
def test_button_offset(self):
|
def test_button_offset(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'snapengage_button_location_offset': "30%",
|
Context(
|
||||||
}))
|
{
|
||||||
assert 'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0","30%");' in r
|
'snapengage_button_location_offset': '30%',
|
||||||
with override_settings(SNAPENGAGE_BUTTON_LOCATION_OFFSET="30%"):
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0","30%");' in r
|
||||||
|
)
|
||||||
|
with override_settings(SNAPENGAGE_BUTTON_LOCATION_OFFSET='30%'):
|
||||||
r = SnapEngageNode().render(Context())
|
r = SnapEngageNode().render(Context())
|
||||||
assert 'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0","30%");' in r
|
assert (
|
||||||
|
'SnapABug.addButton("ec329c69-0bf0-4db8-9b77-3f8150fb977e","0","30%");'
|
||||||
|
in r
|
||||||
|
)
|
||||||
|
|
||||||
def test_button_effect(self):
|
def test_button_effect(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'snapengage_button_effect': "-4px",
|
Context(
|
||||||
}))
|
{
|
||||||
|
'snapengage_button_effect': '-4px',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'SnapABug.setButtonEffect("-4px");' in r
|
assert 'SnapABug.setButtonEffect("-4px");' in r
|
||||||
with override_settings(SNAPENGAGE_BUTTON_EFFECT="-4px"):
|
with override_settings(SNAPENGAGE_BUTTON_EFFECT='-4px'):
|
||||||
r = SnapEngageNode().render(Context())
|
r = SnapEngageNode().render(Context())
|
||||||
assert 'SnapABug.setButtonEffect("-4px");' in r
|
assert 'SnapABug.setButtonEffect("-4px");' in r
|
||||||
|
|
||||||
def test_form_position(self):
|
def test_form_position(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'snapengage_form_position': FORM_POSITION_TOP_LEFT,
|
Context(
|
||||||
}))
|
{
|
||||||
|
'snapengage_form_position': FORM_POSITION_TOP_LEFT,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'SnapABug.setChatFormPosition("tl");' in r
|
assert 'SnapABug.setChatFormPosition("tl");' in r
|
||||||
with override_settings(SNAPENGAGE_FORM_POSITION=FORM_POSITION_TOP_LEFT):
|
with override_settings(SNAPENGAGE_FORM_POSITION=FORM_POSITION_TOP_LEFT):
|
||||||
r = SnapEngageNode().render(Context())
|
r = SnapEngageNode().render(Context())
|
||||||
assert 'SnapABug.setChatFormPosition("tl");' in r
|
assert 'SnapABug.setChatFormPosition("tl");' in r
|
||||||
|
|
||||||
def test_form_top_position(self):
|
def test_form_top_position(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'snapengage_form_top_position': 40,
|
Context(
|
||||||
}))
|
{
|
||||||
|
'snapengage_form_top_position': 40,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'SnapABug.setFormTopPosition(40);' in r
|
assert 'SnapABug.setFormTopPosition(40);' in r
|
||||||
with override_settings(SNAPENGAGE_FORM_TOP_POSITION=40):
|
with override_settings(SNAPENGAGE_FORM_TOP_POSITION=40):
|
||||||
r = SnapEngageNode().render(Context())
|
r = SnapEngageNode().render(Context())
|
||||||
assert 'SnapABug.setFormTopPosition(40);' in r
|
assert 'SnapABug.setFormTopPosition(40);' in r
|
||||||
|
|
||||||
def test_domain(self):
|
def test_domain(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(Context({'snapengage_domain': 'example.com'}))
|
||||||
'snapengage_domain': "example.com"}))
|
|
||||||
assert 'SnapABug.setDomain("example.com");' in r
|
assert 'SnapABug.setDomain("example.com");' in r
|
||||||
with override_settings(SNAPENGAGE_DOMAIN="example.com"):
|
with override_settings(SNAPENGAGE_DOMAIN='example.com'):
|
||||||
r = SnapEngageNode().render(Context())
|
r = SnapEngageNode().render(Context())
|
||||||
assert 'SnapABug.setDomain("example.com");' in r
|
assert 'SnapABug.setDomain("example.com");' in r
|
||||||
|
|
||||||
def test_secure_connection(self):
|
def test_secure_connection(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(Context({'snapengage_secure_connection': True}))
|
||||||
'snapengage_secure_connection': True}))
|
|
||||||
assert 'SnapABug.setSecureConnexion();' in r
|
assert 'SnapABug.setSecureConnexion();' in r
|
||||||
with override_settings(SNAPENGAGE_SECURE_CONNECTION=True):
|
with override_settings(SNAPENGAGE_SECURE_CONNECTION=True):
|
||||||
r = SnapEngageNode().render(Context())
|
r = SnapEngageNode().render(Context())
|
||||||
assert 'SnapABug.setSecureConnexion();' in r
|
assert 'SnapABug.setSecureConnexion();' in r
|
||||||
|
|
||||||
def test_show_offline(self):
|
def test_show_offline(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'snapengage_show_offline': False,
|
Context(
|
||||||
}))
|
{
|
||||||
|
'snapengage_show_offline': False,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'SnapABug.allowOffline(false);' in r
|
assert 'SnapABug.allowOffline(false);' in r
|
||||||
with override_settings(SNAPENGAGE_SHOW_OFFLINE=False):
|
with override_settings(SNAPENGAGE_SHOW_OFFLINE=False):
|
||||||
r = SnapEngageNode().render(Context())
|
r = SnapEngageNode().render(Context())
|
||||||
assert 'SnapABug.allowOffline(false);' in r
|
assert 'SnapABug.allowOffline(false);' in r
|
||||||
|
|
||||||
def test_proactive_chat(self):
|
def test_proactive_chat(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(Context({'snapengage_proactive_chat': False}))
|
||||||
'snapengage_proactive_chat': False}))
|
|
||||||
assert 'SnapABug.allowProactiveChat(false);' in r
|
assert 'SnapABug.allowProactiveChat(false);' in r
|
||||||
|
|
||||||
def test_screenshot(self):
|
def test_screenshot(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'snapengage_screenshots': False,
|
Context(
|
||||||
}))
|
{
|
||||||
|
'snapengage_screenshots': False,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'SnapABug.allowScreenshot(false);' in r
|
assert 'SnapABug.allowScreenshot(false);' in r
|
||||||
with override_settings(SNAPENGAGE_SCREENSHOTS=False):
|
with override_settings(SNAPENGAGE_SCREENSHOTS=False):
|
||||||
r = SnapEngageNode().render(Context())
|
r = SnapEngageNode().render(Context())
|
||||||
assert 'SnapABug.allowScreenshot(false);' in r
|
assert 'SnapABug.allowScreenshot(false);' in r
|
||||||
|
|
||||||
def test_offline_screenshots(self):
|
def test_offline_screenshots(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'snapengage_offline_screenshots': False,
|
Context(
|
||||||
}))
|
{
|
||||||
|
'snapengage_offline_screenshots': False,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'SnapABug.showScreenshotOption(false);' in r
|
assert 'SnapABug.showScreenshotOption(false);' in r
|
||||||
with override_settings(SNAPENGAGE_OFFLINE_SCREENSHOTS=False):
|
with override_settings(SNAPENGAGE_OFFLINE_SCREENSHOTS=False):
|
||||||
r = SnapEngageNode().render(Context())
|
r = SnapEngageNode().render(Context())
|
||||||
|
|
@ -205,35 +287,55 @@ class SnapEngageTestCase(TagTestCase):
|
||||||
|
|
||||||
@override_settings(SNAPENGAGE_READONLY_EMAIL=False)
|
@override_settings(SNAPENGAGE_READONLY_EMAIL=False)
|
||||||
def test_email(self):
|
def test_email(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'snapengage_email': 'test@example.com',
|
Context(
|
||||||
}))
|
{
|
||||||
|
'snapengage_email': 'test@example.com',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'SnapABug.setUserEmail("test@example.com");' in r
|
assert 'SnapABug.setUserEmail("test@example.com");' in r
|
||||||
|
|
||||||
def test_email_readonly(self):
|
def test_email_readonly(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'snapengage_email': 'test@example.com',
|
Context(
|
||||||
'snapengage_readonly_email': True,
|
{
|
||||||
}))
|
'snapengage_email': 'test@example.com',
|
||||||
|
'snapengage_readonly_email': True,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'SnapABug.setUserEmail("test@example.com",true);' in r
|
assert 'SnapABug.setUserEmail("test@example.com",true);' in r
|
||||||
with override_settings(SNAPENGAGE_READONLY_EMAIL=True):
|
with override_settings(SNAPENGAGE_READONLY_EMAIL=True):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'snapengage_email': 'test@example.com',
|
Context(
|
||||||
}))
|
{
|
||||||
|
'snapengage_email': 'test@example.com',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'SnapABug.setUserEmail("test@example.com",true);' in r
|
assert 'SnapABug.setUserEmail("test@example.com",true);' in r
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||||
def test_identify(self):
|
def test_identify(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'user': User(username='test', email='test@example.com'),
|
Context(
|
||||||
}))
|
{
|
||||||
|
'user': User(username='test', email='test@example.com'),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'SnapABug.setUserEmail("test@example.com");' in r
|
assert 'SnapABug.setUserEmail("test@example.com");' in r
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||||
def test_identify_anonymous_user(self):
|
def test_identify_anonymous_user(self):
|
||||||
r = SnapEngageNode().render(Context({
|
r = SnapEngageNode().render(
|
||||||
'user': AnonymousUser(),
|
Context(
|
||||||
}))
|
{
|
||||||
|
'user': AnonymousUser(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'SnapABug.setUserEmail(' not in r
|
assert 'SnapABug.setUserEmail(' not in r
|
||||||
|
|
||||||
def test_language(self):
|
def test_language(self):
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,13 @@ class SpringMetricsTagTestCase(TagTestCase):
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||||
def test_identify(self):
|
def test_identify(self):
|
||||||
r = SpringMetricsNode().render(Context({
|
r = SpringMetricsNode().render(
|
||||||
'user': User(email='test@test.com'),
|
Context(
|
||||||
}))
|
{
|
||||||
|
'user': User(email='test@test.com'),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert "_springMetq.push(['setdata', {'email': 'test@test.com'}]);" in r
|
assert "_springMetq.push(['setdata', {'email': 'test@test.com'}]);" in r
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||||
|
|
@ -50,10 +54,14 @@ class SpringMetricsTagTestCase(TagTestCase):
|
||||||
assert "_springMetq.push(['setdata', {'email':" not in r
|
assert "_springMetq.push(['setdata', {'email':" not in r
|
||||||
|
|
||||||
def test_custom(self):
|
def test_custom(self):
|
||||||
r = SpringMetricsNode().render(Context({
|
r = SpringMetricsNode().render(
|
||||||
'spring_metrics_var1': 'val1',
|
Context(
|
||||||
'spring_metrics_var2': 'val2',
|
{
|
||||||
}))
|
'spring_metrics_var1': 'val1',
|
||||||
|
'spring_metrics_var2': 'val2',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert "_springMetq.push(['setdata', {'var1': 'val1'}]);" in r
|
assert "_springMetq.push(['setdata', {'var1': 'val1'}]);" in r
|
||||||
assert "_springMetq.push(['setdata', {'var2': 'val2'}]);" in r
|
assert "_springMetq.push(['setdata', {'var2': 'val2'}]);" in r
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ class UserVoiceTagTestCase(TagTestCase):
|
||||||
|
|
||||||
def test_node(self):
|
def test_node(self):
|
||||||
r = UserVoiceNode().render(Context())
|
r = UserVoiceNode().render(Context())
|
||||||
assert "widget.uservoice.com/abcdefghijklmnopqrst.js" in r
|
assert 'widget.uservoice.com/abcdefghijklmnopqrst.js' in r
|
||||||
|
|
||||||
def test_tag(self):
|
def test_tag(self):
|
||||||
r = self.render_tag('uservoice', 'uservoice')
|
r = self.render_tag('uservoice', 'uservoice')
|
||||||
assert "widget.uservoice.com/abcdefghijklmnopqrst.js" in r
|
assert 'widget.uservoice.com/abcdefghijklmnopqrst.js' in r
|
||||||
|
|
||||||
@override_settings(USERVOICE_WIDGET_KEY=None)
|
@override_settings(USERVOICE_WIDGET_KEY=None)
|
||||||
def test_no_key(self):
|
def test_no_key(self):
|
||||||
|
|
@ -43,7 +43,7 @@ class UserVoiceTagTestCase(TagTestCase):
|
||||||
def test_overridden_key(self):
|
def test_overridden_key(self):
|
||||||
vars = {'uservoice_widget_key': 'defghijklmnopqrstuvw'}
|
vars = {'uservoice_widget_key': 'defghijklmnopqrstuvw'}
|
||||||
r = UserVoiceNode().render(Context(vars))
|
r = UserVoiceNode().render(Context(vars))
|
||||||
assert "widget.uservoice.com/defghijklmnopqrstuvw.js" in r
|
assert 'widget.uservoice.com/defghijklmnopqrstuvw.js' in r
|
||||||
|
|
||||||
@override_settings(USERVOICE_WIDGET_OPTIONS={'key1': 'val1'})
|
@override_settings(USERVOICE_WIDGET_OPTIONS={'key1': 'val1'})
|
||||||
def test_options(self):
|
def test_options(self):
|
||||||
|
|
|
||||||
|
|
@ -40,23 +40,35 @@ class WoopraTagTestCase(TagTestCase):
|
||||||
@override_settings(WOOPRA_IDLE_TIMEOUT=1234)
|
@override_settings(WOOPRA_IDLE_TIMEOUT=1234)
|
||||||
def test_idle_timeout(self):
|
def test_idle_timeout(self):
|
||||||
r = WoopraNode().render(Context({}))
|
r = WoopraNode().render(Context({}))
|
||||||
assert 'var woo_settings = {"domain": "example.com", "idle_timeout": "1234"};' in r
|
assert (
|
||||||
|
'var woo_settings = {"domain": "example.com", "idle_timeout": "1234"};' in r
|
||||||
|
)
|
||||||
|
|
||||||
def test_custom(self):
|
def test_custom(self):
|
||||||
r = WoopraNode().render(Context({
|
r = WoopraNode().render(
|
||||||
'woopra_var1': 'val1',
|
Context(
|
||||||
'woopra_var2': 'val2',
|
{
|
||||||
}))
|
'woopra_var1': 'val1',
|
||||||
|
'woopra_var2': 'val2',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'var woo_visitor = {"var1": "val1", "var2": "val2"};' in r
|
assert 'var woo_visitor = {"var1": "val1", "var2": "val2"};' in r
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||||
def test_identify_name_and_email(self):
|
def test_identify_name_and_email(self):
|
||||||
r = WoopraNode().render(Context({
|
r = WoopraNode().render(
|
||||||
'user': User(username='test',
|
Context(
|
||||||
first_name='Firstname',
|
{
|
||||||
last_name='Lastname',
|
'user': User(
|
||||||
email="test@example.com"),
|
username='test',
|
||||||
}))
|
first_name='Firstname',
|
||||||
|
last_name='Lastname',
|
||||||
|
email='test@example.com',
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'var woo_visitor = '
|
assert 'var woo_visitor = '
|
||||||
'{"email": "test@example.com", "name": "Firstname Lastname"};' in r
|
'{"email": "test@example.com", "name": "Firstname Lastname"};' in r
|
||||||
|
|
||||||
|
|
@ -67,18 +79,26 @@ class WoopraTagTestCase(TagTestCase):
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||||
def test_no_identify_when_explicit_name(self):
|
def test_no_identify_when_explicit_name(self):
|
||||||
r = WoopraNode().render(Context({
|
r = WoopraNode().render(
|
||||||
'woopra_name': 'explicit',
|
Context(
|
||||||
'user': User(username='implicit'),
|
{
|
||||||
}))
|
'woopra_name': 'explicit',
|
||||||
|
'user': User(username='implicit'),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'var woo_visitor = {"name": "explicit"};' in r
|
assert 'var woo_visitor = {"name": "explicit"};' in r
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||||
def test_no_identify_when_explicit_email(self):
|
def test_no_identify_when_explicit_email(self):
|
||||||
r = WoopraNode().render(Context({
|
r = WoopraNode().render(
|
||||||
'woopra_email': 'explicit',
|
Context(
|
||||||
'user': User(username='implicit'),
|
{
|
||||||
}))
|
'woopra_email': 'explicit',
|
||||||
|
'user': User(username='implicit'),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
assert 'var woo_visitor = {"email": "explicit"};' in r
|
assert 'var woo_visitor = {"email": "explicit"};' in r
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
Tests for the Yandex.Metrica template tags and filters.
|
Tests for the Yandex.Metrica template tags and filters.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
from django.template import Context
|
from django.template import Context
|
||||||
|
|
@ -21,11 +20,11 @@ class YandexMetricaTagTestCase(TagTestCase):
|
||||||
|
|
||||||
def test_tag(self):
|
def test_tag(self):
|
||||||
r = self.render_tag('yandex_metrica', 'yandex_metrica')
|
r = self.render_tag('yandex_metrica', 'yandex_metrica')
|
||||||
assert "w.yaCounter12345678 = new Ya.Metrika" in r
|
assert 'w.yaCounter12345678 = new Ya.Metrika' in r
|
||||||
|
|
||||||
def test_node(self):
|
def test_node(self):
|
||||||
r = YandexMetricaNode().render(Context({}))
|
r = YandexMetricaNode().render(Context({}))
|
||||||
assert "w.yaCounter12345678 = new Ya.Metrika" in r
|
assert 'w.yaCounter12345678 = new Ya.Metrika' in r
|
||||||
|
|
||||||
@override_settings(YANDEX_METRICA_COUNTER_ID=None)
|
@override_settings(YANDEX_METRICA_COUNTER_ID=None)
|
||||||
def test_no_site_id(self):
|
def test_no_site_id(self):
|
||||||
|
|
|
||||||
|
|
@ -21,15 +21,14 @@ from analytical.utils import (
|
||||||
|
|
||||||
|
|
||||||
class SettingDeletedTestCase(TestCase):
|
class SettingDeletedTestCase(TestCase):
|
||||||
|
|
||||||
@override_settings(USER_ID=None)
|
@override_settings(USER_ID=None)
|
||||||
def test_get_required_setting(self):
|
def test_get_required_setting(self):
|
||||||
"""
|
"""
|
||||||
Make sure using get_required_setting fails in the right place.
|
Make sure using get_required_setting fails in the right place.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
with pytest.raises(AnalyticalException, match="USER_ID setting is not set"):
|
with pytest.raises(AnalyticalException, match='USER_ID setting is not set'):
|
||||||
get_required_setting("USER_ID", r"\d+", "invalid USER_ID")
|
get_required_setting('USER_ID', r'\d+', 'invalid USER_ID')
|
||||||
|
|
||||||
|
|
||||||
class MyUser(AbstractBaseUser):
|
class MyUser(AbstractBaseUser):
|
||||||
|
|
@ -47,20 +46,30 @@ class GetIdentityTestCase(TestCase):
|
||||||
assert get_id == 'fake_id'
|
assert get_id == 'fake_id'
|
||||||
|
|
||||||
def test_custom_identity_specific_provider(self):
|
def test_custom_identity_specific_provider(self):
|
||||||
get_id = get_identity(Context({
|
get_id = get_identity(
|
||||||
'foo_provider_identity': 'bar',
|
Context(
|
||||||
'analytical_identity': 'baz',
|
{
|
||||||
}), prefix='foo_provider')
|
'foo_provider_identity': 'bar',
|
||||||
|
'analytical_identity': 'baz',
|
||||||
|
}
|
||||||
|
),
|
||||||
|
prefix='foo_provider',
|
||||||
|
)
|
||||||
assert get_id == 'bar'
|
assert get_id == 'bar'
|
||||||
|
|
||||||
def test_custom_identity_general(self):
|
def test_custom_identity_general(self):
|
||||||
get_id = get_identity(Context({
|
get_id = get_identity(
|
||||||
'analytical_identity': 'baz',
|
Context(
|
||||||
}), prefix='foo_provider')
|
{
|
||||||
|
'analytical_identity': 'baz',
|
||||||
|
}
|
||||||
|
),
|
||||||
|
prefix='foo_provider',
|
||||||
|
)
|
||||||
assert get_id == 'baz'
|
assert get_id == 'baz'
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ANALYTICAL_DOMAIN="example.org")
|
@override_settings(ANALYTICAL_DOMAIN='example.org')
|
||||||
class GetDomainTestCase(TestCase):
|
class GetDomainTestCase(TestCase):
|
||||||
def test_get_service_domain_from_context(self):
|
def test_get_service_domain_from_context(self):
|
||||||
context = Context({'test_domain': 'example.com'})
|
context = Context({'test_domain': 'example.com'})
|
||||||
|
|
@ -70,7 +79,7 @@ class GetDomainTestCase(TestCase):
|
||||||
context = Context({'analytical_domain': 'example.com'})
|
context = Context({'analytical_domain': 'example.com'})
|
||||||
assert get_domain(context, 'test') == 'example.com'
|
assert get_domain(context, 'test') == 'example.com'
|
||||||
|
|
||||||
@override_settings(TEST_DOMAIN="example.net")
|
@override_settings(TEST_DOMAIN='example.net')
|
||||||
def test_get_service_domain_from_settings(self):
|
def test_get_service_domain_from_settings(self):
|
||||||
context = Context()
|
context = Context()
|
||||||
assert get_domain(context, 'test') == 'example.net'
|
assert get_domain(context, 'test') == 'example.net'
|
||||||
|
|
@ -92,7 +101,6 @@ class GetDomainTestCase(TestCase):
|
||||||
|
|
||||||
|
|
||||||
class InternalIpTestCase(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):
|
def test_render_no_internal_ip(self):
|
||||||
context = Context()
|
context = Context()
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class TagTestCase(TestCase):
|
||||||
def render_tag(self, library, tag, vars=None, request=None):
|
def render_tag(self, library, tag, vars=None, request=None):
|
||||||
if vars is None:
|
if vars is None:
|
||||||
vars = {}
|
vars = {}
|
||||||
t = Template("{%% load %s %%}{%% %s %%}" % (library, tag))
|
t = Template('{%% load %s %%}{%% %s %%}' % (library, tag))
|
||||||
if request is not None:
|
if request is not None:
|
||||||
context = RequestContext(request, vars)
|
context = RequestContext(request, vars)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue