This is the last current_revision_property, so delete that too.
This commit is contained in:
Ethan Glasser-Camp 2020-02-27 17:09:29 -05:00
Родитель 8788cecd3c
Коммит d0219be7eb
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 36BCE87195D302D8
10 изменённых файлов: 44 добавлений и 49 удалений

Просмотреть файл

@ -17,7 +17,7 @@ class CapabilitiesView(APIView):
capabilities[cap] = {"is_baseline": True}
for recipe in Recipe.objects.all():
for cap in recipe.capabilities:
for cap in recipe.latest_revision.capabilities:
capabilities.setdefault(cap, {"is_baseline": False})
return Response(CapabilitiesInfoSerializer({"capabilities": capabilities}).data)

Просмотреть файл

@ -17,8 +17,11 @@ class TestServiceInfoView(object):
res = api_client.get("/api/v3/capabilities/")
assert res.status_code == 200
assert any(cap not in settings.BASELINE_CAPABILITIES for cap in recipe.capabilities)
for cap in recipe.capabilities:
assert any(
cap not in settings.BASELINE_CAPABILITIES
for cap in recipe.latest_revision.capabilities
)
for cap in recipe.latest_revision.capabilities:
assert cap in res.data["capabilities"]
assert res.data["capabilities"][cap]["is_baseline"] == (
cap in settings.BASELINE_CAPABILITIES

Просмотреть файл

@ -20,14 +20,3 @@ class RelatedFieldProperty(object):
def __delete__(self, instance):
raise AttributeError("This property cannot be deleted.")
def current_revision_property(default=None):
"""
A decorator that will return a default value if the instance has no `current_revision`
"""
def decorator(method):
return RelatedFieldProperty(method, related_field="current_revision", default=default)
return decorator

Просмотреть файл

@ -17,7 +17,6 @@ from rest_framework.reverse import reverse
from normandy.base.api.renderers import CanonicalJSONRenderer
from normandy.base.utils import filter_m2m, get_client_ip, sri_hash
from normandy.recipes import filters
from normandy.recipes.decorators import current_revision_property
from normandy.recipes.geolocation import get_country_code
from normandy.recipes.signing import Autographer
from normandy.recipes.exports import RemoteSettings
@ -117,10 +116,6 @@ class Recipe(DirtyFieldsMixin, models.Model):
def is_approved(self):
return self.approved_revision is not None
@current_revision_property()
def capabilities(self):
return self.current_revision.capabilities
def uses_only_baseline_capabilities(self):
return self.current_revision.uses_only_baseline_capabilities()

Просмотреть файл

@ -183,7 +183,7 @@ class TestRecipeAPI(object):
def test_it_serves_recipes(self, api_client, settings):
recipe = RecipeFactory()
settings.BASELINE_CAPABILITIES |= recipe.capabilities
settings.BASELINE_CAPABILITIES |= recipe.latest_revision.capabilities
res = api_client.get("/api/v1/recipe/")
assert res.status_code == 200
@ -354,7 +354,7 @@ class TestRecipeAPI(object):
def test_signed_listing_works(self, api_client, settings):
r1 = RecipeFactory(approver=UserFactory(), signed=True)
settings.BASELINE_CAPABILITIES |= r1.capabilities
settings.BASELINE_CAPABILITIES |= r1.latest_revision.capabilities
res = api_client.get("/api/v1/recipe/signed/")
assert res.status_code == 200
assert len(res.data) == 1
@ -371,7 +371,9 @@ class TestRecipeAPI(object):
def test_signed_only_lists_signed_recipes(self, api_client, settings):
r1 = RecipeFactory(approver=UserFactory(), signed=True)
r2 = RecipeFactory(approver=UserFactory(), signed=True)
settings.BASELINE_CAPABILITIES |= r1.capabilities | r2.capabilities
settings.BASELINE_CAPABILITIES |= (
r1.approved_revision.capabilities | r2.approved_revision.capabilities
)
RecipeFactory(signed=False)
res = api_client.get("/api/v1/recipe/signed/")
assert res.status_code == 200
@ -390,7 +392,8 @@ class TestRecipeAPI(object):
)
disabled_recipe = RecipeFactory(approver=UserFactory(), signed=True)
settings.BASELINE_CAPABILITIES |= (
enabled_recipe.capabilities | disabled_recipe.capabilities
enabled_recipe.approved_revision.capabilities
| disabled_recipe.approved_revision.capabilities
)
res = api_client.get("/api/v1/recipe/signed/?enabled=1")
@ -420,7 +423,7 @@ class TestRecipeAPI(object):
)
# Recipes have some auto-generated capabilities as well. Such as action names. Add all of those too
settings.BASELINE_CAPABILITIES |= baseline_recipe.capabilities
settings.BASELINE_CAPABILITIES |= baseline_recipe.approved_revision.capabilities
assert "b" not in settings.BASELINE_CAPABILITIES
res = api_client.get("/api/v1/recipe/signed/")
@ -444,7 +447,7 @@ class TestRecipeAPI(object):
)
# Recipes have some auto-generated capabilities as well. Such as action names. Add all of those too
settings.BASELINE_CAPABILITIES |= baseline_recipe.capabilities
settings.BASELINE_CAPABILITIES |= baseline_recipe.approved_revision.capabilities
assert "b" not in settings.BASELINE_CAPABILITIES
res = api_client.get("/api/v1/recipe/signed/?only_baseline_capabilities=false")

Просмотреть файл

@ -48,7 +48,7 @@ class TestRecipeSerializer:
"comment": None,
},
"identicon_seed": Whatever.startswith("v1:"),
"capabilities": sorted(recipe.capabilities),
"capabilities": sorted(recipe.latest_revision.capabilities),
}
@ -66,7 +66,7 @@ class TestMinimalRecipeSerializer:
"revision_id": str(recipe.approved_revision.id),
"action": action.name,
"arguments": {"foo": "bar"},
"capabilities": sorted(recipe.capabilities),
"capabilities": sorted(recipe.approved_revision.capabilities),
"uses_only_baseline_capabilities": False,
}
@ -125,7 +125,7 @@ class TestSignedRecipeSerializer:
"revision_id": str(recipe.approved_revision.id),
"action": action.name,
"arguments": recipe.approved_revision.arguments,
"capabilities": sorted(recipe.capabilities),
"capabilities": sorted(recipe.approved_revision.capabilities),
"uses_only_baseline_capabilities": False,
},
}

Просмотреть файл

@ -146,7 +146,7 @@ class TestRecipeAPI(object):
def test_list_can_filter_baseline_recipes(self, rs_settings, api_client):
recipe1 = RecipeFactory(extra_capabilities=[])
rs_settings.BASELINE_CAPABILITIES |= recipe1.capabilities
rs_settings.BASELINE_CAPABILITIES |= recipe1.latest_revision.capabilities
assert recipe1.uses_only_baseline_capabilities()
recipe2 = RecipeFactory(extra_capabilities=["test-capability"])
assert not recipe2.uses_only_baseline_capabilities()
@ -521,7 +521,7 @@ class TestRecipeAPI(object):
# Passed extra capabilities:
assert recipe.latest_revision.extra_capabilities == ["test.one", "test.two"]
# Extra capabilities get included in capabilities
assert {"test.one", "test.two"} <= set(recipe.capabilities)
assert {"test.one", "test.two"} <= set(recipe.latest_revision.capabilities)
@pytest.mark.django_db
class TestUpdates(object):
@ -680,8 +680,8 @@ class TestRecipeAPI(object):
)
assert res.status_code == 200
recipe = Recipe.objects.get()
assert {"always", "changed"} <= set(recipe.capabilities)
assert "original" not in recipe.capabilities
assert {"always", "changed"} <= set(recipe.latest_revision.capabilities)
assert "original" not in recipe.latest_revision.capabilities
@pytest.mark.django_db
class TestFilterObjects(object):
@ -1428,7 +1428,7 @@ class TestApprovalFlow(object):
recipe_data_1 = res.json()
assert recipe_data_1["approved_revision"] is not None
assert (
Recipe.objects.get(id=recipe_data_1["id"]).capabilities
Recipe.objects.get(id=recipe_data_1["id"]).latest_revision.capabilities
<= settings.BASELINE_CAPABILITIES
)
self.verify_signatures(api_client, expected_count=1)
@ -1544,7 +1544,10 @@ class TestApprovalFlow(object):
recipe_id = res.json()["id"]
revision_id = res.json()["latest_revision"]["id"]
assert Recipe.objects.get(id=recipe_id).capabilities <= settings.BASELINE_CAPABILITIES
assert (
Recipe.objects.get(id=recipe_id).latest_revision.capabilities
<= settings.BASELINE_CAPABILITIES
)
# Request approval
res = api_client.post(f"/api/v3/recipe_revision/{revision_id}/request_approval/")

Просмотреть файл

@ -496,8 +496,8 @@ class TestSyncRemoteSettings(object):
r1 = RecipeFactory(name="Test 1", enabler=UserFactory(), approver=UserFactory())
r2 = RecipeFactory(name="Test 2", enabler=UserFactory(), approver=UserFactory())
rs_settings.BASELINE_CAPABILITIES |= r1.capabilities
rs_settings.BASELINE_CAPABILITIES |= r2.capabilities
rs_settings.BASELINE_CAPABILITIES |= r1.approved_revision.capabilities
rs_settings.BASELINE_CAPABILITIES |= r2.approved_revision.capabilities
# Mock the server responses.
# `r2` should be on the server
@ -547,8 +547,8 @@ class TestSyncRemoteSettings(object):
r1 = RecipeFactory(name="Test 1", enabler=UserFactory(), approver=UserFactory())
r2 = RecipeFactory(name="Test 2", enabler=UserFactory(), approver=UserFactory())
rs_settings.BASELINE_CAPABILITIES |= r1.capabilities
rs_settings.BASELINE_CAPABILITIES |= r2.capabilities
rs_settings.BASELINE_CAPABILITIES |= r1.approved_revision.capabilities
rs_settings.BASELINE_CAPABILITIES |= r2.approved_revision.capabilities
# Mock the server responses.
to_update = {**exports.recipe_as_record(r2), "name": "Outdated name"}

Просмотреть файл

@ -332,7 +332,9 @@ class TestRemoteSettings:
"id": recipe.id,
"name": recipe.approved_revision.name,
"revision_id": str(recipe.approved_revision.id),
"capabilities": Whatever(lambda caps: set(caps) == recipe.capabilities),
"capabilities": Whatever(
lambda caps: set(caps) == recipe.approved_revision.capabilities
),
"uses_only_baseline_capabilities": False,
},
"signature": {
@ -349,7 +351,7 @@ class TestRemoteSettings:
"""Test that requests are sent to Remote Settings on publish."""
recipe = RecipeFactory(name="Test", approver=UserFactory())
rs_settings.BASELINE_CAPABILITIES |= recipe.capabilities
rs_settings.BASELINE_CAPABILITIES |= recipe.approved_revision.capabilities
auth = (
rs_settings.REMOTE_SETTINGS_USERNAME + ":" + rs_settings.REMOTE_SETTINGS_PASSWORD
@ -399,7 +401,7 @@ class TestRemoteSettings:
"""Test that requests are sent to Remote Settings on unpublish."""
recipe = RecipeFactory(name="Test", approver=UserFactory())
rs_settings.BASELINE_CAPABILITIES |= recipe.capabilities
rs_settings.BASELINE_CAPABILITIES |= recipe.approved_revision.capabilities
urls = rs_urls["workspace"]
auth = (
@ -556,7 +558,7 @@ class TestRemoteSettings:
ws_urls = rs_urls["workspace"]
recipe = RecipeFactory(approver=UserFactory())
rs_settings.BASELINE_CAPABILITIES |= recipe.capabilities
rs_settings.BASELINE_CAPABILITIES |= recipe.approved_revision.capabilities
assert recipe.uses_only_baseline_capabilities()
# Expect publish calls to both collections

Просмотреть файл

@ -806,28 +806,28 @@ class TestRecipeRevision(object):
settings.BASELINE_CAPABILITIES |= action.capabilities
recipe = RecipeFactory(extra_capabilities=[], action=action)
assert recipe.capabilities <= settings.BASELINE_CAPABILITIES
assert "capabilities-v1" not in recipe.capabilities
assert recipe.latest_revision.capabilities <= settings.BASELINE_CAPABILITIES
assert "capabilities-v1" not in recipe.latest_revision.capabilities
recipe = RecipeFactory(extra_capabilities=["non-baseline"], action=action)
assert "non-baseline" not in settings.BASELINE_CAPABILITIES
assert "capabilities-v1" in recipe.capabilities
assert "capabilities-v1" in recipe.latest_revision.capabilities
def test_uses_extra_capabilities(self):
recipe = RecipeFactory(extra_capabilities=["test.foo", "test.bar"])
assert "test.foo" in recipe.capabilities
assert "test.bar" in recipe.capabilities
assert "test.foo" in recipe.latest_revision.capabilities
assert "test.bar" in recipe.latest_revision.capabilities
def test_action_name_is_automatically_included(self):
action = ActionFactory()
recipe = RecipeFactory(action=action)
assert set(action.capabilities) <= set(recipe.capabilities)
assert set(action.capabilities) <= set(recipe.latest_revision.capabilities)
def test_filter_object_capabilities_are_automatically_included(self):
filter_object = StableSampleFilter.create(input=["A"], rate=0.1)
recipe = RecipeFactory(filter_object=[filter_object])
assert filter_object.capabilities
assert filter_object.capabilities <= recipe.capabilities
assert filter_object.capabilities <= recipe.latest_revision.capabilities
@pytest.mark.django_db