Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[glitchtip] add type hints to glitchtip tests #3107

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 7 additions & 4 deletions reconcile/test/glitchtip/conftest.py
Expand Up @@ -18,26 +18,29 @@ def glitchtip_token() -> str:


@pytest.fixture
def glitchtip_client_minimal(glitchtip_url, glitchtip_token) -> GlitchtipClient:
def glitchtip_client_minimal(
glitchtip_url: str, glitchtip_token: str
) -> GlitchtipClient:
return GlitchtipClient(host=glitchtip_url, token=glitchtip_token)


@pytest.fixture
def glitchtip_client(
glitchtip_client_minimal, glitchtip_server_full_api_response
glitchtip_client_minimal: GlitchtipClient,
glitchtip_server_full_api_response: None,
) -> GlitchtipClient:
return glitchtip_client_minimal


@pytest.fixture
def fx():
def fx() -> Fixtures:
return Fixtures("glitchtip")


@pytest.fixture
def glitchtip_server_full_api_response(
httpretty: httpretty_module, glitchtip_url: str, fx: Fixtures
):
) -> None:
"""Text fixture.

See reconcile/glitchtip/README.md for more details.
Expand Down
11 changes: 8 additions & 3 deletions reconcile/test/glitchtip/test_glitchtip.py
@@ -1,8 +1,11 @@
from pytest_mock import MockerFixture

from reconcile.glitchtip.integration import (
fetch_current_state,
fetch_desired_state,
)
from reconcile.gql_definitions.glitchtip.glitchtip_project import GlitchtipProjectsV1
from reconcile.test.fixtures import Fixtures
from reconcile.utils.glitchtip import (
GlitchtipClient,
Organization,
Expand All @@ -26,8 +29,10 @@ def sort_all(orgs: list[Organization]) -> list[Organization]:


def test_fetch_current_state(
glitchtip_client: GlitchtipClient, glitchtip_server_full_api_response, fx
):
glitchtip_client: GlitchtipClient,
glitchtip_server_full_api_response: None,
fx: Fixtures,
) -> None:
current_state = fetch_current_state(
glitchtip_client, ignore_users=["sd-app-sre+glitchtip@nasa.com"]
)
Expand All @@ -38,7 +43,7 @@ def test_fetch_current_state(
assert sort_all(current_state) == sort_all(expected_current_state)


def test_desire_state(mocker, fx):
def test_desire_state(mocker: MockerFixture, fx: Fixtures) -> None:
projects = [
GlitchtipProjectsV1(**i) for i in fx.get_anymarkup("desire_state_projects.yml")
]
Expand Down
25 changes: 14 additions & 11 deletions reconcile/test/glitchtip/test_glitchtip_reconciler.py
Expand Up @@ -6,6 +6,7 @@
import httpretty as httpretty_module
import pytest
from pydantic import BaseModel
from pytest_mock import MockerFixture

from reconcile.glitchtip.reconciler import GlitchtipReconciler
from reconcile.test.fixtures import Fixtures
Expand All @@ -26,7 +27,9 @@ class GlitchtipUrl(BaseModel):


@pytest.fixture
def configure_httpretty(httpretty: httpretty_module, glitchtip_url: str):
def configure_httpretty(
httpretty: httpretty_module, glitchtip_url: str
) -> Callable[[list[GlitchtipUrl]], int]:
httpretty.Response

def f(glitchtip_urls: list[GlitchtipUrl]) -> int:
Expand All @@ -49,7 +52,7 @@ def f(glitchtip_urls: list[GlitchtipUrl]) -> int:
@pytest.mark.parametrize("dry_run", [True, False])
def test_glitchtip_reconciler_init(
glitchtip_client_minimal: GlitchtipClient, dry_run: bool
):
) -> None:
gtr = GlitchtipReconciler(client=glitchtip_client_minimal, dry_run=dry_run)
assert gtr.client == glitchtip_client_minimal
assert gtr.dry_run == dry_run
Expand All @@ -64,8 +67,8 @@ def test_glitchtip_reconciler_reconcile_users(
httpretty: httpretty_module,
glitchtip_client_minimal: GlitchtipClient,
fx: Fixtures,
configure_httpretty: Callable,
):
configure_httpretty: Callable[[list[GlitchtipUrl]], int],
) -> None:
fixture = fx.get_anymarkup(f"reconciler/users/{fixture_name}.yml")
current_users = [User(**i) for i in fixture["current_users"]]
desired_users = [User(**i) for i in fixture["desired_users"]]
Expand Down Expand Up @@ -99,8 +102,8 @@ def test_glitchtip_reconciler_reconcile_teams(
httpretty: httpretty_module,
glitchtip_client_minimal: GlitchtipClient,
fx: Fixtures,
configure_httpretty: Callable,
):
configure_httpretty: Callable[[list[GlitchtipUrl]], int],
) -> None:
fixture = fx.get_anymarkup(f"reconciler/teams/{fixture_name}.yml")
organization_users = [User(**i) for i in fixture["organization_users"]]
current_teams = [Team(**i) for i in fixture["current_teams"]]
Expand Down Expand Up @@ -136,8 +139,8 @@ def test_glitchtip_reconciler_reconcile_projects(
httpretty: httpretty_module,
glitchtip_client_minimal: GlitchtipClient,
fx: Fixtures,
configure_httpretty: Callable,
):
configure_httpretty: Callable[[list[GlitchtipUrl]], int],
) -> None:
fixture = fx.get_anymarkup(f"reconciler/projects/{fixture_name}.yml")
organization_teams = [Team(**i) for i in fixture["organization_teams"]]
current_projects = [Project(**i) for i in fixture["current_projects"]]
Expand Down Expand Up @@ -173,9 +176,9 @@ def test_glitchtip_reconciler_reconcile_organization(
httpretty: httpretty_module,
glitchtip_client_minimal: GlitchtipClient,
fx: Fixtures,
configure_httpretty: Callable,
mocker,
):
configure_httpretty: Callable[[list[GlitchtipUrl]], int],
mocker: MockerFixture,
) -> None:
fixture = fx.get_anymarkup(f"reconciler/organizations/{fixture_name}.yml")
current_organizations = [
Organization(**i) for i in fixture["current_organizations"]
Expand Down
66 changes: 39 additions & 27 deletions reconcile/test/glitchtip/test_utils_glitchtip_client.py
@@ -1,5 +1,9 @@
import json
from typing import Optional
from collections.abc import Mapping
from typing import (
Any,
Optional,
)

import httpretty as httpretty_module
import pytest
Expand Down Expand Up @@ -89,7 +93,7 @@ def test_get_next_url(

def test_glitchtip_client_list(
httpretty: httpretty_module, glitchtip_client: GlitchtipClient, glitchtip_url: str
):
) -> None:
first_url = f"{glitchtip_url}/data"
second_url = f"{glitchtip_url}/data2"

Expand All @@ -113,7 +117,7 @@ def test_glitchtip_client_list(

def test_glitchtip_client_get(
httpretty: httpretty_module, glitchtip_client: GlitchtipClient, glitchtip_url: str
):
) -> None:
url = f"{glitchtip_url}/data"
test_obj = {"test": "object"}
httpretty.register_uri(
Expand All @@ -124,15 +128,19 @@ def test_glitchtip_client_get(

def test_glitchtip_client_post(
httpretty: httpretty_module, glitchtip_client: GlitchtipClient, glitchtip_url: str
):
) -> None:
url = f"{glitchtip_url}/data"
request_data = {"test": "object"}
response_data = {"foo": "bar"}

def request_callback(request, uri, response_headers):
def request_callback(
request: httpretty_module.core.HTTPrettyRequest,
uri: str,
response_headers: Mapping[str, Any],
) -> tuple[int, Mapping[str, Any], str]:
assert request.headers.get("Content-Type") == "application/json"
assert json.loads(request.body) == request_data
return [201, response_headers, json.dumps(response_data)]
return (201, response_headers, json.dumps(response_data))

httpretty.register_uri(
httpretty.POST, url, content_type="text/json", body=request_callback
Expand All @@ -142,56 +150,60 @@ def request_callback(request, uri, response_headers):

def test_glitchtip_client_put(
httpretty: httpretty_module, glitchtip_client: GlitchtipClient, glitchtip_url: str
):
) -> None:
url = f"{glitchtip_url}/data"
request_data = {"test": "object"}
response_data = {"foo": "bar"}

def request_callback(request, uri, response_headers):
def request_callback(
request: httpretty_module.core.HTTPrettyRequest,
uri: str,
response_headers: Mapping[str, Any],
) -> tuple[int, Mapping[str, Any], str]:
assert request.headers.get("Content-Type") == "application/json"
assert json.loads(request.body) == request_data
return [201, response_headers, json.dumps(response_data)]
return (201, response_headers, json.dumps(response_data))

httpretty.register_uri(
httpretty.PUT, url, content_type="text/json", body=request_callback
)
assert glitchtip_client._put(url, data=request_data) == response_data


def test_glitchtip_organizations(glitchtip_client: GlitchtipClient):
def test_glitchtip_organizations(glitchtip_client: GlitchtipClient) -> None:
assert glitchtip_client.organizations() == [
Organization(id=10, name="ESA", slug="esa", projects=[], teams=[], users=[]),
Organization(id=4, name="NASA", slug="nasa", projects=[], teams=[], users=[]),
]


def test_glitchtip_create_organization(glitchtip_client: GlitchtipClient):
def test_glitchtip_create_organization(glitchtip_client: GlitchtipClient) -> None:
org = glitchtip_client.create_organization(name="ASA")
assert org.name == "ASA"
assert org.slug == "asa"


def test_glitchtip_delete_organization(glitchtip_client: GlitchtipClient):
def test_glitchtip_delete_organization(glitchtip_client: GlitchtipClient) -> None:
glitchtip_client.delete_organization(slug="esa")


def test_glitchtip_teams(glitchtip_client: GlitchtipClient):
def test_glitchtip_teams(glitchtip_client: GlitchtipClient) -> None:
assert glitchtip_client.teams(organization_slug="nasa") == [
Team(id=4, slug="nasa-flight-control", users=[]),
Team(id=2, slug="nasa-pilots", users=[]),
]


def test_glitchtip_create_team(glitchtip_client: GlitchtipClient):
def test_glitchtip_create_team(glitchtip_client: GlitchtipClient) -> None:
team = glitchtip_client.create_team(organization_slug="esa", slug="launchpad-crew")
assert team.slug == "launchpad-crew"


def test_glitchtip_delete_team(glitchtip_client: GlitchtipClient):
def test_glitchtip_delete_team(glitchtip_client: GlitchtipClient) -> None:
glitchtip_client.delete_team(organization_slug="esa", slug="esa-pilots")


def test_glitchtip_projects(glitchtip_client: GlitchtipClient):
def test_glitchtip_projects(glitchtip_client: GlitchtipClient) -> None:
assert glitchtip_client.projects(organization_slug="nasa") == [
Project(
id=8,
Expand All @@ -213,7 +225,7 @@ def test_glitchtip_projects(glitchtip_client: GlitchtipClient):
]


def test_glitchtip_create_project(glitchtip_client: GlitchtipClient):
def test_glitchtip_create_project(glitchtip_client: GlitchtipClient) -> None:
project = glitchtip_client.create_project(
organization_slug="nasa",
team_slug="nasa-pilots",
Expand All @@ -225,26 +237,26 @@ def test_glitchtip_create_project(glitchtip_client: GlitchtipClient):
assert project.teams[0].pk == 2


def test_glitchtip_delete_project(glitchtip_client: GlitchtipClient):
def test_glitchtip_delete_project(glitchtip_client: GlitchtipClient) -> None:
glitchtip_client.delete_project(
organization_slug="nasa", team_slug="nasa-pilots", slug="science-tools"
)


def test_glitchtip_add_project_to_team(glitchtip_client: GlitchtipClient):
def test_glitchtip_add_project_to_team(glitchtip_client: GlitchtipClient) -> None:
project = glitchtip_client.add_project_to_team(
organization_slug="nasa", team_slug="nasa-flight-control", slug="science-tools"
)
assert len(project.teams) == 2


def test_glitchtip_remove_project_from_team(glitchtip_client: GlitchtipClient):
def test_glitchtip_remove_project_from_team(glitchtip_client: GlitchtipClient) -> None:
glitchtip_client.remove_project_from_team(
organization_slug="nasa", team_slug="nasa-flight-control", slug="science-tools"
)


def test_glitchtip_organization_users(glitchtip_client: GlitchtipClient):
def test_glitchtip_organization_users(glitchtip_client: GlitchtipClient) -> None:
assert glitchtip_client.organization_users(organization_slug="nasa") == [
User(id=23, email="MichaelCollins@nasa.com", role="member", pending=False),
User(
Expand All @@ -259,26 +271,26 @@ def test_glitchtip_organization_users(glitchtip_client: GlitchtipClient):
]


def test_glitchtip_invite_user(glitchtip_client: GlitchtipClient):
def test_glitchtip_invite_user(glitchtip_client: GlitchtipClient) -> None:
user = glitchtip_client.invite_user(
organization_slug="nasa", email="Gene.Kranz@nasa.com", role="member"
)
assert user.email == "Gene.Kranz@nasa.com"
assert user.pending


def test_glitchtip_delete_user(glitchtip_client: GlitchtipClient):
def test_glitchtip_delete_user(glitchtip_client: GlitchtipClient) -> None:
glitchtip_client.delete_user(organization_slug="nasa", pk=29)


def test_glitchtip_update_user_role(glitchtip_client: GlitchtipClient):
def test_glitchtip_update_user_role(glitchtip_client: GlitchtipClient) -> None:
user = glitchtip_client.update_user_role(
organization_slug="nasa", role="manager", pk=29
)
assert user.role == "manager"


def test_glitchtip_team_users(glitchtip_client: GlitchtipClient):
def test_glitchtip_team_users(glitchtip_client: GlitchtipClient) -> None:
assert glitchtip_client.team_users(
organization_slug="nasa", team_slug="nasa-flight-control"
) == [
Expand All @@ -292,14 +304,14 @@ def test_glitchtip_team_users(glitchtip_client: GlitchtipClient):
]


def test_glitchtip_add_user_to_team(glitchtip_client: GlitchtipClient):
def test_glitchtip_add_user_to_team(glitchtip_client: GlitchtipClient) -> None:
team = glitchtip_client.add_user_to_team(
organization_slug="nasa", team_slug="nasa-pilots", user_pk=29
)
assert len(team.users) > 0


def test_glitchtip_remove_user_from_team(glitchtip_client: GlitchtipClient):
def test_glitchtip_remove_user_from_team(glitchtip_client: GlitchtipClient) -> None:
glitchtip_client.remove_user_from_team(
organization_slug="nasa", team_slug="nasa-pilots", user_pk=29
)
13 changes: 10 additions & 3 deletions reconcile/test/glitchtip/test_utils_glitchtip_models.py
@@ -1,3 +1,6 @@
from collections.abc import Mapping
from typing import Union

import pytest

from reconcile.utils.glitchtip import (
Expand All @@ -19,19 +22,23 @@
],
)
@pytest.mark.parametrize("model", [Organization, Project, Team])
def test_model_slugs(model, name, slug):
def test_model_slugs(
model: Union[type[Organization], type[Project], type[Team]], name: str, slug: str
) -> None:
assert model(name=name).slug == slug


@pytest.mark.parametrize(
"team_kwargs",
[
pytest.param({"name": "Test", "slug": "Test 1 2 3"}, marks=pytest.mark.xfail),
pytest.param(
{"name": "Test", "slug": "Test 1 2 3"}, marks=pytest.mark.xfail(strict=True)
),
{"name": "Test 1 2 3"},
{"slug": "test-1-2-3"},
],
)
def test_model_team(team_kwargs):
def test_model_team(team_kwargs: Mapping[str, str]) -> None:
slug = slugify("Test 1 2 3")
team = Team(**team_kwargs)
assert team.name == slug
Expand Down
4 changes: 4 additions & 0 deletions setup.cfg
Expand Up @@ -565,6 +565,10 @@ check_untyped_defs = False
[mypy-reconcile.test.test_gitlab_housekeeping]
check_untyped_defs = False

[mypy-reconcile.test.glitchtip.*]
disallow_untyped_defs = True
disallow_incomplete_defs = True

[mypy-reconcile.test.test_ocm_upgrade_scheduler]
check_untyped_defs = False

Expand Down