Page Menu
Home
Musing Studio
Search
Configure Global Search
Log In
Files
F10669689
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Subscribers
None
View Options
diff --git a/updates.go b/updates.go
index 63b2378..c33247b 100644
--- a/updates.go
+++ b/updates.go
@@ -1,105 +1,106 @@
/*
* Copyright © 2018-2019 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
* WriteFreely is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, included
* in the LICENSE file in this source code package.
*/
package writefreely
import (
"io/ioutil"
"net/http"
"strings"
"sync"
"time"
)
// 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
type updatesCache struct {
mu sync.Mutex
frequency time.Duration
lastCheck time.Time
latestVersion string
currentVersion string
}
// CheckNow asks for the latest released version of writefreely and updates
// the cache last checked time. If the version postdates the current 'latest'
// the version value is replaced.
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
}
uc.lastCheck = time.Now()
if CompareSemver(latestRemote, uc.latestVersion) == 1 {
uc.latestVersion = latestRemote
}
return nil
}
// AreAvailable updates the cache if the frequency duration has passed
// then returns if the latest release is newer than the current running version.
func (uc updatesCache) AreAvailable() bool {
if time.Since(uc.lastCheck) > uc.frequency {
uc.CheckNow()
}
return CompareSemver(uc.latestVersion, uc.currentVersion) == 1
}
// LatestVersion returns the latest stored version available.
func (uc updatesCache) LatestVersion() string {
return uc.latestVersion
}
// ReleaseURL returns the full URL to the blog.writefreely.org release notes
// for the latest version as stored in the cache.
func (uc updatesCache) ReleaseURL() string {
ver := strings.TrimPrefix(uc.latestVersion, "v")
ver = strings.TrimSuffix(ver, ".0")
// hack until go 1.12 in build/travis
seg := strings.Split(ver, ".")
return "https://blog.writefreely.org/version-" + strings.Join(seg, "-")
}
// 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()
return &cache
}
// 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()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return "", err
}
return string(body), nil
}
return "", err
}
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)
+ }
+ })
+}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, May 16, 3:27 PM (1 d, 13 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3240182
Attached To
rWF WriteFreely
Event Timeline
Log In to Comment