Merge pull request #1244 from jooola/api_client_pytest
Migrate api_clients tests to pytest
This commit is contained in:
commit
8bbd0d608c
|
@ -4,6 +4,9 @@ echo "::group::Install Python apps"
|
||||||
pip3 install nose mock
|
pip3 install nose mock
|
||||||
|
|
||||||
for app in $(ls python_apps); do
|
for app in $(ls python_apps); do
|
||||||
|
if [[ -f "python_apps/$app/requirements-dev.txt" ]]; then
|
||||||
|
pip3 install -r "python_apps/$app/requirements-dev.txt"
|
||||||
|
fi
|
||||||
pip3 install -e python_apps/$app
|
pip3 install -e python_apps/$app
|
||||||
done
|
done
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
|
@ -4,21 +4,19 @@ failed='f'
|
||||||
# Starting at repo root
|
# Starting at repo root
|
||||||
|
|
||||||
echo "::group::Airtime Analyzer"
|
echo "::group::Airtime Analyzer"
|
||||||
cd python_apps/airtime_analyzer
|
pushd python_apps/airtime_analyzer
|
||||||
if ! nosetests . -x; then
|
if ! nosetests . -x; then
|
||||||
failed='t'
|
failed='t'
|
||||||
fi
|
fi
|
||||||
|
popd
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
echo "::group::API Client"
|
echo "::group::API Client"
|
||||||
cd ../api_clients
|
if ! make -C python_apps/api_clients test; then
|
||||||
if ! nosetests . -x; then
|
|
||||||
failed='t'
|
failed='t'
|
||||||
fi
|
fi
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
# Reset to repo root
|
|
||||||
cd ../..
|
|
||||||
if [[ "$failed" = "t" ]]; then
|
if [[ "$failed" = "t" ]]; then
|
||||||
echo "Python tests failed"
|
echo "Python tests failed"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
.PHONY: lint test
|
||||||
|
|
||||||
|
SHELL := bash
|
||||||
|
CPU_CORES := $(shell nproc)
|
||||||
|
|
||||||
|
MODULE_APP := api_clients
|
||||||
|
MODULE_TESTS := tests
|
||||||
|
|
||||||
|
lint:
|
||||||
|
pylint ${MODULE_APP}
|
||||||
|
pylint ${MODULE_TESTS}
|
||||||
|
|
||||||
|
test:
|
||||||
|
pytest -n ${CPU_CORES} --color=yes -v --cov=${MODULE_APP} ${MODULE_TESTS}
|
||||||
|
|
||||||
|
all: lint test
|
|
@ -0,0 +1,5 @@
|
||||||
|
mock
|
||||||
|
pylint
|
||||||
|
pytest
|
||||||
|
pytest-cov
|
||||||
|
pytest-xdist
|
|
@ -1,33 +1,32 @@
|
||||||
import unittest
|
import pytest
|
||||||
|
|
||||||
from api_clients.utils import ApcUrl, IncompleteUrl, UrlBadParam
|
from api_clients.utils import ApcUrl, IncompleteUrl, UrlBadParam
|
||||||
|
|
||||||
|
|
||||||
class TestApcUrl(unittest.TestCase):
|
@pytest.mark.parametrize(
|
||||||
def test_init(self):
|
"url, params, expected",
|
||||||
url = "/testing"
|
[
|
||||||
u = ApcUrl(url)
|
("one/two/three", {}, "one/two/three"),
|
||||||
self.assertEqual(u.base_url, url)
|
("/testing/{key}", {"key": "aaa"}, "/testing/aaa"),
|
||||||
|
(
|
||||||
|
"/more/{key_a}/{key_b}/testing",
|
||||||
|
{"key_a": "aaa", "key_b": "bbb"},
|
||||||
|
"/more/aaa/bbb/testing",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_apc_url(url: str, params: dict, expected: str):
|
||||||
|
found = ApcUrl(url)
|
||||||
|
assert found.base_url == url
|
||||||
|
assert found.params(**params).url() == expected
|
||||||
|
|
||||||
def test_params_1(self):
|
|
||||||
u = ApcUrl("/testing/{key}")
|
|
||||||
self.assertEqual(u.params(key="val").url(), "/testing/val")
|
|
||||||
|
|
||||||
def test_params_2(self):
|
def test_apc_url_bad_param():
|
||||||
u = ApcUrl("/testing/{key}/{api}/more_testing")
|
url = ApcUrl("/testing/{key}")
|
||||||
full_url = u.params(key="AAA", api="BBB").url()
|
with pytest.raises(UrlBadParam):
|
||||||
self.assertEqual(full_url, "/testing/AAA/BBB/more_testing")
|
url.params(bad_key="testing")
|
||||||
|
|
||||||
def test_params_ex(self):
|
|
||||||
u = ApcUrl("/testing/{key}")
|
|
||||||
with self.assertRaises(UrlBadParam):
|
|
||||||
u.params(bad_key="testing")
|
|
||||||
|
|
||||||
def test_url(self):
|
def test_apc_url_incomplete():
|
||||||
u = "one/two/three"
|
url = ApcUrl("/{one}/{two}/three").params(two="testing")
|
||||||
self.assertEqual(ApcUrl(u).url(), u)
|
with pytest.raises(IncompleteUrl):
|
||||||
|
url.url()
|
||||||
def test_url_ex(self):
|
|
||||||
u = ApcUrl("/{one}/{two}/three").params(two="testing")
|
|
||||||
with self.assertRaises(IncompleteUrl):
|
|
||||||
u.url()
|
|
||||||
|
|
|
@ -1,46 +1,33 @@
|
||||||
import json
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
from api_clients.utils import ApcUrl, ApiRequest
|
from api_clients.utils import ApcUrl, ApiRequest
|
||||||
from mock import MagicMock, patch
|
from mock import MagicMock, patch
|
||||||
|
|
||||||
|
|
||||||
class ResponseInfo:
|
def test_api_request_init():
|
||||||
@property
|
u = ApiRequest("request_name", ApcUrl("/test/ing"))
|
||||||
def headers(self):
|
assert u.name == "request_name"
|
||||||
return {"content-type": "application/json"}
|
|
||||||
|
|
||||||
def json(self):
|
|
||||||
return {"ok", "ok"}
|
|
||||||
|
|
||||||
|
|
||||||
class TestApiRequest(unittest.TestCase):
|
def test_api_request_call_json():
|
||||||
def test_init(self):
|
return_value = {"ok": "ok"}
|
||||||
u = ApiRequest("request_name", ApcUrl("/test/ing"))
|
|
||||||
self.assertEqual(u.name, "request_name")
|
|
||||||
|
|
||||||
def test_call_json(self):
|
read = MagicMock()
|
||||||
ret = {"ok": "ok"}
|
read.headers = {"content-type": "application/json"}
|
||||||
read = MagicMock()
|
read.json = MagicMock(return_value=return_value)
|
||||||
read.headers = {"content-type": "application/json"}
|
|
||||||
read.json = MagicMock(return_value=ret)
|
|
||||||
u = "http://localhost/testing"
|
|
||||||
with patch("requests.get") as mock_method:
|
|
||||||
mock_method.return_value = read
|
|
||||||
request = ApiRequest("mm", ApcUrl(u))()
|
|
||||||
self.assertEqual(request, ret)
|
|
||||||
|
|
||||||
def test_call_html(self):
|
with patch("requests.get") as mock_method:
|
||||||
ret = "<html><head></head><body></body></html>"
|
mock_method.return_value = read
|
||||||
read = MagicMock()
|
request = ApiRequest("mm", ApcUrl("http://localhost/testing"))()
|
||||||
read.headers = {"content-type": "application/html"}
|
assert request == return_value
|
||||||
read.text = MagicMock(return_value=ret)
|
|
||||||
u = "http://localhost/testing"
|
|
||||||
with patch("requests.get") as mock_method:
|
|
||||||
mock_method.return_value = read
|
|
||||||
request = ApiRequest("mm", ApcUrl(u))()
|
|
||||||
self.assertEqual(request.text(), ret)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
def test_api_request_call_html():
|
||||||
unittest.main()
|
return_value = "<html><head></head><body></body></html>"
|
||||||
|
|
||||||
|
read = MagicMock()
|
||||||
|
read.headers = {"content-type": "application/html"}
|
||||||
|
read.text = MagicMock(return_value=return_value)
|
||||||
|
|
||||||
|
with patch("requests.get") as mock_method:
|
||||||
|
mock_method.return_value = read
|
||||||
|
request = ApiRequest("mm", ApcUrl("http://localhost/testing"))()
|
||||||
|
assert request.text() == return_value
|
||||||
|
|
|
@ -1,39 +1,33 @@
|
||||||
import json
|
import pytest
|
||||||
import unittest
|
|
||||||
|
|
||||||
from api_clients.utils import RequestProvider
|
from api_clients.utils import RequestProvider
|
||||||
from api_clients.version1 import api_config
|
from api_clients.version1 import api_config
|
||||||
from configobj import ConfigObj
|
|
||||||
from mock import MagicMock, patch
|
|
||||||
|
|
||||||
|
|
||||||
class TestRequestProvider(unittest.TestCase):
|
@pytest.fixture()
|
||||||
def setUp(self):
|
def config():
|
||||||
self.cfg = api_config
|
return {
|
||||||
self.cfg["general"] = {}
|
**api_config,
|
||||||
self.cfg["general"]["base_dir"] = "/test"
|
"general": {
|
||||||
self.cfg["general"]["base_port"] = 80
|
"base_dir": "/test",
|
||||||
self.cfg["general"]["base_url"] = "localhost"
|
"base_port": 80,
|
||||||
self.cfg["general"]["api_key"] = "TEST_KEY"
|
"base_url": "localhost",
|
||||||
self.cfg["api_base"] = "api"
|
"api_key": "TEST_KEY",
|
||||||
|
},
|
||||||
def test_test(self):
|
"api_base": "api",
|
||||||
self.assertTrue("general" in self.cfg)
|
}
|
||||||
|
|
||||||
def test_init(self):
|
|
||||||
rp = RequestProvider(self.cfg, {})
|
|
||||||
self.assertEqual(len(rp.available_requests()), 0)
|
|
||||||
|
|
||||||
def test_contains(self):
|
|
||||||
methods = {
|
|
||||||
"upload_recorded": "/1/",
|
|
||||||
"update_media_url": "/2/",
|
|
||||||
"list_all_db_files": "/3/",
|
|
||||||
}
|
|
||||||
rp = RequestProvider(self.cfg, methods)
|
|
||||||
for meth in methods:
|
|
||||||
self.assertTrue(meth in rp.requests)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
def test_request_provider_init(config):
|
||||||
unittest.main()
|
request_provider = RequestProvider(config, {})
|
||||||
|
assert len(request_provider.available_requests()) == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_request_provider_contains(config):
|
||||||
|
endpoints = {
|
||||||
|
"upload_recorded": "/1/",
|
||||||
|
"update_media_url": "/2/",
|
||||||
|
"list_all_db_files": "/3/",
|
||||||
|
}
|
||||||
|
request_provider = RequestProvider(config, endpoints)
|
||||||
|
for endpoint in endpoints:
|
||||||
|
assert endpoint in request_provider.requests
|
||||||
|
|
|
@ -1,102 +1,57 @@
|
||||||
import configparser
|
|
||||||
import datetime
|
import datetime
|
||||||
import unittest
|
from configparser import ConfigParser
|
||||||
|
|
||||||
|
import pytest
|
||||||
from api_clients import utils
|
from api_clients import utils
|
||||||
|
|
||||||
|
|
||||||
def get_force_ssl(value, useConfigParser):
|
def test_time_in_seconds():
|
||||||
config = {}
|
time = datetime.time(hour=0, minute=3, second=34, microsecond=649600)
|
||||||
if useConfigParser:
|
assert abs(utils.time_in_seconds(time) - 214.65) < 0.009
|
||||||
config = configparser.ConfigParser()
|
|
||||||
config["general"] = {
|
|
||||||
"base_port": 80,
|
|
||||||
"force_ssl": value,
|
|
||||||
}
|
|
||||||
return utils.get_protocol(config)
|
|
||||||
|
|
||||||
|
|
||||||
class TestTime(unittest.TestCase):
|
def test_time_in_milliseconds():
|
||||||
def test_time_in_seconds(self):
|
time = datetime.time(hour=0, minute=0, second=0, microsecond=500000)
|
||||||
time = datetime.time(hour=0, minute=3, second=34, microsecond=649600)
|
assert utils.time_in_milliseconds(time) == 500
|
||||||
self.assertTrue(abs(utils.time_in_seconds(time) - 214.65) < 0.009)
|
|
||||||
|
|
||||||
def test_time_in_milliseconds(self):
|
|
||||||
time = datetime.time(hour=0, minute=0, second=0, microsecond=500000)
|
|
||||||
self.assertEqual(utils.time_in_milliseconds(time), 500)
|
|
||||||
|
|
||||||
|
|
||||||
class TestGetProtocol(unittest.TestCase):
|
@pytest.mark.parametrize(
|
||||||
def test_dict_config_empty_http(self):
|
"payload, expected",
|
||||||
config = {"general": {}}
|
[({}, "http"), ({"base_port": 80}, "http"), ({"base_port": 443}, "https")],
|
||||||
protocol = utils.get_protocol(config)
|
)
|
||||||
self.assertEqual(protocol, "http")
|
@pytest.mark.parametrize(
|
||||||
|
"use_config",
|
||||||
|
[False, True],
|
||||||
|
)
|
||||||
|
def test_get_protocol(payload, use_config, expected):
|
||||||
|
config = ConfigParser() if use_config else {}
|
||||||
|
config["general"] = {**payload}
|
||||||
|
|
||||||
def test_dict_config_http(self):
|
assert utils.get_protocol(config) == expected
|
||||||
config = {
|
|
||||||
"general": {
|
|
||||||
"base_port": 80,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
protocol = utils.get_protocol(config)
|
|
||||||
self.assertEqual(protocol, "http")
|
|
||||||
|
|
||||||
def test_dict_config_https(self):
|
|
||||||
config = {
|
|
||||||
"general": {
|
|
||||||
"base_port": 443,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
protocol = utils.get_protocol(config)
|
|
||||||
self.assertEqual(protocol, "https")
|
|
||||||
|
|
||||||
def test_dict_config_force_https(self):
|
|
||||||
postive_values = ["yes", "Yes", "True", "true", True]
|
|
||||||
negative_values = ["no", "No", "False", "false", False]
|
|
||||||
for value in postive_values:
|
|
||||||
self.assertEqual(get_force_ssl(value, False), "https")
|
|
||||||
for value in negative_values:
|
|
||||||
self.assertEqual(get_force_ssl(value, False), "http")
|
|
||||||
|
|
||||||
def test_configparser_config_empty_http(self):
|
|
||||||
config = configparser.ConfigParser()
|
|
||||||
config["general"] = {}
|
|
||||||
protocol = utils.get_protocol(config)
|
|
||||||
self.assertEqual(protocol, "http")
|
|
||||||
|
|
||||||
def test_configparser_config_http(self):
|
|
||||||
config = configparser.ConfigParser()
|
|
||||||
config["general"] = {
|
|
||||||
"base_port": 80,
|
|
||||||
}
|
|
||||||
protocol = utils.get_protocol(config)
|
|
||||||
self.assertEqual(protocol, "http")
|
|
||||||
|
|
||||||
def test_configparser_config_https(self):
|
|
||||||
config = configparser.ConfigParser()
|
|
||||||
config["general"] = {
|
|
||||||
"base_port": 443,
|
|
||||||
}
|
|
||||||
protocol = utils.get_protocol(config)
|
|
||||||
self.assertEqual(protocol, "https")
|
|
||||||
|
|
||||||
def test_configparser_config_force_https(self):
|
|
||||||
postive_values = ["yes", "Yes", "True", "true", True]
|
|
||||||
negative_values = ["no", "No", "False", "false", False]
|
|
||||||
for value in postive_values:
|
|
||||||
self.assertEqual(get_force_ssl(value, True), "https")
|
|
||||||
for value in negative_values:
|
|
||||||
self.assertEqual(get_force_ssl(value, True), "http")
|
|
||||||
|
|
||||||
def test_fromisoformat(self):
|
|
||||||
time = {
|
|
||||||
"00:00:00.500000": datetime.time(microsecond=500000),
|
|
||||||
"00:04:30.092540": datetime.time(minute=4, second=30, microsecond=92540),
|
|
||||||
}
|
|
||||||
for time_string, expected in time.items():
|
|
||||||
result = utils.fromisoformat(time_string)
|
|
||||||
self.assertEqual(result, expected)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
@pytest.mark.parametrize("payload", [{}, {"base_port": 80}])
|
||||||
unittest.main()
|
@pytest.mark.parametrize("use_config", [False, True])
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"values, expected",
|
||||||
|
[
|
||||||
|
(["yes", "Yes", "True", "true", True], "https"),
|
||||||
|
(["no", "No", "False", "false", False], "http"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_get_protocol_force_https(payload, use_config, values, expected):
|
||||||
|
for value in values:
|
||||||
|
config = ConfigParser() if use_config else {}
|
||||||
|
config["general"] = {**payload, "force_ssl": value}
|
||||||
|
assert utils.get_protocol(config) == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"payload, expected",
|
||||||
|
[
|
||||||
|
("00:00:00.500000", datetime.time(microsecond=500000)),
|
||||||
|
("00:04:30.092540", datetime.time(minute=4, second=30, microsecond=92540)),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_fromisoformat(payload, expected):
|
||||||
|
assert utils.fromisoformat(payload) == expected
|
||||||
|
|
Loading…
Reference in New Issue