package handler import ( "baron-sso-backend/internal/domain" "baron-sso-backend/internal/service" "bytes" "context" "encoding/json" "net/http" "net/http/httptest" "testing" "github.com/gofiber/fiber/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) type devMockRPUserMetadataRepo struct { mock.Mock } func (m *devMockRPUserMetadataRepo) Get(ctx context.Context, clientID, userID string) (*domain.RPUserMetadata, error) { args := m.Called(ctx, clientID, userID) if args.Get(0) == nil { return nil, args.Error(1) } return args.Get(0).(*domain.RPUserMetadata), args.Error(1) } func (m *devMockRPUserMetadataRepo) Upsert(ctx context.Context, metadata *domain.RPUserMetadata) error { args := m.Called(ctx, metadata) return args.Error(0) } func TestDevHandler_RPUserMetadataRoundTrip(t *testing.T) { transport := roundTripFunc(func(r *http.Request) (*http.Response, error) { if r.URL.Path == "/clients/client-1" { return httpJSONAny(r, http.StatusOK, map[string]any{ "client_id": "client-1", "client_name": "Client One", "metadata": map[string]any{ "tenant_id": "tenant-1", }, }), nil } return httpJSONAny(r, http.StatusNotFound, nil), nil }) repo := new(devMockRPUserMetadataRepo) repo.On("Upsert", mock.Anything, mock.MatchedBy(func(row *domain.RPUserMetadata) bool { return row.ClientID == "client-1" && row.UserID == "user-1" && row.Metadata["approvalLevel"] == "A" })).Return(nil).Once() repo.On("Get", mock.Anything, "client-1", "user-1").Return(&domain.RPUserMetadata{ ClientID: "client-1", UserID: "user-1", Metadata: domain.JSONMap{"approvalLevel": "A"}, }, nil).Once() h := &DevHandler{ Hydra: &service.HydraAdminService{ AdminURL: "http://hydra.test", HTTPClient: &http.Client{Transport: transport}, }, RPUserMetadataRepo: repo, } app := fiber.New() app.Use(func(c *fiber.Ctx) error { c.Locals("user_profile", &domain.UserProfileResponse{ID: "admin", Role: domain.RoleSuperAdmin}) return c.Next() }) app.Put("/api/v1/dev/clients/:id/users/:userId/metadata", h.UpsertRPUserMetadata) app.Get("/api/v1/dev/clients/:id/users/:userId/metadata", h.GetRPUserMetadata) body, _ := json.Marshal(map[string]any{ "metadata": map[string]any{"approvalLevel": "A"}, }) putReq := httptest.NewRequest(http.MethodPut, "/api/v1/dev/clients/client-1/users/user-1/metadata", bytes.NewReader(body)) putReq.Header.Set("Content-Type", "application/json") putResp, _ := app.Test(putReq, -1) assert.Equal(t, http.StatusOK, putResp.StatusCode) getReq := httptest.NewRequest(http.MethodGet, "/api/v1/dev/clients/client-1/users/user-1/metadata", nil) getResp, _ := app.Test(getReq, -1) assert.Equal(t, http.StatusOK, getResp.StatusCode) var got map[string]any assert.NoError(t, json.NewDecoder(getResp.Body).Decode(&got)) assert.Equal(t, "client-1", got["clientId"]) assert.Equal(t, "user-1", got["userId"]) assert.Equal(t, "A", got["metadata"].(map[string]any)["approvalLevel"]) repo.AssertExpectations(t) }