| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- package admin
- import (
- "bytes"
- "context"
- "encoding/json"
- "net/http"
- "net/http/httptest"
- "testing"
- "github.com/Wei-Shaw/sub2api/internal/config"
- "github.com/Wei-Shaw/sub2api/internal/pkg/logger"
- "github.com/Wei-Shaw/sub2api/internal/server/middleware"
- "github.com/Wei-Shaw/sub2api/internal/service"
- "github.com/gin-gonic/gin"
- )
- type testSettingRepo struct {
- values map[string]string
- }
- func newTestSettingRepo() *testSettingRepo {
- return &testSettingRepo{values: map[string]string{}}
- }
- func (s *testSettingRepo) Get(ctx context.Context, key string) (*service.Setting, error) {
- v, err := s.GetValue(ctx, key)
- if err != nil {
- return nil, err
- }
- return &service.Setting{Key: key, Value: v}, nil
- }
- func (s *testSettingRepo) GetValue(ctx context.Context, key string) (string, error) {
- v, ok := s.values[key]
- if !ok {
- return "", service.ErrSettingNotFound
- }
- return v, nil
- }
- func (s *testSettingRepo) Set(ctx context.Context, key, value string) error {
- s.values[key] = value
- return nil
- }
- func (s *testSettingRepo) GetMultiple(ctx context.Context, keys []string) (map[string]string, error) {
- out := make(map[string]string, len(keys))
- for _, k := range keys {
- if v, ok := s.values[k]; ok {
- out[k] = v
- }
- }
- return out, nil
- }
- func (s *testSettingRepo) SetMultiple(ctx context.Context, settings map[string]string) error {
- for k, v := range settings {
- s.values[k] = v
- }
- return nil
- }
- func (s *testSettingRepo) GetAll(ctx context.Context) (map[string]string, error) {
- out := make(map[string]string, len(s.values))
- for k, v := range s.values {
- out[k] = v
- }
- return out, nil
- }
- func (s *testSettingRepo) Delete(ctx context.Context, key string) error {
- delete(s.values, key)
- return nil
- }
- func newOpsRuntimeRouter(handler *OpsHandler, withUser bool) *gin.Engine {
- gin.SetMode(gin.TestMode)
- r := gin.New()
- if withUser {
- r.Use(func(c *gin.Context) {
- c.Set(string(middleware.ContextKeyUser), middleware.AuthSubject{UserID: 7})
- c.Next()
- })
- }
- r.GET("/runtime/logging", handler.GetRuntimeLogConfig)
- r.PUT("/runtime/logging", handler.UpdateRuntimeLogConfig)
- r.POST("/runtime/logging/reset", handler.ResetRuntimeLogConfig)
- return r
- }
- func newRuntimeOpsService(t *testing.T) *service.OpsService {
- t.Helper()
- if err := logger.Init(logger.InitOptions{
- Level: "info",
- Format: "json",
- ServiceName: "sub2api",
- Environment: "test",
- Output: logger.OutputOptions{
- ToStdout: false,
- ToFile: false,
- },
- }); err != nil {
- t.Fatalf("init logger: %v", err)
- }
- settingRepo := newTestSettingRepo()
- cfg := &config.Config{
- Ops: config.OpsConfig{Enabled: true},
- Log: config.LogConfig{
- Level: "info",
- Caller: true,
- StacktraceLevel: "error",
- Sampling: config.LogSamplingConfig{
- Enabled: false,
- Initial: 100,
- Thereafter: 100,
- },
- },
- }
- return service.NewOpsService(nil, settingRepo, cfg, nil, nil, nil, nil, nil, nil, nil, nil)
- }
- func TestOpsRuntimeLoggingHandler_GetConfig(t *testing.T) {
- h := NewOpsHandler(newRuntimeOpsService(t))
- r := newOpsRuntimeRouter(h, false)
- w := httptest.NewRecorder()
- req := httptest.NewRequest(http.MethodGet, "/runtime/logging", nil)
- r.ServeHTTP(w, req)
- if w.Code != http.StatusOK {
- t.Fatalf("status=%d, want 200", w.Code)
- }
- }
- func TestOpsRuntimeLoggingHandler_UpdateUnauthorized(t *testing.T) {
- h := NewOpsHandler(newRuntimeOpsService(t))
- r := newOpsRuntimeRouter(h, false)
- body := `{"level":"debug","enable_sampling":false,"sampling_initial":100,"sampling_thereafter":100,"caller":true,"stacktrace_level":"error","retention_days":30}`
- w := httptest.NewRecorder()
- req := httptest.NewRequest(http.MethodPut, "/runtime/logging", bytes.NewBufferString(body))
- req.Header.Set("Content-Type", "application/json")
- r.ServeHTTP(w, req)
- if w.Code != http.StatusUnauthorized {
- t.Fatalf("status=%d, want 401", w.Code)
- }
- }
- func TestOpsRuntimeLoggingHandler_UpdateAndResetSuccess(t *testing.T) {
- h := NewOpsHandler(newRuntimeOpsService(t))
- r := newOpsRuntimeRouter(h, true)
- payload := map[string]any{
- "level": "debug",
- "enable_sampling": false,
- "sampling_initial": 100,
- "sampling_thereafter": 100,
- "caller": true,
- "stacktrace_level": "error",
- "retention_days": 30,
- }
- raw, _ := json.Marshal(payload)
- w := httptest.NewRecorder()
- req := httptest.NewRequest(http.MethodPut, "/runtime/logging", bytes.NewReader(raw))
- req.Header.Set("Content-Type", "application/json")
- r.ServeHTTP(w, req)
- if w.Code != http.StatusOK {
- t.Fatalf("update status=%d, want 200, body=%s", w.Code, w.Body.String())
- }
- w = httptest.NewRecorder()
- req = httptest.NewRequest(http.MethodPost, "/runtime/logging/reset", nil)
- r.ServeHTTP(w, req)
- if w.Code != http.StatusOK {
- t.Fatalf("reset status=%d, want 200, body=%s", w.Code, w.Body.String())
- }
- }
|