mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 19:11:25 +01:00
writeFirstPage answers paged listings in app and services tests, testNow replaces the copied clock, withoutANSI the second color stripper, and the single-entry table test becomes a plain test. Signed-off-by: bircni <bircni@icloud.com>
146 lines
7.5 KiB
Go
146 lines
7.5 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package app
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestNotificationBoundsShareClockAndReachServer(t *testing.T) {
|
|
now := time.Date(2028, 2, 1, 12, 0, 0, 0, time.UTC)
|
|
calls := 0
|
|
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
calls++
|
|
require.Equal(t, "/api/v1/notifications", r.URL.Path)
|
|
require.Equal(t, "2028-01-31T12:00:00Z", r.URL.Query().Get("since"))
|
|
require.Equal(t, "2028-02-01T11:00:00Z", r.URL.Query().Get("before"))
|
|
require.Equal(t, []string{"unread", "pinned"}, r.URL.Query()["status-types"])
|
|
_, _ = w.Write([]byte(`[]`))
|
|
}))
|
|
defer server.Close()
|
|
deps, out, _ := serverDeps(t, server.URL)
|
|
reads := 0
|
|
deps.Now = func() time.Time { reads++; return now }
|
|
err := Execute(context.Background(), deps, []string{"notification", "list", "--mine", "--since=24h", "--before=1h", "--json"})
|
|
require.NoError(t, err)
|
|
require.Equal(t, 1, reads)
|
|
require.Equal(t, 1, calls)
|
|
require.JSONEq(t, `[]`, out.String())
|
|
}
|
|
|
|
// notificationThreads is a page of two notification threads as Gitea sends them.
|
|
const notificationThreads = `[
|
|
{"id":12,"unread":true,"repository":{"full_name":"alice/project"},"updated_at":"2026-10-11T18:00:00Z",
|
|
"subject":{"title":"Improve greeting","type":"Pull","state":"open","html_url":"https://gitea.test/alice/project/pulls/17","url":"https://gitea.test/api/v1/repos/alice/project/issues/17"}},
|
|
{"id":3,"unread":false,"pinned":true,"repository":{"full_name":"alice/project"},"updated_at":"2026-10-11T17:00:00Z",
|
|
"subject":{"title":"Improve error messages","type":"Issue","state":"closed","html_url":"https://gitea.test/alice/project/issues/8","url":"https://gitea.test/api/v1/repos/alice/project/issues/8"}}
|
|
]`
|
|
|
|
func TestNotificationsListTheInboxByDefault(t *testing.T) {
|
|
var path atomic.Value
|
|
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
path.Store(r.URL.Path)
|
|
w.Header().Set("X-Total-Count", "2")
|
|
_, _ = w.Write([]byte(notificationThreads))
|
|
}))
|
|
defer server.Close()
|
|
for _, tc := range []struct {
|
|
args []string
|
|
git map[string]string
|
|
path string
|
|
}{
|
|
{nil, nil, "/api/v1/notifications"},
|
|
{nil, map[string]string{"remote": "origin", "remote get-url origin": server.URL + "/alice/project.git"}, "/api/v1/notifications"},
|
|
{[]string{"-R", "alice/project"}, nil, "/api/v1/repos/alice/project/notifications"},
|
|
{[]string{"--this-repo"}, map[string]string{"remote": "origin", "remote get-url origin": server.URL + "/bob/fork.git"}, "/api/v1/repos/bob/fork/notifications"},
|
|
} {
|
|
deps, _, _ := serverDeps(t, server.URL)
|
|
deps.Git = &fakeGit{results: tc.git}
|
|
require.NoError(t, Execute(context.Background(), deps, append([]string{"notification", "list"}, tc.args...)), tc.args)
|
|
require.Equal(t, tc.path, path.Load(), tc.args)
|
|
}
|
|
deps, out, _ := serverDeps(t, server.URL)
|
|
deps.Streams.OutTTY, deps.Streams.Width = true, 100
|
|
deps.Now = func() time.Time { return testNow }
|
|
require.NoError(t, Execute(context.Background(), deps, []string{"notification", "list"}))
|
|
require.Equal(t, `Showing 2 of 2 unread or pinned notifications in your inbox
|
|
|
|
ID TYPE REPOSITORY SUBJECT STATE UPDATED
|
|
12 pull alice/project #17 Improve greeting open about 2 hours ago
|
|
3 issue alice/project #8 Improve error messages closed about 3 hours ago
|
|
`, stripLinks(withoutANSI(out.String())))
|
|
deps, out, _ = serverDeps(t, server.URL)
|
|
require.NoError(t, Execute(context.Background(), deps, []string{"notification", "list"}))
|
|
require.Equal(t, "12\tpull\talice/project\t#17 Improve greeting\topen\tunread\t2026-10-11T18:00:00Z\thttps://gitea.test/alice/project/pulls/17\n"+
|
|
"3\tissue\talice/project\t#8 Improve error messages\tclosed\tpinned\t2026-10-11T17:00:00Z\thttps://gitea.test/alice/project/issues/8\n", out.String())
|
|
}
|
|
|
|
func TestNotificationWatchStreamsOneJSONObjectPerLine(t *testing.T) {
|
|
var polls atomic.Int32
|
|
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
if polls.Add(1) == 1 {
|
|
_, _ = w.Write([]byte(`[{"id":1,"subject":{"title":"First"}}]`))
|
|
return
|
|
}
|
|
_, _ = w.Write([]byte(`[{"id":1,"subject":{"title":"First"}},{"id":2,"subject":{"title":"Second"}}]`))
|
|
}))
|
|
defer server.Close()
|
|
deps, out, _ := serverDeps(t, server.URL)
|
|
require.NoError(t, Execute(context.Background(), deps, []string{"notification", "watch", "--json", "id,title", "--interval", "20ms", "--timeout", "500ms"}))
|
|
require.Equal(t, "{\"id\":1,\"title\":\"First\"}\n{\"id\":2,\"title\":\"Second\"}\n", out.String())
|
|
}
|
|
|
|
func TestNotificationMutationsReportWhatChanged(t *testing.T) {
|
|
var marks []string
|
|
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch {
|
|
case r.Method == http.MethodPatch && r.URL.Path == "/api/v1/notifications/threads/12":
|
|
marks = append(marks, r.URL.Query().Get("to-status"))
|
|
_, _ = w.Write([]byte(`{"id":12,"repository":{"full_name":"alice/project"},"subject":{"type":"Pull","url":"https://gitea.test/api/v1/repos/alice/project/issues/17"}}`))
|
|
case r.Method == http.MethodGet && r.URL.Path == "/api/v1/notifications/threads/12":
|
|
_, _ = w.Write([]byte(`{"id":12,"unread":true,"repository":{"full_name":"alice/project"},"subject":{"title":"Improve greeting","type":"Pull","state":"open","html_url":"https://gitea.test/alice/project/pulls/17","url":"https://gitea.test/api/v1/repos/alice/project/issues/17","latest_comment_url":"https://gitea.test/api/v1/repos/alice/project/issues/comments/9"}}`))
|
|
case r.URL.Path == "/api/v1/repos/alice/project/issues/comments/9":
|
|
_, _ = w.Write([]byte(`{"id":9,"body":"Looks good to me","user":{"login":"bob"}}`))
|
|
case r.Method == http.MethodPut && r.URL.Path == "/api/v1/notifications":
|
|
marks = append(marks, "all "+r.URL.Query().Get("to-status"))
|
|
_, _ = w.Write([]byte(`[{"id":12},{"id":3}]`))
|
|
default:
|
|
t.Errorf("unexpected %s %s", r.Method, r.URL.Path)
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
deps, out, diagnostics := serverDeps(t, server.URL)
|
|
deps.Streams.OutTTY = true
|
|
for _, tc := range []struct {
|
|
args []string
|
|
want string
|
|
}{
|
|
{[]string{"pin", "12"}, "✓ Pinned notification 12 (alice/project#17)\n"},
|
|
{[]string{"unpin", "#12"}, "✓ Unpinned notification 12 (alice/project#17)\n"},
|
|
{[]string{"mark-read", "12"}, "✓ Marked notification 12 (alice/project#17) as read\n"},
|
|
{[]string{"mark-read", "--all", "--yes"}, "✓ Marked 2 notifications as read\n"},
|
|
} {
|
|
diagnostics.Reset()
|
|
require.NoError(t, Execute(context.Background(), deps, append([]string{"notification"}, tc.args...)), tc.args)
|
|
require.Equal(t, tc.want, withoutANSI(diagnostics.String()), tc.args)
|
|
}
|
|
require.Equal(t, []string{"pinned", "read", "read", "all read"}, marks)
|
|
prompt := &scriptedPrompter{accept: true}
|
|
deps.Prompter, deps.Streams.InTTY, deps.Streams.ErrTTY = prompt, true, true
|
|
require.NoError(t, Execute(context.Background(), deps, []string{"notification", "pin", "--all"}))
|
|
require.Equal(t, []string{"Pin all unread notifications in your inbox?"}, prompt.confirmations)
|
|
deps.Streams.InTTY, deps.Streams.ErrTTY = false, false
|
|
marks = nil
|
|
out.Reset()
|
|
require.NoError(t, Execute(context.Background(), deps, []string{"notification", "view", "12"}))
|
|
require.Contains(t, withoutANSI(out.String()), "Latest comment: bob\n\n Looks good to me\n\nView this pull request on Gitea: https://gitea.test/alice/project/pulls/17\n")
|
|
require.Equal(t, []string{"read"}, marks, "viewing marks an unread notification as read")
|
|
}
|