95 lines
2.9 KiB
Python
95 lines
2.9 KiB
Python
from datetime import timedelta
|
|
|
|
import pytest
|
|
from django.utils import timezone
|
|
from rest_framework import serializers
|
|
|
|
from accounts.models import InviteCode, InviteCodeUsage, User
|
|
from accounts.serializers import RegisterSerializer, UserSerializer
|
|
|
|
|
|
def registration_data(code="VALID-CODE", username="math_user"):
|
|
return {
|
|
"invite_code": code,
|
|
"username": username,
|
|
"password": "StrongPass_2026",
|
|
"nickname": "数学少年",
|
|
"track": User.Track.STANDARD,
|
|
}
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_register_serializer_有效邀请码创建用户并原子消费():
|
|
invite = InviteCode.objects.create(code="VALID-CODE", max_uses=1)
|
|
serializer = RegisterSerializer(
|
|
data=registration_data(),
|
|
context={"ip_address": "127.0.0.1"},
|
|
)
|
|
|
|
assert serializer.is_valid(), serializer.errors
|
|
user = serializer.save()
|
|
|
|
invite.refresh_from_db()
|
|
assert invite.used_count == 1
|
|
assert user.check_password("StrongPass_2026")
|
|
usage = InviteCodeUsage.objects.get(user=user)
|
|
assert usage.invite_code == invite
|
|
assert usage.ip_address == "127.0.0.1"
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_register_serializer_过期邀请码拒绝创建用户():
|
|
InviteCode.objects.create(
|
|
code="EXPIRED",
|
|
max_uses=1,
|
|
expires_at=timezone.now() - timedelta(seconds=1),
|
|
)
|
|
serializer = RegisterSerializer(data=registration_data(code="EXPIRED"))
|
|
|
|
assert serializer.is_valid(), serializer.errors
|
|
with pytest.raises(serializers.ValidationError, match="已过期或已用完"):
|
|
serializer.save()
|
|
assert User.objects.count() == 0
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_register_serializer_用户名大小写重复时校验失败():
|
|
User.objects.create_user(
|
|
username="Math_User",
|
|
password="StrongPass_2026",
|
|
nickname="已有用户",
|
|
)
|
|
serializer = RegisterSerializer(data=registration_data(username="math_user"))
|
|
|
|
assert not serializer.is_valid()
|
|
assert "用户名已存在" in str(serializer.errors["username"])
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_register_serializer_游客迁移字段类型错误时拒绝():
|
|
InviteCode.objects.create(code="VALID-CODE", max_uses=1)
|
|
data = registration_data()
|
|
data["visitor_data"] = {"favorites": None}
|
|
serializer = RegisterSerializer(data=data)
|
|
|
|
assert not serializer.is_valid()
|
|
assert "favorites 必须是数组" in str(serializer.errors["visitor_data"])
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_user_serializer_返回员工身份且客户端不能提权():
|
|
user = User.objects.create_user(
|
|
username="operator",
|
|
password="StrongPass_2026",
|
|
nickname="运营人员",
|
|
is_staff=False,
|
|
)
|
|
|
|
serializer = UserSerializer(user, data={"is_staff": True}, partial=True)
|
|
|
|
assert serializer.is_valid(), serializer.errors
|
|
serializer.save()
|
|
user.refresh_from_db()
|
|
assert user.is_staff is False
|
|
assert UserSerializer(user).data["is_staff"] is False
|