Beispiel #1
0
 def test_records_deletion_when_no_records_exist(self):
     client = Client(server_url=self.server_url, auth=self.auth,
                     bucket='mozilla', collection='payments')
     client.create_bucket()
     client.create_collection()
     deleted_records = client.delete_records()
     assert len(deleted_records) == 0
Beispiel #2
0
 def test_records_deletion_when_no_records_exist(self):
     client = Client(server_url=self.server_url, auth=self.auth,
                     bucket='mozilla', collection='payments')
     client.create_bucket()
     client.create_collection()
     deleted_records = client.delete_records()
     assert len(deleted_records) == 0
Beispiel #3
0
 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
Beispiel #4
0
 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(data={'foo': 'bar'})
     client.delete_records()
     assert len(client.get_records()) == 0
Beispiel #5
0
 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)
Beispiel #6
0
 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
Beispiel #7
0
 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': ['account:alexis']})
     records = client.get_records()
     assert len(records) == 1
Beispiel #8
0
 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)
Beispiel #9
0
 def test_records_timestamp_retrieval(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(data={'foo': 'bar'},
                                   permissions={'read': ['account:alexis']})
     etag = client.get_records_timestamp()
     assert str(etag) == str(record["data"]["last_modified"])
Beispiel #10
0
 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
Beispiel #11
0
 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']
Beispiel #12
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!'
Beispiel #13
0
class CollectionLoggingTest(unittest.TestCase):
    def setUp(self):
        self.session = mock.MagicMock()
        self.client = Client(session=self.session)
        mock_response(self.session)

    def test_create_collection_logs_info_message(self):
        with mock.patch('kinto_http.logger') as mocked_logger:
            self.client.create_collection(id='mozilla',
                                          bucket="buck",
                                          data={'foo': 'bar'},
                                          permissions={'write': [
                                              'blah',
                                          ]})
            mocked_logger.info.assert_called_with(
                "Create collection 'mozilla' in bucket 'buck'")

    def test_update_collection_logs_info_message(self):
        with mock.patch('kinto_http.logger') as mocked_logger:
            self.client.update_collection(
                data={'foo': 'bar'},
                id='mozilla',
                bucket='buck',
                permissions={'write': [
                    'blahblah',
                ]})
            mocked_logger.info.assert_called_with(
                "Update collection 'mozilla' in bucket 'buck'")

    def test_patch_collection_logs_info_message(self):
        with mock.patch('kinto_http.logger') as mocked_logger:
            self.client.patch_collection(data={'foo': 'bar'},
                                         id='mozilla',
                                         bucket='buck',
                                         permissions={'write': [
                                             'blahblah',
                                         ]})
            mocked_logger.info.assert_called_with(
                "Patch collection 'mozilla' in bucket 'buck'")

    def test_get_collection_logs_info_message(self):
        with mock.patch('kinto_http.logger') as mocked_logger:
            self.client.get_collection(id='mozilla', bucket='buck')
            mocked_logger.info.assert_called_with(
                "Get collection 'mozilla' in bucket 'buck'")

    def test_delete_collection_logs_info_message(self):
        with mock.patch('kinto_http.logger') as mocked_logger:
            self.client.delete_collection(id='mozilla', bucket="buck")
            mocked_logger.info.assert_called_with(
                "Delete collection 'mozilla' in bucket 'buck'")

    def test_delete_collections_logs_info_message(self):
        with mock.patch('kinto_http.logger') as mocked_logger:
            self.client.delete_collections(bucket="buck")
            mocked_logger.info.assert_called_with(
                "Delete collections in bucket 'buck'")
Beispiel #14
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!'
Beispiel #15
0
 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': ['account:alexis']})
     record = client.get_record(id=created['data']['id'])
     assert 'account:alexis' in record['permissions']['read']
Beispiel #16
0
 def test_records_timestamp_retrieval(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(data={'foo': 'bar'},
                                   permissions={'read': ['alexis']})
     etag = client.get_records_timestamp()
     assert str(etag) == str(record["data"]["last_modified"])
Beispiel #17
0
 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(data={'foo': 'bar'})
     deleted = client.delete_record(id=record['data']['id'])
     assert deleted['deleted'] is True
     assert len(client.get_records()) == 0
Beispiel #18
0
    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)
Beispiel #19
0
 def test_record_deletion_if_exists(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(data={'foo': 'bar'})
     deleted = client.delete_record(id=record['data']['id'])
     deleted_if_exists = client.delete_record(id=record['data']['id'], if_exists=True)
     assert deleted['deleted'] is True
     assert deleted_if_exists is None
Beispiel #20
0
 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(data={"foo": "bar"})
     client.delete_records()
     assert len(client.get_records()) == 0
Beispiel #21
0
 def test_record_deletion_if_exists(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'])
     deleted_if_exists = client.delete_record(record['data']['id'], if_exists=True)
     assert deleted['deleted'] is True
     assert deleted_if_exists is None
Beispiel #22
0
    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': ['account:alexis']})

        client.create_record(data={'id': created['data']['id'],
                                   'bar': 'baz'}, safe=False)
Beispiel #23
0
    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'})
Beispiel #24
0
 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': ['account:alexis']})
     # Kinto is running with kinto.paginate_by = 5
     records = client.get_records()
     assert len(records) == 10
Beispiel #25
0
 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
Beispiel #26
0
    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': ['account: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'})
Beispiel #27
0
 def test_records_timestamp_retrieval(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(data={"foo": "bar"},
                                   permissions={"read": ["account:alexis"]})
     etag = client.get_records_timestamp()
     assert str(etag) == str(record["data"]["last_modified"])
Beispiel #28
0
 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": ["account:alexis"]})
     record = client.get_record(id=created["data"]["id"])
     assert "account:alexis" in record["permissions"]["read"]
Beispiel #29
0
 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": ["account:alexis"]})
     records = client.get_records()
     assert len(records) == 1
Beispiel #30
0
 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(data={"foo": "bar"})
     deleted = client.delete_record(id=record["data"]["id"])
     assert deleted["deleted"] is True
     assert len(client.get_records()) == 0
Beispiel #31
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!"
Beispiel #32
0
 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)
Beispiel #33
0
 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": ["account:alexis"]})
     # Kinto is running with kinto.paginate_by = 5
     records = client.get_records()
     assert len(records) == 10
Beispiel #34
0
 def test_record_deletion_if_exists(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(data={"foo": "bar"})
     deleted = client.delete_record(id=record["data"]["id"])
     deleted_if_exists = client.delete_record(id=record["data"]["id"],
                                              if_exists=True)
     assert deleted["deleted"] is True
     assert deleted_if_exists is None
Beispiel #35
0
    def test_records_generator_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": ["account:alexis"]})

        pages = list(client.get_paginated_records())

        assert len(pages) == 2
Beispiel #36
0
    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": ["account:alexis"]})

        client.create_record(data={
            "id": created["data"]["id"],
            "bar": "baz"
        },
                             safe=False)
Beispiel #37
0
    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": ["account: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"
            })
Beispiel #38
0
    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']
Beispiel #39
0
    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': ['account: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(id=created['data']['id'])
        assert 'account:alexis' in retrieved['permissions']['read']
        assert retrieved['data']['foo'] == u'bar'
        assert retrieved['data']['bar'] == u'baz'
        assert created['data']['id'] == retrieved['data']['id']
Beispiel #40
0
class CollectionLoggingTest(unittest.TestCase):
    def setUp(self):
        self.session = mock.MagicMock()
        self.client = Client(session=self.session)
        mock_response(self.session)

    def test_create_collection_logs_info_message(self):
        with mock.patch('kinto_http.logger') as mocked_logger:
            self.client.create_collection(
                'mozilla', bucket="buck",
                data={'foo': 'bar'},
                permissions={'write': ['blah', ]})
            mocked_logger.info.assert_called_with(
                "Create collection 'mozilla' in bucket 'buck'")

    def test_update_collection_logs_info_message(self):
        with mock.patch('kinto_http.logger') as mocked_logger:
            self.client.update_collection(
                data={'foo': 'bar'},
                collection='mozilla', bucket='buck',
                permissions={'write': ['blahblah', ]})
            mocked_logger.info.assert_called_with(
                "Update collection 'mozilla' in bucket 'buck'")

    def test_get_collection_logs_info_message(self):
        with mock.patch('kinto_http.logger') as mocked_logger:
            self.client.get_collection(
                'mozilla', bucket='buck')
            mocked_logger.info.assert_called_with(
                "Get collection 'mozilla' in bucket 'buck'")

    def test_delete_collection_logs_info_message(self):
        with mock.patch('kinto_http.logger') as mocked_logger:
            self.client.delete_collection(
                'mozilla', bucket="buck")
            mocked_logger.info.assert_called_with(
                "Delete collection 'mozilla' in bucket 'buck'")

    def test_delete_collections_logs_info_message(self):
        with mock.patch('kinto_http.logger') as mocked_logger:
            self.client.delete_collections(
                bucket="buck")
            mocked_logger.info.assert_called_with(
                "Delete collections in bucket 'buck'")
Beispiel #41
0
    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": ["account: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(id=created["data"]["id"])
        assert "account:alexis" in retrieved["permissions"]["read"]
        assert retrieved["data"]["foo"] == u"bar"
        assert retrieved["data"]["bar"] == u"baz"
        assert created["data"]["id"] == retrieved["data"]["id"]
        #    print(item)



#record = client.delete_record(id='8c3b1c8c-ed5b-46d9-a9f0-681f3debb68c',collection=collection, bucket=bucket)


# F10 vim本地运行python代码,或者分屏,在jupyter里做吧
# http://localhost:8888/v1/buckets/default/collections/tasks/records
# http://localhost:8888/v1/buckets/paperweekly/collections/forum2wechat_todo/records 有记录
# kinto-admin本地有问题

if __name__ == '__main__':
    # 只运行一次
    client.create_bucket(bucket)
    client.create_collection(collection, bucket=bucket)

    #  创建记录 数据单元
    #client.create_record(data={'status': 'todo', 'title': 'Todo #2'},
    #                         collection=collection, bucket=bucket)
    # 获取
    '''
    for i in range(3):
        #push_thread('thread_id2','username','title','content')
        get_threads()
        time.sleep(2)
        push_thread('thread_id','username','title','content')
    '''
    #records = client.get_records(collection=collection, bucket=bucket)

    #client.delete_records(collection=collection,bucket=bucket) #获取即焚
from kinto_http import Client

# Login
credentials = ('paco', '123456')
client = Client(server_url="http://localhost:8888/v1", auth=credentials)

# Create bucket
client.create_collection(id='Tasks', bucket='default')
client.create_collection(id='Test', bucket='default')

# Add records
client.create_record(data={
    'title': 'Create Documentation',
    'description': 'Create docs using Markdown',
    'status': 'Done'
},
                     collection='Test',
                     bucket='default')

client.create_record(data={
    'title': 'Create Dockerfile',
    'description': 'Create Parse Dockerfile',
    'status': 'Done'
},
                     collection='Test',
                     bucket='default')

client.create_record(data={
    'title': 'Update Computer',
    'description': 'Update Solus Distro',
    'status': 'Doing'
Beispiel #44
0
class RecordLoggingTest(unittest.TestCase):
    def setUp(self):
        self.session = mock.MagicMock()
        self.client = Client(session=self.session)
        mock_response(self.session)

    def test_create_record_logs_info_message(self):
        with mock.patch('kinto_http.logger') as mocked_logger:
            self.client.create_bucket(id='buck')
            self.client.create_collection(id='mozilla',
                                          bucket='buck')
            self.client.create_record(
                id='fake-record',
                data={'foo': 'bar'},
                permissions={'write': ['blah', ]},
                bucket='buck',
                collection='mozilla')
            mocked_logger.info.assert_called_with(
                "Create record with id 'fake-record' in collection 'mozilla' in bucket 'buck'")

    def test_update_record_logs_info_message(self):
        with mock.patch('kinto_http.logger') as mocked_logger:
            self.client.create_bucket(id='buck')
            self.client.create_collection(bucket='buck',
                                          id='mozilla')
            self.client.update_record(
                id='fake-record',
                data={'ss': 'aa'},
                bucket='buck',
                collection='mozilla')
            mocked_logger.info.assert_called_with(
                "Update record with id 'fake-record' in collection 'mozilla' in bucket 'buck'")

    def test_get_record_logs_info_message(self):
        with mock.patch('kinto_http.logger') as mocked_logger:
            self.client.create_bucket(id='buck')
            self.client.create_collection(id='mozilla',
                                          bucket='buck')
            self.client.get_record(
                id='fake-record',
                bucket='buck',
                collection='mozilla')
            mocked_logger.info.assert_called_with(
                "Get record with id 'fake-record' from collection 'mozilla' in bucket 'buck'")

    def test_delete_record_logs_info_message(self):
        with mock.patch('kinto_http.logger') as mocked_logger:
            self.client.create_bucket(id='buck')
            self.client.create_collection(id='mozilla',
                                          bucket='buck')
            self.client.delete_record(
                id='fake-record',
                bucket='buck',
                collection='mozilla')
            mocked_logger.info.assert_called_with(
                "Delete record with id 'fake-record' from collection 'mozilla' in bucket 'buck'")

    def test_delete_records_logs_info_message(self):
        with mock.patch('kinto_http.logger') as mocked_logger:
            self.client.create_bucket(id='buck')
            self.client.create_collection(id='mozilla',
                                          bucket='buck')
            self.client.delete_records(
                bucket='buck',
                collection='mozilla')
            mocked_logger.info.assert_called_with(
                "Delete records from collection 'mozilla' in bucket 'buck'")
Beispiel #45
0
def main():
    args = _get_args()

    client = Client(server_url=args.server, auth=tuple(args.auth.split(':')),
                    bucket=args.source_bucket,
                    collection=args.source_col)

    if args.editor_auth is None:
        args.editor_auth = args.auth

    if args.reviewer_auth is None:
        args.reviewer_auth = args.auth

    editor_client = Client(server_url=args.server,
                           auth=tuple(args.editor_auth.split(':')),
                           bucket=args.source_bucket,
                           collection=args.source_col)
    reviewer_client = Client(server_url=args.server,
                             auth=tuple(args.reviewer_auth.split(':')),
                             bucket=args.source_bucket,
                             collection=args.source_col)

    # 0. initialize source bucket/collection (if necessary)
    server_info = client.server_info()
    editor_id = editor_client.server_info()['user']['id']
    reviewer_id = reviewer_client.server_info()['user']['id']
    print('Server: {0}'.format(args.server))
    print('Author: {user[id]}'.format(**server_info))
    print('Editor: {0}'.format(editor_id))
    print('Reviewer: {0}'.format(reviewer_id))

    # 0. check that this collection is well configured.
    signer_capabilities = server_info['capabilities']['signer']

    resources = [r for r in signer_capabilities['resources']
                 if (args.source_bucket, args.source_col) == (r['source']['bucket'], r['source']['collection']) or
                    (args.source_bucket, None) == (r['source']['bucket'], r['source']['collection'])]
    assert len(resources) > 0, 'Specified source not configured to be signed'
    resource = resources[0]
    if 'preview' in resource:
        print('Signoff: {source[bucket]}/{source[collection]} => {preview[bucket]}/{preview[collection]} => {destination[bucket]}/{destination[collection]}'.format(**resource))
    else:
        print('Signoff: {source[bucket]}/{source[collection]} => {destination[bucket]}/{destination[collection]}'.format(**resource))

    print('_' * 80)

    bucket = client.create_bucket(if_not_exists=True)
    client.create_collection(permissions={'write': [editor_id, reviewer_id] + bucket['permissions']['write']}, if_not_exists=True)

    editors_group = resource.get('editors_group') or signer_capabilities['editors_group']
    editors_group = editors_group.format(collection_id=args.source_col)
    client.patch_group(id=editors_group, data={'members': [editor_id]})

    reviewers_group = resource.get('reviewers_group') or signer_capabilities['reviewers_group']
    reviewers_group = reviewers_group.format(collection_id=args.source_col)
    client.patch_group(id=reviewers_group, data={'members': [reviewer_id]})

    if args.reset:
        client.delete_records()
        existing = 0
    else:
        existing_records = client.get_records()
        existing = len(existing_records)

    dest_col = resource['destination'].get('collection') or args.source_col
    dest_client = Client(server_url=args.server,
                         bucket=resource['destination']['bucket'],
                         collection=dest_col)

    preview_client = None
    if 'preview' in resource:
        preview_bucket = resource['preview']['bucket']
        preview_collection = resource['preview'].get('collection') or args.source_col
        preview_client = Client(server_url=args.server,
                                bucket=preview_bucket,
                                collection=preview_collection)

    # 1. upload data
    print('Author uploads 20 random records')
    records = upload_records(client, 20)

    # 2. ask for a signature
    # 2.1 ask for review (noop on old versions)
    print('Editor asks for review')
    data = {"status": "to-review"}
    editor_client.patch_collection(data=data)
    # 2.2 check the preview collection (if enabled)
    if preview_client:
        print('Check preview collection')
        preview_records = preview_client.get_records()
        expected = existing + 20
        assert len(preview_records) == expected, '%s != %s records' % (len(preview_records), expected)
        metadata = preview_client.get_collection()['data']
        preview_signature = metadata.get('signature')
        assert preview_signature, 'Preview collection not signed'
        preview_timestamp = preview_client.get_records_timestamp()
    # 2.3 approve the review
    print('Reviewer approves and triggers signature')
    data = {"status": "to-sign"}
    reviewer_client.patch_collection(data=data)

    # 3. upload more data
    print('Author creates 20 others records')
    upload_records(client, 20)

    print('Editor updates 5 random records')
    for toupdate in random.sample(records, 5):
        editor_client.patch_record(data=dict(newkey=_rand(10), **toupdate))

    print('Author deletes 5 random records')
    for todelete in random.sample(records, 5):
        client.delete_record(id=todelete['id'])

    expected = existing + 20 + 20 - 5

    # 4. ask again for a signature
    # 2.1 ask for review (noop on old versions)
    print('Editor asks for review')
    data = {"status": "to-review"}
    editor_client.patch_collection(data=data)
    # 2.2 check the preview collection (if enabled)
    if preview_client:
        print('Check preview collection')
        preview_records = preview_client.get_records()
        assert len(preview_records) == expected, '%s != %s records' % (len(preview_records), expected)
        # Diff size is 20 + 5 if updated records are also all deleted,
        # or 30 if deletions and updates apply to different records.
        diff_since_last = preview_client.get_records(_since=preview_timestamp)
        assert 25 <= len(diff_since_last) <= 30, 'Changes since last signature are not consistent'

        metadata = preview_client.get_collection()['data']
        assert preview_signature != metadata['signature'], 'Preview collection not updated'

    # 2.3 approve the review
    print('Reviewer approves and triggers signature')
    data = {"status": "to-sign"}
    reviewer_client.patch_collection(data=data)

    # 5. wait for the result

    # 6. obtain the destination records and serialize canonically.

    records = list(dest_client.get_records())
    assert len(records) == expected, '%s != %s records' % (len(records), expected)
    timestamp = dest_client.get_records_timestamp()
    serialized = canonical_json(records, timestamp)
    print('Hash is %r' % compute_hash(serialized))

    # 7. get back the signed hash

    signature = dest_client.get_collection()['data']['signature']

    with open('pub', 'w') as f:
        f.write(signature['public_key'])

    # 8. verify the signature matches the hash
    signer = ECDSASigner(public_key='pub')
    try:
        signer.verify(serialized, signature)
        print('Signature OK')
    except Exception:
        print('Signature KO')
        raise
Beispiel #46
0
class AppWindow(QtWidgets.QMainWindow,Ui_MainWindow):
    def __init__(self, parent = None):
        QtWidgets.QMainWindow.__init__(self, parent)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setupUi(self)




######################################################################################
######################################################################################
        self.settings = Settings()
        self.initRep()
        self.initKintoClient()
        self.syncRecipes()
        self.dlgEditG = Dialog(self)
        self.dlgEditH = DialogH(self)
        self.dlgEditD = DialogD(self)
        self.dlgEditY = DialogL(self)
        self.dlgPref = DialogPref(self)
        self.dlgStep = DialogStep(self)
        self.dlgMash = DialogMash(self)



        self.base = ImportBase()
        self.mashProfileExport = ExportMash()


#        self.base.importBeerXML()
        self.s=0
        self.recipe = None


        #Les connexions
        self.actionEnregistrer.triggered.connect(self.enregistrer)
        self.actionQuitter.triggered.connect(app.quit)
#        self.connect(self.actionQuitter, QtCore.SIGNAL("triggered()"), app, QtCore.SLOT("quit()"))

        self.actionShowJournal.triggered.connect(self.showJournal)


        self.actionEditGrains.triggered.connect(self.editGrains)
        self.actionEditHoublons.triggered.connect(self.editHoublons)
        self.actionEditDivers.triggered.connect(self.editDivers)
        self.actionEditLevures.triggered.connect(self.editLevures)
        self.actionRestaurerIngredients.triggered.connect(self.restoreDataBase)
        self.actionImportIng.triggered.connect(self.importIng)
        self.actionManageProfiles.triggered.connect(self.seeMash)

        self.actionAbout.triggered.connect(self.about)

        self.actionAllTools.triggered.connect(self.showTools)

        self.actionPreferences.triggered.connect(self.dialogPreferences)



        #######################################################################################################
        # Profil de brassage       #########################################################################################################


        self.listWidgetSteps.itemSelectionChanged.connect (self.stepDetails)
        self.listWidgetMashProfiles.itemSelectionChanged.connect (self.mashClicked)
        self.buttonBoxMashDetails.rejected.connect(self.mashRejected)
#        self.comboBoxStepType.addItems(["Infusion", "Température", "Décoction"])
        self.pushButtonStepEdit.clicked.connect(self.stepEdit)
        self.dlgStep.stepChanged.connect(self.stepReload)
        self.pushButtonStepRemove.clicked.connect(self.removeStep)
        self.pushButtonNewStep.clicked.connect(self.addStep)
        self.pushButtonMashEdit.clicked.connect(self.mashEdit)
        self.dlgMash.mashChanged.connect(self.mashReload)
        self.pushButtonNewProfile.clicked.connect(self.addMash)
        self.pushButtonRemoveProfile.clicked.connect(self.removeMash)
        self.pushButtonSaveProfile.clicked.connect(self.saveProfile)

        #La bibliotheque
        ###################################################################################################################
        ###################################################################################################################


        # self.listdir(recettes_dir)
        self.showLib()

###################################################################################################
######## gestion des arguments au lancement du programme  #########################################


        argumentsList=QtWidgets.QApplication.arguments()
        if len(argumentsList) > 1 :
            logger.debug("la liste d'arguments: %s",argumentsList)
            logger.debug("le chemin: %s",argumentsList[1])
            # for part in argumentsList :
            #     recipePath=recipePath + " " + part
            try:
                recipePath= argumentsList[1]
                for part in argumentsList[2:] :
                    recipePath= recipePath +" " + part

                self.openRecipeFile(recipePath)
            except :
                pass
        else:
            pass

########################################################################################################################
####################################################################################################################
# le signal émit à la fermeture de la fenêtre de préférences
        self.dlgPref.prefAccepted.connect(self.prefReload)



###########################################################
############### Journal ##############################
######################################################

    def loadJournal(self):
        self.journal=Journal()
        self.journal.loadJournal()
        # self.actionEditJournal.setEnabled(True)

    @QtCore.pyqtSlot()
    def showJournal(self,entry=" '' ") :
        self.stackedWidget.setCurrentIndex(0)
        self.loadJournal()
        pyDir = os.path.abspath(os.path.dirname(__file__))
        baseUrl = QtCore.QUrl.fromLocalFile(os.path.join(pyDir, "static/"))
        self.webViewBiblio.setHtml(self.journal.export("html",entry), baseUrl)
        self.webViewBiblio.page().mainFrame().addToJavaScriptWindowObject("main", self)
        # self.webViewBiblio.page().settings().setAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled, True)
        # self.webInspector = QtWebKit.QWebInspector(self)
        # self.webInspector.setPage(self.webViewBiblio.page())
        # self.webInspector.setVisible(True)
        # self.verticalLayout_13.addWidget(self.webInspector)


    @QtCore.pyqtSlot(str, str)
    def addToJournal(self,event, recipeName) :
        self.loadJournal()
        entry = '''{recipe:%s,date:%s,event:%s,editing:'True'} ''' %( "'" + recipeName + "'", "'" + str(int(time.time())) + "'" , "'" + self.journal.eventsLabels[event] + "'")
        self.showJournal(entry)


    @QtCore.pyqtSlot(str)
    def dumpJournal(self,journalJson) :
        journalJson= '{"name":"journal","items": %s }' %journalJson
        d=json.loads(journalJson)
        with open(journal_file, mode="w", encoding="utf-8") as f :
            json.dump(d,f,indent=2)



############## Bibliothèque ##############################
##########################################################
    @QtCore.pyqtSlot()
    def showLib(self) :
        # data = json.dumps(self.recipesSummary)
        # data = data.replace("'","&#39;")
        self.stackedWidget.setCurrentIndex(0)
        self.brewdayLock = 0

        self.webSettings = self.webViewBiblio.settings()
        self.webSettings.setAttribute(QtWebKit.QWebSettings.LocalContentCanAccessRemoteUrls, True)

        pyDir = os.path.abspath(os.path.dirname(__file__))
        baseUrl = QtCore.QUrl.fromLocalFile(os.path.join(pyDir, "static/html/"))
        self.webViewBiblio.setHtml(LibExporterRepository['html'](), baseUrl)
        self.webViewBiblio.page().mainFrame().addToJavaScriptWindowObject("main", self)
        self.webViewBiblio.page().settings().setAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled, True)
        self.webViewBiblio.page().action(QtWebKitWidgets.QWebPage.Reload).setVisible(False)


    @QtCore.pyqtSlot(str)
    def deleteLib(self,path) :
        confirmation = QtWidgets.QMessageBox.question(self,
                            self.tr("Supprimer"),
                            self.tr("La recette sera définitivement supprimée <br/> Continuer ?"),
                            QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
        if (confirmation == QtWidgets.QMessageBox.Yes):
            os.remove(path)
            self.listdir(recettes_dir)
            self.showLib()
        else :
            self.showLib()


    @QtCore.pyqtSlot()
    def backWebViewBiblio(self) :
        self.stackedWidget.setCurrentIndex(0)


    @QtCore.pyqtSlot(str, str)
    def saveRecipe(self, recipe, path) :
        logger.debug(path)
        recipeFile = QtCore.QFile(path)
        if recipeFile.open(QtCore.QIODevice.WriteOnly):
            try:
                stream = QtCore.QTextStream(recipeFile)
                stream.setCodec("UTF-8")
                stream << recipe
            finally:
                recipeFile.close()
        else:
            # TODO : Prévenir l'utilisateur en cas d'échec de l'enregistrement
            pass

    @QtCore.pyqtSlot(result=str)
    def createPath(self, file_id=None) :
        if file_id is None:
            file_id = str(int(time.time()*10))
        path = recettes_dir + "/" + file_id + ".xml"
        logger.debug(path)
        return path

    @QtCore.pyqtSlot()
    def resetLock(self):
        self.brewdayLock = 0;




############# Mode Brassage ################################
############################################################

    @QtCore.pyqtSlot(str)
    def showBrewdayMode(self, data):
        if self.brewdayLock == 0 :
            self.stackedWidget.setCurrentIndex(1)
            self.brewdayLock = 1
            data = data.replace("'","&#39;")
            pyDir = os.path.abspath(os.path.dirname(__file__))
            baseUrl = QtCore.QUrl.fromLocalFile(os.path.join(pyDir, "static/"))
            self.webViewBrewday.setHtml(BrewdayExporterRepository['html'](data), baseUrl)
            self.webViewBrewday.page().mainFrame().addToJavaScriptWindowObject("main", self)
            self.webViewBrewday.page().settings().setAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled, True)
            self.webViewBrewday.page().action(QtWebKitWidgets.QWebPage.Reload).setVisible(False)
        else :
            self.stackedWidget.setCurrentIndex(1)





###### Outils ############################################
##########################################################

    @QtCore.pyqtSlot()
    def showTools(self):
        self.stackedWidget.setCurrentIndex(0)
        pyDir = os.path.abspath(os.path.dirname(__file__))
        baseUrl = QtCore.QUrl.fromLocalFile(os.path.join(pyDir, "static/"))
        self.webViewBiblio.setHtml(ToolExporterRepository["html"](), baseUrl)
        self.webViewBiblio.page().mainFrame().addToJavaScriptWindowObject("main", self)
        # self.webViewBiblio.page().settings().setAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled, True)
        # self.webInspector = QtWebKit.QWebInspector(self)
        # self.webInspector.setPage(self.webViewBiblio.page())
        # self.webInspector.setVisible(True)
        # self.verticalLayout_13.addWidget(self.webInspector)



    @QtCore.pyqtSlot(result=str)
    def dataRecipes(self) :
        # f = open(recipeData_file, 'w')
        # f.write(self.recipesSummary)
        self.listdir(recettes_dir)
        return self.recipesSummary

    @QtCore.pyqtSlot(result=str)
    def dataProfiles(self) :
        return self.mashProfileExport.exportJson(ImportBase().listeMashes)


    @QtCore.pyqtSlot(result=str)
    def dataIngredients(self) :
        return ImportBase().exportjson()


    @QtCore.pyqtSlot(result=str)
    def dataPref(self) :
        dic = {}
        dic["boilOffRate"] = settings.conf.value("BoilOffRate")
        dic["coolingLossRate"] = settings.conf.value("CoolingLoss")
        dic["grainTemp"] = settings.conf.value("GrainTemp")
        dic["fudgeFactor"] = settings.conf.value("FudgeFactor")
        dic["grainRetention"] = settings.conf.value("GrainRetention")
        dic = json.dumps(dic)
        return dic











    #Une fonction qui gère l'aperçu des couleurs.
    #Contient un tupple avec plusieurs références de couleurs, classées par rang selon la valeur SRM.
    #################################################################################################
    # def colorPreview (self) :
    #     self.colorTuppleSrm = ('FFE699', 'FFD878', 'FFCA5A', 'FFBF42', 'FBB123', 'F8A600', 'F39C00', 'EA8F00', 'E58500', 'DE7C00', 'D77200', 'CF6900', 'CB6200', 'C35900','BB5100', 'B54C00', 'B04500', 'A63E00', 'A13700', '9B3200', '952D00', '8E2900', '882300', '821E00', '7B1A00', '771900', '701400', '6A0E00', '660D00','5E0B00','5A0A02','600903', '520907', '4C0505', '470606', '440607', '3F0708', '3B0607', '3A070B', '36080A')

    #     colorRef= round(self.recipe.compute_EBC()/1.97)

    #     if colorRef >= 30 :
    #         color = "#" + self.colorTuppleSrm[30]
    #     elif colorRef <= 1 :
    #         color = "#" + self.colorTuppleSrm[0]
    #     else :
    #         color = "#" + self.colorTuppleSrm[colorRef-1]
    #     self.widgetColor.setStyleSheet("background-color :" + color)


    def liste_fichiers_recettes(self, rootdir):
        for root, subFolders, files in os.walk(rootdir):
            for file2 in files:
                yield (file2, os.path.join(root,file2))

    def listdir(self, rootdir) :
        summaries=[]
        for filename, recipe in self.liste_fichiers_recettes(rootdir):
            try :
                summaries.append(self.jsonRecipeLib(recipe))
            except :
                logger.debug("le fichier %s n'est pas une recette" %(recipe))
        self.recipesSummary = "[" + ",".join(summaries) + "]"
        logger.debug("%s recettes détectées" %(len(summaries)))



    def jsonRecipeLib(self,recipe) :
        self.s = recipe
        self.recipe = Recipe.parse(recipe)
        data = self.recipe.export("json")
        data = data[1:-1]
        return data



    def initRep(self) :
        home = QtCore.QDir(home_dir)
        config = QtCore.QDir(config_dir)
        logger.debug (config)
        if not config.exists() :
            home.mkpath (config_dir)
        else :
            pass
        database = QtCore.QFile(database_file)
        if not database.exists() :
            database.copy(database_root, database_file)
        else :
            pass
        recettes = QtCore.QFile(recettes_dir)
        if not recettes.exists() :
            try :
                shutil.copytree(samples_dir, samples_target)
            except :
                home.mkpath(recettes_dir)
        mash  = QtCore.QFile(mash_file)
        if not mash.exists() :
            mash.copy(mash_root, mash_file)
        else :
            pass
        journal  = QtCore.QFile(journal_file)
        if not journal.exists() :
            journal.copy(journal_root, journal_file)
        else :
            pass

        # on configure des valeurs par défaut
        if not settings.conf.contains("BoilOffRate") :
            settings.conf.setValue("BoilOffRate", 10)
        if not settings.conf.contains("CoolingLoss") :
            settings.conf.setValue("CoolingLoss", 5)
        if not settings.conf.contains("GrainTemp") :
            settings.conf.setValue("GrainTemp", 20)
        if not settings.conf.contains("FudgeFactor") :
            settings.conf.setValue("FudgeFactor", 1.7)
        if not settings.conf.contains("GrainRetention") :
            settings.conf.setValue("GrainRetention", 1)
        if not settings.conf.contains("Menus") :
            settings.conf.setValue("Menus", "button")


    def prefReload(self) :
        if platform == 'win32':
            recettes_dir = settings.conf.value("pathWin32")
        else :
            recettes_dir = settings.conf.value("pathUnix")
        self.initRep()
        self.initKintoClient()
        self.listdir(recettes_dir)
        self.showLib()

    def initKintoClient(self):
        self.kinto_client = None
        kinto_url = settings.conf.value("KintoServerUrl")
        if kinto_url is not None and kinto_url != "":
            kinto_bucket = settings.conf.value("KintoDefaultBucket")
            kinto_credentials=(settings.conf.value("KintoBasicUserCred"), settings.conf.value("KintoBasicPasswordCred"))
            logger.debug(kinto_credentials)
            if kinto_bucket is None or kinto_bucket == "":
                kinto_bucket = "joliebulle"
                logger.debug("using default bucket 'joliebulle'")
            try:
                tmp_client = Client(server_url=kinto_url, auth = kinto_credentials)
                tmp_client.create_bucket(id=kinto_bucket, if_not_exists=True)
                self.kinto_client = Client(server_url=kinto_url, bucket=kinto_bucket, auth = kinto_credentials)

                # Création des collections
                self.kinto_client.create_collection(id='recipes', if_not_exists=True)
                self.kinto_client.create_collection(id='ingredients', if_not_exists=True)
                
                logger.info("Synchronize with kinto server at :" + repr(self.kinto_client))
            except Exception as e:
                logger.warn("Failed to initialize Kinto synchronisation: " + repr(e))

    def syncRecipes(self):
        recipes_collection = 'recipes'
        if self.kinto_client is None:
            return

        # Sync local recipes
        id_recettes_locales=[]
        for filename, full_filename in self.liste_fichiers_recettes(recettes_dir):
            recipe_id = filename.replace('.xml', '')
            id_recettes_locales.append(recipe_id)
            try:
                remote_recipe = self.kinto_client.get_record(id=recipe_id, collection=recipes_collection)
                logger.debug("recipe " + recipe_id + " already exists on server, update if needed")
                remote_timestamp = int(remote_recipe['data']['last_modified']/1000)
                local_timestamp = int(os.path.getmtime(full_filename))
                logger.debug(str(remote_timestamp) + " " + str(local_timestamp))
                if remote_timestamp < local_timestamp:
                    logger.info("Mise à jour de la recette distante " + recipe_id)
                    # La recette distant doit être mise à jour
                    local_recipe = Recipe.parse(full_filename)
                    data = local_recipe.export("dict")
                    ret = self.kinto_client.update_record(id=recipe_id, collection=recipes_collection, data=data)
                    new_timestamp = ret['data']['last_modified']
                    #MAJ du mtime du fichier pour marquer la synchronisation
                    os.utime(full_filename, times=(int(new_timestamp/1000), int(new_timestamp/1000)))
                if remote_timestamp > local_timestamp:
                    # La recette distante doit être mise à jour
                    logger.info("Mise à jour de la recette locale " + recipe_id)
                    new_recipe = Recipe.parse(remote_recipe['data'], "dict")
                    self.doEnregistrerRecette(new_recipe, full_filename)
                    os.utime(full_filename, times=(int(remote_timestamp), int(remote_timestamp)))
            except KintoException:
                logger.debug("recipe " + recipe_id + " doesn't exists on server, sending it")
                new_recipe = Recipe.parse(full_filename)
                data = new_recipe.export("dict")
                ret = self.kinto_client.create_record(id=recipe_id, collection=recipes_collection, data=data)
                new_timestamp = ret['data']['last_modified']
                #MAJ du mtime du fichier pour marquer la synchronisation
                os.utime(full_filename, times=(int(new_timestamp/1000), int(new_timestamp/1000)))

        recipes = self.kinto_client.get_records(collection='recipes')
        for recipe in recipes:
            if recipe['id'] not in id_recettes_locales:
                #Recette distante non présente localement
                new_recipe = Recipe.parse(recipe, "dict")
                fullname = recipe['id'] + ".xml"
                logger.debug("Création de la recette " + fullname)
                self.doEnregistrerRecette(new_recipe, os.path.join(recettes_dir, fullname))
                os.utime(full_filename, times=(int(remote_timestamp), int(remote_timestamp)))


    @QtCore.pyqtSlot()
    def switchToLibrary(self) :
        self.stackedWidget.setCurrentIndex(0)
        # self.viewRecipeLib(self.s)

    def switchToMash(self) :
        self.stackedWidget.setCurrentIndex(2)


    def restoreDataBase(self) :
        home = QtCore.QDir(home_dir)
        config = QtCore.QDir(config_dir)
        database = QtCore.QFile(database_file)
        confirmation = QtWidgets.QMessageBox.question(self,
                                    self.tr("Remplacer la base ?"),
                                    self.tr("La base des ingrédients actuelle va être effacée et remplacée par la base originale. Toutes vos modifications vont être effacées. Un redémarrage de l'application sera nécessaire.<br> Continuer ?"),
                                    QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
        if (confirmation == QtWidgets.QMessageBox.Yes):
            database.remove(database_file)
            database.copy(database_root, database_file)
        else :

            pass


    def editGrains(self) :
        self.dlgEditG.setModal(True)
        self.dlgEditG.setModel()
        self.dlgEditG.show()

    def editHoublons(self) :
        self.dlgEditH.setModal(True)
        self.dlgEditH.setModel()
        self.dlgEditH.show()

    def editDivers(self) :
        self.dlgEditD.setModal(True)
        self.dlgEditD.setModel()
        self.dlgEditD.show()

    def editLevures(self) :
        self.dlgEditY.setModal(True)
        self.dlgEditY.setModel()
        self.dlgEditY.show()

    @QtCore.pyqtSlot(float, float, float, float)
    def preBoilCheck(self,volPreBoil,preBoilSg,GU,volume) :
        self.dlgPreBoil = DialogPreBoil(self)
        self.dlgPreBoil.setData(volPreBoil,preBoilSg,GU,volume)
        self.dlgPreBoil.setModal(True)
        self.dlgPreBoil.show()


    def dialogPreferences (self) :
        self.dlgPref.setModal(True)
        self.dlgPref.show()




    def importBeerXML(self) :
        fichierBeerXML = self.s
        try:
            self.recipe = Recipe.parse(fichierBeerXML)
            self.currentRecipeMash = self.recipe.mash

        except :
            errors = Errors()
            errors.warningXml()


    def about(self) :
        about = DialogAbout(self)
        about.show()


    def doEnregistrerRecette(self, recipe, destination):
        recipeFile = QtCore.QFile(destination)
        if recipeFile.open(QtCore.QIODevice.WriteOnly):
            try:
                stream = QtCore.QTextStream(recipeFile)
                stream.setCodec("UTF-8")
                stream << recipe.export("beerxml")
            finally:
                recipeFile.close()
        else:
            # TODO : Prévenir l'utilisateur en cas d'échec de l'enregistrement
            pass

    def enregistrerRecette(self, destination):
        self.doEnregistrerRecette(self.recipe, destination)
        self.fileSaved = True

    def enregistrer (self) :
        if self.recipe.name != self.lineEditRecette.text() :
            self.nameChanged = True
        else :
            self.nameChanged = False

        self.recipe.name = self.lineEditRecette.text()
        self.recipe.style = self.lineEditGenre.text()
        self.recipe.brewer = self.lineEditBrewer.text()
        self.recipe.boil = self.spinBoxBoil.value()
        if not self.s:
            destination = recettes_dir + "/" + self.recipe.name.replace('/', ' ') + ".xml"
            if os.path.exists(destination) :
                errors=Errors()
                errors.warningExistingPath()
                self.fileSaved = False
            else :
                self.s = destination
                self.enregistrerRecette(destination)
        else :
            self.enregistrerRecette(self.s)




    def enregistrerSous (self) :
        self.s = QtGui.QFileDialog.getSaveFileName (self,
                                                    self.tr("Enregistrer dans un fichier"),
                                                    recettes_dir + "/" + self.recipe.name.replace('/', ' ') + ".xml",
                                                    "BeerXML (*.xml)")
        self.enregistrerRecette(self.s)

    @QtCore.pyqtSlot(str)
    def copyBbcode (self, bbcode):
        app.clipboard().setText(bbcode)


    def importIng(self):
        s = QtWidgets.QFileDialog.getOpenFileName(self,
            self.tr("Ouvrir un fichier"),
            home_dir,
            )
        if not s :
            pass
        else :
            self.importIngList = ImportIng()
            self.importIngList.parseFile(s)


    def mashComboChanged (self) :
        #on remet le verrou à 0, il va falloir recalculer en repassant en brewday mode
        self.brewdayLock = 0
        try :
            i =self.comboBoxMashProfiles.currentIndex()
            self.currentMash = ImportBase().listeMashes[i]
        except :
            self.currentMash = self.currentRecipeMash
        if i == -1 :
            self.currentMash = Mash()
        self.recipe.mash = self.currentMash

    def seeMash(self) :
        self.switchToMash()
        index = self.listWidgetMashProfiles.currentRow()
        i = self.listWidgetSteps.currentRow()
        self.listWidgetMashProfiles.clear()
        self.listWidgetSteps.clear()

        self.numMash = len(ImportBase().listeMashes)
        #self.numSteps = self.mashProfilesBase.numSteps
        self.popMashList()
        self.pushButtonMashEdit.setEnabled(False)
        self.pushButtonRemoveProfile.setEnabled(False)
        self.pushButtonStepRemove.setEnabled(False)
        self.pushButtonStepEdit.setEnabled(False)
        self.listWidgetMashProfiles.setCurrentRow(index)
        self.listWidgetSteps.setCurrentRow(i)

    def popMashList(self) :
        self.listWidgetMashProfiles.clear()
        for mash in ImportBase().listeMashes :
           self.listWidgetMashProfiles.addItem(mash.name)

    def mashClicked(self) :
        self.listWidgetSteps.clear()
        index = self.listWidgetMashProfiles.currentRow()
        if index > -1:
            mash = ImportBase().listeMashes[index]
            for step in mash.listeSteps :
                self.listWidgetSteps.addItem(step.name)

            self.labelStepName.setTextFormat(QtCore.Qt.RichText)
            self.labelMashName.setText("<b>" + mash.name + "</b>")
            self.labelMashPh.setText("%.1f" %float(mash.ph))
    #        self.labelMashGrainTemp.setText("%.1f" %float(self.dicMashDetail['grainTemp']))
    #        self.labelMashTunTemp.setText("%.1f" %float(self.dicMashDetail['tunTemp']))
            try :
                self.labelMashSpargeTemp.setText("%.1f" %float(mash.spargeTemp))
            except :
                pass
            try :
                self.listWidgetSteps.setCurrentRow(0)
            except :
                pass
    #        print(self.dicMashDetail)
            self.pushButtonMashEdit.setEnabled(True)
            self.pushButtonRemoveProfile.setEnabled(True)

    def mashDetails(self) :
        self.dlgMashDetail = DialogMashDetail(self)
        self.dlgMashDetail.setModal(True)
        self.dlgMashDetail.show()
        self.dlgMashDetail.setFields(self.currentMash)
        self.dlgMashDetail.setAttribute( QtCore.Qt.WA_DeleteOnClose, True )


    def stepDetails(self) :
        index = self.listWidgetMashProfiles.currentRow()
        if index > -1:
            selected_mash = ImportBase().listeMashes[index]
            i = self.listWidgetSteps.currentRow()
            if i > -1:
                try:
                    selected_step = selected_mash.listeSteps[i]
                    self.labelStepName.setTextFormat(QtCore.Qt.RichText)
                    self.labelStepName.setText("<b>" + selected_step.name +"</b>")
                    self.labelStepType.setText(selected_step.type)
                    self.labelStepTemp.setText(MashStepView.temp_to_display(selected_step.temp))
                    self.labelStepTime.setText(MashStepView.time_to_display(selected_step.time))
                    self.pushButtonStepRemove.setEnabled(True)
                    self.pushButtonStepEdit.setEnabled(True)
                except:
                    pass


    def stepEdit(self) :
        index = self.listWidgetMashProfiles.currentRow()
        if  index > -1:
            selected_mash = ImportBase().listeMashes[index]
            i = self.listWidgetSteps.currentRow()
            if i > -1:
                selected_step = selected_mash.listeSteps[i]

                self.dlgStep.show()
                self.dlgStep.fields (selected_step)

    def stepReload(self, step) :
        index = self.listWidgetMashProfiles.currentRow()
        if index > -1:
            selected_mash = ImportBase().listeMashes[index]
            i = self.listWidgetSteps.currentRow()
            if i > -1:
                selected_step = selected_mash.listeSteps[i]

                selected_step.name = step.name
                selected_step.type = step.type
                selected_step.temp = step.temp
                selected_step.time = step.time
                self.seeMash()
                self.stepDetails()
                self.listWidgetMashProfiles.setCurrentRow(index)
                self.listWidgetSteps.setCurrentRow(i)

    def removeStep(self) :
        index = self.listWidgetMashProfiles.currentRow()
        if index > -1:
            selected_mash = ImportBase().listeMashes[index]
            i = self.listWidgetSteps.currentRow()
            if i > -1:
                item = self.listWidgetSteps.currentItem()
                del selected_mash.listeSteps[i]
                # self.listWidgetSteps.clearSelection()
                #self.listWidgetSteps.takeItem(item)
                #On force la sélection sur la ligne précédente
                self.listWidgetSteps.setCurrentRow(i-1)
                self.seeMash()

    def addStep(self) :
        index = self.listWidgetMashProfiles.currentRow()
        selected_mash = ImportBase().listeMashes[index]
        i = self.listWidgetSteps.currentRow()
        step = MashStep()
        step.name = 'Nouveau palier'
        step.type = 'Infusion'
        step.time = '0'
        step.temp = '0'
        step.vol = '0'
        selected_mash.listeSteps.append(step)

        self.listWidgetMashProfiles.setCurrentRow(index)
        self.seeMash()
        self.stepDetails()
        self.listWidgetMashProfiles.setCurrentRow(index)
        # self.listWidgetSteps.setCurrentRow(i-1)
        # self.stepEdit()

    def mashEdit(self) :
        index = self.listWidgetMashProfiles.currentRow()
        selected_mash = ImportBase().listeMashes[index]
        self.dlgMash.show()
        self.dlgMash.fields(selected_mash)

    def mashReload(self,mash) :
        #on remet le verrou à 0, il va falloir recalculer en repassant en brewday mode
        self.brewdayLock = 0
        f = self.listWidgetMashProfiles.currentRow()
        selected_mash = ImportBase().listeMashes[f]
        selected_mash.name = mash.name
        selected_mash.ph = mash.ph
        selected_mash.grainTemp = 20
        selected_mash.tunTemp = 20
        selected_mash.spargeTemp = mash.spargeTemp
        self.popMashList()
        self.listWidgetMashProfiles.setCurrentRow(f)

    def addMash(self) :
        new_mash = Mash()
        new_mash.name = 'Nouveau profil'
        new_mash.grainTemp = '0'
        new_mash.tunTemp = '0'
        new_mash.spargeTemp = '78'
        new_mash.ph = 5.4
        new_step = MashStep()
        new_step.name = 'Nouveau Palier'
        new_step.type = 'Infusion'
        new_step.time = '0'
        new_step.temp = '0'
        new_mash.listeSteps.append(new_step)
        ImportBase().listeMashes.append(new_mash)
        self.seeMash()
        self.listWidgetMashProfiles.setCurrentRow(len(ImportBase().listeMashes)-1)

    def removeMash(self) :
        i = self.listWidgetMashProfiles.currentRow()
        del ImportBase().listeMashes[i]
        self.seeMash()
        self.listWidgetSteps.clear()

    def mashRejected (self) :
        self.showLib()

    def saveProfile(self) :
        self.mashProfileExport.export(ImportBase().listeMashes)
        self.mashProfileExport.enregistrer(mash_file)

    @QtCore.pyqtSlot()
    def printRecipe (self) :
        printer=QtPrintSupport.QPrinter()
        dialog = QtPrintSupport.QPrintDialog(printer)
        dialog.setModal(True)
        dialog.setWindowTitle("Print Document" )
        if dialog.exec_() == True:
            self.webViewBiblio.print(printer)
            # document=QtGui.QTextDocument()
            # stringHtml=self.recipe.export("print")
            # document.setHtml(stringHtml)
            # document.print(printer)


    @QtCore.pyqtSlot()
    def printBrewday(self) :
        printer=QtPrintSupport.QPrinter()
        dialog = QtPrintSupport.QPrintDialog(printer)
        dialog.setModal(True)
        dialog.setWindowTitle("Print Document" )
        if dialog.exec_() == True:
            self.webViewBrewday.print(printer)
Beispiel #47
0
class FunctionalTest(unittest2.TestCase):

    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)

    def tearDown(self):
        # Delete all the created objects
        flush_url = urljoin(self.server_url, '/__flush__')
        resp = requests.post(flush_url)
        resp.raise_for_status()

    def get_user_id(self, credentials):
        hmac_secret = self.config.get('app:main', 'kinto.userid_hmac_secret')
        credentials = '%s:%s' % credentials
        digest = kinto_core_utils.hmac_digest(hmac_secret, credentials)
        return 'basicauth:%s' % digest

    def test_bucket_creation(self):
        bucket = self.client.create_bucket('mozilla')
        user_id = self.get_user_id(self.auth)
        assert user_id in bucket['permissions']['write']

    def test_bucket_creation_if_not_exists(self):
        self.client.create_bucket('mozilla')
        # Should not raise.
        self.client.create_bucket('mozilla', if_not_exists=True)

    def test_buckets_retrieval(self):
        self.client.create_bucket('mozilla')
        buckets = self.client.get_buckets()
        assert len(buckets) == 1

    def test_bucket_retrieval(self):
        self.client.create_bucket('mozilla')
        self.client.get_bucket('mozilla')
        # XXX Add permissions handling during creation and check they are
        # present during retrieval.

    def test_bucket_modification(self):
        bucket = self.client.create_bucket('mozilla', data={'version': 1})
        assert bucket['data']['version'] == 1
        bucket = self.client.patch_bucket('mozilla', data={'author': 'you'})
        assert bucket['data']['version'] == 1
        assert bucket['data']['author'] == 'you'
        bucket = self.client.update_bucket('mozilla', data={'date': 'today'})
        assert bucket['data']['date'] == 'today'
        assert 'version' not in bucket['data']

    def test_bucket_retrieval_fails_when_not_created(self):
        self.assertRaises(BucketNotFound, self.client.get_bucket,
                          'non-existent')

    def test_bucket_deletion(self):
        self.client.create_bucket('mozilla')
        self.client.delete_bucket('mozilla')
        self.assertRaises(BucketNotFound, self.client.get_bucket, 'mozilla')

    def test_bucket_deletion_if_exists(self):
        self.client.create_bucket('mozilla')
        self.client.delete_bucket('mozilla')
        self.client.delete_bucket('mozilla', if_exists=True)

    def test_buckets_deletion(self):
        self.client.create_bucket('mozilla')
        buckets = self.client.delete_buckets()
        assert buckets[0]['id'] == 'mozilla'
        self.assertRaises(BucketNotFound, self.client.get_bucket, 'mozilla')

    def test_buckets_deletion_when_no_buckets_exist(self):
        deleted_buckets = self.client.delete_buckets()
        assert len(deleted_buckets) == 0

    def test_bucket_save(self):
        self.client.create_bucket('mozilla', permissions={'write': ['alexis']})
        bucket = self.client.get_bucket('mozilla')
        assert 'alexis' in bucket['permissions']['write']

    def test_group_creation(self):
        self.client.create_bucket('mozilla')
        self.client.create_group(
            'payments', bucket='mozilla',
            data={'members': ['blah', ]},
            permissions={'write': ['blah', ]})
        # Test retrieval of a group gets the permissions as well.
        group = self.client.get_group('payments', bucket='mozilla')
        assert 'blah' in group['permissions']['write']

    def test_group_creation_if_not_exists(self):
        self.client.create_bucket('mozilla')
        self.client.create_group('payments', bucket='mozilla', data={'members': ['blah', ]})
        self.client.create_group(
            'payments', bucket='mozilla',
            data={'members': ['blah', ]},
            permissions={'write': ['blah', ]},
            if_not_exists=True)

    def test_group_creation_if_bucket_does_not_exist(self):
        with pytest.raises(KintoException):
            self.client.create_group(
                'payments', bucket='mozilla',
                data={'members': ['blah', ]})
            self.client.create_group(
                'payments', bucket='mozilla',
                data={'members': ['blah', ]},
                if_not_exists=True)

    def test_group_update(self):
        self.client.create_bucket('mozilla')
        group = self.client.create_group(
                    'payments', bucket='mozilla',
                    data={'members': ['blah', ]},
                    if_not_exists=True)
        assert group['data']['members'][0] == 'blah'
        group = self.client.update_group(
                    data={'members': ['blah', 'foo']},
                    group='payments', bucket='mozilla')
        self.assertEquals(group['data']['members'][1], 'foo')

    def test_group_list(self):
        self.client.create_bucket('mozilla')
        self.client.create_group('receipts', bucket='mozilla', data={'members': ['blah', ]})
        self.client.create_group('assets', bucket='mozilla', data={'members': ['blah', ]})
        # The returned groups should be strings.
        groups = self.client.get_groups('mozilla')
        self.assertEquals(2, len(groups))
        self.assertEquals(set([coll['id'] for coll in groups]),
                          set(['receipts', 'assets']))

    def test_group_deletion(self):
        self.client.create_bucket('mozilla')
        self.client.create_group('payments', bucket='mozilla', data={'members': ['blah', ]})
        self.client.delete_group('payments', bucket='mozilla')
        assert len(self.client.get_groups(bucket='mozilla')) == 0

    def test_group_deletion_if_exists(self):
        self.client.create_bucket('mozilla')
        self.client.create_group('payments', bucket='mozilla', data={'members': ['blah', ]})
        self.client.delete_group('payments', bucket='mozilla')
        self.client.delete_group('payments', bucket='mozilla', if_exists=True)

    def test_group_deletion_can_still_raise_errors(self):
        error = KintoException("An error occured")
        with mock.patch.object(self.client.session, 'request', side_effect=error):
            with pytest.raises(KintoException):
                self.client.delete_group('payments', bucket='mozilla', if_exists=True)

    def test_groups_deletion(self):
        self.client.create_bucket('mozilla')
        self.client.create_group('amo', bucket='mozilla', data={'members': ['blah', ]})
        self.client.create_group('blocklist', bucket='mozilla', data={'members': ['blah', ]})
        self.client.delete_groups(bucket='mozilla')
        assert len(self.client.get_groups(bucket='mozilla')) == 0

    def test_groups_deletion_when_no_groups_exist(self):
        self.client.create_bucket('mozilla')
        deleted_groups = self.client.delete_groups(bucket='mozilla')
        assert len(deleted_groups) == 0

    def test_collection_creation(self):
        self.client.create_bucket('mozilla')
        self.client.create_collection(
            'payments', bucket='mozilla',
            permissions={'write': ['alexis', ]}
        )

        # Test retrieval of a collection gets the permissions as well.
        collection = self.client.get_collection('payments', bucket='mozilla')
        assert 'alexis' in collection['permissions']['write']

    def test_collection_creation_if_not_exists(self):
        self.client.create_bucket('mozilla')
        self.client.create_collection('payments', bucket='mozilla')
        # Should not raise.
        self.client.create_collection('payments', bucket='mozilla',
                                      if_not_exists=True)

    def test_collection_list(self):
        self.client.create_bucket('mozilla')
        self.client.create_collection('receipts', bucket='mozilla')
        self.client.create_collection('assets', bucket='mozilla')

        # The returned collections should be strings.
        collections = self.client.get_collections('mozilla')
        self.assertEquals(2, len(collections))

        self.assertEquals(set([coll['id'] for coll in collections]),
                          set(['receipts', 'assets']))

    def test_collection_deletion(self):
        self.client.create_bucket('mozilla')
        self.client.create_collection('payments', bucket='mozilla')
        self.client.delete_collection('payments', bucket='mozilla')
        assert len(self.client.get_collections(bucket='mozilla')) == 0

    def test_collection_deletion_if_exists(self):
        self.client.create_bucket('mozilla')
        self.client.create_collection('payments', bucket='mozilla')
        self.client.delete_collection('payments', bucket='mozilla')
        self.client.delete_collection('payments', bucket='mozilla', if_exists=True)

    def test_collection_deletion_can_still_raise_errors(self):
        error = KintoException("An error occured")
        with mock.patch.object(self.client.session, 'request', side_effect=error):
            with pytest.raises(KintoException):
                self.client.delete_collection('payments', bucket='mozilla', if_exists=True)

    def test_collections_deletion(self):
        self.client.create_bucket('mozilla')
        self.client.create_collection('amo', bucket='mozilla')
        self.client.create_collection('blocklist', bucket='mozilla')
        self.client.delete_collections(bucket='mozilla')
        assert len(self.client.get_collections(bucket='mozilla')) == 0

    def test_collections_deletion_when_no_collections_exist(self):
        self.client.create_bucket('mozilla')
        deleted_collections = self.client.delete_collections(bucket='mozilla')
        assert len(deleted_collections) == 0

    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_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_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_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_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_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_record_deletion_if_exists(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'])
        deleted_if_exists = client.delete_record(record['data']['id'], if_exists=True)
        assert deleted['deleted'] is True
        assert deleted_if_exists is None

    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 test_records_deletion_when_no_records_exist(self):
        client = Client(server_url=self.server_url, auth=self.auth,
                        bucket='mozilla', collection='payments')
        client.create_bucket()
        client.create_collection()
        deleted_records = client.delete_records()
        assert len(deleted_records) == 0

    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_updating_data_on_a_group(self):
        client = Client(server_url=self.server_url, auth=self.auth,
                        bucket='mozilla')
        client.create_bucket()
        client.create_group('payments', data={'members': []})
        client.patch_group('payments', data={'secret': 'psssssst!'})
        group = client.get_group('payments')
        assert group['data']['secret'] == 'psssssst!'

    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_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'

    def test_request_batching(self):
        with self.client.batch(bucket='mozilla', collection='fonts') as batch:
            batch.create_bucket()
            batch.create_collection()
            batch.create_record(data={'foo': 'bar'},
                                permissions={'read': ['natim']})
            batch.create_record(data={'bar': 'baz'},
                                permissions={'read': ['alexis']})

        records = self.client.get_records(bucket='mozilla', collection='fonts')
        assert len(records) == 2

    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
Beispiel #48
0
class FunctionalTest(unittest.TestCase):
    def setUp(self):
        super().setUp()
        # 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)
        self.create_user(self.auth)

    def tearDown(self):
        # Delete all the created objects
        flush_url = urljoin(self.server_url, "/__flush__")
        resp = requests.post(flush_url)
        resp.raise_for_status()

    def create_user(self, credentials):
        account_url = urljoin(self.server_url,
                              "/accounts/{}".format(credentials[0]))
        r = requests.put(account_url,
                         json={"data": {
                             "password": credentials[1]
                         }},
                         auth=DEFAULT_AUTH)
        r.raise_for_status()
        return r.json()

    def get_user_id(self, credentials):
        r = self.create_user(credentials)
        return "account:{}".format(r["data"]["id"])

    def test_bucket_creation(self):
        bucket = self.client.create_bucket(id="mozilla")
        user_id = self.get_user_id(self.auth)
        assert user_id in bucket["permissions"]["write"]

    def test_bucket_creation_if_not_exists(self):
        self.client.create_bucket(id="mozilla")
        # Should not raise.
        self.client.create_bucket(id="mozilla", if_not_exists=True)

    def test_buckets_retrieval(self):
        self.client.create_bucket(id="mozilla")
        buckets = self.client.get_buckets()
        assert len(buckets) == 1

    def test_bucket_retrieval(self):
        self.client.create_bucket(id="mozilla")
        self.client.get_bucket(id="mozilla")
        # XXX Add permissions handling during creation and check they are
        # present during retrieval.

    def test_bucket_modification(self):
        bucket = self.client.create_bucket(id="mozilla", data={"version": 1})
        assert bucket["data"]["version"] == 1
        bucket = self.client.patch_bucket(id="mozilla", data={"author": "you"})
        assert bucket["data"]["version"] == 1
        assert bucket["data"]["author"] == "you"
        bucket = self.client.update_bucket(id="mozilla",
                                           data={"date": "today"})
        assert bucket["data"]["date"] == "today"
        assert "version" not in bucket["data"]

    def test_bucket_retrieval_fails_when_not_created(self):
        self.assertRaises(BucketNotFound,
                          self.client.get_bucket,
                          id="non-existent")

    def test_bucket_deletion(self):
        self.client.create_bucket(id="mozilla")
        self.client.delete_bucket(id="mozilla")
        self.assertRaises(BucketNotFound, self.client.get_bucket, id="mozilla")

    def test_bucket_deletion_if_exists(self):
        self.client.create_bucket(id="mozilla")
        self.client.delete_bucket(id="mozilla")
        self.client.delete_bucket(id="mozilla", if_exists=True)

    def test_buckets_deletion(self):
        self.client.create_bucket(id="mozilla")
        buckets = self.client.delete_buckets()
        assert buckets[0]["id"] == "mozilla"
        self.assertRaises(BucketNotFound, self.client.get_bucket, id="mozilla")

    def test_buckets_deletion_when_no_buckets_exist(self):
        deleted_buckets = self.client.delete_buckets()
        assert len(deleted_buckets) == 0

    def test_bucket_save(self):
        self.client.create_bucket(id="mozilla",
                                  permissions={"write": ["account:alexis"]})
        bucket = self.client.get_bucket(id="mozilla")
        assert "account:alexis" in bucket["permissions"]["write"]

    def test_group_creation(self):
        self.client.create_bucket(id="mozilla")
        self.client.create_group(
            id="payments",
            bucket="mozilla",
            data={"members": ["blah"]},
            permissions={"write": ["blah"]},
        )
        # Test retrieval of a group gets the permissions as well.
        group = self.client.get_group(id="payments", bucket="mozilla")
        assert "blah" in group["permissions"]["write"]

    def test_group_creation_if_not_exists(self):
        self.client.create_bucket(id="mozilla")
        self.client.create_group(id="payments",
                                 bucket="mozilla",
                                 data={"members": ["blah"]})
        self.client.create_group(
            id="payments",
            bucket="mozilla",
            data={"members": ["blah"]},
            permissions={"write": ["blah"]},
            if_not_exists=True,
        )

    def test_group_creation_if_bucket_does_not_exist(self):
        with pytest.raises(KintoException) as e:
            self.client.create_group(id="payments",
                                     bucket="mozilla",
                                     data={"members": ["blah"]})
        assert str(e).endswith(
            "PUT /v1/buckets/mozilla/groups/payments - "
            "403 Unauthorized. Please check that the "
            "bucket exists and that you have the permission "
            "to create or write on this group.")

    def test_group_update(self):
        self.client.create_bucket(id="mozilla")
        group = self.client.create_group(id="payments",
                                         bucket="mozilla",
                                         data={"members": ["blah"]},
                                         if_not_exists=True)
        assert group["data"]["members"][0] == "blah"
        group = self.client.update_group(data={"members": ["blah", "foo"]},
                                         id="payments",
                                         bucket="mozilla")
        self.assertEqual(group["data"]["members"][1], "foo")

    def test_group_list(self):
        self.client.create_bucket(id="mozilla")
        self.client.create_group(id="receipts",
                                 bucket="mozilla",
                                 data={"members": ["blah"]})
        self.client.create_group(id="assets",
                                 bucket="mozilla",
                                 data={"members": ["blah"]})
        # The returned groups should be strings.
        groups = self.client.get_groups(bucket="mozilla")
        self.assertEqual(2, len(groups))
        self.assertEqual(set([coll["id"] for coll in groups]),
                         set(["receipts", "assets"]))

    def test_group_deletion(self):
        self.client.create_bucket(id="mozilla")
        self.client.create_group(id="payments",
                                 bucket="mozilla",
                                 data={"members": ["blah"]})
        self.client.delete_group(id="payments", bucket="mozilla")
        assert len(self.client.get_groups(bucket="mozilla")) == 0

    def test_group_deletion_if_exists(self):
        self.client.create_bucket(id="mozilla")
        self.client.create_group(id="payments",
                                 bucket="mozilla",
                                 data={"members": ["blah"]})
        self.client.delete_group(id="payments", bucket="mozilla")
        self.client.delete_group(id="payments",
                                 bucket="mozilla",
                                 if_exists=True)

    def test_group_deletion_can_still_raise_errors(self):
        error = KintoException("An error occured")
        with mock.patch.object(self.client.session,
                               "request",
                               side_effect=error):
            with pytest.raises(KintoException):
                self.client.delete_group(id="payments",
                                         bucket="mozilla",
                                         if_exists=True)

    def test_groups_deletion(self):
        self.client.create_bucket(id="mozilla")
        self.client.create_group(id="amo",
                                 bucket="mozilla",
                                 data={"members": ["blah"]})
        self.client.create_group(id="blocklist",
                                 bucket="mozilla",
                                 data={"members": ["blah"]})
        self.client.delete_groups(bucket="mozilla")
        assert len(self.client.get_groups(bucket="mozilla")) == 0

    def test_groups_deletion_when_no_groups_exist(self):
        self.client.create_bucket(id="mozilla")
        deleted_groups = self.client.delete_groups(bucket="mozilla")
        assert len(deleted_groups) == 0

    def test_collection_creation(self):
        self.client.create_bucket(id="mozilla")
        self.client.create_collection(
            id="payments",
            bucket="mozilla",
            permissions={"write": ["account:alexis"]})

        # Test retrieval of a collection gets the permissions as well.
        collection = self.client.get_collection(id="payments",
                                                bucket="mozilla")
        assert "account:alexis" in collection["permissions"]["write"]

    def test_collection_not_found(self):
        self.client.create_bucket(id="mozilla")

        with pytest.raises(CollectionNotFound):
            self.client.get_collection(id="payments", bucket="mozilla")

    def test_collection_access_forbidden(self):
        with pytest.raises(KintoException):
            self.client.get_collection(id="payments", bucket="mozilla")

    def test_collection_creation_if_not_exists(self):
        self.client.create_bucket(id="mozilla")
        self.client.create_collection(id="payments", bucket="mozilla")
        # Should not raise.
        self.client.create_collection(id="payments",
                                      bucket="mozilla",
                                      if_not_exists=True)

    def test_collection_list(self):
        self.client.create_bucket(id="mozilla")
        self.client.create_collection(id="receipts", bucket="mozilla")
        self.client.create_collection(id="assets", bucket="mozilla")

        # The returned collections should be strings.
        collections = self.client.get_collections(bucket="mozilla")
        self.assertEqual(len(collections), 2)

        self.assertEqual(set([coll["id"] for coll in collections]),
                         set(["receipts", "assets"]))

    def test_collection_deletion(self):
        self.client.create_bucket(id="mozilla")
        self.client.create_collection(id="payments", bucket="mozilla")
        self.client.delete_collection(id="payments", bucket="mozilla")
        assert len(self.client.get_collections(bucket="mozilla")) == 0

    def test_collection_deletion_if_exists(self):
        self.client.create_bucket(id="mozilla")
        self.client.create_collection(id="payments", bucket="mozilla")
        self.client.delete_collection(id="payments", bucket="mozilla")
        self.client.delete_collection(id="payments",
                                      bucket="mozilla",
                                      if_exists=True)

    def test_collection_deletion_can_still_raise_errors(self):
        error = KintoException("An error occured")
        with mock.patch.object(self.client.session,
                               "request",
                               side_effect=error):
            with pytest.raises(KintoException):
                self.client.delete_collection(id="payments",
                                              bucket="mozilla",
                                              if_exists=True)

    def test_collections_deletion(self):
        self.client.create_bucket(id="mozilla")
        self.client.create_collection(id="amo", bucket="mozilla")
        self.client.create_collection(id="blocklist", bucket="mozilla")
        self.client.delete_collections(bucket="mozilla")
        assert len(self.client.get_collections(bucket="mozilla")) == 0

    def test_collections_deletion_when_no_collections_exist(self):
        self.client.create_bucket(id="mozilla")
        deleted_collections = self.client.delete_collections(bucket="mozilla")
        assert len(deleted_collections) == 0

    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": ["account:alexis"]})
        record = client.get_record(id=created["data"]["id"])
        assert "account:alexis" in record["permissions"]["read"]

    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": ["account:alexis"]})
        records = client.get_records()
        assert len(records) == 1

    def test_records_timestamp_retrieval(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(data={"foo": "bar"},
                                      permissions={"read": ["account:alexis"]})
        etag = client.get_records_timestamp()
        assert str(etag) == str(record["data"]["last_modified"])

    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": ["account:alexis"]})
        # Kinto is running with kinto.paginate_by = 5
        records = client.get_records()
        assert len(records) == 10

    def test_records_generator_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": ["account:alexis"]})

        pages = list(client.get_paginated_records())

        assert len(pages) == 2

    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": ["account: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(id=created["data"]["id"])
        assert "account: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": ["account: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_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": ["account:alexis"]})

        client.create_record(data={
            "id": created["data"]["id"],
            "bar": "baz"
        },
                             safe=False)

    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(data={"foo": "bar"})
        deleted = client.delete_record(id=record["data"]["id"])
        assert deleted["deleted"] is True
        assert len(client.get_records()) == 0

    def test_record_deletion_if_exists(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(data={"foo": "bar"})
        deleted = client.delete_record(id=record["data"]["id"])
        deleted_if_exists = client.delete_record(id=record["data"]["id"],
                                                 if_exists=True)
        assert deleted["deleted"] is True
        assert deleted_if_exists is None

    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(data={"foo": "bar"})
        client.delete_records()
        assert len(client.get_records()) == 0

    def test_records_deletion_when_no_records_exist(self):
        client = Client(server_url=self.server_url,
                        auth=self.auth,
                        bucket="mozilla",
                        collection="payments")
        client.create_bucket()
        client.create_collection()
        deleted_records = client.delete_records()
        assert len(deleted_records) == 0

    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(id="shared-bucket",
                                  permissions={"read": [alice_userid]})

        alice_client = Client(server_url=self.server_url,
                              auth=alice_credentials)
        alice_client.get_bucket(id="shared-bucket")

    def test_updating_data_on_a_group(self):
        client = Client(server_url=self.server_url,
                        auth=self.auth,
                        bucket="mozilla")
        client.create_bucket()
        client.create_group(id="payments", data={"members": []})
        client.patch_group(id="payments", data={"secret": "psssssst!"})
        group = client.get_group(id="payments")
        assert group["data"]["secret"] == "psssssst!"

    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(id="bob-bucket")
        self.client.create_collection(id="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(id="shared", bucket="bob-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(id="bob-bucket")
        self.client.create_collection(id="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"

    def test_request_batching(self):
        with self.client.batch(bucket="mozilla", collection="fonts") as batch:
            batch.create_bucket()
            batch.create_collection()
            batch.create_record(data={"foo": "bar"},
                                permissions={"read": ["natim"]})
            batch.create_record(data={"bar": "baz"},
                                permissions={"read": ["account:alexis"]})

        _, _, r1, r2 = batch.results()
        records = self.client.get_records(bucket="mozilla", collection="fonts")

        assert len(records) == 2
        assert records[0] == r2["data"]
        assert records[1] == r1["data"]

    def test_patch_record_jsonpatch(self):
        self.client.create_bucket(id="b1")
        self.client.create_collection(id="c1", bucket="b1")
        self.client.create_record(id="r1",
                                  collection="c1",
                                  bucket="b1",
                                  data={"hello": "world"})
        patch = JSONPatch([
            {
                "op": "add",
                "path": "/data/goodnight",
                "value": "moon"
            },
            {
                "op": "add",
                "path": "/permissions/read/alice"
            },
        ])
        self.client.patch_record(id="r1",
                                 collection="c1",
                                 bucket="b1",
                                 changes=patch)
        record = self.client.get_record(bucket="b1", collection="c1", id="r1")
        assert record["data"]["hello"] == "world"
        assert record["data"]["goodnight"] == "moon"
        assert record["permissions"]["read"] == ["alice"]

    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
Beispiel #49
0
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_if_match(self):
        self.client.update_collection(
            {'foo': 'bar'},
            collection='mycollection',
            if_match=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_if_match(self):
        self.client.patch_collection(
            collection='mycollection',
            data={'key': 'secret'},
            if_match=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',
            if_match=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',
            if_match=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 test_create_collection_raises_a_special_error_on_403(self):
        self.session.request.side_effect = get_http_error(status=403)
        with self.assertRaises(KintoException) as e:
            self.client.create_collection(
                bucket="buck",
                collection="coll")
        expected_msg = ("Unauthorized. Please check that the bucket exists "
                        "and that you have the permission to create or write "
                        "on this collection.")
        assert e.exception.message == expected_msg