from types import SimpleNamespace from unittest.mock import MagicMock, patch from app.services.wechat_login_service import resolve_wechat_login_user def test_openid_bound_phone_mismatch_rejects(): bound = SimpleNamespace(id="u1", phone_no="13800138000", wx_openid="oid-a") db = MagicMock() with patch( "app.services.wechat_login_service.user_crud.get_by_wx_openid", return_value=bound, ): user, err, code = resolve_wechat_login_user( db, openid="oid-a", phone="13900139000" ) assert user is None assert code == 401 assert "不一致" in err or "不匹配" in err def test_openid_bound_phone_match_ok(): bound = SimpleNamespace(id="u1", phone_no="13800138000", wx_openid="oid-a") db = MagicMock() with patch( "app.services.wechat_login_service.user_crud.get_by_wx_openid", return_value=bound, ): user, err, code = resolve_wechat_login_user( db, openid="oid-a", phone="+8613800138000" ) assert user is bound assert err is None assert code is None def test_unbound_no_user_rejects(): db = MagicMock() with patch( "app.services.wechat_login_service.user_crud.get_by_wx_openid", return_value=None, ), patch( "app.services.wechat_login_service.user_crud.list_active_by_phone_no", return_value=[], ): user, err, code = resolve_wechat_login_user( db, openid="oid-new", phone="13800138000" ) assert user is None assert code == 401 def test_unbound_multi_user_rejects(): db = MagicMock() u1 = SimpleNamespace(id="a", phone_no="13800138000", wx_openid=None) u2 = SimpleNamespace(id="b", phone_no="13800138000", wx_openid=None) with patch( "app.services.wechat_login_service.user_crud.get_by_wx_openid", return_value=None, ), patch( "app.services.wechat_login_service.user_crud.list_active_by_phone_no", return_value=[u1, u2], ): user, err, code = resolve_wechat_login_user( db, openid="oid-new", phone="13800138000" ) assert user is None assert code == 400 assert "多个" in err def test_unbound_unique_binds_openid(): db = MagicMock() u = SimpleNamespace(id="a", phone_no="13800138000", wx_openid=None, update_time=None) with patch( "app.services.wechat_login_service.user_crud.get_by_wx_openid", side_effect=[None, None], ), patch( "app.services.wechat_login_service.user_crud.list_active_by_phone_no", return_value=[u], ): user, err, code = resolve_wechat_login_user( db, openid="oid-new", phone="13800138000" ) assert err is None assert user is u assert u.wx_openid == "oid-new" db.commit.assert_called()