]> littlesong.place Git - littlesongplace.git/commitdiff
Implement event update/delete
authorChris Fulljames <christianfulljames@gmail.com>
Sat, 12 Apr 2025 17:08:24 +0000 (13:08 -0400)
committerChris Fulljames <christianfulljames@gmail.com>
Sat, 12 Apr 2025 17:08:24 +0000 (13:08 -0400)
src/littlesongplace/jams.py
src/littlesongplace/templates/jam-event.html
test/test_jams.py

index ebc17e2eb7f621a46f92f61489b7dfdf99319bc7..96dd6d5d8b3bf5182fdddbdc676853d23fede938 100644 (file)
@@ -55,7 +55,7 @@ def create():
 
 @bp.get("/<int:jamid>")
 def jam(jamid):
-    jam = get_jam_by_id(jamid)
+    jam = _get_jam_by_id(jamid)
     # Show the main jam page
     return render_template("jam.html", jam=jam)
 
@@ -114,7 +114,7 @@ def events_create(jamid):
 @bp.get("/<int:jamid>/events/<int:eventid>")
 def events_view(jamid, eventid):
     # Show the event page
-    jam = get_jam_by_id(jamid)
+    jam = _get_jam_by_id(jamid)
     try:
         event = next(e for e in jam.events if e.eventid == eventid)
     except StopIteration:
@@ -128,7 +128,23 @@ def events_view(jamid, eventid):
 @jam_owner_only
 def events_update(jamid, eventid):
     # Update an event with the new form data
-    ...
+    title = request.form["title"]
+    description = request.form["description"]
+    startdate = request.form["startdate"]
+    enddate = request.form["enddate"]
+    _validate_timestamp(startdate)
+    _validate_timestamp(enddate)
+    db.query(
+            """
+            UPDATE jam_events
+            SET title = ?, description = ?, startdate = ?, enddate = ?
+            WHERE eventid = ? AND jamid = ?
+            RETURNING *
+            """,
+            [title, description, startdate, enddate, eventid, jamid],
+            expect_one=True)
+    db.commit()
+    return redirect(url_for("jams.events_view", jamid=jamid, eventid=eventid))
 
 
 @bp.get("/<int:jamid>/events/<int:eventid>/delete")
@@ -136,9 +152,16 @@ def events_update(jamid, eventid):
 @jam_owner_only
 def events_delete(jamid, eventid):
     # Delete an event, redirect to list of all events
-    ...
+    db.query(
+            """
+            DELETE FROM jam_events
+            WHERE eventid = ? AND jamid = ?
+            RETURNING *
+            """, [eventid, jamid], expect_one=True)
+    return redirect(url_for("jams.jam", jamid=jamid))
+
 
-def get_jam_by_id(jamid):
+def _get_jam_by_id(jamid):
     row = db.query(
             """
             SELECT * FROM jams
@@ -147,6 +170,13 @@ def get_jam_by_id(jamid):
             """, [jamid], expect_one=True)
     return Jam.from_row(row)
 
+
+def _validate_timestamp(timestamp):
+    try:
+        datetime.fromisoformat(timestamp)
+    except ValueError:
+        abort(400)
+
 @dataclass
 class Jam:
     jamid: int
@@ -215,8 +245,8 @@ class JamEvent:
                 threadid=row["threadid"],
                 created=datetime.fromisoformat(row["created"]),
                 title=row["title"],
-                startdate=datetime.fromisoformat(row["startdate"]) if "startdate" in row else None,
-                enddate=datetime.fromisoformat(row["enddate"]) if "enddate" in row else None,
+                startdate=datetime.fromisoformat(row["startdate"]) if row["startdate"] else None,
+                enddate=datetime.fromisoformat(row["enddate"]) if row["enddate"] else None,
                 description=sanitize_user_text(row["description"] or ""),
                 jam_title=row["jam_title"],
                 jam_ownername=row["jam_ownername"],
index 8dad7a7993faf03fb0e51ca00fd8b3ef2c999cf8..d67660ec080d6c06eb01117f8ebe6ed8db26b2d8 100644 (file)
         <br/>
     {% if event.startdate %}
     <strong>Start Date:</strong>
-        {{ event.startdate.aslocaltime().strftime("%Y-%m-%d @ %H:%M") }}
+        {{ event.startdate.astimezone().strftime("%Y-%m-%d @ %I:%M%p") }}
         <br/>
     {% endif %}
     {% if event.enddate %}
     <strong>End Date:</strong>
-        {{ event.enddate.aslocaltime().strftime("%Y-%m-%d @ %H:%M") }}
+        {{ event.enddate.astimezone().strftime("%Y-%m-%d @ %I:%M%p") }}
     {% endif %}
 </div>
 
index 58a51daac8a53f0ad046f66f1c072db01413eb6b..46daefa47912d1e4703eeb9bcab22141612148ba 100644 (file)
@@ -1,3 +1,5 @@
+from datetime import datetime, timezone
+
 import pytest
 
 from .utils import create_user
@@ -8,10 +10,15 @@ def user(client):
     yield "user"
 
 @pytest.fixture
-def jam(client):
+def jam(client, user):
     client.get("/jams/create")
     return 1
 
+@pytest.fixture
+def event(client, jam):
+    client.get(f"/jams/{jam}/events/create")
+    return 1
+
 # Jams #########################################################################
 
 def test_view_invalid_jam(client):
@@ -107,13 +114,91 @@ def test_create_event_on_other_users_jam(client, user, jam):
     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
+def _to_utc(timestamp):
+    return (datetime
+            .fromisoformat(timestamp)
+            .astimezone(timezone.utc)
+            .isoformat())
+
+def _get_event_data(**kwargs):
+    event_data = {
+            "title": "Event Title",
+            "description": "description of the event",
+            "startdate": _to_utc("2040-01-01T00:00:00"),
+            "enddate": _to_utc("2040-01-02T00:00:00"),
+    }
+    for k, v in kwargs.items():
+        event_data[k] = v
+    return event_data
+
+def test_update_event(client, user, jam, event):
+    response = client.post(
+            f"/jams/{jam}/events/{event}/update",
+            data=_get_event_data(), follow_redirects=True)
+    assert response.request.path == f"/jams/{jam}/events/{event}"
+    assert b"Event Title" in response.data
+    assert b"description of the event" in response.data
+    assert b"2040-01-01" in response.data
+    assert b"2040-01-02" in response.data
+
+def test_update_event_invalid_eventid(client, user, jam):
+    response = client.post(f"/jams/{jam}/events/1/update", data=_get_event_data())
+    assert response.status_code == 404
+
+def test_update_event_invalid_jamid(client, user, event):
+    response = client.post(f"/jams/2/events/{event}/update", data=_get_event_data())
+    assert response.status_code == 404
+
+def test_update_event_not_logged_in(client, user, jam, event):
+    response = client.get("/logout")
+    response = client.post(
+            f"/jams/{jam}/events/{event}/update",
+            data=_get_event_data(),
+            follow_redirects=True)
+    assert response.request.path == "/login"
+
+def test_update_event_other_users_jam(client, user, jam, event):
+    create_user(client, "otheruser", login=True)
+    response = client.post(
+            f"/jams/{jam}/events/{event}/update",
+            data=_get_event_data(),
+            follow_redirects=True)
+    assert response.status_code == 403
+
+def test_update_event_invalid_startdate(client, user, jam, event):
+    response = client.post(
+            f"/jams/{jam}/events/{event}/update",
+            data=_get_event_data(startdate="notadate"),
+            follow_redirects=True)
+    assert response.status_code == 400
+
+def test_update_event_invalid_enddate(client, user, jam, event):
+    response = client.post(
+            f"/jams/{jam}/events/{event}/update",
+            data=_get_event_data(enddate="notadate"),
+            follow_redirects=True)
+    assert response.status_code == 400
+
+def test_delete_event(client, user, jam, event):
+    response = client.get(f"/jams/{jam}/events/{event}/delete", follow_redirects=True)
+    assert response.request.path == f"/jams/{jam}"
+    assert b"Event Title" not in response.data
 
-# Delete event
-# Delete event not logged in
-# Delete event invalid event
-# Delete event other users jam
+def test_delete_event_not_logged_in(client, user, jam, event):
+    client.get("/logout")
+    response = client.get(f"/jams/{jam}/events/{event}/delete", follow_redirects=True)
+    assert response.request.path == "/login"
+
+def test_delete_event_invalid_jamid(client, user, jam, event):
+    response = client.get(f"/jams/2/events/{event}/delete", follow_redirects=True)
+    assert response.status_code == 404
+
+def test_delete_event_invalid_eventid(client, user, jam, event):
+    response = client.get(f"/jams/{jam}/events/2/delete", follow_redirects=True)
+    assert response.status_code == 404
+
+def test_delete_event_other_users_jam(client, user, jam, event):
+    create_user(client, "otheruser", login=True)
+    response = client.get(f"/jams/{jam}/events/{event}/delete", follow_redirects=True)
+    assert response.status_code == 403