From 908f009248ec540576f3dd02ecf6d35edb0c5dce Mon Sep 17 00:00:00 2001 From: Rob Loranger Date: Mon, 9 Sep 2019 10:24:29 -0700 Subject: [PATCH] clean up and add tests for updates cache - removes the parameter for newVersionCheck as was not being used - changes newUpdatesCache to take expiry parameter for possible future configuration option - adds basic test quite to verify all cache fucntions work as expected --- updates.go | 13 ++++---- updates_test.go | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 updates_test.go diff --git a/updates.go b/updates.go index 63b2378..c33247b 100644 --- a/updates.go +++ b/updates.go @@ -20,7 +20,7 @@ import ( // updatesCacheTime is the default interval between cache updates for new // software versions -const updatesCacheTime = 12 * time.Hour +const defaultUpdatesCacheTime = 12 * time.Hour // updatesCache holds data about current and new releases of the writefreely // software @@ -38,7 +38,7 @@ type updatesCache struct { func (uc *updatesCache) CheckNow() error { uc.mu.Lock() defer uc.mu.Unlock() - latestRemote, err := newVersionCheck(uc.currentVersion) + latestRemote, err := newVersionCheck() if err != nil { return err } @@ -74,9 +74,9 @@ func (uc updatesCache) ReleaseURL() string { } // newUpdatesCache returns an initialized updates cache -func newUpdatesCache() *updatesCache { +func newUpdatesCache(expiry time.Duration) *updatesCache { cache := updatesCache{ - frequency: updatesCacheTime, + frequency: expiry, currentVersion: "v" + softwareVer, } cache.CheckNow() @@ -84,13 +84,14 @@ func newUpdatesCache() *updatesCache { } // InitUpdates initializes the updates cache, if the config value is set +// It uses the defaultUpdatesCacheTime for the cache expiry func (app *App) InitUpdates() { if app.cfg.App.UpdateChecks { - app.updates = newUpdatesCache() + app.updates = newUpdatesCache(defaultUpdatesCacheTime) } } -func newVersionCheck(serverVersion string) (string, error) { +func newVersionCheck() (string, error) { res, err := http.Get("https://version.writefreely.org") if err == nil && res.StatusCode == http.StatusOK { defer res.Body.Close() diff --git a/updates_test.go b/updates_test.go new file mode 100644 index 0000000..2cb9f92 --- /dev/null +++ b/updates_test.go @@ -0,0 +1,82 @@ +package writefreely + +import ( + "regexp" + "testing" + "time" +) + +func TestUpdatesRoundTrip(t *testing.T) { + cache := newUpdatesCache(defaultUpdatesCacheTime) + t.Run("New Updates Cache", func(t *testing.T) { + + if cache == nil { + t.Fatal("Returned nil cache") + } + + if cache.frequency != defaultUpdatesCacheTime { + t.Fatalf("Got cache expiry frequency: %s but expected: %s", cache.frequency, defaultUpdatesCacheTime) + } + + if cache.currentVersion != "v"+softwareVer { + t.Fatalf("Got current version: %s but expected: %s", cache.currentVersion, "v"+softwareVer) + } + }) + + t.Run("Release URL", func(t *testing.T) { + url := cache.ReleaseURL() + + reg, err := regexp.Compile(`^https:\/\/blog.writefreely.org\/version(-\d+){1,}$`) + if err != nil { + t.Fatalf("Test Case Error: Failed to compile regex: %v", err) + } + match := reg.MatchString(url) + + if !match { + t.Fatalf("Malformed Release URL: %s", url) + } + }) + + t.Run("Check Now", func(t *testing.T) { + // ensure time between init and next check + time.Sleep(1 * time.Second) + + prevLastCheck := cache.lastCheck + + // force to known older version for latest and current + prevLatestVer := "v0.8.1" + cache.latestVersion = prevLatestVer + cache.currentVersion = "v0.8.0" + + err := cache.CheckNow() + if err != nil { + t.Fatalf("Error should be nil, got: %v", err) + } + + if prevLastCheck == cache.lastCheck { + t.Fatal("Expected lastCheck to update") + } + + if cache.lastCheck.Before(prevLastCheck) { + t.Fatal("Last check should be newer than previous") + } + + if prevLatestVer == cache.latestVersion { + t.Fatal("expected latestVersion to update") + } + + }) + + t.Run("Are Available", func(t *testing.T) { + if !cache.AreAvailable() { + t.Fatalf("Cache reports not updates but Current is %s and Latest is %s", cache.currentVersion, cache.latestVersion) + } + }) + + t.Run("Latest Version", func(t *testing.T) { + gotLatest := cache.LatestVersion() + if gotLatest != cache.latestVersion { + t.Fatalf("Malformed latest version. Expected: %s but got: %s", cache.latestVersion, gotLatest) + } + }) +}