feat(web): add status endpoint for archive, finish, and restore
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -599,3 +599,79 @@ func TestRecentStripExcludesArchivedAndFinished(t *testing.T) {
|
||||
t.Fatal("recent strip dropped the reading series")
|
||||
}
|
||||
}
|
||||
|
||||
func postStatus(t *testing.T, srv http.Handler, cfg Config, key, status string) *httptest.ResponseRecorder {
|
||||
t.Helper()
|
||||
form := url.Values{"status": {status}}
|
||||
req := httptest.NewRequest(http.MethodPost, "/ui/bookmarks/"+key+"/status",
|
||||
strings.NewReader(form.Encode()))
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.AddCookie(sessionCookie(t, cfg))
|
||||
rr := httptest.NewRecorder()
|
||||
srv.ServeHTTP(rr, req)
|
||||
return rr
|
||||
}
|
||||
|
||||
func TestUIStatusSetsBucket(t *testing.T) {
|
||||
cfg := webConfig()
|
||||
srv, store := newWebTestServer(t, cfg)
|
||||
seedStatusRows(t, store)
|
||||
|
||||
for _, want := range []string{statusArchived, statusFinished, statusReading} {
|
||||
if rr := postStatus(t, srv, cfg, "asura:reading", want); rr.Code != http.StatusOK {
|
||||
t.Fatalf("set %s: status = %d, body %s", want, rr.Code, rr.Body.String())
|
||||
}
|
||||
b, ok, err := store.Get("asura:reading")
|
||||
if err != nil || !ok {
|
||||
t.Fatalf("Get: ok=%v err=%v", ok, err)
|
||||
}
|
||||
if b.Status != want {
|
||||
t.Fatalf("stored status = %q, want %q", b.Status, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUIStatusRejectsUnknownValue(t *testing.T) {
|
||||
cfg := webConfig()
|
||||
srv, store := newWebTestServer(t, cfg)
|
||||
seedStatusRows(t, store)
|
||||
|
||||
if rr := postStatus(t, srv, cfg, "asura:reading", "dropped"); rr.Code != http.StatusBadRequest {
|
||||
t.Fatalf("status = %d, want 400", rr.Code)
|
||||
}
|
||||
b, _, _ := store.Get("asura:reading")
|
||||
if b.Status != statusReading {
|
||||
t.Fatalf("stored status = %q, want it untouched", b.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUIStatusRequiresSession(t *testing.T) {
|
||||
srv, store := newWebTestServer(t, webConfig())
|
||||
seedStatusRows(t, store)
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "/ui/bookmarks/asura:reading/status",
|
||||
strings.NewReader("status=archived"))
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
rr := httptest.NewRecorder()
|
||||
srv.ServeHTTP(rr, req)
|
||||
|
||||
if rr.Code != http.StatusUnauthorized {
|
||||
t.Fatalf("status = %d, want 401", rr.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUIStatusDoesNotReorderList(t *testing.T) {
|
||||
cfg := webConfig()
|
||||
srv, store := newWebTestServer(t, cfg)
|
||||
seedStatusRows(t, store)
|
||||
|
||||
before, _, _ := store.Get("asura:reading")
|
||||
time.Sleep(2 * time.Millisecond)
|
||||
if rr := postStatus(t, srv, cfg, "asura:reading", statusArchived); rr.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d", rr.Code)
|
||||
}
|
||||
after, _, _ := store.Get("asura:reading")
|
||||
if after.UpdatedAt != before.UpdatedAt {
|
||||
t.Fatalf("UpdatedAt moved %d -> %d", before.UpdatedAt, after.UpdatedAt)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user