account_traffic_handler_test.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package admin
  2. import (
  3. "context"
  4. "encoding/json"
  5. "net/http"
  6. "net/http/httptest"
  7. "strings"
  8. "testing"
  9. "github.com/Wei-Shaw/sub2api/internal/server/middleware"
  10. "github.com/Wei-Shaw/sub2api/internal/service"
  11. "github.com/gin-gonic/gin"
  12. "github.com/stretchr/testify/require"
  13. )
  14. type trafficAdminStub struct {
  15. service.AdminService
  16. account *service.Account
  17. reads, writes int
  18. }
  19. func (s *trafficAdminStub) GetAccount(context.Context, int64) (*service.Account, error) {
  20. s.reads++
  21. return s.account, nil
  22. }
  23. func (s *trafficAdminStub) UpdateAccountExtra(_ context.Context, _ int64, extra map[string]any) error {
  24. s.writes++
  25. for k, v := range extra {
  26. s.account.Extra[k] = v
  27. }
  28. return nil
  29. }
  30. func TestAccountTrafficHandlerPermissionsAndIndependentSwitches(t *testing.T) {
  31. for _, role := range []string{"", "user", "admin", "super_admin"} {
  32. t.Run(role, func(t *testing.T) {
  33. repo := &trafficAdminStub{account: &service.Account{ID: 42, Concurrency: 128, Extra: map[string]any{"keep": "value"}}}
  34. h := NewAccountTrafficHandler(repo, nil)
  35. r := gin.New()
  36. r.Use(func(c *gin.Context) {
  37. if role != "" {
  38. c.Set(string(middleware.ContextKeyUser), middleware.AuthSubject{UserID: 1})
  39. c.Set(string(middleware.ContextKeyUserRole), role)
  40. }
  41. })
  42. r.GET("/:id", h.Get)
  43. r.PUT("/:id", h.Update)
  44. policy := service.DefaultAccountTrafficPolicy()
  45. policy.StrictRPMEnabled = true
  46. raw, _ := json.Marshal(policy)
  47. w := httptest.NewRecorder()
  48. r.ServeHTTP(w, httptest.NewRequest(http.MethodPut, "/42", strings.NewReader(string(raw))))
  49. if role == "" || role == "user" {
  50. require.Contains(t, []int{401, 403}, w.Code)
  51. require.Zero(t, repo.reads)
  52. require.Zero(t, repo.writes)
  53. return
  54. }
  55. require.Equal(t, 200, w.Code, w.Body.String())
  56. require.Equal(t, 1, repo.writes)
  57. require.Equal(t, 128, repo.account.Concurrency)
  58. require.Equal(t, "value", repo.account.Extra["keep"])
  59. stored, err := service.ParseAccountTrafficPolicy(repo.account.Extra)
  60. require.NoError(t, err)
  61. require.True(t, stored.StrictRPMEnabled)
  62. require.False(t, stored.AdaptiveEnabled)
  63. policy.StrictRPMEnabled = false
  64. raw, _ = json.Marshal(policy)
  65. w = httptest.NewRecorder()
  66. r.ServeHTTP(w, httptest.NewRequest(http.MethodPut, "/42", strings.NewReader(string(raw))))
  67. require.Equal(t, 200, w.Code)
  68. stored, err = service.ParseAccountTrafficPolicy(repo.account.Extra)
  69. require.NoError(t, err)
  70. require.False(t, stored.Enabled())
  71. })
  72. }
  73. }