diff --git a/handlers/guest_links_test.go b/handlers/guest_links_test.go index b1ce0838..96338c9d 100644 --- a/handlers/guest_links_test.go +++ b/handlers/guest_links_test.go @@ -57,6 +57,40 @@ func TestGuestLinksPostAcceptsValidRequest(t *testing.T) { MaxFileUploads: makeGuestUploadCountLimit(1), }, }, + { + description: "guest file expires in 1 day", + payload: `{ + "label": "For my good pal, Maurice", + "urlExpirationTime":"2030-01-02T03:04:25Z", + "fileLifetime":"24h0m0s", + "maxFileBytes": 1048576, + "maxFileUploads": 1 + }`, + expected: picoshare.GuestLink{ + Label: picoshare.GuestLinkLabel("For my good pal, Maurice"), + UrlExpires: mustParseExpirationTime("2030-01-02T03:04:25Z"), + FileLifetime: picoshare.NewFileLifetimeInDays(1), + MaxFileBytes: makeGuestUploadMaxFileBytes(1048576), + MaxFileUploads: makeGuestUploadCountLimit(1), + }, + }, + { + description: "guest file expires in 30 day", + payload: `{ + "label": "For my good pal, Maurice", + "urlExpirationTime":"2030-01-02T03:04:25Z", + "fileLifetime":"720h0m0s", + "maxFileBytes": 1048576, + "maxFileUploads": 1 + }`, + expected: picoshare.GuestLink{ + Label: picoshare.GuestLinkLabel("For my good pal, Maurice"), + UrlExpires: mustParseExpirationTime("2030-01-02T03:04:25Z"), + FileLifetime: picoshare.NewFileLifetimeInDays(30), + MaxFileBytes: makeGuestUploadMaxFileBytes(1048576), + MaxFileUploads: makeGuestUploadCountLimit(1), + }, + }, } { t.Run(tt.description, func(t *testing.T) { dataStore := test_sqlite.New() diff --git a/handlers/templates/pages/guest-link-index.html b/handlers/templates/pages/guest-link-index.html index a6edcae4..d34f667f 100644 --- a/handlers/templates/pages/guest-link-index.html +++ b/handlers/templates/pages/guest-link-index.html @@ -144,7 +144,7 @@

Guest Links

{{ formatExpiration .UrlExpires }} - {{ formatFileExpiration .FileLifetime }} + {{ .FileLifetime.FriendlyName }} {{ formatSizeLimit .MaxFileBytes }} diff --git a/handlers/upload_test.go b/handlers/upload_test.go index 07bd1d5e..1e86cb77 100644 --- a/handlers/upload_test.go +++ b/handlers/upload_test.go @@ -5,6 +5,7 @@ import ( "bytes" "encoding/json" "io" + "math" "mime/multipart" "net/http" "net/http/httptest" @@ -280,9 +281,10 @@ func TestGuestUpload(t *testing.T) { { description: "valid upload to guest link", guestLinkInStore: picoshare.GuestLink{ - ID: picoshare.GuestLinkID("abcdefgh23456789"), - Created: mustParseTime("2022-01-01T00:00:00Z"), - UrlExpires: mustParseExpirationTime("2030-01-02T03:04:25Z"), + ID: picoshare.GuestLinkID("abcdefgh23456789"), + Created: mustParseTime("2022-01-01T00:00:00Z"), + UrlExpires: mustParseExpirationTime("2030-01-02T03:04:25Z"), + FileLifetime: picoshare.FileLifetimeInfinite, }, guestLinkID: "abcdefgh23456789", status: http.StatusOK, @@ -378,6 +380,28 @@ func TestGuestUpload(t *testing.T) { guestLinkID: "abcdefgh23456789", status: http.StatusBadRequest, }, + { + description: "guest file expires in 1 day", + guestLinkInStore: picoshare.GuestLink{ + ID: picoshare.GuestLinkID("abcdefgh23456789"), + Created: mustParseTime("2022-01-01T00:00:00Z"), + UrlExpires: mustParseExpirationTime("2030-01-02T03:04:25Z"), + FileLifetime: picoshare.NewFileLifetimeInDays(1), + }, + guestLinkID: "abcdefgh23456789", + status: http.StatusOK, + }, + { + description: "guest file expires in 365 day", + guestLinkInStore: picoshare.GuestLink{ + ID: picoshare.GuestLinkID("abcdefgh23456789"), + Created: mustParseTime("2022-01-01T00:00:00Z"), + UrlExpires: mustParseExpirationTime("2030-01-02T03:04:25Z"), + FileLifetime: picoshare.NewFileLifetimeInDays(365), + }, + guestLinkID: "abcdefgh23456789", + status: http.StatusOK, + }, } { t.Run(tt.description, func(t *testing.T) { store := test_sqlite.New() @@ -441,13 +465,21 @@ func TestGuestUpload(t *testing.T) { } // Guest uploads never expire. - // if got, want := entry.Expires, picoshare.NeverExpire; got != want { - // t.Errorf("expiration=%v, want=%v", got, want) - // } + if got, want := convertExpirationTimeToFileLifetime(entry.Expires), tt.guestLinkInStore.FileLifetime; got != want { + t.Errorf("expiration=%v, want=%v", got, want) + } }) } } +func convertExpirationTimeToFileLifetime(et picoshare.ExpirationTime) picoshare.FileLifetime { + if et == picoshare.NeverExpire { + return picoshare.FileLifetimeInfinite + } + delta := math.Round(time.Until(time.Time(et)).Hours() / 24) + return picoshare.NewFileLifetimeInDays(uint16(delta)) +} + func createMultipartFormBody(filename, note string, r io.Reader) (io.Reader, string) { var b bytes.Buffer bw := bufio.NewWriter(&b) diff --git a/handlers/views.go b/handlers/views.go index 4ae498e8..42e26dd0 100644 --- a/handlers/views.go +++ b/handlers/views.go @@ -87,17 +87,6 @@ func (s Server) guestLinkIndexGet() http.HandlerFunc { } return fmt.Sprintf("%s (%.0f days%s)", t.Format(time.DateOnly), math.Abs(delta.Hours())/24, suffix) }, - "formatFileExpiration": func(flt picoshare.FileLifetime) string { - if flt == picoshare.FileLifetimeInfinite { - return "Never" - } - - letterS := "s" - if flt.Duration().Hours() < 25 { - letterS = "" - } - return fmt.Sprintf("After %.0f day%s", math.Abs(flt.Duration().Hours()/24), letterS) - }, "isActive": func(gl picoshare.GuestLink) bool { return gl.IsActive() },