import time from datetime import datetime, timezone import requests from tests.conftest import BASE_URL from devplacepy.database import get_table from devplacepy.utils import generate_uid _counter = [0] AJAX = {"X-Requested-With": "fetch"} def _session(): _counter[0] += 1 name = f"vot{int(time.time() * 1000)}{_counter[0]}" s = requests.Session() s.post(f"{BASE_URL}/auth/signup", data={ "username": name, "email": f"{name}@t.dev", "password": "secret123", "confirm_password": "secret123", }, allow_redirects=True) return s, name def _uid(username): return get_table("users").find_one(username=username)["uid"] def _make_post(owner_uid): uid = generate_uid() get_table("posts").insert({ "uid": uid, "user_uid": owner_uid, "slug": f"{uid[:8]}-vote-post", "title": None, "content": "vote target content", "topic": "random", "project_uid": None, "image": None, "stars": 0, "created_at": datetime.now(timezone.utc).isoformat(), }) return uid def test_upvote_returns_ajax_payload(app_server): s_a, a_name = _session() s_b, _ = _session() post_uid = _make_post(_uid(a_name)) r = s_b.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "1"}, headers=AJAX) assert r.json() == {"net": 1, "up": 1, "down": 0, "value": 1} def test_repeated_vote_toggles_off(app_server): s_a, a_name = _session() s_b, _ = _session() post_uid = _make_post(_uid(a_name)) s_b.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "1"}, headers=AJAX) r = s_b.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "1"}, headers=AJAX) assert r.json()["net"] == 0 assert r.json()["value"] == 0 def test_switch_upvote_to_downvote(app_server): s_a, a_name = _session() s_b, _ = _session() post_uid = _make_post(_uid(a_name)) s_b.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "1"}, headers=AJAX) r = s_b.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "-1"}, headers=AJAX) assert r.json()["net"] == -1 assert r.json()["value"] == -1 def test_upvote_notifies_owner_and_awards_xp(app_server): s_a, a_name = _session() s_b, _ = _session() a_uid = _uid(a_name) post_uid = _make_post(a_uid) before = get_table("users").find_one(uid=a_uid).get("xp", 0) or 0 s_b.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "1"}, headers=AJAX) assert get_table("notifications").count(user_uid=a_uid, type="vote") == 1 after = get_table("users").find_one(uid=a_uid).get("xp", 0) or 0 assert after - before == 5 def test_self_vote_does_not_notify(app_server): s_a, a_name = _session() a_uid = _uid(a_name) post_uid = _make_post(a_uid) before = get_table("notifications").count(user_uid=a_uid, type="vote") s_a.post(f"{BASE_URL}/votes/post/{post_uid}", data={"value": "1"}, headers=AJAX) after = get_table("notifications").count(user_uid=a_uid, type="vote") assert after == before def test_non_ajax_vote_redirects_to_referer(app_server): s_a, a_name = _session() s_b, _ = _session() post_uid = _make_post(_uid(a_name)) r = s_b.post( f"{BASE_URL}/votes/post/{post_uid}", data={"value": "1"}, headers={"Referer": f"{BASE_URL}/feed"}, allow_redirects=False, ) assert r.status_code == 302 assert r.headers["location"] == f"{BASE_URL}/feed"