diff --git a/Makefile b/Makefile index 9eb1e0e..177d8f5 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,7 @@ lint: @poetry run black --check . @poetry run isort --check . @poetry run flake8 --ignore=E501 . + @poetry run mypy --config-file ${mkfile_dir}mypy.ini . .PHONY: test ## Run unit tests diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 0000000..c0f154d --- /dev/null +++ b/mypy.ini @@ -0,0 +1,19 @@ +[mypy] +disallow_untyped_defs = False +namespace_packages = True +exclude = "scripts/" + +[mypy-blaise_restapi.*] +ignore_missing_imports = True + +[mypy-flask_httpauth.*] +ignore_missing_imports = True + +[mypy-google.auth.transport.requests.*] +ignore_missing_imports = True + +[mypy-google.oauth2.*] +ignore_missing_imports = True + +[mypy-dataclass_wizard.*] +ignore_missing_imports = True diff --git a/pyproject.toml b/pyproject.toml index b50a27c..9cee177 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,27 +7,20 @@ readme = "README.md" [tool.poetry.dependencies] python = "^3.9" -google-cloud-pubsub = "^2.4.1" -google-cloud-storage = "^2.5.0" -grpcio = "^1.59" black = "^24.3.0" -isort = "^5.13.2" -flake8 = "^7.0.0" pytest = "^8.1.1" -mypy = "^1.10.0" -codecov = "^2.1.13" flask = "^2.0.0" -python-dotenv = "^0.18.0" -flake8-cognitive-complexity = "^0.1.0" -pytest-flakefinder = "^1.0.0" -#pytest-lazy-fixture = "^0.6.3" pytest-cov = "^5.0.0" +mypy = "^1.10.0" +isort = "^5.13.2" +codecov = "^2.1.13" blaise-restapi = {git = "https://github.com/ONSdigital/blaise-api-python-client", branch = "BLAIS5-4597"} google-cloud-logging = "^3.10.0" +flake8 = "^7.0.0" [tool.isort] profile = "black" [build-system] -requires = ["poetry-core>=1.0.0"] +requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" diff --git a/tests/services/test_blaise_service.py b/tests/services/test_blaise_service.py index 4261547..857ff46 100644 --- a/tests/services/test_blaise_service.py +++ b/tests/services/test_blaise_service.py @@ -4,9 +4,11 @@ import blaise_restapi import pytest -# import utils +import services +import utils from appconfig.config import Config -from services import validation_service + +# from services import validation_service from services.blaise_service import BlaiseService from services.validation_service import ValidationService from tests.helpers import get_default_config @@ -23,108 +25,108 @@ def blaise_service(config) -> BlaiseService: return BlaiseService(config=config) -# class TestUtils: - -# @pytest.mark.parametrize( -# "file_name, questionnaire_name", -# [ -# ("IPS2501A.zip", "IPS2501A"), -# ("IPS2501A_AA1.zip", "IPS2501A_AA1"), -# ("IPS2502.zip", "IPS2502"), -# ("IPS2503_edit.zip", "IPS2503_edit"), -# ("IPS2503_edit", None), -# ], -# ) -# def test_get_questionnaire_name(self, file_name, questionnaire_name): -# # arrange -# result = utils.get_questionnaire_name(file_name) -# -# # assert -# assert result == questionnaire_name - - -# class TestValidateConfig: - -# @pytest.mark.parametrize( -# "blaise_api_url, blaise_server_park", -# [ -# (None, None), -# ("", None), -# (None, ""), -# ("", ""), -# ], -# ) -# def test_validate_config_logs_and_raises_validation_error_exception_when_both_config_values_are_missing( -# self, blaise_api_url, blaise_server_park, caplog -# ): -# # arrange -# mock_config = Config( -# blaise_api_url=blaise_api_url, blaise_server_park=blaise_server_park -# ) -# validation_service = ValidationService() -# -# # act -# with pytest.raises(ConfigError) as err: -# validation_service.validate_config(mock_config) -# -# # assert -# error_message = "Missing required values from config: ['blaise_api_url', 'blaise_server_park']" -# assert err.value.args[0] == error_message -# assert ( -# "root", -# 40, -# error_message, -# ) in caplog.record_tuples - -# @pytest.mark.parametrize( -# "blaise_api_url", -# [None, ""], -# ) -# def test_validate_config_logs_and_raises_validation_error_exception_when_blaise_api_url_is_missing( -# self, blaise_api_url, caplog -# ): -# # arrange -# mock_config = Config(blaise_api_url=blaise_api_url, blaise_server_park="bar") -# validation_service = ValidationService() -# -# # act -# with pytest.raises(ConfigError) as err: -# validation_service.validate_config(mock_config) -# -# # assert -# error_message = "Missing required values from config: ['blaise_api_url']" -# assert err.value.args[0] == error_message -# assert ( -# "root", -# 40, -# error_message, -# ) in caplog.record_tuples - -# @pytest.mark.parametrize( -# "blaise_server_park", -# [None, ""], -# ) -# def test_validate_config_logs_and_raises_validation_error_exception_when_blaise_server_park_is_missing( -# self, blaise_server_park, caplog -# ): -# # arrange -# mock_config = Config( -# blaise_api_url="foo", blaise_server_park=blaise_server_park -# ) -# validation_service = ValidationService() -# -# # act -# with pytest.raises(ConfigError) as err: -# validation_service.validate_config(mock_config) -# -# # assert -# error_message = "Missing required values from config: ['blaise_server_park']" -# assert err.value.args[0] == error_message -# assert ( -# "root", -# 40, -# error_message, -# ) in caplog.record_tuples +class TestUtils: + + @pytest.mark.parametrize( + "file_name, questionnaire_name", + [ + ("IPS2501A.zip", "IPS2501A"), + ("IPS2501A_AA1.zip", "IPS2501A_AA1"), + ("IPS2502.zip", "IPS2502"), + ("IPS2503_edit.zip", "IPS2503_edit"), + ("IPS2503_edit", None), + ], + ) + def test_get_questionnaire_name(self, file_name, questionnaire_name): + # arrange + result = utils.get_questionnaire_name(file_name) + + # assert + assert result == questionnaire_name + + +class TestValidateConfig: + + @pytest.mark.parametrize( + "blaise_api_url, blaise_server_park", + [ + (None, None), + ("", None), + (None, ""), + ("", ""), + ], + ) + def test_validate_config_logs_and_raises_validation_error_exception_when_both_config_values_are_missing( + self, blaise_api_url, blaise_server_park, caplog + ): + # arrange + mock_config = Config( + blaise_api_url=blaise_api_url, blaise_server_park=blaise_server_park + ) + validation_service = ValidationService() + + # act + with pytest.raises(ConfigError) as err: + validation_service.validate_config(mock_config) + + # assert + error_message = "Missing required values from config: ['blaise_api_url', 'blaise_server_park']" + assert err.value.args[0] == error_message + assert ( + "root", + 40, + error_message, + ) in caplog.record_tuples + + @pytest.mark.parametrize( + "blaise_api_url", + [None, ""], + ) + def test_validate_config_logs_and_raises_validation_error_exception_when_blaise_api_url_is_missing( + self, blaise_api_url, caplog + ): + # arrange + mock_config = Config(blaise_api_url=blaise_api_url, blaise_server_park="bar") + validation_service = ValidationService() + + # act + with pytest.raises(ConfigError) as err: + validation_service.validate_config(mock_config) + + # assert + error_message = "Missing required values from config: ['blaise_api_url']" + assert err.value.args[0] == error_message + assert ( + "root", + 40, + error_message, + ) in caplog.record_tuples + + @pytest.mark.parametrize( + "blaise_server_park", + [None, ""], + ) + def test_validate_config_logs_and_raises_validation_error_exception_when_blaise_server_park_is_missing( + self, blaise_server_park, caplog + ): + # arrange + mock_config = Config( + blaise_api_url="foo", blaise_server_park=blaise_server_park + ) + validation_service = ValidationService() + + # act + with pytest.raises(ConfigError) as err: + validation_service.validate_config(mock_config) + + # assert + error_message = "Missing required values from config: ['blaise_server_park']" + assert err.value.args[0] == error_message + assert ( + "root", + 40, + error_message, + ) in caplog.record_tuples class TestIngest: @@ -211,7 +213,7 @@ def test_validate_config_does_not_raise_an_exception_when_given_valid_config(sel class TestProcessZipFile: @mock.patch.object( - validation_service.ValidationService, "validate_questionnaire_exists" + services.validation_service.ValidationService, "validate_questionnaire_exists" ) def test_validation_questionnaire_exists(self, mock_validate_questionnaire_exists): # arrange