summaryrefslogtreecommitdiff
path: root/internal/handlers/handlers_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/handlers/handlers_test.go')
-rw-r--r--internal/handlers/handlers_test.go87
1 files changed, 65 insertions, 22 deletions
diff --git a/internal/handlers/handlers_test.go b/internal/handlers/handlers_test.go
index 1842c38..0ad36b2 100644
--- a/internal/handlers/handlers_test.go
+++ b/internal/handlers/handlers_test.go
@@ -1901,6 +1901,18 @@ func TestHandleTimeline_RendersDataToTemplate(t *testing.T) {
}
}
+// assertTemplateContains reads a template file and asserts it contains the expected string.
+func assertTemplateContains(t *testing.T, templatePath, expected, errMsg string) {
+ t.Helper()
+ content, err := os.ReadFile(templatePath)
+ if err != nil {
+ t.Skipf("Cannot read template file: %v", err)
+ }
+ if !strings.Contains(string(content), expected) {
+ t.Error(errMsg)
+ }
+}
+
// =============================================================================
// Dashboard Content Verification Tests
// =============================================================================
@@ -1945,34 +1957,18 @@ func TestHandleDashboard_ContainsSettingsLink(t *testing.T) {
// contains a link to /settings. This catches regressions where the settings
// button is accidentally removed.
func TestDashboardTemplate_HasSettingsLink(t *testing.T) {
- // Read the actual template file and verify it contains a settings link
- content, err := os.ReadFile("../../web/templates/index.html")
- if err != nil {
- t.Skipf("Cannot read template file (running from unexpected directory): %v", err)
- }
-
- templateStr := string(content)
-
- if !strings.Contains(templateStr, `href="/settings"`) {
- t.Error("index.html must contain a link to /settings (settings button missing from UI)")
- }
+ assertTemplateContains(t, "../../web/templates/index.html",
+ `href="/settings"`,
+ "index.html must contain a link to /settings (settings button missing from UI)")
}
// TestSettingsTemplate_HasCSRFToken verifies the settings page exposes a CSRF
// token in a meta tag so that JavaScript (e.g. passkey registration) can include
// it in POST requests. Without this, passkey registration fails with 403.
func TestSettingsTemplate_HasCSRFToken(t *testing.T) {
- content, err := os.ReadFile("../../web/templates/settings.html")
- if err != nil {
- t.Skipf("Cannot read template file: %v", err)
- }
- tmpl := string(content)
-
- // The template must include a meta tag or hidden input with the Go template
- // variable .CSRFToken so JS can retrieve it
- if !strings.Contains(tmpl, ".CSRFToken") {
- t.Error("settings.html must expose .CSRFToken (e.g. via meta tag) for JavaScript passkey registration")
- }
+ assertTemplateContains(t, "../../web/templates/settings.html",
+ ".CSRFToken",
+ "settings.html must expose .CSRFToken (e.g. via meta tag) for JavaScript passkey registration")
}
// TestHandleSettingsPage_PassesCSRFToken verifies the settings handler includes
@@ -2007,6 +2003,53 @@ func TestHandleSettingsPage_PassesCSRFToken(t *testing.T) {
}
}
+// TestHandleDashboard_PassesBuildVersion verifies the dashboard handler includes
+// BuildVersion in the template data.
+func TestHandleDashboard_PassesBuildVersion(t *testing.T) {
+ db, cleanup := setupTestDB(t)
+ defer cleanup()
+
+ mockTodoist := &mockTodoistClient{}
+ mockTrello := &mockTrelloClient{}
+ renderer := NewMockRenderer()
+
+ h := &Handler{
+ store: db,
+ todoistClient: mockTodoist,
+ trelloClient: mockTrello,
+ config: &config.Config{CacheTTLMinutes: 5},
+ renderer: renderer,
+ BuildVersion: "abc123",
+ }
+
+ req := httptest.NewRequest("GET", "/", nil)
+ w := httptest.NewRecorder()
+
+ h.HandleDashboard(w, req)
+
+ if w.Code != http.StatusOK {
+ t.Fatalf("Expected status 200, got %d", w.Code)
+ }
+
+ if len(renderer.Calls) == 0 {
+ t.Fatal("Expected renderer to be called")
+ }
+
+ lastCall := renderer.Calls[len(renderer.Calls)-1]
+ dataStr := fmt.Sprintf("%+v", lastCall.Data)
+ if !strings.Contains(dataStr, "abc123") {
+ t.Error("Dashboard template data must include BuildVersion value")
+ }
+}
+
+// TestDashboardTemplate_HasBuildVersion verifies that index.html contains
+// a build version placeholder so users can see the deployed version.
+func TestDashboardTemplate_HasBuildVersion(t *testing.T) {
+ assertTemplateContains(t, "../../web/templates/index.html",
+ ".BuildVersion",
+ "index.html must contain .BuildVersion to display the build version in the footer")
+}
+
// TestTimelineTemplate_CheckboxesTargetSelf verifies that completion checkboxes
// in the timeline calendar grid target their parent item, not #tab-content.
func TestTimelineTemplate_CheckboxesTargetSelf(t *testing.T) {