from pywebpush import WebPushException from app.models.push_subscription import PushSubscription from app.schemas.push import PushKeys, PushSubscribeRequest from app.services import push_service class _FakeResponse: def __init__(self, status_code): self.status_code = status_code def _subscribe_request(endpoint="https://push.example.com/1"): return PushSubscribeRequest(endpoint=endpoint, keys=PushKeys(p256dh="p256dh-key", auth="auth-key")) # ---- save_subscription ---- def test_save_subscription_creates_new_row(db_session, test_user): sub = push_service.save_subscription(db_session, test_user.id, _subscribe_request()) assert sub.user_id == test_user.id assert sub.endpoint == "https://push.example.com/1" def test_save_subscription_reassigns_existing_endpoint_to_new_user(db_session, test_user, other_user): request = _subscribe_request() push_service.save_subscription(db_session, other_user.id, request) # 같은 기기(endpoint)에서 다른 유저(test_user)로 재구독하면 소유자가 갱신되어야 한다. updated = push_service.save_subscription(db_session, test_user.id, request) assert updated.user_id == test_user.id assert db_session.query(PushSubscription).filter_by(endpoint=request.endpoint).count() == 1 def test_delete_subscription_removes_row(db_session, test_user): sub = push_service.save_subscription(db_session, test_user.id, _subscribe_request()) push_service.delete_subscription(db_session, sub.endpoint) assert db_session.query(PushSubscription).filter_by(endpoint=sub.endpoint).count() == 0 # ---- send_to_user ---- def test_send_to_user_counts_successful_sends(db_session, test_user, monkeypatch): push_service.save_subscription(db_session, test_user.id, _subscribe_request("https://push.example.com/a")) push_service.save_subscription(db_session, test_user.id, _subscribe_request("https://push.example.com/b")) monkeypatch.setattr(push_service, "webpush", lambda **kwargs: None) sent = push_service.send_to_user(db_session, test_user.id, title="제목", body="본문") assert sent == 2 def test_send_to_user_deletes_expired_subscription_on_410(db_session, test_user, monkeypatch): sub = push_service.save_subscription(db_session, test_user.id, _subscribe_request()) def _raise_gone(**kwargs): raise WebPushException("gone", response=_FakeResponse(410)) monkeypatch.setattr(push_service, "webpush", _raise_gone) sent = push_service.send_to_user(db_session, test_user.id, title="제목", body="본문") assert sent == 0 assert db_session.query(PushSubscription).filter_by(id=sub.id).count() == 0 def test_send_to_user_keeps_subscription_on_other_errors(db_session, test_user, monkeypatch): sub = push_service.save_subscription(db_session, test_user.id, _subscribe_request()) def _raise_server_error(**kwargs): raise WebPushException("server error", response=_FakeResponse(500)) monkeypatch.setattr(push_service, "webpush", _raise_server_error) sent = push_service.send_to_user(db_session, test_user.id, title="제목", body="본문") assert sent == 0 assert db_session.query(PushSubscription).filter_by(id=sub.id).count() == 1