From: Chris Fulljames Date: Tue, 28 Jan 2025 12:35:14 +0000 (-0500) Subject: Add comment tests X-Git-Url: https://littlesong.place/gitweb/?a=commitdiff_plain;h=1986689f1bc919165ca535663312e3b2e5a4b441;p=littlesongplace.git Add comment tests --- diff --git a/main.py b/main.py index 23cb2a7..8be4b4e 100644 --- a/main.py +++ b/main.py @@ -477,6 +477,9 @@ def songs(): @app.route("/comment", methods=["GET", "POST"]) def comment(): + if not "userid" in session: + return redirect("/login") + if not "songid" in request.args: abort(400) # Must have songid @@ -485,9 +488,6 @@ def comment(): except ValueError: abort(404) # Invald songid - if not "userid" in session: - abort(401) # Must be logged in - # Check for comment being replied to replyto = None if "replytoid" in request.args: @@ -550,24 +550,28 @@ def comment(): get_db().commit() - if "previous_page" in session: - return redirect(session["previous_page"]) - else: - return redirect("/") + return redirect_to_previous_page() + +def redirect_to_previous_page(): + previous_page = "/" + if "previous_page" in session: + previous_page = session["previous_page"] + session.pop("previous_page") + return redirect(previous_page) @app.get("/delete-comment/") def comment_delete(commentid): + if "userid" not in session: + return redirect("/login") + comment = query_db("select c.userid as comment_user, s.userid as song_user from song_comments as c inner join songs as s on c.songid == s.songid where commentid = ?", [commentid], one=True) - print(dict(comment)) if not comment: abort(404) # Invalid comment # Only commenter and song owner can delete comments - if not ( - ("userid" in session) - and ((comment["comment_user"] == session["userid"]) - or (comment["song_user"] == session["userid"]))): - abort(401) + if not ((comment["comment_user"] == session["userid"]) + or (comment["song_user"] == session["userid"])): + abort(403) query_db("delete from song_comments where (commentid = ?) or (replytoid = ?)", [commentid, commentid]) get_db().commit() diff --git a/templates/song-list.html b/templates/song-list.html index 062495e..b75d4ed 100644 --- a/templates/song-list.html +++ b/templates/song-list.html @@ -66,7 +66,9 @@
Comments:
+ {% if session['userid'] %} Add a Comment + {% endif %} {% for comment in song.get_comments() %}
diff --git a/test/test_offline.py b/test/test_offline.py index 3e78f9d..c18d62d 100644 --- a/test/test_offline.py +++ b/test/test_offline.py @@ -264,9 +264,9 @@ def test_edit_other_users_song(client): response = client.get("/edit-song?songid=1") assert response.status_code == 401 -def _create_user_and_song(client): - _create_user(client, "user", "password", login=True) - _test_upload_song(client, b"Success") +def _create_user_and_song(client, username="user"): + _create_user(client, username, "password", login=True) + _test_upload_song(client, b"Success", user=username) def test_update_song_success(client): _create_user_and_song(client) @@ -514,7 +514,7 @@ def test_single_song(client): _test_upload_song(client, b"Success", user="user1", title="song1", tags="tag") songs = _get_song_list_from_page(client, "/song/1/1?action=view") - + assert len(songs) == 1 assert songs[0]["title"] == "song1" assert songs[0]["username"] == "user1" @@ -528,3 +528,160 @@ def test_site_news(client): assert response.status_code == 200 assert b"Site News" in response.data +################################################################################ +# Comments - Normal Flow +################################################################################ + +def _create_user_song_and_comment(client, content): + _create_user_and_song(client) + response = client.post("/comment?songid=1", data={"content": content}) + assert response.status_code == 302 + assert response.headers["Location"] == "/" # No previous page, use homepage + +def test_comment_page_no_reply_or_edit(client): + _create_user_and_song(client) + response = client.get("/comment?songid=1") + assert response.status_code == 200 + assert not b"reply" in response.data + +def test_post_comment(client): + _create_user_and_song(client) + response = client.post("/comment?songid=1", data={"content": "comment text here"}) + assert response.status_code == 302 + assert response.headers["Location"] == "/" # No previous page, use homepage + + response = client.get("/song/1/1?action=view") + assert b"comment text here" in response.data + +def test_edit_comment(client): + _create_user_song_and_comment(client, "comment text here") + + response = client.post("/comment?songid=1&commentid=1", data={"content": "new comment content"}) + assert response.status_code == 302 + assert response.headers["Location"] == "/" # No previous page, use homepage + + response = client.get("/song/1/1?action=view") + assert b"new comment content" in response.data + +def test_delete_comment(client): + _create_user_song_and_comment(client, "comment text here") + + response = client.get("/delete-comment/1") + assert response.status_code == 302 + assert response.headers["Location"] == "None" + + response = client.get("/song/1/1?action=view") + assert b"comment text here" not in response.data + +def test_reply_to_comment(client): + _create_user_song_and_comment(client, "parent comment") + + response = client.post("/comment?songid=1&replytoid=1", data={"content": "child comment"}) + assert response.status_code == 302 + assert response.headers["Location"] == "/" # No previous page, use homepage + + response = client.get("/song/1/1?action=view") + assert b"parent comment" in response.data + assert b"child comment" in response.data + +################################################################################ +# Comments - Auth Status and Errors +################################################################################ + +def test_comment_page_redirects_when_not_logged_in(client): + _create_user_and_song(client) + client.get("/logout") + + response = client.get("/comment?songid=1") + assert response.status_code == 302 + assert response.headers["Location"] == "/login" + +def test_post_comment_redirects_when_not_logged_in(client): + _create_user_and_song(client) + client.get("/logout") + + response = client.post("/comment?songid=1", data={"content": "should fail"}) + assert response.status_code == 302 + assert response.headers["Location"] == "/login" + +def test_add_comment_link_not_shown_when_not_logged_in(client): + _create_user_and_song(client) + response = client.get("/song/1/1?action=view") + assert b"Add a Comment" in response.data + + client.get("/logout") + response = client.get("/song/1/1?action=view") + assert b"Add a Comment" not in response.data + +def test_delete_comment_not_logged_in(client): + _create_user_song_and_comment(client, "comment text here") + client.get("/logout") + + response = client.get("/delete-comment/1") + assert response.status_code == 302 + assert response.headers["Location"] == "/login" + + # Comment not deleted + response = client.get("/song/1/1?action=view") + assert b"comment text here" in response.data + +def test_song_owner_can_delete_other_users_comment(client): + _create_user(client, "user1") + _create_user_and_song(client, "user2") + + # user1 comments on user2's song + client.post("/login", data={"username": "user1", "password": "password"}) + client.post("/comment?songid=1", data={"content": "mean comment"}) + response = client.get("/song/2/1?action=view") + assert b"mean comment" in response.data + + # user2 deletes user1's rude comment + client.post("/login", data={"username": "user2", "password": "password"}) + response = client.get("/delete-comment/1") + assert response.status_code == 302 + response = client.get("/song/2/1?action=view") + assert b"mean comment" not in response.data + +def test_rando_cannot_delete_other_users_comment(client): + _create_user(client, "user1") + _create_user(client, "user2") + _create_user_and_song(client, "user3") + + # user1 comments on user3's song + client.post("/login", data={"username": "user1", "password": "password"}) + client.post("/comment?songid=1", data={"content": "nice comment"}) + response = client.get("/song/3/1?action=view") + assert b"nice comment" in response.data + + # user2 cannot delete user1's comment + client.post("/login", data={"username": "user2", "password": "password"}) + response = client.get("/delete-comment/1") + assert response.status_code == 403 + response = client.get("/song/3/1?action=view") + assert b"nice comment" in response.data + +def test_cannot_edit_other_users_comment(client): + _create_user(client, "user1") + _create_user_and_song(client, "user2") + + # user1 comments on user2's song + client.post("/login", data={"username": "user1", "password": "password"}) + client.post("/comment?songid=1", data={"content": "mean comment"}) + response = client.get("/song/2/1?action=view") + assert b"mean comment" in response.data + + # user2 cannot edit user1's rude comment + client.post("/login", data={"username": "user2", "password": "password"}) + response = client.post("/comment?songid=1&commentid=1", data={"content": "im a meanie"}) + assert response.status_code == 403 + response = client.get("/song/2/1?action=view") + assert b"mean comment" in response.data + +# TODO: post/edit/delete invalid comment id, song id, replyto id + +################################################################################ +# Activity +################################################################################ + +# TODO +