Codestyle fixes (flake8)
This also adds the flake8 dependencies to the test extras for installation.
This commit is contained in:
@@ -11,10 +11,12 @@ line_length = 79
|
|||||||
multi_line_output = 4
|
multi_line_output = 4
|
||||||
balanced_wrapping = true
|
balanced_wrapping = true
|
||||||
use_parentheses = true
|
use_parentheses = true
|
||||||
|
default_section = THIRDPARTY
|
||||||
|
known_first_party = wagtail_personalisation,tests
|
||||||
|
|
||||||
[*.json, *.yml, *rc]
|
[*.json, *.yml, *rc]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
[Makefile]
|
[Makefile]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
7
Makefile
7
Makefile
@@ -10,7 +10,7 @@ clean:
|
|||||||
find . -name '*.egg-info' -delete
|
find . -name '*.egg-info' -delete
|
||||||
|
|
||||||
requirements:
|
requirements:
|
||||||
pip install --upgrade -e .[test]
|
pip install --upgrade -e .[docs,test]
|
||||||
|
|
||||||
install: develop
|
install: develop
|
||||||
|
|
||||||
@@ -28,18 +28,15 @@ coverage:
|
|||||||
lint: flake8 isort
|
lint: flake8 isort
|
||||||
|
|
||||||
flake8:
|
flake8:
|
||||||
pip install flake8 flake8-debugger flake8-blind-except
|
flake8 src/ tests/
|
||||||
flake8 src/
|
|
||||||
|
|
||||||
isort:
|
isort:
|
||||||
pip install isort
|
pip install isort
|
||||||
isort --recursive src tests
|
isort --recursive src tests
|
||||||
|
|
||||||
|
|
||||||
dist:
|
dist:
|
||||||
./setup.py sdist bdist_wheel
|
./setup.py sdist bdist_wheel
|
||||||
|
|
||||||
|
|
||||||
sandbox:
|
sandbox:
|
||||||
pip install -r sandbox/requirements.txt
|
pip install -r sandbox/requirements.txt
|
||||||
sandbox/manage.py migrate
|
sandbox/manage.py migrate
|
||||||
|
10
setup.py
10
setup.py
@@ -7,12 +7,16 @@ install_requires = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
tests_require = [
|
tests_require = [
|
||||||
'pytest==3.1.0',
|
'factory_boy==2.8.1',
|
||||||
|
'flake8',
|
||||||
|
'flake8-blind-except',
|
||||||
|
'flake8-debugger',
|
||||||
|
'flake8-imports',
|
||||||
|
'freezegun==0.3.8',
|
||||||
'pytest-cov==2.4.0',
|
'pytest-cov==2.4.0',
|
||||||
'pytest-django==3.1.2',
|
'pytest-django==3.1.2',
|
||||||
'pytest-sugar==0.7.1',
|
'pytest-sugar==0.7.1',
|
||||||
'freezegun==0.3.8',
|
'pytest==3.1.0',
|
||||||
'factory_boy==2.8.1',
|
|
||||||
'wagtail_factories==0.3.0',
|
'wagtail_factories==0.3.0',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
from django.db.models import F
|
from django.db.models import F
|
||||||
|
|
||||||
from wagtail_personalisation.models import Segment
|
from wagtail_personalisation.models import Segment
|
||||||
from wagtail_personalisation.rules import AbstractBaseRule
|
from wagtail_personalisation.rules import AbstractBaseRule
|
||||||
from wagtail_personalisation.utils import create_segment_dictionary
|
from wagtail_personalisation.utils import create_segment_dictionary
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from wagtail_personalisation import models, rules
|
from wagtail_personalisation import models, rules
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|
||||||
from wagtail_personalisation import views
|
from wagtail_personalisation import views
|
||||||
|
|
||||||
app_name = 'segment'
|
app_name = 'segment'
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from wagtail_personalisation.models import Segment
|
|
||||||
from wagtail.wagtailcore import blocks
|
from wagtail.wagtailcore import blocks
|
||||||
|
|
||||||
|
from wagtail_personalisation.models import Segment
|
||||||
|
|
||||||
|
|
||||||
def list_segment_choices():
|
def list_segment_choices():
|
||||||
for segment in Segment.objects.all():
|
for segment in Segment.objects.all():
|
||||||
|
@@ -77,7 +77,7 @@ class Segment(ClusterableModel):
|
|||||||
class PersonalisablePage(Page):
|
class PersonalisablePage(Page):
|
||||||
"""The personalisable page model. Allows creation of variants with linked
|
"""The personalisable page model. Allows creation of variants with linked
|
||||||
segments.
|
segments.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
canonical_page = models.ForeignKey(
|
canonical_page = models.ForeignKey(
|
||||||
'self', related_name='variations', on_delete=models.SET_NULL,
|
'self', related_name='variations', on_delete=models.SET_NULL,
|
||||||
@@ -130,7 +130,7 @@ class PersonalisablePage(Page):
|
|||||||
def get_edit_handler(cls):
|
def get_edit_handler(cls):
|
||||||
"""Add additional edit handlers to pages that are allowed to have
|
"""Add additional edit handlers to pages that are allowed to have
|
||||||
variations.
|
variations.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
tabs = []
|
tabs = []
|
||||||
if cls.content_panels:
|
if cls.content_panels:
|
||||||
|
@@ -36,10 +36,10 @@ class AbstractBaseRule(models.Model):
|
|||||||
def description(self):
|
def description(self):
|
||||||
"""Return a description explaining the functionality of the rule.
|
"""Return a description explaining the functionality of the rule.
|
||||||
Used in the segmentation dashboard.
|
Used in the segmentation dashboard.
|
||||||
|
|
||||||
:returns: A dict containing a title and a value
|
:returns: A dict containing a title and a value
|
||||||
:rtype: dict
|
:rtype: dict
|
||||||
|
|
||||||
"""
|
"""
|
||||||
description = {
|
description = {
|
||||||
'title': _('Abstract segmentation rule'),
|
'title': _('Abstract segmentation rule'),
|
||||||
@@ -55,10 +55,10 @@ class AbstractBaseRule(models.Model):
|
|||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class TimeRule(AbstractBaseRule):
|
class TimeRule(AbstractBaseRule):
|
||||||
"""Time rule to segment users based on a start and end time.
|
"""Time rule to segment users based on a start and end time.
|
||||||
|
|
||||||
Matches when the time a request is made falls between the
|
Matches when the time a request is made falls between the
|
||||||
set start time and end time.
|
set start time and end time.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
start_time = models.TimeField(_("Starting time"))
|
start_time = models.TimeField(_("Starting time"))
|
||||||
end_time = models.TimeField(_("Ending time"))
|
end_time = models.TimeField(_("Ending time"))
|
||||||
@@ -98,10 +98,10 @@ class TimeRule(AbstractBaseRule):
|
|||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class DayRule(AbstractBaseRule):
|
class DayRule(AbstractBaseRule):
|
||||||
"""Day rule to segment users based on the day(s) of a visit.
|
"""Day rule to segment users based on the day(s) of a visit.
|
||||||
|
|
||||||
Matches when the day a request is made matches with the days
|
Matches when the day a request is made matches with the days
|
||||||
set in the rule.
|
set in the rule.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
mon = models.BooleanField(_("Monday"), default=False)
|
mon = models.BooleanField(_("Monday"), default=False)
|
||||||
tue = models.BooleanField(_("Tuesday"), default=False)
|
tue = models.BooleanField(_("Tuesday"), default=False)
|
||||||
@@ -159,10 +159,10 @@ class DayRule(AbstractBaseRule):
|
|||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class ReferralRule(AbstractBaseRule):
|
class ReferralRule(AbstractBaseRule):
|
||||||
"""Referral rule to segment users based on a regex test.
|
"""Referral rule to segment users based on a regex test.
|
||||||
|
|
||||||
Matches when the referral header in a request matches with
|
Matches when the referral header in a request matches with
|
||||||
the set regex test.
|
the set regex test.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
regex_string = models.TextField(
|
regex_string = models.TextField(
|
||||||
_("Regex string to match the referer with"))
|
_("Regex string to match the referer with"))
|
||||||
@@ -202,10 +202,10 @@ class ReferralRule(AbstractBaseRule):
|
|||||||
class VisitCountRule(AbstractBaseRule):
|
class VisitCountRule(AbstractBaseRule):
|
||||||
"""Visit count rule to segment users based on amount of visits to a
|
"""Visit count rule to segment users based on amount of visits to a
|
||||||
specified page.
|
specified page.
|
||||||
|
|
||||||
Matches when the operator and count validate True
|
Matches when the operator and count validate True
|
||||||
when visiting the set page.
|
when visiting the set page.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
OPERATOR_CHOICES = (
|
OPERATOR_CHOICES = (
|
||||||
('more_than', _("More than")),
|
('more_than', _("More than")),
|
||||||
@@ -241,13 +241,13 @@ class VisitCountRule(AbstractBaseRule):
|
|||||||
def get_visit_count(request):
|
def get_visit_count(request):
|
||||||
"""Search through the request sessions to get the page visit count
|
"""Search through the request sessions to get the page visit count
|
||||||
corresponding to the request.
|
corresponding to the request.
|
||||||
|
|
||||||
:param request: The http request
|
:param request: The http request
|
||||||
:type request: django.http.HttpRequest
|
:type request: django.http.HttpRequest
|
||||||
:returns: A number indicating the amount of visits
|
:returns: A number indicating the amount of visits
|
||||||
to the requested page
|
to the requested page
|
||||||
:rtype: int
|
:rtype: int
|
||||||
|
|
||||||
"""
|
"""
|
||||||
for page in request.session['visit_count']:
|
for page in request.session['visit_count']:
|
||||||
if page['path'] == request.path:
|
if page['path'] == request.path:
|
||||||
@@ -286,10 +286,10 @@ class VisitCountRule(AbstractBaseRule):
|
|||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class QueryRule(AbstractBaseRule):
|
class QueryRule(AbstractBaseRule):
|
||||||
"""Query rule to segment users based on matching queries.
|
"""Query rule to segment users based on matching queries.
|
||||||
|
|
||||||
Matches when both the set parameter and value match with one
|
Matches when both the set parameter and value match with one
|
||||||
present in the request query.
|
present in the request query.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
parameter = models.SlugField(_("The query parameter to search for"),
|
parameter = models.SlugField(_("The query parameter to search for"),
|
||||||
max_length=20)
|
max_length=20)
|
||||||
@@ -332,10 +332,10 @@ class QueryRule(AbstractBaseRule):
|
|||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class DeviceRule(AbstractBaseRule):
|
class DeviceRule(AbstractBaseRule):
|
||||||
"""Device rule to segment users based on matching devices.
|
"""Device rule to segment users based on matching devices.
|
||||||
|
|
||||||
Matches when the set device type matches with the one present
|
Matches when the set device type matches with the one present
|
||||||
in the request user agent headers.
|
in the request user agent headers.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
mobile = models.BooleanField(_("Mobile phone"), default=False)
|
mobile = models.BooleanField(_("Mobile phone"), default=False)
|
||||||
tablet = models.BooleanField(_("Tablet"), default=False)
|
tablet = models.BooleanField(_("Tablet"), default=False)
|
||||||
@@ -371,9 +371,9 @@ class DeviceRule(AbstractBaseRule):
|
|||||||
class UserIsLoggedInRule(AbstractBaseRule):
|
class UserIsLoggedInRule(AbstractBaseRule):
|
||||||
"""User is logged in rule to segment users based on their authentication
|
"""User is logged in rule to segment users based on their authentication
|
||||||
status.
|
status.
|
||||||
|
|
||||||
Matches when the user is authenticated.
|
Matches when the user is authenticated.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
is_logged_in = models.BooleanField(default=False)
|
is_logged_in = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
from django.template import Library
|
from django.template import Library
|
||||||
|
|
||||||
from wagtail_personalisation.app_settings import segments_adapter
|
from wagtail_personalisation.app_settings import segments_adapter
|
||||||
|
|
||||||
register = Library()
|
register = Library()
|
||||||
|
@@ -4,12 +4,12 @@ import time
|
|||||||
def impersonate_other_page(page, other_page):
|
def impersonate_other_page(page, other_page):
|
||||||
"""Function to change the page metadata so the user gets to see the
|
"""Function to change the page metadata so the user gets to see the
|
||||||
non-personalized path and page.
|
non-personalized path and page.
|
||||||
|
|
||||||
:param page: The page to be impersonated
|
:param page: The page to be impersonated
|
||||||
:type page: personalisation.models.PersonalisablePage
|
:type page: personalisation.models.PersonalisablePage
|
||||||
:param other_page: The page it should impersonate
|
:param other_page: The page it should impersonate
|
||||||
:type other_page: personalisation.models.PersonalisablePage
|
:type other_page: personalisation.models.PersonalisablePage
|
||||||
|
|
||||||
"""
|
"""
|
||||||
page.path = other_page.path
|
page.path = other_page.path
|
||||||
page.depth = other_page.depth
|
page.depth = other_page.depth
|
||||||
@@ -19,12 +19,12 @@ def impersonate_other_page(page, other_page):
|
|||||||
|
|
||||||
def create_segment_dictionary(segment):
|
def create_segment_dictionary(segment):
|
||||||
"""Creates a dictionary with all the required segment information.
|
"""Creates a dictionary with all the required segment information.
|
||||||
|
|
||||||
:param segment: Segment object
|
:param segment: Segment object
|
||||||
:type segment: personalisation.models.Segment
|
:type segment: personalisation.models.Segment
|
||||||
:return: Dictionary with name, id, timestamp and persistent state.
|
:return: Dictionary with name, id, timestamp and persistent state.
|
||||||
:rtype: dict
|
:rtype: dict
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
"encoded_name": segment.encoded_name(),
|
"encoded_name": segment.encoded_name(),
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
from django.http import HttpResponseRedirect, HttpResponseForbidden
|
from django.http import HttpResponseForbidden, HttpResponseRedirect
|
||||||
from django.shortcuts import get_object_or_404, reverse
|
from django.shortcuts import get_object_or_404, reverse
|
||||||
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
|
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
|
||||||
from wagtail.contrib.modeladmin.views import IndexView
|
from wagtail.contrib.modeladmin.views import IndexView
|
||||||
@@ -13,6 +13,7 @@ class SegmentModelIndexView(IndexView):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@modeladmin_register
|
||||||
class SegmentModelAdmin(ModelAdmin):
|
class SegmentModelAdmin(ModelAdmin):
|
||||||
"""The model admin for the Segments administration interface."""
|
"""The model admin for the Segments administration interface."""
|
||||||
model = Segment
|
model = Segment
|
||||||
@@ -25,8 +26,6 @@ class SegmentModelAdmin(ModelAdmin):
|
|||||||
form_view_extra_js = ['js/commons.js', 'js/form.js']
|
form_view_extra_js = ['js/commons.js', 'js/form.js']
|
||||||
form_view_extra_css = ['css/form.css']
|
form_view_extra_css = ['css/form.css']
|
||||||
|
|
||||||
modeladmin_register(SegmentModelAdmin)
|
|
||||||
|
|
||||||
|
|
||||||
def toggle(request, segment_id):
|
def toggle(request, segment_id):
|
||||||
"""Toggle the status of the selected segment.
|
"""Toggle the status of the selected segment.
|
||||||
@@ -56,7 +55,7 @@ def toggle(request, segment_id):
|
|||||||
|
|
||||||
def copy_page_view(request, page_id, segment_id):
|
def copy_page_view(request, page_id, segment_id):
|
||||||
"""Copy page with selected segment.
|
"""Copy page with selected segment.
|
||||||
|
|
||||||
:param request: The http request
|
:param request: The http request
|
||||||
:type request: django.http.HttpRequest
|
:type request: django.http.HttpRequest
|
||||||
:param page_id: The primary key of the page
|
:param page_id: The primary key of the page
|
||||||
@@ -65,7 +64,7 @@ def copy_page_view(request, page_id, segment_id):
|
|||||||
:type segment_id: int
|
:type segment_id: int
|
||||||
:returns: A redirect to the new page
|
:returns: A redirect to the new page
|
||||||
:rtype: django.http.HttpResponseRedirect
|
:rtype: django.http.HttpResponseRedirect
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if request.user.has_perm('wagtailadmin.access_admin'):
|
if request.user.has_perm('wagtailadmin.access_admin'):
|
||||||
segment = get_object_or_404(Segment, pk=segment_id)
|
segment = get_object_or_404(Segment, pk=segment_id)
|
||||||
|
@@ -51,7 +51,7 @@ def set_visit_count(page, request, serve_args, serve_kwargs):
|
|||||||
:type page: wagtail.wagtailcore.models.Page
|
:type page: wagtail.wagtailcore.models.Page
|
||||||
:param request: The http request
|
:param request: The http request
|
||||||
:type request: django.http.HttpRequest
|
:type request: django.http.HttpRequest
|
||||||
|
|
||||||
"""
|
"""
|
||||||
countdict = {
|
countdict = {
|
||||||
"slug": page.slug,
|
"slug": page.slug,
|
||||||
@@ -129,7 +129,7 @@ def serve_variation(page, request, serve_args, serve_kwargs):
|
|||||||
def _check_for_variations(segments, page):
|
def _check_for_variations(segments, page):
|
||||||
"""Check whether there are variations available for the provided segments
|
"""Check whether there are variations available for the provided segments
|
||||||
on the page being served.
|
on the page being served.
|
||||||
|
|
||||||
:param segments: The segments applicable to the request.
|
:param segments: The segments applicable to the request.
|
||||||
:type segments: list of personalisation.models.Segment
|
:type segments: list of personalisation.models.Segment
|
||||||
:param page: The page being served
|
:param page: The page being served
|
||||||
@@ -157,7 +157,7 @@ def _check_for_variations(segments, page):
|
|||||||
def page_listing_variant_buttons(page, page_perms, is_parent=False):
|
def page_listing_variant_buttons(page, page_perms, is_parent=False):
|
||||||
"""Adds page listing buttons to personalisable pages. Shows variants for
|
"""Adds page listing buttons to personalisable pages. Shows variants for
|
||||||
the page (if any) and a 'Create a new variant' button.
|
the page (if any) and a 'Create a new variant' button.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
personalisable_page = PersonalisablePage.objects.filter(pk=page.pk)
|
personalisable_page = PersonalisablePage.objects.filter(pk=page.pk)
|
||||||
segments = Segment.objects.all()
|
segments = Segment.objects.all()
|
||||||
@@ -181,9 +181,10 @@ def page_listing_more_buttons(page, page_perms, is_parent=False):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
segments = Segment.objects.all()
|
segments = Segment.objects.all()
|
||||||
available_segments = [item for item in segments
|
available_segments = [
|
||||||
if not PersonalisablePage.objects.filter(
|
item for item in segments
|
||||||
segment=item, pk=page.pk)]
|
if not PersonalisablePage.objects.filter(segment=item, pk=page.pk)
|
||||||
|
]
|
||||||
|
|
||||||
for segment in available_segments:
|
for segment in available_segments:
|
||||||
yield Button(segment.name,
|
yield Button(segment.name,
|
||||||
@@ -194,7 +195,7 @@ def page_listing_more_buttons(page, page_perms, is_parent=False):
|
|||||||
class SegmentSummaryPanel(SummaryItem):
|
class SegmentSummaryPanel(SummaryItem):
|
||||||
"""The segment summary panel showing the total amount of segments on the
|
"""The segment summary panel showing the total amount of segments on the
|
||||||
site and allowing quick access to the Segment dashboard.
|
site and allowing quick access to the Segment dashboard.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
order = 500
|
order = 500
|
||||||
|
|
||||||
|
@@ -1,11 +1,9 @@
|
|||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
import factory
|
|
||||||
from wagtail.wagtailcore.models import Page
|
|
||||||
from wagtail_factories import PageFactory
|
from wagtail_factories import PageFactory
|
||||||
|
|
||||||
from wagtail_personalisation.models import PersonalisablePage
|
|
||||||
from tests.sandbox.pages.models import HomePage
|
from tests.sandbox.pages.models import HomePage
|
||||||
|
from wagtail_personalisation.models import PersonalisablePage
|
||||||
|
|
||||||
|
|
||||||
class PersonalisablePageFactory(PageFactory):
|
class PersonalisablePageFactory(PageFactory):
|
||||||
|
@@ -2,8 +2,6 @@ from __future__ import absolute_import, unicode_literals
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import django
|
|
||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': os.environ.get('DATABASE_ENGINE', 'django.db.backends.sqlite3'),
|
'ENGINE': os.environ.get('DATABASE_ENGINE', 'django.db.backends.sqlite3'),
|
@@ -1 +0,0 @@
|
|||||||
from .base import * # noqa
|
|
@@ -1,6 +1,5 @@
|
|||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.conf.urls import include, url
|
from django.conf.urls import include, url
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from wagtail.wagtailadmin import urls as wagtailadmin_urls
|
from wagtail.wagtailadmin import urls as wagtailadmin_urls
|
||||||
|
@@ -4,34 +4,43 @@ import datetime
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from tests.factories.rule import (
|
||||||
|
DayRuleFactory, DeviceRuleFactory, ReferralRuleFactory, TimeRuleFactory)
|
||||||
|
from tests.factories.segment import SegmentFactory
|
||||||
from wagtail_personalisation.models import Segment
|
from wagtail_personalisation.models import Segment
|
||||||
from wagtail_personalisation.rules import TimeRule
|
from wagtail_personalisation.rules import TimeRule
|
||||||
from tests.factories.rule import (
|
|
||||||
DayRuleFactory, DeviceRuleFactory, QueryRuleFactory, ReferralRuleFactory,
|
|
||||||
TimeRuleFactory, VisitCountRuleFactory)
|
|
||||||
from tests.factories.segment import SegmentFactory
|
|
||||||
|
|
||||||
"""Factory tests"""
|
|
||||||
|
# Factory tests
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_create_segment_factory():
|
def test_create_segment_factory():
|
||||||
factoried_segment = SegmentFactory()
|
factoried_segment = SegmentFactory()
|
||||||
segment = Segment(name='TestSegment', status='enabled')
|
segment = Segment(name='TestSegment', status='enabled')
|
||||||
time_rule = TimeRule(start_time=datetime.time(8,0,0), end_time=datetime.time(23,0,0), segment=segment)
|
TimeRule(
|
||||||
|
start_time=datetime.time(8, 0, 0),
|
||||||
|
end_time=datetime.time(23, 0, 0),
|
||||||
|
segment=segment)
|
||||||
|
|
||||||
assert factoried_segment.name == segment.name
|
assert factoried_segment.name == segment.name
|
||||||
assert factoried_segment.status == segment.status
|
assert factoried_segment.status == segment.status
|
||||||
|
|
||||||
|
|
||||||
"""TimeRuleFactory tests"""
|
# TimeRuleFactory tests
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_create_segment_with_time_rule():
|
def test_create_segment_with_time_rule():
|
||||||
segment = SegmentFactory(name='TimeSegment')
|
segment = SegmentFactory(name='TimeSegment')
|
||||||
time_rule = TimeRuleFactory(start_time=datetime.time(8, 0, 0), end_time=datetime.time(23, 0, 0), segment=segment)
|
time_rule = TimeRuleFactory(
|
||||||
|
start_time=datetime.time(8, 0, 0),
|
||||||
|
end_time=datetime.time(23, 0, 0),
|
||||||
|
segment=segment)
|
||||||
|
|
||||||
assert time_rule.start_time == datetime.time(8,0,0)
|
assert time_rule.start_time == datetime.time(8, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
"""TimeRuleFactory tests"""
|
# TimeRuleFactory tests
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_create_segment_with_day_rule():
|
def test_create_segment_with_day_rule():
|
||||||
segment = SegmentFactory(name='DaySegment')
|
segment = SegmentFactory(name='DaySegment')
|
||||||
@@ -42,7 +51,8 @@ def test_create_segment_with_day_rule():
|
|||||||
assert day_rule.sun is False
|
assert day_rule.sun is False
|
||||||
|
|
||||||
|
|
||||||
"""DeviceRuleFactory tests"""
|
# DeviceRuleFactory tests
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_create_segment_with_device_rule():
|
def test_create_segment_with_device_rule():
|
||||||
segment = SegmentFactory(name='DeviceSegment')
|
segment = SegmentFactory(name='DeviceSegment')
|
||||||
@@ -53,11 +63,14 @@ def test_create_segment_with_device_rule():
|
|||||||
assert device_rule.desktop is False
|
assert device_rule.desktop is False
|
||||||
|
|
||||||
|
|
||||||
"""ReferralRuleFactory tests"""
|
# ReferralRuleFactory tests
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_create_segment_with_referral_rule():
|
def test_create_segment_with_referral_rule():
|
||||||
segment = SegmentFactory(name='Referral')
|
segment = SegmentFactory(name='Referral')
|
||||||
referral_rule = ReferralRuleFactory(regex_string='test.test', segment=segment)
|
referral_rule = ReferralRuleFactory(
|
||||||
|
regex_string='test.test',
|
||||||
|
segment=segment)
|
||||||
|
|
||||||
assert referral_rule.regex_string == 'test.test'
|
assert referral_rule.regex_string == 'test.test'
|
||||||
|
|
||||||
@@ -66,6 +79,8 @@ def test_create_segment_with_referral_rule():
|
|||||||
def test_create_segment_with_new_referral_rule():
|
def test_create_segment_with_new_referral_rule():
|
||||||
segment = SegmentFactory()
|
segment = SegmentFactory()
|
||||||
|
|
||||||
segment.referral_rule = ReferralRuleFactory(regex_string='test.notest', segment=segment)
|
segment.referral_rule = ReferralRuleFactory(
|
||||||
|
regex_string='test.notest',
|
||||||
|
segment=segment)
|
||||||
|
|
||||||
assert segment.referral_rule.regex_string == 'test.notest'
|
assert segment.referral_rule.regex_string == 'test.notest'
|
||||||
|
@@ -3,9 +3,7 @@ from __future__ import absolute_import, unicode_literals
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from django.test.client import Client
|
|
||||||
from freezegun import freeze_time
|
from freezegun import freeze_time
|
||||||
from wagtail.wagtailcore.models import Page
|
|
||||||
from wagtail_factories import SiteFactory
|
from wagtail_factories import SiteFactory
|
||||||
|
|
||||||
from tests.factories.rule import (
|
from tests.factories.rule import (
|
||||||
@@ -23,41 +21,37 @@ class TestUserSegmenting(object):
|
|||||||
"""
|
"""
|
||||||
self.site = SiteFactory(is_default_site=True)
|
self.site = SiteFactory(is_default_site=True)
|
||||||
|
|
||||||
|
|
||||||
def test_no_segments(self, client):
|
def test_no_segments(self, client):
|
||||||
request = client.get('/')
|
client.get('/')
|
||||||
|
|
||||||
assert client.session['segments'] == []
|
assert client.session['segments'] == []
|
||||||
|
|
||||||
|
|
||||||
@freeze_time("10:00:00")
|
@freeze_time("10:00:00")
|
||||||
def test_time_segment(self, client):
|
def test_time_segment(self, client):
|
||||||
time_only_segment = SegmentFactory(name='Time only')
|
time_only_segment = SegmentFactory(name='Time only')
|
||||||
time_rule = TimeRuleFactory(
|
TimeRuleFactory(
|
||||||
start_time=datetime.time(8, 0, 0),
|
start_time=datetime.time(8, 0, 0),
|
||||||
end_time=datetime.time(23, 0, 0),
|
end_time=datetime.time(23, 0, 0),
|
||||||
segment=time_only_segment)
|
segment=time_only_segment)
|
||||||
|
|
||||||
request = client.get('/')
|
client.get('/')
|
||||||
|
|
||||||
assert client.session['segments'][0]['encoded_name'] == 'time-only'
|
assert client.session['segments'][0]['encoded_name'] == 'time-only'
|
||||||
|
|
||||||
|
|
||||||
@freeze_time("2017-01-01")
|
@freeze_time("2017-01-01")
|
||||||
def test_day_segment(self, client):
|
def test_day_segment(self, client):
|
||||||
day_only_segment = SegmentFactory(name='Day only')
|
day_only_segment = SegmentFactory(name='Day only')
|
||||||
day_rule = DayRuleFactory(
|
DayRuleFactory(
|
||||||
sun=True,
|
sun=True,
|
||||||
segment=day_only_segment)
|
segment=day_only_segment)
|
||||||
|
|
||||||
request = client.get('/')
|
client.get('/')
|
||||||
|
|
||||||
assert client.session['segments'][0]['encoded_name'] == 'day-only'
|
assert client.session['segments'][0]['encoded_name'] == 'day-only'
|
||||||
|
|
||||||
|
|
||||||
def test_device_segment(self, client):
|
def test_device_segment(self, client):
|
||||||
device_only_segment = SegmentFactory(name='Device only')
|
device_only_segment = SegmentFactory(name='Device only')
|
||||||
device_rule = DeviceRuleFactory(
|
DeviceRuleFactory(
|
||||||
tablet=True,
|
tablet=True,
|
||||||
segment=device_only_segment)
|
segment=device_only_segment)
|
||||||
|
|
||||||
@@ -65,10 +59,9 @@ class TestUserSegmenting(object):
|
|||||||
|
|
||||||
assert client.session['segments'][0]['encoded_name'] == 'device-only'
|
assert client.session['segments'][0]['encoded_name'] == 'device-only'
|
||||||
|
|
||||||
|
|
||||||
def test_device_segment_no_match(self, client):
|
def test_device_segment_no_match(self, client):
|
||||||
no_device_segment = SegmentFactory(name='No device')
|
no_device_segment = SegmentFactory(name='No device')
|
||||||
device_rule = DeviceRuleFactory(
|
DeviceRuleFactory(
|
||||||
mobile=True,
|
mobile=True,
|
||||||
segment=no_device_segment)
|
segment=no_device_segment)
|
||||||
|
|
||||||
@@ -76,10 +69,9 @@ class TestUserSegmenting(object):
|
|||||||
|
|
||||||
assert not client.session['segments']
|
assert not client.session['segments']
|
||||||
|
|
||||||
|
|
||||||
def test_referral_segment(self, client):
|
def test_referral_segment(self, client):
|
||||||
referral_segment = SegmentFactory(name='Referral')
|
referral_segment = SegmentFactory(name='Referral')
|
||||||
referral_rule = ReferralRuleFactory(
|
ReferralRuleFactory(
|
||||||
regex_string="test.test",
|
regex_string="test.test",
|
||||||
segment=referral_segment
|
segment=referral_segment
|
||||||
)
|
)
|
||||||
@@ -91,46 +83,46 @@ class TestUserSegmenting(object):
|
|||||||
@freeze_time("10:00:00")
|
@freeze_time("10:00:00")
|
||||||
def test_time_and_referral_segment(self, client):
|
def test_time_and_referral_segment(self, client):
|
||||||
segment = SegmentFactory(name='Both')
|
segment = SegmentFactory(name='Both')
|
||||||
time_rule = TimeRuleFactory(
|
TimeRuleFactory(
|
||||||
start_time=datetime.time(8, 0, 0),
|
start_time=datetime.time(8, 0, 0),
|
||||||
end_time=datetime.time(23, 0, 0),
|
end_time=datetime.time(23, 0, 0),
|
||||||
segment=segment
|
segment=segment
|
||||||
)
|
)
|
||||||
referral_rule = ReferralRuleFactory(
|
ReferralRuleFactory(
|
||||||
regex_string="test.test",
|
regex_string="test.test",
|
||||||
segment=segment
|
segment=segment
|
||||||
)
|
)
|
||||||
|
|
||||||
client.get('/', **{ 'HTTP_REFERER': 'test.test'})
|
client.get('/', **{'HTTP_REFERER': 'test.test'})
|
||||||
|
|
||||||
assert client.session['segments'][0]['encoded_name'] == 'both'
|
assert client.session['segments'][0]['encoded_name'] == 'both'
|
||||||
|
|
||||||
@freeze_time("7:00:00")
|
@freeze_time("7:00:00")
|
||||||
def test_no_time_but_referral_segment(self, client):
|
def test_no_time_but_referral_segment(self, client):
|
||||||
segment = SegmentFactory(name='Not both')
|
segment = SegmentFactory(name='Not both')
|
||||||
time_rule = TimeRuleFactory(
|
TimeRuleFactory(
|
||||||
start_time=datetime.time(8, 0, 0),
|
start_time=datetime.time(8, 0, 0),
|
||||||
end_time=datetime.time(23, 0, 0),
|
end_time=datetime.time(23, 0, 0),
|
||||||
segment=segment
|
segment=segment
|
||||||
)
|
)
|
||||||
referral_rule = ReferralRuleFactory(
|
ReferralRuleFactory(
|
||||||
regex_string="test.test",
|
regex_string="test.test",
|
||||||
segment=segment
|
segment=segment
|
||||||
)
|
)
|
||||||
|
|
||||||
client.get('/', **{ 'HTTP_REFERER': 'test.test'})
|
client.get('/', **{'HTTP_REFERER': 'test.test'})
|
||||||
|
|
||||||
assert len(client.session['segments']) == 0
|
assert len(client.session['segments']) == 0
|
||||||
|
|
||||||
@freeze_time("9:00:00")
|
@freeze_time("9:00:00")
|
||||||
def test_time_but_no_referral_segment(self, client):
|
def test_time_but_no_referral_segment(self, client):
|
||||||
segment = SegmentFactory(name='Not both')
|
segment = SegmentFactory(name='Not both')
|
||||||
time_rule = TimeRuleFactory(
|
TimeRuleFactory(
|
||||||
start_time=datetime.time(8, 0, 0),
|
start_time=datetime.time(8, 0, 0),
|
||||||
end_time=datetime.time(23, 0, 0),
|
end_time=datetime.time(23, 0, 0),
|
||||||
segment=segment
|
segment=segment
|
||||||
)
|
)
|
||||||
referral_rule = ReferralRuleFactory(
|
ReferralRuleFactory(
|
||||||
regex_string="test.test",
|
regex_string="test.test",
|
||||||
segment=segment
|
segment=segment
|
||||||
)
|
)
|
||||||
@@ -144,29 +136,26 @@ class TestUserSegmenting(object):
|
|||||||
first_segment = SegmentFactory(name='First')
|
first_segment = SegmentFactory(name='First')
|
||||||
second_segment = SegmentFactory(name='Second')
|
second_segment = SegmentFactory(name='Second')
|
||||||
|
|
||||||
first_segment_time_rule = TimeRuleFactory(
|
TimeRuleFactory(
|
||||||
start_time=datetime.time(8, 0, 0),
|
start_time=datetime.time(8, 0, 0),
|
||||||
end_time=datetime.time(23, 0, 0),
|
end_time=datetime.time(23, 0, 0),
|
||||||
segment=first_segment
|
segment=first_segment
|
||||||
)
|
)
|
||||||
first_segment_referral_rule = ReferralRuleFactory(
|
ReferralRuleFactory(
|
||||||
regex_string="test.test",
|
regex_string="test.test",
|
||||||
segment=first_segment
|
segment=first_segment
|
||||||
)
|
)
|
||||||
|
|
||||||
second_segment_time_rule = TimeRuleFactory(
|
TimeRuleFactory(
|
||||||
start_time=datetime.time(8, 0, 0),
|
start_time=datetime.time(8, 0, 0),
|
||||||
end_time=datetime.time(23, 0, 0),
|
end_time=datetime.time(23, 0, 0),
|
||||||
segment=second_segment
|
segment=second_segment
|
||||||
)
|
)
|
||||||
|
|
||||||
second_segment_referral_rule = ReferralRuleFactory
|
|
||||||
|
|
||||||
|
|
||||||
def test_visit_count_rule(self, client):
|
def test_visit_count_rule(self, client):
|
||||||
segment = SegmentFactory(name='Visit Count')
|
segment = SegmentFactory(name='Visit Count')
|
||||||
|
|
||||||
visit_count_rule = VisitCountRuleFactory(
|
VisitCountRuleFactory(
|
||||||
counted_page=self.site.root_page,
|
counted_page=self.site.root_page,
|
||||||
segment=segment
|
segment=segment
|
||||||
)
|
)
|
||||||
@@ -177,7 +166,7 @@ class TestUserSegmenting(object):
|
|||||||
|
|
||||||
def test_query_rule(self, client):
|
def test_query_rule(self, client):
|
||||||
segment = SegmentFactory(name='Query')
|
segment = SegmentFactory(name='Query')
|
||||||
query_rule = QueryRuleFactory(
|
QueryRuleFactory(
|
||||||
parameter="query",
|
parameter="query",
|
||||||
value="value",
|
value="value",
|
||||||
segment=segment,
|
segment=segment,
|
||||||
@@ -189,7 +178,7 @@ class TestUserSegmenting(object):
|
|||||||
|
|
||||||
def test_only_one_query_rule(self, client):
|
def test_only_one_query_rule(self, client):
|
||||||
segment = SegmentFactory(name='Query')
|
segment = SegmentFactory(name='Query')
|
||||||
query_rule = QueryRuleFactory(
|
QueryRuleFactory(
|
||||||
parameter="query",
|
parameter="query",
|
||||||
value="value",
|
value="value",
|
||||||
segment=segment
|
segment=segment
|
||||||
@@ -201,13 +190,13 @@ class TestUserSegmenting(object):
|
|||||||
|
|
||||||
def test_multiple_queries(self, client):
|
def test_multiple_queries(self, client):
|
||||||
segment = SegmentFactory(name='Multiple queries')
|
segment = SegmentFactory(name='Multiple queries')
|
||||||
first_query_rule = QueryRuleFactory(
|
QueryRuleFactory(
|
||||||
parameter="test",
|
parameter="test",
|
||||||
value="test",
|
value="test",
|
||||||
segment=segment
|
segment=segment
|
||||||
)
|
)
|
||||||
|
|
||||||
second_query_rule = QueryRuleFactory(
|
QueryRuleFactory(
|
||||||
parameter="query",
|
parameter="query",
|
||||||
value="value",
|
value="value",
|
||||||
segment=segment,
|
segment=segment,
|
||||||
@@ -217,10 +206,9 @@ class TestUserSegmenting(object):
|
|||||||
|
|
||||||
assert any(item['encoded_name'] == 'multiple-queries' for item in client.session['segments'])
|
assert any(item['encoded_name'] == 'multiple-queries' for item in client.session['segments'])
|
||||||
|
|
||||||
|
|
||||||
def test_persistent_segmenting(self, client):
|
def test_persistent_segmenting(self, client):
|
||||||
segment = SegmentFactory(name='Persistent', persistent=True)
|
segment = SegmentFactory(name='Persistent', persistent=True)
|
||||||
query_rule = QueryRuleFactory(
|
QueryRuleFactory(
|
||||||
parameter="test",
|
parameter="test",
|
||||||
value="test",
|
value="test",
|
||||||
segment=segment
|
segment=segment
|
||||||
@@ -236,7 +224,7 @@ class TestUserSegmenting(object):
|
|||||||
|
|
||||||
def test_non_persistent_segmenting(self, client):
|
def test_non_persistent_segmenting(self, client):
|
||||||
segment = SegmentFactory(name='Non Persistent')
|
segment = SegmentFactory(name='Non Persistent')
|
||||||
query_rule = QueryRuleFactory(
|
QueryRuleFactory(
|
||||||
parameter="test",
|
parameter="test",
|
||||||
value="test",
|
value="test",
|
||||||
segment=segment
|
segment=segment
|
||||||
@@ -250,15 +238,14 @@ class TestUserSegmenting(object):
|
|||||||
|
|
||||||
assert not any(item['encoded_name'] == 'non-persistent' for item in client.session['segments'])
|
assert not any(item['encoded_name'] == 'non-persistent' for item in client.session['segments'])
|
||||||
|
|
||||||
|
|
||||||
def test_match_any_segmenting(self, client):
|
def test_match_any_segmenting(self, client):
|
||||||
segment = SegmentFactory(name='Match any', match_any=True)
|
segment = SegmentFactory(name='Match any', match_any=True)
|
||||||
query_rule = QueryRuleFactory(
|
QueryRuleFactory(
|
||||||
parameter='test',
|
parameter='test',
|
||||||
value='test',
|
value='test',
|
||||||
segment=segment,
|
segment=segment,
|
||||||
)
|
)
|
||||||
second_query_rule = QueryRuleFactory(
|
QueryRuleFactory(
|
||||||
parameter='test2',
|
parameter='test2',
|
||||||
value='test2',
|
value='test2',
|
||||||
segment=segment
|
segment=segment
|
||||||
@@ -268,6 +255,7 @@ class TestUserSegmenting(object):
|
|||||||
|
|
||||||
assert any(item['encoded_name'] == 'match-any' for item in client.session['segments'])
|
assert any(item['encoded_name'] == 'match-any' for item in client.session['segments'])
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
class TestUserVisitCount(object):
|
class TestUserVisitCount(object):
|
||||||
|
|
||||||
|
@@ -10,25 +10,30 @@ from wagtail_factories import SiteFactory
|
|||||||
|
|
||||||
from wagtail_personalisation import rules
|
from wagtail_personalisation import rules
|
||||||
|
|
||||||
"""Time Rule tests"""
|
|
||||||
|
# Time Rule tests
|
||||||
|
|
||||||
@freeze_time("10:00:00")
|
@freeze_time("10:00:00")
|
||||||
def test_create_time_rule():
|
def test_create_time_rule():
|
||||||
time_rule = rules.TimeRule(start_time=datetime.time(8, 0, 0), end_time=datetime.time(23, 0, 0))
|
time_rule = rules.TimeRule(start_time=datetime.time(8, 0, 0), end_time=datetime.time(23, 0, 0))
|
||||||
|
|
||||||
assert time_rule.test_user() is True
|
assert time_rule.test_user() is True
|
||||||
|
|
||||||
|
|
||||||
@freeze_time("10:00:00")
|
@freeze_time("10:00:00")
|
||||||
def test_time_rule_false():
|
def test_time_rule_false():
|
||||||
time_rule = rules.TimeRule(start_time=datetime.time(11, 0, 0), end_time=datetime.time(23, 0, 0))
|
time_rule = rules.TimeRule(start_time=datetime.time(11, 0, 0), end_time=datetime.time(23, 0, 0))
|
||||||
|
|
||||||
assert time_rule.test_user() is False
|
assert time_rule.test_user() is False
|
||||||
|
|
||||||
|
|
||||||
@freeze_time("10:00:00")
|
@freeze_time("10:00:00")
|
||||||
def test_time_rule_reverse():
|
def test_time_rule_reverse():
|
||||||
time_rule = rules.TimeRule(start_time=datetime.time(13, 0, 0), end_time=datetime.time(9, 0, 0))
|
time_rule = rules.TimeRule(start_time=datetime.time(13, 0, 0), end_time=datetime.time(9, 0, 0))
|
||||||
|
|
||||||
assert time_rule.test_user() is False
|
assert time_rule.test_user() is False
|
||||||
|
|
||||||
|
|
||||||
@freeze_time("10:00:00")
|
@freeze_time("10:00:00")
|
||||||
def test_time_rule_reverse_next_day():
|
def test_time_rule_reverse_next_day():
|
||||||
time_rule = rules.TimeRule(start_time=datetime.time(11, 0, 0), end_time=datetime.time(11, 0, 0))
|
time_rule = rules.TimeRule(start_time=datetime.time(11, 0, 0), end_time=datetime.time(11, 0, 0))
|
||||||
@@ -36,12 +41,13 @@ def test_time_rule_reverse_next_day():
|
|||||||
assert time_rule.test_user() is False
|
assert time_rule.test_user() is False
|
||||||
|
|
||||||
|
|
||||||
"""Visit Count Rule tests"""
|
# Visit Count Rule tests
|
||||||
def test_visit_count_rule():
|
def test_visit_count_rule():
|
||||||
visit_count_rule = rules.VisitCountRule()
|
rules.VisitCountRule()
|
||||||
|
|
||||||
|
|
||||||
"""Test test"""
|
# Test test
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_test(rf):
|
def test_test(rf):
|
||||||
site = SiteFactory()
|
site = SiteFactory()
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
import pytest
|
|
||||||
|
|
||||||
from wagtail_personalisation.utils import impersonate_other_page
|
from wagtail_personalisation.utils import impersonate_other_page
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user