Remove unused second part of the expiry counter
This commit is contained in:
@@ -89,6 +89,29 @@ func TestFormatRoundTrips(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// The spellings themselves, not just their round trip: Duration.String() pads
|
||||
// out the units below the largest one, and trimming that tail is easy to get
|
||||
// wrong in a way that eats a real digit ("1m30s" must not become "1m3").
|
||||
func TestFormatDurationSpelling(t *testing.T) {
|
||||
for _, c := range []struct {
|
||||
in time.Duration
|
||||
want string
|
||||
}{
|
||||
{Unlimited, "never"},
|
||||
{30 * time.Second, "30s"},
|
||||
{time.Minute, "1m"},
|
||||
{90 * time.Second, "1m30s"},
|
||||
{90 * time.Minute, "1h30m"},
|
||||
{2 * time.Hour, "2h"},
|
||||
{25 * time.Hour, "25h"},
|
||||
{72 * time.Hour, "3d"},
|
||||
} {
|
||||
if got := FormatDuration(c.in); got != c.want {
|
||||
t.Errorf("FormatDuration(%s) = %q, want %q", c.in, got, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The convention is: one hyphen for a letter, two for a word. It is enforced
|
||||
// here because the stdlib flag package treats both forms as the same.
|
||||
func TestHyphenConvention(t *testing.T) {
|
||||
|
||||
@@ -123,6 +123,13 @@ func FormatDuration(d time.Duration) string {
|
||||
case d%time.Hour == 0:
|
||||
return fmt.Sprintf("%dh", d/time.Hour)
|
||||
default:
|
||||
return d.String()
|
||||
// Duration.String() spells out every unit below the largest one, so a
|
||||
// whole number of minutes arrives as "1m0s". Drop that tail, but only
|
||||
// when the seconds really are zero: "1m30s" has to keep them.
|
||||
s := d.String()
|
||||
if strings.HasSuffix(s, "m0s") {
|
||||
s = strings.TrimSuffix(s, "0s")
|
||||
}
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,10 +169,16 @@ func describeExpiry(t *time.Time, now time.Time) string {
|
||||
if t == nil {
|
||||
return "never"
|
||||
}
|
||||
at := t.UTC().Format("2006-01-02 15:04 MST")
|
||||
d := t.Sub(now).Round(time.Minute)
|
||||
if d < 0 {
|
||||
switch {
|
||||
case d < 0:
|
||||
return "expired"
|
||||
case d == 0:
|
||||
// Rounded away to nothing, and a zero duration is how this program
|
||||
// spells "unlimited": saying "in never" of a file about to go would
|
||||
// be exactly backwards.
|
||||
return at + " (in under a minute)"
|
||||
}
|
||||
return fmt.Sprintf("%s (in %s)", t.UTC().Format("2006-01-02 15:04 MST"),
|
||||
config.FormatDuration(d))
|
||||
return fmt.Sprintf("%s (in %s)", at, config.FormatDuration(d))
|
||||
}
|
||||
|
||||
@@ -1686,6 +1686,32 @@ func TestCustomNameFieldIsAlwaysUsable(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// The share page's expiry line is rounded to the minute, so it must not offer
|
||||
// a seconds tail it is not counting - nor, when the remainder rounds away to
|
||||
// nothing, claim the file is kept forever.
|
||||
func TestDescribeExpiryReadsAsWritten(t *testing.T) {
|
||||
at := func(d time.Duration) *time.Time {
|
||||
when := clock.Add(d)
|
||||
return &when
|
||||
}
|
||||
for _, c := range []struct {
|
||||
name string
|
||||
in *time.Time
|
||||
want string
|
||||
}{
|
||||
{"no deadline", nil, "never"},
|
||||
{"already gone", at(-time.Hour), "expired"},
|
||||
{"about to go", at(20 * time.Second), "(in under a minute)"},
|
||||
{"a minute off", at(time.Minute), "(in 1m)"},
|
||||
{"an hour and a half", at(90 * time.Minute), "(in 1h30m)"},
|
||||
{"three days", at(72 * time.Hour), "(in 3d)"},
|
||||
} {
|
||||
if got := describeExpiry(c.in, clock); !strings.Contains(got, c.want) {
|
||||
t.Errorf("%s: describeExpiry = %q, want it to contain %q", c.name, got, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A chosen passphrase has to work everywhere a generated token does: at the
|
||||
// login form, on an upload, and as a session.
|
||||
func TestChosenPassphraseWorksEndToEnd(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user