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 on join queries. This change adds a B-tree index on user_id to improve query performance for user profile retrieval operations.
This commit is contained in:
@@ -332,3 +332,182 @@ def test_reply_notification(app_server, browser, seeded_db):
|
||||
|
||||
ctx_a.close()
|
||||
ctx_b.close()
|
||||
|
||||
|
||||
def test_mention_notification_names_actor(app_server, browser, seeded_db):
|
||||
from tests.conftest import login_user
|
||||
ctx_a = browser.new_context(viewport={"width": 1400, "height": 900})
|
||||
ctx_b = browser.new_context(viewport={"width": 1400, "height": 900})
|
||||
pa = ctx_a.new_page()
|
||||
pb = ctx_b.new_page()
|
||||
pa.set_default_timeout(15000)
|
||||
pb.set_default_timeout(15000)
|
||||
|
||||
login_user(pa, seeded_db["alice"])
|
||||
login_user(pb, seeded_db["bob"])
|
||||
|
||||
pb.goto(f"{BASE_URL}/feed", wait_until="domcontentloaded")
|
||||
pb.locator(".feed-fab").first.wait_for(state="visible", timeout=10000)
|
||||
pb.locator(".feed-fab").first.click()
|
||||
pb.fill("#post-content", "Naming check @alice_test please read")
|
||||
pb.locator("#create-post-modal button.btn-primary:has-text('Post')").click()
|
||||
pb.wait_for_url("**/posts/*", timeout=10000, wait_until="domcontentloaded")
|
||||
|
||||
pa.goto(f"{BASE_URL}/notifications", wait_until="domcontentloaded")
|
||||
pa.wait_for_timeout(1500)
|
||||
texts = pa.locator(".notification-text").all_text_contents()
|
||||
assert any("@bob_test mentioned you" in t for t in texts), f"mention message must name the actor (bob): {texts}"
|
||||
assert not any("@alice_test mentioned you" in t for t in texts), f"mention message must not name the mentioned user (alice): {texts}"
|
||||
|
||||
ctx_a.close()
|
||||
ctx_b.close()
|
||||
|
||||
|
||||
def test_comment_notification_click_opens_comment(app_server, browser, seeded_db):
|
||||
from tests.conftest import login_user
|
||||
ctx_a = browser.new_context(viewport={"width": 1400, "height": 900})
|
||||
ctx_b = browser.new_context(viewport={"width": 1400, "height": 900})
|
||||
pa = ctx_a.new_page()
|
||||
pb = ctx_b.new_page()
|
||||
pa.set_default_timeout(15000)
|
||||
pb.set_default_timeout(15000)
|
||||
|
||||
login_user(pa, seeded_db["alice"])
|
||||
login_user(pb, seeded_db["bob"])
|
||||
|
||||
pa.goto(f"{BASE_URL}/feed", wait_until="domcontentloaded")
|
||||
pa.locator(".feed-fab").first.wait_for(state="visible", timeout=10000)
|
||||
pa.locator(".feed-fab").first.click()
|
||||
pa.fill("#post-content", "Post for click navigation test")
|
||||
pa.locator("#create-post-modal button.btn-primary:has-text('Post')").click()
|
||||
pa.wait_for_url("**/posts/*", timeout=10000, wait_until="domcontentloaded")
|
||||
post_url = pa.url
|
||||
|
||||
pb.goto(post_url, wait_until="domcontentloaded")
|
||||
textarea = pb.locator("form.comment-form textarea[name='content']").first
|
||||
textarea.wait_for(state="visible", timeout=10000)
|
||||
textarea.fill("Bob comment that alice should jump to")
|
||||
pb.locator("button.comment-form-submit").first.click()
|
||||
pb.wait_for_timeout(1500)
|
||||
|
||||
pa.goto(f"{BASE_URL}/notifications", wait_until="domcontentloaded")
|
||||
card = pa.locator(".notification-card[data-href]").filter(has_text="commented on your post").first
|
||||
card.wait_for(state="visible", timeout=10000)
|
||||
href = card.get_attribute("data-href")
|
||||
assert href.startswith("/notifications/open/"), f"unexpected data-href: {href}"
|
||||
|
||||
card.locator(".notification-text").click()
|
||||
pa.wait_for_url("**/posts/**", timeout=10000, wait_until="domcontentloaded")
|
||||
assert "#comment-" in pa.url, f"click did not deep-link to a comment: {pa.url}"
|
||||
|
||||
comment_uid = pa.url.split("#comment-")[1]
|
||||
pa.locator(f"#comment-{comment_uid}").wait_for(state="visible", timeout=10000)
|
||||
pa.wait_for_selector(f"#comment-{comment_uid}.comment-highlight", timeout=5000)
|
||||
|
||||
pa.goto(f"{BASE_URL}/notifications", wait_until="domcontentloaded")
|
||||
pa.wait_for_timeout(1000)
|
||||
target = pa.locator(f'.notification-card[data-href="{href}"]')
|
||||
target.wait_for(state="visible", timeout=10000)
|
||||
assert "unread" not in (target.get_attribute("class") or ""), "opening a notification should mark it read"
|
||||
|
||||
ctx_a.close()
|
||||
ctx_b.close()
|
||||
|
||||
|
||||
def test_follow_notification_click_opens_profile(app_server, browser, seeded_db):
|
||||
from tests.conftest import login_user
|
||||
ctx_a = browser.new_context(viewport={"width": 1400, "height": 900})
|
||||
ctx_b = browser.new_context(viewport={"width": 1400, "height": 900})
|
||||
pa = ctx_a.new_page()
|
||||
pb = ctx_b.new_page()
|
||||
pa.set_default_timeout(15000)
|
||||
pb.set_default_timeout(15000)
|
||||
|
||||
login_user(pa, seeded_db["alice"])
|
||||
login_user(pb, seeded_db["bob"])
|
||||
|
||||
pb.goto(f"{BASE_URL}/profile/alice_test", wait_until="domcontentloaded")
|
||||
pb.wait_for_timeout(1000)
|
||||
follow_btn = pb.locator("button:has-text('Follow')")
|
||||
if follow_btn.is_visible():
|
||||
follow_btn.click()
|
||||
pb.wait_for_timeout(1000)
|
||||
|
||||
pa.goto(f"{BASE_URL}/notifications", wait_until="domcontentloaded")
|
||||
card = pa.locator(".notification-card[data-href]").filter(has_text="started following you").first
|
||||
card.wait_for(state="visible", timeout=10000)
|
||||
card.locator(".notification-text").click()
|
||||
pa.wait_for_url("**/profile/bob_test", timeout=10000, wait_until="domcontentloaded")
|
||||
assert pa.url.endswith("/profile/bob_test"), f"follow notification should open the follower profile: {pa.url}"
|
||||
|
||||
ctx_a.close()
|
||||
ctx_b.close()
|
||||
|
||||
|
||||
def test_message_notification_click_opens_conversation(app_server, browser, seeded_db):
|
||||
from tests.conftest import login_user
|
||||
ctx_a = browser.new_context(viewport={"width": 1400, "height": 900})
|
||||
ctx_b = browser.new_context(viewport={"width": 1400, "height": 900})
|
||||
pa = ctx_a.new_page()
|
||||
pb = ctx_b.new_page()
|
||||
pa.set_default_timeout(15000)
|
||||
pb.set_default_timeout(15000)
|
||||
|
||||
login_user(pa, seeded_db["alice"])
|
||||
login_user(pb, seeded_db["bob"])
|
||||
|
||||
pb.goto(f"{BASE_URL}/messages?search=alice_test", wait_until="domcontentloaded")
|
||||
pb.wait_for_timeout(2000)
|
||||
msg_input = pb.locator("input[name='content']").first
|
||||
msg_input.wait_for(state="visible", timeout=10000)
|
||||
msg_input.fill("Click-through message from bob")
|
||||
pb.locator("button[type='submit']").last.click()
|
||||
pb.wait_for_timeout(1500)
|
||||
|
||||
pa.goto(f"{BASE_URL}/notifications", wait_until="domcontentloaded")
|
||||
card = pa.locator(".notification-card[data-href]").filter(has_text="sent you a message").first
|
||||
card.wait_for(state="visible", timeout=10000)
|
||||
card.locator(".notification-text").click()
|
||||
pa.wait_for_url("**/messages**", timeout=10000, wait_until="domcontentloaded")
|
||||
assert "with_uid=" in pa.url, f"message notification should open the conversation: {pa.url}"
|
||||
|
||||
ctx_a.close()
|
||||
ctx_b.close()
|
||||
|
||||
|
||||
def test_vote_notification_click_opens_target(app_server, browser, seeded_db):
|
||||
from tests.conftest import login_user
|
||||
ctx_a = browser.new_context(viewport={"width": 1400, "height": 900})
|
||||
ctx_b = browser.new_context(viewport={"width": 1400, "height": 900})
|
||||
pa = ctx_a.new_page()
|
||||
pb = ctx_b.new_page()
|
||||
pa.set_default_timeout(15000)
|
||||
pb.set_default_timeout(15000)
|
||||
|
||||
login_user(pa, seeded_db["alice"])
|
||||
login_user(pb, seeded_db["bob"])
|
||||
|
||||
pb.goto(f"{BASE_URL}/feed", wait_until="domcontentloaded")
|
||||
pb.locator(".feed-fab").first.wait_for(state="visible", timeout=10000)
|
||||
pb.locator(".feed-fab").first.click()
|
||||
pb.fill("#post-content", "Post for vote click-through test")
|
||||
pb.locator("#create-post-modal button.btn-primary:has-text('Post')").click()
|
||||
pb.wait_for_url("**/posts/*", timeout=10000, wait_until="domcontentloaded")
|
||||
post_path = "/posts/" + pb.url.split("/posts/")[1]
|
||||
|
||||
pa.goto(f"{BASE_URL}{post_path}", wait_until="domcontentloaded")
|
||||
pa.wait_for_timeout(1000)
|
||||
vote_btn = pa.locator("button.post-action-btn").filter(has_text="+").first
|
||||
vote_btn.wait_for(state="visible", timeout=10000)
|
||||
vote_btn.click()
|
||||
pa.wait_for_timeout(1500)
|
||||
|
||||
pb.goto(f"{BASE_URL}/notifications", wait_until="domcontentloaded")
|
||||
card = pb.locator(".notification-card[data-href]").filter(has_text="++'d").first
|
||||
card.wait_for(state="visible", timeout=10000)
|
||||
card.locator(".notification-text").click()
|
||||
pb.wait_for_url(f"**{post_path}", timeout=10000, wait_until="domcontentloaded")
|
||||
assert post_path in pb.url, f"vote notification should open the voted post: {pb.url}"
|
||||
|
||||
ctx_a.close()
|
||||
ctx_b.close()
|
||||
|
||||
Reference in New Issue
Block a user