7

Merge pull request #10 from praekeltfoundation/feature/SAS-92-store-randomisation-percentage

Add randomisation percentage to segment model
This commit is contained in:
Kaitlyn
2018-02-05 11:54:23 +02:00
committed by GitHub
4 changed files with 73 additions and 1 deletions

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2018-01-31 16:12
from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wagtail_personalisation', '0016_auto_20180125_0918'),
]
operations = [
migrations.AddField(
model_name='segment',
name='randomisation_percent',
field=models.PositiveSmallIntegerField(blank=True, default=None, help_text='If this number is set each user matching the rules will have this percentage chance of being placed in the segment.', null=True, validators=[django.core.validators.MaxValueValidator(100), django.core.validators.MinValueValidator(0)]),
),
]

View File

@ -2,6 +2,7 @@ from __future__ import absolute_import, unicode_literals
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.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.encoding import python_2_unicode_compatible
@ -85,6 +86,16 @@ class Segment(ClusterableModel):
matched_users_count = models.PositiveIntegerField(default=0, editable=False) matched_users_count = models.PositiveIntegerField(default=0, editable=False)
matched_count_updated_at = models.DateTimeField(null=True, editable=False) matched_count_updated_at = models.DateTimeField(null=True, editable=False)
randomisation_percent = models.PositiveSmallIntegerField(
null=True, blank=True, default=None,
help_text=_(
"If this number is set each user matching the rules will "
"have this percentage chance of being placed in the segment."
), validators=[
MaxValueValidator(100),
MinValueValidator(0)
])
objects = SegmentQuerySet.as_manager() objects = SegmentQuerySet.as_manager()
base_form_class = SegmentAdminForm base_form_class = SegmentAdminForm
@ -100,6 +111,7 @@ class Segment(ClusterableModel):
FieldPanel('match_any'), FieldPanel('match_any'),
FieldPanel('type', widget=forms.RadioSelect), FieldPanel('type', widget=forms.RadioSelect),
FieldPanel('count', classname='count_field'), FieldPanel('count', classname='count_field'),
FieldPanel('randomisation_percent', classname='percent_field'),
], heading="Segment"), ], heading="Segment"),
MultiFieldPanel([ MultiFieldPanel([
InlinePanel( InlinePanel(

View File

@ -70,6 +70,13 @@
{% endif %} {% endif %}
</li> </li>
{% if segment.randomisation_percent is not None %}
<li class="stat_card">
<span>{{ segment.randomisation_percent }} %</span>
{% trans "Chance that visitors matching the rules are added to the segment" %}
</li>
{% endif %}
{% for rule in segment.get_rules %} {% for rule in segment.get_rules %}
<li class="stat_card {{ rule.encoded_name }}"> <li class="stat_card {{ rule.encoded_name }}">
{{ rule.description.title }} {{ rule.description.title }}

View File

@ -13,7 +13,7 @@ from wagtail_personalisation.rules import (AbstractBaseRule, TimeRule,
def form_with_data(segment, *rules): def form_with_data(segment, *rules):
model_fields = ['type', 'status', 'count', 'name', 'match_any'] model_fields = ['type', 'status', 'count', 'name', 'match_any', 'randomisation_percent']
class TestSegmentAdminForm(SegmentAdminForm): class TestSegmentAdminForm(SegmentAdminForm):
class Meta: class Meta:
@ -249,6 +249,38 @@ def test_dynamic_segment_with_non_static_rules_have_a_count():
assert form.is_valid(), form.errors assert form.is_valid(), form.errors
@pytest.mark.django_db
def test_randomisation_percentage_added_to_segment_at_creation(site, client, mocker, django_user_model):
segment = SegmentFactory.build(type=Segment.TYPE_STATIC)
segment.randomisation_percent = 80
rule = VisitCountRule()
form = form_with_data(segment, rule)
instance = form.save()
assert instance.randomisation_percent == 80
@pytest.mark.django_db
def test_randomisation_percentage_min_zero(site, client, mocker, django_user_model):
segment = SegmentFactory.build(type=Segment.TYPE_STATIC)
segment.randomisation_percent = -1
rule = VisitCountRule()
form = form_with_data(segment, rule)
assert not form.is_valid()
@pytest.mark.django_db
def test_randomisation_percentage_max_100(site, client, mocker, django_user_model):
segment = SegmentFactory.build(type=Segment.TYPE_STATIC)
segment.randomisation_percent = 101
rule = VisitCountRule()
form = form_with_data(segment, rule)
assert not form.is_valid()
@pytest.mark.django_db @pytest.mark.django_db
def test_matched_user_count_added_to_segment_at_creation(site, client, mocker, django_user_model): def test_matched_user_count_added_to_segment_at_creation(site, client, mocker, django_user_model):
django_user_model.objects.create(username='first') django_user_model.objects.create(username='first')