Repository: julianneswinoga/flightgear-python (language: python)

Issue:
Add tests for `HTTPConnection`
Like `tests/test_props_connection.py` a test for the new `HTTPConnection` class would be fantastic.


Discussion / hints:

Fix patch:
diff --git a/README.md b/README.md
index c3678ca..9dd0931 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
 [![CircleCI](https://circleci.com/gh/julianneswinoga/flightgear-python.svg?style=shield)](https://circleci.com/gh/julianneswinoga/flightgear-python)
 [![Coverage Status](https://coveralls.io/repos/github/julianneswinoga/flightgear-python/badge.svg?branch=master)](https://coveralls.io/github/julianneswinoga/flightgear-python?branch=master)
 [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/flightgear_python)](https://pypi.org/project/flightgear-python/)
-![PyPI - Downloads](https://img.shields.io/pypi/dm/flightgear-python)
+[![PyPI - Downloads](https://img.shields.io/pypi/dm/flightgear-python)](https://pypistats.org/packages/flightgear-python)
 
 `flightgear-python` is an interface package to the [FlightGear flight simulation software](https://www.flightgear.org/) aimed at simplicity.
 
diff --git a/poetry.lock b/poetry.lock
index 4edacca..c9571ff 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -441,6 +441,22 @@ urllib3 = ">=1.21.1,<1.27"
 socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
 use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"]
 
+[[package]]
+name = "requests-mock"
+version = "1.11.0"
+description = "Mock out responses from the requests package"
+category = "dev"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+requests = ">=2.3,<3"
+six = "*"
+
+[package.extras]
+fixture = ["fixtures"]
+test = ["fixtures", "mock", "purl", "pytest", "requests-futures", "sphinx", "testtools"]
+
 [[package]]
 name = "sh"
 version = "1.14.3"
@@ -449,6 +465,14 @@ category = "dev"
 optional = false
 python-versions = "*"
 
+[[package]]
+name = "six"
+version = "1.16.0"
+description = "Python 2 and 3 compatibility utilities"
+category = "dev"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
+
 [[package]]
 name = "smmap"
 version = "5.0.0"
@@ -648,7 +672,7 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=4.6)", "pytest-black (
 [metadata]
 lock-version = "1.1"
 python-versions = "^3.6.2"
-content-hash = "99c4505e37a80a373308a23ac00a11b28d7b043fcdd953d425d89f79c0757b1a"
+content-hash = "35f5e64d391914eca6323ba77de36c05e926f416fb3c063826ae3e0eef6ee534"
 
 [metadata.files]
 alabaster = [
@@ -998,9 +1022,17 @@ requests = [
     {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"},
     {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"},
 ]
+requests-mock = [
+    {file = "requests-mock-1.11.0.tar.gz", hash = "sha256:ef10b572b489a5f28e09b708697208c4a3b2b89ef80a9f01584340ea357ec3c4"},
+    {file = "requests_mock-1.11.0-py2.py3-none-any.whl", hash = "sha256:f7fae383f228633f6bececebdab236c478ace2284d6292c6e7e2867b9ab74d15"},
+]
 sh = [
     {file = "sh-1.14.3.tar.gz", hash = "sha256:e4045b6c732d9ce75d571c79f5ac2234edd9ae4f5fa9d59b09705082bdca18c7"},
 ]
+six = [
+    {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
+    {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
+]
 smmap = [
     {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"},
     {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"},
diff --git a/pyproject.toml b/pyproject.toml
index a7a2d7b..c797ca1 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -15,7 +15,7 @@ python = "^3.6.2"
 construct = "^2.10"
 # Following are pegged at the latest version that supports Python 3.6
 multiprocess = "==0.70.12.2"
-requests = "2.27.1"
+requests = "==2.27.1"
 
 [tool.poetry.dev-dependencies]
 sphinx = "^5.1.1"
@@ -23,6 +23,7 @@ sphinx_mdinclude = "^0.5.2"
 sphinx-rtd-theme = "^0.5.2"  # Can't `poetry update` with 1.0.0?
 sh = "^1.14.3"
 pytest-cov = "^3.0.0"
+requests-mock = "^1.11.0"
 # Following are pegged at the latest version that supports Python 3.6
 pytest = "==7.0.1"
 GitPython = "==3.1.20"


Test patch:
diff --git a/scripts/run_tests.sh b/scripts/run_tests.sh
index da4cdb1..32e396a 100755
--- a/scripts/run_tests.sh
+++ b/scripts/run_tests.sh
@@ -13,6 +13,14 @@ if [ "$1" = 'clean' ]; then
   pip3 install -U Cython
   poetry update -vvv
 fi
+
+# Remove clean from args
+for arg in "$@"; do
+  shift
+  [ "$arg" = "clean" ] && continue
+  set -- "$@" "$arg"
+done
+
 poetry build
 poetry install
-pytest --cov-report term-missing:skip-covered --cov=flightgear_python tests/
+pytest --cov-report term-missing:skip-covered --cov=flightgear_python tests/ "$@"
diff --git a/tests/test_fdm_connection.py b/tests/test_fdm_connection.py
index c3bdf11..e0a763a 100644
--- a/tests/test_fdm_connection.py
+++ b/tests/test_fdm_connection.py
@@ -65,6 +65,10 @@ def rx_cb(fdm_data, event_pipe):
         assert run_idx == i
         assert callback_version == fdm_version
 
+    # Prevent 'ResourceWarning: unclosed' warning
+    fdm_c.fg_rx_sock.close()
+    fdm_c.fg_tx_sock.close()
+
 
 @pytest.mark.parametrize('fdm_version', supported_fdm_versions)
 def test_fdm_only_rx(mocker, fdm_version):
@@ -83,3 +87,6 @@ def rx_cb(fdm_data, event_pipe):
         fdm_c._fg_packet_roundtrip()
         (callback_version,) = fdm_c.event_pipe.parent_recv()
         assert callback_version == fdm_version
+
+    # Prevent 'ResourceWarning: unclosed' warning
+    fdm_c.fg_rx_sock.close()
diff --git a/tests/test_http_connection.py b/tests/test_http_connection.py
new file mode 100644
index 0000000..5d0bf07
--- /dev/null
+++ b/tests/test_http_connection.py
@@ -0,0 +1,65 @@
+import requests_mock
+import pytest
+
+from flightgear_python.fg_if import HTTPConnection
+
+# Excerpt from https://wiki.flightgear.org/Json_Properties#Example
+preset_values = [
+    {
+        'path': '/sim/time/cur-time-override',
+        'name': 'cur-time-override',
+        'value': '0',
+        'type': 'long',
+        'index': 0,
+        'nChildren': 0,
+    },
+    {
+        'path': '/sim/time/local-offset',
+        'name': 'local-offset',
+        'value': '3600',
+        'type': 'int',
+        'index': 0,
+        'nChildren': 0,
+    },
+    {
+        'path': '/sim/time/gmt',
+        'name': 'gmt',
+        'value': '2014-03-27T13:25:10',
+        'type': 'string',
+        'index': 0,
+        'nChildren': 0,
+    },
+    {
+        'path': '/sim/time/sun-angle-rad',
+        'name': 'sun-angle-rad',
+        'value': '0.9883239645',
+        'type': 'double',
+        'index': 0,
+        'nChildren': 0,
+    },
+]
+
+
+@pytest.mark.parametrize('preset_value', preset_values)
+def test_http_get_prop(preset_value):
+    h_con = HTTPConnection('localhost', 55555)
+    with requests_mock.Mocker() as m:
+        prop_path = preset_value['path']
+        # Set the mock value
+        m.get(h_con.url + prop_path, json=preset_value)
+        # Check the code result
+        resp = h_con.get_prop(prop_path)
+        # Instead of comparing the converted value, just convert the converted value to a string and compare that
+        assert str(resp) == preset_value['value']
+
+
+@pytest.mark.parametrize('preset_value', preset_values)
+def test_http_set_prop(preset_value):
+    h_con = HTTPConnection('localhost', 55555)
+    with requests_mock.Mocker() as m:
+        prop_path = preset_value['path']
+        # Set the mock value
+        m.get(h_con.url + prop_path, json=preset_value)
+        m.post(h_con.url + prop_path)
+        # Check the code doesn't break (nothing to assert)
+        h_con.set_prop(prop_path, 'test value')
diff --git a/tests/test_integration_using_JSBSim.py b/tests/test_integration_using_JSBSim.py
index ea99611..fbd8e84 100644
--- a/tests/test_integration_using_JSBSim.py
+++ b/tests/test_integration_using_JSBSim.py
@@ -62,6 +62,9 @@ def test_jsbsim_integration(fdm_version, capsys):
 
     fdm_conn.stop()
 
+    # Prevent 'ResourceWarning: unclosed' warning
+    fdm_conn.fg_rx_sock.close()
+
     # Make sure we got at least half of the updates
     total_updates = len(pos_history)
     assert total_updates > (total_sim_steps / 2)
diff --git a/tests/test_props_connection.py b/tests/test_props_connection.py
index 26a5af3..58c116c 100644
--- a/tests/test_props_connection.py
+++ b/tests/test_props_connection.py
@@ -28,3 +28,5 @@ def test_props_round_trip(mocker):
     p_con = PropsConnection('localhost', 55554)
     resp = p_con._send_cmd_get_resp(cmd)
     assert ('A' * 512) in resp
+    # Prevent 'ResourceWarning: unclosed' warning
+    p_con.sock.close()