Files
gitea-tea/internal/app/time_test.go
T
bircni b5fecbde42 fix(time): accept spaced durations and print whole-second times
tea time create 1 1h25m printed 2026-10-11T18:57:49.588823137Z while time
list printed whole seconds, and "1h 30m" or 2d failed with "duration
must be nonzero whole seconds". Durations may now contain spaces, and
errors name the problem: "invalid duration "2d": use h, m and s units
such as 1h25m". Tracked times are whole seconds everywhere.

Signed-off-by: bircni <bircni@icloud.com>
2026-10-12 00:14:52 +02:00

60 lines
2.7 KiB
Go

// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package app
import (
"context"
"net/http"
"testing"
"gitea.dev/tea/internal/clierr"
"github.com/stretchr/testify/require"
)
func TestTimeListShowsRepositoryAndDurations(t *testing.T) {
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, "/api/v1/user/times", r.URL.Path)
_, _ = w.Write([]byte(`[
{"id":1,"time":5100,"created":"2026-10-01T10:00:00Z","user_name":"alice","issue":{"number":3,"repository":{"full_name":"alice/project"}}},
{"id":2,"time":900,"created":"2026-10-02T10:00:00Z","user_name":"alice","issue":{"number":3,"repository":{"full_name":"bob/tools"}}}
]`))
}))
defer server.Close()
deps, out, _ := serverDeps(t, server.URL)
require.NoError(t, Execute(context.Background(), deps, []string{"time", "list", "--mine", "--total"}))
require.Equal(t, "1 alice/project#3 alice 1h25m0s 2026-10-01T10:00:00Z\n"+
"2 bob/tools#3 alice 15m0s 2026-10-02T10:00:00Z\n"+
"Total on this page: 1h40m0s\n", out.String())
out.Reset()
require.NoError(t, Execute(context.Background(), deps, []string{"time", "list", "--mine", "--json=repository,issue_number"}))
require.JSONEq(t, `[{"repository":"alice/project","issue_number":3},{"repository":"bob/tools","issue_number":3}]`, out.String())
}
func TestTimeCreateReadsDurationsAndWholeSecondTimes(t *testing.T) {
var seconds []string
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, "POST /api/v1/repos/alice/project/issues/1/times", r.Method+" "+r.URL.Path)
seconds = append(seconds, payloadField(t, r, "time"))
_, _ = w.Write([]byte(`{"id":5,"time":5400,"created":"2026-10-11T18:57:49.588823137Z","user_name":"alice"}`))
}))
defer server.Close()
deps, out, _ := serverDeps(t, server.URL)
for _, duration := range []string{"1h30m", "1h 30m", " 90m "} {
out.Reset()
require.NoError(t, Execute(context.Background(), deps, []string{"time", "create", "1", duration, "-R", "alice/project", "--json=created_at"}))
require.JSONEq(t, `{"created_at":"2026-10-11T18:57:49Z"}`, out.String())
}
require.Equal(t, []string{"5400", "5400", "5400"}, seconds)
for duration, want := range map[string]string{
"2d": `invalid duration "2d": use h, m and s units such as 1h25m`,
"0m": `invalid duration "0m": time spent must be positive`,
"1.5s": `invalid duration "1.5s": use whole seconds`,
} {
err := Execute(context.Background(), deps, []string{"time", "create", "1", duration, "-R", "alice/project"})
require.Equal(t, clierr.Usage, clierr.ExitCode(err), duration)
require.ErrorContains(t, err, want)
}
require.Len(t, seconds, 3)
}