Skip to content

Commit

Permalink
feat(nimbus): Add Firefox Labs Description Links field (#12139)
Browse files Browse the repository at this point in the history
Because:

- We want to publish the Firefox Labs Description Links field

This commit:

- Updates Experimenter to mozila-nimbus-schemas 2025.1.1; and
- Adds a `firefox_labs_description_links` field to the
`NimbusExperiment` model.

Fixes #12133
  • Loading branch information
brennie authored Feb 5, 2025
1 parent c1752b3 commit 17e588f
Show file tree
Hide file tree
Showing 12 changed files with 66 additions and 57 deletions.
4 changes: 4 additions & 0 deletions docs/experimenter/openapi-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -4264,6 +4264,10 @@
"type": "string",
"readOnly": true
},
"firefoxLabsDescriptionLinks": {
"type": "string",
"readOnly": true
},
"firefoxLabsGroup": {
"type": "string",
"readOnly": true
Expand Down
4 changes: 4 additions & 0 deletions docs/experimenter/swagger-ui.html
Original file line number Diff line number Diff line change
Expand Up @@ -4276,6 +4276,10 @@
"type": "string",
"readOnly": true
},
"firefoxLabsDescriptionLinks": {
"type": "string",
"readOnly": true
},
"firefoxLabsGroup": {
"type": "string",
"readOnly": true
Expand Down
4 changes: 4 additions & 0 deletions experimenter/experimenter/experiments/api/v6/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ class NimbusExperimentSerializer(serializers.ModelSerializer):
isFirefoxLabsOptIn = serializers.ReadOnlyField(source="is_firefox_labs_opt_in")
firefoxLabsTitle = serializers.ReadOnlyField(source="firefox_labs_title")
firefoxLabsDescription = serializers.ReadOnlyField(source="firefox_labs_description")
firefoxLabsDescriptionLinks = serializers.ReadOnlyField(
source="firefox_labs_description_links"
)
firefoxLabsGroup = serializers.ReadOnlyField(source="firefox_labs_group")
requiresRestart = serializers.ReadOnlyField(source="requires_restart")

Expand Down Expand Up @@ -152,6 +155,7 @@ class Meta:
"isFirefoxLabsOptIn",
"firefoxLabsTitle",
"firefoxLabsDescription",
"firefoxLabsDescriptionLinks",
"firefoxLabsGroup",
"requiresRestart",
)
Expand Down
4 changes: 4 additions & 0 deletions experimenter/experimenter/experiments/api/v8/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ class NimbusExperimentSerializer(serializers.ModelSerializer):
isFirefoxLabsOptIn = serializers.ReadOnlyField(source="is_firefox_labs_opt_in")
firefoxLabsTitle = serializers.ReadOnlyField(source="firefox_labs_title")
firefoxLabsDescription = serializers.ReadOnlyField(source="firefox_labs_description")
firefoxLabsDescriptionLinks = serializers.ReadOnlyField(
source="firefox_labs_description_links"
)
firefoxLabsGroup = serializers.ReadOnlyField(source="firefox_labs_group")
requiresRestart = serializers.ReadOnlyField(source="requires_restart")

Expand Down Expand Up @@ -154,6 +157,7 @@ class Meta:
"isFirefoxLabsOptIn",
"firefoxLabsTitle",
"firefoxLabsDescription",
"firefoxLabsDescriptionLinks",
"firefoxLabsGroup",
"requiresRestart",
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 5.1.5 on 2025-02-03 21:02

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("experiments", "0276_nimbusexperiment_requires_restart"),
]

operations = [
migrations.AddField(
model_name="nimbusexperiment",
name="firefox_labs_description_links",
field=models.JSONField(
blank=True,
default=None,
null=True,
verbose_name="Firefox Labs Description Links",
),
),
]
6 changes: 6 additions & 0 deletions experimenter/experimenter/experiments/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,12 @@ class NimbusExperiment(NimbusConstants, TargetingConstants, FilterMixin, models.
blank=True,
null=True,
)
firefox_labs_description_links = models.JSONField[dict[str, str]](
"Firefox Labs Description Links",
blank=True,
null=True,
default=None,
)
firefox_labs_group = models.CharField(
"The group this should appear under in Firefox Labs",
blank=True,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,57 +71,6 @@ def test_expected_schema_with_desktop(self):
)
self.assertDictEqual(experiment_data, expected_experiment_data)

self.assertDictEqual(
experiment_data,
{
"arguments": {},
"application": "firefox-desktop",
"appName": "firefox_desktop",
"appId": "firefox-desktop",
"channel": "nightly",
# DRF manually replaces the isoformat suffix so we have to do the same
"startDate": experiment.start_date.isoformat().replace("+00:00", "Z"),
"enrollmentEndDate": (
experiment.actual_enrollment_end_date.isoformat().replace(
"+00:00", "Z"
)
),
"endDate": experiment.end_date.isoformat().replace("+00:00", "Z"),
"id": experiment.slug,
"isEnrollmentPaused": True,
"isRollout": False,
"proposedDuration": experiment.proposed_duration,
"proposedEnrollment": experiment.proposed_enrollment,
"referenceBranch": experiment.reference_branch.slug,
"schemaVersion": settings.NIMBUS_SCHEMA_VERSION,
"slug": experiment.slug,
"targeting": (
f'(browserSettings.update.channel == "nightly") '
f"&& (version|versionCompare('{min_required_version}') >= 0) "
f"&& (locale in ['en-US'])"
),
"userFacingDescription": experiment.public_description,
"userFacingName": experiment.name,
"probeSets": [],
"outcomes": [
{"priority": "primary", "slug": "foo"},
{"priority": "primary", "slug": "bar"},
{"priority": "primary", "slug": "baz"},
{"priority": "secondary", "slug": "quux"},
{"priority": "secondary", "slug": "xyzzy"},
],
"featureValidationOptOut": experiment.is_client_schema_disabled,
"localizations": None,
"locales": ["en-US"],
"publishedDate": experiment.published_date,
"isFirefoxLabsOptIn": False,
"firefoxLabsTitle": None,
"firefoxLabsDescription": None,
"firefoxLabsGroup": None,
"requiresRestart": False,
},
)

self.assertEqual(set(feature_ids_data), {feature1.slug, feature2.slug})

self.assertEqual(
Expand Down Expand Up @@ -183,6 +132,9 @@ def test_expected_schema_with_desktop_with_non_default_fxlabs_fields(self):
is_firefox_labs_opt_in=True,
firefox_labs_title="test-fx-labs-title",
firefox_labs_description="test-fx-labs-description",
firefox_labs_description_links={
"foo": "https://example.com",
},
firefox_labs_group="group",
requires_restart=True,
)
Expand All @@ -198,6 +150,9 @@ def test_expected_schema_with_desktop_with_non_default_fxlabs_fields(self):
"isFirefoxLabsOptIn": True,
"firefoxLabsTitle": "test-fx-labs-title",
"firefoxLabsDescription": "test-fx-labs-description",
"firefoxLabsDescriptionLinks": {
"foo": "https://example.com",
},
"firefoxLabsGroup": "group",
"requiresRestart": True,
}
Expand Down Expand Up @@ -493,6 +448,7 @@ def _experiment_data_without_branches_and_featureIds(
"isFirefoxLabsOptIn": False,
"firefoxLabsTitle": None,
"firefoxLabsDescription": None,
"firefoxLabsDescriptionLinks": None,
"firefoxLabsGroup": None,
"requiresRestart": False,
}
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ def _experiment_data_without_branches_and_featureIds(
"isFirefoxLabsOptIn": False,
"firefoxLabsTitle": None,
"firefoxLabsDescription": None,
"firefoxLabsDescriptionLinks": None,
"firefoxLabsGroup": None,
"requiresRestart": False,
}
1 change: 1 addition & 0 deletions experimenter/experimenter/experiments/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ class NimbusExperimentFactory(factory.django.DjangoModelFactory):
firefox_labs_description = factory.LazyAttribute(
lambda o: faker.catch_phrase() if o.is_firefox_labs_opt_in else None
)
firefox_labs_description_links = factory.LazyAttribute(lambda o: None)
firefox_labs_group = factory.LazyAttribute(
lambda o: (
random.choice(NimbusExperiment.FirefoxLabsGroups.choices)[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ def test_outputs_expected_schema_for_empty_experiment(self):
"firefox_min_version": NimbusExperiment.Version.NO_VERSION,
"firefox_labs_title": experiment.firefox_labs_title,
"firefox_labs_description": experiment.firefox_labs_description,
"firefox_labs_description_links": (
experiment.firefox_labs_description_links
),
"firefox_labs_group": experiment.firefox_labs_group,
"hypothesis": NimbusExperiment.HYPOTHESIS_DEFAULT,
"is_archived": experiment.is_archived,
Expand Down Expand Up @@ -173,6 +176,9 @@ def test_outputs_expected_schema_for_complete_experiment(self):
"firefox_min_version": experiment.firefox_min_version,
"firefox_labs_title": experiment.firefox_labs_title,
"firefox_labs_description": experiment.firefox_labs_description,
"firefox_labs_description_links": (
experiment.firefox_labs_description_links
),
"firefox_labs_group": experiment.firefox_labs_group,
"hypothesis": experiment.hypothesis,
"is_archived": experiment.is_archived,
Expand Down
10 changes: 5 additions & 5 deletions experimenter/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion experimenter/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ djangorestframework-dataclasses = "^1.3.0"
graphene-django = "^3.2.0"
pyright = "^1.1.291"
django-types = "^0.20.0"
mozilla-nimbus-schemas = "2024.12.2"
mozilla-nimbus-schemas = "2025.1.1"
mozilla-metric-config-parser = "^2024.11.1"
django-redis = "^5.4.0"
fontawesomefree = "6.6.0"
Expand Down

0 comments on commit 17e588f

Please sign in to comment.