mirror of
https://github.com/BaaRai/ARTEX.git
synced 2026-11-13 11:40:53 +08:00
ARTEX_UPDATE_CHECK=1 lets the backend check the public GitHub releases API for the latest tag at most once per 24 h (in-memory cache; failures are not retried in the window) and report it in GET /api/health when it is newer than the build version. The web UI shows a dismissible strip linking to the Releases page. Unset (the default), no update request is made.
79 lines
2.4 KiB
Go
79 lines
2.4 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func countingFetch(tag string, err error, calls *int) func(context.Context) (string, error) {
|
|
return func(context.Context) (string, error) { *calls++; return tag, err }
|
|
}
|
|
|
|
func TestUpdateCheckOffByDefault(t *testing.T) {
|
|
t.Setenv("ARTEX_UPDATE_CHECK", "")
|
|
if updateCheckEnabled() {
|
|
t.Fatal("update check must be off when ARTEX_UPDATE_CHECK is unset")
|
|
}
|
|
calls := 0
|
|
u := &updateCheck{enabled: false, fetch: countingFetch("v9.9.9", nil, &calls)}
|
|
if got := u.newerVersion(context.Background(), time.Now(), "2.2.0"); got != "" || calls != 0 {
|
|
t.Fatalf("disabled: got %q with %d fetches, want no banner and no fetch", got, calls)
|
|
}
|
|
}
|
|
|
|
func TestUpdateCheckOncePer24h(t *testing.T) {
|
|
t0 := time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)
|
|
calls := 0
|
|
u := &updateCheck{enabled: true, fetch: countingFetch("v2.3.0", nil, &calls)}
|
|
for _, at := range []time.Duration{0, time.Hour, 23*time.Hour + 59*time.Minute} {
|
|
if got := u.newerVersion(context.Background(), t0.Add(at), "2.2.0"); got != "v2.3.0" {
|
|
t.Fatalf("at +%v: got %q, want v2.3.0", at, got)
|
|
}
|
|
}
|
|
if calls != 1 {
|
|
t.Fatalf("fetched %d times within 24h, want 1", calls)
|
|
}
|
|
u.newerVersion(context.Background(), t0.Add(24*time.Hour), "2.2.0")
|
|
if calls != 2 {
|
|
t.Fatalf("fetched %d times after 24h, want 2", calls)
|
|
}
|
|
if got := u.newerVersion(context.Background(), t0.Add(25*time.Hour), "2.3.0"); got != "" {
|
|
t.Fatalf("up to date: got %q, want no banner", got)
|
|
}
|
|
}
|
|
|
|
func TestUpdateCheckFailureShowsNothingAndWaits(t *testing.T) {
|
|
t0 := time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)
|
|
calls := 0
|
|
u := &updateCheck{enabled: true, fetch: countingFetch("", errors.New("rate limited"), &calls)}
|
|
for _, at := range []time.Duration{0, time.Minute, 23 * time.Hour} {
|
|
if got := u.newerVersion(context.Background(), t0.Add(at), "2.2.0"); got != "" {
|
|
t.Fatalf("failed check: got %q, want no banner", got)
|
|
}
|
|
}
|
|
if calls != 1 {
|
|
t.Fatalf("failed check retried %d times within 24h, want 1 attempt", calls)
|
|
}
|
|
}
|
|
|
|
func TestVersionLess(t *testing.T) {
|
|
cases := []struct {
|
|
a, b string
|
|
want bool
|
|
}{
|
|
{"2.2.0", "v2.3.0", true},
|
|
{"v2.2.0", "v2.2.0", false},
|
|
{"2.10.0", "v2.9.0", false},
|
|
{"2.2.0-3-gabc123-dirty", "v2.2.1", true},
|
|
{"dev", "v9.0.0", false},
|
|
{"2.2.0", "not-a-tag", false},
|
|
}
|
|
for _, c := range cases {
|
|
if got := versionLess(c.a, c.b); got != c.want {
|
|
t.Errorf("versionLess(%q, %q) = %v, want %v", c.a, c.b, got, c.want)
|
|
}
|
|
}
|
|
}
|