diff --git a/pgs/web_test.go b/pgs/web_test.go index 9d817727..6e7c7567 100644 --- a/pgs/web_test.go +++ b/pgs/web_test.go @@ -8,6 +8,7 @@ import ( "net/http/httptest" "strings" "testing" + "time" "github.com/picosh/pico/db" "github.com/picosh/pico/db/stub" @@ -22,6 +23,7 @@ var testUsername = "user" type ApiExample struct { name string path string + reqHeaders map[string]string want string wantUrl string status int @@ -227,11 +229,101 @@ func TestApiBasic(t *testing.T) { }, }, }, + { + name: "conditional-if-modified-since-future", + path: "/test.html", + reqHeaders: map[string]string{ + "If-Modified-Since": time.Now().UTC().Add(time.Hour).Format(http.TimeFormat), + }, + want: "", + status: http.StatusNotModified, + contentType: "", + + dbpool: NewPgsDb(cfg.Logger), + storage: map[string]map[string]string{ + bucketName: { + "test/test.html": "hello world!", + }, + }, + }, + { + name: "conditional-if-modified-since-past", + path: "/test.html", + reqHeaders: map[string]string{ + "If-Modified-Since": time.Now().UTC().Add(-time.Hour).Format(http.TimeFormat), + }, + want: "hello world!", + status: http.StatusOK, + contentType: "text/html", + + dbpool: NewPgsDb(cfg.Logger), + storage: map[string]map[string]string{ + bucketName: { + "test/test.html": "hello world!", + }, + }, + }, + { + name: "conditional-if-none-match-pass", + path: "/test.html", + reqHeaders: map[string]string{ + "If-None-Match": "\"static-etag-for-testing-purposes\"", + }, + want: "", + status: http.StatusNotModified, + contentType: "", + + dbpool: NewPgsDb(cfg.Logger), + storage: map[string]map[string]string{ + bucketName: { + "test/test.html": "hello world!", + }, + }, + }, + { + name: "conditional-if-none-match-fail", + path: "/test.html", + reqHeaders: map[string]string{ + "If-None-Match": "\"non-matching-etag\"", + }, + want: "hello world!", + status: http.StatusOK, + contentType: "text/html", + + dbpool: NewPgsDb(cfg.Logger), + storage: map[string]map[string]string{ + bucketName: { + "test/test.html": "hello world!", + }, + }, + }, + { + name: "conditional-if-none-match-and-if-modified-since", + path: "/test.html", + reqHeaders: map[string]string{ + // The matching etag should take precedence over the past mod time + "If-None-Match": "\"static-etag-for-testing-purposes\"", + "If-Modified-Since": time.Now().UTC().Add(-time.Hour).Format(http.TimeFormat), + }, + want: "", + status: http.StatusNotModified, + contentType: "", + + dbpool: NewPgsDb(cfg.Logger), + storage: map[string]map[string]string{ + bucketName: { + "test/test.html": "hello world!", + }, + }, + }, } for _, tc := range tt { t.Run(tc.name, func(t *testing.T) { request := httptest.NewRequest("GET", mkpath(tc.path), strings.NewReader("")) + for key, val := range tc.reqHeaders { + request.Header.Set(key, val) + } responseRecorder := httptest.NewRecorder() st, _ := storage.NewStorageMemory(tc.storage) diff --git a/shared/storage/memory.go b/shared/storage/memory.go index a8cac896..5574447e 100644 --- a/shared/storage/memory.go +++ b/shared/storage/memory.go @@ -3,6 +3,7 @@ package storage import ( "io" "net/http" + "time" sst "github.com/picosh/pobj/storage" ) @@ -24,6 +25,13 @@ func (s *StorageMemory) ServeObject(bucket sst.Bucket, fpath string, opts *ImgPr if info.Metadata == nil { info.Metadata = make(http.Header) } + // Make tests work by supplying non-null Last-Modified and Etag values + if info.LastModified.IsZero() { + info.LastModified = time.Now().UTC() + } + if info.ETag == "" { + info.ETag = "static-etag-for-testing-purposes" + } mimeType := GetMimeType(fpath) info.Metadata.Set("content-type", mimeType) return obj, info, err