Coverage for app/backend/src/tests/test_user_email_history.py: 100%

35 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-09-27 19:48 +0000

1from sqlalchemy import select 

2 

3from couchers.crypto import hash_password, random_hex 

4from couchers.db import session_scope 

5from couchers.models import User, UserEmailHistory 

6from couchers.proto import account_pb2, auth_pb2 

7from tests.fixtures.db import generate_user 

8from tests.fixtures.sessions import account_session, auth_api_session 

9from tests.test_auth import _quick_signup 

10 

11 

12def get_history(user_id: int) -> list[str]: 

13 with session_scope() as session: 

14 return list( 

15 session.execute( 

16 select(UserEmailHistory.email).where(UserEmailHistory.user_id == user_id).order_by(UserEmailHistory.id) 

17 ).scalars() 

18 ) 

19 

20 

21def change_email(token: str, password: str, new_email: str) -> None: 

22 with account_session(token) as account: 

23 account.ChangeEmailV2(account_pb2.ChangeEmailV2Req(password=password, new_email=new_email)) 

24 

25 with session_scope() as session: 

26 change_email_token = session.execute( 

27 select(User.new_email_token).where(User.new_email == new_email) 

28 ).scalar_one() 

29 

30 with auth_api_session() as (auth_api, metadata_interceptor): 

31 auth_api.ConfirmChangeEmailV2(auth_pb2.ConfirmChangeEmailV2Req(change_email_token=change_email_token)) 

32 

33 

34def test_email_history_recorded_on_signup(db, fast_passwords): 

35 user_id = _quick_signup() 

36 

37 assert get_history(user_id) == ["email@couchers.org.invalid"] 

38 

39 

40def test_email_history_recorded_on_confirmed_email_change(db, fast_passwords): 

41 password = random_hex() 

42 user, token = generate_user(hashed_password=hash_password(password)) 

43 first_email = f"{random_hex()}@couchers.org.invalid" 

44 second_email = f"{random_hex()}@couchers.org.invalid" 

45 

46 change_email(token, password, first_email) 

47 change_email(token, password, second_email) 

48 

49 assert get_history(user.id) == [first_email, second_email] 

50 

51 

52def test_email_history_not_recorded_on_unconfirmed_email_change(db, fast_passwords): 

53 password = random_hex() 

54 user, token = generate_user(hashed_password=hash_password(password)) 

55 

56 with account_session(token) as account: 

57 account.ChangeEmailV2( 

58 account_pb2.ChangeEmailV2Req(password=password, new_email=f"{random_hex()}@couchers.org.invalid") 

59 ) 

60 

61 assert get_history(user.id) == []