def test_serializer_outputs_expected_schema_for_addon_experiment(self): experiment = ExperimentFactory.create_with_status( Experiment.STATUS_SHIP, firefox_min_version="63.0", type=Experiment.TYPE_ADDON, locales=[LocaleFactory.create()], countries=[CountryFactory.create()], platforms=[Experiment.PLATFORM_WINDOWS], windows_versions=[Experiment.VERSION_WINDOWS_8], ) serializer = ExperimentRecipeSerializer(experiment) self.assertEqual(serializer.data["action_name"], "opt-out-study") self.assertEqual(serializer.data["name"], experiment.name) expected_comment = (f"{experiment.client_matching}\n" f"Platform: ['All Windows']\n" f"Windows Versions: ['Windows 8']\n") self.assertEqual(serializer.data["comment"], expected_comment) self.assertEqual( serializer.data["filter_object"], [ FilterObjectBucketSampleSerializer(experiment).data, FilterObjectChannelSerializer(experiment).data, FilterObjectVersionsSerializer(experiment).data, FilterObjectLocaleSerializer(experiment).data, FilterObjectCountrySerializer(experiment).data, ], ) self.assertDictEqual( serializer.data["arguments"], ExperimentRecipeAddonArgumentsSerializer(experiment).data, ) self.assertEqual(serializer.data["experimenter_slug"], experiment.slug)
def test_serializer_outputs_expected_schema_for_pref_experiment(self): experiment = ExperimentFactory.create_with_status( Experiment.STATUS_SHIP, firefox_min_version="65.0", type=Experiment.TYPE_PREF, locales=[LocaleFactory.create()], countries=[CountryFactory.create()], platforms=[Experiment.PLATFORM_MAC], profile_age="Existing Profiles Only", ) serializer = ExperimentRecipeSerializer(experiment) self.assertEqual(serializer.data["action_name"], "preference-experiment") self.assertEqual(serializer.data["name"], experiment.name) expected_comment = (f"{experiment.client_matching}\n" f"Platform: ['All Mac']\n" "Profile Age: Existing Profiles Only") self.assertEqual(serializer.data["comment"], expected_comment) self.assertEqual( serializer.data["filter_object"], [ FilterObjectBucketSampleSerializer(experiment).data, FilterObjectChannelSerializer(experiment).data, FilterObjectVersionsSerializer(experiment).data, FilterObjectLocaleSerializer(experiment).data, FilterObjectCountrySerializer(experiment).data, ], ) self.assertDictEqual( serializer.data["arguments"], ExperimentRecipePrefArgumentsSerializer(experiment).data, ) self.assertEqual(serializer.data["experimenter_slug"], experiment.slug)
def test_serializer_outputs_expected_schema_for_multipref(self): experiment = ExperimentFactory.create( name="public name", firefox_min_version="70.0", locales=[LocaleFactory.create()], countries=[CountryFactory.create()], public_description="this is my public description!", recipe_slug="some-random-slug", platforms=[ Experiment.PLATFORM_WINDOWS, Experiment.PLATFORM_MAC, Experiment.PLATFORM_LINUX, ], is_multi_pref=True, ) variant = ExperimentVariant( slug="slug-value", ratio=25, experiment=experiment, is_control=True ) variant.save() pref = VariantPreferencesFactory.create(variant=variant) expected_comment = expected_comment = f"{experiment.client_matching}\n" serializer = ExperimentRecipeSerializer(experiment) self.assertEqual(serializer.data["action_name"], "multi-preference-experiment") self.assertEqual(serializer.data["name"], experiment.name) self.assertEqual(serializer.data["comment"], expected_comment) self.assertEqual( serializer.data["filter_object"], [ FilterObjectBucketSampleSerializer(experiment).data, FilterObjectChannelSerializer(experiment).data, FilterObjectVersionsSerializer(experiment).data, FilterObjectLocaleSerializer(experiment).data, FilterObjectCountrySerializer(experiment).data, ], ) expected_data = { "slug": "some-random-slug", "experimentDocumentUrl": experiment.experiment_url, "userFacingName": "public name", "userFacingDescription": "this is my public description!", "branches": [ { "preferences": { pref.pref_name: { "preferenceBranchType": pref.pref_branch, "preferenceType": pref.pref_type, "preferenceValue": pref.pref_value, } }, "ratio": 25, "slug": "slug-value", } ], } self.assertDictEqual(serializer.data["arguments"], expected_data)
def test_serializer_excludes_countries_if_none_set(self): experiment = ExperimentFactory.create_with_status( Experiment.STATUS_SHIP, type=Experiment.TYPE_ADDON ) experiment.countries.all().delete() serializer = ExperimentRecipeSerializer(experiment) filter_object_types = [f["type"] for f in serializer.data["filter_object"]] self.assertNotIn("country", filter_object_types)
def test_serializer_outputs_expected_schema_for_message(self): experiment = ExperimentFactory.create( name="public name", type=Experiment.TYPE_MESSAGE, firefox_min_version="70.0", locales=[LocaleFactory.create()], countries=[CountryFactory.create()], public_description="this is my public description!", normandy_slug="some-random-slug", platforms=[Experiment.PLATFORM_WINDOWS], ) variant = ExperimentVariant(slug="slug-value", ratio=25, experiment=experiment, is_control=True) variant.save() expected_comment = expected_comment = ( f"{experiment.client_matching}\n" f"Platform: ['All Windows']\n") serializer = ExperimentRecipeSerializer(experiment) self.assertEqual(serializer.data["action_name"], "messaging-experiment") self.assertEqual(serializer.data["name"], experiment.name) self.assertEqual(serializer.data["comment"], expected_comment) self.assertEqual( serializer.data["filter_object"], [ FilterObjectBucketSampleSerializer(experiment).data, FilterObjectChannelSerializer(experiment).data, FilterObjectVersionsSerializer(experiment).data, FilterObjectLocaleSerializer(experiment).data, FilterObjectCountrySerializer(experiment).data, ], ) expected_data = { "slug": "some-random-slug", "experimentDocumentUrl": experiment.experiment_url, "userFacingName": "public name", "userFacingDescription": "this is my public description!", "branches": [{ "groups": [], "value": {}, "ratio": 25, "slug": "slug-value" }], } self.assertDictEqual(serializer.data["arguments"], expected_data)
def test_serializer_outputs_expected_multipref_schema_for_singularpref(self): experiment = ExperimentFactory.create( name="public name", pref_type=Experiment.PREF_TYPE_INT, pref_branch=Experiment.PREF_BRANCH_DEFAULT, firefox_min_version="70.0", locales=[LocaleFactory.create()], countries=[CountryFactory.create()], public_description="this is my public description!", recipe_slug="some-random-slug", platforms=[Experiment.PLATFORM_WINDOWS], ) variant = ExperimentVariant( slug="slug-value", ratio=25, experiment=experiment, value=5 ) variant.save() expected_comment = expected_comment = ( f"{experiment.client_matching}\n" f"Platform: ['All Windows']\n" ) serializer = ExperimentRecipeSerializer(experiment) self.assertEqual(serializer.data["action_name"], "multi-preference-experiment") self.assertEqual(serializer.data["name"], experiment.name) self.assertEqual(serializer.data["comment"], expected_comment) self.assertEqual( serializer.data["filter_object"], [ FilterObjectBucketSampleSerializer(experiment).data, FilterObjectChannelSerializer(experiment).data, FilterObjectVersionsSerializer(experiment).data, FilterObjectLocaleSerializer(experiment).data, FilterObjectCountrySerializer(experiment).data, ], ) expected_data = { "slug": "some-random-slug", "experimentDocumentUrl": experiment.experiment_url, "userFacingName": "public name", "userFacingDescription": "this is my public description!", "branches": [ { "preferences": { experiment.pref_name: { "preferenceBranchType": "default", "preferenceType": Experiment.PREF_TYPE_INT, "preferenceValue": 5, } }, "ratio": 25, "slug": "slug-value", } ], } self.assertDictEqual(serializer.data["arguments"], expected_data)
def test_serializer_outputs_expected_schema_for_addon_rollout(self): experiment = ExperimentFactory.create( addon_release_url="https://www.example.com/addon.xpi", countries=[], firefox_channel=Experiment.CHANNEL_BETA, firefox_max_version="71", firefox_min_version="70", locales=[], name="Experimenter Name", normandy_slug="normandy-slug", platforms=[Experiment.PLATFORM_WINDOWS], population_percent=30.0, rollout_type=Experiment.TYPE_ADDON, slug="experimenter-slug", type=Experiment.TYPE_ROLLOUT, ) serializer = ExperimentRecipeSerializer(experiment) self.assertDictEqual( serializer.data, { "action_name": "addon-rollout", "arguments": { "extensionApiId": "TODO: https://www.example.com/addon.xpi", "slug": "normandy-slug", }, "comment": "Geos: US, CA, GB\n" 'Some "additional" filtering\n' "Platform: ['All Windows']\n", "experimenter_slug": "experimenter-slug", "filter_object": [ { "count": 3000, "input": ["normandy.userId"], "start": 0, "total": 10000, "type": "bucketSample", }, { "channels": ["beta"], "type": "channel" }, { "type": "version", "versions": [70, 71] }, ], "name": "Experimenter Name", }, )
def test_serializer_outputs_expect_schema_for_branched_addon(self): experiment = ExperimentFactory.create( countries=[CountryFactory.create()], firefox_min_version="70.0", locales=[LocaleFactory.create()], name="public name", normandy_slug="some-random-slug", platforms=[Experiment.PLATFORM_LINUX], public_description="this is my public description!", type=Experiment.TYPE_ADDON, ) variant = ExperimentVariant(slug="slug-value", ratio=25, experiment=experiment) variant.save() serializer = ExperimentRecipeSerializer(experiment) self.assertEqual(serializer.data["action_name"], "branched-addon-study") self.assertEqual(serializer.data["name"], experiment.name) expected_comment = f"{experiment.client_matching}\n" f"Platform: ['All Linux']\n" self.assertEqual(serializer.data["comment"], expected_comment) self.assertEqual( serializer.data["filter_object"], [ FilterObjectBucketSampleSerializer(experiment).data, FilterObjectChannelSerializer(experiment).data, FilterObjectVersionsSerializer(experiment).data, FilterObjectLocaleSerializer(experiment).data, FilterObjectCountrySerializer(experiment).data, ], ) self.assertDictEqual( serializer.data["arguments"], { "branches": [{ "ratio": 25, "slug": "slug-value", "extensionApiId": None }], "slug": "some-random-slug", "userFacingDescription": "this is my public description!", "userFacingName": "public name", }, )
def test_serializer_outputs_expected_schema_for_pref_rollout(self): experiment = ExperimentFactory.create( countries=[], firefox_channel=Experiment.CHANNEL_BETA, firefox_max_version="71", firefox_min_version="70", locales=[], name="Experimenter Name", recipe_slug="normandy-slug", platforms=[Experiment.PLATFORM_WINDOWS], population_percent=30.0, rollout_type=Experiment.TYPE_PREF, slug="experimenter-slug", type=Experiment.TYPE_ROLLOUT, ) preference = RolloutPreference( pref_name="browser.pref", pref_value="true", pref_type=Experiment.PREF_TYPE_BOOL, experiment=experiment, ) preference.save() serializer = ExperimentRecipeSerializer(experiment) self.assertDictEqual( serializer.data, { "action_name": "preference-rollout", "arguments": { "preferences": [{"preferenceName": "browser.pref", "value": True}], "slug": "normandy-slug", }, "comment": "Geos: US, CA, GB\n" 'Some "additional" filtering\n' "Platform: ['All Windows']\n", "experimenter_slug": "experimenter-slug", "filter_object": [ { "count": 3000, "input": ["normandy.userId"], "start": 0, "total": 10000, "type": "bucketSample", }, {"type": "channel", "channels": ["beta"]}, {"type": "version", "versions": [70, 71]}, ], "name": "Experimenter Name", }, )
def test_get_experiment_recipe_returns_recipe_info_for_launched_experiment( self, status): user_email = "*****@*****.**" experiment = ExperimentFactory.create_with_status(status) response = self.client.get( reverse("experiments-api-recipe", kwargs={"slug": experiment.slug}), **{settings.OPENIDC_EMAIL_HEADER: user_email}, ) self.assertEqual(response.status_code, 200) json_data = json.loads(response.content) serialized_experiment = ExperimentRecipeSerializer(experiment).data self.assertEqual(serialized_experiment, json_data)
def test_serializer_outputs_expected_schema_for_windows_versions(self): experiment = ExperimentFactory.create_with_status( Experiment.STATUS_SHIP, firefox_min_version="65.0", type=Experiment.TYPE_PREF, locales=[LocaleFactory.create()], countries=[CountryFactory.create()], windows_versions=[Experiment.VERSION_WINDOWS_8], ) serializer = ExperimentRecipeSerializer(experiment) self.assertEqual( serializer.data["filter_object"], [ FilterObjectBucketSampleSerializer(experiment).data, FilterObjectChannelSerializer(experiment).data, FilterObjectVersionsSerializer(experiment).data, FilterObjectLocaleSerializer(experiment).data, FilterObjectCountrySerializer(experiment).data, ], )
def normandy_recipe_json(self): from experimenter.normandy.serializers import ExperimentRecipeSerializer return json.dumps(ExperimentRecipeSerializer(self).data, indent=2)