Skip to content

Commit

Permalink
create http client class (#135)
Browse files Browse the repository at this point in the history
  • Loading branch information
fsilvamaia authored Oct 24, 2023
1 parent 8084d45 commit d3e2e35
Show file tree
Hide file tree
Showing 12 changed files with 549 additions and 204 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ venv/
ENV/
env.bak/
venv.bak/
.vscode

# Spyder project settings
.spyderproject
Expand Down
90 changes: 90 additions & 0 deletions tests/functional/test_http_client_functional.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
"""This module contains unit tests for the HTTPClient class."""
# vim: set filetype=python ts=4 sw=4
# -*- coding: utf-8 -*-
import pytest
from requests import RequestException
from tokendito import __title__
from tokendito import __version__
from tokendito.http_client import HTTPClient


@pytest.fixture
def client():
"""Fixture to create and return an HTTPClient instance."""
client = HTTPClient()
client.session.headers.update({"User-Agent": f"{__title__}/{__version__}"})
return client


def test_get_request(client):
"""Test the GET request functionality of HTTPClient."""
# Make a GET request to the /get endpoint of httpbin which reflects the sent request data
response = client.get("https://httpbin.org/get")
json_data = response.json()

# Assert that the request was successful and the returned User-Agent matches the one we set
assert response.status_code == 200
assert json_data["headers"]["User-Agent"] == f"{__title__}/{__version__}"


def test_post_request(client):
"""Test the POST request functionality of HTTPClient."""
# Make a POST request to the /post endpoint of httpbin with sample data
response = client.post("https://httpbin.org/post", json={"key": "value"})
json_data = response.json()

# Assert that the request was successful and the returned json data matches the data we sent
assert response.status_code == 200
assert json_data["json"] == {"key": "value"}


def test_set_cookies(client):
"""Test the ability to set cookies using HTTPClient."""
# Set a test cookie for the client
client.set_cookies({"test_cookie": "cookie_value"})

# Make a request to the /cookies endpoint of httpbin which returns set cookies
response = client.get("https://httpbin.org/cookies")
json_data = response.json()

# Assert that the cookie we set is correctly returned by the server
assert json_data["cookies"] == {"test_cookie": "cookie_value"}


def test_custom_header(client):
"""Test the ability to send custom headers using HTTPClient."""
# Make a GET request with a custom header
response = client.get("https://httpbin.org/get", headers={"X-Test-Header": "TestValue"})
json_data = response.json()

# Assert that the custom header was correctly sent
assert json_data["headers"]["X-Test-Header"] == "TestValue"


def test_bad_get_request(client, mocker):
"""Test GET request failure scenario."""
mocker.patch("requests.Session.get", side_effect=RequestException("An error occurred"))
with pytest.raises(SystemExit):
client.get("https://httpbin.org/get")


def test_bad_post_request(client, mocker):
"""Test POST request failure scenario."""
mocker.patch("requests.Session.post", side_effect=RequestException("An error occurred"))
with pytest.raises(SystemExit):
client.post("https://httpbin.org/post", json={"key": "value"})


def test_reset_session(client):
"""Test the reset method to ensure session is reset."""
# Set a test cookie for the client
client.set_cookies({"test_cookie": "cookie_value"})
# Reset the session
client.reset()

# Make a request to the /cookies endpoint of httpbin which returns set cookies
response = client.get("https://httpbin.org/cookies")
json_data = response.json()

# Assert that the cookies have been cleared
assert json_data["cookies"] == {}
20 changes: 15 additions & 5 deletions tests/unit/test_aws.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# vim: set filetype=python ts=4 sw=4
# -*- coding: utf-8 -*-
"""Unit tests, and local fixtures for AWS module."""
from unittest.mock import Mock

import pytest


Expand Down Expand Up @@ -91,10 +93,18 @@ def test_select_assumeable_role_no_tiles():
@pytest.mark.parametrize("status_code", [(400), (401), (404), (500), (503)])
def test_authenticate_to_roles(status_code, monkeypatch):
"""Test if function return correct response."""
import requests
from tokendito.aws import authenticate_to_roles
import tokendito.http_client as http_client

mock_get = {"status_code": status_code, "text": "response"}
monkeypatch.setattr(requests, "get", mock_get)
with pytest.raises(SystemExit) as error:
assert authenticate_to_roles([("http://test.url.com", "")], "secret_session_token") == error
# Create a mock response object
mock_response = Mock()
mock_response.status_code = status_code
mock_response.text = "response"

# Use monkeypatch to replace the HTTP_client.get method with the mock
monkeypatch.setattr(http_client.HTTP_client, "get", lambda *args, **kwargs: mock_response)

cookies = {"some_cookie": "some_value"}

with pytest.raises(SystemExit):
authenticate_to_roles([("http://test.url.com", "")], cookies)
157 changes: 157 additions & 0 deletions tests/unit/test_http_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
"""Unit tests for the HTTPClient class."""
# vim: set filetype=python ts=4 sw=4
# -*- coding: utf-8 -*-
import pytest
import requests
from tokendito import __title__
from tokendito import __version__
from tokendito.http_client import HTTPClient

# Unit test class for the HTTPClient.


@pytest.fixture
def client():
"""Fixture for setting up an HTTPClient instance."""
# Initializing HTTPClient instance without the 'user_agent' parameter
return HTTPClient()


def test_init(client):
"""Test initialization of HTTPClient instance."""
# Check if the session property of the client is an instance of requests.Session
assert isinstance(client.session, requests.Session)

# Check if the User-Agent header was set correctly during initialization
expected_user_agent = f"{__title__}/{__version__}"
assert client.session.headers["User-Agent"] == expected_user_agent


def test_set_cookies(client):
"""Test setting cookies in the session."""
cookies = {"test_cookie": "cookie_value"}
client.set_cookies(cookies)
# Check if the provided cookie is set correctly in the session
assert client.session.cookies.get_dict() == cookies


def test_get(client, mocker):
"""Test GET request method."""
mock_get = mocker.patch("requests.Session.get")
mock_resp = mocker.Mock()
mock_resp.status_code = 200
mock_resp.text = "OK"
mock_get.return_value = mock_resp

response = client.get("http://test.com")
# Check if the response status code and text match the expected values
assert response.status_code == 200
assert response.text == "OK"


def test_post(client, mocker):
"""Test POST request method."""
mock_post = mocker.patch("requests.Session.post")
mock_resp = mocker.Mock()
mock_resp.status_code = 201
mock_resp.text = "Created"
mock_post.return_value = mock_resp

response = client.post("http://test.com", json={"key": "value"})
# Check if the response status code and text match the expected values
assert response.status_code == 201
assert response.text == "Created"


def test_get_failure(client, mocker):
"""Test GET request failure scenario."""
mock_get = mocker.patch("requests.Session.get")
mock_get.side_effect = requests.RequestException("Failed to connect")

with pytest.raises(SystemExit):
client.get("http://test.com")


def test_post_failure(client, mocker):
"""Test POST request failure scenario."""
mock_post = mocker.patch("requests.Session.post")
mock_post.side_effect = requests.RequestException("Failed to connect")

with pytest.raises(SystemExit):
client.post("http://test.com", json={"key": "value"})


def test_post_with_return_json(client, mocker):
"""Test POST request with return_json=True."""
mock_post = mocker.patch("requests.Session.post")
mock_resp = mocker.Mock()
mock_resp.status_code = 201
mock_resp.json.return_value = {"status": "Created"}
mock_post.return_value = mock_resp

response = client.post("http://test.com", json={"key": "value"}, return_json=True)
assert response == {"status": "Created"}


def test_reset(client):
"""Test the reset method."""
# Updating the session headers to check if they are reset later
client.session.headers.update({"Test-Header": "Test-Value"})

client.reset()

expected_user_agent = f"{__title__}/{__version__}"
assert "Test-Header" not in client.session.headers
assert client.session.headers["User-Agent"] == expected_user_agent


def test_get_generic_exception(client, mocker):
"""Test GET request with generic exception."""
mock_get = mocker.patch("requests.Session.get")
mock_get.side_effect = Exception("Some Exception")

with pytest.raises(SystemExit):
client.get("http://test.com")


def test_post_generic_exception(client, mocker):
"""Test POST request with generic exception."""
mock_post = mocker.patch("requests.Session.post")
mock_post.side_effect = Exception("Some Exception")

with pytest.raises(SystemExit):
client.post("http://test.com", json={"key": "value"})


def test_post_json_exception(client, mocker):
"""Test POST request when json() method raises an exception."""
mock_post = mocker.patch("requests.Session.post")
mock_resp = mocker.Mock()
mock_resp.status_code = 201
mock_resp.json.side_effect = Exception("JSON Exception")
mock_post.return_value = mock_resp

with pytest.raises(SystemExit):
client.post("http://test.com", json={"key": "value"}, return_json=True)


def test_get_logging_on_exception(client, mocker):
"""Test if logging occurs during exception in GET request."""
mock_get = mocker.patch("requests.Session.get")
mock_get.side_effect = requests.RequestException("Failed to connect")
mock_logger = mocker.patch("logging.Logger.error")

with pytest.raises(SystemExit):
client.get("http://test.com")
mock_logger.assert_called()


def test_post_logging_on_exception(client, mocker):
"""Test if logging occurs during exception in POST request."""
mock_post = mocker.patch("requests.Session.post")
mock_post.side_effect = requests.RequestException("Failed to connect")
mock_logger = mocker.patch("logging.Logger.error")

with pytest.raises(SystemExit):
client.post("http://test.com", json={"key": "value"})
mock_logger.assert_called()
Loading

0 comments on commit d3e2e35

Please sign in to comment.