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.conf import settings
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models, transaction
from django.template.defaultfilters import slugify
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_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()
base_form_class = SegmentAdminForm
@ -100,6 +111,7 @@ class Segment(ClusterableModel):
FieldPanel('match_any'),
FieldPanel('type', widget=forms.RadioSelect),
FieldPanel('count', classname='count_field'),
FieldPanel('randomisation_percent', classname='percent_field'),
], heading="Segment"),
MultiFieldPanel([
InlinePanel(

View File

@ -70,6 +70,13 @@
{% endif %}
</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 %}
<li class="stat_card {{ rule.encoded_name }}">
{{ rule.description.title }}

View File

@ -13,7 +13,7 @@ from wagtail_personalisation.rules import (AbstractBaseRule, TimeRule,
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 Meta:
@ -249,6 +249,38 @@ def test_dynamic_segment_with_non_static_rules_have_a_count():
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
def test_matched_user_count_added_to_segment_at_creation(site, client, mocker, django_user_model):
django_user_model.objects.create(username='first')