from __future__ import annotations import pytest from pydantic import ValidationError from v1.profile.schemas import ProfileResponse, ProfileUpdateRequest def test_profile_response_maps_fields() -> None: response = ProfileResponse( id="user-1", username="demo", avatar_url=None, bio=None, ) assert response.id == "user-1" assert response.username == "demo" def test_profile_update_requires_one_field() -> None: with pytest.raises(ValidationError): ProfileUpdateRequest() def test_profile_update_accepts_valid_https_url() -> None: request = ProfileUpdateRequest(avatar_url="https://example.com/avatar.png") assert request.avatar_url == "https://example.com/avatar.png" def test_profile_update_accepts_valid_http_url() -> None: request = ProfileUpdateRequest( avatar_url="http://localhost:8001/storage/avatar.png" ) assert request.avatar_url == "http://localhost:8001/storage/avatar.png" def test_profile_update_rejects_invalid_url() -> None: with pytest.raises(ValidationError) as exc_info: ProfileUpdateRequest(avatar_url="not-a-valid-url") errors = exc_info.value.errors() assert len(errors) == 1 assert "avatar_url" in str(errors[0]["loc"]) def test_profile_update_rejects_javascript_url() -> None: with pytest.raises(ValidationError): ProfileUpdateRequest(avatar_url="javascript:alert('xss')") def test_profile_update_rejects_data_url() -> None: with pytest.raises(ValidationError): ProfileUpdateRequest(avatar_url="data:text/html,") def test_profile_update_accepts_none_avatar_url_with_other_field() -> None: request = ProfileUpdateRequest(username="tester", avatar_url=None) assert request.avatar_url is None assert request.username == "tester" def test_profile_update_rejects_display_name_field() -> None: with pytest.raises(ValidationError): ProfileUpdateRequest.model_validate({"display_name": "legacy"})