From 07dfd16feadeca2f0d1c751e74b0e42005e794da Mon Sep 17 00:00:00 2001 From: Mathieu Leplatre Date: Fri, 22 Nov 2024 11:50:36 +0100 Subject: [PATCH] Add methods related to Remote Settings plugin (#379) --- src/kinto_http/client.py | 56 ++++++++++++++++++++ src/kinto_http/endpoints.py | 1 + tests/test_client.py | 102 ++++++++++++++++++++++++++++++++++++ 3 files changed, 159 insertions(+) diff --git a/src/kinto_http/client.py b/src/kinto_http/client.py index c7e178e..cb5ccce 100644 --- a/src/kinto_http/client.py +++ b/src/kinto_http/client.py @@ -5,6 +5,7 @@ import logging import mimetypes import os +import random import uuid from collections import OrderedDict from contextlib import contextmanager @@ -940,6 +941,61 @@ def remove_attachment(self, id, bucket=None, collection=None): resp, _ = self.session.request("delete", endpoint) return resp + def get_changeset(self, bucket=None, collection=None, bust_cache=False, **kwargs): + kwargs.setdefault( + "_expected", random.randint(999999000000, 999999999999) if bust_cache else 0 + ) + endpoint = self._get_endpoint("changeset", bucket=bucket, collection=collection) + resp, _ = self.session.request("get", endpoint, params=kwargs) + return resp + + def request_review(self, message, id=None, bucket=None, **kwargs): + return self.patch_collection( + id=id, + bucket=bucket, + data={ + **kwargs.pop("data", {}), + "status": "to-review", + "last_editor_comment": message, + }, + **kwargs, + ) + + def decline_changes(self, message, id=None, bucket=None, **kwargs): + return self.patch_collection( + id=id, + bucket=bucket, + data={ + **kwargs.pop("data", {}), + "status": "work-in-progress", + "last_reviewer_comment": message, + }, + **kwargs, + ) + + def approve_changes(self, id=None, bucket=None, **kwargs): + return self.patch_collection( + id=id, + bucket=bucket, + data={ + **kwargs.pop("data", {}), + "status": "to-sign", + }, + **kwargs, + ) + + def rollback_changes(self, message, id=None, bucket=None, **kwargs): + return self.patch_collection( + id=id, + bucket=bucket, + data={ + **kwargs.pop("data", {}), + "status": "to-rollback", + "last_editor_comment": message, + }, + **kwargs, + ) + def __repr__(self) -> str: if self.collection_name: endpoint = self._get_endpoint( diff --git a/src/kinto_http/endpoints.py b/src/kinto_http/endpoints.py index f632c55..a64bfd4 100644 --- a/src/kinto_http/endpoints.py +++ b/src/kinto_http/endpoints.py @@ -22,6 +22,7 @@ class Endpoints(object): "records": "{root}/buckets/{bucket}/collections/{collection}/records", # NOQA "record": "{root}/buckets/{bucket}/collections/{collection}/records/{id}", # NOQA "attachment": "{root}/buckets/{bucket}/collections/{collection}/records/{id}/attachment", # NOQA + "changeset": "{root}/buckets/{bucket}/collections/{collection}/changeset", # NOQA } def __init__(self, root=""): diff --git a/tests/test_client.py b/tests/test_client.py index e2bce35..3f52bf3 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -1462,3 +1462,105 @@ def test_get_permissions(client_setup: Client): "_sort": "id", }, ) + + +def test_get_changeset_default(client_setup: Client): + client = client_setup + client.collection_name = "foo" + mock_response(client.session) + + client.get_changeset() + client.session.request.assert_called_with( + "get", "/buckets/mybucket/collections/foo/changeset", params={"_expected": 0} + ) + + +def test_get_changeset_bust(client_setup: Client, mocker: MockerFixture): + client = client_setup + mock_response(client.session) + mocked_random = mocker.patch("kinto_http.client.random") + mocked_random.randint.return_value = 42 + + client.get_changeset(collection="bar", bust_cache=True) + client.session.request.assert_called_with( + "get", "/buckets/mybucket/collections/bar/changeset", params={"_expected": 42} + ) + + +def test_get_changeset_params(client_setup: Client, mocker: MockerFixture): + client = client_setup + mock_response(client.session) + + client.get_changeset(bucket="foo", collection="bar", _since='"42"') + client.session.request.assert_called_with( + "get", "/buckets/foo/collections/bar/changeset", params={"_expected": 0, "_since": '"42"'} + ) + + +def test_request_review(client_setup: Client, mocker: MockerFixture): + client = client_setup.clone(collection="cid") + mock_response(client.session) + + client.request_review("r?") + client.session.request.assert_called_with( + "patch", + "/buckets/mybucket/collections/cid", + headers={"Content-Type": "application/json"}, + payload={"data": {"last_editor_comment": "r?", "status": "to-review"}}, + ) + + +def test_request_review_advanced(client_setup: Client, mocker: MockerFixture): + client = client_setup + mock_response(client.session) + + client.request_review("r?", id="cid", data={"field": "foo"}, if_match='"42"') + client.session.request.assert_called_with( + "patch", + "/buckets/mybucket/collections/cid", + headers={"Content-Type": "application/json", "If-Match": '"42"'}, + payload={"data": {"field": "foo", "last_editor_comment": "r?", "status": "to-review"}}, + ) + + +def test_approve_changes(client_setup: Client, mocker: MockerFixture): + client = client_setup + mock_response(client.session) + + client.approve_changes(id="cid", data={"field": "foo"}, if_match='"42"') + client.session.request.assert_called_with( + "patch", + "/buckets/mybucket/collections/cid", + headers={"Content-Type": "application/json", "If-Match": '"42"'}, + payload={"data": {"field": "foo", "status": "to-sign"}}, + ) + + +def test_decline_changes(client_setup: Client, mocker: MockerFixture): + client = client_setup + mock_response(client.session) + + client.decline_changes(message="r-", id="cid", data={"field": "foo"}, if_match='"42"') + client.session.request.assert_called_with( + "patch", + "/buckets/mybucket/collections/cid", + headers={"Content-Type": "application/json", "If-Match": '"42"'}, + payload={ + "data": {"field": "foo", "last_reviewer_comment": "r-", "status": "work-in-progress"} + }, + ) + + +def test_rollback_changes(client_setup: Client, mocker: MockerFixture): + client = client_setup + mock_response(client.session) + + client.rollback_changes(message="cancel", id="cid", data={"field": "foo"}, if_match='"42"') + client.session.request.assert_called_with( + "patch", + "/buckets/mybucket/collections/cid", + headers={"Content-Type": "application/json", "If-Match": '"42"'}, + payload={ + "data": {"field": "foo", "last_editor_comment": "cancel", "status": "to-rollback"} + }, + )