Include addon version in experiment data model fixes #34
This commit is contained in:
Родитель
c8807f9d77
Коммит
d1d3124078
|
@ -92,7 +92,10 @@ Example:
|
|||
{
|
||||
"name": "New Feature",
|
||||
"slug": "new-feature",
|
||||
"active": true,
|
||||
"addon_versions": [
|
||||
"1.0",
|
||||
"2.0"
|
||||
],
|
||||
"start_date": 1493928948000.0,
|
||||
"end_date": 1495138548000.0,
|
||||
"variant": {
|
||||
|
|
|
@ -72,7 +72,7 @@ class ExperimentAdmin(SlugPrepopulatedMixin, admin.ModelAdmin):
|
|||
|
||||
fieldsets = (
|
||||
('Overview', {
|
||||
'fields': ('project', 'name', 'slug'),
|
||||
'fields': ('project', 'name', 'slug', 'addon_versions'),
|
||||
}),
|
||||
('Notes', {
|
||||
'fields': ('objectives', 'success_criteria', 'analysis'),
|
||||
|
@ -102,7 +102,8 @@ class ExperimentAdmin(SlugPrepopulatedMixin, admin.ModelAdmin):
|
|||
readonly_fields += ('status',)
|
||||
|
||||
if db_obj.is_begun:
|
||||
readonly_fields += ('project', 'name', 'slug')
|
||||
readonly_fields += (
|
||||
'project', 'name', 'slug', 'addon_versions')
|
||||
|
||||
return readonly_fields
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11 on 2017-05-18 19:40
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import django.contrib.postgres.fields.jsonb
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('experiments', '0008_auto_20170516_1928'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='experiment',
|
||||
name='addon_versions',
|
||||
field=django.contrib.postgres.fields.jsonb.JSONField(default=[]),
|
||||
),
|
||||
]
|
|
@ -32,6 +32,7 @@ class Experiment(models.Model):
|
|||
max_length=255, unique=True, blank=False, null=False)
|
||||
slug = models.SlugField(
|
||||
max_length=255, unique=True, blank=False, null=False)
|
||||
addon_versions = JSONField(default=[])
|
||||
objectives = models.TextField(default='')
|
||||
success_criteria = models.TextField(default='')
|
||||
analysis = models.TextField(default='')
|
||||
|
@ -48,7 +49,19 @@ class Experiment(models.Model):
|
|||
verbose_name = 'Experiment'
|
||||
verbose_name_plural = 'Experiments'
|
||||
|
||||
def clean(self):
|
||||
def clean_addon_versions(self):
|
||||
if not (
|
||||
type(self.addon_versions) is list and
|
||||
all([type(version) is str for version in self.addon_versions])
|
||||
):
|
||||
raise ValidationError({
|
||||
'addon_versions': (
|
||||
'addon_versions must be a list of '
|
||||
'strings, ex: ["1.0.0", "1.0.1"]'
|
||||
),
|
||||
})
|
||||
|
||||
def clean_status(self):
|
||||
if not self.pk:
|
||||
return
|
||||
|
||||
|
@ -69,11 +82,15 @@ class Experiment(models.Model):
|
|||
self.end_date = datetime.datetime.now()
|
||||
|
||||
else:
|
||||
raise ValidationError((
|
||||
raise ValidationError({'status': (
|
||||
'You can not change an Experiment\'s status '
|
||||
'from {old_status} to {new_status}'
|
||||
).format(
|
||||
old_status=old_state.status, new_status=new_state.status))
|
||||
old_status=old_state.status, new_status=new_state.status)})
|
||||
|
||||
def clean(self):
|
||||
self.clean_addon_versions()
|
||||
self.clean_status()
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.clean()
|
||||
|
|
|
@ -53,6 +53,7 @@ class ExperimentSerializer(serializers.ModelSerializer):
|
|||
fields = (
|
||||
'name',
|
||||
'slug',
|
||||
'addon_versions',
|
||||
'start_date',
|
||||
'end_date',
|
||||
'variant',
|
||||
|
|
|
@ -14,6 +14,7 @@ class ExperimentFactory(factory.django.DjangoModelFactory):
|
|||
project = factory.SubFactory(ProjectFactory)
|
||||
name = factory.LazyAttribute(lambda o: faker.catch_phrase())
|
||||
slug = factory.LazyAttribute(lambda o: slugify(o.name))
|
||||
addon_versions = ['1.0', '2.0']
|
||||
objectives = factory.LazyAttribute(lambda o: faker.paragraphs())
|
||||
success_criteria = factory.LazyAttribute(lambda o: faker.paragraphs())
|
||||
analysis = factory.LazyAttribute(lambda o: faker.paragraphs())
|
||||
|
|
|
@ -7,6 +7,10 @@ from experimenter.experiments.tests.factories import ExperimentFactory
|
|||
|
||||
class TestExperimentModel(TestCase):
|
||||
|
||||
def test_invalid_addon_versions_raises_validation_error(self):
|
||||
with self.assertRaises(ValidationError):
|
||||
ExperimentFactory.create_with_variants(addon_versions='invalid')
|
||||
|
||||
def test_control_property_returns_experiment_control(self):
|
||||
experiment = ExperimentFactory.create_with_variants()
|
||||
control = ExperimentVariant.objects.get(
|
||||
|
|
|
@ -61,6 +61,7 @@ class TestExperimentSerializer(TestCase):
|
|||
self.assertEqual(serialized.data, {
|
||||
'name': experiment.name,
|
||||
'slug': experiment.slug,
|
||||
'addon_versions': experiment.addon_versions,
|
||||
'start_date': JSTimestampField().to_representation(
|
||||
experiment.start_date),
|
||||
'end_date': JSTimestampField().to_representation(
|
||||
|
|
Загрузка…
Ссылка в новой задаче