from typing import Final

from dirty_equals import IsPartialDict
from dishka import FromDishka

from tests.web_api.helpers import is_forbidden_response, is_success_response
from tests.web_api.ioc import DatabaseClearer, inject
from tests.web_api.test_api_gateway import TestApiGateway

DEFAULT_PASSWORD: Final = "Sup3rSecret"  # noqa: S105


@inject
async def test_get_profile_returns_current_user(
    unique_email: str,
    test_api_gateway: FromDishka[TestApiGateway],
    database_clearer: FromDishka[DatabaseClearer],
) -> None:
    await database_clearer.clear()

    response_sign_up = await test_api_gateway.sign_up_email(unique_email, DEFAULT_PASSWORD)
    access_token = response_sign_up.json()["access_token"]

    response = await test_api_gateway.get_profile(access_token)
    assert is_success_response(response)
    assert response.json() == IsPartialDict(
        email=unique_email,
        display_name=None,
    )


@inject
async def test_patch_profile_updates_profile_data(
    unique_email: str,
    test_api_gateway: FromDishka[TestApiGateway],
    database_clearer: FromDishka[DatabaseClearer],
) -> None:
    await database_clearer.clear()

    response = await test_api_gateway.sign_up_email(
        email=unique_email,
        password=DEFAULT_PASSWORD,
    )
    access_token = response.json()["access_token"]

    patch_response = await test_api_gateway.patch_profile(
        access_token=access_token,
        display_name="Alice",
        first_name="Alice",
        last_name="Smith",
        avatar_url="https://example.com/avatar.png",
        phone="+1234567890",
    )
    assert is_success_response(patch_response)
    assert patch_response.json() == IsPartialDict(
        display_name="Alice",
        first_name="Alice",
        last_name="Smith",
        avatar_url="https://example.com/avatar.png",
        phone="+1234567890",
        email=unique_email,
    )

    get_response = await test_api_gateway.get_profile(access_token)
    assert is_success_response(get_response)
    assert get_response.json() == IsPartialDict(
        display_name="Alice",
        first_name="Alice",
        last_name="Smith",
        avatar_url="https://example.com/avatar.png",
        phone="+1234567890",
        email=unique_email,
    )


@inject
async def test_profile_routes_require_authentication(
    test_api_gateway: FromDishka[TestApiGateway],
    database_clearer: FromDishka[DatabaseClearer],
) -> None:
    await database_clearer.clear()

    response_get = await test_api_gateway.get_profile(None)
    assert is_forbidden_response(response_get)

    response_patch = await test_api_gateway.patch_profile()
    assert is_forbidden_response(response_patch)
