feat: add user_id index to profiles table for faster lookups
The profiles table previously lacked an index on the user_id column, causing full table scans during user lookups. This change adds a B-tree index on user_id to improve query performance for profile retrieval operations.
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
import requests
|
||||
from playwright.sync_api import expect
|
||||
|
||||
from tests.conftest import BASE_URL
|
||||
from devplacepy.database import (
|
||||
get_notification_default,
|
||||
get_notification_prefs,
|
||||
get_table,
|
||||
notification_enabled,
|
||||
reset_notification_prefs,
|
||||
set_notification_default,
|
||||
set_notification_pref,
|
||||
)
|
||||
from devplacepy.utils import create_notification, generate_uid
|
||||
|
||||
|
||||
def _user(username):
|
||||
return get_table("users").find_one(username=username)
|
||||
|
||||
|
||||
def _pref(prefs, key):
|
||||
return next(p for p in prefs if p["key"] == key)
|
||||
|
||||
|
||||
def test_defaults_all_enabled(bob):
|
||||
_, user = bob
|
||||
uid = _user(user["username"])["uid"]
|
||||
reset_notification_prefs(uid)
|
||||
prefs = get_notification_prefs(uid)
|
||||
assert prefs, "every notification type must be listed"
|
||||
for pref in prefs:
|
||||
assert pref["in_app"] is True
|
||||
assert pref["push"] is True
|
||||
assert pref["customized"] is False
|
||||
assert notification_enabled(uid, "vote", "in_app") is True
|
||||
assert notification_enabled(uid, "vote", "push") is True
|
||||
|
||||
|
||||
def test_set_pref_channels_are_independent(bob):
|
||||
_, user = bob
|
||||
uid = _user(user["username"])["uid"]
|
||||
reset_notification_prefs(uid)
|
||||
try:
|
||||
set_notification_pref(uid, "vote", "push", False)
|
||||
assert notification_enabled(uid, "vote", "push") is False
|
||||
assert notification_enabled(uid, "vote", "in_app") is True
|
||||
vote = _pref(get_notification_prefs(uid), "vote")
|
||||
assert vote["push"] is False
|
||||
assert vote["in_app"] is True
|
||||
assert vote["customized"] is True
|
||||
# an untouched type is unaffected
|
||||
assert notification_enabled(uid, "follow", "push") is True
|
||||
finally:
|
||||
reset_notification_prefs(uid)
|
||||
|
||||
|
||||
def test_reset_restores_defaults(bob):
|
||||
_, user = bob
|
||||
uid = _user(user["username"])["uid"]
|
||||
set_notification_pref(uid, "comment", "in_app", False)
|
||||
assert notification_enabled(uid, "comment", "in_app") is False
|
||||
reset_notification_prefs(uid)
|
||||
assert notification_enabled(uid, "comment", "in_app") is True
|
||||
assert _pref(get_notification_prefs(uid), "comment")["customized"] is False
|
||||
|
||||
|
||||
def test_global_default_applies_only_to_untouched_users(alice, bob):
|
||||
_, admin = alice
|
||||
_, member = bob
|
||||
admin_uid = _user(admin["username"])["uid"]
|
||||
member_uid = _user(member["username"])["uid"]
|
||||
reset_notification_prefs(admin_uid)
|
||||
set_notification_pref(member_uid, "badge", "push", True)
|
||||
try:
|
||||
set_notification_default("badge", "push", False)
|
||||
# untouched admin inherits the new default
|
||||
assert notification_enabled(admin_uid, "badge", "push") is False
|
||||
# member with an explicit choice keeps it
|
||||
assert notification_enabled(member_uid, "badge", "push") is True
|
||||
finally:
|
||||
set_notification_default("badge", "push", True)
|
||||
reset_notification_prefs(member_uid)
|
||||
assert get_notification_default("badge", "push") is True
|
||||
|
||||
|
||||
def test_create_notification_honors_in_app_pref(bob):
|
||||
_, user = bob
|
||||
uid = _user(user["username"])["uid"]
|
||||
notifications = get_table("notifications")
|
||||
reset_notification_prefs(uid)
|
||||
try:
|
||||
set_notification_pref(uid, "follow", "in_app", False)
|
||||
suppressed = f"suppressed {generate_uid()}"
|
||||
create_notification(uid, "follow", suppressed, uid, "/feed")
|
||||
assert notifications.find_one(user_uid=uid, message=suppressed) is None
|
||||
|
||||
set_notification_pref(uid, "follow", "in_app", True)
|
||||
delivered = f"delivered {generate_uid()}"
|
||||
create_notification(uid, "follow", delivered, uid, "/feed")
|
||||
assert notifications.find_one(user_uid=uid, message=delivered) is not None
|
||||
finally:
|
||||
reset_notification_prefs(uid)
|
||||
|
||||
|
||||
def test_profile_tab_renders_for_owner(bob):
|
||||
page, user = bob
|
||||
page.goto(
|
||||
f"{BASE_URL}/profile/{user['username']}?tab=notifications",
|
||||
wait_until="domcontentloaded",
|
||||
)
|
||||
expect(page.locator("[data-notif-prefs]")).to_be_visible()
|
||||
expect(
|
||||
page.locator("[data-notif-toggle][data-type='vote'][data-channel='push']")
|
||||
).to_have_count(1)
|
||||
assert page.is_visible("text=Direct messages")
|
||||
|
||||
|
||||
def test_owner_toggle_via_http_persists(bob):
|
||||
_, user = bob
|
||||
target = _user(user["username"])
|
||||
reset_notification_prefs(target["uid"])
|
||||
try:
|
||||
response = requests.post(
|
||||
f"{BASE_URL}/profile/{target['username']}/notifications",
|
||||
data={"notification_type": "mention", "channel": "push", "value": "false"},
|
||||
headers={"Accept": "application/json", "X-API-KEY": target["api_key"]},
|
||||
allow_redirects=False,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["ok"] is True
|
||||
assert notification_enabled(target["uid"], "mention", "push") is False
|
||||
assert notification_enabled(target["uid"], "mention", "in_app") is True
|
||||
finally:
|
||||
reset_notification_prefs(target["uid"])
|
||||
|
||||
|
||||
def test_non_owner_non_admin_forbidden(bob):
|
||||
_, user = bob
|
||||
member = _user(user["username"])
|
||||
target = _user("alice_test")
|
||||
response = requests.post(
|
||||
f"{BASE_URL}/profile/{target['username']}/notifications",
|
||||
data={"notification_type": "vote", "channel": "in_app", "value": "false"},
|
||||
headers={"Accept": "application/json", "X-API-KEY": member["api_key"]},
|
||||
allow_redirects=False,
|
||||
)
|
||||
assert response.status_code == 403
|
||||
|
||||
|
||||
def test_admin_edits_other_user(alice):
|
||||
_, admin_user = alice
|
||||
admin = _user(admin_user["username"])
|
||||
target = _user("bob_test")
|
||||
reset_notification_prefs(target["uid"])
|
||||
try:
|
||||
response = requests.post(
|
||||
f"{BASE_URL}/profile/{target['username']}/notifications",
|
||||
data={"notification_type": "comment", "channel": "push", "value": "false"},
|
||||
headers={"Accept": "application/json", "X-API-KEY": admin["api_key"]},
|
||||
allow_redirects=False,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert notification_enabled(target["uid"], "comment", "push") is False
|
||||
finally:
|
||||
reset_notification_prefs(target["uid"])
|
||||
|
||||
|
||||
def test_admin_default_endpoint(alice):
|
||||
_, admin_user = alice
|
||||
admin = _user(admin_user["username"])
|
||||
try:
|
||||
response = requests.post(
|
||||
f"{BASE_URL}/admin/notifications",
|
||||
data={"notification_type": "level", "channel": "push", "value": "false"},
|
||||
headers={"Accept": "application/json", "X-API-KEY": admin["api_key"]},
|
||||
allow_redirects=False,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert get_notification_default("level", "push") is False
|
||||
finally:
|
||||
set_notification_default("level", "push", True)
|
||||
|
||||
|
||||
def test_member_cannot_set_default(bob):
|
||||
_, user = bob
|
||||
member = _user(user["username"])
|
||||
response = requests.post(
|
||||
f"{BASE_URL}/admin/notifications",
|
||||
data={"notification_type": "level", "channel": "push", "value": "false"},
|
||||
headers={"Accept": "application/json", "X-API-KEY": member["api_key"]},
|
||||
allow_redirects=False,
|
||||
)
|
||||
assert response.status_code in (302, 303, 403)
|
||||
assert get_notification_default("level", "push") is True
|
||||
Reference in New Issue
Block a user