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}')