Python implementation of the Piwik HTTP API
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

161 lines
6.2KB

  1. # -*- coding: utf-8 -*-
  2. from collections import OrderedDict
  3. import difflib
  4. import unittest
  5. try:
  6. # py3
  7. from urllib.parse import urlparse, parse_qs, urljoin, urlunparse, urlencode
  8. except ImportError:
  9. from urlparse import urljoin, urlparse, parse_qs, urlunparse
  10. from urllib import urlencode
  11. from pypiwik.tracker import TrackingCodeBuilder, PiwikTracker
  12. import re
  13. img_src_re = re.compile('img src="(.*?)"', re.IGNORECASE)
  14. class TrackingCodeBuilderTest(unittest.TestCase):
  15. def assertTrackingCodeEquals(self, first, second):
  16. def _clean(s):
  17. m = img_src_re.search(s)
  18. assert m and len(m.groups()) == 1, "String does not have an image tracker code"
  19. url = m.group(1)
  20. urlparts = urlparse(url)
  21. query = parse_qs(urlparts.query)
  22. d = OrderedDict(sorted(((k, v[0]) for k, v in query.items()), key=lambda x: x[0]))
  23. new_url = urlunparse((urlparts.scheme, urlparts.netloc, urlparts.path, urlparts.params, urlencode(d), urlparts.fragment))
  24. s2 = img_src_re.sub(new_url, s)
  25. return [x.strip(' ') for x in s2.splitlines(True) if x.strip(' ') if x.strip(' ') != '\n']
  26. t1_lines = _clean(first)
  27. t2_lines = _clean(second)
  28. assert difflib.SequenceMatcher(None, t1_lines, t2_lines).ratio() == 1.0, \
  29. "Tracking codes do not match: %s" % ''.join(difflib.ndiff(t1_lines, t2_lines))
  30. def assertImageTrackingVars(self, tracking_code, expected_vars):
  31. m = img_src_re.search(tracking_code)
  32. assert m and len(m.groups()) == 1, "String does not have an image tracker code"
  33. url = m.group(1)
  34. urlparts = urlparse(url)
  35. query = parse_qs(urlparts.query)
  36. for k, v in expected_vars.items():
  37. assert k in query, "Image tracker query string does not contain '%s'" % k
  38. assert query[k] == [v], \
  39. "Image tracker variable %s does not match expected value '%s'. It's '%s'" % (k, v, query[k])
  40. def test_simple_tracking_code(self):
  41. tracker = PiwikTracker('http://localhost', 1)
  42. builder = TrackingCodeBuilder(tracker)
  43. s = builder.render(tracker._build_parameters())
  44. self.assertTrackingCodeEquals(s, """<script type="text/javascript">
  45. var _paq = _paq || [];
  46. _paq.push(['trackPageView']);
  47. _paq.push(['enableLinkTracking']);
  48. (function() {
  49. _paq.push(['setTrackerUrl', 'http://localhost/piwik.php']);
  50. _paq.push(['setSiteId', 1]);
  51. var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
  52. g.type='text/javascript'; g.async=true; g.defer=true; g.src='http://localhost/piwik.js'; s.parentNode.insertBefore(g,s);
  53. })();
  54. </script>
  55. <noscript><p><img src="http://localhost/piwik.php?idsite=1&rec=1&apiv=1" style="border:0;" alt="" /></p></noscript>""")
  56. def test_event_tracking_code(self):
  57. tracker = PiwikTracker('http://localhost', 1)
  58. tracker.event_category = "event_category"
  59. tracker.event_action = "event_action"
  60. builder = TrackingCodeBuilder(tracker)
  61. s = builder.render(tracker._build_parameters())
  62. self.assertTrackingCodeEquals(s, """<script type="text/javascript">
  63. var _paq = _paq || [];
  64. _paq.push(["trackEvent", "event_category", "event_action"]);
  65. _paq.push(['trackPageView']);
  66. _paq.push(['enableLinkTracking']);
  67. (function() {
  68. _paq.push(['setTrackerUrl', 'http://localhost/piwik.php']);
  69. _paq.push(['setSiteId', 1]);
  70. var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
  71. g.type='text/javascript'; g.async=true; g.defer=true; g.src='http://localhost/piwik.js'; s.parentNode.insertBefore(g,s);
  72. })();
  73. </script>
  74. <noscript><p><img src="http://localhost/piwik.php?idsite=1&rec=1&apiv=1&e_a=event_action&e_c=event_category" style="border:0;" alt="" /></p></noscript>""")
  75. def test_method_call_generation(self):
  76. # test new_visit=True
  77. tracker = PiwikTracker('http://localhost', 1)
  78. tracker.new_visit = True
  79. builder = TrackingCodeBuilder(tracker)
  80. s = builder.render(tracker._build_parameters())
  81. assert '_paq.push(["deleteCookies"]);' in s
  82. assert '_paq.push(["appendToTrackingUrl", "new_visit=1"]);' in s
  83. self.assertImageTrackingVars(s, {
  84. 'new_visit': '1'
  85. })
  86. # test track_bots=True
  87. tracker = PiwikTracker('http://localhost', 1)
  88. tracker.track_bots = True
  89. builder = TrackingCodeBuilder(tracker)
  90. s = builder.render(tracker._build_parameters())
  91. assert '_paq.push(["appendToTrackingUrl", "bots=1"]);' in s
  92. self.assertImageTrackingVars(s, {
  93. 'bots': '1'
  94. })
  95. # test action_name
  96. tracker = PiwikTracker('http://localhost', 1)
  97. tracker.action_name = "Foo / Bar"
  98. builder = TrackingCodeBuilder(tracker)
  99. s = builder.render(tracker._build_parameters())
  100. assert '_paq.push(["setDocumentTitle", "Foo / Bar"]);' in s
  101. self.assertImageTrackingVars(s, {
  102. 'action_name': 'Foo / Bar'
  103. })
  104. # test action_name
  105. tracker = PiwikTracker('http://localhost', 1)
  106. tracker.referer = 'http://foobar.local'
  107. builder = TrackingCodeBuilder(tracker)
  108. s = builder.render(tracker._build_parameters())
  109. assert '_paq.push(["setReferrerUrl", "http://foobar.local"]);' in s
  110. self.assertImageTrackingVars(s, {
  111. 'urlref': 'http://foobar.local'
  112. })
  113. def test_heartbeat_timer(self):
  114. tracker = PiwikTracker('http://localhost', 1)
  115. tracker.heartbeat_timer = None
  116. builder = TrackingCodeBuilder(tracker)
  117. s = builder.render(tracker._build_parameters())
  118. assert 'enableHeartBeatTimer' not in s, "Heartbeat timer enabled but set to None"
  119. tracker = PiwikTracker('http://localhost', 1)
  120. tracker.heartbeat_timer = 0
  121. builder = TrackingCodeBuilder(tracker)
  122. s = builder.render(tracker._build_parameters())
  123. assert 'enableHeartBeatTimer' not in s, "Heartbeat timer enabled but set to 0"
  124. tracker = PiwikTracker('http://localhost', 1)
  125. tracker.heartbeat_timer = 10
  126. builder = TrackingCodeBuilder(tracker)
  127. s = builder.render(tracker._build_parameters())
  128. assert '_paq.push(["enableHeartBeatTimer", 10]);' in s, "heartbeat_timer set but not enabled in tracking code"