feat(users): add authenticated user quota getter
All checks were successful
Security Scan / security (push) Successful in 13s
Test / test (push) Successful in 1m21s

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-02 00:27:55 +00:00
parent 1c03ea14a3
commit cb54c357e1
3 changed files with 45 additions and 0 deletions

View file

@ -221,6 +221,7 @@ Coverage notes: rows list direct tests when a symbol is named in test names or r
| method | TeamService.RemoveRepo | `func (s *TeamService) RemoveRepo(ctx context.Context, teamID int64, org, repo string) error` | RemoveRepo removes a repository from a team. | No direct tests. |
| method | UserService.Follow | `func (s *UserService) Follow(ctx context.Context, username string) error` | Follow follows a user as the authenticated user. | No direct tests. |
| method | UserService.GetCurrent | `func (s *UserService) GetCurrent(ctx context.Context) (*types.User, error)` | GetCurrent returns the authenticated user. | `TestUserService_Good_GetCurrent` |
| method | UserService.GetQuota | `func (s *UserService) GetQuota(ctx context.Context) (*types.QuotaInfo, error)` | GetQuota returns the authenticated user's quota information. | `TestUserService_GetQuota_Good` |
| method | UserService.ListStopwatches | `func (s *UserService) ListStopwatches(ctx context.Context) ([]types.StopWatch, error)` | ListStopwatches returns all existing stopwatches for the authenticated user. | `TestUserService_ListStopwatches_Good` |
| method | UserService.IterStopwatches | `func (s *UserService) IterStopwatches(ctx context.Context) iter.Seq2[types.StopWatch, error]` | IterStopwatches returns an iterator over all existing stopwatches for the authenticated user. | `TestUserService_IterStopwatches_Good` |
| method | UserService.IterFollowers | `func (s *UserService) IterFollowers(ctx context.Context, username string) iter.Seq2[types.User, error]` | IterFollowers returns an iterator over all followers of a user. | No direct tests. |

View file

@ -52,6 +52,15 @@ func (s *UserService) UpdateSettings(ctx context.Context, opts *types.UserSettin
return &out, nil
}
// GetQuota returns the authenticated user's quota information.
func (s *UserService) GetQuota(ctx context.Context) (*types.QuotaInfo, error) {
var out types.QuotaInfo
if err := s.client.Get(ctx, "/api/v1/user/quota", &out); err != nil {
return nil, err
}
return &out, nil
}
// ListEmails returns all email addresses for the authenticated user.
func (s *UserService) ListEmails(ctx context.Context) ([]types.Email, error) {
return ListAll[types.Email](ctx, s.client, "/api/v1/user/emails", nil)

View file

@ -128,6 +128,41 @@ func TestUserService_UpdateSettings_Good(t *testing.T) {
}
}
func TestUserService_GetQuota_Good(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
t.Errorf("expected GET, got %s", r.Method)
}
if r.URL.Path != "/api/v1/user/quota" {
t.Errorf("wrong path: %s", r.URL.Path)
}
json.NewEncoder(w).Encode(types.QuotaInfo{
Groups: &types.QuotaGroupList{},
Used: &types.QuotaUsed{
Size: &types.QuotaUsedSize{
Repos: &types.QuotaUsedSizeRepos{
Public: 123,
Private: 456,
},
},
},
})
}))
defer srv.Close()
f := NewForge(srv.URL, "tok")
quota, err := f.Users.GetQuota(context.Background())
if err != nil {
t.Fatal(err)
}
if quota.Used == nil || quota.Used.Size == nil || quota.Used.Size.Repos == nil {
t.Fatalf("quota usage was not decoded: %+v", quota)
}
if quota.Used.Size.Repos.Public != 123 || quota.Used.Size.Repos.Private != 456 {
t.Errorf("unexpected repository quota usage: %+v", quota.Used.Size.Repos)
}
}
func TestUserService_ListEmails_Good(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {