|
1 | 1 | package app |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "fmt" |
4 | 5 | "net/http/httptest" |
5 | 6 | "os" |
6 | 7 | "path/filepath" |
7 | 8 | "strings" |
8 | 9 | "testing" |
| 10 | + "time" |
9 | 11 | ) |
10 | 12 |
|
11 | 13 | func TestBacklinksAndSearch(t *testing.T) { |
@@ -61,6 +63,55 @@ func TestSearchRanksTitleMatchesAndHighlightsSnippets(t *testing.T) { |
61 | 63 | } |
62 | 64 | } |
63 | 65 |
|
| 66 | +func TestEmptySearchPageShowsHundredMostRecentlyModifiedNotes(t *testing.T) { |
| 67 | + v := makeVault(t) |
| 68 | + base := time.Date(2026, 5, 30, 12, 0, 0, 0, time.UTC) |
| 69 | + for i := 0; i < 105; i++ { |
| 70 | + rel := fmt.Sprintf("Recent/Note-%03d.md", i) |
| 71 | + p := filepath.Join(v.Root, filepath.FromSlash(rel)) |
| 72 | + if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil { |
| 73 | + t.Fatal(err) |
| 74 | + } |
| 75 | + if err := os.WriteFile(p, []byte(fmt.Sprintf("# Recent %03d\n", i)), 0o644); err != nil { |
| 76 | + t.Fatal(err) |
| 77 | + } |
| 78 | + mt := base.Add(time.Duration(i) * time.Minute) |
| 79 | + if err := os.Chtimes(p, mt, mt); err != nil { |
| 80 | + t.Fatal(err) |
| 81 | + } |
| 82 | + } |
| 83 | + |
| 84 | + s := NewServer(v, "", "") |
| 85 | + w := httptest.NewRecorder() |
| 86 | + r := httptest.NewRequest("GET", "/_search", nil) |
| 87 | + s.ServeHTTP(w, r) |
| 88 | + body := w.Body.String() |
| 89 | + |
| 90 | + for _, want := range []string{ |
| 91 | + `<h2>Recently modified</h2>`, |
| 92 | + `Showing the 100 latest Markdown files by modification date.`, |
| 93 | + `Recent 104`, |
| 94 | + `Recent/Note-104.md`, |
| 95 | + } { |
| 96 | + if !strings.Contains(body, want) { |
| 97 | + t.Fatalf("empty search page missing %q in:\n%s", want, body) |
| 98 | + } |
| 99 | + } |
| 100 | + recentSectionStart := strings.Index(body, `class="recent-search-results card"`) |
| 101 | + if recentSectionStart < 0 { |
| 102 | + t.Fatalf("missing recent results section in:\n%s", body) |
| 103 | + } |
| 104 | + recentSection := body[recentSectionStart:] |
| 105 | + if strings.Contains(recentSection, `<small>Recent/Note-004.md`) { |
| 106 | + t.Fatalf("empty search page should cap recent notes to 100; oldest extra note leaked in recent section:\n%s", recentSection) |
| 107 | + } |
| 108 | + newest := strings.Index(recentSection, `Recent/Note-104.md`) |
| 109 | + older := strings.Index(recentSection, `Recent/Note-103.md`) |
| 110 | + if newest < 0 || older < 0 || newest > older { |
| 111 | + t.Fatalf("recent notes should be sorted by descending mtime; got indexes newest=%d older=%d", newest, older) |
| 112 | + } |
| 113 | +} |
| 114 | + |
64 | 115 | func TestSearchQuerySyntaxFiltersTagsPathsTitlesFrontmatterAndPhrases(t *testing.T) { |
65 | 116 | v := makeVault(t) |
66 | 117 | searcher := NewSearcher(v) |
|
0 commit comments