Device detection and accompanying rule
Signed-off-by: Jasper Berghoef <jasper.berghoef@gmail.com>
This commit is contained in:
2
setup.py
2
setup.py
@ -2,8 +2,8 @@ from setuptools import find_packages, setup
|
||||
|
||||
|
||||
install_requires = [
|
||||
'django-polymorphic==1.0.2',
|
||||
'wagtail>=1.7',
|
||||
'user-agents>=1.0.1',
|
||||
]
|
||||
|
||||
tests_require = [
|
||||
|
@ -2,6 +2,7 @@ from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import re
|
||||
from datetime import datetime
|
||||
from user_agents import parse
|
||||
|
||||
from django.db import models
|
||||
from django.db.models.signals import pre_save
|
||||
@ -228,6 +229,38 @@ class QueryRule(AbstractBaseRule):
|
||||
return _('Query Rule')
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class DeviceRule(AbstractBaseRule):
|
||||
"""Device rule to segment users based on matching devices"""
|
||||
mobile = models.BooleanField(_("Mobile phone"), default=False)
|
||||
tablet = models.BooleanField(_("Tablet"), default=False)
|
||||
desktop = models.BooleanField(_("Desktop"), default=False)
|
||||
|
||||
panels = [
|
||||
FieldPanel('mobile'),
|
||||
FieldPanel('tablet'),
|
||||
FieldPanel('desktop'),
|
||||
]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DeviceRule, self).__init__(*args, **kwargs)
|
||||
|
||||
def test_user(self, request=None):
|
||||
ua_header = request.META['HTTP_USER_AGENT']
|
||||
user_agent = parse(ua_header)
|
||||
|
||||
if user_agent.is_mobile:
|
||||
return self.mobile
|
||||
elif user_agent.is_tablet:
|
||||
return self.tablet
|
||||
elif user_agent.is_pc:
|
||||
return self.desktop
|
||||
else:
|
||||
return False
|
||||
|
||||
def __str__(self):
|
||||
return _('Device Rule')
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class UserIsLoggedInRule(AbstractBaseRule):
|
||||
"""User should be logged in"""
|
||||
|
@ -48,3 +48,8 @@ class QueryRuleFactory(factory.DjangoModelFactory):
|
||||
|
||||
class Meta:
|
||||
model = models.QueryRule
|
||||
|
||||
class DeviceRuleFactory(factory.DjangoModelFactory):
|
||||
|
||||
class Meta:
|
||||
model = models.DeviceRule
|
||||
|
@ -6,7 +6,7 @@ import pytest
|
||||
|
||||
from personalisation.models import Segment, TimeRule
|
||||
from tests.factories.segment import (
|
||||
ReferralRuleFactory, SegmentFactory, TimeRuleFactory, DayRuleFactory)
|
||||
ReferralRuleFactory, SegmentFactory, TimeRuleFactory, DayRuleFactory, DeviceRuleFactory)
|
||||
|
||||
"""Factory tests"""
|
||||
@pytest.mark.django_db
|
||||
@ -39,6 +39,17 @@ def test_create_segment_with_day_rule():
|
||||
assert day_rule.sun is False
|
||||
|
||||
|
||||
"""DeviceRuleFactory tests"""
|
||||
@pytest.mark.django_db
|
||||
def test_create_segment_with_device_rule():
|
||||
segment = SegmentFactory(name='DeviceSegment')
|
||||
device_rule = DeviceRuleFactory(mobile=True, segment=segment)
|
||||
|
||||
assert device_rule.mobile is True
|
||||
assert device_rule.tablet is False
|
||||
assert device_rule.desktop is False
|
||||
|
||||
|
||||
"""ReferralRuleFactory tests"""
|
||||
@pytest.mark.django_db
|
||||
def test_create_segment_with_referral_rule():
|
||||
|
@ -9,7 +9,7 @@ from wagtail.wagtailcore.models import Page
|
||||
|
||||
from tests.factories.segment import (
|
||||
QueryRuleFactory, ReferralRuleFactory, SegmentFactory, TimeRuleFactory,
|
||||
DayRuleFactory, VisitCountRuleFactory)
|
||||
DayRuleFactory, VisitCountRuleFactory, DeviceRuleFactory)
|
||||
from tests.factories.site import SiteFactory
|
||||
|
||||
|
||||
@ -52,6 +52,28 @@ class TestUserSegmenting(object):
|
||||
assert client.session['segments'][0]['encoded_name'] == 'day-only'
|
||||
|
||||
|
||||
def test_device_segment(self, client):
|
||||
device_only_segment = SegmentFactory(name='Device only')
|
||||
device_rule = DeviceRuleFactory(
|
||||
tablet=True,
|
||||
segment=device_only_segment)
|
||||
|
||||
client.get('/', **{'HTTP_USER_AGENT': 'Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X)'})
|
||||
|
||||
assert client.session['segments'][0]['encoded_name'] == 'device-only'
|
||||
|
||||
|
||||
def test_device_segment_no_match(self, client):
|
||||
no_device_segment = SegmentFactory(name='No device')
|
||||
device_rule = DeviceRuleFactory(
|
||||
mobile=True,
|
||||
segment=no_device_segment)
|
||||
|
||||
client.get('/', **{'HTTP_USER_AGENT': 'Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X)'})
|
||||
|
||||
assert not client.session['segments']
|
||||
|
||||
|
||||
def test_referral_segment(self, client):
|
||||
referral_segment = SegmentFactory(name='Referral')
|
||||
referral_rule = ReferralRuleFactory(
|
||||
@ -59,7 +81,7 @@ class TestUserSegmenting(object):
|
||||
segment=referral_segment
|
||||
)
|
||||
|
||||
client.get('/', **{ 'HTTP_REFERER': 'test.test'})
|
||||
client.get('/', **{'HTTP_REFERER': 'test.test'})
|
||||
|
||||
assert client.session['segments'][0]['encoded_name'] == 'referral'
|
||||
|
||||
|
Reference in New Issue
Block a user