]> littlesong.place Git - littlesongplace.git/commitdiff
Separate out authentication tests
authorChris Fulljames <christianfulljames@gmail.com>
Mon, 31 Mar 2025 23:14:41 +0000 (19:14 -0400)
committerChris Fulljames <christianfulljames@gmail.com>
Mon, 31 Mar 2025 23:14:41 +0000 (19:14 -0400)
test/test_auth.py [new file with mode: 0644]
test/test_offline.py
test/utils.py

diff --git a/test/test_auth.py b/test/test_auth.py
new file mode 100644 (file)
index 0000000..1d66b33
--- /dev/null
@@ -0,0 +1,98 @@
+from flask import session
+from .utils import create_user, post_signup_form
+
+################################################################################
+# Signup
+################################################################################
+
+def test_signup_get(client):
+    response = client.get("/signup")
+    assert b"Create a new account" in response.data
+
+def test_signup_success(client):
+    response = post_signup_form(client, "user", "password")
+    assert response.status_code == 302
+    assert response.headers["Location"] == "/login"
+
+    response = client.get("/login")
+    assert b"User created" in response.data
+
+def _test_signup_error(client, username, password, password_confirm, msg):
+    response = post_signup_form(client, username, password, password_confirm)
+    assert response.status_code == 302
+    assert response.headers["Location"] == "None"
+
+    response = client.get("/signup")
+    assert b"User created" not in response.data
+    assert msg in response.data
+
+def test_signup_username_invalid_characters(client):
+    _test_signup_error(client, "user@gmail.com", "password", "password", b"special characters")
+
+def test_signup_username_too_short(client):
+    _test_signup_error(client, "us", "password", "password", b"at least 3 characters")
+
+def test_signup_username_too_long(client):
+    _test_signup_error(client, "a"*31, "password", "password", b"more than 30 characters")
+
+def test_signup_passwords_dont_match(client):
+    _test_signup_error(client, "user", "password", "passwor", b"Passwords do not match")
+
+def test_signup_password_too_short(client):
+    _test_signup_error(client, "user", "passwor", "passwor", b"at least 8 characters")
+
+def test_signup_user_exists(client):
+    # Success the first time
+    response = post_signup_form(client, "user", "password")
+    assert response.status_code == 302
+    assert response.headers["Location"] == "/login"
+    response = client.get("/login")
+    assert b"User created" in response.data
+
+    # Error the second time
+    _test_signup_error(client, "user", "password", "password", b"already taken")
+
+################################################################################
+# Login/Logout
+################################################################################
+
+def test_login_get(client):
+    response = client.get("/login")
+    assert b"Sign In" in response.data
+
+def test_login_success(client):
+    create_user(client, "username", "password")
+    response = client.post("/login", data={"username": "username", "password": "password"})
+    assert response.status_code == 302
+    assert response.headers["Location"] == "/users/username"
+
+    response = client.get("/users/username")
+    assert b'username="username"' in response.data
+
+def test_login_invalid_username(client):
+    create_user(client, "username", "password")
+    response = client.post("/login", data={"username": "incorrect", "password": "password"})
+    assert response.status_code == 200
+    assert b"Invalid username/password" in response.data
+
+def test_login_invalid_username(client):
+    create_user(client, "username", "password")
+    response = client.post("/login", data={"username": "username", "password": "incorrect"})
+    assert response.status_code == 200
+    assert b"Invalid username/password" in response.data
+
+def test_logout(client, app):
+    with client:
+        create_user(client, "username", "password")
+        response = client.post("/login", data={"username": "username", "password": "password"})
+        assert response.status_code == 302
+
+        assert session["username"] == "username"
+        assert session["userid"] == 1
+
+        response = client.get("/logout")
+        assert response.status_code == 302
+        assert response.headers["Location"] == "/"
+
+        assert "username" not in session
+        assert "userid" not in session
index 495b009d4ecb5918747999069e5101db820bcdbf..d11aa0324140a3d420ab8e086033d251a99ba64b 100644 (file)
@@ -4,137 +4,24 @@ import re
 from pathlib import Path
 
 import pytest
-from flask import session
 
-import littlesongplace as lsp
+from .utils import create_user
 
 TEST_DATA = Path(__file__).parent / "data"
 
-################################################################################
-# Signup
-################################################################################
-
-def test_signup_get(client):
-    response = client.get("/signup")
-    assert b"Create a new account" in response.data
-
-def _post_signup_form(client, username, password, password_confirm=None):
-    if password_confirm is None:
-        password_confirm = password
-    return client.post(
-            "/signup",
-            data=dict(username=username, password=password, password_confirm=password_confirm))
-
-def test_signup_success(client):
-    response = _post_signup_form(client, "user", "password")
-    assert response.status_code == 302
-    assert response.headers["Location"] == "/login"
-
-    response = client.get("/login")
-    assert b"User created" in response.data
-
-def _test_signup_error(client, username, password, password_confirm, msg):
-    response = _post_signup_form(client, username, password, password_confirm)
-    assert response.status_code == 302
-    assert response.headers["Location"] == "None"
-
-    response = client.get("/signup")
-    assert b"User created" not in response.data
-    assert msg in response.data
-
-def test_signup_username_invalid_characters(client):
-    _test_signup_error(client, "user@gmail.com", "password", "password", b"special characters")
-
-def test_signup_username_too_short(client):
-    _test_signup_error(client, "us", "password", "password", b"at least 3 characters")
-
-def test_signup_username_too_long(client):
-    _test_signup_error(client, "a"*31, "password", "password", b"more than 30 characters")
-
-def test_signup_passwords_dont_match(client):
-    _test_signup_error(client, "user", "password", "passwor", b"Passwords do not match")
-
-def test_signup_password_too_short(client):
-    _test_signup_error(client, "user", "passwor", "passwor", b"at least 8 characters")
-
-def test_signup_user_exists(client):
-    # Success the first time
-    response = _post_signup_form(client, "user", "password")
-    assert response.status_code == 302
-    assert response.headers["Location"] == "/login"
-    response = client.get("/login")
-    assert b"User created" in response.data
-
-    # Error the second time
-    _test_signup_error(client, "user", "password", "password", b"already taken")
-
-################################################################################
-# Login/Logout
-################################################################################
-
-def test_login_get(client):
-    response = client.get("/login")
-    assert b"Sign In" in response.data
-
-def _create_user(client, username, password="password", login=False):
-    response = _post_signup_form(client, username, password)
-    assert response.status_code == 302
-    assert response.headers["Location"] == "/login"
-
-    if login:
-        response = client.post("/login", data={"username": username, "password": password})
-        assert response.status_code == 302
-        assert response.headers["Location"] == f"/users/{username}"
-
-def test_login_success(client):
-    _create_user(client, "username", "password")
-    response = client.post("/login", data={"username": "username", "password": "password"})
-    assert response.status_code == 302
-    assert response.headers["Location"] == "/users/username"
-
-    response = client.get("/users/username")
-    assert b'username="username"' in response.data
-
-def test_login_invalid_username(client):
-    _create_user(client, "username", "password")
-    response = client.post("/login", data={"username": "incorrect", "password": "password"})
-    assert response.status_code == 200
-    assert b"Invalid username/password" in response.data
-
-def test_login_invalid_username(client):
-    _create_user(client, "username", "password")
-    response = client.post("/login", data={"username": "username", "password": "incorrect"})
-    assert response.status_code == 200
-    assert b"Invalid username/password" in response.data
-
-def test_logout(client, app):
-    with client:
-        _create_user(client, "username", "password")
-        response = client.post("/login", data={"username": "username", "password": "password"})
-        assert response.status_code == 302
-
-        assert session["username"] == "username"
-        assert session["userid"] == 1
-
-        response = client.get("/logout")
-        assert response.status_code == 302
-        assert response.headers["Location"] == "/"
-
-        assert "username" not in session
-        assert "userid" not in session
 
 ################################################################################
 # Profile/Bio
 ################################################################################
 
 def test_default_bio_empty(client):
-    _create_user(client, "user", "password")
+    create_user(client, "user", "password")
 
     response = client.get("/users/user")
     assert b'<div class="profile-bio" id="profile-bio"></div>' in response.data
 
 def test_update_bio(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
 
     response = client.post("/edit-profile", data={
         "bio": "this is the bio",
@@ -156,7 +43,7 @@ def test_update_bio(client):
     assert b'accolor="#FF00FF"' in response.data
 
 def test_upload_pfp(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     response = client.post("/edit-profile", data={
         "bio": "",
         "pfp": open(TEST_DATA/"lsp_notes.png", "rb"),
@@ -177,7 +64,7 @@ def test_edit_profile_not_logged_in(client):
     assert response.status_code == 401
 
 def test_get_pfp(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     client.post("/edit-profile", data={
         "bio": "",
         "pfp": open(TEST_DATA/"lsp_notes.png", "rb"),
@@ -192,7 +79,7 @@ def test_get_pfp(client):
     # Can't check image file, since site has modified it
 
 def test_get_pfp_no_file(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     # User exists but doesn't have a pfp
     response = client.get("/pfp/1")
     assert response.status_code == 404
@@ -236,49 +123,49 @@ def _test_upload_song(client, msg, error=False, songid=None, user="user", userid
     assert msg in response.data
 
 def test_upload_song_success(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     _test_upload_song(client, b"Successfully uploaded &#39;song title&#39;")
 
 def test_upload_song_bad_title(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     _test_upload_song(client, b"not a valid song title", error=True, title="\r\n")
 
 def test_upload_song_title_too_long(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     _test_upload_song(client, b"cannot be more than 80 characters", error=True, title="a"*81)
 
 def test_upload_song_description_too_long(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     _test_upload_song(client, b"cannot be more than 10k characters", error=True, description="a"*10_001)
 
 def test_upload_song_invalid_tag(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     _test_upload_song(client, b"not a valid tag name", error=True, tags="a\r\na")
 
 def test_upload_song_tag_too_long(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     _test_upload_song(client, b"not a valid tag name", error=True, tags="a"*31)
 
 def test_upload_song_invalid_collab(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     _test_upload_song(client, b"not a valid collaborator name", error=True, collabs="a\r\na")
 
 def test_upload_song_collab_too_long(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     _test_upload_song(client, b"not a valid collaborator name", error=True, collabs="a"*32)
 
 def test_upload_song_invalid_audio(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     # Use this script file as the "audio" file
     _test_upload_song(client, b"Invalid audio file", error=True, filename=__file__)
 
 def test_upload_song_from_mp4(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     _test_upload_song(client, b"Successfully uploaded &#39;song title&#39;", filename=TEST_DATA/"sample-4s.mp4")
 
 @pytest.mark.skip
 def test_upload_song_from_youtube(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     data = {
         "song-url": "https://youtu.be/5e5Z6gZWiEs",
         "title": "song title",
@@ -298,29 +185,29 @@ def test_upload_song_from_youtube(client):
 ################################################################################
 
 def test_edit_invalid_song(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     response = client.get("/edit-song?songid=1")
     assert response.status_code == 404
 
 def test_edit_invalid_id(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     response = client.get("/edit-song?songid=abc")
     assert response.status_code == 404
 
 def test_edit_other_users_song(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     _test_upload_song(client, b"Success")
 
-    _create_user(client, "user2", "password", login=True)
+    create_user(client, "user2", "password", login=True)
     response = client.get("/edit-song?songid=1")
     assert response.status_code == 401
 
-def _create_user_and_song(client, username="user"):
-    _create_user(client, username, "password", login=True)
+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)
+    create_user_and_song(client)
     _test_upload_song(client, b"Successfully updated &#39;song title&#39;", filename=TEST_DATA/"sample-6s.mp3", songid=1)
     response = client.get("/song/1/1")
     assert response.status_code == 200
@@ -329,7 +216,7 @@ def test_update_song_success(client):
 
 @pytest.mark.skip
 def test_update_song_from_youtube(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     data = {
         "song-url": "https://youtu.be/5e5Z6gZWiEs",
         "title": "song title",
@@ -345,39 +232,39 @@ def test_update_song_from_youtube(client):
     assert b"Successfully updated &#39;song title&#39;" in response.data
 
 def test_update_song_bad_title(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     _test_upload_song(client, b"not a valid song title", error=True, songid=1, title="\r\n")
 
 def test_update_song_title_too_long(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     _test_upload_song(client, b"cannot be more than 80 characters", error=True, songid=1, title="a"*81)
 
 def test_update_song_description_too_long(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     _test_upload_song(client, b"cannot be more than 10k characters", error=True, songid=1, description="a"*10_001)
 
 def test_update_song_invalid_tag(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     _test_upload_song(client, b"not a valid tag name", error=True, songid=1, tags="a\r\na")
 
 def test_update_song_tag_too_long(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     _test_upload_song(client, b"not a valid tag name", error=True, songid=1, tags="a"*31)
 
 def test_update_song_invalid_collab(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     _test_upload_song(client, b"not a valid collaborator name", error=True, songid=1, collabs="a\r\na")
 
 def test_update_song_collab_too_long(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     _test_upload_song(client, b"not a valid collaborator name", error=True, songid=1, collabs="a"*32)
 
 def test_update_song_invalid_mp3(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     _test_upload_song(client, b"Invalid audio file", error=True, songid=1, filename=__file__)
 
 def test_update_song_invalid_song(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
 
     data = {
         "song-file": open(TEST_DATA/"sample-3s.mp3", "rb"),
@@ -391,7 +278,7 @@ def test_update_song_invalid_song(client):
     assert response.status_code == 400
 
 def test_update_song_invalid_id(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
 
     data = {
         "song-file": open(TEST_DATA/"sample-3s.mp3", "rb"),
@@ -405,8 +292,8 @@ def test_update_song_invalid_id(client):
     assert response.status_code == 400
 
 def test_update_song_other_users_song(client):
-    _create_user_and_song(client)
-    _create_user(client, "user2", login=True)
+    create_user_and_song(client)
+    create_user(client, "user2", login=True)
 
     data = {
         "song-file": open(TEST_DATA/"sample-3s.mp3", "rb"),
@@ -420,7 +307,7 @@ def test_update_song_other_users_song(client):
     assert response.status_code == 401
 
 def test_uppercase_tags(client):
-    _create_user(client, "user", "password", login=True)
+    create_user(client, "user", "password", login=True)
     _test_upload_song(client, b"Success", tags="TAG1, tag2")
     response = client.get("/users/user")
 
@@ -444,7 +331,7 @@ def test_uppercase_tags(client):
 ################################################################################
 
 def test_delete_song_success(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     response = client.get("/delete-song/1")
     assert response.status_code == 302
     assert response.headers["Location"] == "/users/user"
@@ -457,18 +344,18 @@ def test_delete_song_success(client):
     assert response.status_code == 404
 
 def test_delete_song_invalid_song(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     response = client.get("/delete-song/2")
     assert response.status_code == 404
 
 def test_delete_song_invalid_id(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     response = client.get("/delete-song/abc")
     assert response.status_code == 404
 
 def test_delete_song_other_users_song(client):
-    _create_user_and_song(client)
-    _create_user(client, "user2", login=True)
+    create_user_and_song(client)
+    create_user(client, "user2", login=True)
     response = client.get("/delete-song/1")
     assert response.status_code == 401
 
@@ -477,18 +364,18 @@ def test_delete_song_other_users_song(client):
 ################################################################################
 
 def test_get_song(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     response = client.get("/song/1/1")
     with open(TEST_DATA/"sample-3s.mp3", "rb") as mp3file:
         assert response.data == mp3file.read()
 
 def test_get_song_invalid_song(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     response = client.get("/song/1/2")
     assert response.status_code == 404
 
 def test_get_song_invalid_user(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     response = client.get("/song/2/1")
     assert response.status_code == 404
 
@@ -504,14 +391,14 @@ def _get_song_list_from_page(client, url):
     return [json.loads(html.unescape(m)) for m in matches]
 
 def test_profile_songs_one_song(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     songs = _get_song_list_from_page(client, "/users/user")
 
     assert len(songs) == 1
     assert songs[0]["title"] == "song title"
 
 def test_profile_songs_two_songs(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     _test_upload_song(client, b"Success", title="title2")
     songs = _get_song_list_from_page(client, "/users/user")
 
@@ -523,10 +410,10 @@ def test_profile_songs_two_songs(client):
 # Homepage
 
 def test_homepage_songs_two_songs(client):
-    _create_user(client, "user1", "password", login=True)
+    create_user(client, "user1", "password", login=True)
     _test_upload_song(client, b"Success", user="user1", title="song1")
 
-    _create_user(client, "user2", "password", login=True)
+    create_user(client, "user2", "password", login=True)
     _test_upload_song(client, b"Success", user="user2", title="song2")
 
     songs = _get_song_list_from_page(client, "/")
@@ -542,10 +429,10 @@ def test_homepage_songs_two_songs(client):
 # Songs by tag
 
 def test_songs_by_tag_no_user(client):
-    _create_user(client, "user1", "password", login=True)
+    create_user(client, "user1", "password", login=True)
     _test_upload_song(client, b"Success", user="user1", title="song1", tags="tag")
 
-    _create_user(client, "user2", "password", login=True)
+    create_user(client, "user2", "password", login=True)
     _test_upload_song(client, b"Success", user="user2", title="song2", tags="")
     _test_upload_song(client, b"Success", user="user2", title="song3", tags="tag")
 
@@ -562,11 +449,11 @@ def test_songs_by_tag_no_user(client):
     assert songs[1]["username"] == "user1"
 
 def test_songs_by_tag_with_user(client):
-    _create_user(client, "user1", "password", login=True)
+    create_user(client, "user1", "password", login=True)
     _test_upload_song(client, b"Success", user="user1", title="song1", tags="tag")
     _test_upload_song(client, b"Success", user="user1", title="song2", tags="")
 
-    _create_user(client, "user2", "password", login=True)
+    create_user(client, "user2", "password", login=True)
     _test_upload_song(client, b"Success", user="user2", title="song3", tags="tag")
 
     songs = _get_song_list_from_page(client, "/songs?tag=tag&user=user1")
@@ -577,11 +464,11 @@ def test_songs_by_tag_with_user(client):
     # Song 2 not shown, no tag; song 3 not shown, by different user
 
 def test_songs_by_user(client):
-    _create_user(client, "user1", "password", login=True)
+    create_user(client, "user1", "password", login=True)
     _test_upload_song(client, b"Success", user="user1", title="song1", tags="tag")
     _test_upload_song(client, b"Success", user="user1", title="song2", tags="")
 
-    _create_user(client, "user2", "password", login=True)
+    create_user(client, "user2", "password", login=True)
     _test_upload_song(client, b"Success", user="user2", title="song3", tags="tag")
 
     songs = _get_song_list_from_page(client, "/songs?user=user1")
@@ -597,7 +484,7 @@ def test_songs_by_user(client):
     # Song 3 not shown, by different user
 
 def test_single_song(client):
-    _create_user(client, "user1", "password", login=True)
+    create_user(client, "user1", "password", login=True)
     _test_upload_song(client, b"Success", user="user1", title="song1", tags="tag")
 
     songs = _get_song_list_from_page(client, "/song/1/1?action=view")
@@ -619,20 +506,20 @@ def test_site_news(client):
 # Comments - Normal Flow
 ################################################################################
 
-def _create_user_song_and_comment(client, content):
-    _create_user_and_song(client)
+def create_user_song_and_comment(client, content):
+    create_user_and_song(client)
     response = client.post("/comment?threadid=2", 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)
+    create_user_and_song(client)
     response = client.get("/comment?threadid=2")
     assert response.status_code == 200
     assert not b"reply" in response.data
 
 def test_post_comment(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     response = client.post("/comment?threadid=2", data={"content": "comment text here"})
     assert response.status_code == 302
     assert response.headers["Location"] == "/" # No previous page, use homepage
@@ -641,7 +528,7 @@ def test_post_comment(client):
     assert b"comment text here" in response.data
 
 def test_edit_comment(client):
-    _create_user_song_and_comment(client, "comment text here")
+    create_user_song_and_comment(client, "comment text here")
 
     response = client.post("/comment?threadid=2&commentid=1", data={"content": "new comment content"})
     assert response.status_code == 302
@@ -651,7 +538,7 @@ def test_edit_comment(client):
     assert b"new comment content" in response.data
 
 def test_delete_comment(client):
-    _create_user_song_and_comment(client, "comment text here")
+    create_user_song_and_comment(client, "comment text here")
 
     response = client.get("/delete-comment/1")
     assert response.status_code == 302
@@ -661,7 +548,7 @@ def test_delete_comment(client):
     assert b"comment text here" not in response.data
 
 def test_delete_song_with_comments(client):
-    _create_user_song_and_comment(client, "comment text here")
+    create_user_song_and_comment(client, "comment text here")
     response = client.get("/delete-song/1")
     assert response.status_code == 302
     assert response.headers["Location"] == "/users/user"
@@ -670,7 +557,7 @@ def test_delete_song_with_comments(client):
     assert response.status_code == 404  # Song deleted
 
 def test_reply_to_comment(client):
-    _create_user_song_and_comment(client, "parent comment")
+    create_user_song_and_comment(client, "parent comment")
 
     response = client.post("/comment?threadid=2&replytoid=1", data={"content": "child comment"})
     assert response.status_code == 302
@@ -681,14 +568,14 @@ def test_reply_to_comment(client):
     assert b"child comment" in response.data
 
 def test_comment_on_profile(client):
-    _create_user(client, "user1", login=True)
+    create_user(client, "user1", login=True)
     response = client.get("/comment?threadid=1", headers={"Referer": "/users/user1"})
     response = client.post("/comment?threadid=1", data={"content": "comment on profile"}, follow_redirects=True)
     assert response.request.path == "/users/user1"
     assert b"comment on profile" in response.data
 
 def test_comment_on_playlist(client):
-    _create_user_song_and_playlist(client)
+    create_user_song_and_playlist(client)
     response = client.get("/comment?threadid=3", headers={"Referer": "/playlists/1"})
     response = client.post("/comment?threadid=3", data={"content": "comment on playlist"}, follow_redirects=True)
     assert response.request.path == "/playlists/1"
@@ -699,7 +586,7 @@ def test_comment_on_playlist(client):
 ################################################################################
 
 def test_comment_page_redirects_when_not_logged_in(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     client.get("/logout")
 
     response = client.get("/comment?threadid=2")
@@ -707,7 +594,7 @@ def test_comment_page_redirects_when_not_logged_in(client):
     assert response.headers["Location"] == "/login"
 
 def test_post_comment_redirects_when_not_logged_in(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     client.get("/logout")
 
     response = client.post("/comment?threadid=2", data={"content": "should fail"})
@@ -715,7 +602,7 @@ def test_post_comment_redirects_when_not_logged_in(client):
     assert response.headers["Location"] == "/login"
 
 def test_add_comment_link_not_shown_when_not_logged_in(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     response = client.get("/song/1/1?action=view")
     assert b"Add a Comment" in response.data
 
@@ -724,7 +611,7 @@ def test_add_comment_link_not_shown_when_not_logged_in(client):
     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")
+    create_user_song_and_comment(client, "comment text here")
     client.get("/logout")
 
     response = client.get("/delete-comment/1")
@@ -736,8 +623,8 @@ def test_delete_comment_not_logged_in(client):
     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")
+    create_user(client, "user1")
+    create_user_and_song(client, "user2")
 
     # user1 comments on user2's song
     client.post("/login", data={"username": "user1", "password": "password"})
@@ -753,9 +640,9 @@ def test_song_owner_can_delete_other_users_comment(client):
     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")
+    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"})
@@ -771,8 +658,8 @@ def test_rando_cannot_delete_other_users_comment(client):
     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")
+    create_user(client, "user1")
+    create_user_and_song(client, "user2")
 
     # user1 comments on user2's song
     client.post("/login", data={"username": "user1", "password": "password"})
@@ -788,7 +675,7 @@ def test_cannot_edit_other_users_comment(client):
     assert b"mean comment" in response.data
 
 def test_comment_invalid_threadid(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     response = client.post("/comment?threadid=3", data={"content": "broken comment"})
     assert response.status_code == 404
 
@@ -796,7 +683,7 @@ def test_comment_invalid_threadid(client):
     assert response.status_code == 404
 
 def test_comment_invalid_replytoid(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     response = client.post("/comment?threadid=2&replytoid=1", data={"content": "broken comment"})
     assert response.status_code == 404
 
@@ -804,7 +691,7 @@ def test_comment_invalid_replytoid(client):
     assert response.status_code == 404
 
 def test_comment_invalid_commentid(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     response = client.post("/comment?threadid=2&commentid=1", data={"content": "broken comment"})
     assert response.status_code == 404
 
@@ -812,7 +699,7 @@ def test_comment_invalid_commentid(client):
     assert response.status_code == 404
 
 def test_comment_no_songid(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     response = client.post("/comment", data={"content": "broken comment"})
     assert response.status_code == 400
 
@@ -820,7 +707,7 @@ def test_comment_no_songid(client):
     assert response.status_code == 400
 
 def test_delete_invalid_comment_id(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     response = client.get("/delete-comment/1")
     assert response.status_code == 404
 
@@ -834,13 +721,13 @@ def test_activity_redirects_when_not_logged_in(client):
     assert response.headers["Location"] == "/login"
 
 def test_activity_empty_when_user_has_no_notifications(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     response = client.get("/activity")
     assert b"Nothing to show" in response.data
 
 def test_activity_for_comment_on_song(client):
-    _create_user_and_song(client)
-    _create_user(client, "user2", login=True)
+    create_user_and_song(client)
+    create_user(client, "user2", login=True)
     client.post("/comment?threadid=2", data={"content": "hey cool song"})
     response = client.get("/activity")
     assert b"Nothing to show" in response.data
@@ -850,8 +737,8 @@ def test_activity_for_comment_on_song(client):
     assert b"hey cool song" in response.data
 
 def test_activity_for_reply_to_comment(client):
-    _create_user_and_song(client)
-    _create_user(client, "user2", login=True)
+    create_user_and_song(client)
+    create_user(client, "user2", login=True)
     client.post("/comment?threadid=2", data={"content": "hey cool song"})
 
     client.post("/login", data={"username": "user", "password": "password"})
@@ -862,9 +749,9 @@ def test_activity_for_reply_to_comment(client):
     assert b"thank you" in response.data
 
 def test_activity_for_reply_to_reply(client):
-    _create_user_and_song(client)
-    _create_user(client, "user2")
-    _create_user(client, "user3", login=True)
+    create_user_and_song(client)
+    create_user(client, "user2")
+    create_user(client, "user3", login=True)
     client.post("/comment?threadid=2", data={"content": "hey cool song"})
 
     client.post("/login", data={"username": "user2", "password": "password"})
@@ -891,8 +778,8 @@ def test_activity_for_reply_to_reply(client):
     assert b"it really is cool" in response.data
 
 def test_activity_deleted_when_song_deleted(client):
-    _create_user_and_song(client)
-    _create_user(client, "user2", login=True)
+    create_user_and_song(client)
+    create_user(client, "user2", login=True)
     client.post("/comment?threadid=2", data={"content": "hey cool song"})
 
     client.post("/login", data={"username": "user", "password": "password"})
@@ -904,8 +791,8 @@ def test_activity_deleted_when_song_deleted(client):
     assert b"hey cool song" not in response.data
 
 def test_activity_deleted_when_comment_deleted(client):
-    _create_user_and_song(client)
-    _create_user(client, "user2", login=True)
+    create_user_and_song(client)
+    create_user(client, "user2", login=True)
     client.post("/comment?threadid=2", data={"content": "hey cool song"})
 
     client.post("/login", data={"username": "user", "password": "password"})
@@ -926,14 +813,14 @@ def test_no_new_activity_when_not_logged_in(client):
     assert not response.json["new_activity"]
 
 def test_no_new_activity_when_no_activity(client):
-    _create_user_and_song(client)
+    create_user_and_song(client)
     response = client.get("/new-activity")
     assert response.status_code == 200
     assert not response.json["new_activity"]
 
 def test_new_activity_after_comment(client):
-    _create_user_and_song(client)
-    _create_user(client, "user2", login=True)
+    create_user_and_song(client)
+    create_user(client, "user2", login=True)
     client.post("/comment?threadid=2", data={"content": "hey cool song"})
 
     client.post("/login", data={"username": "user", "password": "password"})
@@ -942,8 +829,8 @@ def test_new_activity_after_comment(client):
     assert response.json["new_activity"]
 
 def test_no_new_activity_after_checking(client):
-    _create_user_and_song(client)
-    _create_user(client, "user2", login=True)
+    create_user_and_song(client)
+    create_user(client, "user2", login=True)
     client.post("/comment?threadid=2", data={"content": "hey cool song"})
 
     client.post("/login", data={"username": "user", "password": "password"})
@@ -960,7 +847,7 @@ def test_no_new_activity_after_checking(client):
 # Create Playlist ##############################################################
 
 def test_create_playlist(client):
-    _create_user(client, "user", login=True)
+    create_user(client, "user", login=True)
     response = client.post("/create-playlist", data={"name": "my playlist", "type": "private"})
     assert response.status_code == 302
 
@@ -969,7 +856,7 @@ def test_create_playlist(client):
     assert b"[Private]" in response.data
 
 def test_create_playlist_invalid_name(client):
-    _create_user(client, "user", login=True)
+    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")
@@ -987,12 +874,12 @@ def test_create_playlist_not_logged_in(client):
 
 # Delete Playlist ##############################################################
 
-def _create_user_and_playlist(client):
-    _create_user(client, "user", login=True)
+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)
+    create_user_and_playlist(client)
     response = client.get("/delete-playlist/1", follow_redirects=True)
     assert b"Deleted playlist my playlist" in response.data
 
@@ -1000,63 +887,63 @@ def test_delete_playlist(client):
     assert not b"my playlist" in response.data
 
 def test_delete_playlist_invalid_playlistid(client):
-    _create_user_and_playlist(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)
+    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)
+    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)
+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)
+    create_user_song_and_playlist(client)
     response = client.post("/append-to-playlist", data={"playlistid": "1", "songid": "1"})
     data = response.json
     assert data["status"] == "success"
     assert "Added 'song title' to my playlist" in data["messages"]
 
 def test_append_to_playlist_not_logged_in(client):
-    _create_user_song_and_playlist(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)
+    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)
+    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)
+    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
+    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
 
@@ -1066,12 +953,12 @@ def test_playlists_on_own_profile(client):
     assert b"my public playlist" in response.data
 
 def test_playlists_on_other_users_profile(client):
-    _create_user_song_and_playlist(client)  # Private playlist
+    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)
+    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
@@ -1079,27 +966,27 @@ def test_playlists_on_other_users_profile(client):
 # View Playlist ################################################################
 
 def test_view_own_public_playlist(client):
-    _create_user_song_and_playlist(client, playlist_type="public")
+    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")
+    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)
+    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)
+    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
 
@@ -1110,7 +997,7 @@ def test_view_invalid_playlist(client):
 # Edit Playlist ################################################################
 
 def test_edit_playlist_change_type(client):
-    _create_user_song_and_playlist(client, playlist_type="private")
+    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
 
@@ -1118,7 +1005,7 @@ def test_edit_playlist_change_type(client):
     assert b"[Public]" in response.data
 
 def test_edit_playlist_change_name(client):
-    _create_user_song_and_playlist(client, playlist_type="private")
+    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
 
@@ -1126,7 +1013,7 @@ def test_edit_playlist_change_name(client):
     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")
+    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
@@ -1136,7 +1023,7 @@ def test_edit_playlist_change_name_invalid(client):
     assert b"must have a name" in response.data
 
 def test_edit_playlist_change_song_order(client):
-    _create_user_song_and_playlist(client)
+    create_user_song_and_playlist(client)
     _test_upload_song(client, b"Successfully uploaded")
     client.post("/append-to-playlist", data={"playlistid": "1", "songid": "1"})
     client.post("/append-to-playlist", data={"playlistid": "1", "songid": "2"})
@@ -1150,7 +1037,7 @@ def test_edit_playlist_change_song_order(client):
     assert songs[1]["songid"] == 1
 
 def test_edit_playlist_remove_song(client):
-    _create_user_song_and_playlist(client)
+    create_user_song_and_playlist(client)
     _test_upload_song(client, b"Successfully uploaded")
     client.post("/append-to-playlist", data={"playlistid": "1", "songid": "1"})
     client.post("/append-to-playlist", data={"playlistid": "1", "songid": "2"})
@@ -1163,26 +1050,26 @@ def test_edit_playlist_remove_song(client):
     assert songs[0]["songid"] == 2
 
 def test_edit_playlist_not_logged_in(client):
-    _create_user_song_and_playlist(client)
+    create_user_song_and_playlist(client)
     client.get("/logout")
 
     response = client.post("/edit-playlist/1", data={"name": "my playlist", "type": "private", "songids": ""})
     assert response.status_code == 401
 
 def test_edit_other_users_playlist(client):
-    _create_user_song_and_playlist(client)
-    _create_user(client, "user2", login=True)
+    create_user_song_and_playlist(client)
+    create_user(client, "user2", login=True)
 
     response = client.post("/edit-playlist/1", data={"name": "my playlist", "type": "private", "songids": ""})
     assert response.status_code == 403
 
 def test_edit_playlist_invalid_songid(client):
-    _create_user_and_playlist(client)
+    create_user_and_playlist(client)
     response = client.post("/edit-playlist/1", data={"name": "my playlist", "type": "private", "songids": "1"})
     assert response.status_code == 400
 
 def test_edit_playlist_invalid_playlistid(client):
-    _create_user_and_playlist(client)
+    create_user_and_playlist(client)
     response = client.post("/edit-playlist/2", data={"name": "my playlist", "type": "private", "songids": ""})
     assert response.status_code == 404
 
index 622e218f4bc511ca5ec34577dba8bcc8ebabe848..2f8388de2eaccc060339389b0bfbe375e696d961 100644 (file)
@@ -8,3 +8,20 @@ def login(session, username, password):
     response = session.post(url("/login"), data={"username": username, "password": password})
     response.raise_for_status()
 
+def post_signup_form(client, username, password, password_confirm=None):
+    if password_confirm is None:
+        password_confirm = password
+    return client.post(
+            "/signup",
+            data=dict(username=username, password=password, password_confirm=password_confirm))
+
+def create_user(client, username, password="password", login=False):
+    response = post_signup_form(client, username, password)
+    assert response.status_code == 302
+    assert response.headers["Location"] == "/login"
+
+    if login:
+        response = client.post("/login", data={"username": username, "password": password})
+        assert response.status_code == 302
+        assert response.headers["Location"] == f"/users/{username}"
+