Skip to content

Commit 8b12e33

Browse files
committed
Add more config options for Woopra
Closes #100
1 parent e0f95bc commit 8b12e33

File tree

4 files changed

+164
-6
lines changed

4 files changed

+164
-6
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Unreleased
88
license metadata field (Peter Bittner)
99
* Remove AUTHORS file to avoid confusion; this is now metadata maintained
1010
in pyproject.toml (Peter Bittner)
11+
* Add more configuration options for Woopra (Peter Bittner)
1112

1213
Version 3.1.0
1314
-------------

analytical/templatetags/woopra.py

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44

55
import json
66
import re
7+
from contextlib import suppress
78

89
from django.conf import settings
910
from django.template import Library, Node, TemplateSyntaxError
1011

1112
from analytical.utils import (
13+
AnalyticalException,
1214
disable_html,
1315
get_identity,
1416
get_required_setting,
@@ -66,10 +68,42 @@ def render(self, context):
6668

6769
def _get_settings(self, context):
6870
variables = {'domain': self.domain}
69-
try:
70-
variables['idle_timeout'] = str(settings.WOOPRA_IDLE_TIMEOUT)
71-
except AttributeError:
72-
pass
71+
woopra_int_settings = {
72+
'idle_timeout': 'WOOPRA_IDLE_TIMEOUT',
73+
}
74+
woopra_str_settings = {
75+
'cookie_name': 'WOOPRA_COOKIE_NAME',
76+
'cookie_domain': 'WOOPRA_COOKIE_DOMAIN',
77+
'cookie_path': 'WOOPRA_COOKIE_PATH',
78+
'cookie_expire': 'WOOPRA_COOKIE_EXPIRE',
79+
}
80+
woopra_bool_settings = {
81+
'click_tracking': 'WOOPRA_CLICK_TRACKING',
82+
'download_tracking': 'WOOPRA_DOWNLOAD_TRACKING',
83+
'outgoing_tracking': 'WOOPRA_OUTGOING_TRACKING',
84+
'outgoing_ignore_subdomain': 'WOOPRA_OUTGOING_IGNORE_SUBDOMAIN',
85+
'ignore_query_url': 'WOOPRA_IGNORE_QUERY_URL',
86+
'hide_campaign': 'WOOPRA_HIDE_CAMPAIGN',
87+
}
88+
89+
for key, name in woopra_int_settings.items():
90+
with suppress(AttributeError):
91+
variables[key] = getattr(settings, name)
92+
if type(variables[key]) is not int:
93+
raise AnalyticalException(f'{name} must be an int value')
94+
95+
for key, name in woopra_str_settings.items():
96+
with suppress(AttributeError):
97+
variables[key] = getattr(settings, name)
98+
if type(variables[key]) is not str:
99+
raise AnalyticalException(f'{name} must be a string value')
100+
101+
for key, name in woopra_bool_settings.items():
102+
with suppress(AttributeError):
103+
variables[key] = getattr(settings, name)
104+
if type(variables[key]) is not bool:
105+
raise AnalyticalException(f'{name} must be a boolean value')
106+
73107
return variables
74108

75109
def _get_visitor(self, context):

docs/services/woopra.rst

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,38 @@ a page reporting. So it’s important to keep the number reasonable in
9494
order to accurately make predictions.
9595

9696

97+
Cookie control
98+
--------------
99+
100+
Optional settings that influence the cookie behavior::
101+
102+
WOOPRA_COOKIE_NAME = "wooTracker"
103+
WOOPRA_COOKIE_DOMAIN = ".example.com"
104+
WOOPRA_COOKIE_PATH = "/"
105+
WOOPRA_COOKIE_EXPIRE = "Fri Jan 01 2027 15:00:00 GMT+0000"
106+
107+
See the `Woopra documentation`_ for more specific details.
108+
109+
110+
Tracking control
111+
----------------
112+
113+
Optional settings that influence the tracking as such::
114+
115+
WOOPRA_CLICK_TRACKING = False
116+
WOOPRA_DOWNLOAD_TRACKING = False
117+
WOOPRA_OUTGOING_TRACKING = False
118+
WOOPRA_OUTGOING_IGNORE_SUBDOMAIN = True
119+
WOOPRA_IGNORE_QUERY_URL = True
120+
WOOPRA_HIDE_CAMPAIGN = False
121+
122+
See the `Woopra documentation`_ for more specific details.
123+
124+
125+
.. _`Woopra documentation`:
126+
https://docs.woopra.com/reference/woopraconfig#configuring-your-tracker
127+
128+
97129
Internal IP addresses
98130
---------------------
99131

tests/unit/test_tag_woopra.py

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
Tests for the Woopra template tags and filters.
33
"""
44

5+
from datetime import datetime
6+
57
import pytest
68
from django.contrib.auth.models import AnonymousUser, User
79
from django.http import HttpRequest
@@ -41,8 +43,97 @@ def test_wrong_domain(self):
4143
def test_idle_timeout(self):
4244
r = WoopraNode().render(Context({}))
4345
assert (
44-
'var woo_settings = {"domain": "example.com", "idle_timeout": "1234"};' in r
45-
)
46+
'var woo_settings = {"domain": "example.com", "idle_timeout": 1234};'
47+
) in r
48+
49+
@override_settings(WOOPRA_COOKIE_NAME='foo')
50+
def test_cookie_name(self):
51+
r = WoopraNode().render(Context({}))
52+
assert (
53+
'var woo_settings = {"cookie_name": "foo", "domain": "example.com"};'
54+
) in r
55+
56+
@override_settings(WOOPRA_COOKIE_DOMAIN='.example.com')
57+
def test_cookie_domain(self):
58+
r = WoopraNode().render(Context({}))
59+
assert (
60+
'var woo_settings = {"cookie_domain": ".example.com",'
61+
' "domain": "example.com"};'
62+
) in r
63+
64+
@override_settings(WOOPRA_COOKIE_PATH='/foo/cookie/path')
65+
def test_cookie_path(self):
66+
r = WoopraNode().render(Context({}))
67+
assert (
68+
'var woo_settings = {"cookie_path": "/foo/cookie/path",'
69+
' "domain": "example.com"};'
70+
) in r
71+
72+
@override_settings(WOOPRA_COOKIE_EXPIRE='Fri Jan 01 2027 15:00:00 GMT+0000')
73+
def test_cookie_expire(self):
74+
r = WoopraNode().render(Context({}))
75+
assert (
76+
'var woo_settings = {"cookie_expire":'
77+
' "Fri Jan 01 2027 15:00:00 GMT+0000", "domain": "example.com"};'
78+
) in r
79+
80+
@override_settings(WOOPRA_CLICK_TRACKING=True)
81+
def test_click_tracking(self):
82+
r = WoopraNode().render(Context({}))
83+
assert (
84+
'var woo_settings = {"click_tracking": true, "domain": "example.com"};'
85+
) in r
86+
87+
@override_settings(WOOPRA_DOWNLOAD_TRACKING=True)
88+
def test_download_tracking(self):
89+
r = WoopraNode().render(Context({}))
90+
assert (
91+
'var woo_settings = {"domain": "example.com", "download_tracking": true};'
92+
) in r
93+
94+
@override_settings(WOOPRA_OUTGOING_TRACKING=True)
95+
def test_outgoing_tracking(self):
96+
r = WoopraNode().render(Context({}))
97+
assert (
98+
'var woo_settings = {"domain": "example.com", "outgoing_tracking": true};'
99+
) in r
100+
101+
@override_settings(WOOPRA_OUTGOING_IGNORE_SUBDOMAIN=False)
102+
def test_outgoing_ignore_subdomain(self):
103+
r = WoopraNode().render(Context({}))
104+
assert (
105+
'var woo_settings = {"domain": "example.com",'
106+
' "outgoing_ignore_subdomain": false};'
107+
) in r
108+
109+
@override_settings(WOOPRA_IGNORE_QUERY_URL=False)
110+
def test_ignore_query_url(self):
111+
r = WoopraNode().render(Context({}))
112+
assert (
113+
'var woo_settings = {"domain": "example.com", "ignore_query_url": false};'
114+
) in r
115+
116+
@override_settings(WOOPRA_HIDE_CAMPAIGN=True)
117+
def test_hide_campaign(self):
118+
r = WoopraNode().render(Context({}))
119+
assert (
120+
'var woo_settings = {"domain": "example.com", "hide_campaign": true};'
121+
) in r
122+
123+
@override_settings(WOOPRA_IDLE_TIMEOUT='1234')
124+
def test_invalid_int_setting(self):
125+
with pytest.raises(AnalyticalException, match=r'must be an int'):
126+
WoopraNode().render(Context({}))
127+
128+
@override_settings(WOOPRA_HIDE_CAMPAIGN='tomorrow')
129+
def test_invalid_bool_setting(self):
130+
with pytest.raises(AnalyticalException, match=r'must be a boolean'):
131+
WoopraNode().render(Context({}))
132+
133+
@override_settings(WOOPRA_COOKIE_EXPIRE=datetime.now())
134+
def test_invalid_str_setting(self):
135+
with pytest.raises(AnalyticalException, match=r'must be a string'):
136+
WoopraNode().render(Context({}))
46137

47138
def test_custom(self):
48139
r = WoopraNode().render(

0 commit comments

Comments
 (0)