diff --git a/analytical/templatetags/chartbeat.py b/analytical/templatetags/chartbeat.py index a9baf1b..26d2c7d 100644 --- a/analytical/templatetags/chartbeat.py +++ b/analytical/templatetags/chartbeat.py @@ -86,7 +86,7 @@ class ChartbeatBottomNode(Node): domain = _get_domain(context) if domain is not None: config['domain'] = domain - html = SETUP_CODE % {'config': json.dumps(config)} + html = SETUP_CODE % {'config': json.dumps(config, sort_keys=True)} if is_internal_ip(context, 'CHARTBEAT'): html = disable_html(html, 'Chartbeat') return html diff --git a/analytical/templatetags/clicky.py b/analytical/templatetags/clicky.py index ce150eb..a2bf1c3 100644 --- a/analytical/templatetags/clicky.py +++ b/analytical/templatetags/clicky.py @@ -66,7 +66,7 @@ class ClickyNode(Node): custom.setdefault('session', {})['username'] = identity html = TRACKING_CODE % {'site_id': self.site_id, - 'custom': json.dumps(custom)} + 'custom': json.dumps(custom, sort_keys=True)} if is_internal_ip(context, 'CLICKY'): html = disable_html(html, 'Clicky') return html diff --git a/analytical/templatetags/intercom.py b/analytical/templatetags/intercom.py index 8ea0498..aa83828 100644 --- a/analytical/templatetags/intercom.py +++ b/analytical/templatetags/intercom.py @@ -75,7 +75,7 @@ class IntercomNode(Node): user = get_user_from_context(context) vars = self._get_custom_attrs(context) vars["app_id"] = self.app_id - html = TRACKING_CODE % {"settings_json": json.dumps(vars)} + html = TRACKING_CODE % {"settings_json": json.dumps(vars, sort_keys=True)} if is_internal_ip(context, 'INTERCOM') or not user or not user.is_authenticated(): # Intercom is disabled for non-logged in users. diff --git a/analytical/templatetags/kiss_metrics.py b/analytical/templatetags/kiss_metrics.py index 8f234ac..d53d11c 100644 --- a/analytical/templatetags/kiss_metrics.py +++ b/analytical/templatetags/kiss_metrics.py @@ -78,13 +78,13 @@ class KissMetricsNode(Node): try: name, properties = context[EVENT_CONTEXT_KEY] commands.append(EVENT_CODE % {'name': name, - 'properties': json.dumps(properties)}) + 'properties': json.dumps(properties, sort_keys=True)}) except KeyError: pass try: properties = context[PROPERTY_CONTEXT_KEY] commands.append(PROPERTY_CODE % { - 'properties': json.dumps(properties)}) + 'properties': json.dumps(properties, sort_keys=True)}) except KeyError: pass html = TRACKING_CODE % {'api_key': self.api_key, diff --git a/analytical/templatetags/mixpanel.py b/analytical/templatetags/mixpanel.py index 5d7d532..fff984b 100644 --- a/analytical/templatetags/mixpanel.py +++ b/analytical/templatetags/mixpanel.py @@ -56,7 +56,7 @@ class MixpanelNode(Node): try: name, properties = context[EVENT_CONTEXT_KEY] commands.append(EVENT_CODE % {'name': name, - 'properties': json.dumps(properties)}) + 'properties': json.dumps(properties, sort_keys=True)}) except KeyError: pass html = TRACKING_CODE % {'token': self.token, diff --git a/analytical/templatetags/olark.py b/analytical/templatetags/olark.py index c9e9232..a42ae8c 100644 --- a/analytical/templatetags/olark.py +++ b/analytical/templatetags/olark.py @@ -64,7 +64,7 @@ class OlarkNode(Node): extra_code.append(NICKNAME_CODE % identity) try: extra_code.append(STATUS_CODE % - json.dumps(context[STATUS_CONTEXT_KEY])) + json.dumps(context[STATUS_CONTEXT_KEY], sort_keys=True)) except KeyError: pass extra_code.extend(self._get_configuration(context)) diff --git a/analytical/templatetags/reinvigorate.py b/analytical/templatetags/reinvigorate.py index aeda778..dd16c95 100644 --- a/analytical/templatetags/reinvigorate.py +++ b/analytical/templatetags/reinvigorate.py @@ -65,7 +65,7 @@ class ReinvigorateNode(Node): email = get_identity(context, 'reinvigorate', lambda u: u.email) if email is not None: re_vars['context'] = email - tags = " ".join("var re_%s_tag = %s;" % (tag, json.dumps(value)) + tags = " ".join("var re_%s_tag = %s;" % (tag, json.dumps(value, sort_keys=True)) for tag, value in re_vars.items()) html = TRACKING_CODE % {'tracking_id': self.tracking_id, diff --git a/analytical/templatetags/uservoice.py b/analytical/templatetags/uservoice.py index 55273b6..178a433 100644 --- a/analytical/templatetags/uservoice.py +++ b/analytical/templatetags/uservoice.py @@ -62,7 +62,7 @@ class UserVoiceNode(Node): # Enable SSO pass html = TRACKING_CODE % {'widget_key': widget_key, - 'options': json.dumps(options)} + 'options': json.dumps(options, sort_keys=True)} return html @@ -103,7 +103,7 @@ class UserVoiceKeyLinkNode(Node): vars = {} if self.widget_key: vars['widget_key'] = self.widget_key.resolve(context) - return LINK_CODE % json.dumps(vars) + return LINK_CODE % json.dumps(vars, sort_keys=True) def contribute_to_analytical(add_node): diff --git a/analytical/templatetags/woopra.py b/analytical/templatetags/woopra.py index d70ed5b..8018e78 100644 --- a/analytical/templatetags/woopra.py +++ b/analytical/templatetags/woopra.py @@ -57,8 +57,8 @@ class WoopraNode(Node): visitor = self._get_visitor(context) html = TRACKING_CODE % { - 'settings': json.dumps(settings), - 'visitor': json.dumps(visitor), + 'settings': json.dumps(settings, sort_keys=True), + 'visitor': json.dumps(visitor, sort_keys=True), } if is_internal_ip(context, 'WOOPRA'): html = disable_html(html, 'Woopra') diff --git a/analytical/tests/test_tag_clicky.py b/analytical/tests/test_tag_clicky.py index e7d9b2d..1755e7e 100644 --- a/analytical/tests/test_tag_clicky.py +++ b/analytical/tests/test_tag_clicky.py @@ -54,12 +54,8 @@ class ClickyTagTestCase(TagTestCase): def test_custom(self): r = ClickyNode().render(Context({'clicky_var1': 'val1', 'clicky_var2': 'val2'})) - self.assertTrue( - (re.search('var clicky_custom = {.*' - '"var1": "val1", "var2": "val2".*};', r) or - re.search('var clicky_custom = {.*' - '"var2": "val2", "var1": "val1".*};', r)), r - ) + self.assertTrue(re.search('var clicky_custom = {.*' + '"var1": "val1", "var2": "val2".*};', r), r) @override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1']) def test_render_internal_ip(self): diff --git a/analytical/tests/test_tag_intercom.py b/analytical/tests/test_tag_intercom.py index ad2b015..edd69ba 100644 --- a/analytical/tests/test_tag_intercom.py +++ b/analytical/tests/test_tag_intercom.py @@ -34,13 +34,10 @@ class IntercomTagTestCase(TagTestCase): date_joined=now) })) # Because the json isn't predictably ordered, we can't just test the whole thing verbatim. - self.assertIn(""" + self.assertEquals(""" + """, rendered_tag) @@ -57,19 +54,17 @@ class IntercomTagTestCase(TagTestCase): r = IntercomNode().render(Context({'user': User(username='test', first_name='Firstname', last_name='Lastname', email="test@example.com", date_joined=now)})) - self.assertTrue("window.intercomSettings = {" in r, r) - self.assertTrue('"app_id": "1234567890abcdef0123456789"' in r) - self.assertTrue('"full_name": "Firstname Lastname"' in r) - self.assertTrue('"email": "test@example.com"' in r) - self.assertTrue('"created_at": 1397074500' in r) + self.assertTrue( + """window.intercomSettings = {"app_id": "1234567890abcdef0123456789", "created_at": 1397074500, "email": "test@example.com", "full_name": "Firstname Lastname"};"""\ + in r + ) def test_custom(self): r = IntercomNode().render(Context({ 'intercom_var1': 'val1', 'intercom_var2': 'val2' })) - self.assertTrue('"var1": "val1"' in r) - self.assertTrue('"var2": "val2"' in r) + self.assertTrue('var1": "val1", "var2": "val2"' in r) def test_identify_name_and_email(self): r = IntercomNode().render(Context({ @@ -78,8 +73,7 @@ class IntercomTagTestCase(TagTestCase): last_name='Lastname', email="test@example.com") })) - self.assertTrue('"full_name": "Firstname Lastname"' in r) - self.assertTrue('"email": "test@example.com"' in r) + self.assertTrue('"email": "test@example.com", "full_name": "Firstname Lastname"' in r) def test_identify_username_no_email(self): r = IntercomNode().render(Context({'user': User(username='test')})) diff --git a/analytical/tests/test_tag_kiss_metrics.py b/analytical/tests/test_tag_kiss_metrics.py index 7393321..d520f52 100644 --- a/analytical/tests/test_tag_kiss_metrics.py +++ b/analytical/tests/test_tag_kiss_metrics.py @@ -55,19 +55,14 @@ class KissMetricsTagTestCase(TagTestCase): def test_event(self): r = KissMetricsNode().render(Context({'kiss_metrics_event': ('test_event', {'prop1': 'val1', 'prop2': 'val2'})})) - self.assertTrue( - ("_kmq.push(['record', 'test_event', " - '{"prop1": "val1", "prop2": "val2"}]);' in r or\ - "_kmq.push(['record', 'test_event', " - '{"prop2": "val2", "prop1": "val1"}]);' in r), r) + self.assertTrue("_kmq.push(['record', 'test_event', " + '{"prop1": "val1", "prop2": "val2"}]);' in r, r) def test_property(self): r = KissMetricsNode().render(Context({'kiss_metrics_properties': {'prop1': 'val1', 'prop2': 'val2'}})) - self.assertTrue( - ('_kmq.push([\'set\', {"prop1": "val1", "prop2": "val2"}]);' in r or - '_kmq.push([\'set\', {"prop2": "val2", "prop1": "val1"}]);' in r), - r) + self.assertTrue("_kmq.push([\'set\', " + '{"prop1": "val1", "prop2": "val2"}]);' in r, r) def test_alias(self): r = KissMetricsNode().render(Context({'kiss_metrics_alias': diff --git a/analytical/tests/test_tag_mixpanel.py b/analytical/tests/test_tag_mixpanel.py index a6259d8..a4e762e 100644 --- a/analytical/tests/test_tag_mixpanel.py +++ b/analytical/tests/test_tag_mixpanel.py @@ -54,9 +54,8 @@ class MixpanelTagTestCase(TagTestCase): def test_event(self): r = MixpanelNode().render(Context({'mixpanel_event': ('test_event', {'prop1': 'val1', 'prop2': 'val2'})})) - self.assertTrue( - ('mixpanel.track(\'test_event\', {"prop1": "val1", "prop2": "val2"});' in r or - 'mixpanel.track(\'test_event\', {"prop2": "val2", "prop1": "val1"});' in r), r) + self.assertTrue("mixpanel.track(\'test_event\', " + '{"prop1": "val1", "prop2": "val2"});' in r, r) @override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1']) def test_render_internal_ip(self): diff --git a/analytical/tests/test_tag_uservoice.py b/analytical/tests/test_tag_uservoice.py index 99a4b38..5f082d6 100644 --- a/analytical/tests/test_tag_uservoice.py +++ b/analytical/tests/test_tag_uservoice.py @@ -89,6 +89,5 @@ class UserVoiceTagTestCase(TagTestCase): } } r = UserVoiceNode().render(Context(vars)) - self.assertTrue( - ('"custom_fields": {"field2": "val2", "field1": "val1"}' in r or - '"custom_fields": {"field1": "val1", "field2": "val2"}' in r ), r) + self.assertTrue('"custom_fields": {"field1": "val1", "field2": "val2"}' + in r , r) diff --git a/analytical/tests/test_tag_woopra.py b/analytical/tests/test_tag_woopra.py index 2cb2179..42dd8fa 100644 --- a/analytical/tests/test_tag_woopra.py +++ b/analytical/tests/test_tag_woopra.py @@ -37,25 +37,22 @@ class WoopraTagTestCase(TagTestCase): @override_settings(WOOPRA_IDLE_TIMEOUT=1234) def test_idle_timeout(self): r = WoopraNode().render(Context({})) - self.assertTrue( - ('var woo_settings = {"domain": "example.com", "idle_timeout": "1234"};' in r or - 'var woo_settings = {"idle_timeout": "1234", "domain": "example.com"};' in r), r) + self.assertTrue('var woo_settings = {"domain": "example.com", ' + '"idle_timeout": "1234"};' in r, r) def test_custom(self): r = WoopraNode().render(Context({'woopra_var1': 'val1', 'woopra_var2': 'val2'})) - self.assertTrue( - ('var woo_visitor = {"var1": "val1", "var2": "val2"};' in r or - 'var woo_visitor = {"var2": "val2", "var1": "val1"};' in r), r) + self.assertTrue('var woo_visitor = {"var1": "val1", "var2": "val2"};' + in r, r) @override_settings(ANALYTICAL_AUTO_IDENTIFY=True) def test_identify_name_and_email(self): r = WoopraNode().render(Context({'user': User(username='test', first_name='Firstname', last_name='Lastname', email="test@example.com")})) - self.assertTrue( - ('var woo_visitor = {"name": "Firstname Lastname", "email": "test@example.com"};' in r or - 'var woo_visitor = {"email": "test@example.com", "name": "Firstname Lastname"};' in r), r) + self.assertTrue('var woo_visitor = {"email": "test@example.com", ' + '"name": "Firstname Lastname"};' in r, r) @override_settings(ANALYTICAL_AUTO_IDENTIFY=True) def test_identify_username_no_email(self):