Compare commits
1 Commits
feature/se
...
feature/74
Author | SHA1 | Date | |
---|---|---|---|
2ae115c72f |
@ -137,7 +137,7 @@ class SessionSegmentsAdapter(BaseSegmentsAdapter):
|
|||||||
segments = self.get_segments()
|
segments = self.get_segments()
|
||||||
return next((s for s in segments if s.pk == segment_id), None)
|
return next((s for s in segments if s.pk == segment_id), None)
|
||||||
|
|
||||||
def add_page_visit(self, page):
|
def add_page_visit(self, page, path=None):
|
||||||
"""Mark the page as visited by the user"""
|
"""Mark the page as visited by the user"""
|
||||||
visit_count = self.request.session.setdefault('visit_count', [])
|
visit_count = self.request.session.setdefault('visit_count', [])
|
||||||
page_visits = [visit for visit in visit_count if visit['id'] == page.pk]
|
page_visits = [visit for visit in visit_count if visit['id'] == page.pk]
|
||||||
@ -150,7 +150,7 @@ class SessionSegmentsAdapter(BaseSegmentsAdapter):
|
|||||||
visit_count.append({
|
visit_count.append({
|
||||||
'slug': page.slug,
|
'slug': page.slug,
|
||||||
'id': page.pk,
|
'id': page.pk,
|
||||||
'path': self.request.path,
|
'path': path or self.request.path,
|
||||||
'count': 1,
|
'count': 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -2,13 +2,16 @@ from __future__ import absolute_import, unicode_literals
|
|||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
|
||||||
from django.http import HttpResponseForbidden, HttpResponseRedirect
|
from django.http import HttpResponseForbidden, HttpResponseRedirect, HttpResponseBadRequest, JsonResponse
|
||||||
from django.shortcuts import get_object_or_404, reverse
|
from django.shortcuts import get_object_or_404, reverse
|
||||||
|
from django.views.decorators.cache import never_cache
|
||||||
|
from django.views.decorators.http import require_POST
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
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
|
||||||
from wagtail.wagtailcore.models import Page
|
from wagtail.wagtailcore.models import Page
|
||||||
|
|
||||||
|
from wagtail_personalisation.adapters import get_segment_adapter
|
||||||
from wagtail_personalisation.models import Segment
|
from wagtail_personalisation.models import Segment
|
||||||
|
|
||||||
|
|
||||||
@ -137,3 +140,36 @@ def copy_page_view(request, page_id, segment_id):
|
|||||||
return HttpResponseRedirect(edit_url)
|
return HttpResponseRedirect(edit_url)
|
||||||
|
|
||||||
return HttpResponseForbidden()
|
return HttpResponseForbidden()
|
||||||
|
|
||||||
|
|
||||||
|
@never_cache
|
||||||
|
@require_POST
|
||||||
|
def visit_page(request):
|
||||||
|
"""Allows a frontend user to submit a page view and retrieve their current
|
||||||
|
segments on a site that is behind a cache or CDN.
|
||||||
|
|
||||||
|
On each page view, the user must POST to this view the page ID and path
|
||||||
|
that they are browsing. It will return a JSON-formatted document containing
|
||||||
|
a list of segments that are currently active for them.
|
||||||
|
"""
|
||||||
|
segment_adapter = get_segment_adapter(request)
|
||||||
|
page_id = request.POST.get('page_id')
|
||||||
|
path = request.POST.get('path')
|
||||||
|
|
||||||
|
if page_id is None or path is None:
|
||||||
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
|
page = Page.objects.filter(id=page_id).only('id', 'slug', 'live').first()
|
||||||
|
|
||||||
|
if page is None or page.live is False:
|
||||||
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
|
segment_adapter.add_page_visit(page, path=path)
|
||||||
|
segment_adapter.refresh()
|
||||||
|
|
||||||
|
return JsonResponse({
|
||||||
|
'segments': [
|
||||||
|
segment['encoded_name']
|
||||||
|
for segment in segment_adapter.get_segments()
|
||||||
|
]
|
||||||
|
})
|
||||||
|
@ -5,6 +5,7 @@ from django.contrib import admin
|
|||||||
from wagtail.wagtailadmin import urls as wagtailadmin_urls
|
from wagtail.wagtailadmin import urls as wagtailadmin_urls
|
||||||
from wagtail.wagtailcore import urls as wagtail_urls
|
from wagtail.wagtailcore import urls as wagtail_urls
|
||||||
from wagtail.wagtaildocs import urls as wagtaildocs_urls
|
from wagtail.wagtaildocs import urls as wagtaildocs_urls
|
||||||
|
from wagtail_personalisation.views import visit_page
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^django-admin/', include(admin.site.urls)),
|
url(r'^django-admin/', include(admin.site.urls)),
|
||||||
@ -12,5 +13,7 @@ urlpatterns = [
|
|||||||
url(r'^admin/', include(wagtailadmin_urls)),
|
url(r'^admin/', include(wagtailadmin_urls)),
|
||||||
url(r'^documents/', include(wagtaildocs_urls)),
|
url(r'^documents/', include(wagtaildocs_urls)),
|
||||||
|
|
||||||
|
url(r'^visit-page/', visit_page),
|
||||||
|
|
||||||
url(r'', include(wagtail_urls)),
|
url(r'', include(wagtail_urls)),
|
||||||
]
|
]
|
||||||
|
71
tests/unit/test_visit_page_view.py
Normal file
71
tests/unit/test_visit_page_view.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from freezegun import freeze_time
|
||||||
|
from wagtail_factories import SiteFactory
|
||||||
|
|
||||||
|
from tests.factories.rule import DayRuleFactory
|
||||||
|
from tests.factories.segment import SegmentFactory
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
class TestVisitPageView(object):
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
"""
|
||||||
|
Sets up a site root to test segmenting
|
||||||
|
"""
|
||||||
|
self.site = SiteFactory(is_default_site=True)
|
||||||
|
|
||||||
|
def test_counts_visits(self, client):
|
||||||
|
response = client.post('/visit-page/', {
|
||||||
|
'page_id': 1,
|
||||||
|
'path': 'foo',
|
||||||
|
})
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert client.session['visit_count'] == [
|
||||||
|
{'slug': 'root', 'id': 1, 'path': 'foo', 'count': 1}
|
||||||
|
]
|
||||||
|
|
||||||
|
@freeze_time("2017-01-01")
|
||||||
|
def test_returns_segments(self, client):
|
||||||
|
day_only_segment = SegmentFactory(name='Day only')
|
||||||
|
DayRuleFactory(
|
||||||
|
sun=True,
|
||||||
|
segment=day_only_segment)
|
||||||
|
|
||||||
|
response = client.post('/visit-page/', {
|
||||||
|
'page_id': 1,
|
||||||
|
'path': 'foo',
|
||||||
|
})
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response.json() == {
|
||||||
|
'segments': ['day-only']
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_get_request(self, client):
|
||||||
|
response = client.get('/visit-page/')
|
||||||
|
|
||||||
|
assert response.status_code == 405
|
||||||
|
|
||||||
|
def test_missing_page_id(self, client):
|
||||||
|
response = client.post('/visit-page/')
|
||||||
|
|
||||||
|
assert response.status_code == 400
|
||||||
|
|
||||||
|
def test_missing_path(self, client):
|
||||||
|
response = client.post('/visit-page/', {
|
||||||
|
'page_id': 1,
|
||||||
|
})
|
||||||
|
|
||||||
|
assert response.status_code == 400
|
||||||
|
|
||||||
|
def test_nonexistent_page(self, client):
|
||||||
|
response = client.post('/visit-page/', {
|
||||||
|
'page_id': 9999999,
|
||||||
|
'path': 'foo',
|
||||||
|
})
|
||||||
|
|
||||||
|
assert response.status_code == 400
|
Reference in New Issue
Block a user