7

Merge preakholt changes

This commit is contained in:
Paul J Stevens
2019-03-15 11:15:31 +01:00
14 changed files with 131 additions and 36 deletions

1
.gitignore vendored
View File

@ -13,6 +13,7 @@
.vscode/ .vscode/
build/ build/
ve/
dist/ dist/
htmlcov/ htmlcov/
docs/_build docs/_build

View File

@ -14,6 +14,8 @@ matrix:
env: TOXENV=py36-django20-wagtail21 env: TOXENV=py36-django20-wagtail21
- python: 3.6 - python: 3.6
env: TOXENV=py36-django20-wagtail21-geoip2 env: TOXENV=py36-django20-wagtail21-geoip2
- python: 3.6
env: TOXENV=py36-django111-wagtail22
install: install:
- pip install tox codecov - pip install tox codecov

10
CHANGES
View File

@ -1,10 +1,18 @@
0.13.0
=================
- Merged Praekolt fork
- Add custom javascript to segment forms
- bugfix:exclude variant returns queryset when params is queryset
- Added RulePanel, a subclass of InlinePanel, for Rules
- Upgrade to Wagtail > 2.0, drop support for Wagtail < 2
0.12.0 0.12.0
================== ==================
- Fix Django version classifier in setup.py - Fix Django version classifier in setup.py
0.12.0 0.12.0
================== ==================
- Merged forks of Torchbox and Praekelt - Merged forks of Torchbox and Praekolt
- Wagtail 2 compatibility - Wagtail 2 compatibility
- Makefile adjustments for portability - Makefile adjustments for portability
- Adds simple segment forcing for superusers - Adds simple segment forcing for superusers

1
VERSON Normal file
View File

@ -0,0 +1 @@
1.0.3

View File

@ -54,7 +54,7 @@ master_doc = 'index'
# General information about the project. # General information about the project.
project = 'wagtail-personalisation' project = 'wagtail-personalisation'
copyright = '2018, Lab Digital BV' copyright = '2019, Lab Digital BV'
author = 'Lab Digital BV' author = 'Lab Digital BV'
# The version info for the project you're documenting, acts as replacement for # The version info for the project you're documenting, acts as replacement for

View File

@ -2,7 +2,7 @@ import re
from setuptools import find_packages, setup from setuptools import find_packages, setup
install_requires = [ install_requires = [
'wagtail>=2.0', 'wagtail>=2.0,<2.3',
'user-agents>=1.1.0', 'user-agents>=1.1.0',
'wagtailfontawesome>=1.1.3', 'wagtailfontawesome>=1.1.3',
'pycountry', 'pycountry',
@ -20,7 +20,7 @@ tests_require = [
'pytest-pythonpath==0.7.2', 'pytest-pythonpath==0.7.2',
'pytest-sugar==0.9.1', 'pytest-sugar==0.9.1',
'pytest==3.4.2', 'pytest==3.4.2',
'wagtail_factories==1.0.0', 'wagtail_factories==1.1.0',
'pytest-mock==1.6.3', 'pytest-mock==1.6.3',
] ]
@ -52,7 +52,7 @@ setup(
license='MIT', license='MIT',
long_description=long_description, long_description=long_description,
classifiers=[ classifiers=[
'Development Status :: 2 - Pre-Alpha', 'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment', 'Environment :: Web Environment',
'Intended Audience :: Developers', 'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License', 'License :: OSI Approved :: BSD License',

View File

@ -1,16 +1,15 @@
import random import random
import wagtail
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from django.core.validators import MaxValueValidator, MinValueValidator from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models, transaction from django.db import models, transaction
from django.template.defaultfilters import slugify from django.template.defaultfilters import slugify
from django.utils.encoding import python_2_unicode_compatible
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from modelcluster.models import ClusterableModel from modelcluster.models import ClusterableModel
import wagtail
from wagtail.admin.edit_handlers import ( from wagtail.admin.edit_handlers import (
FieldPanel, FieldRowPanel, InlinePanel, MultiFieldPanel) FieldPanel, FieldRowPanel, InlinePanel, MultiFieldPanel)
from wagtail.core.models import Page from wagtail.core.models import Page
@ -21,12 +20,19 @@ from wagtail_personalisation.utils import count_active_days
from .forms import SegmentAdminForm from .forms import SegmentAdminForm
class RulePanel(InlinePanel):
def on_model_bound(self):
self.db_field = self.model._meta.get_field(
self.relation_name.replace('_related', 's'))
manager = getattr(self.model, self.relation_name)
self.related = manager.rel
class SegmentQuerySet(models.QuerySet): class SegmentQuerySet(models.QuerySet):
def enabled(self): def enabled(self):
return self.filter(status=self.model.STATUS_ENABLED) return self.filter(status=self.model.STATUS_ENABLED)
@python_2_unicode_compatible
class Segment(ClusterableModel): class Segment(ClusterableModel):
"""The segment model.""" """The segment model."""
STATUS_ENABLED = 'enabled' STATUS_ENABLED = 'enabled'
@ -121,8 +127,8 @@ class Segment(ClusterableModel):
FieldPanel('randomisation_percent', classname='percent_field'), FieldPanel('randomisation_percent', classname='percent_field'),
], heading="Segment"), ], heading="Segment"),
MultiFieldPanel([ MultiFieldPanel([
InlinePanel( RulePanel(
"{}s".format(rule_model._meta.db_table), "{}_related".format(rule_model._meta.db_table),
label='{}{}'.format( label='{}{}'.format(
rule_model._meta.verbose_name, rule_model._meta.verbose_name,
' ({})'.format(_('Static compatible')) if rule_model.static else '' ' ({})'.format(_('Static compatible')) if rule_model.static else ''

View File

@ -1,5 +1,3 @@
from __future__ import absolute_import, unicode_literals
import csv import csv
from django import forms from django import forms
@ -87,7 +85,10 @@ class SegmentModelAdmin(ModelAdmin):
'page_count', 'variant_count', 'statistics') 'page_count', 'variant_count', 'statistics')
index_view_extra_js = ['js/commons.js', 'js/index.js'] index_view_extra_js = ['js/commons.js', 'js/index.js']
index_view_extra_css = ['css/index.css'] index_view_extra_css = ['css/index.css']
form_view_extra_js = ['js/commons.js', 'js/form.js'] form_view_extra_js = ['js/commons.js', 'js/form.js',
'js/segment_form_control.js',
'wagtailadmin/js/page-chooser-modal.js',
'wagtailadmin/js/page-chooser.js']
form_view_extra_css = ['css/form.css'] form_view_extra_css = ['css/form.css']
def index_view(self, request): def index_view(self, request):

View File

@ -1,5 +1,3 @@
from __future__ import absolute_import, unicode_literals
import logging import logging
from django.conf.urls import include, url from django.conf.urls import include, url
@ -227,8 +225,7 @@ class PersonalisedPagesSummaryPanel(PagesSummaryItem):
order = 2100 order = 2100
def render(self): def render(self):
page_count = models.PersonalisablePageMetadata.objects.filter( page_count = models.PersonalisablePageMetadata.objects.filter(segment__isnull=True).count()
segment__isnull=True).count()
title = _("Personalised Page") title = _("Personalised Page")
return mark_safe(""" return mark_safe("""
<li class="icon icon-fa-file-o"> <li class="icon icon-fa-file-o">

View File

@ -1,5 +1,3 @@
from __future__ import absolute_import, unicode_literals
import pytest import pytest
pytest_plugins = [ pytest_plugins = [
@ -7,6 +5,11 @@ pytest_plugins = [
] ]
@pytest.fixture(autouse=True)
def enable_db_access(db):
pass
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def django_db_setup(django_db_setup, django_db_blocker): def django_db_setup(django_db_setup, django_db_blocker):
from wagtail.core.models import Page, Site from wagtail.core.models import Page, Site

View File

@ -1,6 +1,7 @@
from __future__ import absolute_import, unicode_literals
import os import os
from distutils.version import StrictVersion as V
import django
DATABASES = { DATABASES = {
'default': { 'default': {
@ -52,16 +53,27 @@ TEMPLATES = [
}, },
] ]
MIDDLEWARE = (
def get_middleware_settings():
return (
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'wagtail.core.middleware.SiteMiddleware', 'wagtail.core.middleware.SiteMiddleware',
) )
# Django 1.10 started to use "MIDDLEWARE" instead of "MIDDLEWARE_CLASSES".
if V(django.get_version()) < V('1.10'):
MIDDLEWARE_CLASSES = get_middleware_settings()
else:
MIDDLEWARE = get_middleware_settings()
INSTALLED_APPS = ( INSTALLED_APPS = (
'wagtail_personalisation', 'wagtail_personalisation',

View File

@ -1,5 +1,3 @@
from __future__ import absolute_import, unicode_literals
import datetime import datetime
import pytest import pytest
@ -8,7 +6,7 @@ from django.db.models import ProtectedError
from tests.factories.page import ContentPageFactory from tests.factories.page import ContentPageFactory
from tests.factories.segment import SegmentFactory from tests.factories.segment import SegmentFactory
from tests.site.pages import models from tests.site.pages import models
from wagtail_personalisation.models import PersonalisablePageMetadata from wagtail_personalisation.models import PersonalisablePageMetadata, Segment
from wagtail_personalisation.rules import TimeRule from wagtail_personalisation.rules import TimeRule
@ -73,3 +71,10 @@ def test_sitemap_generation_for_canonical_pages_is_enabled(segmented_page):
def test_sitemap_generation_for_variants_is_disabled(segmented_page): def test_sitemap_generation_for_variants_is_disabled(segmented_page):
assert not segmented_page.personalisation_metadata.is_canonical assert not segmented_page.personalisation_metadata.is_canonical
assert not segmented_page.get_sitemap_urls() assert not segmented_page.get_sitemap_urls()
@pytest.mark.django_db
def test_segment_edit_view(site, client, django_user_model):
test_segment = Segment()
new_panel = test_segment.panels[1].children[0].bind_to_model(Segment)
assert new_panel.related.name == "wagtail_personalisation_timerules"

View File

@ -3,8 +3,14 @@ import pytest
from django.test import override_settings from django.test import override_settings
from tests.factories.page import ContentPageFactory from tests.factories.page import ContentPageFactory
from wagtail.core.models import Page as WagtailPage
from wagtail_personalisation.utils import ( from wagtail_personalisation.utils import (
can_delete_pages, get_client_ip, impersonate_other_page) can_delete_pages, get_client_ip, impersonate_other_page, exclude_variants)
class Metadata:
def __init__(self, is_canonical=True):
self.is_canonical = is_canonical
@pytest.fixture @pytest.fixture
@ -64,3 +70,54 @@ def test_get_client_ip_custom_get_client_ip_function_does_not_exist(rf):
) )
def test_get_client_ip_custom_get_client_ip_used(rf): def test_get_client_ip_custom_get_client_ip_used(rf):
assert get_client_ip(rf.get('/')) == '123.123.123.123' assert get_client_ip(rf.get('/')) == '123.123.123.123'
def test_exclude_variants_with_pages_querysets():
'''
Test that excludes variant works for querysets
'''
for i in range(5):
page = WagtailPage(path="/" + str(i), depth=0, url_path="/", title="Hoi " + str(i))
page.save()
pages = WagtailPage.objects.all().order_by('id')
result = exclude_variants(pages)
assert type(result) == type(pages)
assert result == pages
def test_exclude_variants_with_pages_querysets_not_canonical():
'''
Test that excludes variant works for querysets with
personalisation_metadata canonical False
'''
for i in range(5):
page = WagtailPage(path="/" + str(i), depth=0, url_path="/", title="Hoi " + str(i))
page.save()
pages = WagtailPage.objects.all().order_by('id')
# add variants
for page in pages:
page.personalisation_metadata = Metadata(is_canonical=False)
page.save()
result = exclude_variants(pages)
assert type(result) == type(pages)
assert result.count() == 0
def test_exclude_variants_with_pages_querysets_meta_none():
'''
Test that excludes variant works for querysets with meta as none
'''
for i in range(5):
page = WagtailPage(path="/" + str(i), depth=0, url_path="/", title="Hoi " + str(i))
page.save()
pages = WagtailPage.objects.all().order_by('id')
# add variants
for page in pages:
page.personalisation_metadata = None
page.save()
result = exclude_variants(pages)
assert type(result) == type(pages)
assert result == pages

View File

@ -1,5 +1,5 @@
[tox] [tox]
envlist = py{36}-django{20}-wagtail{20,21}{,-geoip2},lint envlist = py{36}-django{111,20}-wagtail{20,21,22}{,-geoip2},lint
[testenv] [testenv]
basepython = python3.6 basepython = python3.6
@ -9,7 +9,9 @@ deps =
django20: django>=2.0,<2.1 django20: django>=2.0,<2.1
wagtail20: wagtail>=2.0,<2.1 wagtail20: wagtail>=2.0,<2.1
wagtail21: wagtail>=2.1,<2.2 wagtail21: wagtail>=2.1,<2.2
wagtail22: wagtail>=2.2,<2.3
geoip2: geoip2 geoip2: geoip2
django111: django>=1.11,<1.12
[testenv:coverage-report] [testenv:coverage-report]
basepython = python3.6 basepython = python3.6
@ -21,7 +23,7 @@ commands =
[testenv:lint] [testenv:lint]
basepython = python3.6 basepython = python3.6
deps = flake8 deps = flake8==3.5.0
commands = commands =
flake8 src tests setup.py flake8 src tests setup.py
isort -q --recursive --diff src/ tests/ isort -q --recursive --diff src/ tests/