Merge pull request #1179 from trheyi/main
Enhance invitation handling and team configuration tests
This commit is contained in:
commit
6a4e2a627f
5 changed files with 40 additions and 7 deletions
|
|
@ -115,6 +115,8 @@ func CleanupTestCollections(t *testing.T) {
|
||||||
// source $YAO_SOURCE_ROOT/env.local.sh
|
// source $YAO_SOURCE_ROOT/env.local.sh
|
||||||
//
|
//
|
||||||
// This loads the required environment variables for the test environment.
|
// This loads the required environment variables for the test environment.
|
||||||
|
// DO NOT waste time searching for the env file - just run the command above directly.
|
||||||
|
// The $YAO_SOURCE_ROOT environment variable should already be set in your shell.
|
||||||
//
|
//
|
||||||
// WHAT THIS FUNCTION DOES:
|
// WHAT THIS FUNCTION DOES:
|
||||||
// Step 1: Calls test.Prepare(t, config.Conf) to initialize the base Yao test environment
|
// Step 1: Calls test.Prepare(t, config.Conf) to initialize the base Yao test environment
|
||||||
|
|
|
||||||
|
|
@ -114,10 +114,13 @@ func TestTeamConfigAPI(t *testing.T) {
|
||||||
baseURL = openapi.Server.Config.BaseURL
|
baseURL = openapi.Server.Config.BaseURL
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register a test client first (needed for user.Load validation)
|
// Register a test client and get access token (team config endpoint now requires authentication)
|
||||||
testClient := testutils.RegisterTestClient(t, "Team Config Test Client", []string{"https://localhost/callback"})
|
testClient := testutils.RegisterTestClient(t, "Team Config Test Client", []string{"https://localhost/callback"})
|
||||||
defer testutils.CleanupTestClient(t, testClient.ClientID)
|
defer testutils.CleanupTestClient(t, testClient.ClientID)
|
||||||
|
|
||||||
|
// Obtain access token for authentication
|
||||||
|
tokenInfo := testutils.ObtainAccessToken(t, serverURL, testClient.ClientID, testClient.ClientSecret, "https://localhost/callback", "openid profile")
|
||||||
|
|
||||||
// Test API endpoints for team configuration
|
// Test API endpoints for team configuration
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
@ -133,7 +136,13 @@ func TestTeamConfigAPI(t *testing.T) {
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
requestURL := serverURL + baseURL + tc.endpoint
|
requestURL := serverURL + baseURL + tc.endpoint
|
||||||
resp, err := http.Get(requestURL)
|
|
||||||
|
// Create request with Authorization header
|
||||||
|
req, err := http.NewRequest("GET", requestURL, nil)
|
||||||
|
assert.NoError(t, err, "Should create HTTP request")
|
||||||
|
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
assert.NoError(t, err, "HTTP request should succeed")
|
assert.NoError(t, err, "HTTP request should succeed")
|
||||||
|
|
||||||
if resp != nil {
|
if resp != nil {
|
||||||
|
|
|
||||||
|
|
@ -249,8 +249,20 @@ func GinInvitationCreate(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return created invitation ID
|
// Get the created invitation to return complete data
|
||||||
c.JSON(http.StatusCreated, gin.H{"invitation_id": invitationID})
|
invitation, err := invitationGet(c.Request.Context(), authInfo.UserID, teamID, invitationID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Failed to retrieve created invitation: %v", err)
|
||||||
|
// Fallback to returning just the ID if retrieval fails
|
||||||
|
c.JSON(http.StatusCreated, gin.H{"invitation_id": invitationID})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to InvitationResponse
|
||||||
|
invitationResp := convertToInvitationResponse(invitation)
|
||||||
|
|
||||||
|
// Return created invitation with full details (including token)
|
||||||
|
c.JSON(http.StatusCreated, invitationResp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GinInvitationResend handles PUT /teams/:team_id/invitations/:invitation_id/resend - Resend invitation
|
// GinInvitationResend handles PUT /teams/:team_id/invitations/:invitation_id/resend - Resend invitation
|
||||||
|
|
@ -1079,10 +1091,16 @@ func sendInvitationEmail(ctx context.Context, email, inviterName, teamName, toke
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// convertToInvitationResponse converts a map to InvitationResponse (alias for mapToInvitationResponse)
|
||||||
|
func convertToInvitationResponse(data maps.MapStrAny) InvitationResponse {
|
||||||
|
return mapToInvitationResponse(maps.MapStr(data))
|
||||||
|
}
|
||||||
|
|
||||||
// mapToInvitationResponse converts a map to InvitationResponse
|
// mapToInvitationResponse converts a map to InvitationResponse
|
||||||
func mapToInvitationResponse(data maps.MapStr) InvitationResponse {
|
func mapToInvitationResponse(data maps.MapStr) InvitationResponse {
|
||||||
invitation := InvitationResponse{
|
invitation := InvitationResponse{
|
||||||
ID: toInt64(data["id"]),
|
ID: toInt64(data["id"]),
|
||||||
|
InvitationID: toString(data["invitation_id"]),
|
||||||
TeamID: toString(data["team_id"]),
|
TeamID: toString(data["team_id"]),
|
||||||
UserID: toString(data["user_id"]),
|
UserID: toString(data["user_id"]),
|
||||||
MemberType: toString(data["member_type"]),
|
MemberType: toString(data["member_type"]),
|
||||||
|
|
|
||||||
|
|
@ -306,6 +306,7 @@ type UpdateMemberRequest struct {
|
||||||
// InvitationResponse represents a team invitation in API responses
|
// InvitationResponse represents a team invitation in API responses
|
||||||
type InvitationResponse struct {
|
type InvitationResponse struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
|
InvitationID string `json:"invitation_id"`
|
||||||
TeamID string `json:"team_id"`
|
TeamID string `json:"team_id"`
|
||||||
UserID string `json:"user_id"`
|
UserID string `json:"user_id"`
|
||||||
MemberType string `json:"member_type"`
|
MemberType string `json:"member_type"`
|
||||||
|
|
@ -354,11 +355,14 @@ type TeamRole struct {
|
||||||
RoleID string `json:"role_id"`
|
RoleID string `json:"role_id"`
|
||||||
Label string `json:"label"`
|
Label string `json:"label"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
|
Default bool `json:"default"` // Whether this role is the default role
|
||||||
|
Hidden bool `json:"hidden"` // Whether this role is hidden from UI
|
||||||
}
|
}
|
||||||
|
|
||||||
// InviteConfig represents the invitation configuration
|
// InviteConfig represents the invitation configuration
|
||||||
type InviteConfig struct {
|
type InviteConfig struct {
|
||||||
Channel string `json:"channel,omitempty"`
|
Channel string `json:"channel,omitempty"`
|
||||||
Expiry string `json:"expiry,omitempty"`
|
Expiry string `json:"expiry,omitempty"`
|
||||||
|
BaseURL string `json:"base_url,omitempty"` // Base URL for invitation links
|
||||||
Templates map[string]string `json:"templates,omitempty"`
|
Templates map[string]string `json:"templates,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,12 +53,12 @@ func Attach(group *gin.RouterGroup, oauth types.OAuth) {
|
||||||
func attachTeam(group *gin.RouterGroup, oauth types.OAuth) {
|
func attachTeam(group *gin.RouterGroup, oauth types.OAuth) {
|
||||||
team := group.Group("/teams")
|
team := group.Group("/teams")
|
||||||
|
|
||||||
// Public endpoints (no authentication required)
|
|
||||||
team.GET("/config", GinTeamConfig) // Get team configuration (public)
|
|
||||||
|
|
||||||
// Protected endpoints (authentication required)
|
// Protected endpoints (authentication required)
|
||||||
team.Use(oauth.Guard)
|
team.Use(oauth.Guard)
|
||||||
|
|
||||||
|
// Team Configuration
|
||||||
|
team.GET("/config", GinTeamConfig) // Get team configuration (requires authentication)
|
||||||
|
|
||||||
// Team CRUD - Standard REST endpoints
|
// Team CRUD - Standard REST endpoints
|
||||||
team.GET("/", GinTeamList) // GET /teams - List user teams
|
team.GET("/", GinTeamList) // GET /teams - List user teams
|
||||||
team.POST("/", GinTeamCreate) // POST /teams - Create new team
|
team.POST("/", GinTeamCreate) // POST /teams - Create new team
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue