]> littlesong.place Git - littlesongplace.git/commitdiff
Add playlist tests - incomplete
authorChris Fulljames <christianfulljames@gmail.com>
Sun, 16 Feb 2025 17:38:40 +0000 (12:38 -0500)
committerChris Fulljames <christianfulljames@gmail.com>
Sun, 16 Feb 2025 17:38:40 +0000 (12:38 -0500)
main.py
test/test_offline.py
todo.txt

diff --git a/main.py b/main.py
index 488fd02868e6d0589e13dff0889aa88b0797c690..ed075b6c3f943b5e973c34ff13647af91d2ebfb6 100644 (file)
--- a/main.py
+++ b/main.py
@@ -157,9 +157,9 @@ def users_profile(profile_username):
     userid = session.get("userid", None)
     show_private = userid == profile_userid
     if show_private:
-        plist_data = query_db("select * from playlists where userid = ? order by created desc", [profile_userid])
+        plist_data = query_db("select * from playlists where userid = ? order by updated desc", [profile_userid])
     else:
-        plist_data = query_db("select * from playlists where userid = ? and private = 0 order by created desc", [profile_userid])
+        plist_data = query_db("select * from playlists where userid = ? and private = 0 order by updated desc", [profile_userid])
 
     # Get songs for current profile
     songs = Song.get_all_for_userid(profile_userid)
@@ -744,7 +744,7 @@ def delete_playlist(playlistid):
 
     # Cannot delete other user's playlist
     if session["userid"] != plist_data["userid"]:
-        abort(401)
+        abort(403)
 
     # Delete playlist
     query_db("delete from playlists where playlistid = ?", args=[playlistid])
@@ -770,7 +770,7 @@ def append_to_playlist():
 
     # Cannot edit other user's playlist
     if session["userid"] != plist_data["userid"]:
-        abort(401)
+        abort(403)
 
     songid = request.form["songid"]
 
@@ -809,18 +809,26 @@ def edit_playlist_post(playlistid):
     if session["userid"] != plist_data["userid"]:
         abort(401)
 
-    # Make sure all songs are valid
-    try:
-        songids = [int(s) for s in request.form["songids"].split(",")]
-    except ValueError:
-        # Invalid songid(s)
-        abort(400)
+    # Make sure name is valid
+    name = request.form["name"]
+    if not name or len(name) > 200:
+        flash_and_log("Playlist must have a name", "error")
+        return redirect(request.referrer)
 
-    for songid in songids:
-        song_data = query_db("select * from songs where songid = ?", args=[songid])
-        if not song_data:
+    # Make sure all songs are valid
+    songids = []
+    if request.form["songids"]:
+        try:
+            songids = [int(s) for s in request.form["songids"].split(",")]
+        except ValueError:
+            # Invalid songid(s)
             abort(400)
 
+        for songid in songids:
+            song_data = query_db("select * from songs where songid = ?", args=[songid])
+            if not song_data:
+                abort(400)
+
     # All songs valid - delete old songs
     query_db("delete from playlist_songs where playlistid = ?", args=[playlistid])
 
@@ -831,7 +839,6 @@ def edit_playlist_post(playlistid):
 
     # Update private, name
     private = int(request.form["type"] == "private")
-    name = request.form["name"]
     query_db("update playlists set private = ?, name = ? where playlistid = ?", [private, name, playlistid])
 
     get_db().commit()
@@ -849,10 +856,8 @@ def playlists(playlistid):
 
     # Protect private playlists
     if plist_data["private"]:
-        if "userid" not in session:
-            return redirect("/login")
-        elif session["userid"] != plist_data["userid"]:
-            abort(401)  # Cannot view other user's private playlist
+        if ("userid" not in session) or (session["userid"] != plist_data["userid"]):
+            abort(404)  # Cannot view other user's private playlist - pretend it doesn't even exist
 
     # Get songs
     songs = Song.get_for_playlist(playlistid)
index 539f1240619849d442ef54b159cec1116ead5ea8..29755a2d8f303cd6d801eb04d47304b545169841 100644 (file)
@@ -966,3 +966,189 @@ def test_no_new_activity_after_checking(client):
     assert response.status_code == 200
     assert not response.json["new_activity"]
 
+################################################################################
+# Playlists
+################################################################################
+
+# Create Playlist ##############################################################
+
+def test_create_playlist(client):
+    _create_user(client, "user", login=True)
+    response = client.post("/create-playlist", data={"name": "my playlist", "type": "private"})
+    assert response.status_code == 302
+
+    response = client.get("/users/user")
+    assert b"my playlist" in response.data
+    assert b"[Private]" in response.data
+
+def test_create_playlist_invalid_name(client):
+    _create_user(client, "user", login=True)
+    response = client.post("/create-playlist", data={"name": "a"*201, "type": "private"})
+    assert response.status_code == 302
+    response = client.get("/users/user")
+    assert b"must have a name" in response.data
+    
+    response = client.post("/create-playlist", data={"name": "", "type": "private"})
+    assert response.status_code == 302
+    response = client.get("/users/user")
+    assert b"must have a name" in response.data
+
+def test_create_playlist_not_logged_in(client):
+    response = client.post("/create-playlist", data={"name": "my playlist", "type": "private"})
+    assert response.status_code == 302
+    assert response.headers["Location"] == "/login"
+
+# Delete Playlist ##############################################################
+
+def _create_user_and_playlist(client):
+    _create_user(client, "user", login=True)
+    client.post("/create-playlist", data={"name": "my playlist", "type": "private"})
+
+def test_delete_playlist(client):
+    _create_user_and_playlist(client)
+    response = client.get("/delete-playlist/1", follow_redirects=True)
+    assert b"Deleted playlist my playlist" in response.data
+
+    response = client.get("/users/user")
+    assert not b"my playlist" in response.data
+
+def test_delete_playlist_invalid_playlistid(client):
+    _create_user_and_playlist(client)
+    response = client.get("/delete-playlist/2")
+    assert response.status_code == 404
+
+def test_delete_playlist_not_logged_in(client):
+    _create_user_and_playlist(client)
+    client.get("/logout")
+
+    response = client.get("/delete-playlist/2")
+    assert response.status_code == 401
+
+def test_delete_playlist_other_users_playlist(client):
+    _create_user_and_playlist(client)
+    _create_user(client, "user2", login=True)
+
+    response = client.get("/delete-playlist/1")
+    assert response.status_code == 403
+
+# Append to Playlist ###########################################################
+
+def _create_user_song_and_playlist(client, playlist_type="private"):
+    _create_user_and_song(client)
+    client.post("/create-playlist", data={"name": "my playlist", "type": playlist_type})
+
+def test_append_to_playlist(client):
+    _create_user_song_and_playlist(client)
+    client.post("/append-to-playlist", data={"playlistid": "1", "songid": "1"})
+    response = client.get("/")
+    assert b"Added &#39;song title&#39; to my playlist" in response.data
+
+def test_append_to_playlist_not_logged_in(client):
+    _create_user_song_and_playlist(client)
+    client.get("/logout")
+    response = client.post("/append-to-playlist", data={"playlistid": "1", "songid": "1"})
+    assert response.status_code == 401
+
+def test_append_to_other_users_playlist(client):
+    _create_user_song_and_playlist(client)
+    _create_user(client, "user2", login=True)
+    response = client.post("/append-to-playlist", data={"playlistid": "1", "songid": "1"})
+    assert response.status_code == 403
+
+def test_append_playlist_invalid_songid(client):
+    _create_user_song_and_playlist(client)
+    response = client.post("/append-to-playlist", data={"playlistid": "1", "songid": "2"})
+    assert response.status_code == 404
+
+def test_append_playlist_invalid_playlistid(client):
+    _create_user_song_and_playlist(client)
+    response = client.post("/append-to-playlist", data={"playlistid": "2", "songid": "1"})
+    assert response.status_code == 404
+
+# Playlist on Profile ##########################################################
+
+def test_playlists_on_own_profile(client):
+    _create_user_song_and_playlist(client)  # Private playlist
+    client.post("/create-playlist", data={"name": "my public playlist", "type": "public"}, follow_redirects=True)
+    client.get("/users/user") # Clear flashes
+
+    # Shows public and private playlists
+    response = client.get("/users/user")
+    assert b"my playlist" in response.data
+    assert b"my public playlist" in response.data
+
+def test_playlists_on_other_users_profile(client):
+    _create_user_song_and_playlist(client)  # Private playlist
+    client.post("/create-playlist", data={"name": "my public playlist", "type": "public"})
+    client.get("/users/user") # Clear flashes
+
+    # Shows only public playlists
+    _create_user(client, "user2", login=True)
+    response = client.get("/users/user")
+    assert b"my playlist" not in response.data
+    assert b"my public playlist" in response.data
+
+# View Playlist ################################################################
+
+def test_view_own_public_playlist(client):
+    _create_user_song_and_playlist(client, playlist_type="public")
+    response = client.get("/playlists/1")
+    assert response.status_code == 200
+    assert b"[Public]" in response.data
+
+def test_view_own_private_playlist(client):
+    _create_user_song_and_playlist(client, playlist_type="private")
+    response = client.get("/playlists/1")
+    assert response.status_code == 200
+    assert b"[Private]" in response.data
+
+def test_view_other_users_public_playlist(client):
+    _create_user_song_and_playlist(client, playlist_type="public")
+    _create_user(client, "user2", login=True)
+    response = client.get("/playlists/1")
+    assert response.status_code == 200
+    assert b"[Public]" not in response.data  # Type not shown
+
+def test_view_other_users_private_playlist(client):
+    _create_user_song_and_playlist(client, playlist_type="private")
+    _create_user(client, "user2", login=True)
+    response = client.get("/playlists/1")
+    assert response.status_code == 404
+
+def test_view_invalid_playlist(client):
+    response = client.get("/playlists/0")
+    assert response.status_code == 404
+
+# Edit Playlist ################################################################
+
+def test_edit_playlist_change_type(client):
+    _create_user_song_and_playlist(client, playlist_type="private")
+    response = client.post("/edit-playlist/1", data={"name": "my playlist", "type": "public", "songids": ""})
+    assert response.status_code == 302
+
+    response = client.get("/playlists/1")
+    assert b"[Public]" in response.data
+
+def test_edit_playlist_change_name(client):
+    _create_user_song_and_playlist(client, playlist_type="private")
+    response = client.post("/edit-playlist/1", data={"name": "cool new playlist name", "type": "private", "songids": ""})
+    assert response.status_code == 302
+
+    response = client.get("/playlists/1")
+    assert b"cool new playlist name" in response.data
+
+def test_edit_playlist_change_name_invalid(client):
+    _create_user_song_and_playlist(client, playlist_type="private")
+    client.get("/playlists/1")  # Clear flashes
+    response = client.post("/edit-playlist/1", data={"name": "", "type": "private", "songids": ""})
+    assert response.status_code == 302
+
+    response = client.get("/playlists/1")
+    assert b"my playlist" in response.data
+    assert b"must have a name" in response.data
+
+# Edit playlist - change song order
+# Edit playlist - remove song(s)
+# Edit playlist - not logged in
+# Edit playlist - other user's playlist
+# Edit playlist - invalid songid
index 40a601edb1e0644f58d9f62c9a4cecceb59d84b6..2dcc9df64cc353c072d6ed71bf924cd1165c42b1 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -2,10 +2,11 @@ NOW
 - Test playlist API
 
 SOON
-- Break up main.py
+- Break up main.py, test_offline.py
 - AJAX pages so songs can play during navigation
 - Pinned profile playlists
 
+- Image support in comments, descriptions, bios, etc.
 - Player minimize button
 - Shuffle all page
 - Shuffle song list toggle