Repository: andreroggeri/pynubank

Issue:
NuException does not show which status code I actually got
exception looks like this:

```
Traceback (most recent call last):
  File "main.py", line 11, in <module>
    nu.authenticate_with_qr_code(os.environ['NU_CPF'], os.environ['NU_PWD'], uuid)
  File "/usr/local/lib/python3.8/site-packages/pynubank/nubank.py", line 96, in authenticate_with_qr_code
    auth_data = self._password_auth(cpf, password)
  File "/usr/local/lib/python3.8/site-packages/pynubank/nubank.py", line 79, in _password_auth
    data = self._handle_response(response)
  File "/usr/local/lib/python3.8/site-packages/pynubank/nubank.py", line 84, in _handle_response
    raise NuException(f'The request made failed with HTTP status code {response.status_code}',
pynubank.nubank.NuException
make: *** [run] Error 1
```

its probably a 422, but I think it should show it here...

Discussion:
andreroggeri: Nice catch ! Would you mind adding a new test to catch this scenario ?
coveralls: 
[![Coverage Status](https://coveralls.io/builds/26660815/badge)](https://coveralls.io/builds/26660815)

Coverage remained the same at 100.0% when pulling **e59c3d60fe03e142740a92fb3b3f2b97fc8c5928 on marcoaaguiar:master** into **4e3c7ca641da2b557137c649911e222e752eea1c on andreroggeri:master**.

marcoaaguiar: I dont have experience with pytest but created a few test to cover the attributes of NuException. Could you check if it is correct?

Patch:
diff --git a/pynubank/nubank.py b/pynubank/nubank.py
index d38a582..f7174db 100644
--- a/pynubank/nubank.py
+++ b/pynubank/nubank.py
@@ -18,9 +18,8 @@ PAYMENT_EVENT_TYPES = (
 
 
 class NuException(Exception):
-
     def __init__(self, status_code, response, url):
-        super().__init__()
+        super().__init__(f'The request made failed with HTTP status code {status_code}')
         self.url = url
         self.status_code = status_code
         self.response = response
@@ -81,8 +80,7 @@ class Nubank:
 
     def _handle_response(self, response: Response) -> dict:
         if response.status_code != 200:
-            raise NuException(f'The request made failed with HTTP status code {response.status_code}',
-                              response.status_code, response.json())
+            raise NuException(response.status_code, response.json(), response.url)
 
         return response.json()
 


Test patch:
diff --git a/requirements-test.txt b/requirements-test.txt
index 39f5d78..a64d515 100644
--- a/requirements-test.txt
+++ b/requirements-test.txt
@@ -1,4 +1,4 @@
 -r requirements.txt
-pytest==5.0.1
+pytest==5.2.2
 pytest-cov==2.7.1
 coveralls==1.8.1
diff --git a/tests/test_nubank_client.py b/tests/test_nubank_client.py
index ba1a5ba..83c6a46 100644
--- a/tests/test_nubank_client.py
+++ b/tests/test_nubank_client.py
@@ -684,7 +684,7 @@ def test_get_qr_code():
     assert isinstance(qr, QRCode)
 
 
-@pytest.mark.parametrize("http_status", [
+@pytest.mark.parametrize('http_status', [
     100, 101, 102, 103,
     201, 202, 203, 204, 205, 206, 207, 208, 226,
     300, 301, 302, 303, 304, 305, 306, 307, 308,
@@ -699,3 +699,43 @@ def test_nubank_request_handler_throws_exception_on_status_different_of_200(http
     client = Nubank()
     with pytest.raises(NuException):
         client._handle_response(response)
+
+
+@patch.object(Nubank, '_update_proxy_urls', fake_update_proxy)
+def test_nubank_request_handler_throws_exception_with_status_code_attribute():
+    http_status = 400
+    response = create_fake_response({}, http_status)
+    client = Nubank()
+    with pytest.raises(NuException) as exception_info:
+        client._handle_response(response)
+
+    assert exception_info.value.status_code == http_status
+
+
+@patch.object(Nubank, '_update_proxy_urls', fake_update_proxy)
+def test_nubank_request_handler_throws_exception_status_code_in_the_exception_message():
+    http_status = 400
+    response = create_fake_response({}, http_status)
+    client = Nubank()
+    with pytest.raises(NuException, match=fr'.*{http_status}.*'):
+        client._handle_response(response)
+
+
+@patch.object(Nubank, '_update_proxy_urls', fake_update_proxy)
+def test_nubank_request_handler_throws_exception_with_url_attribute():
+    response = create_fake_response({}, 400)
+    client = Nubank()
+    with pytest.raises(NuException) as exception_info:
+        client._handle_response(response)
+
+    assert exception_info.value.url == response.url
+
+
+@patch.object(Nubank, '_update_proxy_urls', fake_update_proxy)
+def test_nubank_request_handler_throws_exception_with_response_attribute():
+    response = create_fake_response({}, 400)
+    client = Nubank()
+    with pytest.raises(NuException) as exception_info:
+        client._handle_response(response)
+
+    assert exception_info.value.response == response.json()