def test_ssl_verification(self, mock_requests):
        """Test ssl usage"""
        # ensure error is raised if http is supplied and use_ssl is true
        with self.assertRaises(APIClientError) as conm:
            JSONAPI('http://example.org')
        exception = conm.exception
        expected = SSL_ERROR
        self.assertEqual(expected, str(exception))

        # ensure error is raised if https is supplied and use_ssl is false
        with self.assertRaises(APIClientError) as conm:
            JSONAPI('https://example.org', use_ssl=False)
        exception = conm.exception
        expected = SSL_ERROR2
        self.assertEqual(expected, str(exception))

        # test defaults to https
        api = JSONAPI('example.org')
        api._get()
        mock_requests.get.assert_called_with('https://example.org',
                                             timeout=None,
                                             headers=None)

        # use_ssl is False
        api = JSONAPI('example.org', use_ssl=False)
        api._get()
        mock_requests.get.assert_called_with('http://example.org',
                                             timeout=None,
                                             headers=None)
class APITests(unittest.TestCase):
    """Tests for API base classes"""

    # pylint: disable=protected-access, no-self-use, unused-argument

    def setUp(self):
        self.url = 'example.org'
        self.api = JSONAPI(self.url)

    def test_ssl_verification(self, mock_requests):
        """Test ssl usage"""
        # ensure error is raised if http is supplied and use_ssl is true
        with self.assertRaises(APIClientError) as conm:
            JSONAPI('http://example.org')
        exception = conm.exception
        expected = SSL_ERROR
        self.assertEqual(expected, str(exception))

        # ensure error is raised if https is supplied and use_ssl is false
        with self.assertRaises(APIClientError) as conm:
            JSONAPI('https://example.org', use_ssl=False)
        exception = conm.exception
        expected = SSL_ERROR2
        self.assertEqual(expected, str(exception))

        # test defaults to https
        api = JSONAPI('example.org')
        api._get()
        mock_requests.get.assert_called_with('https://example.org',
                                             timeout=None,
                                             headers=None)

        # use_ssl is False
        api = JSONAPI('example.org', use_ssl=False)
        api._get()
        mock_requests.get.assert_called_with('http://example.org',
                                             timeout=None,
                                             headers=None)

    def test_get(self, mock_requests):
        """Test _get method."""
        self.api._get(id=1, foo='bar')
        mock_requests.get.assert_called_with('https://example.org',
                                             params={
                                                 'id': 1,
                                                 'foo': 'bar'
                                             },
                                             timeout=None,
                                             headers=None)

    def test_post(self, mock_requests):
        """Test _get_post."""
        params = {'id': 1}
        files = {'file': 'mock_file'}
        data = {'foo': 'bar', 'test': 'test'}
        self.api._post(params=params, files=files, foo='bar', test='test')
        mock_requests.post.assert_called_with('https://example.org',
                                              params=params,
                                              files=files,
                                              json=data,
                                              timeout=None,
                                              headers=None)

        # Not json
        api = BaseAPI('example.org')
        api._post(params=params, files=files, foo='bar', test='test')
        mock_requests.post.assert_called_with('https://example.org',
                                              params=params,
                                              files=files,
                                              data=data,
                                              timeout=None,
                                              headers=None)

    def test_patch(self, mock_requests):
        """Test _get_patch."""
        params = {'id': 1}
        files = {'file': 'mock_file'}
        data = {'foo': 'bar', 'test': 'test'}
        self.api._patch(params=params, files=files, foo='bar', test='test')
        mock_requests.patch.assert_called_with('https://example.org',
                                               params=params,
                                               files=files,
                                               json=data,
                                               timeout=None,
                                               headers=None)

        # Not json
        api = BaseAPI('example.org')
        api._patch(params=params, files=files, foo='bar', test='test')
        mock_requests.patch.assert_called_with('https://example.org',
                                               params=params,
                                               files=files,
                                               data=data,
                                               timeout=None,
                                               headers=None)

    def test_delete(self, mock_requests):
        """Test _delete method."""
        self.api._delete(id=1, foo='bar')
        mock_requests.delete.assert_called_with('https://example.org',
                                                params={
                                                    'id': 1,
                                                    'foo': 'bar'
                                                },
                                                timeout=None,
                                                headers=None)

    def test_construct_payload(self, mock_requests):
        """Test construct_payload  method."""
        with self.assertRaises(APIClientError):
            api = BaseAPI('example.org', compulsory_params=['id'])
            api._get(foo='bar')
        api._get(id=1)
        self.assertTrue(mock_requests.get.called)

        url = self.url

        class TestAPI(BaseAPI):
            """test class"""

            # pylint: disable=too-few-public-methods

            def __init__(self):
                self.compulsory_params = ['id', 'comp']
                super(TestAPI, self).__init__(url)
                self.comp = 1

        with self.assertRaises(APIClientError) as conm:
            api = TestAPI()
            api._get()
        exception = conm.exception
        self.assertEqual('APIClientError: id is a compulsory field',
                         str(exception))
        api._get(id=1)
        self.assertTrue(mock_requests.get.called)

    def test_check_call_success(self, mock_requests):
        """Test check_call_success method."""
        mock_response = mock.MagicMock()
        mock_response.status_code = 200
        mock_requests.get.return_value = mock_response
        mock_requests.codes.ok = 200
        response = self.api._get(id=1)
        self.assertTrue(self.api.check_call_success(response))

    def test_construct_url(self, mock_requests):
        """Test _construct_url method."""
        api = BaseAPI(use_ssl=False)

        # ensure error is raised if no url  is supplied
        with self.assertRaises(APIClientError) as conm:
            api._construct_url(None)
        exception = conm.exception
        expected = NO_URL_ERROR
        self.assertEqual(expected, str(exception))

        # ensure error is raised if https is supplied and use_ssl is false
        with self.assertRaises(APIClientError) as conm:
            api._construct_url('https://www.example.org', use_ssl=False)
        exception = conm.exception
        expected = SSL_ERROR2
        self.assertEqual(expected, str(exception))

    def test_construct_url_ssl_explicit(self, mock_requests):
        """Test _construct_url method."""
        api = BaseAPI(use_ssl=True)

        # ensure error is raised if http is supplied and use_ssl is true
        with self.assertRaises(APIClientError) as conm:
            api._construct_url('http://example.org', use_ssl=True)
        exception = conm.exception
        expected = SSL_ERROR
        self.assertEqual(expected, str(exception))

        # ensure error is raised if http is supplied and use_ssl is default
        with self.assertRaises(APIClientError) as conm:
            api._construct_url('http://example.org')
        exception = conm.exception
        expected = SSL_ERROR
        self.assertEqual(expected, str(exception))

    def test_construct_url_ssl_implicit(self, mock_requests):
        """Test _construct_url method."""
        api = BaseAPI()

        # ensure error is raised if http is supplied and use_ssl is true
        with self.assertRaises(APIClientError) as conm:
            api._construct_url('http://example.org', use_ssl=True)
        exception = conm.exception
        expected = SSL_ERROR
        self.assertEqual(expected, str(exception))

        # ensure error is raised if http is supplied and use_ssl is default
        with self.assertRaises(APIClientError) as conm:
            api._construct_url('http://example.org')
        exception = conm.exception
        expected = SSL_ERROR
        self.assertEqual(expected, str(exception))
 def setUp(self):
     self.url = 'example.org'
     self.api = JSONAPI(self.url)
class APITestsNoURL(unittest.TestCase):
    """Tests for API base classes with no self.url set"""

    # pylint: disable=protected-access, no-self-use, unused-argument

    def setUp(self):
        self.url = 'example.org'
        self.api = JSONAPI()

    def test_no_url(self, mock_requests):
        """Test ssl usage"""

    def test_get(self, mock_requests):
        """Test _get method."""
        self.api._get(self.url, id=1, foo='bar')
        mock_requests.get.assert_called_with('https://example.org',
                                             params={
                                                 'id': 1,
                                                 'foo': 'bar'
                                             },
                                             timeout=None,
                                             headers=None)

        # ensure error is raised if https is supplied and use_ssl is false
        with self.assertRaises(APIClientError) as conm:
            api = BaseAPI('example.org', use_ssl=False)
            api._get(url='https://www.example.org', use_ssl=False)
        exception = conm.exception
        expected = SSL_ERROR2
        self.assertEqual(expected, str(exception))

        # ensure error is raised if http is supplied and use_ssl is true
        with self.assertRaises(APIClientError) as conm:
            self.api._get(url='http://example.org')
        exception = conm.exception
        expected = SSL_ERROR
        self.assertEqual(expected, str(exception))

        # ensure error is raised if no url  is supplied
        with self.assertRaises(APIClientError) as conm:
            self.api._get()
        exception = conm.exception
        expected = NO_URL_ERROR
        self.assertEqual(expected, str(exception))

        # test defaults to http
        self.api._get(url=self.url)
        mock_requests.get.assert_called_with('https://example.org',
                                             timeout=None,
                                             headers=None)

        # use_ssl is False
        api = BaseAPI('example.org', use_ssl=False)
        api._get(url=self.url, use_ssl=False)
        mock_requests.get.assert_called_with('http://example.org',
                                             timeout=None,
                                             headers=None)

    def test_post(self, mock_requests):
        """Test _get_post."""
        params = {'id': 1}
        files = {'file': 'mock_file'}
        data = {'foo': 'bar', 'test': 'test'}
        self.api._post(url=self.url,
                       params=params,
                       files=files,
                       foo='bar',
                       test='test')
        mock_requests.post.assert_called_with('https://example.org',
                                              params=params,
                                              files=files,
                                              json=data,
                                              timeout=None,
                                              headers=None)

        # Not json
        api = BaseAPI()
        api._post(url=self.url,
                  params=params,
                  files=files,
                  foo='bar',
                  test='test')
        mock_requests.post.assert_called_with('https://example.org',
                                              params=params,
                                              files=files,
                                              data=data,
                                              timeout=None,
                                              headers=None)

        # ensure error is raised if no url  is supplied
        with self.assertRaises(APIClientError) as conm:
            self.api._post(params=params, files=files, foo='bar', test='test')
        exception = conm.exception
        expected = NO_URL_ERROR
        self.assertEqual(expected, str(exception))

        # ensure error is raised if https is supplied and use_ssl is false
        with self.assertRaises(APIClientError) as conm:
            api = BaseAPI('example.org', use_ssl=False)
            api._post(url='https://example.org',
                      use_ssl=False,
                      params=params,
                      files=files,
                      foo='bar',
                      test='test')
        exception = conm.exception
        expected = SSL_ERROR2
        self.assertEqual(expected, str(exception))

        # ensure error is raised if http is supplied and use_ssl is true
        with self.assertRaises(APIClientError) as conm:
            self.api._post(url='http://example.org',
                           use_ssl=True,
                           params=params,
                           files=files,
                           foo='bar',
                           test='test')
        exception = conm.exception
        expected = SSL_ERROR
        self.assertEqual(expected, str(exception))

    def test_patch(self, mock_requests):
        """Test _get_patch."""
        params = {'id': 1}
        files = {'file': 'mock_file'}
        data = {'foo': 'bar', 'test': 'test'}
        self.api._patch(url=self.url,
                        params=params,
                        files=files,
                        foo='bar',
                        test='test')
        mock_requests.patch.assert_called_with('https://example.org',
                                               params=params,
                                               files=files,
                                               json=data,
                                               timeout=None,
                                               headers=None)

        # Not json
        api = BaseAPI('example.org')
        api._patch(url=self.url,
                   params=params,
                   files=files,
                   foo='bar',
                   test='test')
        mock_requests.patch.assert_called_with('https://example.org',
                                               params=params,
                                               files=files,
                                               data=data,
                                               timeout=None,
                                               headers=None)

        # ensure error is raised if no url  is supplied
        with self.assertRaises(APIClientError) as conm:
            self.api._patch(params=params, files=files, foo='bar', test='test')
        exception = conm.exception
        expected = NO_URL_ERROR
        self.assertEqual(expected, str(exception))

        # ensure error is raised if https is supplied and use_ssl is false
        with self.assertRaises(APIClientError) as conm:
            api = BaseAPI('example.org', use_ssl=False)
            api._patch(url='https://example.org',
                       use_ssl=False,
                       params=params,
                       files=files,
                       foo='bar',
                       test='test')
        exception = conm.exception
        expected = SSL_ERROR2
        self.assertEqual(expected, str(exception))

        # ensure error is raised if http is supplied and use_ssl is true
        with self.assertRaises(APIClientError) as conm:
            self.api._patch(url='http://example.org',
                            use_ssl=True,
                            params=params,
                            files=files,
                            foo='bar',
                            test='test')
        exception = conm.exception
        expected = SSL_ERROR
        self.assertEqual(expected, str(exception))

    def test_delete(self, mock_requests):
        """Test _delete method."""
        self.api._delete(url=self.url, id=1, foo='bar')
        mock_requests.delete.assert_called_with('https://example.org',
                                                params={
                                                    'id': 1,
                                                    'foo': 'bar'
                                                },
                                                timeout=None,
                                                headers=None)

        # ensure error is raised if https is supplied and use_ssl is false
        with self.assertRaises(APIClientError) as conm:
            api = BaseAPI('example.org', use_ssl=False)
            api._delete(url='https://www.example.org')
        exception = conm.exception
        expected = SSL_ERROR2
        self.assertEqual(expected, str(exception))

        # ensure error is raised if http is supplied and use_ssl is true
        with self.assertRaises(APIClientError) as conm:
            self.api._delete(url='http://example.org')
        exception = conm.exception
        expected = SSL_ERROR
        self.assertEqual(expected, str(exception))

        # ensure error is raised if no url  is supplied
        with self.assertRaises(APIClientError) as conm:
            self.api._delete()
        exception = conm.exception
        expected = NO_URL_ERROR
        self.assertEqual(expected, str(exception))

        # test defaults to http
        self.api._delete(url=self.url)
        mock_requests.delete.assert_called_with('https://example.org',
                                                timeout=None,
                                                headers=None)

        # use_ssl is False
        api = BaseAPI('example.org', use_ssl=False)
        api._delete(url=self.url, use_ssl=False)
        mock_requests.delete.assert_called_with('http://example.org',
                                                timeout=None,
                                                headers=None)