Skip to content

Commit

Permalink
Remove Google Analytics features (#1697)
Browse files Browse the repository at this point in the history
  • Loading branch information
istride authored May 21, 2024
1 parent 4fd379b commit 5f293f2
Show file tree
Hide file tree
Showing 13 changed files with 46 additions and 395 deletions.
30 changes: 9 additions & 21 deletions home/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,6 @@ class SiteSettings(BaseSetting):
help_text=_('When selecting this option, untranslated pages'
' will not be visible to the front end user'
' when viewing a child language of the site'))
# TODO: GA, FB analytics should be global.
fb_analytics_app_id = models.CharField(
verbose_name=_('Facebook Analytics App ID'),
max_length=25,
Expand All @@ -639,6 +638,10 @@ class SiteSettings(BaseSetting):
help_text=_(
"The tracking ID to be used to view Facebook Analytics")
)

# Begin GA settings
# These are now obsolete and should be removed once it is deemed safe for these
# fields to be removed.
local_ga_tag_manager = models.CharField(
verbose_name=_('Local GA Tag Manager'),
max_length=255,
Expand Down Expand Up @@ -675,6 +678,8 @@ class SiteSettings(BaseSetting):
"Global GA tracking code to be used"
" to view analytics on more than one site globally")
)
# End GA settings

social_media_link = StreamField(
[('social_media_link', SocialMediaLinkBlock())],
null=True,
Expand All @@ -691,7 +696,10 @@ class SiteSettings(BaseSetting):
registration_survey = models.ForeignKey('questionnaires.Survey', null=True,
blank=True,
on_delete=models.SET_NULL)

# Obsolete - Web Light service discontinued Dec 2022
opt_in_to_google_web_light = models.BooleanField(default=False)

mtm_container_id = models.CharField(
verbose_name=_("Matomo Tag Manager container ID"),
max_length=255,
Expand Down Expand Up @@ -719,20 +727,6 @@ class SiteSettings(BaseSetting):
],
heading="Facebook Analytics Settings",
),
MultiFieldPanel(
[
FieldPanel('local_ga_tag_manager'),
FieldPanel('global_ga_tag_manager'),
],
heading="GA Tag Manager Settings",
),
MultiFieldPanel(
[
FieldPanel('local_ga_tracking_code'),
FieldPanel('global_ga_tracking_code'),
],
heading="GA Tracking Code Settings",
),
MultiFieldPanel(
[
MultiFieldPanel(
Expand Down Expand Up @@ -769,12 +763,6 @@ class SiteSettings(BaseSetting):
],
heading="Registration Settings",
),
MultiFieldPanel(
[
FieldPanel('opt_in_to_google_web_light'),
],
heading="Opt in to Google web light",
),
MultiFieldPanel(
[
FieldPanel(
Expand Down
45 changes: 0 additions & 45 deletions home/templatetags/generic_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from django import template
from django.conf import settings
from django.urls import reverse
from google_analytics import CAMPAIGN_TRACKING_PARAMS

import iogt.iogt_globals as globals_

Expand Down Expand Up @@ -83,47 +82,3 @@ def language_picker_style():
theme_settings = globals_.theme_settings
return f"color:{theme_settings.language_picker_font_color};background-color:" \
f"{theme_settings.language_picker_background_color}"


@register.simple_tag(takes_context=True)
def google_analytics(context, tracking_code=None, debug=False):
if not tracking_code:
try:
assert settings.GOOGLE_ANALYTICS['google_analytics_id']
except KeyError:
return ''
# attempt get the request from the context
request = context.get('request', None)
if request is None:
raise RuntimeError("Request context required")
# intialise the parameters collection
params = {}
# collect the campaign tracking parameters from the request
for param in CAMPAIGN_TRACKING_PARAMS.values():
value = request.GET.get(param, None)
if value:
params[param] = value
# pass on the referer if present
referer = request.META.get('HTTP_REFERER', None)
if referer:
params['r'] = referer
# remove collected parameters from the path and pass it on
path = request.get_full_path()
parsed_url = urlparse(path)
query = parse_qs(parsed_url.query, keep_blank_values=True)
for param in params:
if param in query:
del query[param]
query = urlencode(query, doseq=True)
new_url = parsed_url._replace(query=query)
params['p'] = new_url.geturl()
params['tracking_code'] = tracking_code or settings.GOOGLE_ANALYTICS[
'google_analytics_id']
# append the debug parameter if requested
if debug:
params['utmdebug'] = 1
# build and return the url
url = reverse('google-analytics')
if params:
url += '?&' + urlencode(params)
return url
141 changes: 34 additions & 107 deletions home/test.py
Original file line number Diff line number Diff line change
@@ -1,65 +1,65 @@
from urllib.parse import parse_qs
from unittest.mock import patch

from django.conf import settings
from django.db.utils import IntegrityError
from django.template import Context
from django.test import TestCase, RequestFactory
from django.test import TestCase
from django.urls import reverse
from iogt_users.factories import GroupFactory, UserFactory
from rest_framework import status
from wagtail.models import PageViewRestriction, Site
from unittest.mock import patch
from wagtail_factories import SiteFactory

from home.models import SVGToPNGMap
from home.templatetags.generic_components import google_analytics
from iogt_users.factories import UserFactory, GroupFactory
from home.factories import ArticleFactory, HomePageFactory
from wagtail_factories import SiteFactory
from home.models import SVGToPNGMap


class PageViewGroupPermissionTests(TestCase):
def setUp(self):
self.user = UserFactory()

Site.objects.all().delete()
self.site = SiteFactory(site_name='IoGT', port=8000, is_default_site=True)
self.site = SiteFactory(site_name="IoGT", port=8000, is_default_site=True)
self.home_page = HomePageFactory(parent=self.site.root_page)

self.group_restricted_article = ArticleFactory(parent=self.home_page)
view_restriction = PageViewRestriction.objects.create(
page=self.group_restricted_article, restriction_type=PageViewRestriction.GROUPS)
page=self.group_restricted_article,
restriction_type=PageViewRestriction.GROUPS,
)

self.allowed_group = GroupFactory(name='Allowed group')
self.allowed_group = GroupFactory(name="Allowed group")
view_restriction.groups.add(self.allowed_group)

def test_group_limited_article_without_login_redirects_to_login_page(self):
response = self.client.get(self.group_restricted_article.url)
self.assertEqual(response.status_code, status.HTTP_302_FOUND)
self.assertEqual(
f'{reverse("account_login")}?next={self.group_restricted_article.url}', response.url)
f'{reverse("account_login")}?next={self.group_restricted_article.url}',
response.url,
)

def test_group_limited_article_without_group_returns_403(self):
self.client.login(username=self.user.username, password='test@123')
self.client.login(username=self.user.username, password="test@123")
response = self.client.get(self.group_restricted_article.url)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

def test_group_limited_article_with_group_user_returns_200(self):
self.user.groups.add(self.allowed_group)
self.client.login(username=self.user.username, password='test@123')
self.client.login(username=self.user.username, password="test@123")
response = self.client.get(self.group_restricted_article.url)
self.assertEqual(response.status_code, status.HTTP_200_OK)


class SVGToPNGMapTests(TestCase):

def setUp(self) -> None:
self.svg_path = 'static/icons/search.svg'
self.svg_path = "static/icons/search.svg"

def test_create_png_if_not_found(self):
png = SVGToPNGMap.get_png_image(self.svg_path)
expected_path_regex = ''.join([
settings.MEDIA_ROOT,
r"/svg-to-png-maps/svg-to-png.*\.png"
])
expected_path_regex = "".join(
[settings.MEDIA_ROOT, r"/svg-to-png-maps/svg-to-png.*\.png"]
)
self.assertRegex(png.path, expected_path_regex)
self.assertGreater(png.size, 0)

Expand All @@ -69,27 +69,25 @@ def test_create_png_if_not_found(self):
def test_ignore_duplicates(self):
png = SVGToPNGMap.get_png_image(self.svg_path)
duplicate = {
'svg_path': self.svg_path,
'fill_color': None,
'stroke_color': None,
'png_image_file': png
"svg_path": self.svg_path,
"fill_color": None,
"stroke_color": None,
"png_image_file": png,
}
SVGToPNGMap.objects.create(**duplicate)
SVGToPNGMap.objects.create(**duplicate)
count = SVGToPNGMap.objects.filter(
svg_path=self.svg_path,
fill_color=None,
stroke_color=None
svg_path=self.svg_path, fill_color=None, stroke_color=None
).count()
self.assertEquals(count, 2)
png_2 = SVGToPNGMap.get_png_image(self.svg_path, None, None)
self.assertEquals(png, png_2)

@patch.object(SVGToPNGMap, 'create')
@patch.object(SVGToPNGMap, "create")
def test_get_png_must_not_fail(self, create):
create.side_effect = Exception('boom')
png = SVGToPNGMap.get_png_image(self.svg_path)
self.assertIsNone(png)
create.side_effect = Exception("boom")
png = SVGToPNGMap.get_png_image(self.svg_path)
self.assertIsNone(png)

def test_uniqueness_unspecified_stroke_and_fill(self):
SVGToPNGMap.create(self.svg_path)
Expand All @@ -102,87 +100,16 @@ def test_uniqueness_no_stroke_and_fill(self):
SVGToPNGMap.create(self.svg_path, None, None)

def test_uniqueness_fill_no_stroke(self):
SVGToPNGMap.create(
self.svg_path,
fill_color='#a1b2c3',
stroke_color=None
)
SVGToPNGMap.create(self.svg_path, fill_color="#a1b2c3", stroke_color=None)
with self.assertRaises(IntegrityError):
SVGToPNGMap.create(
self.svg_path,
fill_color='#a1b2c3',
stroke_color=None
)
SVGToPNGMap.create(self.svg_path, fill_color="#a1b2c3", stroke_color=None)

def test_uniqueness_stroke_no_fill(self):
SVGToPNGMap.create(self.svg_path, fill_color=None, stroke_color='#fff')
SVGToPNGMap.create(self.svg_path, fill_color=None, stroke_color="#fff")
with self.assertRaises(IntegrityError):
SVGToPNGMap.create(
self.svg_path,
fill_color=None,
stroke_color='#fff'
)
SVGToPNGMap.create(self.svg_path, fill_color=None, stroke_color="#fff")

def test_uniqueness_stroke_and_fill(self):
SVGToPNGMap.create(
self.svg_path,
fill_color='#555',
stroke_color='#666'
)
SVGToPNGMap.create(self.svg_path, fill_color="#555", stroke_color="#666")
with self.assertRaises(IntegrityError):
SVGToPNGMap.create(
self.svg_path,
fill_color='#555',
stroke_color='#666'
)


class GoogleAnalyticsTagsTestCase(TestCase):
def setUp(self):
self.request_factory = RequestFactory()

def test_query_param_without_value(self):
request = self.request_factory.get('/en/?test')
context = Context({'request': request})

rendered_template = google_analytics(context, tracking_code='my-code')

parsed_qs = parse_qs(rendered_template)
self.assertEqual(parsed_qs['tracking_code'][0], "my-code")
self.assertEqual(parsed_qs['p'][0], "/en/?test=")

def test_query_param_with_value(self):
request = self.request_factory.get('/en/?test=abc')
context = Context({'request': request})

rendered_template = google_analytics(context, tracking_code='my-code')

parsed_qs = parse_qs(rendered_template)
self.assertEqual(parsed_qs['tracking_code'][0], "my-code")
self.assertEqual(parsed_qs['p'][0], "/en/?test=abc")

def test_query_param_with_multiple_values_with_same_key(self):
request = self.request_factory.get('/en/?test=abc&test=xyz')
context = Context({'request': request})

rendered_template = google_analytics(context, tracking_code='my-code')

parsed_qs = parse_qs(rendered_template)
self.assertEqual(parsed_qs['tracking_code'][0], "my-code")
self.assertEqual(parsed_qs['p'][0], "/en/?test=abc&test=xyz")

def test_query_param_with_utm(self):
request = self.request_factory.get(
'/en/?utm_content=content&utm_term=term&utm_source=source&utm_medium=medium&utm_campaign=campaign')
context = Context({'request': request})

rendered_template = google_analytics(context, tracking_code='my-code')

parsed_qs = parse_qs(rendered_template)
self.assertEqual(parsed_qs['tracking_code'][0], "my-code")
self.assertEqual(parsed_qs['p'][0], "/en/")
self.assertEqual(parsed_qs['utm_content'][0], "content")
self.assertEqual(parsed_qs['utm_term'][0], "term")
self.assertEqual(parsed_qs['utm_source'][0], "source")
self.assertEqual(parsed_qs['utm_medium'][0], "medium")
self.assertEqual(parsed_qs['utm_campaign'][0], "campaign")
SVGToPNGMap.create(self.svg_path, fill_color="#555", stroke_color="#666")
13 changes: 0 additions & 13 deletions iogt/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,6 @@
import iogt.iogt_globals as globals_


class CacheControlMiddleware:
def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
response = self.get_response(request)

if SiteSettings.for_request(request).opt_in_to_google_web_light:
response['Cache-Control'] = 'no-transform'

return response


class LocaleMiddleware(DjangoLocaleMiddleware):
def _get_language_from_request(self, request, check_path=False):
if check_path:
Expand Down
2 changes: 0 additions & 2 deletions iogt/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@
'health_check.storage',
'health_check.contrib.migrations',
'rest_framework_simplejwt',
'google_analytics',
'django_filters',
'drf_yasg',
'webpush',
Expand Down Expand Up @@ -115,7 +114,6 @@
'iogt.middleware.CustomRedirectMiddleware',
'iogt_users.middlewares.RegistrationSurveyRedirectMiddleware',
'external_links.middleware.RewriteExternalLinksMiddleware',
'iogt.middleware.CacheControlMiddleware',
'iogt.middleware.GlobalDataMiddleware',
'wagtailcache.cache.FetchFromCacheMiddleware',
]
Expand Down
2 changes: 0 additions & 2 deletions iogt/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
{% include 'google_analytics_tag_manager.html' %}
<meta charset="utf-8"/>
<meta name="vapid-key" content="{{ vapid_public_key }}">
<title>
Expand Down Expand Up @@ -50,7 +49,6 @@

{% get_current_language_bidi as LANGUAGE_BIDI %}
<body class="{% if LANGUAGE_BIDI %}rtl{% endif %} {% block body_class %}{% endblock %}">
{% include 'google_analytics_pixel_tracking.html' %}
{% wagtailuserbar %}

<main id="app">
Expand Down
Loading

0 comments on commit 5f293f2

Please sign in to comment.