mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 19:11:25 +01:00
feat(services): classify API failures by resource and report page totals
Add NotFoundError, ConflictError and AmbiguousError so commands can report "issue #999 not found in alice/project" or "alice/old-stuff is archived" instead of the transport's status text. Classify wraps a failure with the resource the caller names; ClassifyRequest infers it from the endpoint for failures no service classified, and maps the refusals Gitea explains (archived repository, merged or draft pull request, own review, existing resource, unknown user, disabled workflow, completed run, reused SSH key). Page reports the X-Total-Count that listWindow discarded, NameOrID resolves a resource by ID or name (numeric values are IDs first, ambiguous names list their IDs), and rawPage pages raw collection endpoints. Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
5 files changed
+603
-5
No files matched your search
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"gitea.dev/tea/internal/transport"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// newTestClient serves handler for the duration of the test and returns a client for it.
|
||||
@@ -38,3 +39,39 @@ func requestJSON(t *testing.T, r *http.Request) map[string]any {
|
||||
assert.NoError(t, json.NewDecoder(r.Body).Decode(&payload))
|
||||
return payload
|
||||
}
|
||||
|
||||
func TestNameOrIDPrefersIDsThenExactThenFoldedNames(t *testing.T) {
|
||||
type label struct {
|
||||
id int64
|
||||
name string
|
||||
}
|
||||
labels := []label{{11, "bug"}, {12, "Bug"}, {13, "7"}, {7, "seven"}, {20, "kind/feature"}, {21, "dup"}, {22, "dup"}}
|
||||
lookup := NameOrID[label]{Kind: "label", Scope: "alice/project", ID: func(l label) int64 { return l.id }, Name: func(l label) string { return l.name }}
|
||||
for _, tc := range []struct {
|
||||
raw string
|
||||
byName bool
|
||||
want int64
|
||||
err string
|
||||
}{
|
||||
{raw: "7", want: 7},
|
||||
{raw: "7", byName: true, want: 13},
|
||||
{raw: "13", want: 13},
|
||||
{raw: "bug", want: 11},
|
||||
{raw: "BUG", err: `label "BUG" is ambiguous in alice/project (IDs 11, 12); pass an ID`},
|
||||
{raw: "KIND/FEATURE", want: 20},
|
||||
{raw: " kind/feature ", want: 20},
|
||||
{raw: "dup", err: `label "dup" is ambiguous in alice/project (IDs 21, 22); pass an ID`},
|
||||
{raw: "nope", err: `label "nope" not found in alice/project`},
|
||||
{raw: "99", err: "label 99 not found in alice/project"},
|
||||
{raw: "99", byName: true, err: `label "99" not found in alice/project`},
|
||||
} {
|
||||
lookup.ByName = tc.byName
|
||||
got, err := lookup.Find(labels, tc.raw)
|
||||
if tc.err != "" {
|
||||
require.EqualError(t, err, tc.err, tc.raw)
|
||||
continue
|
||||
}
|
||||
require.NoError(t, err, tc.raw)
|
||||
require.Equal(t, tc.want, got.id, tc.raw)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user