forked from retoor/devplacepy
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7332e4dd59 |
File diff suppressed because one or more lines are too long
@@ -360,37 +360,6 @@ def create_comment_record(
|
|||||||
comment_url,
|
comment_url,
|
||||||
)
|
)
|
||||||
|
|
||||||
if target_type == "post":
|
|
||||||
posts_table = get_table("posts")
|
|
||||||
post_record = posts_table.find_one(uid=target_uid)
|
|
||||||
if not post_record:
|
|
||||||
post_record = posts_table.find_one(slug=target_uid)
|
|
||||||
|
|
||||||
commenter_uids = set()
|
|
||||||
for c in get_table("comments").find(
|
|
||||||
target_type="post", target_uid=target_uid, deleted_at=None
|
|
||||||
):
|
|
||||||
commenter_uids.add(c["user_uid"])
|
|
||||||
|
|
||||||
commenter_uids.discard(user["uid"])
|
|
||||||
if post_record:
|
|
||||||
commenter_uids.discard(post_record["user_uid"])
|
|
||||||
if parent_uid:
|
|
||||||
parent_comment = get_table("comments").find_one(
|
|
||||||
uid=parent_uid, deleted_at=None
|
|
||||||
)
|
|
||||||
if parent_comment and parent_comment["user_uid"] != user["uid"]:
|
|
||||||
commenter_uids.discard(parent_comment["user_uid"])
|
|
||||||
|
|
||||||
for commenter_uid in commenter_uids:
|
|
||||||
create_notification(
|
|
||||||
commenter_uid,
|
|
||||||
"thread_comment",
|
|
||||||
f"{user['username']} also commented on a post you commented on",
|
|
||||||
user["uid"],
|
|
||||||
comment_url,
|
|
||||||
)
|
|
||||||
|
|
||||||
create_mention_notifications(content, user["uid"], comment_url)
|
create_mention_notifications(content, user["uid"], comment_url)
|
||||||
schedule_correction(user, "comments", comment_uid, request)
|
schedule_correction(user, "comments", comment_uid, request)
|
||||||
schedule_modification(user, "comments", comment_uid, request)
|
schedule_modification(user, "comments", comment_uid, request)
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ NOTIFICATION_TYPES = [
|
|||||||
{"key": "harvest_stolen", "label": "Farm raids", "description": "Someone steals a ready build from your Code Farm"},
|
{"key": "harvest_stolen", "label": "Farm raids", "description": "Someone steals a ready build from your Code Farm"},
|
||||||
{"key": "award", "label": "Awards", "description": "Someone gives you an award on your profile"},
|
{"key": "award", "label": "Awards", "description": "Someone gives you an award on your profile"},
|
||||||
{"key": "system", "label": "System alerts", "description": "Platform infrastructure alerts (e.g. the AI gateway going down)"},
|
{"key": "system", "label": "System alerts", "description": "Platform infrastructure alerts (e.g. the AI gateway going down)"},
|
||||||
{"key": "thread_comment", "label": "Thread comments", "description": "Someone else comments on a post you commented on"},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -439,8 +439,8 @@ class VoteForm(BaseModel):
|
|||||||
@field_validator("value")
|
@field_validator("value")
|
||||||
@classmethod
|
@classmethod
|
||||||
def valid_value(cls, value):
|
def valid_value(cls, value):
|
||||||
if value not in (1, -1):
|
if value not in (1, -1, 0):
|
||||||
raise ValueError("value must be 1 or -1")
|
raise ValueError("value must be 1, -1, or 0")
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ ENGAGEMENT_ACTIONS: tuple[Action, ...] = (
|
|||||||
),
|
),
|
||||||
body(
|
body(
|
||||||
"value",
|
"value",
|
||||||
"Vote value: 1 to upvote, -1 to downvote (re-send to remove).",
|
"Vote value: 1 to upvote, -1 to downvote, 0 to retract.",
|
||||||
required=True,
|
required=True,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -135,3 +135,13 @@ def test_non_ajax_vote_redirects_to_referer(app_server):
|
|||||||
)
|
)
|
||||||
assert r.status_code == 302
|
assert r.status_code == 302
|
||||||
assert r.headers["location"] == "/gists"
|
assert r.headers["location"] == "/gists"
|
||||||
|
|
||||||
|
|
||||||
|
def test_explicit_zero_retracts_vote(app_server):
|
||||||
|
s_a, a_name = _session_votes()
|
||||||
|
s_b, _ = _session_votes()
|
||||||
|
post_uid = _make_post_votes(_uid_votes(a_name))
|
||||||
|
s_b.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "1"}, headers=AJAX_votes)
|
||||||
|
r = s_b.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "0"}, headers=AJAX_votes)
|
||||||
|
assert r.json()["value"] == 0
|
||||||
|
assert r.json()["net"] == 0
|
||||||
|
|||||||
@@ -384,66 +384,6 @@ def test_comment_notification_on_post(app_server, browser, seeded_db):
|
|||||||
ctx_b.close()
|
ctx_b.close()
|
||||||
|
|
||||||
|
|
||||||
def test_thread_comment_notification(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 thread comment notification 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")
|
|
||||||
pb.wait_for_timeout(1000)
|
|
||||||
comment_textarea = pb.locator("form.comment-form textarea[name='content']").first
|
|
||||||
comment_textarea.wait_for(state="visible", timeout=10000)
|
|
||||||
comment_textarea.fill("Bob's top-level comment")
|
|
||||||
pb.locator("button.comment-form-submit").first.click()
|
|
||||||
pb.wait_for_timeout(1500)
|
|
||||||
|
|
||||||
pb_body = pb.locator("body").text_content()
|
|
||||||
assert "Internal Server Error" not in pb_body, f"Bob got 500: {pb_body[:300]}"
|
|
||||||
|
|
||||||
pa.goto(post_url, wait_until="domcontentloaded")
|
|
||||||
pa.wait_for_timeout(1000)
|
|
||||||
comment_textarea = pa.locator("form.comment-form textarea[name='content']").first
|
|
||||||
comment_textarea.wait_for(state="visible", timeout=10000)
|
|
||||||
comment_textarea.fill("Alice also comments on her own post")
|
|
||||||
pa.locator("button.comment-form-submit").first.click()
|
|
||||||
pa.wait_for_timeout(1500)
|
|
||||||
|
|
||||||
pa_body = pa.locator("body").text_content()
|
|
||||||
assert "Internal Server Error" not in pa_body, f"Alice got 500: {pa_body[:300]}"
|
|
||||||
|
|
||||||
pb.goto(f"{BASE_URL}/notifications", wait_until="domcontentloaded")
|
|
||||||
pb.wait_for_timeout(2000)
|
|
||||||
body = pb.locator("body").text_content()
|
|
||||||
assert "Internal Server Error" not in body, (
|
|
||||||
f"Got 500 error on notifications: {body[:500]}"
|
|
||||||
)
|
|
||||||
assert "alice_test" in body, (
|
|
||||||
f"Expected 'alice_test' in notifications, got: {body[:500]}"
|
|
||||||
)
|
|
||||||
assert "also commented" in body, (
|
|
||||||
f"Expected 'also commented' in notifications, got: {body[:500]}"
|
|
||||||
)
|
|
||||||
|
|
||||||
ctx_a.close()
|
|
||||||
ctx_b.close()
|
|
||||||
|
|
||||||
|
|
||||||
def test_follow_notification(app_server, browser, seeded_db):
|
def test_follow_notification(app_server, browser, seeded_db):
|
||||||
from tests.conftest import login_user
|
from tests.conftest import login_user
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user