Loading gitlab_test/groups_integration_test.go +53 −0 Original line number Diff line number Diff line Loading @@ -166,3 +166,56 @@ func Test_GroupProtectedBranches_Integration(t *testing.T) { assert.Error(t, err) assert.Equal(t, 404, resp.StatusCode) } func Test_GroupsCreateGroup_CodeOwnerApprovalRequired_Integration(t *testing.T) { // GIVEN a GitLab client client := SetupIntegrationClient(t) // WHEN creating a group with CodeOwnerApprovalRequired enabled group, _, err := client.Groups.CreateGroup(&gitlab.CreateGroupOptions{ Name: gitlab.Ptr("code-owner-create-test"), Path: gitlab.Ptr("code-owner-create-test"), DefaultBranchProtectionDefaults: &gitlab.DefaultBranchProtectionDefaultsOptions{ CodeOwnerApprovalRequired: gitlab.Ptr(true), }, }) require.NoError(t, err, "Failed to create group") // THEN the setting should be enabled require.NotNil(t, group.DefaultBranchProtectionDefaults) assert.True(t, group.DefaultBranchProtectionDefaults.CodeOwnerApprovalRequired) // AND WHEN retrieving the group retrievedGroup, _, err := client.Groups.GetGroup(group.ID, nil) require.NoError(t, err) // THEN it should persist require.NotNil(t, retrievedGroup.DefaultBranchProtectionDefaults) assert.True(t, retrievedGroup.DefaultBranchProtectionDefaults.CodeOwnerApprovalRequired) } func Test_GroupsUpdateGroup_CodeOwnerApprovalRequired_Integration(t *testing.T) { // GIVEN a GitLab client and a test group client := SetupIntegrationClient(t) group := CreateTestGroup(t, client) // WHEN updating CodeOwnerApprovalRequired to true updatedGroup, _, err := client.Groups.UpdateGroup(group.ID, &gitlab.UpdateGroupOptions{ DefaultBranchProtectionDefaults: &gitlab.DefaultBranchProtectionDefaultsOptions{ CodeOwnerApprovalRequired: gitlab.Ptr(true), }, }) require.NoError(t, err) // THEN the update response should reflect the change require.NotNil(t, updatedGroup.DefaultBranchProtectionDefaults) assert.True(t, updatedGroup.DefaultBranchProtectionDefaults.CodeOwnerApprovalRequired) // AND WHEN retrieving the group again retrievedGroup, _, err := client.Groups.GetGroup(group.ID, nil) require.NoError(t, err) // THEN the setting should persist require.NotNil(t, retrievedGroup.DefaultBranchProtectionDefaults) assert.True(t, retrievedGroup.DefaultBranchProtectionDefaults.CodeOwnerApprovalRequired) } groups.go +14 −8 Original line number Diff line number Diff line Loading @@ -189,6 +189,7 @@ type BranchProtectionDefaults struct { AllowForcePush bool `json:"allow_force_push,omitempty"` AllowedToMerge []*GroupAccessLevel `json:"allowed_to_merge,omitempty"` DeveloperCanInitialPush bool `json:"developer_can_initial_push,omitempty"` CodeOwnerApprovalRequired bool `json:"code_owner_approval_required,omitempty"` } // GroupAccessLevel represents default branch protection defaults access levels. Loading Loading @@ -425,6 +426,7 @@ type DefaultBranchProtectionDefaultsOptions struct { AllowForcePush *bool `url:"allow_force_push,omitempty" json:"allow_force_push,omitempty"` AllowedToMerge *[]*GroupAccessLevel `url:"allowed_to_merge,omitempty" json:"allowed_to_merge,omitempty"` DeveloperCanInitialPush *bool `url:"developer_can_initial_push,omitempty" json:"developer_can_initial_push,omitempty"` CodeOwnerApprovalRequired *bool `url:"code_owner_approval_required,omitempty" json:"code_owner_approval_required,omitempty"` } // EncodeValues implements the query.Encoder interface Loading @@ -435,6 +437,9 @@ func (d *DefaultBranchProtectionDefaultsOptions) EncodeValues(key string, v *url if d.DeveloperCanInitialPush != nil { v.Add(key+"[developer_can_initial_push]", strconv.FormatBool(*d.DeveloperCanInitialPush)) } if d.CodeOwnerApprovalRequired != nil { v.Add(key+"[code_owner_approval_required]", strconv.FormatBool(*d.CodeOwnerApprovalRequired)) } // The GitLab API only accepts one value for `allowed_to_merge` even when multiples are // provided on the request. The API will take the highest permission level. For instance, // if 'developer' and 'maintainer' are provided, the API will take 'maintainer'. Loading @@ -455,6 +460,7 @@ func (d *DefaultBranchProtectionDefaultsOptions) EncodeValues(key string, v *url } } } return nil } Loading groups_test.go +19 −2 Original line number Diff line number Diff line Loading @@ -221,7 +221,8 @@ func TestCreateGroupDefaultBranchSettings(t *testing.T) { { "access_level": 40 } ] ], "code_owner_approval_required": true } } `) Loading @@ -241,6 +242,7 @@ func TestCreateGroupDefaultBranchSettings(t *testing.T) { AccessLevel: Ptr(AccessLevelValue(40)), }, }, CodeOwnerApprovalRequired: Ptr(true), }, } Loading @@ -265,6 +267,7 @@ func TestCreateGroupDefaultBranchSettings(t *testing.T) { AccessLevel: Ptr(MaintainerPermissions), }, }, CodeOwnerApprovalRequired: true, }, } Loading @@ -275,8 +278,13 @@ func TestCreateGroupDefaultBranchSettings(t *testing.T) { // Validate the request does what we want it to allowedToMerge := *jsonRequestBody.DefaultBranchProtectionDefaults.AllowedToMerge allowedToPush := *jsonRequestBody.DefaultBranchProtectionDefaults.AllowedToPush assert.Equal(t, Ptr(MaintainerPermissions), allowedToMerge[0].AccessLevel) assert.Equal(t, Ptr(MaintainerPermissions), allowedToPush[0].AccessLevel) assert.True( t, *jsonRequestBody.DefaultBranchProtectionDefaults.CodeOwnerApprovalRequired, ) } func TestTransferGroup(t *testing.T) { Loading Loading @@ -1389,6 +1397,12 @@ func TestCreateGroupDefaultBranchSettingsWithAvatar(t *testing.T) { testFormBody(t, r, "path", "g") testFormBody(t, r, "default_branch_protection_defaults[allowed_to_push][][access_level]", "40") testFormBody(t, r, "default_branch_protection_defaults[allowed_to_merge][][access_level]", "40") testFormBody( t, r, "default_branch_protection_defaults[code_owner_approval_required]", "true", ) fmt.Fprint(w, ` { Loading @@ -1406,7 +1420,8 @@ func TestCreateGroupDefaultBranchSettingsWithAvatar(t *testing.T) { { "access_level": 40 } ] ], "code_owner_approval_required": true }, "avatar_url":"http://localhost/uploads/-/system/group/avatar/999/avatar.png" } Loading @@ -1433,6 +1448,7 @@ func TestCreateGroupDefaultBranchSettingsWithAvatar(t *testing.T) { AccessLevel: Ptr(AccessLevelValue(40)), }, }, CodeOwnerApprovalRequired: Ptr(true), }, } Loading Loading @@ -1460,6 +1476,7 @@ func TestCreateGroupDefaultBranchSettingsWithAvatar(t *testing.T) { AccessLevel: Ptr(MaintainerPermissions), }, }, CodeOwnerApprovalRequired: true, }, } Loading Loading
gitlab_test/groups_integration_test.go +53 −0 Original line number Diff line number Diff line Loading @@ -166,3 +166,56 @@ func Test_GroupProtectedBranches_Integration(t *testing.T) { assert.Error(t, err) assert.Equal(t, 404, resp.StatusCode) } func Test_GroupsCreateGroup_CodeOwnerApprovalRequired_Integration(t *testing.T) { // GIVEN a GitLab client client := SetupIntegrationClient(t) // WHEN creating a group with CodeOwnerApprovalRequired enabled group, _, err := client.Groups.CreateGroup(&gitlab.CreateGroupOptions{ Name: gitlab.Ptr("code-owner-create-test"), Path: gitlab.Ptr("code-owner-create-test"), DefaultBranchProtectionDefaults: &gitlab.DefaultBranchProtectionDefaultsOptions{ CodeOwnerApprovalRequired: gitlab.Ptr(true), }, }) require.NoError(t, err, "Failed to create group") // THEN the setting should be enabled require.NotNil(t, group.DefaultBranchProtectionDefaults) assert.True(t, group.DefaultBranchProtectionDefaults.CodeOwnerApprovalRequired) // AND WHEN retrieving the group retrievedGroup, _, err := client.Groups.GetGroup(group.ID, nil) require.NoError(t, err) // THEN it should persist require.NotNil(t, retrievedGroup.DefaultBranchProtectionDefaults) assert.True(t, retrievedGroup.DefaultBranchProtectionDefaults.CodeOwnerApprovalRequired) } func Test_GroupsUpdateGroup_CodeOwnerApprovalRequired_Integration(t *testing.T) { // GIVEN a GitLab client and a test group client := SetupIntegrationClient(t) group := CreateTestGroup(t, client) // WHEN updating CodeOwnerApprovalRequired to true updatedGroup, _, err := client.Groups.UpdateGroup(group.ID, &gitlab.UpdateGroupOptions{ DefaultBranchProtectionDefaults: &gitlab.DefaultBranchProtectionDefaultsOptions{ CodeOwnerApprovalRequired: gitlab.Ptr(true), }, }) require.NoError(t, err) // THEN the update response should reflect the change require.NotNil(t, updatedGroup.DefaultBranchProtectionDefaults) assert.True(t, updatedGroup.DefaultBranchProtectionDefaults.CodeOwnerApprovalRequired) // AND WHEN retrieving the group again retrievedGroup, _, err := client.Groups.GetGroup(group.ID, nil) require.NoError(t, err) // THEN the setting should persist require.NotNil(t, retrievedGroup.DefaultBranchProtectionDefaults) assert.True(t, retrievedGroup.DefaultBranchProtectionDefaults.CodeOwnerApprovalRequired) }
groups.go +14 −8 Original line number Diff line number Diff line Loading @@ -189,6 +189,7 @@ type BranchProtectionDefaults struct { AllowForcePush bool `json:"allow_force_push,omitempty"` AllowedToMerge []*GroupAccessLevel `json:"allowed_to_merge,omitempty"` DeveloperCanInitialPush bool `json:"developer_can_initial_push,omitempty"` CodeOwnerApprovalRequired bool `json:"code_owner_approval_required,omitempty"` } // GroupAccessLevel represents default branch protection defaults access levels. Loading Loading @@ -425,6 +426,7 @@ type DefaultBranchProtectionDefaultsOptions struct { AllowForcePush *bool `url:"allow_force_push,omitempty" json:"allow_force_push,omitempty"` AllowedToMerge *[]*GroupAccessLevel `url:"allowed_to_merge,omitempty" json:"allowed_to_merge,omitempty"` DeveloperCanInitialPush *bool `url:"developer_can_initial_push,omitempty" json:"developer_can_initial_push,omitempty"` CodeOwnerApprovalRequired *bool `url:"code_owner_approval_required,omitempty" json:"code_owner_approval_required,omitempty"` } // EncodeValues implements the query.Encoder interface Loading @@ -435,6 +437,9 @@ func (d *DefaultBranchProtectionDefaultsOptions) EncodeValues(key string, v *url if d.DeveloperCanInitialPush != nil { v.Add(key+"[developer_can_initial_push]", strconv.FormatBool(*d.DeveloperCanInitialPush)) } if d.CodeOwnerApprovalRequired != nil { v.Add(key+"[code_owner_approval_required]", strconv.FormatBool(*d.CodeOwnerApprovalRequired)) } // The GitLab API only accepts one value for `allowed_to_merge` even when multiples are // provided on the request. The API will take the highest permission level. For instance, // if 'developer' and 'maintainer' are provided, the API will take 'maintainer'. Loading @@ -455,6 +460,7 @@ func (d *DefaultBranchProtectionDefaultsOptions) EncodeValues(key string, v *url } } } return nil } Loading
groups_test.go +19 −2 Original line number Diff line number Diff line Loading @@ -221,7 +221,8 @@ func TestCreateGroupDefaultBranchSettings(t *testing.T) { { "access_level": 40 } ] ], "code_owner_approval_required": true } } `) Loading @@ -241,6 +242,7 @@ func TestCreateGroupDefaultBranchSettings(t *testing.T) { AccessLevel: Ptr(AccessLevelValue(40)), }, }, CodeOwnerApprovalRequired: Ptr(true), }, } Loading @@ -265,6 +267,7 @@ func TestCreateGroupDefaultBranchSettings(t *testing.T) { AccessLevel: Ptr(MaintainerPermissions), }, }, CodeOwnerApprovalRequired: true, }, } Loading @@ -275,8 +278,13 @@ func TestCreateGroupDefaultBranchSettings(t *testing.T) { // Validate the request does what we want it to allowedToMerge := *jsonRequestBody.DefaultBranchProtectionDefaults.AllowedToMerge allowedToPush := *jsonRequestBody.DefaultBranchProtectionDefaults.AllowedToPush assert.Equal(t, Ptr(MaintainerPermissions), allowedToMerge[0].AccessLevel) assert.Equal(t, Ptr(MaintainerPermissions), allowedToPush[0].AccessLevel) assert.True( t, *jsonRequestBody.DefaultBranchProtectionDefaults.CodeOwnerApprovalRequired, ) } func TestTransferGroup(t *testing.T) { Loading Loading @@ -1389,6 +1397,12 @@ func TestCreateGroupDefaultBranchSettingsWithAvatar(t *testing.T) { testFormBody(t, r, "path", "g") testFormBody(t, r, "default_branch_protection_defaults[allowed_to_push][][access_level]", "40") testFormBody(t, r, "default_branch_protection_defaults[allowed_to_merge][][access_level]", "40") testFormBody( t, r, "default_branch_protection_defaults[code_owner_approval_required]", "true", ) fmt.Fprint(w, ` { Loading @@ -1406,7 +1420,8 @@ func TestCreateGroupDefaultBranchSettingsWithAvatar(t *testing.T) { { "access_level": 40 } ] ], "code_owner_approval_required": true }, "avatar_url":"http://localhost/uploads/-/system/group/avatar/999/avatar.png" } Loading @@ -1433,6 +1448,7 @@ func TestCreateGroupDefaultBranchSettingsWithAvatar(t *testing.T) { AccessLevel: Ptr(AccessLevelValue(40)), }, }, CodeOwnerApprovalRequired: Ptr(true), }, } Loading Loading @@ -1460,6 +1476,7 @@ func TestCreateGroupDefaultBranchSettingsWithAvatar(t *testing.T) { AccessLevel: Ptr(MaintainerPermissions), }, }, CodeOwnerApprovalRequired: true, }, } Loading