mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
SCIM test refactor (#28524)
For #28196 I told AI agent to find duplicate code and refactor the test. Not bad, although I was actually hoping it would find duplicate tests — where we are testing the same thing. I reviewed and cleaned up the code a bit. # Checklist for submitter - [x] Added/updated automated tests
This commit is contained in:
parent
d403755b59
commit
effacaf5f5
1 changed files with 54 additions and 160 deletions
|
|
@ -182,18 +182,18 @@ func testBaseEndpoints(t *testing.T, s *Suite) {
|
|||
})
|
||||
}
|
||||
|
||||
func testUsersBasicCRUD(t *testing.T, s *Suite) {
|
||||
// Test creating a user
|
||||
// createTestUser creates a test user with the given username and returns the user ID and response
|
||||
func createTestUser(t *testing.T, s *Suite, userName string) (string, map[string]interface{}) {
|
||||
createUserPayload := map[string]interface{}{
|
||||
"schemas": []string{"urn:ietf:params:scim:schemas:core:2.0:User"},
|
||||
"userName": "testuser@example.com",
|
||||
"userName": userName,
|
||||
"name": map[string]interface{}{
|
||||
"givenName": "Test",
|
||||
"familyName": "User",
|
||||
},
|
||||
"emails": []map[string]interface{}{
|
||||
{
|
||||
"value": "testuser@example.com",
|
||||
"value": userName,
|
||||
"type": "work",
|
||||
"primary": true,
|
||||
},
|
||||
|
|
@ -205,18 +205,26 @@ func testUsersBasicCRUD(t *testing.T, s *Suite) {
|
|||
s.DoJSON(t, "POST", scimPath("/Users"), createUserPayload, http.StatusCreated, &createResp)
|
||||
|
||||
// Verify the created user
|
||||
assert.Equal(t, "testuser@example.com", createResp["userName"])
|
||||
assert.Equal(t, userName, createResp["userName"])
|
||||
assert.Equal(t, true, createResp["active"])
|
||||
|
||||
// Extract the user ID for subsequent operations
|
||||
// Extract the user ID
|
||||
userID := createResp["id"].(string)
|
||||
assert.NotEmpty(t, userID)
|
||||
|
||||
return userID, createResp
|
||||
}
|
||||
|
||||
func testUsersBasicCRUD(t *testing.T, s *Suite) {
|
||||
// Test creating a user
|
||||
userName := "testuser@example.com"
|
||||
userID, _ := createTestUser(t, s, userName)
|
||||
|
||||
// Test getting a user by ID
|
||||
var getResp map[string]interface{}
|
||||
s.DoJSON(t, "GET", scimPath("/Users/"+userID), nil, http.StatusOK, &getResp)
|
||||
assert.Equal(t, userID, getResp["id"])
|
||||
assert.Equal(t, "testuser@example.com", getResp["userName"])
|
||||
assert.Equal(t, userName, getResp["userName"])
|
||||
assert.Equal(t, true, getResp["active"])
|
||||
|
||||
// Test getting a user with a bad ID
|
||||
|
|
@ -262,7 +270,7 @@ func testUsersBasicCRUD(t *testing.T, s *Suite) {
|
|||
user, ok := caseInsensitiveResources[0].(map[string]interface{})
|
||||
assert.True(t, ok, "User should be an object")
|
||||
assert.Equal(t, userID, user["id"], "Should be the same user despite case differences in userName filter")
|
||||
assert.Equal(t, "testuser@example.com", user["userName"], "Original userName should be preserved")
|
||||
assert.Equal(t, userName, user["userName"], "Original userName should be preserved")
|
||||
}
|
||||
|
||||
// Test filtering users by non-existent userName
|
||||
|
|
@ -276,14 +284,14 @@ func testUsersBasicCRUD(t *testing.T, s *Suite) {
|
|||
// Test updating a user
|
||||
updateUserPayload := map[string]interface{}{
|
||||
"schemas": []string{"urn:ietf:params:scim:schemas:core:2.0:User"},
|
||||
"userName": "testuser@example.com",
|
||||
"userName": userName,
|
||||
"name": map[string]interface{}{
|
||||
"givenName": "Updated",
|
||||
"familyName": "User",
|
||||
},
|
||||
"emails": []map[string]interface{}{
|
||||
{
|
||||
"value": "testuser@example.com",
|
||||
"value": userName,
|
||||
"type": "work",
|
||||
"primary": true,
|
||||
},
|
||||
|
|
@ -293,7 +301,7 @@ func testUsersBasicCRUD(t *testing.T, s *Suite) {
|
|||
|
||||
var updateResp map[string]interface{}
|
||||
s.DoJSON(t, "PUT", scimPath("/Users/"+userID), updateUserPayload, http.StatusOK, &updateResp)
|
||||
assert.Equal(t, "testuser@example.com", updateResp["userName"])
|
||||
assert.Equal(t, userName, updateResp["userName"])
|
||||
|
||||
// Verify the name was updated
|
||||
name, ok := updateResp["name"].(map[string]interface{})
|
||||
|
|
@ -373,46 +381,43 @@ func testUsersBasicCRUD(t *testing.T, s *Suite) {
|
|||
assert.Contains(t, deleteAgainResp["detail"], "not found")
|
||||
}
|
||||
|
||||
func testGroupsBasicCRUD(t *testing.T, s *Suite) {
|
||||
// First, create a user to add as a member of the group
|
||||
createUserPayload := map[string]interface{}{
|
||||
"schemas": []string{"urn:ietf:params:scim:schemas:core:2.0:User"},
|
||||
"userName": "groupmember@example.com",
|
||||
"name": map[string]interface{}{
|
||||
"givenName": "Group",
|
||||
"familyName": "Member",
|
||||
},
|
||||
"emails": []map[string]interface{}{
|
||||
{
|
||||
"value": "groupmember@example.com",
|
||||
"type": "work",
|
||||
"primary": true,
|
||||
},
|
||||
},
|
||||
"active": true,
|
||||
// createTestGroup creates a test group with the given display name and members and returns the group ID and response
|
||||
func createTestGroup(t *testing.T, s *Suite, displayName string, memberIDs []string) (string, map[string]interface{}) {
|
||||
members := make([]map[string]interface{}, 0, len(memberIDs))
|
||||
for _, id := range memberIDs {
|
||||
members = append(members, map[string]interface{}{
|
||||
"value": id,
|
||||
})
|
||||
}
|
||||
|
||||
var createUserResp map[string]interface{}
|
||||
s.DoJSON(t, "POST", scimPath("/Users"), createUserPayload, http.StatusCreated, &createUserResp)
|
||||
userID := createUserResp["id"].(string)
|
||||
assert.NotEmpty(t, userID)
|
||||
|
||||
// Test creating a group
|
||||
createGroupPayload := map[string]interface{}{
|
||||
"schemas": []string{"urn:ietf:params:scim:schemas:core:2.0:Group"},
|
||||
"displayName": "Test Group",
|
||||
"members": []map[string]interface{}{
|
||||
{
|
||||
"value": userID,
|
||||
},
|
||||
},
|
||||
"displayName": displayName,
|
||||
}
|
||||
|
||||
if len(members) > 0 {
|
||||
createGroupPayload["members"] = members
|
||||
}
|
||||
|
||||
var createResp map[string]interface{}
|
||||
s.DoJSON(t, "POST", scimPath("/Groups"), createGroupPayload, http.StatusCreated, &createResp)
|
||||
|
||||
// Verify the created group
|
||||
assert.Equal(t, "Test Group", createResp["displayName"])
|
||||
assert.Equal(t, displayName, createResp["displayName"])
|
||||
|
||||
// Extract the group ID
|
||||
groupID := createResp["id"].(string)
|
||||
assert.NotEmpty(t, groupID)
|
||||
|
||||
return groupID, createResp
|
||||
}
|
||||
|
||||
func testGroupsBasicCRUD(t *testing.T, s *Suite) {
|
||||
// First, create a user to add as a member of the group
|
||||
userID, _ := createTestUser(t, s, "groupmember@example.com")
|
||||
|
||||
// Test creating a group
|
||||
groupID, createResp := createTestGroup(t, s, "Test Group", []string{userID})
|
||||
|
||||
// Verify members
|
||||
members, ok := createResp["members"].([]interface{})
|
||||
|
|
@ -423,10 +428,6 @@ func testGroupsBasicCRUD(t *testing.T, s *Suite) {
|
|||
assert.Equal(t, "User", member["type"])
|
||||
assert.Equal(t, "Users/"+userID, member["$ref"])
|
||||
|
||||
// Extract the group ID for subsequent operations
|
||||
groupID := createResp["id"].(string)
|
||||
assert.NotEmpty(t, groupID)
|
||||
|
||||
// Test getting a group by ID
|
||||
var getResp map[string]interface{}
|
||||
s.DoJSON(t, "GET", scimPath("/Groups/"+groupID), nil, http.StatusOK, &getResp)
|
||||
|
|
@ -1163,26 +1164,7 @@ func testUsersPagination(t *testing.T, s *Suite) {
|
|||
|
||||
for i := 1; i <= 10; i++ {
|
||||
userName := fmt.Sprintf("pagination-user-%d@example.com", i)
|
||||
createUserPayload := map[string]interface{}{
|
||||
"schemas": []string{"urn:ietf:params:scim:schemas:core:2.0:User"},
|
||||
"userName": userName,
|
||||
"name": map[string]interface{}{
|
||||
"givenName": fmt.Sprintf("User%d", i),
|
||||
"familyName": "Pagination",
|
||||
},
|
||||
"emails": []map[string]interface{}{
|
||||
{
|
||||
"value": userName,
|
||||
"type": "work",
|
||||
"primary": true,
|
||||
},
|
||||
},
|
||||
"active": true,
|
||||
}
|
||||
|
||||
var createResp map[string]interface{}
|
||||
s.DoJSON(t, "POST", scimPath("/Users"), createUserPayload, http.StatusCreated, &createResp)
|
||||
userID := createResp["id"].(string)
|
||||
userID, _ := createTestUser(t, s, userName)
|
||||
userIDs = append(userIDs, userID)
|
||||
}
|
||||
|
||||
|
|
@ -1318,54 +1300,19 @@ func testUsersPagination(t *testing.T, s *Suite) {
|
|||
|
||||
func testGroupsPagination(t *testing.T, s *Suite) {
|
||||
// First, create a user to be added as a member of some groups
|
||||
createUserPayload := map[string]interface{}{
|
||||
"schemas": []string{"urn:ietf:params:scim:schemas:core:2.0:User"},
|
||||
"userName": "group-pagination-member@example.com",
|
||||
"name": map[string]interface{}{
|
||||
"givenName": "Group",
|
||||
"familyName": "PaginationMember",
|
||||
},
|
||||
"emails": []map[string]interface{}{
|
||||
{
|
||||
"value": "group-pagination-member@example.com",
|
||||
"type": "work",
|
||||
"primary": true,
|
||||
},
|
||||
},
|
||||
"active": true,
|
||||
}
|
||||
|
||||
var createUserResp map[string]interface{}
|
||||
s.DoJSON(t, "POST", scimPath("/Users"), createUserPayload, http.StatusCreated, &createUserResp)
|
||||
userID := createUserResp["id"].(string)
|
||||
assert.NotEmpty(t, userID)
|
||||
userID, _ := createTestUser(t, s, "group-pagination-member@example.com")
|
||||
|
||||
// Create multiple groups for pagination testing
|
||||
groupIDs := make([]string, 0, 10)
|
||||
|
||||
for i := 1; i <= 10; i++ {
|
||||
// Add the user as a member to even-numbered groups
|
||||
var members []map[string]interface{}
|
||||
var memberIDs []string
|
||||
if i%2 == 0 {
|
||||
members = []map[string]interface{}{
|
||||
{
|
||||
"value": userID,
|
||||
},
|
||||
}
|
||||
memberIDs = []string{userID}
|
||||
}
|
||||
|
||||
createGroupPayload := map[string]interface{}{
|
||||
"schemas": []string{"urn:ietf:params:scim:schemas:core:2.0:Group"},
|
||||
"displayName": fmt.Sprintf("Pagination Group %d", i),
|
||||
}
|
||||
|
||||
if len(members) > 0 {
|
||||
createGroupPayload["members"] = members
|
||||
}
|
||||
|
||||
var createResp map[string]interface{}
|
||||
s.DoJSON(t, "POST", scimPath("/Groups"), createGroupPayload, http.StatusCreated, &createResp)
|
||||
groupID := createResp["id"].(string)
|
||||
groupID, _ := createTestGroup(t, s, fmt.Sprintf("Pagination Group %d", i), memberIDs)
|
||||
groupIDs = append(groupIDs, groupID)
|
||||
}
|
||||
|
||||
|
|
@ -1538,69 +1485,16 @@ func testUsersAndGroups(t *testing.T, s *Suite) {
|
|||
userIDs := make([]string, 0, 3)
|
||||
for i := 1; i <= 3; i++ {
|
||||
userName := fmt.Sprintf("user-group-test-%d@example.com", i)
|
||||
createUserPayload := map[string]interface{}{
|
||||
"schemas": []string{"urn:ietf:params:scim:schemas:core:2.0:User"},
|
||||
"userName": userName,
|
||||
"name": map[string]interface{}{
|
||||
"givenName": fmt.Sprintf("User%d", i),
|
||||
"familyName": "GroupTest",
|
||||
},
|
||||
"emails": []map[string]interface{}{
|
||||
{
|
||||
"value": userName,
|
||||
"type": "work",
|
||||
"primary": true,
|
||||
},
|
||||
},
|
||||
"active": true,
|
||||
}
|
||||
|
||||
var createResp map[string]interface{}
|
||||
s.DoJSON(t, "POST", scimPath("/Users"), createUserPayload, http.StatusCreated, &createResp)
|
||||
userID := createResp["id"].(string)
|
||||
userID, _ := createTestUser(t, s, userName)
|
||||
userIDs = append(userIDs, userID)
|
||||
}
|
||||
|
||||
// Create two groups with different membership patterns
|
||||
// Group 1: Contains users 1 and 2
|
||||
group1Members := []map[string]interface{}{
|
||||
{
|
||||
"value": userIDs[0],
|
||||
},
|
||||
{
|
||||
"value": userIDs[1],
|
||||
},
|
||||
}
|
||||
|
||||
createGroup1Payload := map[string]interface{}{
|
||||
"schemas": []string{"urn:ietf:params:scim:schemas:core:2.0:Group"},
|
||||
"displayName": "Test Group 1",
|
||||
"members": group1Members,
|
||||
}
|
||||
|
||||
var createGroup1Resp map[string]interface{}
|
||||
s.DoJSON(t, "POST", scimPath("/Groups"), createGroup1Payload, http.StatusCreated, &createGroup1Resp)
|
||||
group1ID := createGroup1Resp["id"].(string)
|
||||
group1ID, _ := createTestGroup(t, s, "Test Group 1", []string{userIDs[0], userIDs[1]})
|
||||
|
||||
// Group 2: Contains users 2 and 3
|
||||
group2Members := []map[string]interface{}{
|
||||
{
|
||||
"value": userIDs[1],
|
||||
},
|
||||
{
|
||||
"value": userIDs[2],
|
||||
},
|
||||
}
|
||||
|
||||
createGroup2Payload := map[string]interface{}{
|
||||
"schemas": []string{"urn:ietf:params:scim:schemas:core:2.0:Group"},
|
||||
"displayName": "Test Group 2",
|
||||
"members": group2Members,
|
||||
}
|
||||
|
||||
var createGroup2Resp map[string]interface{}
|
||||
s.DoJSON(t, "POST", scimPath("/Groups"), createGroup2Payload, http.StatusCreated, &createGroup2Resp)
|
||||
group2ID := createGroup2Resp["id"].(string)
|
||||
group2ID, _ := createTestGroup(t, s, "Test Group 2", []string{userIDs[1], userIDs[2]})
|
||||
|
||||
// Test 1: Verify that User 1 is in Group 1 only
|
||||
var user1Resp map[string]interface{}
|
||||
|
|
|
|||
Loading…
Reference in a new issue