コード例 #1
0
    def test_unpublish_reverts_changes_if_approval_fails(
            self, rs_urls, rs_settings, requestsmock):
        recipe = RecipeFactory(name="Test", approver=UserFactory())
        baseline_record_url = rs_urls["workspace"]["baseline"][
            "record"].format(recipe.id)
        capabilities_record_url = rs_urls["workspace"]["capabilities"][
            "record"].format(recipe.id)
        # Deleting the record works.
        requestsmock.request("delete",
                             baseline_record_url,
                             json={"data": {
                                 "deleted": True
                             }})
        requestsmock.request("delete",
                             capabilities_record_url,
                             json={"data": {
                                 "deleted": True
                             }})

        requestsmock.request("patch",
                             rs_urls["workspace"]["baseline"]["collection"],
                             json={"data": {}})
        requestsmock.register_uri(
            "patch",
            rs_urls["workspace"]["capabilities"]["collection"],
            [
                # Approving fails.
                {
                    "status_code": 403
                },
                # Rollback succeeds.
                {
                    "status_code": 200,
                    "json": {
                        "data": {}
                    }
                },
            ],
        )

        remotesettings = exports.RemoteSettings()
        with pytest.raises(kinto_http.KintoException):
            remotesettings.unpublish(recipe)

        requests = requestsmock.request_history
        assert len(requests) == 5
        # Unpublish the recipe in both collections
        assert requests[0].url == capabilities_record_url
        assert requests[0].method == "DELETE"
        assert requests[1].url == baseline_record_url
        assert requests[1].method == "DELETE"
        # Try (and fail) to approve the capabilities change
        assert requests[2].url == rs_urls["workspace"]["capabilities"][
            "collection"]
        assert requests[2].method == "PATCH"
        # so it rollsback both collections
        assert requests[3].method == "PATCH"
        assert requests[3].url == rs_urls["workspace"]["capabilities"][
            "collection"]
        assert requests[4].method == "PATCH"
        assert requests[4].url == rs_urls["workspace"]["baseline"][
            "collection"]
コード例 #2
0
 def test_cant_change_signature_and_other_fields(self):
     recipe = RecipeFactory(name="unchanged", signed=False)
     recipe.signature = SignatureFactory()
     with pytest.raises(ValidationError) as exc_info:
         recipe.revise(name="changed")
     assert exc_info.value.message == "Signatures must change alone"
コード例 #3
0
 def test_recipe_force_revise(self):
     recipe = RecipeFactory(name="my name")
     revision_id = recipe.revision_id
     recipe.revise(name="my name", force=True)
     assert revision_id != recipe.revision_id
コード例 #4
0
ファイル: testcases.py プロジェクト: leplatrem/normandy
def console_log(message, **kwargs):
    return RecipeFactory(action=Action.objects.get(name='console-log'),
                         arguments={'message': message},
                         **kwargs)
コード例 #5
0
    def test_filter_expression(self):
        r = RecipeFactory(extra_filter_expression="", filter_object_json=None)
        assert r.filter_expression == ""

        r = RecipeFactory(extra_filter_expression="2 + 2 == 4", filter_object_json=None)
        assert r.filter_expression == "2 + 2 == 4"
コード例 #6
0
ファイル: test_api.py プロジェクト: andymikulski/normandy
 def test_it_serves_revisions(self, api_client):
     recipe = RecipeFactory()
     res = api_client.get('/api/v2/recipe_revision/%s/' %
                          recipe.latest_revision.id)
     assert res.status_code == 200
     assert res.data['id'] == recipe.latest_revision.id
コード例 #7
0
 def test_revision_id_changes(self):
     """Ensure that the revision id is incremented on each save"""
     recipe = RecipeFactory()
     revision_id = recipe.revision_id
     recipe.revise(action=ActionFactory())
     assert recipe.revision_id != revision_id
コード例 #8
0
ファイル: test_api.py プロジェクト: mythmon/normandy
 def test_it_works(self, api_client):
     recipe = RecipeFactory()
     res = api_client.get(f"/api/v1/recipe/{recipe.id}/")
     assert res.status_code == 200, res.data
     assert res.data["id"] == recipe.id
コード例 #9
0
ファイル: test_commands.py プロジェクト: mythmon/normandy
 def test_it_unsigns_disabled_recipes(self, mocked_autograph):
     r = RecipeFactory(approver=UserFactory(), signed=True)
     call_command("update_recipe_signatures")
     r.refresh_from_db()
     assert r.signature is None
コード例 #10
0
ファイル: test_factories.py プロジェクト: mythmon/normandy
 def test_signed_false(self):
     r = RecipeFactory(signed=False)
     assert r.signature is None
コード例 #11
0
ファイル: test_factories.py プロジェクト: mythmon/normandy
 def test_signed_true(self):
     r = RecipeFactory(approver=UserFactory(), signed=True)
     assert r.signature is not None
     assert r.signature.signature == hashlib.sha256(
         r.canonical_json()).hexdigest()
     assert isinstance(r.signature.timestamp, datetime)
コード例 #12
0
 def test_it_unsigns_disabled_recipes(self, mocked_autograph):
     r = RecipeFactory(enabled=False, signed=True)
     call_command('update_recipe_signatures')
     r.refresh_from_db()
     assert r.signature is None
コード例 #13
0
 def test_it_signs_unsigned_enabled_recipes(self, mocked_autograph):
     r = RecipeFactory(approver=UserFactory(), enabled=True, signed=False)
     call_command('update_recipe_signatures')
     r.refresh_from_db()
     assert r.signature is not None
コード例 #14
0
    def test_publish_and_unpublish_baseline_recipe_to_both_collections(
            self, rs_settings, rs_urls, requestsmock):
        ws_urls = rs_urls["workspace"]

        recipe = RecipeFactory()
        rs_settings.BASELINE_CAPABILITIES |= recipe.capabilities
        assert recipe.uses_only_baseline_capabilities()

        # Expect publish calls to both collections
        requestsmock.put(ws_urls["baseline"]["record"].format(recipe.id),
                         json={"data": {}},
                         status_code=201)
        requestsmock.put(ws_urls["capabilities"]["record"].format(recipe.id),
                         json={"data": {}},
                         status_code=201)
        # Expect both workspaces to be approved
        requestsmock.patch(ws_urls["baseline"]["collection"],
                           json={"data": {}})
        requestsmock.patch(ws_urls["capabilities"]["collection"],
                           json={"data": {}})

        remotesettings = exports.RemoteSettings()
        remotesettings.publish(recipe)

        requests = requestsmock.request_history
        assert len(requests) == 4
        # First it publishes a recipe to both collections
        assert requests[0].method == "PUT"
        assert requests[0].url == ws_urls["capabilities"]["record"].format(
            recipe.id)
        assert requests[1].method == "PUT"
        assert requests[1].url == ws_urls["baseline"]["record"].format(
            recipe.id)
        # and then approves both changes
        assert requests[2].method == "PATCH"
        assert requests[2].url == rs_urls["workspace"]["capabilities"][
            "collection"]
        assert requests[3].method == "PATCH"
        assert requests[3].url == rs_urls["workspace"]["baseline"][
            "collection"]

        # reset request history
        requestsmock._adapter.request_history = []

        # Expect delete calls
        requestsmock.delete(ws_urls["baseline"]["record"].format(recipe.id),
                            json={"data": {}})
        requestsmock.delete(ws_urls["capabilities"]["record"].format(
            recipe.id),
                            json={"data": {}})

        remotesettings.unpublish(recipe)

        requests = requestsmock.request_history
        assert len(requests) == 4
        # First it removes the recipe from both collections
        assert requests[0].method == "DELETE"
        assert requests[0].url == ws_urls["capabilities"]["record"].format(
            recipe.id)
        assert requests[1].method == "DELETE"
        assert requests[1].url == ws_urls["baseline"]["record"].format(
            recipe.id)
        # and then approves both changes
        assert requests[2].method == "PATCH"
        assert requests[2].url == rs_urls["workspace"]["capabilities"][
            "collection"]
        assert requests[3].method == "PATCH"
        assert requests[3].url == rs_urls["workspace"]["baseline"][
            "collection"]
コード例 #15
0
 def test_recipe_force_update(self):
     recipe = RecipeFactory(name='my name')
     revision_id = recipe.revision_id
     recipe.update(name='my name', force=True)
     assert revision_id != recipe.revision_id
コード例 #16
0
 def test_latest_revision_changes(self):
     """Ensure that a new revision is created on each save"""
     recipe = RecipeFactory()
     revision_id = recipe.latest_revision.id
     recipe.revise(action=ActionFactory())
     assert recipe.latest_revision.id != revision_id
コード例 #17
0
ファイル: test_api.py プロジェクト: andymikulski/normandy
 def test_detail_sets_no_cookies(self, api_client):
     recipe = RecipeFactory()
     res = api_client.get('/api/v2/recipe/{id}/'.format(id=recipe.id))
     assert res.status_code == 200
     assert res.client.cookies == {}
コード例 #18
0
 def test_uses_extra_capabilities(self):
     recipe = RecipeFactory(extra_capabilities=["test.foo", "test.bar"])
     assert "test.foo" in recipe.latest_revision.capabilities
     assert "test.bar" in recipe.latest_revision.capabilities
コード例 #19
0
ファイル: test_api.py プロジェクト: andymikulski/normandy
    def test_it_serves_recipes(self, api_client):
        recipe = RecipeFactory()

        res = api_client.get('/api/v2/recipe/')
        assert res.status_code == 200
        assert res.data['results'][0]['name'] == recipe.name
コード例 #20
0
 def test_action_name_is_automatically_included(self):
     action = ActionFactory()
     recipe = RecipeFactory(action=action)
     assert set(action.capabilities) <= set(
         recipe.latest_revision.capabilities)
コード例 #21
0
 def test_revise_arguments(self):
     recipe = RecipeFactory(arguments_json="[]")
     recipe.revise(arguments=[{"id": 1}])
     assert recipe.arguments_json == '[{"id": 1}]'
コード例 #22
0
 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.latest_revision.capabilities
コード例 #23
0
ファイル: testcases.py プロジェクト: leplatrem/normandy
def show_heartbeat(**kwargs):
    return RecipeFactory(action=Action.objects.get(name='show-heartbeat'),
                         **kwargs)
コード例 #24
0
ファイル: test_api.py プロジェクト: rbillings/normandy
        def test_it_serves_recipes(self, api_client):
            recipe = RecipeFactory()

            res = api_client.get("/api/v1/recipe/")
            assert res.status_code == 200
            assert res.data[0]["name"] == recipe.name
コード例 #25
0
 def test_signature_is_correct_on_creation_if_autograph_available(self, mocked_autograph):
     recipe = RecipeFactory(approver=UserFactory(), enabler=UserFactory())
     expected_sig = fake_sign([recipe.canonical_json()])[0]["signature"]
     assert recipe.signature.signature == expected_sig
コード例 #26
0
 def test_signature_is_correct_on_creation_if_autograph_available(
         self, mocked_autograph):
     recipe = RecipeFactory()
     expected_sig = hashlib.sha256(recipe.canonical_json()).hexdigest()
     assert recipe.signature.signature == expected_sig
コード例 #27
0
 def test_recipe_revise_arguments(self):
     recipe = RecipeFactory(arguments_json="{}")
     recipe.revise(arguments={"something": "value"})
     assert recipe.arguments_json == '{"something": "value"}'
コード例 #28
0
 def test_recipe_update_arguments(self):
     recipe = RecipeFactory(arguments_json='')
     recipe.update(arguments={'something': 'value'})
     assert recipe.arguments_json == '{"something": "value"}'
コード例 #29
0
 def test_update_logging(self, mock_logger):
     recipe = RecipeFactory(name="my name")
     recipe.revise(name="my name", force=True)
     mock_logger.info.assert_called_with(
         Whatever.contains(str(recipe.id)), extra={"code": INFO_CREATE_REVISION}
     )
コード例 #30
0
ファイル: test_schema.py プロジェクト: mythmon/normandy
 def test_resolve_all_recipes(self, gql_client):
     r = RecipeFactory()
     res = gql_client.execute(GQ().query.allRecipes.fields("id"))
     assert res == {"data": {"allRecipes": [{"id": str(r.id)}]}}