Merge pull request #1244 from jooola/api_client_pytest

Migrate api_clients tests to pytest
This commit is contained in:
Kyle Robbertze 2021-06-08 14:19:31 +02:00 committed by GitHub
commit 8bbd0d608c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 147 additions and 190 deletions

View File

@ -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::"

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,5 @@
mock
pylint
pytest
pytest-cov
pytest-xdist

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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