Skip to content

Commit

Permalink
Connect firefox version to V3 API fixes #3042
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredlockhart committed Jul 14, 2020
1 parent 29d1431 commit 14a9f6e
Show file tree
Hide file tree
Showing 13 changed files with 1,840 additions and 409 deletions.
1,040 changes: 850 additions & 190 deletions app/experimenter/docs/openapi-schema.json

Large diffs are not rendered by default.

1,040 changes: 850 additions & 190 deletions app/experimenter/docs/swagger-ui.html

Large diffs are not rendered by default.

18 changes: 11 additions & 7 deletions app/experimenter/experiments/api/v3/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,24 @@ class ExperimentRapidSerializer(ChangelogSerializerMixin, serializers.ModelSeria
required=True, choices=Experiment.RAPID_AUDIENCE_CHOICES
)
bugzilla_url = serializers.ReadOnlyField()
firefox_min_version = serializers.ChoiceField(
required=True, choices=Experiment.VERSION_CHOICES,
)

class Meta:
model = Experiment
fields = (
"type",
"rapid_type",
"owner",
"audience",
"bugzilla_url",
"features",
"firefox_min_version",
"name",
"slug",
"objectives",
"owner",
"public_description",
"features",
"audience",
"bugzilla_url",
"rapid_type",
"slug",
"type",
)

def validate(self, data):
Expand Down
70 changes: 58 additions & 12 deletions app/experimenter/experiments/tests/api/v3/test_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
from experimenter.bugzilla.tests.mixins import MockBugzillaTasksMixin


firefox_min_version = Experiment.VERSION_CHOICES[0][0]


class TestExperimentRapidSerializer(MockRequestMixin, MockBugzillaTasksMixin, TestCase):
def test_serializer_outputs_expected_schema(self):
owner = UserFactory(email="[email protected]")
Expand All @@ -21,6 +24,7 @@ def test_serializer_outputs_expected_schema(self):
objectives="gotta go fast",
audience="AUDIENCE 1",
features=["FEATURE 1"],
firefox_min_version=firefox_min_version,
)

serializer = ExperimentRapidSerializer(experiment)
Expand All @@ -37,23 +41,25 @@ def test_serializer_outputs_expected_schema(self):
"bugzilla_url": "{bug_host}show_bug.cgi?id={bug_id}".format(
bug_host=settings.BUGZILLA_HOST, bug_id=experiment.bugzilla_id
),
"firefox_min_version": firefox_min_version,
},
)

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)
self.assertIn("audience", serializer.errors)
self.assertIn("features", serializer.errors)
self.assertEqual(
set(serializer.errors.keys()),
set(["name", "objectives", "audience", "features", "firefox_min_version"]),
)

def test_serializer_bad_audience_value(self):
data = {
"name": "rapid experiment",
"objectives": "gotta go fast",
"audience": " WRONG AUDIENCE CHOICE",
"features": ["FEATURE 1", "FEATURE 2"],
"firefox_min_version": firefox_min_version,
}
serializer = ExperimentRapidSerializer(
data=data, context={"request": self.request}
Expand All @@ -67,20 +73,35 @@ def test_serializer_bad_feature_value(self):
"objectives": "gotta go fast",
"audience": "AUDIENCE 1",
"features": ["WRONG FEATURE 1", "WRONG FEATURE 2"],
"firefox_min_version": firefox_min_version,
}
serializer = ExperimentRapidSerializer(
data=data, context={"request": self.request}
)
self.assertFalse(serializer.is_valid())
self.assertIn("features", serializer.errors)

def test_serializer_creates_experiment_and_sets_slug_and_changelog(self):
def test_serializer_bad_firefox_min_version_value(self):
data = {
"name": "rapid experiment",
"objectives": "gotta go fast",
"audience": "AUDIENCE 1",
"features": ["FEATURE 1", "FEATURE 2"],
"firefox_min_version": "invalid version",
}
serializer = ExperimentRapidSerializer(
data=data, context={"request": self.request}
)
self.assertFalse(serializer.is_valid())
self.assertIn("firefox_min_version", serializer.errors)

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"],
"firefox_min_version": firefox_min_version,
}

serializer = ExperimentRapidSerializer(
Expand All @@ -95,6 +116,9 @@ def test_serializer_creates_experiment_and_sets_slug_and_changelog(self):
self.assertEqual(experiment.name, "rapid experiment")
self.assertEqual(experiment.slug, "rapid-experiment")
self.assertEqual(experiment.objectives, "gotta go fast")
self.assertEqual(experiment.audience, "AUDIENCE 1")
self.assertEqual(experiment.features, ["FEATURE 1", "FEATURE 2"])
self.assertEqual(experiment.firefox_min_version, firefox_min_version)
self.assertEqual(
experiment.public_description, Experiment.BUGZILLA_RAPID_EXPERIMENT_TEMPLATE
)
Expand Down Expand Up @@ -135,6 +159,11 @@ def test_serializer_creates_experiment_and_sets_slug_and_changelog(self):
"new_value": ["FEATURE 1", "FEATURE 2"],
"old_value": None,
},
"firefox_min_version": {
"display_name": "Firefox Min Version",
"new_value": firefox_min_version,
"old_value": None,
},
}
self.assertTrue(
experiment.changes.filter(
Expand All @@ -156,15 +185,17 @@ def test_serializer_creates_changelog_for_updates(self):
objectives="gotta go fast",
audience="AUDIENCE 1",
features=["FEATURE 1"],
firefox_min_version=firefox_min_version,
public_description=Experiment.BUGZILLA_RAPID_EXPERIMENT_TEMPLATE,
)

self.assertEqual(experiment.changes.count(), 1)
data = {
"name": "changing the name",
"objectives": "changing objectives",
"audience": "AUDIENCE 1",
"features": ["FEATURE 1"],
"audience": "AUDIENCE 2",
"features": ["FEATURE 2"],
"firefox_min_version": Experiment.VERSION_CHOICES[1][0],
}
serializer = ExperimentRapidSerializer(
instance=experiment, data=data, context={"request": self.request}
Expand All @@ -175,14 +206,29 @@ def test_serializer_creates_changelog_for_updates(self):

changed_values = {
"name": {
"display_name": "Name",
"new_value": "changing the name",
"old_value": "rapid experiment",
"display_name": "Name",
},
"objectives": {
"display_name": "Objectives",
"new_value": "changing objectives",
"old_value": "gotta go fast",
"display_name": "Objectives",
},
"audience": {
"display_name": "Audience",
"new_value": "AUDIENCE 2",
"old_value": "AUDIENCE 1",
},
"features": {
"display_name": "Features",
"new_value": ["FEATURE 2"],
"old_value": ["FEATURE 1"],
},
"firefox_min_version": {
"display_name": "Firefox Min Version",
"new_value": Experiment.VERSION_CHOICES[1][0],
"old_value": firefox_min_version,
},
}
self.assertTrue(
Expand All @@ -194,12 +240,12 @@ def test_serializer_creates_changelog_for_updates(self):
)

def test_serializer_returns_errors_for_non_alpha_numeric_name(self):

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

serializer = ExperimentRapidSerializer(
Expand All @@ -211,14 +257,14 @@ def test_serializer_returns_errors_for_non_alpha_numeric_name(self):
)

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": "AUDIENCE 1",
"features": ["FEATURE 1", "FEATURE 2"],
"firefox_min_version": firefox_min_version,
}

serializer = ExperimentRapidSerializer(
Expand All @@ -231,7 +277,6 @@ def test_serializer_returns_error_for_non_unique_slug(self):
)

def test_serializer_update_experiment_does_not_throw_slug_err(self):

experiment = ExperimentFactory.create(
name="non unique slug", slug="non-unique-slug"
)
Expand All @@ -241,6 +286,7 @@ def test_serializer_update_experiment_does_not_throw_slug_err(self):
"objectives": "gotta go fast",
"audience": "AUDIENCE 1",
"features": ["FEATURE 1", "FEATURE 2"],
"firefox_min_version": firefox_min_version,
}

serializer = ExperimentRapidSerializer(
Expand Down
10 changes: 10 additions & 0 deletions app/experimenter/experiments/tests/api/v3/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def test_post_detail_edits_rapid_experiment(self):
user_email = "[email protected]"
audience = Experiment.RAPID_AUDIENCE_CHOICES[0][1]
features = [feature[0] for feature in Experiment.RAPID_FEATURE_CHOICES]
firefox_min_version = Experiment.VERSION_CHOICES[0][0]

owner = UserFactory(email=user_email)
experiment = ExperimentFactory.create(
Expand All @@ -76,6 +77,7 @@ def test_post_detail_edits_rapid_experiment(self):
"objectives": "new hypothesis",
"audience": audience,
"features": features,
"firefox_min_version": firefox_min_version,
}
)

Expand All @@ -92,18 +94,23 @@ def test_post_detail_edits_rapid_experiment(self):
self.assertEqual(experiment.name, "new name")
self.assertEqual(experiment.slug, "rapid-experiment")
self.assertEqual(experiment.objectives, "new hypothesis")
self.assertEqual(experiment.audience, audience)
self.assertEqual(experiment.features, features)
self.assertEqual(experiment.firefox_min_version, firefox_min_version)

def test_post_list_creates_rapid_experiment(self):
user_email = "[email protected]"
audience = Experiment.RAPID_AUDIENCE_CHOICES[0][1]
features = [feature[0] for feature in Experiment.RAPID_FEATURE_CHOICES]
firefox_min_version = Experiment.VERSION_CHOICES[0][0]

data = json.dumps(
{
"name": "rapid experiment",
"objectives": "gotta go fast",
"audience": audience,
"features": features,
"firefox_min_version": firefox_min_version,
}
)

Expand All @@ -120,3 +127,6 @@ def test_post_list_creates_rapid_experiment(self):
self.assertEqual(experiment.name, "rapid experiment")
self.assertEqual(experiment.slug, "rapid-experiment")
self.assertEqual(experiment.objectives, "gotta go fast")
self.assertEqual(experiment.audience, audience)
self.assertEqual(experiment.features, features)
self.assertEqual(experiment.firefox_min_version, firefox_min_version)
1 change: 1 addition & 0 deletions app/experimenter/static/rapid/__tests__/app.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ describe("<App />", () => {
owner: "[email protected]",
features: ["FEATURE 1", "FEATURE 2"],
audience: "AUDIENCE 1",
firefox_min_version: "78.0",
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ describe("<ExperimentDetails />", () => {
owner: "[email protected]",
features: ["FEATURE 1", "FEATURE 2"],
audience: "AUDIENCE 1",
firefox_min_version: "78.0",
},
}),
);
Expand All @@ -46,6 +47,7 @@ describe("<ExperimentDetails />", () => {
owner: "[email protected]",
features: ["FEATURE 1", "FEATURE 2"],
audience: "AUDIENCE 1",
firefox_min_version: "78.0",
bugzilla_url: "https://example.com",
},
}),
Expand All @@ -66,6 +68,7 @@ describe("<ExperimentDetails />", () => {
owner: "[email protected]",
features: ["FEATURE 1", "FEATURE 2"],
audience: "AUDIENCE 1",
firefox_min_version: "78.0",
},
}),
);
Expand All @@ -87,6 +90,7 @@ describe("<ExperimentDetails />", () => {
owner: "[email protected]",
features: ["FEATURE 1", "FEATURE 2"],
audience: "AUDIENCE 1",
firefox_min_version: "78.0",
},
}),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ describe("<ExperimentForm />", () => {
const audienceField = getByLabelText("Audience");
await selectEvent.select(audienceField, "AUDIENCE 2");

// Update the firefox version field
const firefoxVersionField = getByLabelText("Firefox Minimum Version");
await selectEvent.select(firefoxVersionField, "Firefox 78.0");

// Click the save button
fireEvent.click(getByText("Save"));

Expand All @@ -104,6 +108,7 @@ describe("<ExperimentForm />", () => {
objectives: "test objective",
audience: "AUDIENCE 2",
features: ["FEATURE 1", "FEATURE 2"],
firefox_min_version: "78.0",
});
});

Expand Down Expand Up @@ -165,7 +170,7 @@ describe("<ExperimentForm />", () => {
});
});

["name", "objectives", "features", "audience", "version"].forEach(
["name", "objectives", "features", "audience", "firefox_min_version"].forEach(
(fieldName) => {
it(`shows the appropriate error message for '${fieldName}' on save`, async () => {
const { getByText } = renderWithRouter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Link } from "react-router-dom";
import {
featureOptions,
audienceOptions,
firefoxVersionOptions,
} from "experimenter-rapid/components/forms/ExperimentFormOptions";
import { useExperimentState } from "experimenter-rapid/contexts/experiment/hooks";

Expand Down Expand Up @@ -75,7 +76,13 @@ const ExperimentDetails: React.FC = () => {
label="Audience"
value={displaySelectOptionLabels(audienceOptions, data.audience)}
/>
<LabelledRow label="Firefox Version" />
<LabelledRow
label="Firefox Minimum Version"
value={displaySelectOptionLabels(
firefoxVersionOptions,
data.firefox_min_version,
)}
/>

<h3 className="my-4">Results</h3>
<p>
Expand Down
Loading

0 comments on commit 14a9f6e

Please sign in to comment.