|
1 | 1 | import http |
2 | 2 |
|
3 | 3 | import pytest |
| 4 | +import yaml |
4 | 5 | from allauth.account.models import EmailAddress |
5 | 6 | from allauth.socialaccount.models import SocialAccount, SocialApp |
6 | 7 | from django.urls import reverse |
@@ -134,6 +135,74 @@ def test_social_account_list_filter_by_user(api_client, regular_user, multi_soci |
134 | 135 | assert {row["uid"] for row in rows} == {"alice-google-1"} |
135 | 136 |
|
136 | 137 |
|
| 138 | +@pytest.mark.django_db |
| 139 | +def test_social_account_list_filter_by_provider_csv(api_client, regular_user, multi_social_user): |
| 140 | + # provider choices 는 SocialApp 등록값 기반 — alice=google, bob=google+kakao 모두 매치되려면 |
| 141 | + # google/kakao 두 SocialApp 모두 등록되어 있어야 함. |
| 142 | + SocialApp.objects.get_or_create(provider="google", defaults={"name": "Google", "client_id": "g", "secret": "g"}) |
| 143 | + SocialApp.objects.get_or_create(provider="kakao", defaults={"name": "Kakao", "client_id": "k", "secret": "k"}) |
| 144 | + |
| 145 | + response = api_client.get(reverse("v1:admin-social-account-list"), {"provider": "google,kakao"}) |
| 146 | + assert response.status_code == http.HTTPStatus.OK |
| 147 | + rows = response.json()["results"] |
| 148 | + assert {row["uid"] for row in rows} == {"alice-google-1", "bob-google-1", "bob-kakao-1"} |
| 149 | + |
| 150 | + |
| 151 | +@pytest.mark.django_db |
| 152 | +def test_social_account_list_filter_by_provider_unknown_rejected(api_client, regular_user, social_app): |
| 153 | + # social_app fixture 가 google 만 등록 — kakao 는 SocialApp 에 없으므로 거부. |
| 154 | + response = api_client.get(reverse("v1:admin-social-account-list"), {"provider": "kakao"}) |
| 155 | + assert response.status_code == http.HTTPStatus.BAD_REQUEST |
| 156 | + |
| 157 | + |
| 158 | +@pytest.mark.django_db |
| 159 | +def test_social_account_provider_filter_enum_exposed_in_openapi(api_client): |
| 160 | + # callable choices 를 OpenAPI 스키마에 enum 으로 노출 (core.openapi.filter_extension). |
| 161 | + SocialApp.objects.get_or_create(provider="google", defaults={"name": "G", "client_id": "g", "secret": "g"}) |
| 162 | + SocialApp.objects.get_or_create(provider="kakao", defaults={"name": "K", "client_id": "k", "secret": "k"}) |
| 163 | + |
| 164 | + response = APIClient().get("/api/schema/v1/") |
| 165 | + assert response.status_code == http.HTTPStatus.OK |
| 166 | + schema = yaml.safe_load(response.content) |
| 167 | + |
| 168 | + list_path = next(p for p in schema["paths"] if p.endswith("/allauth/social-account/")) |
| 169 | + params = schema["paths"][list_path]["get"]["parameters"] |
| 170 | + provider = next(p for p in params if p["name"] == "provider") |
| 171 | + assert provider["schema"]["items"]["enum"] == ["google", "kakao"] |
| 172 | + |
| 173 | + |
| 174 | +@pytest.mark.django_db |
| 175 | +def test_social_account_list_filter_by_uid_icontains(api_client, regular_user, multi_social_user): |
| 176 | + response = api_client.get(reverse("v1:admin-social-account-list"), {"uid": "kakao"}) |
| 177 | + assert response.status_code == http.HTTPStatus.OK |
| 178 | + rows = response.json()["results"] |
| 179 | + assert {row["uid"] for row in rows} == {"bob-kakao-1"} |
| 180 | + |
| 181 | + |
| 182 | +@pytest.mark.django_db |
| 183 | +def test_social_account_list_filter_by_user_email_and_username(api_client, regular_user, multi_social_user): |
| 184 | + response = api_client.get(reverse("v1:admin-social-account-list"), {"user_email": "alice@"}) |
| 185 | + assert response.status_code == http.HTTPStatus.OK |
| 186 | + rows = response.json()["results"] |
| 187 | + assert {row["uid"] for row in rows} == {"alice-google-1"} |
| 188 | + |
| 189 | + response = api_client.get(reverse("v1:admin-social-account-list"), {"user_username": "bob"}) |
| 190 | + assert response.status_code == http.HTTPStatus.OK |
| 191 | + rows = response.json()["results"] |
| 192 | + assert {row["uid"] for row in rows} == {"bob-google-1", "bob-kakao-1"} |
| 193 | + |
| 194 | + |
| 195 | +@pytest.mark.django_db |
| 196 | +def test_social_account_list_filter_by_date_joined_range(api_client, regular_user, multi_social_user): |
| 197 | + import datetime as _dt |
| 198 | + |
| 199 | + # 미래 시점 _after 는 결과 0 건. |
| 200 | + future = (_dt.datetime.now(_dt.timezone.utc) + _dt.timedelta(days=1)).isoformat() |
| 201 | + response = api_client.get(reverse("v1:admin-social-account-list"), {"date_joined_after": future}) |
| 202 | + assert response.status_code == http.HTTPStatus.OK |
| 203 | + assert response.json()["results"] == [] |
| 204 | + |
| 205 | + |
137 | 206 | @pytest.mark.django_db |
138 | 207 | def test_social_account_no_create_endpoint(api_client, regular_user): |
139 | 208 | response = api_client.post( |
@@ -175,6 +244,55 @@ def test_email_address_list_filter_by_user(api_client, regular_user): |
175 | 244 | assert {row["email"] for row in rows} == {"alice@example.com"} |
176 | 245 |
|
177 | 246 |
|
| 247 | +@pytest.mark.django_db |
| 248 | +def test_email_address_list_filter_by_email_matches_emailaddress(api_client, regular_user, multi_social_user): |
| 249 | + # EmailAddress.email substring 매칭. |
| 250 | + response = api_client.get(reverse("v1:admin-email-address-list"), {"email": "alice@"}) |
| 251 | + assert response.status_code == http.HTTPStatus.OK |
| 252 | + rows = response.json()["results"] |
| 253 | + assert {row["email"] for row in rows} == {"alice@example.com"} |
| 254 | + |
| 255 | + |
| 256 | +@pytest.mark.django_db |
| 257 | +def test_email_address_list_filter_by_email_matches_user_email(api_client, regular_user): |
| 258 | + # EA.email 은 alt 이지만 user.email 은 alice 라서 ?email=alice 로도 잡혀야 한다. |
| 259 | + EmailAddress.objects.create(user=regular_user, email="alt@example.com", verified=False, primary=False) |
| 260 | + response = api_client.get(reverse("v1:admin-email-address-list"), {"email": "alice@"}) |
| 261 | + assert response.status_code == http.HTTPStatus.OK |
| 262 | + rows = response.json()["results"] |
| 263 | + # alice 의 primary EA + alt EA (User.email join 으로 매칭) 모두 포함. |
| 264 | + assert {row["email"] for row in rows} == {"alice@example.com", "alt@example.com"} |
| 265 | + |
| 266 | + |
| 267 | +@pytest.mark.django_db |
| 268 | +def test_email_address_list_filter_by_email_csv(api_client, regular_user, multi_social_user): |
| 269 | + response = api_client.get(reverse("v1:admin-email-address-list"), {"email": "alice@,bob@"}) |
| 270 | + assert response.status_code == http.HTTPStatus.OK |
| 271 | + rows = response.json()["results"] |
| 272 | + assert {row["email"] for row in rows} == {"alice@example.com", "bob@example.com"} |
| 273 | + |
| 274 | + |
| 275 | +@pytest.mark.django_db |
| 276 | +def test_email_address_list_filter_by_verified_and_primary(api_client, regular_user): |
| 277 | + EmailAddress.objects.create(user=regular_user, email="alt@example.com", verified=False, primary=False) |
| 278 | + # verified=false |
| 279 | + response = api_client.get(reverse("v1:admin-email-address-list"), {"verified": "false"}) |
| 280 | + assert response.status_code == http.HTTPStatus.OK |
| 281 | + assert {row["email"] for row in response.json()["results"]} == {"alt@example.com"} |
| 282 | + # primary=true |
| 283 | + response = api_client.get(reverse("v1:admin-email-address-list"), {"primary": "true"}) |
| 284 | + assert response.status_code == http.HTTPStatus.OK |
| 285 | + assert {row["email"] for row in response.json()["results"]} == {"alice@example.com"} |
| 286 | + |
| 287 | + |
| 288 | +@pytest.mark.django_db |
| 289 | +def test_email_address_list_filter_by_user_username(api_client, regular_user, multi_social_user): |
| 290 | + response = api_client.get(reverse("v1:admin-email-address-list"), {"user_username": "bob"}) |
| 291 | + assert response.status_code == http.HTTPStatus.OK |
| 292 | + rows = response.json()["results"] |
| 293 | + assert {row["email"] for row in rows} == {"bob@example.com"} |
| 294 | + |
| 295 | + |
178 | 296 | @pytest.mark.django_db |
179 | 297 | def test_email_address_create_lowercases_email(api_client, regular_user): |
180 | 298 | response = api_client.post( |
|
0 commit comments