import os

import pytest
import pytest_httpbin.certs
from requests.exceptions import SSLError

from httpie import ExitStatus
from httpie.input import SSL_VERSION_ARG_MAPPING
from utils import http, HTTP_OK, TESTS_ROOT


CLIENT_CERT = os.path.join(TESTS_ROOT, 'client_certs', 'client.crt')
CLIENT_KEY = os.path.join(TESTS_ROOT, 'client_certs', 'client.key')
CLIENT_PEM = os.path.join(TESTS_ROOT, 'client_certs', 'client.pem')

# FIXME:
# We test against a local httpbin instance which uses a self-signed cert.
# Requests without --verify=<CA_BUNDLE> will fail with a verification error.
# See: https://github.com/kevin1024/pytest-httpbin#https-support
CA_BUNDLE = pytest_httpbin.certs.where()


@pytest.mark.parametrize('ssl_version', SSL_VERSION_ARG_MAPPING.keys())
def test_ssl_version(httpbin_secure, ssl_version):
    try:
        r = http(
            '--ssl', ssl_version,
            httpbin_secure + '/get'
        )
        assert HTTP_OK in r
    except SSLError as e:
        if ssl_version == 'ssl3':
            # pytest-httpbin doesn't support ssl3
            assert 'SSLV3_ALERT_HANDSHAKE_FAILURE' in str(e)
        else:
            raise


class TestClientCert:

    def test_cert_and_key(self, httpbin_secure):
        r = http(httpbin_secure + '/get',
                 '--cert', CLIENT_CERT,
                 '--cert-key', CLIENT_KEY)
        assert HTTP_OK in r

    def test_cert_pem(self, httpbin_secure):
        r = http(httpbin_secure + '/get',
                 '--cert', CLIENT_PEM)
        assert HTTP_OK in r

    def test_cert_file_not_found(self, httpbin_secure):
        r = http(httpbin_secure + '/get',
                 '--cert', '/__not_found__',
                 error_exit_ok=True)
        assert r.exit_status == ExitStatus.ERROR
        assert 'No such file or directory' in r.stderr

    def test_cert_file_invalid(self, httpbin_secure):
        with pytest.raises(SSLError):
            http(httpbin_secure + '/get',
                 '--cert', __file__)

    def test_cert_ok_but_missing_key(self, httpbin_secure):
        with pytest.raises(SSLError):
            http(httpbin_secure + '/get',
                 '--cert', CLIENT_CERT)


class TestServerCert:

    def test_verify_no_OK(self, httpbin_secure):
        r = http(httpbin_secure.url + '/get', '--verify=no')
        assert HTTP_OK in r

    @pytest.mark.parametrize('verify_value', ['false', 'fALse'])
    def test_verify_false_OK(self, httpbin_secure, verify_value):
        r = http(httpbin_secure.url + '/get', '--verify', verify_value)
        assert HTTP_OK in r

    def test_verify_custom_ca_bundle_path(
            self, httpbin_secure_untrusted):
        r = http(httpbin_secure_untrusted + '/get', '--verify', CA_BUNDLE)
        assert HTTP_OK in r

    def test_self_signed_server_cert_by_default_raises_ssl_error(
            self,
            httpbin_secure_untrusted):
        with pytest.raises(SSLError):
            http(httpbin_secure_untrusted.url + '/get')

    def test_verify_custom_ca_bundle_invalid_path(self, httpbin_secure):
        # since 2.14.0 requests raises IOError
        with pytest.raises((SSLError, IOError)):
            http(httpbin_secure.url + '/get', '--verify', '/__not_found__')

    def test_verify_custom_ca_bundle_invalid_bundle(self, httpbin_secure):
        with pytest.raises(SSLError):
            http(httpbin_secure.url + '/get', '--verify', __file__)

@@ -46,20 +46,22 @@
 n.certs%0A
-from
+import
  request
@@ -76,24 +76,8 @@
 ions
- import SSLError
 %0A%0Afr
@@ -174,14 +174,8 @@
 port
- http,
  HTT
@@ -190,16 +190,373 @@
 STS_ROOT
+, http%0A%0A%0Atry:%0A    # Handle OpenSSL errors, if installed.%0A    # See %3Chttps://github.com/jakubroztocil/httpie/issues/729%3E%0A    # noinspection PyUnresolvedReferences%0A    import OpenSSL.SSL%0A    ssl_errors = (%0A        requests.exceptions.SSLError,%0A        OpenSSL.SSL.Error,%0A    )%0Aexcept ImportError:%0A    ssl_errors = (%0A        requests.exceptions.SSLError,%0A    )
 %0A%0A%0ACLIEN
@@ -755,17 +755,16 @@
 t.pem')%0A
-%0A
 # FIXME:
@@ -1292,24 +1292,26 @@
  except 
-SSLE
+ssl_e
 rror
+s
  as e:%0A 
@@ -2231,32 +2231,34 @@
 test.raises(
-SSLE
+ssl_e
 rror
+s
 ):%0A         
@@ -2411,32 +2411,34 @@
 test.raises(
-SSLE
+ssl_e
 rror
+s
 ):%0A         
@@ -2953,28 +2953,24 @@
 th(%0A        
-    
 self, httpbi
@@ -2979,32 +2979,37 @@
 secure_untrusted
+%0A    
 ):%0A        r = h
@@ -3177,22 +3177,14 @@
     
-    
 self,%0A
-    
     
@@ -3211,16 +3211,21 @@
 ntrusted
+%0A    
 ):%0A     
@@ -3242,32 +3242,34 @@
 test.raises(
-SSLE
+ssl_e
 rror
+s
 ):%0A         
@@ -3467,26 +3467,30 @@
 ses(
-(SSLError, 
+ssl_errors + (
 IOError
+,
 )):%0A
@@ -3668,24 +3668,26 @@
 .raises(
-SSLE
+ssl_e
 rror
+s
 ):%0A     

Fix tests for installation with pyOpenSSL #729