Ejemplo n.º 1
0
class CloudantDBTest(unittest.TestCase):
    """
    Tests for additional Cloudant database features
    """
    def setUp(self):
        self.mock_session = mock.Mock()
        self.mock_session.get = mock.Mock()
        self.mock_session.post = mock.Mock()
        self.mock_session.put = mock.Mock()
        self.mock_session.delete = mock.Mock()

        self.account = mock.Mock()
        self.account.cloudant_url = "https://bob.cloudant.com"
        self.account.r_session = self.mock_session

        self.username = "******"
        self.db_name = "testdb"
        self.cl = CloudantDatabase(self.account, self.db_name)

        self.sec_doc = {
            "_id": "_security",
            "cloudant": {
                "someapikey": [
                    "_reader"
                ],
                "nobody": [],
                "bob": [
                    "_writer",
                    "_admin",
                    "_replicator",
                    "_reader"
                ]
            }
        }

        self.shards = {
            "shards": {
                "00000000-3fffffff": [
                    "*****@*****.**",
                    "*****@*****.**",
                    "*****@*****.**"
                ],
                "40000000-7fffffff": [
                    "*****@*****.**",
                    "*****@*****.**",
                    "*****@*****.**"
                ],
                "80000000-bfffffff": [
                    "*****@*****.**",
                    "*****@*****.**",
                    "*****@*****.**"
                ],
                "c0000000-ffffffff": [
                    "*****@*****.**",
                    "*****@*****.**",
                    "*****@*****.**"
                ]
            }
        }

    def test_security_doc(self):
        mock_resp = mock.Mock()
        mock_resp.json = mock.Mock(return_value=self.sec_doc)
        self.mock_session.get = mock.Mock(return_value=mock_resp)

        security_doc = self.cl.security_document()

        self.assertTrue(self.mock_session.get.called)
        self.assertDictEqual(security_doc, self.sec_doc)

    def test_shared_dbs(self):
        # share database
        mock_sec_doc = mock.Mock()
        mock_sec_doc.json.return_value = self.sec_doc
        self.mock_session.get.return_value = mock_sec_doc
        self.mock_session.put.return_value = mock_sec_doc

        shared_resp = self.cl.share_database(
            'someotheruser',
            reader=True,
            writer=True
        )

        self.assertTrue(self.mock_session.get.called)
        self.assertTrue(self.mock_session.put.called)
        self.assertIn('someotheruser', shared_resp['cloudant'])

        # unshare database
        unshared_resp = self.cl.unshare_database('someotheruser')
        self.assertNotIn('someotheruser', unshared_resp['cloudant'])

    def test_shards(self):
        mock_resp = mock.Mock()
        mock_resp.status_code = 200
        mock_resp.raise_for_status = mock.Mock()
        mock_resp.json = mock.Mock(return_value=self.shards)
        self.mock_session.get.return_value = mock_resp

        r = self.cl.shards()

        self.assertTrue(self.mock_session.get.called)
        self.assertEqual(r, self.shards)

    def test_missing_revs(self):
        doc_id = 'somedocument'
        ret_val = {
            "missing_revs": {doc_id: ['rev1']}
        }
        mock_resp = mock.Mock()
        mock_resp.status_code = 201
        mock_resp.raise_for_status = mock.Mock()
        mock_resp.json = mock.Mock(return_value=ret_val)
        self.mock_session.post.return_value = mock_resp

        missed_revs = self.cl.missing_revisions(doc_id, 'rev1', 'rev2', 'rev3')

        expected_data = {doc_id: ['rev1', 'rev2', 'rev3']}
        expected_url = posixpath.join(
            self.account.cloudant_url,
            self.db_name,
            '_missing_revs'
        )
        self.assertTrue(self.mock_session.post.called)
        self.mock_session.post.assert_called_once_with(
            expected_url,
            headers={'Content-Type': 'application/json'},
            data=json.dumps(expected_data)
        )
        self.assertEqual(missed_revs, ret_val["missing_revs"][doc_id])

    def test_revs_diff(self):
        doc_id = 'somedocument'
        ret_val = {
            doc_id: {
                "missing": ['rev1', 'rev3'],
                "possible_ancestors": ['rev2']
            }
        }
        mock_resp = mock.Mock()
        mock_resp.status_code = 201
        mock_resp.raise_for_status = mock.Mock()
        mock_resp.json = mock.Mock(return_value=ret_val)
        self.mock_session.post.return_value = mock_resp

        revs_diff = self.cl.revisions_diff(doc_id, 'rev1', 'rev2', 'rev3')

        expected_data = {doc_id: ['rev1', 'rev2', 'rev3']}
        expected_url = posixpath.join(
            self.account.cloudant_url,
            self.db_name,
            '_revs_diff'
        )
        self.assertTrue(self.mock_session.post.called)
        self.mock_session.post.assert_called_once_with(
            expected_url,
            headers={'Content-Type': 'application/json'},
            data=json.dumps(expected_data)
        )
        self.assertEqual(revs_diff, ret_val)

    def test_revs_limit(self):
        limit = 500
        expected_url = posixpath.join(
            self.account.cloudant_url,
            self.db_name,
            '_revs_limit'
        )

        # set rev limit
        mock_put = mock.Mock()
        mock_put.status_code = 201
        mock_put.raise_for_status = mock.Mock()
        mock_put.json = mock.Mock(return_value='{"ok": true}')
        self.mock_session.put.return_value = mock_put

        set_limit = self.cl.set_revision_limit(limit)

        self.assertTrue(self.mock_session.put.called)
        self.mock_session.put.assert_called_once_with(
            expected_url,
            data=json.dumps(limit)
        )
        self.assertEqual(set_limit, '{"ok": true}')

        # get rev limit
        mock_get = mock.Mock()
        mock_get.status_code = 200
        mock_get.raise_for_status = mock.Mock()
        mock_get.text = limit
        self.mock_session.get.return_value = mock_get

        get_limit = self.cl.get_revision_limit()

        self.assertTrue(self.mock_session.put.called)
        self.mock_session.get.assert_called_once_with(expected_url)
        self.assertEqual(get_limit, limit)

    def test_get_revs_limit_bad_resp(self):
        mock_get = mock.Mock()
        mock_get.status_code = 200
        mock_get.raise_for_status = mock.Mock()
        mock_get.text = 'bloop'
        self.mock_session.get.return_value = mock_get

        with self.assertRaises(CloudantException):
            resp = self.cl.get_revision_limit()
            self.assertTrue(self.mock_session.get.called)
            self.assertEqual(resp.status_code, 400)

    def test_view_cleanup(self):
        expected_url = posixpath.join(
            self.account.cloudant_url,
            self.db_name,
            '_view_cleanup'
        )

        mock_post = mock.Mock()
        mock_post.status_code = 201
        mock_post.raise_for_status = mock.Mock()
        mock_post.json = mock.Mock(return_value='{"ok": true}')
        self.mock_session.post.return_value = mock_post

        cleanup = self.cl.view_cleanup()

        self.assertTrue(self.mock_session.post.called)
        self.mock_session.post.assert_called_once_with(
            expected_url,
            headers={'Content-Type': 'application/json'}
        )
        self.assertEqual(cleanup, '{"ok": true}')