Example #1
0
 def test_serializer_bad_duplicate_variant_name(self):
     data = {
         "name": "rapid experiment",
         "objectives": "gotta go fast",
         "audience": "all_english",
         "features": ["picture_in_picture", "pinned_tabs"],
         "firefox_min_version": "80.0",
         "firefox_channel": Experiment.CHANNEL_RELEASE,
         "variants": [
             {
                 "name": "duplicate",
                 "ratio": 50,
                 "description": "a variant",
                 "is_control": True,
             },
             {
                 "name": "duplicate",
                 "ratio": 50,
                 "description": "a variant",
                 "is_control": True,
             },
         ],
     }
     serializer = ExperimentRapidSerializer(
         data=data, context={"request": self.request}
     )
     self.assertFalse(serializer.is_valid())
     self.assertIn("variants", serializer.errors)
 def test_serializer_bad_firefox_channel_value(self):
     data = {
         "name": "rapid experiment",
         "objectives": "gotta go fast",
         "audience": "all_english",
         "features": ["picture_in_picture", "pinned_tabs"],
         "firefox_min_version": FIREFOX_VERSION,
         "firefox_channel": "invalid channel",
     }
     serializer = ExperimentRapidSerializer(
         data=data, context={"request": self.request})
     self.assertFalse(serializer.is_valid())
     self.assertIn("firefox_channel", serializer.errors)
 def test_serializer_bad_feature_value(self):
     data = {
         "name": "rapid experiment",
         "objectives": "gotta go fast",
         "audience": "all_english",
         "features": ["WRONG FEATURE 1", "WRONG FEATURE 2"],
         "firefox_min_version": FIREFOX_VERSION,
         "firefox_channel": Experiment.CHANNEL_RELEASE,
     }
     serializer = ExperimentRapidSerializer(
         data=data, context={"request": self.request})
     self.assertFalse(serializer.is_valid())
     self.assertIn("features", serializer.errors)
 def test_serializer_bad_audience_value(self):
     data = {
         "name": "rapid experiment",
         "objectives": "gotta go fast",
         "audience": "WRONG AUDIENCE CHOICE",
         "features": ["picture_in_picture", "pinned_tabs"],
         "firefox_min_version": FIREFOX_VERSION,
         "firefox_channel": Experiment.CHANNEL_RELEASE,
     }
     serializer = ExperimentRapidSerializer(
         data=data, context={"request": self.request})
     self.assertFalse(serializer.is_valid())
     self.assertIn("audience", serializer.errors)
    def test_serializer_returns_errors_for_non_alpha_numeric_name(self):
        data = {
            "name": "!!!!!!!!!!!!!!!",
            "objectives": "gotta go fast",
            "audience": "all_english",
            "features": ["picture_in_picture", "pinned_tabs"],
            "firefox_min_version": FIREFOX_VERSION,
            "firefox_channel": Experiment.CHANNEL_RELEASE,
        }

        serializer = ExperimentRapidSerializer(
            data=data, context={"request": self.request})
        self.assertFalse(serializer.is_valid())
        self.assertIn("Name needs to contain alphanumeric characters",
                      serializer.errors["name"])
 def test_serializer_required_fields(self):
     serializer = ExperimentRapidSerializer(
         data={}, context={"request": self.request})
     self.assertFalse(serializer.is_valid())
     self.assertEqual(
         set(serializer.errors.keys()),
         set([
             "name",
             "objectives",
             "audience",
             "features",
             "firefox_min_version",
             "firefox_channel",
         ]),
     )
    def test_serializer_update_experiment_does_not_throw_slug_err(self):
        experiment = ExperimentFactory.create(name="non unique slug",
                                              slug="non-unique-slug")

        data = {
            "name": "non unique slug",
            "objectives": "gotta go fast",
            "audience": "all_english",
            "features": ["picture_in_picture", "pinned_tabs"],
            "firefox_min_version": FIREFOX_VERSION,
            "firefox_channel": Experiment.CHANNEL_RELEASE,
        }

        serializer = ExperimentRapidSerializer(
            data=data, context={"request": self.request}, instance=experiment)
        self.assertTrue(serializer.is_valid())
Example #8
0
    def test_serializer_creates_changelog_for_updates(self):
        owner = UserFactory(email="*****@*****.**")
        experiment = ExperimentFactory.create_with_status(
            target_status=Experiment.STATUS_DRAFT,
            type=Experiment.TYPE_RAPID,
            rapid_type=Experiment.RAPID_AA_CFR,
            owner=owner,
            name="rapid experiment",
            slug="rapid-experiment",
            objectives="gotta go fast",
            public_description=Experiment.BUGZILLA_RAPID_EXPERIMENT_TEMPLATE,
        )

        self.assertEqual(experiment.changes.count(), 1)
        data = {
            "name": "changing the name",
            "objectives": "changing objectives",
        }
        serializer = ExperimentRapidSerializer(
            instance=experiment, data=data, context={"request": self.request})
        self.assertTrue(serializer.is_valid())
        experiment = serializer.save()
        self.assertEqual(experiment.changes.count(), 2)

        changed_values = {
            "name": {
                "new_value": "changing the name",
                "old_value": "rapid experiment",
                "display_name": "Name",
            },
            "objectives": {
                "new_value": "changing objectives",
                "old_value": "gotta go fast",
                "display_name": "Objectives",
            },
        }
        self.assertTrue(
            experiment.changes.filter(
                old_status=Experiment.STATUS_DRAFT,
                new_status=Experiment.STATUS_DRAFT,
                changed_values=changed_values,
            ).exists())
    def test_serializer_returns_error_for_non_unique_slug(self):
        ExperimentFactory.create(name="non unique slug",
                                 slug="non-unique-slug")

        data = {
            "name": "non. unique slug",
            "objectives": "gotta go fast",
            "audience": "all_english",
            "features": ["picture_in_picture", "pinned_tabs"],
            "firefox_min_version": FIREFOX_VERSION,
            "firefox_channel": Experiment.CHANNEL_RELEASE,
        }

        serializer = ExperimentRapidSerializer(
            data=data, context={"request": self.request})
        self.assertFalse(serializer.is_valid())

        self.assertIn(
            "Name maps to a pre-existing slug, please choose another name",
            serializer.errors["name"],
        )
Example #10
0
    def test_serializer_creates_experiment_and_sets_slug_and_changelog(self):

        data = {
            "name": "rapid experiment",
            "objectives": "gotta go fast",
            "audience": "AUDIENCE 1",
            "features": ["FEATURE 1", "FEATURE 2"],
        }

        serializer = ExperimentRapidSerializer(
            data=data, context={"request": self.request})
        self.assertTrue(serializer.is_valid())
        experiment = serializer.save()

        self.assertEqual(experiment.type, Experiment.TYPE_RAPID)
        self.assertEqual(experiment.rapid_type, Experiment.RAPID_AA_CFR)
        self.assertEqual(experiment.owner, self.user)
        self.assertEqual(experiment.name, "rapid experiment")
        self.assertEqual(experiment.slug, "rapid-experiment")
        self.assertEqual(experiment.objectives, "gotta go fast")
        self.assertEqual(experiment.public_description,
                         Experiment.BUGZILLA_RAPID_EXPERIMENT_TEMPLATE)

        self.mock_tasks_serializer_create_bug.delay.assert_called()

        self.assertEqual(experiment.changes.count(), 1)

        changed_values = {
            "name": {
                "display_name": "Name",
                "new_value": "rapid experiment",
                "old_value": None,
            },
            "objectives": {
                "display_name": "Objectives",
                "new_value": "gotta go fast",
                "old_value": None,
            },
            "owner": {
                "display_name": "Owner",
                "new_value": self.user.id,
                "old_value": None,
            },
            "type": {
                "display_name": "Type",
                "new_value": "rapid",
                "old_value": None
            },
            "public_description": {
                "display_name": "Public Description",
                "new_value": Experiment.BUGZILLA_RAPID_EXPERIMENT_TEMPLATE,
                "old_value": None,
            },
            "audience": {
                "display_name": "Audience",
                "new_value": "AUDIENCE 1",
                "old_value": None,
            },
            "features": {
                "display_name": "Features",
                "new_value": ["FEATURE 1", "FEATURE 2"],
                "old_value": None,
            },
        }
        self.assertTrue(
            experiment.changes.filter(
                old_status=None,
                new_status=Experiment.STATUS_DRAFT,
                changed_values=changed_values,
            ).exists())
Example #11
0
 def test_serializer_required_fields(self):
     serializer = ExperimentRapidSerializer(
         data={}, context={"request": self.request})
     self.assertFalse(serializer.is_valid())
     self.assertIn("name", serializer.errors)
     self.assertIn("objectives", serializer.errors)
Example #12
0
    def test_serializer_updates_experiment_and_creates_changelog(self):
        owner = UserFactory(email="*****@*****.**")
        experiment = ExperimentRapidFactory.create_with_status(
            Experiment.STATUS_DRAFT,
            owner=owner,
            name="rapid experiment",
            slug="rapid-experiment",
            objectives="gotta go fast",
            audience="us_only",
            features=["picture_in_picture", "pinned_tabs"],
            firefox_channel=Experiment.CHANNEL_RELEASE,
            firefox_min_version="79.0",
        )
        experiment.variants.all().delete()
        variant = ExperimentVariantFactory.create(experiment=experiment)

        self.assertEqual(experiment.changes.count(), 1)
        data = {
            "name": "changing the name",
            "objectives": "changing objectives",
            "audience": "all_english",
            "features": ["pinned_tabs"],
            "firefox_channel": Experiment.CHANNEL_NIGHTLY,
            "firefox_min_version": "80.0",
            "variants": [
                {
                    "id": variant.id,
                    "name": "something else",
                    "description": "something",
                    "is_control": True,
                    "ratio": 50,
                    "value": "something",
                },
                {
                    "name": "variant1",
                    "description": "variant1 description",
                    "is_control": False,
                    "ratio": 50,
                    "value": "variant value",
                },
            ],
        }

        serializer = ExperimentRapidSerializer(
            instance=experiment, data=data, context={"request": self.request}
        )

        self.assertTrue(serializer.is_valid())
        experiment = serializer.save()
        self.assertEqual(experiment.changes.count(), 2)

        changelog = experiment.changes.latest()
        self.assertEqual(changelog.old_status, Experiment.STATUS_DRAFT)
        self.assertEqual(changelog.new_status, Experiment.STATUS_DRAFT)
        self.assertEqual(
            set(changelog.changed_values.keys()),
            set(
                [
                    "audience",
                    "features",
                    "firefox_channel",
                    "firefox_min_version",
                    "name",
                    "objectives",
                    "public_description",
                    "variants",
                ]
            ),
        )
Example #13
0
    def test_serializer_creates_experiment_and_sets_slug_and_changelog(self):
        data = {
            "name": "rapid experiment",
            "objectives": "gotta go fast",
            "audience": "all_english",
            "features": ["picture_in_picture", "pinned_tabs"],
            "firefox_min_version": "80.0",
            "firefox_channel": Experiment.CHANNEL_RELEASE,
            "variants": self.variants_data,
        }

        serializer = ExperimentRapidSerializer(
            data=data, context={"request": self.request}
        )
        self.assertTrue(serializer.is_valid())
        experiment = serializer.save()

        # Preset data
        preset_data = NIMBUS_DATA["ExperimentDesignPresets"]["empty_aa"]["preset"][
            "arguments"
        ]

        # User input data
        self.assertEqual(experiment.type, Experiment.TYPE_RAPID)
        self.assertEqual(experiment.rapid_type, Experiment.RAPID_AA)
        self.assertEqual(experiment.owner, self.user)
        self.assertEqual(experiment.name, "rapid experiment")
        self.assertEqual(experiment.slug, "rapid-experiment")
        self.assertEqual(experiment.objectives, "gotta go fast")
        self.assertEqual(experiment.audience, "all_english")
        self.assertEqual(experiment.features, ["picture_in_picture", "pinned_tabs"])
        self.assertEqual(experiment.firefox_min_version, "80.0")
        self.assertEqual(experiment.firefox_channel, Experiment.CHANNEL_RELEASE)
        self.assertEqual(
            experiment.public_description, Experiment.BUGZILLA_RAPID_EXPERIMENT_TEMPLATE
        )
        self.assertEqual(experiment.firefox_channel, Experiment.CHANNEL_RELEASE)
        self.assertEqual(experiment.proposed_duration, preset_data["proposedDuration"])
        self.assertEqual(
            experiment.proposed_enrollment, preset_data["proposedEnrollment"]
        )

        self.assertEqual(experiment.variants.count(), 2)
        self.assertTrue(experiment.variants.filter(**self.variants_data[0]).exists())
        self.assertTrue(experiment.variants.filter(**self.variants_data[1]).exists())

        self.mock_tasks_serializer_create_bug.delay.assert_called()

        self.assertEqual(experiment.changes.count(), 1)

        changelog = experiment.changes.get(
            old_status=None, new_status=Experiment.STATUS_DRAFT
        )
        self.assertEqual(changelog.changed_by, self.request.user)
        self.assertEqual(
            set(changelog.changed_values.keys()),
            set(
                [
                    "audience",
                    "features",
                    "firefox_channel",
                    "firefox_min_version",
                    "name",
                    "objectives",
                    "owner",
                    "proposed_duration",
                    "proposed_enrollment",
                    "public_description",
                    "type",
                    "variants",
                ]
            ),
        )
    def test_serializer_creates_changelog_for_updates(self):
        owner = UserFactory(email="*****@*****.**")
        experiment = ExperimentFactory.create_with_status(
            target_status=Experiment.STATUS_DRAFT,
            type=Experiment.TYPE_RAPID,
            rapid_type=Experiment.RAPID_AA,
            owner=owner,
            name="rapid experiment",
            slug="rapid-experiment",
            objectives="gotta go fast",
            audience="us_only",
            features=["picture_in_picture", "pinned_tabs"],
            firefox_channel=Experiment.CHANNEL_RELEASE,
            firefox_min_version=FIREFOX_VERSION,
            public_description=Experiment.BUGZILLA_RAPID_EXPERIMENT_TEMPLATE,
        )

        self.assertEqual(experiment.changes.count(), 1)
        data = {
            "name": "changing the name",
            "objectives": "changing objectives",
            "audience": "all_english",
            "features": ["pinned_tabs"],
            "firefox_channel": Experiment.CHANNEL_NIGHTLY,
            "firefox_min_version": Experiment.VERSION_CHOICES[1][0],
        }
        serializer = ExperimentRapidSerializer(
            instance=experiment, data=data, context={"request": self.request})
        self.assertTrue(serializer.is_valid())
        experiment = serializer.save()
        self.assertEqual(experiment.changes.count(), 2)

        changed_values = {
            "name": {
                "display_name": "Name",
                "new_value": "changing the name",
                "old_value": "rapid experiment",
            },
            "objectives": {
                "display_name": "Objectives",
                "new_value": "changing objectives",
                "old_value": "gotta go fast",
            },
            "audience": {
                "display_name": "Audience",
                "new_value": "all_english",
                "old_value": "us_only",
            },
            "features": {
                "display_name": "Features",
                "new_value": ["pinned_tabs"],
                "old_value": ["picture_in_picture", "pinned_tabs"],
            },
            "firefox_min_version": {
                "display_name": "Firefox Min Version",
                "new_value": Experiment.VERSION_CHOICES[1][0],
                "old_value": FIREFOX_VERSION,
            },
            "firefox_channel": {
                "display_name": "Firefox Channel",
                "new_value": Experiment.CHANNEL_NIGHTLY,
                "old_value": Experiment.CHANNEL_RELEASE,
            },
        }
        self.assertTrue(
            experiment.changes.filter(
                old_status=Experiment.STATUS_DRAFT,
                new_status=Experiment.STATUS_DRAFT,
                changed_values=changed_values,
            ).exists())
    def test_serializer_creates_experiment_and_sets_slug_and_changelog(self):
        data = {
            "name": "rapid experiment",
            "objectives": "gotta go fast",
            "audience": "all_english",
            "features": ["picture_in_picture", "pinned_tabs"],
            "firefox_min_version": FIREFOX_VERSION,
            "firefox_channel": Experiment.CHANNEL_RELEASE,
        }

        serializer = ExperimentRapidSerializer(
            data=data, context={"request": self.request})
        self.assertTrue(serializer.is_valid())
        experiment = serializer.save()

        # User input data
        self.assertEqual(experiment.type, Experiment.TYPE_RAPID)
        self.assertEqual(experiment.rapid_type, Experiment.RAPID_AA)
        self.assertEqual(experiment.owner, self.user)
        self.assertEqual(experiment.name, "rapid experiment")
        self.assertEqual(experiment.slug, "rapid-experiment")
        self.assertEqual(experiment.objectives, "gotta go fast")
        self.assertEqual(experiment.audience, "all_english")
        self.assertEqual(experiment.features,
                         ["picture_in_picture", "pinned_tabs"])
        self.assertEqual(experiment.firefox_min_version, FIREFOX_VERSION)
        self.assertEqual(experiment.firefox_channel,
                         Experiment.CHANNEL_RELEASE)
        self.assertEqual(experiment.public_description,
                         Experiment.BUGZILLA_RAPID_EXPERIMENT_TEMPLATE)

        # Preset data
        preset_data = NIMBUS_DATA["ExperimentDesignPresets"]["empty_aa"][
            "preset"]["arguments"]

        self.assertEqual(experiment.firefox_channel,
                         Experiment.CHANNEL_RELEASE)
        self.assertEqual(experiment.proposed_duration,
                         preset_data["proposedDuration"])
        self.assertEqual(experiment.proposed_enrollment,
                         preset_data["proposedEnrollment"])

        self.mock_tasks_serializer_create_bug.delay.assert_called()

        self.assertEqual(experiment.changes.count(), 1)

        changed_values = {
            "name": {
                "display_name": "Name",
                "new_value": "rapid experiment",
                "old_value": None,
            },
            "objectives": {
                "display_name": "Objectives",
                "new_value": "gotta go fast",
                "old_value": None,
            },
            "owner": {
                "display_name": "Owner",
                "new_value": self.user.id,
                "old_value": None,
            },
            "type": {
                "display_name": "Type",
                "new_value": "rapid",
                "old_value": None
            },
            "public_description": {
                "display_name": "Public Description",
                "new_value": Experiment.BUGZILLA_RAPID_EXPERIMENT_TEMPLATE,
                "old_value": None,
            },
            "audience": {
                "display_name": "Audience",
                "new_value": "all_english",
                "old_value": None,
            },
            "features": {
                "display_name": "Features",
                "new_value": ["picture_in_picture", "pinned_tabs"],
                "old_value": None,
            },
            "firefox_min_version": {
                "display_name": "Firefox Min Version",
                "new_value": FIREFOX_VERSION,
                "old_value": None,
            },
            "firefox_channel": {
                "display_name": "Firefox Channel",
                "new_value": Experiment.CHANNEL_RELEASE,
                "old_value": None,
            },
            "proposed_duration": {
                "display_name": "Proposed Duration",
                "new_value": 28,
                "old_value": None,
            },
            "proposed_enrollment": {
                "display_name": "Proposed Enrollment",
                "new_value": 7,
                "old_value": None,
            },
        }
        changelog = experiment.changes.get(old_status=None,
                                           new_status=Experiment.STATUS_DRAFT)
        self.maxDiff = None
        self.assertEqual(changelog.changed_values, changed_values)