main
1package flux
2
3import (
4 "testing"
5 "time"
6)
7
8func TestGitLogParseLog(t *testing.T) {
9 g := &GitLogSource{
10 RepoPath: "/tmp/test",
11 BaseURL: "https://example.com",
12 }
13
14 output := `COMMIT abc12345 2026-04-01T10:00:00+02:00
15A posts/2026-04-01-new-post.html
16M articles/emacs.html
17
18COMMIT def67890 2026-03-15T09:00:00+02:00
19A articles/emacs.html
20A articles/containers.html
21`
22
23 entries, err := g.parseLog(output)
24 if err != nil {
25 t.Fatalf("parseLog: %v", err)
26 }
27
28 // Should have 3 entries (most recent event per file)
29 if len(entries) != 3 {
30 t.Fatalf("got %d entries, want 3", len(entries))
31 }
32
33 // posts/2026-04-01-new-post.html — added (A in first commit)
34 if entries[0].Kind != KindPageNew {
35 t.Errorf("entries[0].Kind = %s, want page-new", entries[0].Kind)
36 }
37
38 // articles/emacs.html — most recent is M, but first seen is def67890 (A), so updated
39 if entries[1].Kind != KindPageUpdated {
40 t.Errorf("entries[1].Kind = %s, want page-updated", entries[1].Kind)
41 }
42
43 // articles/containers.html — only appeared in def67890 as A
44 if entries[2].Kind != KindPageNew {
45 t.Errorf("entries[2].Kind = %s, want page-new", entries[2].Kind)
46 }
47}
48
49func TestGitLogShouldSkip(t *testing.T) {
50 g := &GitLogSource{
51 RepoPath: "/tmp/test",
52 BaseURL: "https://example.com",
53 }
54
55 tests := []struct {
56 file string
57 skip bool
58 }{
59 // Content — keep
60 {"posts/hello.html", false},
61 {"articles/emacs.html", false},
62 {"2022/digital-garden.html", false},
63 {"about.html", false},
64 {"emacs/org_mode.html", false},
65 {"tekton/build-your-ci.html", false},
66 {"posts/index.html", false},
67 // Infrastructure — skip
68 {"index.html", true},
69 {"sitemap.html", true},
70 {"articles/sitemap.html", true},
71 {"flux/index.html", true},
72 {"flux/2026.html", true},
73 {"build/index.html", true},
74 {"site/about.html", true},
75 {"tufte.html", true},
76 {"css.html", true},
77 {"articles/data/7a/f3b3f4/some.html", true},
78 {"assets/.fancyindex/header.html", true},
79 }
80
81 for _, tt := range tests {
82 got := g.shouldSkip(tt.file)
83 if got != tt.skip {
84 t.Errorf("shouldSkip(%q) = %v, want %v", tt.file, got, tt.skip)
85 }
86 }
87}
88
89func TestTitleFromFilename(t *testing.T) {
90 tests := []struct {
91 file string
92 want string
93 }{
94 {"posts/2020-04-15-emacs-bankruptcy-is-fun.html", "Emacs bankruptcy is fun"},
95 {"articles/emacs.html", "Emacs"},
96 {"articles/kubernetes_on_nixos.html", "Kubernetes on nixos"},
97 }
98
99 for _, tt := range tests {
100 got := titleFromFilename(tt.file)
101 if got != tt.want {
102 t.Errorf("titleFromFilename(%q) = %q, want %q", tt.file, got, tt.want)
103 }
104 }
105}
106
107func TestGitLogFileToURL(t *testing.T) {
108 g := &GitLogSource{BaseURL: "https://vincent.demeester.fr"}
109
110 got := g.fileToURL("articles/emacs.html")
111 want := "https://vincent.demeester.fr/articles/emacs.html"
112 if got != want {
113 t.Errorf("fileToURL = %q, want %q", got, want)
114 }
115}
116
117func TestGitLogFetchReal(t *testing.T) {
118 // Only run if we're in the actual www repo
119 g := &GitLogSource{
120 RepoPath: ".",
121 BaseURL: "https://vincent.demeester.fr",
122 }
123
124 // Quick check: is this a git repo?
125 _, err := g.Fetch(t.Context(), time.Now().AddDate(0, -1, 0))
126 if err != nil {
127 t.Skipf("not in a git repo or git unavailable: %v", err)
128 }
129}