Go · 2174 bytes Raw Blame History
1 // SPDX-License-Identifier: AGPL-3.0-or-later
2
3 package handlers
4
5 import (
6 "net/http/httptest"
7 "net/url"
8 "testing"
9 "time"
10
11 "github.com/tenseleyFlow/shithub/internal/social"
12 )
13
14 func TestExploreFeedFragmentRequestRequiresHTMXAndCursor(t *testing.T) {
15 t.Parallel()
16
17 req := httptest.NewRequest("GET", "/explore?before=2026-05-12T00:00:00Z~42", nil)
18 if isExploreFeedFragmentRequest(req) {
19 t.Fatal("plain cursor request should stay a full-page no-JS fallback")
20 }
21
22 req.Header.Set("HX-Request", "true")
23 if !isExploreFeedFragmentRequest(req) {
24 t.Fatal("HTMX cursor request should render feed fragment")
25 }
26
27 req = httptest.NewRequest("GET", "/explore", nil)
28 req.Header.Set("HX-Request", "true")
29 if isExploreFeedFragmentRequest(req) {
30 t.Fatal("HTMX first-page request should not render feed fragment")
31 }
32 }
33
34 func TestFeedPageForBuildsNextCursorFromLastDisplayedItem(t *testing.T) {
35 t.Parallel()
36
37 req := httptest.NewRequest("GET", "/explore?tab=activity", nil)
38 base := time.Date(2026, 5, 12, 14, 0, 0, 0, time.UTC)
39 items := make([]social.FeedItem, 0, feedDisplayLimit+1)
40 for i := int32(0); i < feedDisplayLimit+1; i++ {
41 items = append(items, social.FeedItem{
42 ID: int64(1000 + i),
43 CreatedAt: base.Add(-time.Duration(i) * time.Minute),
44 })
45 }
46
47 got, hasNext, nextURL := feedPageFor(req, func(cursor social.FeedCursor, limit int32) ([]social.FeedItem, error) {
48 if !cursor.BeforeCreatedAt.IsZero() || cursor.BeforeID != 0 {
49 t.Fatalf("first page cursor = %+v, want zero", cursor)
50 }
51 if limit != feedDisplayLimit+1 {
52 t.Fatalf("limit = %d, want %d", limit, feedDisplayLimit+1)
53 }
54 return items, nil
55 })
56
57 if len(got) != int(feedDisplayLimit) {
58 t.Fatalf("display item count = %d, want %d", len(got), feedDisplayLimit)
59 }
60 if !hasNext {
61 t.Fatal("hasNext = false, want true")
62 }
63 wantCursor := got[len(got)-1].CreatedAt.UTC().Format(time.RFC3339Nano) + "~" + "1019"
64 parsed, err := url.Parse(nextURL)
65 if err != nil {
66 t.Fatalf("parse nextURL: %v", err)
67 }
68 if parsed.Query().Get("tab") != "activity" || parsed.Query().Get("before") != wantCursor {
69 t.Fatalf("nextURL = %q, want preserved query and cursor %q", nextURL, wantCursor)
70 }
71 }
72