diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..39fd6e0 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{scss,sass}] +indent_size = 2 + +[*.{yml,yaml}] +indent_size = 2 + +[*.js] +indent_size = 2 + +[Makefile] +indent_style = tab diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cbb206f..6b4913f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,3 +43,26 @@ jobs: uses: codecov/codecov-action@v3 with: directory: reports/ + + e2e_tests: + runs-on: ubuntu-latest + name: Run the end-to-end tests + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + + - name: Install dependencies + run: | + pip install tox tox-gh-actions pytest-playwright + playwright install --with-deps + + - name: Run tests + run: tox -e e2e + + - name: Publish coverage report + uses: codecov/codecov-action@v3 + with: + directory: reports/ diff --git a/.gitignore b/.gitignore index b0196e7..9751be2 100644 --- a/.gitignore +++ b/.gitignore @@ -19,5 +19,6 @@ dist/ .tox/ .pytest_cache .coverage +htmlcov/ reports/ testapp/*.db diff --git a/cookie_consent/cache.py b/cookie_consent/cache.py index 674007d..50f8fb4 100644 --- a/cookie_consent/cache.py +++ b/cookie_consent/cache.py @@ -31,7 +31,10 @@ def all_cookie_groups(): qs = CookieGroup.objects.filter(is_required=False) qs = qs.prefetch_related("cookie_set") - items = dict([(g.varname, g) for g in qs]) + # items = qs.in_bulk(field_name="varname") + # FIXME -> doesn't work because varname is not a unique fieldl, we need to + # make this unique + items = {group.varname: group for group in qs} cache.set(CACHE_KEY, items, CACHE_TIMEOUT) return items diff --git a/cookie_consent/compat.py b/cookie_consent/compat.py index 9c105a7..8e207da 100644 --- a/cookie_consent/compat.py +++ b/cookie_consent/compat.py @@ -9,3 +9,5 @@ from django.contrib.auth.views import ( SuccessURLAllowedHostsMixin as RedirectURLMixin, ) + +__all__ = ["url_has_allowed_host_and_scheme", "RedirectURLMixin"] diff --git a/cookie_consent/models.py b/cookie_consent/models.py index b3f5f06..c099328 100644 --- a/cookie_consent/models.py +++ b/cookie_consent/models.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- import re +from typing import TypedDict from django.core.validators import RegexValidator from django.db import models @@ -18,6 +19,16 @@ ) +class CookieGroupDict(TypedDict): + varname: str + name: str + description: str + is_required: bool + # TODO: should we output this? page cache busting would be + # required if we do this. Alternatively, set up a JSONView to output these? + # version: str + + class CookieGroup(models.Model): varname = models.CharField( _("Variable name"), max_length=32, validators=[validate_cookie_name] @@ -45,7 +56,7 @@ class Meta: def __str__(self): return self.name - def get_version(self): + def get_version(self) -> str: try: return str(self.cookie_set.all()[0].get_version()) except IndexError: @@ -59,6 +70,15 @@ def save(self, *args, **kwargs): super(CookieGroup, self).save(*args, **kwargs) delete_cache() + def for_json(self) -> CookieGroupDict: + return { + "varname": self.varname, + "name": self.name, + "description": self.description, + "is_required": self.is_required, + # "version": self.get_version(), + } + class Cookie(models.Model): cookiegroup = models.ForeignKey( diff --git a/cookie_consent/static/cookie_consent/cookiebar.js b/cookie_consent/static/cookie_consent/cookiebar.js index f87ef67..bcb9dfe 100644 --- a/cookie_consent/static/cookie_consent/cookiebar.js +++ b/cookie_consent/static/cookie_consent/cookiebar.js @@ -10,7 +10,7 @@ function evalXCookieConsent(script) { script.remove(); } -function showCookieBar (options) { +function lecacyShowCookieBar (options) { const defaults = { content: '', cookie_groups: [], @@ -64,3 +64,4 @@ function showCookieBar (options) { }); } +window.legacyShowCookieBar = window.showCookieBar = lecacyShowCookieBar; diff --git a/cookie_consent/static/cookie_consent/cookiebar.module.js b/cookie_consent/static/cookie_consent/cookiebar.module.js new file mode 100644 index 0000000..af27203 --- /dev/null +++ b/cookie_consent/static/cookie_consent/cookiebar.module.js @@ -0,0 +1,203 @@ +/** + * Cookiebar functionality, as a Javascript module. + * + * About modules: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules + * + * The code is organized here in a way to make the templates work with Django's page + * cache. This means that anything user-specific (so different django session and even + * cookie consent cookies) cannot be baked into the templates, as that breaks caches. + * + * The cookie bar operates on the following principles: + * + * - The developer using the library includes the desired template in their django + * templates, using the HTML