diff --git a/pyproject.toml b/pyproject.toml index 0bcaf242..874f0033 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -282,7 +282,6 @@ ignorelist = [ # Review and update builtin shadowing below this line "filter", "format", - "input", "list", "property", ] @@ -347,18 +346,6 @@ max-complexity = 17 "tests/unit/sdk/test_diff_summary.py" = ["ANN001"] # 9 errors "tests/unit/sdk/test_object_store.py" = ["ANN001"] # 7 errors "tests/unit/sdk/graphql/test_query.py" = ["ANN001"] # 7 errors -"tests/unit/sdk/test_timestamp.py" = ["ANN001"] # 6 errors -"tests/unit/sdk/test_repository.py" = ["ANN001"] # 6 errors -"tests/unit/sdk/test_utils.py" = ["ANN001"] # 4 errors -"tests/unit/sdk/test_store_branch.py" = ["ANN001"] # 4 errors -"tests/unit/sdk/test_query_analyzer.py" = ["ANN001"] # 4 errors -"tests/unit/sdk/test_group_context.py" = ["ANN001"] # 4 errors -"tests/unit/sdk/test_branch.py" = ["ANN001"] # 4 errors -"tests/unit/sdk/test_batch.py" = ["ANN001"] # 4 errors -"tests/unit/sdk/graphql/test_renderer.py" = ["ANN001"] # 4 errors -"tests/unit/sdk/checks/test_checks.py" = ["ANN001"] # 2 errors -"tests/unit/sdk/test_schema_sorter.py" = ["ANN001"] # 1 error -"tests/unit/sdk/test_protocols_generator.py" = ["ANN001"] # 1 error # tests/integration/ - 60 errors total "tests/integration/test_infrahub_client.py" = ["ANN001"] # 32 errors diff --git a/tests/unit/sdk/checks/test_checks.py b/tests/unit/sdk/checks/test_checks.py index 7fe0c691..6433b8b4 100644 --- a/tests/unit/sdk/checks/test_checks.py +++ b/tests/unit/sdk/checks/test_checks.py @@ -1,10 +1,16 @@ +from __future__ import annotations + from pathlib import Path +from typing import TYPE_CHECKING import pytest from infrahub_sdk import InfrahubClient from infrahub_sdk.checks import InfrahubCheck +if TYPE_CHECKING: + from pytest_httpx import HTTPXMock + pytestmark = pytest.mark.httpx_mock(can_send_already_matched_responses=True) @@ -36,7 +42,7 @@ class IFCheckNoName(InfrahubCheck): assert check.root_directory == str(tmp_path) -async def test_async_init(client) -> None: +async def test_async_init(client: InfrahubClient) -> None: class IFCheck(InfrahubCheck): query = "my_query" @@ -44,7 +50,7 @@ class IFCheck(InfrahubCheck): assert isinstance(check.client, InfrahubClient) -async def test_validate_sync_async(mock_gql_query_my_query) -> None: +async def test_validate_sync_async(mock_gql_query_my_query: HTTPXMock) -> None: class IFCheckAsync(InfrahubCheck): query = "my_query" diff --git a/tests/unit/sdk/graphql/test_renderer.py b/tests/unit/sdk/graphql/test_renderer.py index 7803a890..642d688f 100644 --- a/tests/unit/sdk/graphql/test_renderer.py +++ b/tests/unit/sdk/graphql/test_renderer.py @@ -1,7 +1,9 @@ +from typing import Any + from infrahub_sdk.graphql.renderers import render_input_block, render_query_block -def test_render_query_block(query_data_no_filter) -> None: +def test_render_query_block(query_data_no_filter: dict[str, Any]) -> None: lines = render_query_block(data=query_data_no_filter) expected_lines = [ @@ -44,7 +46,7 @@ def test_render_query_block(query_data_no_filter) -> None: assert lines == expected_lines -def test_render_query_block_alias(query_data_alias) -> None: +def test_render_query_block_alias(query_data_alias: dict[str, Any]) -> None: lines = render_query_block(data=query_data_alias) expected_lines = [ @@ -66,7 +68,7 @@ def test_render_query_block_alias(query_data_alias) -> None: assert lines == expected_lines -def test_render_query_block_fragment(query_data_fragment) -> None: +def test_render_query_block_fragment(query_data_fragment: dict[str, Any]) -> None: lines = render_query_block(data=query_data_fragment) expected_lines = [ @@ -90,7 +92,7 @@ def test_render_query_block_fragment(query_data_fragment) -> None: assert lines == expected_lines -def test_render_input_block(input_data_01) -> None: +def test_render_input_block(input_data_01: dict[str, Any]) -> None: lines = render_input_block(data=input_data_01) expected_lines = [ diff --git a/tests/unit/sdk/test_batch.py b/tests/unit/sdk/test_batch.py index 2998f767..7bdf00ad 100644 --- a/tests/unit/sdk/test_batch.py +++ b/tests/unit/sdk/test_batch.py @@ -50,8 +50,8 @@ def test_func() -> int: @pytest.mark.parametrize("client_type", client_types) async def test_batch_return_exception( httpx_mock: HTTPXMock, - mock_query_mutation_location_create_failed, - mock_schema_query_01, + mock_query_mutation_location_create_failed: HTTPXMock, + mock_schema_query_01: HTTPXMock, clients: BothClients, client_type: str, ) -> None: @@ -96,8 +96,8 @@ async def test_batch_return_exception( @pytest.mark.parametrize("client_type", client_types) async def test_batch_exception( httpx_mock: HTTPXMock, - mock_query_mutation_location_create_failed, - mock_schema_query_01, + mock_query_mutation_location_create_failed: HTTPXMock, + mock_schema_query_01: HTTPXMock, clients: BothClients, client_type: str, ) -> None: diff --git a/tests/unit/sdk/test_branch.py b/tests/unit/sdk/test_branch.py index 4e3d93f2..88f4a530 100644 --- a/tests/unit/sdk/test_branch.py +++ b/tests/unit/sdk/test_branch.py @@ -1,4 +1,7 @@ +from __future__ import annotations + import inspect +from typing import TYPE_CHECKING import pytest @@ -8,6 +11,11 @@ InfrahubBranchManagerSync, ) +if TYPE_CHECKING: + from pytest_httpx import HTTPXMock + + from tests.unit.sdk.conftest import BothClients + async_branch_methods = [method for method in dir(InfrahubBranchManager) if not method.startswith("_")] sync_branch_methods = [method for method in dir(InfrahubBranchManagerSync) if not method.startswith("_")] @@ -21,7 +29,7 @@ def test_method_sanity() -> None: @pytest.mark.parametrize("method", async_branch_methods) -def test_validate_method_signature(method) -> None: +def test_validate_method_signature(method: str) -> None: async_method = getattr(InfrahubBranchManager, method) sync_method = getattr(InfrahubBranchManagerSync, method) async_sig = inspect.signature(async_method) @@ -31,7 +39,7 @@ def test_validate_method_signature(method) -> None: @pytest.mark.parametrize("client_type", client_types) -async def test_get_branches(clients, mock_branches_list_query, client_type) -> None: +async def test_get_branches(clients: BothClients, mock_branches_list_query: HTTPXMock, client_type: str) -> None: if client_type == "standard": branches = await clients.standard.branch.all() else: diff --git a/tests/unit/sdk/test_group_context.py b/tests/unit/sdk/test_group_context.py index be00cd51..7b4de550 100644 --- a/tests/unit/sdk/test_group_context.py +++ b/tests/unit/sdk/test_group_context.py @@ -1,8 +1,10 @@ import inspect +from collections.abc import Callable import pytest from infrahub_sdk.query_groups import InfrahubGroupContext, InfrahubGroupContextBase, InfrahubGroupContextSync +from infrahub_sdk.schema import NodeSchemaAPI async_methods = [method for method in dir(InfrahubGroupContext) if not method.startswith("_")] sync_methods = [method for method in dir(InfrahubGroupContextSync) if not method.startswith("_")] @@ -18,7 +20,9 @@ async def test_method_sanity() -> None: @pytest.mark.parametrize("method", async_methods) async def test_validate_method_signature( - method, replace_sync_return_annotation, replace_async_return_annotation + method: str, + replace_sync_return_annotation: Callable[[str], str], + replace_async_return_annotation: Callable[[str], str], ) -> None: async_method = getattr(InfrahubGroupContext, method) sync_method = getattr(InfrahubGroupContextSync, method) @@ -65,7 +69,7 @@ def test_generate_group_name() -> None: assert context._generate_group_name(suffix="xxx") == "MYID-xxx-11aaec5206c3dca37cbbcaaabf121550" -def test_generate_group_description(std_group_schema) -> None: +def test_generate_group_description(std_group_schema: NodeSchemaAPI) -> None: context = InfrahubGroupContextBase() context.set_properties(identifier="MYID") assert not context._generate_group_description(schema=std_group_schema) diff --git a/tests/unit/sdk/test_protocols_generator.py b/tests/unit/sdk/test_protocols_generator.py index 22822717..55796db6 100644 --- a/tests/unit/sdk/test_protocols_generator.py +++ b/tests/unit/sdk/test_protocols_generator.py @@ -1,10 +1,14 @@ from dataclasses import dataclass +from typing import TYPE_CHECKING import pytest from infrahub_sdk import InfrahubClient from infrahub_sdk.protocols_generator.generator import CodeGenerator +if TYPE_CHECKING: + from pytest_httpx import HTTPXMock + @dataclass class SyncifyTestCase: @@ -41,7 +45,7 @@ async def test_filter_syncify(test_case: SyncifyTestCase) -> None: assert CodeGenerator._jinja2_filter_syncify(value=test_case.input, sync=test_case.sync) == test_case.output -async def test_generator(client: InfrahubClient, mock_schema_query_05) -> None: +async def test_generator(client: InfrahubClient, mock_schema_query_05: "HTTPXMock") -> None: schemas = await client.schema.fetch(branch="main") code_generator = CodeGenerator(schema=schemas) diff --git a/tests/unit/sdk/test_query_analyzer.py b/tests/unit/sdk/test_query_analyzer.py index 26acdd16..a4deefb2 100644 --- a/tests/unit/sdk/test_query_analyzer.py +++ b/tests/unit/sdk/test_query_analyzer.py @@ -5,7 +5,7 @@ from infrahub_sdk.analyzer import GraphQLOperation, GraphQLQueryAnalyzer -async def test_analyzer_init_query_only(query_01, bad_query_01) -> None: +async def test_analyzer_init_query_only(query_01: str, bad_query_01: str) -> None: gqa = GraphQLQueryAnalyzer(query=query_01) assert isinstance(gqa.document, DocumentNode) @@ -151,7 +151,7 @@ async def test_get_variables(query_01: str, query_04: str, query_05: str, query_ "var_type,var_required", [("[ID]", False), ("[ID]!", True), ("[ID!]", False), ("[ID!]!", True)], ) -async def test_get_nested_variables(var_type, var_required) -> None: +async def test_get_nested_variables(var_type: str, var_required: bool) -> None: query = ( """ query ($ids: %s){ diff --git a/tests/unit/sdk/test_repository.py b/tests/unit/sdk/test_repository.py index 4e4bf177..a3c7f6eb 100644 --- a/tests/unit/sdk/test_repository.py +++ b/tests/unit/sdk/test_repository.py @@ -17,7 +17,7 @@ def temp_dir() -> Generator[str]: yield tmp_dir -def test_initialize_repo_creates_new_repo(temp_dir) -> None: +def test_initialize_repo_creates_new_repo(temp_dir: str) -> None: """Test that a new Git repository is created if none exists.""" manager = GitRepoManager(root_directory=temp_dir, branch="main") @@ -29,7 +29,7 @@ def test_initialize_repo_creates_new_repo(temp_dir) -> None: assert isinstance(manager.git, Repo) -def test_initialize_repo_uses_existing_repo(temp_dir) -> None: +def test_initialize_repo_uses_existing_repo(temp_dir: str) -> None: """Test that the GitRepoManager uses an existing repository without an active branch.""" # Manually initialize a repo Repo.init(temp_dir, default_branch=b"main") @@ -40,7 +40,7 @@ def test_initialize_repo_uses_existing_repo(temp_dir) -> None: assert (Path(temp_dir) / ".git").is_dir() -def test_active_branch_returns_correct_branch(temp_dir) -> None: +def test_active_branch_returns_correct_branch(temp_dir: str) -> None: """Test that the active branch is correctly returned.""" manager = GitRepoManager(temp_dir, branch="develop") @@ -48,7 +48,7 @@ def test_active_branch_returns_correct_branch(temp_dir) -> None: assert manager.active_branch == "develop" -def test_initialize_repo_raises_error_on_failure(monkeypatch, temp_dir) -> None: +def test_initialize_repo_raises_error_on_failure(monkeypatch: pytest.MonkeyPatch, temp_dir: str) -> None: """Test that an error is raised if the repository cannot be initialized.""" def mock_init(*args, **kwargs) -> None: # noqa: ANN002, ANN003 @@ -60,7 +60,7 @@ def mock_init(*args, **kwargs) -> None: # noqa: ANN002, ANN003 GitRepoManager(temp_dir) -def test_gitrepo_init(temp_dir) -> None: +def test_gitrepo_init(temp_dir: str) -> None: src_directory = get_fixtures_dir() / "integration/mock_repo" repo = GitRepo(name="mock_repo", src_directory=src_directory, dst_directory=Path(temp_dir)) assert len(list(repo._repo.git.get_walker())) == 1 diff --git a/tests/unit/sdk/test_schema_sorter.py b/tests/unit/sdk/test_schema_sorter.py index 5db5bb68..20d0cc5f 100644 --- a/tests/unit/sdk/test_schema_sorter.py +++ b/tests/unit/sdk/test_schema_sorter.py @@ -1,8 +1,13 @@ +from typing import TYPE_CHECKING + from infrahub_sdk import InfrahubClient from infrahub_sdk.transfer.schema_sorter import InfrahubSchemaTopologicalSorter +if TYPE_CHECKING: + from pytest_httpx import HTTPXMock + -async def test_schema_sorter(client: InfrahubClient, mock_schema_query_01) -> None: +async def test_schema_sorter(client: InfrahubClient, mock_schema_query_01: "HTTPXMock") -> None: schemas = await client.schema.all() topological_sorter = InfrahubSchemaTopologicalSorter() diff --git a/tests/unit/sdk/test_store_branch.py b/tests/unit/sdk/test_store_branch.py index 3262f406..81c89705 100644 --- a/tests/unit/sdk/test_store_branch.py +++ b/tests/unit/sdk/test_store_branch.py @@ -3,10 +3,11 @@ from infrahub_sdk.client import InfrahubClient from infrahub_sdk.exceptions import NodeNotFoundError from infrahub_sdk.node import InfrahubNode +from infrahub_sdk.schema import NodeSchemaAPI from infrahub_sdk.store import NodeStoreBranch -def test_node_store_set(client: InfrahubClient, schema_with_hfid) -> None: +def test_node_store_set(client: InfrahubClient, schema_with_hfid: dict[str, NodeSchemaAPI]) -> None: data = { "name": {"value": "JFK1"}, "description": {"value": "JFK Airport"}, @@ -22,7 +23,7 @@ def test_node_store_set(client: InfrahubClient, schema_with_hfid) -> None: assert store._keys["mykey"] == node._internal_id -def test_node_store_set_no_hfid(client: InfrahubClient, location_schema) -> None: +def test_node_store_set_no_hfid(client: InfrahubClient, location_schema: NodeSchemaAPI) -> None: data = { "name": {"value": "JFK1"}, "description": {"value": "JFK Airport"}, @@ -39,7 +40,7 @@ def test_node_store_set_no_hfid(client: InfrahubClient, location_schema) -> None assert store._keys["mykey"] == node._internal_id -def test_node_store_get(client: InfrahubClient, location_schema) -> None: +def test_node_store_get(client: InfrahubClient, location_schema: NodeSchemaAPI) -> None: data = { "id": "54f3108c-1f21-44c4-93cf-ec5737587b48", "name": {"value": "JFK1"}, @@ -65,7 +66,7 @@ def test_node_store_get(client: InfrahubClient, location_schema) -> None: store.get(key="anotherkey") -def test_node_store_get_with_hfid(client: InfrahubClient, schema_with_hfid) -> None: +def test_node_store_get_with_hfid(client: InfrahubClient, schema_with_hfid: dict[str, NodeSchemaAPI]) -> None: data = { "id": "54f3108c-1f21-44c4-93cf-ec5737587b48", "name": {"value": "JFK1"}, diff --git a/tests/unit/sdk/test_timestamp.py b/tests/unit/sdk/test_timestamp.py index ec219a45..a4e9bc79 100644 --- a/tests/unit/sdk/test_timestamp.py +++ b/tests/unit/sdk/test_timestamp.py @@ -63,7 +63,7 @@ def test_parse_string() -> None: ), ], ) -def test_to_datetime(input_str, expected_datetime) -> None: +def test_to_datetime(input_str: str, expected_datetime: datetime) -> None: assert isinstance(Timestamp(input_str).to_datetime(), datetime) assert Timestamp(input_str).to_datetime() == expected_datetime @@ -85,7 +85,7 @@ def test_to_datetime(input_str, expected_datetime) -> None: ), ], ) -def test_to_string_default(input_str, expected_str, expected_str_no_z) -> None: +def test_to_string_default(input_str: str, expected_str: str, expected_str_no_z: str) -> None: assert isinstance(Timestamp(input_str).to_string(), str) assert Timestamp(input_str).to_string() == expected_str assert Timestamp(input_str).to_string(with_z=False) == expected_str_no_z @@ -129,6 +129,6 @@ def test_serialize() -> None: @pytest.mark.parametrize("invalid_str", ["blurple", "1122334455667788", "2023-45-99"]) -def test_invalid_raises_correct_error(invalid_str) -> None: +def test_invalid_raises_correct_error(invalid_str: str) -> None: with pytest.raises(TimestampFormatError): Timestamp(invalid_str) diff --git a/tests/unit/sdk/test_utils.py b/tests/unit/sdk/test_utils.py index fb7a3557..eae23150 100644 --- a/tests/unit/sdk/test_utils.py +++ b/tests/unit/sdk/test_utils.py @@ -1,7 +1,9 @@ import json import tempfile import uuid +from dataclasses import dataclass from pathlib import Path +from typing import Any from unittest.mock import Mock import pytest @@ -47,22 +49,31 @@ def test_is_valid_uuid() -> None: assert is_valid_uuid(uuid.UUID) is False +@dataclass +class ValidURLTestCase: + input: Any + result: bool + + +VALID_URL_TEST_CASES = [ + ValidURLTestCase(input=55, result=False), + ValidURLTestCase(input="https://", result=False), + ValidURLTestCase(input="my-server", result=False), + ValidURLTestCase(input="http://my-server", result=True), + ValidURLTestCase(input="http://my-server:8080", result=True), + ValidURLTestCase(input="http://192.168.1.10", result=True), + ValidURLTestCase(input="/test", result=True), + ValidURLTestCase(input="/", result=True), + ValidURLTestCase(input="http:/192.168.1.10", result=False), +] + + @pytest.mark.parametrize( - "input,result", - [ - (55, False), - ("https://", False), - ("my-server", False), - ("http://my-server", True), - ("http://my-server:8080", True), - ("http://192.168.1.10", True), - ("/test", True), - ("/", True), - ("http:/192.168.1.10", False), - ], + "test_case", + [pytest.param(tc, id=str(tc.input)) for tc in VALID_URL_TEST_CASES], ) -def test_is_valid_url(input, result) -> None: - assert is_valid_url(input) is result +def test_is_valid_url(test_case: ValidURLTestCase) -> None: + assert is_valid_url(test_case.input) is test_case.result def test_duplicates() -> None: @@ -156,7 +167,7 @@ def test_dict_hash() -> None: assert dict_hash({}) == "99914b932bd37a50b983c5e7c90ae93b" -async def test_extract_fields(query_01) -> None: +async def test_extract_fields(query_01: str) -> None: document = parse(query_01) expected_response = { "TestPerson": { @@ -171,7 +182,7 @@ async def test_extract_fields(query_01) -> None: assert await extract_fields(document.definitions[0].selection_set) == expected_response -async def test_extract_fields_fragment(query_02) -> None: +async def test_extract_fields_fragment(query_02: str) -> None: document = parse(query_02) expected_response = {