def setUp(self): self.credentials = ('testuser', 'abc123') self.client = Client(server_url=DEFAULT_SERVER, auth=self.credentials) self.collection = uuid.uuid1() self.bucket = 'deploytest' self.client.create_bucket(self.bucket, if_not_exists=True) self.client.create_collection(self.collection, bucket=self.bucket)
def test_logger_outputs_replication_information(self, logger): origin_session = mock.MagicMock() origin_session.server_url = "http://origin/v1" destination_session = mock.MagicMock() destination_session.server_url = "http://destination/v1" mock_response(origin_session) mock_response(destination_session) origin = Client( session=origin_session, bucket="buck", collection="coll" ) destination = Client( session=destination_session, bucket="buck", collection="coll" ) destination._server_settings = {'batch_max_requests': 15} replicate(origin, destination) msg = ("Replication from <KintoClient http://origin/v1/buckets/buck/" "collections/coll> to <KintoClient http://destination/v1/" "buckets/buck/collections/coll>") logger.info.assert_any_call(msg) logger.info.assert_any_call("replication of 0 records")
def test_multiple_record_deletion(self): client = Client(server_url=self.server_url, auth=self.auth, bucket="mozilla", collection="payments") client.create_bucket() client.create_collection() client.create_record({"foo": "bar"}) client.delete_records() assert len(client.get_records()) == 0
def __init__(self, *args, **kwargs): super(FunctionalTest, self).__init__(*args, **kwargs) self.auth = DEFAULT_AUTH self.private_key = os.path.join(__HERE__, 'config/ecdsa.private.pem') self.signer_config = configparser.RawConfigParser() self.signer_config.read(os.path.join(__HERE__, 'config/signer.ini')) priv_key = self.signer_config.get( 'app:main', 'kinto.signer.ecdsa.private_key') self.signer = ECDSASigner(private_key=priv_key) # Setup the kinto clients for the source and destination. self._auth = DEFAULT_AUTH self._server_url = SERVER_URL self._source_bucket = "source" self._destination_bucket = "destination" self._collection_id = "collection1" self.source = Client( server_url=self._server_url, auth=self._auth, bucket=self._source_bucket, collection=self._collection_id) self.destination = Client( server_url=self._server_url, auth=self._auth, bucket=self._destination_bucket, collection=self._collection_id)
class KintoRecords(Records): def _load(self): self.client = Client(server_url=self.options['server'], auth=self.options['auth'], bucket=self.options['bucket_name'], collection=self.options['collection_name']) # Create bucket self.client.create_bucket() self.client.create_collection(self.options['collection_name'], permissions=self.options['permissions']) # XXX to be removed later # remove the 'onecrl' bucket if it exists try: self.client.delete_bucket('onecrl') except KintoException: pass return [self._kinto2rec(rec) for rec in self.client.get_records()] def _kinto2rec(self, record): return record def delete(self, data): self.client.delete_record(data['id']) def create(self, data): if 'id' not in data: data['id'] = create_id(data) rec = self.client.create_record(data) return rec
def test_bucket_sharing(self): alice_credentials = ("alice", "p4ssw0rd") alice_userid = self.get_user_id(alice_credentials) # Create a bucket and share it with alice. self.client.create_bucket("shared-bucket", permissions={"read": [alice_userid]}) alice_client = Client(server_url=self.server_url, auth=alice_credentials) alice_client.get_bucket("shared-bucket")
def test_collection_sharing(self): alice_credentials = ("alice", "p4ssw0rd") alice_userid = self.get_user_id(alice_credentials) self.client.create_bucket("bob-bucket") self.client.create_collection("shared", bucket="bob-bucket", permissions={"read": [alice_userid]}) # Try to read the collection as Alice. alice_client = Client(server_url=self.server_url, auth=alice_credentials) alice_client.get_collection("shared", bucket="bob-bucket")
def __init__(self, *args, **kwargs): super(FunctionalTest, self).__init__(*args, **kwargs) # XXX Read the configuration from env variables. self.server_url = SERVER_URL self.auth = DEFAULT_AUTH # Read the configuration. self.config = configparser.RawConfigParser() self.config.read(os.path.join(__HERE__, 'config/kinto.ini')) self.client = Client(server_url=self.server_url, auth=self.auth)
class FunctionalTest(unittest.TestCase): def __init__(self, *args, **kwargs): super(FunctionalTest, self).__init__(*args, **kwargs) self.emailer_config = configparser.RawConfigParser() self.emailer_config.read(os.path.join(__HERE__, 'config/kinto.ini')) # Setup the kinto clients for the source and destination. self._auth = DEFAULT_AUTH self._server_url = SERVER_URL self._bucket = "emailer" self._collection = "collection1" self.client = Client( server_url=self._server_url, auth=self._auth, bucket=self._bucket, collection=self._collection) def tearDown(self): # Delete all the created objects. self._flush_server(self._server_url) shutil.rmtree('mail/', ignore_errors=True) def _flush_server(self, server_url): flush_url = urljoin(server_url, '/__flush__') resp = requests.post(flush_url) resp.raise_for_status() def test_new_record_send_email(self): self.client.create_bucket() self.client.create_collection(data={ "kinto-emailer": { 'hooks': [{ "resource_name": "record", "action": "create", "subject": "Action on {root_url}", "template": ("{client_address} edited:\n " "{bucket_id}/{collection_id}/{record_id}."), "recipients": ['*****@*****.**'], }] } }) record = self.client.create_record({'foo': 'bar'})['data'] filename = glob('mail/*.eml')[0] with open(filename, 'r') as f: body = f.read() assert '*****@*****.**' in body assert "Action on http://localhost:8888/v1/" in body assert "127.0.0.1=20edited" in body assert "emailer/collection1/{}".format(record['id']) in body
def test_bucket_sharing(self): alice_credentials = ('alice', 'p4ssw0rd') alice_userid = self.get_user_id(alice_credentials) # Create a bucket and share it with alice. self.client.create_bucket('shared-bucket', permissions={'read': [alice_userid, ]}) alice_client = Client(server_url=self.server_url, auth=alice_credentials) alice_client.get_bucket('shared-bucket')
def test_bucket_sharing(self): alice_credentials = ('alice', 'p4ssw0rd') alice_userid = self.get_user_id(alice_credentials) # Create a bucket and share it with alice. self.client.create_bucket('shared-bucket', permissions={'read': [ alice_userid, ]}) alice_client = Client(server_url=self.server_url, auth=alice_credentials) alice_client.get_bucket('shared-bucket')
def test_collection_argument_takes_precedence(self): mock_response(self.session) # Specify a different collection name for the client and the operation. client = Client(session=self.session, bucket="mybucket", collection="wrong_collection") client.update_record(data={"id": "1234"}, collection="good_collection", permissions=mock.sentinel.permissions) self.session.request.assert_called_with( "put", "/buckets/mybucket/collections/good_collection/records/1234", data={"id": "1234"}, headers=None, permissions=mock.sentinel.permissions, )
def test_single_record_can_overwrite(self): client = Client(server_url=self.server_url, auth=self.auth, bucket="mozilla", collection="payments") client.create_bucket() client.create_collection() created = client.create_record(data={"foo": "bar"}, permissions={"read": ["alexis"]}) client.create_record(data={"id": created["data"]["id"], "bar": "baz"}, safe=False)
class KintoRecords(Records): def _load(self): self.client = Client(server_url=self.options['server'], auth=self.options['auth'], bucket=self.options['bucket_name'], collection=self.options['collection_name']) # Create bucket try: self.client.create_bucket() except KintoException as e: if e.response.status_code != 412: raise e try: self.client.create_collection( permissions=self.options['permissions']) except KintoException as e: if e.response.status_code != 412: raise e return [self._kinto2rec(rec) for rec in self.client.get_records()] def _kinto2rec(self, record): return record def delete(self, data): self.client.delete_record(data['id']) def create(self, data): if 'id' not in data: data['id'] = create_id(data) rec = self.client.create_record(data) return rec
def test_collection_argument_takes_precedence(self): mock_response(self.session) # Specify a different collection name for the client and the operation. client = Client(session=self.session, bucket='mybucket', collection='wrong_collection') client.update_record(data={'id': '1234'}, collection='good_collection', permissions=mock.sentinel.permissions) self.session.request.assert_called_with( 'put', '/buckets/mybucket/collections/good_collection/records/1234', data={'id': '1234'}, headers=None, permissions=mock.sentinel.permissions)
def test_collection_sharing(self): alice_credentials = ('alice', 'p4ssw0rd') alice_userid = self.get_user_id(alice_credentials) self.client.create_bucket('bob-bucket') self.client.create_collection( 'shared', bucket='bob-bucket', permissions={'read': [alice_userid, ]}) # Try to read the collection as Alice. alice_client = Client(server_url=self.server_url, auth=alice_credentials) alice_client.get_collection('shared', bucket='bob-bucket')
def test_records_list_retrieval(self): client = Client(server_url=self.server_url, auth=self.auth, bucket="mozilla", collection="payments") client.create_bucket() client.create_collection() client.create_record(data={"foo": "bar"}, permissions={"read": ["alexis"]}) records = client.get_records() assert len(records) == 1
def test_updating_data_on_a_collection(self): client = Client(server_url=self.server_url, auth=self.auth, bucket='mozilla', collection='payments') client.create_bucket() client.create_collection() client.patch_collection(data={'secret': 'psssssst!'}) collection = client.get_collection() assert collection['data']['secret'] == 'psssssst!'
def test_records_list_retrieval(self): client = Client(server_url=self.server_url, auth=self.auth, bucket='mozilla', collection='payments') client.create_bucket() client.create_collection() client.create_record(data={'foo': 'bar'}, permissions={'read': ['alexis']}) records = client.get_records() assert len(records) == 1
def test_one_record_deletion(self): client = Client(server_url=self.server_url, auth=self.auth, bucket='mozilla', collection='payments') client.create_bucket() client.create_collection() record = client.create_record({'foo': 'bar'}) deleted = client.delete_record(record['data']['id']) assert deleted['deleted'] is True assert len(client.get_records()) == 0
def test_updating_data_on_a_collection(self): client = Client(server_url=self.server_url, auth=self.auth, bucket="mozilla", collection="payments") client.create_bucket() client.create_collection() client.patch_collection(data={"secret": "psssssst!"}) collection = client.get_collection() assert collection["data"]["secret"] == "psssssst!"
def test_collection_sharing(self): alice_credentials = ('alice', 'p4ssw0rd') alice_userid = self.get_user_id(alice_credentials) self.client.create_bucket('bob-bucket') self.client.create_collection('shared', bucket='bob-bucket', permissions={'read': [ alice_userid, ]}) # Try to read the collection as Alice. alice_client = Client(server_url=self.server_url, auth=alice_credentials) alice_client.get_collection('shared', bucket='bob-bucket')
def test_one_record_deletion(self): client = Client(server_url=self.server_url, auth=self.auth, bucket="mozilla", collection="payments") client.create_bucket() client.create_collection() record = client.create_record({"foo": "bar"}) deleted = client.delete_record(record["data"]["id"]) assert deleted["deleted"] is True assert len(client.get_records()) == 0
def test_client_is_represented_properly(self): client = Client(server_url="https://kinto.notmyidea.org/v1", bucket="homebrewing", collection="recipes") expected_repr = ("<KintoClient https://kinto.notmyidea.org/v1/" "buckets/homebrewing/collections/recipes>") assert str(client) == expected_repr
def test_single_record_creation_if_not_exists(self): client = Client(server_url=self.server_url, auth=self.auth, bucket='mozilla', collection='payments') client.create_bucket() client.create_collection() created = client.create_record(data={'foo': 'bar'}) client.create_record(data={'id': created['data']['id'], 'bar': 'baz'}, if_not_exists=True)
def test_records_paginated_list_retrieval(self): client = Client(server_url=self.server_url, auth=self.auth, bucket="mozilla", collection="payments") client.create_bucket() client.create_collection() for i in range(10): client.create_record(data={"foo": "bar"}, permissions={"read": ["alexis"]}) # Kinto is running with kinto.paginate_by = 5 records = client.get_records() assert len(records) == 10
def test_single_record_doesnt_overwrite(self): client = Client(server_url=self.server_url, auth=self.auth, bucket="mozilla", collection="payments") client.create_bucket() client.create_collection() created = client.create_record(data={"foo": "bar"}, permissions={"read": ["alexis"]}) with self.assertRaises(KintoException): # Create a second record with the ID of the first one. client.create_record(data={"id": created["data"]["id"], "bar": "baz"})
def test_records_paginated_list_retrieval(self): client = Client(server_url=self.server_url, auth=self.auth, bucket='mozilla', collection='payments') client.create_bucket() client.create_collection() for i in range(10): client.create_record(data={'foo': 'bar'}, permissions={'read': ['alexis']}) # Kinto is running with kinto.paginate_by = 5 records = client.get_records() assert len(records) == 10
def test_single_record_creation_if_not_exists(self): client = Client(server_url=self.server_url, auth=self.auth, bucket='mozilla', collection='payments') client.create_bucket() client.create_collection() created = client.create_record(data={'foo': 'bar'}) client.create_record(data={ 'id': created['data']['id'], 'bar': 'baz' }, if_not_exists=True)
def test_single_record_can_overwrite(self): client = Client(server_url=self.server_url, auth=self.auth, bucket='mozilla', collection='payments') client.create_bucket() client.create_collection() created = client.create_record(data={'foo': 'bar'}, permissions={'read': ['alexis']}) client.create_record(data={'id': created['data']['id'], 'bar': 'baz'}, safe=False)
def test_record_creation_and_retrieval(self): client = Client(server_url=self.server_url, auth=self.auth, bucket="mozilla", collection="payments") client.create_bucket() client.create_collection() created = client.create_record(data={"foo": "bar"}, permissions={"read": ["alexis"]}) record = client.get_record(created["data"]["id"]) assert "alexis" in record["permissions"]["read"]
def test_record_creation_and_retrieval(self): client = Client(server_url=self.server_url, auth=self.auth, bucket='mozilla', collection='payments') client.create_bucket() client.create_collection() created = client.create_record(data={'foo': 'bar'}, permissions={'read': ['alexis']}) record = client.get_record(created['data']['id']) assert 'alexis' in record['permissions']['read']
def test_single_record_save(self): client = Client(server_url=self.server_url, auth=self.auth, bucket="mozilla", collection="payments") client.create_bucket() client.create_collection() created = client.create_record(data={"foo": "bar"}, permissions={"read": ["alexis"]}) created["data"]["bar"] = "baz" # XXX enhance this in order to have to pass only one argument, created. client.update_record(id=created["data"]["id"], data=created["data"]) retrieved = client.get_record(created["data"]["id"]) assert "alexis" in retrieved["permissions"]["read"] assert retrieved["data"]["foo"] == u"bar" assert retrieved["data"]["bar"] == u"baz" assert created["data"]["id"] == retrieved["data"]["id"]
def test_single_record_can_overwrite(self): client = Client(server_url=self.server_url, auth=self.auth, bucket='mozilla', collection='payments') client.create_bucket() client.create_collection() created = client.create_record(data={'foo': 'bar'}, permissions={'read': ['alexis']}) client.create_record(data={ 'id': created['data']['id'], 'bar': 'baz' }, safe=False)
def test_single_record_save(self): client = Client(server_url=self.server_url, auth=self.auth, bucket='mozilla', collection='payments') client.create_bucket() client.create_collection() created = client.create_record(data={'foo': 'bar'}, permissions={'read': ['alexis']}) created['data']['bar'] = 'baz' # XXX enhance this in order to have to pass only one argument, created. client.update_record(id=created['data']['id'], data=created['data']) retrieved = client.get_record(created['data']['id']) assert 'alexis' in retrieved['permissions']['read'] assert retrieved['data']['foo'] == u'bar' assert retrieved['data']['bar'] == u'baz' assert created['data']['id'] == retrieved['data']['id']
def test_single_record_doesnt_overwrite(self): client = Client(server_url=self.server_url, auth=self.auth, bucket='mozilla', collection='payments') client.create_bucket() client.create_collection() created = client.create_record(data={'foo': 'bar'}, permissions={'read': ['alexis']}) with self.assertRaises(KintoException): # Create a second record with the ID of the first one. client.create_record(data={'id': created['data']['id'], 'bar': 'baz'})
def test_single_record_doesnt_overwrite(self): client = Client(server_url=self.server_url, auth=self.auth, bucket='mozilla', collection='payments') client.create_bucket() client.create_collection() created = client.create_record(data={'foo': 'bar'}, permissions={'read': ['alexis']}) with self.assertRaises(KintoException): # Create a second record with the ID of the first one. client.create_record(data={ 'id': created['data']['id'], 'bar': 'baz' })
def main(): # pragma: nocover args = get_arguments() cli_utils.setup_logger(logger, args) origin = Client(server_url=args.origin_server, auth=args.origin_auth or args.auth, bucket=args.origin_bucket or args.bucket, collection=args.origin_collection or args.collection) destination = cli_utils.create_client_from_args(args) replicate(origin, destination)
def _load(self): self.client = Client(server_url=self.options['server'], auth=self.options['auth'], bucket=self.options['bucket_name'], collection=self.options['collection_name']) # Create bucket try: self.client.create_bucket() except KintoException as e: if e.response.status_code != 412: raise e try: self.client.create_collection( permissions=self.options['permissions']) except KintoException as e: if e.response.status_code != 412: raise e return [self._kinto2rec(rec) for rec in self.client.get_records()]
def test_replication(self): # First, create a few records on the first kinto collection. with self.client.batch(bucket='origin', collection='coll') as batch: batch.create_bucket() batch.create_collection() for n in range(10): batch.create_record(data={'foo': 'bar', 'n': n}) origin = Client(server_url=self.server_url, auth=self.auth, bucket='origin', collection='coll') destination = Client(server_url=self.server_url, auth=self.auth, bucket='destination', collection='coll') replication.replicate(origin, destination) records = self.client.get_records(bucket='destination', collection='coll') assert len(records) == 10
def setUp(self): # Figure out what the IP address where the containers are running f = os.popen('which docker-machine') docker_machine = str(f.read()).strip() if string.find(docker_machine, "/docker-machine") == -1: print("Could not find docker-machine in our path") exit() f = os.popen('%s ip default' % docker_machine) ip = str(f.read()).strip() # Set our master and read-only end points and create our test bucket self.master_url = "http://%s:8888/v1/" % ip self.read_only_url = "http://%s:8889/v1/" % ip self.credentials = ('testuser', 'abc123') self.master = Client(server_url=self.master_url, auth=self.credentials) self.read_only = Client(server_url=self.read_only_url, auth=self.credentials) self.bucket = self.get_timestamp() self.master.create_bucket(self.bucket) self.read_only.create_bucket(self.bucket)
def test_record_sharing(self): alice_credentials = ('alice', 'p4ssw0rd') alice_userid = self.get_user_id(alice_credentials) # Create a record, and share it with Alice. self.client.create_bucket('bob-bucket') self.client.create_collection('bob-personal-collection', bucket='bob-bucket') record = self.client.create_record( data={'foo': 'bar'}, permissions={'read': [ alice_userid, ]}, bucket='bob-bucket', collection='bob-personal-collection') # Try to read the record as Alice alice_client = Client(server_url=self.server_url, auth=alice_credentials) record = alice_client.get_record(id=record['data']['id'], bucket='bob-bucket', collection='bob-personal-collection') assert record['data']['foo'] == 'bar'
class ClientTest(unittest.TestCase): def setUp(self): self.session = mock.MagicMock() self.client = Client(session=self.session) mock_response(self.session) def test_context_manager_works_as_expected(self): settings = {"batch_max_requests": 25} self.session.request.side_effect = [({ "settings": settings }, []), ({ "responses": [] }, [])] with self.client.batch(bucket='mozilla', collection='test') as batch: batch.create_record(id=1234, data={'foo': 'bar'}) batch.create_record(id=5678, data={'bar': 'baz'}) self.session.request.assert_called_with( method='POST', endpoint='/batch', payload={ 'requests': [{ 'body': { 'data': { 'foo': 'bar' } }, 'path': '/buckets/mozilla/collections/test/records/1234', 'method': 'PUT', 'headers': { 'If-None-Match': '*' } }, { 'body': { 'data': { 'bar': 'baz' } }, 'path': '/buckets/mozilla/collections/test/records/5678', 'method': 'PUT', 'headers': { 'If-None-Match': '*' } }] }) def test_batch_raises_exception(self): # Make the next call to sess.request raise a 403. exception = KintoException() exception.response = mock.MagicMock() exception.response.status_code = 403 exception.request = mock.sentinel.request self.session.request.side_effect = exception with self.assertRaises(KintoException): with self.client.batch(bucket='moz', collection='test') as batch: batch.create_record(id=1234, data={'foo': 'bar'}) def test_batch_raises_exception_if_subrequest_failed(self): error = { "errno": 121, "message": "This user cannot access this resource.", "code": 403, "error": "Forbidden" } self.session.request.side_effect = [({ "settings": { "batch_max_requests": 25 } }, []), ({ "responses": [{ "status": 200, "path": "/url1", "body": {}, "headers": {} }, { "status": 404, "path": "/url2", "body": error, "headers": {} }] }, [])] with self.assertRaises(KintoException): with self.client.batch(bucket='moz', collection='test') as batch: batch.create_record(id=1234, data={'foo': 'bar'}) batch.create_record(id=5678, data={'tutu': 'toto'}) def test_batch_options_are_transmitted(self): settings = {"batch_max_requests": 25} self.session.request.side_effect = [({"settings": settings}, [])] with mock.patch('kinto_client.create_session') as create_session: with self.client.batch(bucket='moz', collection='test', retry=12, retry_after=20): _, last_call_kwargs = create_session.call_args_list[-1] self.assertEqual(last_call_kwargs['retry'], 12) self.assertEqual(last_call_kwargs['retry_after'], 20) def test_client_is_represented_properly(self): client = Client(server_url="https://kinto.notmyidea.org/v1", bucket="homebrewing", collection="recipes") expected_repr = ("<KintoClient https://kinto.notmyidea.org/v1/" "buckets/homebrewing/collections/recipes>") assert str(client) == expected_repr def test_client_uses_default_bucket_if_not_specified(self): mock_response(self.session) client = Client(session=self.session) client.get_bucket() self.session.request.assert_called_with('get', '/buckets/default') def test_client_uses_passed_bucket_if_specified(self): client = Client(server_url="https://kinto.notmyidea.org/v1", bucket="buck") assert client._bucket_name == "buck"
class BucketTest(unittest.TestCase): def setUp(self): self.session = mock.MagicMock() self.client = Client(session=self.session) mock_response(self.session) def test_put_is_issued_on_creation(self): self.client.create_bucket('testbucket') self.session.request.assert_called_with('put', '/buckets/testbucket', data=None, permissions=None, headers=DO_NOT_OVERWRITE) def test_put_is_issued_on_update(self): self.client.update_bucket('testbucket', data={ 'foo': 'bar', 'last_modified': '1234' }, permissions={'read': ['natim']}) self.session.request.assert_called_with( 'put', '/buckets/testbucket', data={ 'foo': 'bar', 'last_modified': '1234' }, permissions={'read': ['natim']}, headers={'If-Match': '"1234"'}) def test_patch_is_issued_on_patch(self): self.client.create_bucket('testbucket') self.client.patch_bucket('testbucket', data={'foo': 'bar'}, permissions={'read': ['natim']}) self.session.request.assert_called_with( 'patch', '/buckets/testbucket', data={'foo': 'bar'}, permissions={'read': ['natim']}, headers=None) def test_update_bucket_handles_last_modified(self): self.client.update_bucket('testbucket', data={'foo': 'bar'}, last_modified=1234) self.session.request.assert_called_with('put', '/buckets/testbucket', data={'foo': 'bar'}, permissions=None, headers={'If-Match': '"1234"'}) def test_get_is_issued_on_list_retrieval(self): self.client.get_buckets() self.session.request.assert_called_with('get', '/buckets', headers={}, params={}) def test_get_is_issued_on_retrieval(self): self.client.get_bucket('testbucket') self.session.request.assert_called_with('get', '/buckets/testbucket') def test_bucket_names_are_slugified(self): self.client.get_bucket('my bucket') url = '/buckets/my-bucket' self.session.request.assert_called_with('get', url) def test_permissions_are_retrieved(self): mock_response(self.session, permissions={'read': [ 'phrawzty', ]}) bucket = self.client.get_bucket('testbucket') self.assertIn('phrawzty', bucket['permissions']['read']) def test_unexisting_bucket_raises(self): # Make the next call to sess.request raise a 403. exception = KintoException() exception.response = mock.MagicMock() exception.response.status_code = 403 exception.request = mock.sentinel.request self.session.request.side_effect = exception with self.assertRaises(BucketNotFound) as cm: self.client.get_bucket('test') e = cm.exception self.assertEquals(e.response, exception.response) self.assertEquals(e.request, mock.sentinel.request) self.assertEquals(e.message, 'test') def test_http_500_raises_an_error(self): exception = KintoException() exception.response = mock.MagicMock() exception.response.status_code = 400 exception.request = mock.sentinel.request self.session.request.side_effect = exception try: self.client.get_bucket('test') except KintoException as e: self.assertEquals(e.response, exception.response) self.assertEquals(e.request, mock.sentinel.request) else: self.fail("Exception not raised") def test_delete_bucket_returns_the_contained_data(self): mock_response(self.session, data={'deleted': True}) assert self.client.delete_bucket('bucket') == {'deleted': True} def test_delete_bucket_handles_last_modified(self): self.client.delete_bucket('mybucket', last_modified=1234) url = '/buckets/mybucket' headers = {'If-Match': '"1234"'} self.session.request.assert_called_with('delete', url, headers=headers) def test_delete_is_issued_on_list_deletion(self): self.client.delete_buckets() self.session.request.assert_called_with('delete', '/buckets', headers=None) def test_get_or_create_dont_raise_in_case_of_conflict(self): bucket_data = { 'permissions': mock.sentinel.permissions, 'data': { 'foo': 'bar' } } self.session.request.side_effect = [ get_http_error(status=412), (bucket_data, None) ] returned_data = self.client.create_bucket( "buck", if_not_exists=True) # Should not raise. assert returned_data == bucket_data def test_get_or_create_raise_in_other_cases(self): self.session.request.side_effect = get_http_error(status=500) with self.assertRaises(KintoException): self.client.create_bucket(bucket="buck", if_not_exists=True)
def setUp(self): self.session = mock.MagicMock() mock_response(self.session) self.client = Client(session=self.session, bucket='mybucket')
class RecordTest(unittest.TestCase): def setUp(self): self.session = mock.MagicMock() self.client = Client(session=self.session, bucket='mybucket', collection='mycollection') def test_record_id_is_given_after_creation(self): mock_response(self.session, data={'id': 5678}) record = self.client.create_record({'foo': 'bar'}) assert 'id' in record['data'].keys() def test_generated_record_id_is_an_uuid(self): mock_response(self.session) self.client.create_record({'foo': 'bar'}) id = self.session.request.mock_calls[0][1][1].split('/')[-1] uuid_regexp = r'[\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}' self.assertRegexpMatches(id, uuid_regexp) def test_records_handles_permissions(self): mock_response(self.session) self.client.create_record({ 'id': '1234', 'foo': 'bar' }, permissions=mock.sentinel.permissions) self.session.request.assert_called_with( 'put', '/buckets/mybucket/collections/mycollection/records/1234', data={ 'foo': 'bar', 'id': '1234' }, permissions=mock.sentinel.permissions, headers=DO_NOT_OVERWRITE) def test_collection_argument_takes_precedence(self): mock_response(self.session) # Specify a different collection name for the client and the operation. client = Client(session=self.session, bucket='mybucket', collection='wrong_collection') client.update_record(data={'id': '1234'}, collection='good_collection', permissions=mock.sentinel.permissions) self.session.request.assert_called_with( 'put', '/buckets/mybucket/collections/good_collection/records/1234', data={'id': '1234'}, headers=None, permissions=mock.sentinel.permissions) def test_record_id_is_derived_from_data_if_present(self): mock_response(self.session) self.client.create_record(data={ 'id': '1234', 'foo': 'bar' }, permissions=mock.sentinel.permissions) self.session.request.assert_called_with( 'put', '/buckets/mybucket/collections/mycollection/records/1234', data={ 'id': '1234', 'foo': 'bar' }, permissions=mock.sentinel.permissions, headers=DO_NOT_OVERWRITE) def test_data_and_permissions_are_added_on_create(self): mock_response(self.session) data = {'foo': 'bar'} permissions = {'read': ['mle']} self.client.create_record(id='1234', data=data, permissions=permissions) url = '/buckets/mybucket/collections/mycollection/records/1234' self.session.request.assert_called_with('put', url, data=data, permissions=permissions, headers=DO_NOT_OVERWRITE) def test_creation_sends_if_none_match_by_default(self): mock_response(self.session) data = {'foo': 'bar'} self.client.create_record(id='1234', data=data) url = '/buckets/mybucket/collections/mycollection/records/1234' self.session.request.assert_called_with('put', url, data=data, permissions=None, headers=DO_NOT_OVERWRITE) def test_creation_doesnt_add_if_none_match_when_overwrite(self): mock_response(self.session) data = {'foo': 'bar'} self.client.create_record(id='1234', data=data, safe=False) url = '/buckets/mybucket/collections/mycollection/records/1234' self.session.request.assert_called_with('put', url, data=data, permissions=None, headers=None) def test_records_issues_a_request_on_delete(self): mock_response(self.session) self.client.delete_record('1234') url = '/buckets/mybucket/collections/mycollection/records/1234' self.session.request.assert_called_with('delete', url, headers=None) def test_record_issues_a_request_on_retrieval(self): mock_response(self.session, data={'foo': 'bar'}) record = self.client.get_record('1234') self.assertEquals(record['data'], {'foo': 'bar'}) url = '/buckets/mybucket/collections/mycollection/records/1234' self.session.request.assert_called_with('get', url) def test_collection_can_retrieve_all_records(self): mock_response(self.session, data=[{'id': 'foo'}, {'id': 'bar'}]) records = self.client.get_records() assert list(records) == [{'id': 'foo'}, {'id': 'bar'}] def test_pagination_is_followed(self): # Mock the calls to request. link = ('http://example.org/buckets/buck/collections/coll/records/' '?token=1234') self.session.request.side_effect = [ # First one returns a list of items with a pagination token. build_response([ { 'id': '1', 'value': 'item1' }, { 'id': '2', 'value': 'item2' }, ], {'Next-Page': link}), # Second one returns a list of items without a pagination token. build_response([ { 'id': '3', 'value': 'item3' }, { 'id': '4', 'value': 'item4' }, ], ), ] records = self.client.get_records('bucket', 'collection') assert list(records) == [ { 'id': '1', 'value': 'item1' }, { 'id': '2', 'value': 'item2' }, { 'id': '3', 'value': 'item3' }, { 'id': '4', 'value': 'item4' }, ] def test_pagination_supports_if_none_match(self): link = ('http://example.org/buckets/buck/collections/coll/records/' '?token=1234') self.session.request.side_effect = [ # First one returns a list of items with a pagination token. build_response([ { 'id': '1', 'value': 'item1' }, { 'id': '2', 'value': 'item2' }, ], {'Next-Page': link}), # Second one returns a list of items without a pagination token. build_response([ { 'id': '3', 'value': 'item3' }, { 'id': '4', 'value': 'item4' }, ], ), ] self.client.get_records('bucket', 'collection', if_none_match="1234") # Check that the If-None-Match header is present in the requests. self.session.request.assert_any_call( 'get', '/buckets/collection/collections/bucket/records', headers={'If-None-Match': '"1234"'}, params={}) self.session.request.assert_any_call( 'get', link, headers={'If-None-Match': '"1234"'}, params={}) def test_collection_can_delete_a_record(self): mock_response(self.session, data={'id': 1234}) resp = self.client.delete_record(id=1234) assert resp == {'id': 1234} url = '/buckets/mybucket/collections/mycollection/records/1234' self.session.request.assert_called_with('delete', url, headers=None) def test_record_delete_if_match(self): data = {} mock_response(self.session, data=data) deleted = self.client.delete_record(collection='mycollection', bucket='mybucket', id='1', last_modified=1234) assert deleted == data url = '/buckets/mybucket/collections/mycollection/records/1' self.session.request.assert_called_with('delete', url, headers={'If-Match': '"1234"'}) def test_record_delete_if_match_not_included_if_not_safe(self): data = {} mock_response(self.session, data=data) deleted = self.client.delete_record(collection='mycollection', bucket='mybucket', id='1', last_modified=1234, safe=False) assert deleted == data url = '/buckets/mybucket/collections/mycollection/records/1' self.session.request.assert_called_with('delete', url, headers=None) def test_update_record_gets_the_id_from_data_if_exists(self): mock_response(self.session) self.client.update_record(bucket='mybucket', collection='mycollection', data={ 'id': 1, 'foo': 'bar' }) self.session.request.assert_called_with( 'put', '/buckets/mybucket/collections/mycollection/records/1', data={ 'id': 1, 'foo': 'bar' }, headers=None, permissions=None) def test_update_record_handles_last_modified(self): mock_response(self.session) self.client.update_record(bucket='mybucket', collection='mycollection', data={ 'id': 1, 'foo': 'bar' }, last_modified=1234) headers = {'If-Match': '"1234"'} self.session.request.assert_called_with( 'put', '/buckets/mybucket/collections/mycollection/records/1', data={ 'id': 1, 'foo': 'bar' }, headers=headers, permissions=None) def test_patch_record_uses_the_patch_method(self): mock_response(self.session) self.client.patch_record(bucket='mybucket', collection='mycollection', data={ 'id': 1, 'foo': 'bar' }) self.session.request.assert_called_with( 'patch', '/buckets/mybucket/collections/mycollection/records/1', data={ 'id': 1, 'foo': 'bar' }, headers=None, permissions=None) def test_update_record_raises_if_no_id_is_given(self): with self.assertRaises(KeyError) as cm: self.client.update_record( data={'foo': 'bar'}, # Omit the id on purpose here. bucket='mybucket', collection='mycollection') assert text_type( cm.exception) == ("'Unable to update a record, need an id.'") def test_get_or_create_doesnt_raise_in_case_of_conflict(self): data = { 'permissions': mock.sentinel.permissions, 'data': { 'foo': 'bar' } } self.session.request.side_effect = [ get_http_error(status=412), (data, None) ] returned_data = self.client.create_record( bucket="buck", collection="coll", data={ 'id': 1234, 'foo': 'bar' }, if_not_exists=True) # Should not raise. assert returned_data == data def test_get_or_create_raise_in_other_cases(self): self.session.request.side_effect = get_http_error(status=500) with self.assertRaises(KintoException): self.client.create_record(bucket="buck", collection="coll", data={'foo': 'bar'}, if_not_exists=True)
def setUp(self): self.session = mock.MagicMock() self.client = Client(session=self.session) mock_response(self.session)
def test_client_uses_passed_bucket_if_specified(self): client = Client(server_url="https://kinto.notmyidea.org/v1", bucket="buck") assert client._bucket_name == "buck"
class CollectionTest(unittest.TestCase): def setUp(self): self.session = mock.MagicMock() mock_response(self.session) self.client = Client(session=self.session, bucket='mybucket') def test_collection_names_are_slugified(self): self.client.get_collection('my collection') url = '/buckets/mybucket/collections/my-collection' self.session.request.assert_called_with('get', url) def test_collection_creation_issues_an_http_put(self): self.client.create_collection('mycollection', permissions=mock.sentinel.permissions) url = '/buckets/mybucket/collections/mycollection' self.session.request.assert_called_with( 'put', url, data=None, permissions=mock.sentinel.permissions, headers=DO_NOT_OVERWRITE) def test_data_can_be_sent_on_creation(self): self.client.create_collection('mycollection', 'testbucket', data={'foo': 'bar'}) self.session.request.assert_called_with( 'put', '/buckets/testbucket/collections/mycollection', data={'foo': 'bar'}, permissions=None, headers=DO_NOT_OVERWRITE) def test_collection_update_issues_an_http_put(self): self.client.update_collection({'foo': 'bar'}, collection='mycollection', permissions=mock.sentinel.permissions) url = '/buckets/mybucket/collections/mycollection' self.session.request.assert_called_with( 'put', url, data={'foo': 'bar'}, permissions=mock.sentinel.permissions, headers=None) def test_update_handles_last_modified(self): self.client.update_collection({'foo': 'bar'}, collection='mycollection', last_modified=1234) url = '/buckets/mybucket/collections/mycollection' headers = {'If-Match': '"1234"'} self.session.request.assert_called_with('put', url, data={'foo': 'bar'}, headers=headers, permissions=None) def test_collection_update_use_an_if_match_header(self): data = {'foo': 'bar', 'last_modified': '1234'} self.client.update_collection(data, collection='mycollection', permissions=mock.sentinel.permissions) url = '/buckets/mybucket/collections/mycollection' self.session.request.assert_called_with( 'put', url, data={ 'foo': 'bar', 'last_modified': '1234' }, permissions=mock.sentinel.permissions, headers={'If-Match': '"1234"'}) def test_patch_collection_issues_an_http_patch(self): self.client.patch_collection(collection='mycollection', data={'key': 'secret'}) url = '/buckets/mybucket/collections/mycollection' self.session.request.assert_called_with('patch', url, data={'key': 'secret'}, headers=None, permissions=None) def test_patch_collection_handles_last_modified(self): self.client.patch_collection(collection='mycollection', data={'key': 'secret'}, last_modified=1234) url = '/buckets/mybucket/collections/mycollection' headers = {'If-Match': '"1234"'} self.session.request.assert_called_with('patch', url, data={'key': 'secret'}, headers=headers, permissions=None) def test_get_collections_returns_the_list_of_collections(self): mock_response(self.session, data=[ { 'id': 'foo', 'last_modified': '12345' }, { 'id': 'bar', 'last_modified': '59874' }, ]) collections = self.client.get_collections(bucket='default') assert list(collections) == [ { 'id': 'foo', 'last_modified': '12345' }, { 'id': 'bar', 'last_modified': '59874' }, ] def test_collection_can_delete_all_its_records(self): self.client.delete_records(bucket='abucket', collection='acollection') url = '/buckets/abucket/collections/acollection/records' self.session.request.assert_called_with('delete', url, headers=None) def test_delete_is_issued_on_list_deletion(self): self.client.delete_collections(bucket='mybucket') url = '/buckets/mybucket/collections' self.session.request.assert_called_with('delete', url, headers=None) def test_collection_can_be_deleted(self): data = {} mock_response(self.session, data=data) deleted = self.client.delete_collection('mycollection') assert deleted == data url = '/buckets/mybucket/collections/mycollection' self.session.request.assert_called_with('delete', url, headers=None) def test_collection_delete_if_match(self): data = {} mock_response(self.session, data=data) deleted = self.client.delete_collection('mycollection', last_modified=1234) assert deleted == data url = '/buckets/mybucket/collections/mycollection' self.session.request.assert_called_with('delete', url, headers={'If-Match': '"1234"'}) def test_collection_delete_if_match_not_included_if_not_safe(self): data = {} mock_response(self.session, data=data) deleted = self.client.delete_collection('mycollection', last_modified=1324, safe=False) assert deleted == data url = '/buckets/mybucket/collections/mycollection' self.session.request.assert_called_with('delete', url, headers=None) def test_get_or_create_doesnt_raise_in_case_of_conflict(self): data = { 'permissions': mock.sentinel.permissions, 'data': { 'foo': 'bar' } } self.session.request.side_effect = [ get_http_error(status=412), (data, None) ] returned_data = self.client.create_collection( bucket="buck", collection="coll", if_not_exists=True) # Should not raise. assert returned_data == data def test_get_or_create_raise_in_other_cases(self): self.session.request.side_effect = get_http_error(status=500) with self.assertRaises(KintoException): self.client.create_collection(bucket="buck", collection="coll", if_not_exists=True)
def setUp(self): self.session = mock.MagicMock() self.client = Client(session=self.session, bucket='mybucket', collection='mycollection')