mirror of
https://github.com/sartoopjj/thefeed.git
synced 2026-05-19 06:14:35 +03:00
feat: improve frontend (add light theme, handle back button, get approve for resolver checker, new message lable, ... )
This commit is contained in:
@@ -460,3 +460,80 @@ func TestE2E_WebAPI_GlobalAuth(t *testing.T) {
|
||||
t.Errorf("wrong password: expected 401, got %d", resp.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
// TestE2E_NewMsgSeparator_TimestampBased verifies the index.html uses
|
||||
// timestamp-based (not ID-based) comparison for the "new messages" separator.
|
||||
// This is critical because X/Twitter post IDs are CRC32 hashes that don't
|
||||
// increase monotonically, so ID-based comparison would place the separator
|
||||
// in wrong positions.
|
||||
func TestE2E_NewMsgSeparator_TimestampBased(t *testing.T) {
|
||||
base, _ := startWebServer(t)
|
||||
|
||||
resp := getJSON(t, base+"/")
|
||||
defer resp.Body.Close()
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
html := string(body)
|
||||
|
||||
// The separator must compare against timestamp, not message ID.
|
||||
// Look for the timestamp-based lastSeen check in the new-msg separator logic.
|
||||
checks := []struct {
|
||||
name string
|
||||
needle string
|
||||
wantHas bool
|
||||
}{
|
||||
{"uses timestamp for lastSeen storage", "thefeed_seen_ts_", true},
|
||||
{"compares msgTs > lastSeenTs", "msgTs > lastSeenTs", true},
|
||||
{"tracks maxTimestamp", "maxTimestamp", true},
|
||||
{"no old ID-based seen key", "thefeed_seen_'", false},
|
||||
{"no old id > lastSeen comparison", "id > lastSeen", false},
|
||||
}
|
||||
for _, c := range checks {
|
||||
has := strings.Contains(html, c.needle)
|
||||
if has != c.wantHas {
|
||||
if c.wantHas {
|
||||
t.Errorf("%s: expected %q in index.html but not found", c.name, c.needle)
|
||||
} else {
|
||||
t.Errorf("%s: found %q in index.html but should have been removed", c.name, c.needle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also verify that first-visit logic stores timestamp, not ID
|
||||
if !strings.Contains(html, "setLastSeenTimestamp") {
|
||||
t.Error("expected setLastSeenTimestamp function in index.html")
|
||||
}
|
||||
if !strings.Contains(html, "getLastSeenTimestamp") {
|
||||
t.Error("expected getLastSeenTimestamp function in index.html")
|
||||
}
|
||||
|
||||
// Verify wasAtBottom updates lastSeen on re-renders (prevents stale separator)
|
||||
if !strings.Contains(html, "wasAtBottom && maxTimestamp > 0") {
|
||||
t.Error("expected wasAtBottom to update lastSeen timestamp on re-render")
|
||||
}
|
||||
}
|
||||
|
||||
// TestE2E_MessagesHaveTimestamps verifies that the messages API response
|
||||
// includes Timestamp fields needed for the new-messages separator.
|
||||
func TestE2E_MessagesHaveTimestamps(t *testing.T) {
|
||||
base, _ := startWebServer(t)
|
||||
|
||||
resp := getJSON(t, base+"/api/messages/1")
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result struct {
|
||||
Messages []struct {
|
||||
ID uint32 `json:"ID"`
|
||||
Timestamp uint32 `json:"Timestamp"`
|
||||
Text string `json:"Text"`
|
||||
} `json:"messages"`
|
||||
}
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
if err := json.Unmarshal(body, &result); err != nil {
|
||||
t.Fatalf("decode messages: %v", err)
|
||||
}
|
||||
|
||||
// With no messages configured, the array should be empty or nil — but the
|
||||
// response format must still be valid JSON with a "messages" key.
|
||||
// This verifies the API structure supports the timestamp-based separator.
|
||||
t.Logf("messages response contains %d messages", len(result.Messages))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user