]> littlesong.place Git - littlesongplace.git/commitdiff
Implement event create/view
authorChris Fulljames <christianfulljames@gmail.com>
Sat, 12 Apr 2025 15:54:02 +0000 (11:54 -0400)
committerChris Fulljames <christianfulljames@gmail.com>
Sat, 12 Apr 2025 15:54:02 +0000 (11:54 -0400)
src/littlesongplace/comments.py
src/littlesongplace/jams.py
src/littlesongplace/templates/jam-event.html
test/test_jams.py

index 5e47b93d4c8de93e205b810f2882a9024838eaac..69320a65a76e67267ff1e600b96bc10deb246df4 100644 (file)
@@ -12,6 +12,7 @@ class ThreadType(enum.IntEnum):
     SONG = 0
     PROFILE = 1
     PLAYLIST = 2
+    JAM_EVENT = 3
 
 class ObjectType(enum.IntEnum):
     COMMENT = 0
index 75a143c81bfec72b857efff4add6e647d46c3542..ebc17e2eb7f621a46f92f61489b7dfdf99319bc7 100644 (file)
@@ -4,7 +4,7 @@ from datetime import datetime, timezone
 
 from flask import abort, Blueprint, g, redirect, render_template, request, url_for
 
-from . import auth, db
+from . import auth, comments, db
 from .sanitize import sanitize_user_text
 
 bp = Blueprint("jams", __name__, url_prefix="/jams")
@@ -55,14 +55,7 @@ def create():
 
 @bp.get("/<int:jamid>")
 def jam(jamid):
-    row = db.query(
-            """
-            SELECT * FROM jams
-            INNER JOIN users ON jams.ownerid = users.userid
-            WHERE jamid = ?
-            """, [jamid], expect_one=True)
-
-    jam = Jam.from_row(row)
+    jam = get_jam_by_id(jamid)
     # Show the main jam page
     return render_template("jam.html", jam=jam)
 
@@ -104,13 +97,30 @@ def delete(jamid):
 @jam_owner_only
 def events_create(jamid):
     # Create a new event and redirect to the edit form
-    ...
+    threadid = comments.create_thread(comments.ThreadType.JAM_EVENT, g.userid)
+    timestamp = datetime.now(timezone.utc).isoformat()
+    row = db.query(
+            """
+            INSERT INTO jam_events (jamid, threadid, created, title)
+            VALUES (?, ?, ?, ?)
+            RETURNING eventid
+            """, [jamid, threadid, timestamp, "New Event"], one=True)
+    db.commit()
+
+    eventid = row["eventid"]
+    return redirect(url_for("jams.events_view", jamid=jamid, eventid=eventid))
 
 
 @bp.get("/<int:jamid>/events/<int:eventid>")
 def events_view(jamid, eventid):
     # Show the event page
-    ...
+    jam = get_jam_by_id(jamid)
+    try:
+        event = next(e for e in jam.events if e.eventid == eventid)
+    except StopIteration:
+        abort(404)  # No event with this ID
+
+    return render_template("jam-event.html", jam=jam, event=event)
 
 
 @bp.post("/<int:jamid>/events/<int:eventid>/update")
@@ -128,6 +138,14 @@ def events_delete(jamid, eventid):
     # Delete an event, redirect to list of all events
     ...
 
+def get_jam_by_id(jamid):
+    row = db.query(
+            """
+            SELECT * FROM jams
+            INNER JOIN users ON jams.ownerid = users.userid
+            WHERE jamid = ?
+            """, [jamid], expect_one=True)
+    return Jam.from_row(row)
 
 @dataclass
 class Jam:
@@ -197,8 +215,8 @@ class JamEvent:
                 threadid=row["threadid"],
                 created=datetime.fromisoformat(row["created"]),
                 title=row["title"],
-                startdate=datetime.fromisoformat(row["startdate"]),
-                enddate=datetime.fromisoformat(row["enddate"]),
+                startdate=datetime.fromisoformat(row["startdate"]) if "startdate" in row else None,
+                enddate=datetime.fromisoformat(row["enddate"]) if "enddate" in row else None,
                 description=sanitize_user_text(row["description"] or ""),
                 jam_title=row["jam_title"],
                 jam_ownername=row["jam_ownername"],
index 06c4ca10dedf2944c69c932cf3c0d6343b7a1f46..8dad7a7993faf03fb0e51ca00fd8b3ef2c999cf8 100644 (file)
     <strong>Host:</strong>
         <a href="/users/{{ jam.ownername }}" class="profile-link">{{ jam.ownername }}</a>
         <br/>
+    {% if event.startdate %}
     <strong>Start Date:</strong>
         {{ event.startdate.aslocaltime().strftime("%Y-%m-%d @ %H:%M") }}
         <br/>
+    {% endif %}
+    {% if event.enddate %}
     <strong>End Date:</strong>
         {{ event.enddate.aslocaltime().strftime("%Y-%m-%d @ %H:%M") }}
+    {% endif %}
 </div>
 
 <div class="jam-description">
@@ -31,6 +35,7 @@
 {% include "song-list.html" %}
 
 <h2>Comments</h2>
+{% from "comment-thread.html" import comment_thread %}
 {{ comment_thread(event.threadid, session['userid'], jam.ownerid, event.comments) }}
 
 {% endblock %}
index e415101379e4f8384a05762173b2e73315da08df..58a51daac8a53f0ad046f66f1c072db01413eb6b 100644 (file)
@@ -12,6 +12,8 @@ def jam(client):
     client.get("/jams/create")
     return 1
 
+# Jams #########################################################################
+
 def test_view_invalid_jam(client):
     response = client.get("/jams/1")
     assert response.status_code == 404
@@ -22,6 +24,10 @@ def test_create_jam(client, user):
     assert response.request.path == "/jams/1"
     assert b"New Jam" in response.data
 
+def test_create_jam_not_logged_in(client):
+    response = client.get("/jams/create", follow_redirects=True)
+    assert response.request.path == "/login"
+
 def test_jams_list(client, user, jam):
     response = client.get("/jams")
     assert response.status_code == 200
@@ -38,6 +44,10 @@ def test_update_jam(client, user, jam):
     assert b"Coolest Jam" in response.data
     assert b"pb and jam" in response.data
 
+def test_update_jam_not_logged_in(client):
+    response = client.post("/jams/1/update", follow_redirects=True)
+    assert response.request.path == "/login"
+
 def test_update_invalid_jam(client, user):
     response = client.post(
             "/jams/1/update",
@@ -59,6 +69,10 @@ def test_delete_jam(client, user, jam):
     response = client.get(f"/jams/{jam}")
     assert response.status_code == 404
 
+def test_delete_jam_not_logged_in(client):
+    response = client.get("/jams/1/delete", follow_redirects=True)
+    assert response.request.path == "/login"
+
 def test_delete_invalid_jam(client, user):
     response = client.get("/jams/1/delete")
     assert response.status_code == 404
@@ -67,3 +81,39 @@ def test_delete_other_users_jam(client, user, jam):
     create_user(client, "otheruser", login=True)
     response = client.get(f"/jams/{jam}/delete")
     assert response.status_code == 403
+
+# Jam Events ###################################################################
+
+def test_view_event_invalid_jamid(client, user):
+    response = client.get("/jams/1/events/1")
+    assert response.status_code == 404
+
+def test_view_event_invalid_eventid(client, user, jam):
+    response = client.get(f"/jams/{jam}/events/1")
+    assert response.status_code == 404
+
+def test_create_event(client, user, jam):
+    response = client.get(f"/jams/{jam}/events/create", follow_redirects=True)
+    assert response.request.path == f"/jams/{jam}/events/1"
+    assert b"New Event" in response.data
+
+def test_create_event_not_logged_in(client, user, jam):
+    response = client.get("/logout")
+    response = client.get(f"/jams/{jam}/events/create", follow_redirects=True)
+    assert response.request.path == "/login"
+
+def test_create_event_on_other_users_jam(client, user, jam):
+    create_user(client, "otheruser", login=True)
+    response = client.get(f"/jams/{jam}/events/create", follow_redirects=True)
+    assert response.status_code == 403
+
+# Update event
+# Update event invalid event
+# Update event not logged in
+# Update event other users jam
+
+# Delete event
+# Delete event not logged in
+# Delete event invalid event
+# Delete event other users jam
+