96 lines
3.2 KiB
Python
96 lines
3.2 KiB
Python
|
|
"""Integration tests for the Evotor invite flow (/invite)."""
|
|||
|
|
import secrets
|
|||
|
|
from datetime import datetime, timezone, timedelta
|
|||
|
|
from unittest.mock import patch
|
|||
|
|
|
|||
|
|
import pytest
|
|||
|
|
|
|||
|
|
from web.models.user import User, UserStatusEnum
|
|||
|
|
|
|||
|
|
|
|||
|
|
@pytest.mark.asyncio
|
|||
|
|
async def test_invite_get_valid_token(client, override_db, user_factory):
|
|||
|
|
token = secrets.token_urlsafe(32)
|
|||
|
|
user = user_factory.create(
|
|||
|
|
invite_token=token,
|
|||
|
|
invite_expires=datetime.now(timezone.utc).replace(tzinfo=None) + timedelta(hours=48),
|
|||
|
|
password_hash=None,
|
|||
|
|
status=UserStatusEnum.pending,
|
|||
|
|
is_email_confirmed=False,
|
|||
|
|
)
|
|||
|
|
resp = await client.get(f"/invite?token={token}")
|
|||
|
|
assert resp.status_code == 200
|
|||
|
|
assert "Завершение регистрации" in resp.text or "ЭВОСИНК" in resp.text
|
|||
|
|
|
|||
|
|
|
|||
|
|
@pytest.mark.asyncio
|
|||
|
|
async def test_invite_get_expired_token(client, user_factory):
|
|||
|
|
token = secrets.token_urlsafe(32)
|
|||
|
|
user_factory.create(
|
|||
|
|
invite_token=token,
|
|||
|
|
invite_expires=datetime.now(timezone.utc).replace(tzinfo=None) - timedelta(hours=1),
|
|||
|
|
password_hash=None,
|
|||
|
|
status=UserStatusEnum.pending,
|
|||
|
|
)
|
|||
|
|
resp = await client.get(f"/invite?token={token}")
|
|||
|
|
assert resp.status_code == 200
|
|||
|
|
assert "недействительна" in resp.text
|
|||
|
|
|
|||
|
|
|
|||
|
|
@pytest.mark.asyncio
|
|||
|
|
async def test_invite_get_bogus_token(client):
|
|||
|
|
resp = await client.get("/invite?token=notexist")
|
|||
|
|
assert resp.status_code == 200
|
|||
|
|
assert "недействительна" in resp.text
|
|||
|
|
|
|||
|
|
|
|||
|
|
@pytest.mark.asyncio
|
|||
|
|
async def test_invite_post_activates_user(client, override_db, user_factory):
|
|||
|
|
token = secrets.token_urlsafe(32)
|
|||
|
|
user = user_factory.create(
|
|||
|
|
email="invite@test.com",
|
|||
|
|
phone="+79001119999",
|
|||
|
|
invite_token=token,
|
|||
|
|
invite_expires=datetime.now(timezone.utc).replace(tzinfo=None) + timedelta(hours=48),
|
|||
|
|
password_hash=None,
|
|||
|
|
status=UserStatusEnum.pending,
|
|||
|
|
is_email_confirmed=False,
|
|||
|
|
)
|
|||
|
|
resp = await client.post(f"/invite?token={token}", data={
|
|||
|
|
"first_name": "Петр",
|
|||
|
|
"last_name": "Петров",
|
|||
|
|
"email": "invite@test.com",
|
|||
|
|
"phone": "+79001119999",
|
|||
|
|
"password": "newpassword1",
|
|||
|
|
"password_confirm": "newpassword1",
|
|||
|
|
})
|
|||
|
|
assert resp.status_code == 200
|
|||
|
|
assert "активирован" in resp.text.lower()
|
|||
|
|
|
|||
|
|
override_db.refresh(user)
|
|||
|
|
assert user.status == UserStatusEnum.active
|
|||
|
|
assert user.is_email_confirmed is True
|
|||
|
|
assert user.password_hash is not None
|
|||
|
|
assert user.invite_token is None
|
|||
|
|
|
|||
|
|
|
|||
|
|
@pytest.mark.asyncio
|
|||
|
|
async def test_invite_post_password_mismatch(client, user_factory):
|
|||
|
|
token = secrets.token_urlsafe(32)
|
|||
|
|
user_factory.create(
|
|||
|
|
invite_token=token,
|
|||
|
|
invite_expires=datetime.now(timezone.utc).replace(tzinfo=None) + timedelta(hours=48),
|
|||
|
|
password_hash=None,
|
|||
|
|
status=UserStatusEnum.pending,
|
|||
|
|
)
|
|||
|
|
resp = await client.post(f"/invite?token={token}", data={
|
|||
|
|
"first_name": "А",
|
|||
|
|
"last_name": "Б",
|
|||
|
|
"email": "x@test.com",
|
|||
|
|
"phone": "+79001112233",
|
|||
|
|
"password": "password123",
|
|||
|
|
"password_confirm": "different",
|
|||
|
|
})
|
|||
|
|
assert resp.status_code == 200
|
|||
|
|
assert "не совпадают" in resp.text
|