From b69e9d925a83d501e1be1d6110a1414b30a91a04 Mon Sep 17 00:00:00 2001 From: moha Date: Tue, 21 Apr 2026 10:20:28 +0000 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20=E5=AD=98=E5=9C=A8=E3=81=97=E3=81=AA?= =?UTF-8?q?=E3=81=84=E3=83=AA=E3=82=B9=E3=83=88=E3=81=AB=E5=AF=BE=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=82=A2=E3=82=A4=E3=83=86=E3=83=A0=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E3=81=A7404=E3=82=92=E8=BF=94=E3=81=99=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handler.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/handler.go b/handler.go index b29cf04..3d2949d 100644 --- a/handler.go +++ b/handler.go @@ -142,6 +142,10 @@ func handleShowList(store *Store) http.HandlerFunc { func handleAddItem(store *Store) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { token := r.PathValue("token") + if store.GetList(token) == nil { + http.NotFound(w, r) + return + } name := strings.TrimSpace(r.FormValue("name")) if name == "" { http.Redirect(w, r, "/lists/"+token, http.StatusSeeOther) @@ -158,6 +162,10 @@ func handleAddItem(store *Store) http.HandlerFunc { func handleTogglePrepared(store *Store) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { token := r.PathValue("token") + if store.GetList(token) == nil { + http.NotFound(w, r) + return + } id := r.PathValue("id") store.TogglePrepared(token, id) http.Redirect(w, r, "/lists/"+token, http.StatusSeeOther) @@ -167,6 +175,10 @@ func handleTogglePrepared(store *Store) http.HandlerFunc { func handleToggleRequired(store *Store) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { token := r.PathValue("token") + if store.GetList(token) == nil { + http.NotFound(w, r) + return + } id := r.PathValue("id") store.ToggleRequired(token, id) http.Redirect(w, r, "/lists/"+token, http.StatusSeeOther) @@ -176,6 +188,10 @@ func handleToggleRequired(store *Store) http.HandlerFunc { func handleUpdateAssignee(store *Store) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { token := r.PathValue("token") + if store.GetList(token) == nil { + http.NotFound(w, r) + return + } id := r.PathValue("id") assignee := truncateRunes(strings.TrimSpace(r.FormValue("assignee")), maxAssigneeLen) store.UpdateAssignee(token, id, assignee) @@ -186,6 +202,10 @@ func handleUpdateAssignee(store *Store) http.HandlerFunc { func handleDeleteItem(store *Store) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { token := r.PathValue("token") + if store.GetList(token) == nil { + http.NotFound(w, r) + return + } id := r.PathValue("id") store.DeleteItem(token, id) http.Redirect(w, r, "/lists/"+token, http.StatusSeeOther) From 22bc9c95770299ce9574177d481f73783a919e6f Mon Sep 17 00:00:00 2001 From: moha Date: Tue, 21 Apr 2026 10:20:35 +0000 Subject: [PATCH 2/2] =?UTF-8?q?test:=20=E5=AD=98=E5=9C=A8=E3=81=97?= =?UTF-8?q?=E3=81=AA=E3=81=84=E3=83=AA=E3=82=B9=E3=83=88=E3=81=AB=E5=AF=BE?= =?UTF-8?q?=E3=81=99=E3=82=8B=E3=82=A2=E3=82=A4=E3=83=86=E3=83=A0=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E3=83=86=E3=82=B9=E3=83=885=E4=BB=B6=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handler_test.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/handler_test.go b/handler_test.go index 9b90454..785315c 100644 --- a/handler_test.go +++ b/handler_test.go @@ -503,6 +503,65 @@ func TestUpdateAssigneeTruncation(t *testing.T) { } } +func TestHandlerAddItemToNonExistentList(t *testing.T) { + mux, _ := setupTestServer() + form := url.Values{"name": {"テント"}, "assignee": {"太郎"}} + req := httptest.NewRequest("POST", "/lists/nonexistent-token/items", strings.NewReader(form.Encode())) + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + w := httptest.NewRecorder() + mux.ServeHTTP(w, req) + + if w.Code != http.StatusNotFound { + t.Fatalf("expected 404 for adding item to non-existent list, got %d", w.Code) + } +} + +func TestTogglePreparedOnNonExistentList(t *testing.T) { + mux, _ := setupTestServer() + req := httptest.NewRequest("POST", "/lists/nonexistent-token/items/1/toggle-prepared", nil) + w := httptest.NewRecorder() + mux.ServeHTTP(w, req) + + if w.Code != http.StatusNotFound { + t.Fatalf("expected 404 for toggle-prepared on non-existent list, got %d", w.Code) + } +} + +func TestToggleRequiredOnNonExistentList(t *testing.T) { + mux, _ := setupTestServer() + req := httptest.NewRequest("POST", "/lists/nonexistent-token/items/1/toggle-required", nil) + w := httptest.NewRecorder() + mux.ServeHTTP(w, req) + + if w.Code != http.StatusNotFound { + t.Fatalf("expected 404 for toggle-required on non-existent list, got %d", w.Code) + } +} + +func TestUpdateAssigneeOnNonExistentList(t *testing.T) { + mux, _ := setupTestServer() + form := url.Values{"assignee": {"花子"}} + req := httptest.NewRequest("POST", "/lists/nonexistent-token/items/1/assignee", strings.NewReader(form.Encode())) + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + w := httptest.NewRecorder() + mux.ServeHTTP(w, req) + + if w.Code != http.StatusNotFound { + t.Fatalf("expected 404 for update assignee on non-existent list, got %d", w.Code) + } +} + +func TestDeleteItemOnNonExistentList(t *testing.T) { + mux, _ := setupTestServer() + req := httptest.NewRequest("POST", "/lists/nonexistent-token/items/1/delete", nil) + w := httptest.NewRecorder() + mux.ServeHTTP(w, req) + + if w.Code != http.StatusNotFound { + t.Fatalf("expected 404 for delete item on non-existent list, got %d", w.Code) + } +} + func TestSecurityHeaders(t *testing.T) { mux, _ := setupTestServer() handler := securityHeaders(mux)