|
# retoor <retoor@molodetz.nl>
|
|
|
|
from datetime import datetime, timedelta, timezone
|
|
|
|
from devplacepy.database import get_table
|
|
from devplacepy.push import store
|
|
from devplacepy.services.push import PushService
|
|
from devplacepy.utils import generate_uid
|
|
|
|
|
|
def _registration(user_uid, deleted_at=None, provider="webpush"):
|
|
record = {
|
|
"uid": generate_uid(),
|
|
"user_uid": user_uid,
|
|
"provider": provider,
|
|
"endpoint": f"https://push.example.com/{generate_uid()}",
|
|
"key_auth": "a",
|
|
"key_p256dh": "p",
|
|
"created_at": datetime.now(timezone.utc).isoformat(),
|
|
"deleted_at": deleted_at,
|
|
}
|
|
get_table("push_registration").insert(record)
|
|
return record
|
|
|
|
|
|
def test_config_fields_cover_every_provider(local_db):
|
|
keys = [field.key for field in PushService().all_fields()]
|
|
for expected in (
|
|
"service_push_enabled",
|
|
"push_dead_retention_days",
|
|
"push_delivery_timeout_seconds",
|
|
"push_webpush_enabled",
|
|
"push_webpush_subject",
|
|
"push_apns_enabled",
|
|
"push_apns_team_id",
|
|
"push_apns_key_id",
|
|
"push_apns_auth_key",
|
|
"push_apns_topic",
|
|
"push_apns_environment",
|
|
):
|
|
assert expected in keys
|
|
|
|
|
|
def test_apns_auth_key_field_is_a_masked_secret(local_db):
|
|
fields = {field.key: field for field in PushService().all_fields()}
|
|
auth_key = fields["push_apns_auth_key"]
|
|
assert auth_key.secret is True
|
|
assert auth_key.type == "text"
|
|
assert auth_key.display_value() == ""
|
|
|
|
|
|
def test_run_once_prunes_only_stale_dead_rows(local_db, monkeypatch):
|
|
from devplacepy.services import push as push_service
|
|
|
|
user_uid = f"prune_{generate_uid()}"
|
|
live = _registration(user_uid)
|
|
fresh_dead = _registration(
|
|
user_uid,
|
|
deleted_at=(datetime.now(timezone.utc) - timedelta(days=1)).isoformat(),
|
|
)
|
|
stale_dead = _registration(
|
|
user_uid,
|
|
deleted_at=(datetime.now(timezone.utc) - timedelta(days=90)).isoformat(),
|
|
)
|
|
|
|
service = PushService()
|
|
monkeypatch.setattr(
|
|
push_service.service, "get_int_setting", lambda key, default: 30
|
|
)
|
|
from tests.conftest import run_async
|
|
|
|
run_async(service.run_once())
|
|
|
|
registrations = get_table("push_registration")
|
|
assert registrations.find_one(uid=live["uid"]) is not None
|
|
assert registrations.find_one(uid=fresh_dead["uid"]) is not None
|
|
assert registrations.find_one(uid=stale_dead["uid"]) is None
|
|
|
|
|
|
def test_run_once_with_retention_disabled_prunes_nothing(local_db, monkeypatch):
|
|
from devplacepy.services import push as push_service
|
|
from tests.conftest import run_async
|
|
|
|
user_uid = f"keep_{generate_uid()}"
|
|
stale_dead = _registration(
|
|
user_uid,
|
|
deleted_at=(datetime.now(timezone.utc) - timedelta(days=900)).isoformat(),
|
|
)
|
|
|
|
service = PushService()
|
|
monkeypatch.setattr(push_service.service, "get_int_setting", lambda key, default: 0)
|
|
run_async(service.run_once())
|
|
|
|
assert get_table("push_registration").find_one(uid=stale_dead["uid"]) is not None
|
|
|
|
|
|
def test_metrics_count_live_rows_per_provider(local_db):
|
|
user_uid = f"metrics_{generate_uid()}"
|
|
_registration(user_uid)
|
|
_registration(user_uid, provider="apns")
|
|
|
|
metrics = PushService().collect_metrics()
|
|
assert metrics["webpush_active"] >= 1
|
|
assert metrics["apns_active"] >= 1
|
|
assert metrics["webpush_ready"] == 1
|
|
assert "dead" in metrics
|
|
|
|
|
|
def test_store_counts_treats_a_missing_provider_as_webpush(local_db):
|
|
user_uid = f"legacy_{generate_uid()}"
|
|
record = _registration(user_uid)
|
|
get_table("push_registration").update(
|
|
{"id": get_table("push_registration").find_one(uid=record["uid"])["id"], "provider": None},
|
|
["id"],
|
|
)
|
|
|
|
assert store.counts().get("webpush", 0) >= 1
|