From 8ade787421bf5691d861c923befc683d7827d475 Mon Sep 17 00:00:00 2001 From: Florian Ringbeck Date: Mon, 20 Apr 2026 10:47:34 +0200 Subject: [PATCH] updated time --- main.go | 16 +++++++++++++++- main_test.go | 14 ++++++++++++-- static/index.html | 10 ++++++---- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/main.go b/main.go index bbbfd00..6330ba7 100644 --- a/main.go +++ b/main.go @@ -11,6 +11,7 @@ import ( "strconv" "strings" "sync" + "time" ) //go:embed static/* @@ -19,6 +20,7 @@ var indexHTML embed.FS type store struct { mu sync.RWMutex value int + updatedAt time.Time } func (s *store) get() int { @@ -30,9 +32,16 @@ func (s *store) get() int { func (s *store) set(v int) { s.mu.Lock() s.value = v + s.updatedAt = time.Now() s.mu.Unlock() } +func (s *store) snapshot() (int, time.Time) { + s.mu.RLock() + defer s.mu.RUnlock() + return s.value, s.updatedAt +} + func main() { secret := os.Getenv("WRITE_SECRET") addr := os.Getenv("ADDR") @@ -108,7 +117,12 @@ func (s *server) handleIndex(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Content-Type", "text/html; charset=utf-8") - if err := page.Execute(w, map[string]any{"Watts": s.store.get()}); err != nil { + watts, updatedAt := s.store.snapshot() + updatedLabel := "not updated yet" + if !updatedAt.IsZero() { + updatedLabel = updatedAt.Format("02.01.2006 15:04:05") + } + if err := page.Execute(w, map[string]any{"Watts": watts, "UpdatedAt": updatedLabel}); err != nil { http.Error(w, "render error", http.StatusInternalServerError) } } diff --git a/main_test.go b/main_test.go index 28d8f4d..e38c083 100644 --- a/main_test.go +++ b/main_test.go @@ -2,15 +2,16 @@ package main import ( "bytes" - "os" "net/http" "net/http/httptest" + "os" "strings" "testing" + "time" ) func TestHandleIndexRendersWatts(t *testing.T) { - srv := &server{secret: "secret", store: &store{value: 123}} + srv := &server{secret: "secret", store: &store{value: 123, updatedAt: time.Date(2026, 4, 20, 12, 34, 56, 0, time.UTC)}} req := httptest.NewRequest(http.MethodGet, "/", nil) rec := httptest.NewRecorder() @@ -22,6 +23,12 @@ func TestHandleIndexRendersWatts(t *testing.T) { if !strings.Contains(rec.Body.String(), "123") { t.Fatalf("response did not contain watt value: %s", rec.Body.String()) } + if !strings.Contains(rec.Body.String(), "Last updated:") { + t.Fatalf("response did not contain last updated label: %s", rec.Body.String()) + } + if !strings.Contains(rec.Body.String(), "20.04.2026 12:34:56") { + t.Fatalf("response did not contain german datetime: %s", rec.Body.String()) + } } func TestHandleWriteRequiresSecret(t *testing.T) { @@ -52,6 +59,9 @@ func TestHandleWriteStoresValue(t *testing.T) { if got := srv.store.get(); got != 456 { t.Fatalf("stored watts = %d, want %d", got, 456) } + if srv.store.updatedAt.IsZero() { + t.Fatal("updatedAt was not set") + } } func TestLoadConfig(t *testing.T) { diff --git a/static/index.html b/static/index.html index 7574ef3..bf5b13e 100644 --- a/static/index.html +++ b/static/index.html @@ -11,12 +11,14 @@ main { text-align: center; padding: 2rem; } .value { font-size: clamp(3rem, 12vw, 8rem); font-weight: 800; line-height: 1; } .unit { margin-top: 0.75rem; font-size: 1.25rem; color: #94a3b8; } + .updated-at { margin-top: 0.5rem; font-size: 0.875rem; color: #64748b; } -
-
{{.Watts}}
-
watts
-
+
+
{{.Watts}}
+
watts
+
Last updated: {{.UpdatedAt}}
+