Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connect firefox version to V3 API fixes #3042 #3043

Merged
merged 2 commits into from
Jul 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
888 changes: 876 additions & 12 deletions app/experimenter/docs/openapi-schema.json

Large diffs are not rendered by default.

888 changes: 876 additions & 12 deletions app/experimenter/docs/swagger-ui.html

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion app/experimenter/experiments/api/v3/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,17 @@ class ExperimentRapidSerializer(
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 = (
"audience",
"bugzilla_url",
"features",
"features",
"firefox_min_version",
"name",
"objectives",
"owner",
Expand Down
67 changes: 54 additions & 13 deletions app/experimenter/experiments/tests/api/v3/test_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
from experimenter.bugzilla.tests.mixins import MockBugzillaTasksMixin


FIREFOX_VERSION = Experiment.VERSION_CHOICES[0][0]


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

serializer = ExperimentRapidSerializer(experiment)
Expand All @@ -42,23 +46,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_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_VERSION,
}
serializer = ExperimentRapidSerializer(
data=data, context={"request": self.request}
Expand All @@ -72,20 +78,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_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_VERSION,
}

serializer = ExperimentRapidSerializer(
Expand All @@ -100,6 +121,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_VERSION)
self.assertEqual(
experiment.public_description, Experiment.BUGZILLA_RAPID_EXPERIMENT_TEMPLATE
)
Expand Down Expand Up @@ -144,7 +168,7 @@ def test_serializer_creates_experiment_and_sets_slug_and_changelog(self):
},
"firefox_min_version": {
"display_name": "Firefox Min Version",
"new_value": Experiment.VERSION_CHOICES[0][0],
"new_value": FIREFOX_VERSION,
"old_value": None,
},
"firefox_channel": {
Expand Down Expand Up @@ -173,15 +197,17 @@ def test_serializer_creates_changelog_for_updates(self):
objectives="gotta go fast",
audience="AUDIENCE 1",
features=["FEATURE 1"],
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": "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 @@ -192,14 +218,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_VERSION,
},
}
self.assertTrue(
Expand All @@ -211,12 +252,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_VERSION,
}

serializer = ExperimentRapidSerializer(
Expand All @@ -228,14 +269,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_VERSION,
}

serializer = ExperimentRapidSerializer(
Expand All @@ -248,7 +289,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 @@ -258,6 +298,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_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 = "user@example.com"
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 = "user@example.com"
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,6 +127,9 @@ 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)

def test_request_review_updates_status_creates_changelog(self):
user_email = "user@example.com"
Expand Down
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: "test@owner.com",
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: "test@owner.com",
features: ["FEATURE 1", "FEATURE 2"],
audience: "AUDIENCE 1",
firefox_min_version: "78.0",
},
}),
);
Expand All @@ -46,6 +47,7 @@ describe("<ExperimentDetails />", () => {
owner: "test@owner.com",
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: "test@owner.com",
features: ["FEATURE 1", "FEATURE 2"],
audience: "AUDIENCE 1",
firefox_min_version: "78.0",
},
}),
);
Expand All @@ -87,6 +90,7 @@ describe("<ExperimentDetails />", () => {
owner: "test@owner.com",
features: ["FEATURE 1", "FEATURE 2"],
audience: "AUDIENCE 1",
firefox_min_version: "78.0",
},
}),
);
Expand All @@ -111,6 +115,7 @@ describe("<ExperimentDetails />", () => {
owner: "test@owner.com",
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 @@ -77,7 +78,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