def test__mattermost_confidential_issues_events(self, gitlab, group_and_project): config_service_mattermost_confidential_issues_events = f""" projects_and_groups: {group_and_project}: services: mattermost: active: true webhook: https://mattermost.com/hooks/xxx username: gitlab merge_requests_events: true merge_request_channel: "merge-requests" push_events: false issues_events: false confidential_issues_events: false # this was not supposed to work according to #70 tag_push_events: false note_events: false confidential_note_events: false pipeline_events: false wiki_page_events: false branches_to_be_notified: "all" """ run_gitlabform(config_service_mattermost_confidential_issues_events, group_and_project) service = gitlab.get_service(group_and_project, "mattermost") assert service["confidential_issues_events"] is False
def test__enforce( self, gitlab, group_and_project, three_members, outsider_user, ): members_before = gitlab.get_project_members(group_and_project) assert len(members_before) > 0 members_usernames_before = [ member["username"] for member in members_before ] assert outsider_user not in members_usernames_before enforce_users = f""" projects_and_groups: {group_and_project}: members: users: {outsider_user}: # new user access_level: {AccessLevel.MAINTAINER.value} enforce: true """ run_gitlabform(enforce_users, group_and_project) members = gitlab.get_project_members(group_and_project) assert len(members) == 1 assert members[0]["username"] == outsider_user
def test__remove_group_old_syntax(self, gitlab, group, users, groups, one_owner): gitlab.add_share_to_group(group, groups[0], AccessLevel.OWNER.value) gitlab.add_share_to_group(group, groups[1], AccessLevel.OWNER.value) no_of_members_before = len(gitlab.get_group_members(group)) no_of_shared_with_before = len(gitlab.get_group_shared_with(group)) remove_group = f""" projects_and_groups: {group}/*: enforce_group_members: true group_members: {users[0]}: access_level: {AccessLevel.OWNER.value} group_shared_with: {groups[0]}: group_access_level: {AccessLevel.DEVELOPER.value} """ run_gitlabform(remove_group, group) members = gitlab.get_group_members(group) assert len(members) == no_of_members_before shared_with = gitlab.get_group_shared_with(group) assert len(shared_with) == no_of_shared_with_before - 1 assert [sw["group_name"] for sw in shared_with] == [groups[0]]
def test__delete_file_specific_branch(self, gitlab, group_and_project, branch): set_file_specific_branch = f""" projects_and_groups: {group_and_project}: branches: {branch}: protected: true developers_can_push: false developers_can_merge: true files: "README.md": branches: - {branch} delete: true """ run_gitlabform(set_file_specific_branch, group_and_project) commit = gitlab.get_last_commit(group_and_project, branch) assert commit["message"] == "Automated delete made by gitlabform" with pytest.raises(NotFoundException): gitlab.get_file(group_and_project, branch, "README.md") # check if main stays protected after the file delete the_branch = gitlab.get_branch(group_and_project, branch) assert the_branch["protected"] is True
def test__remove_user_old_syntax( self, gitlab, group, users, one_owner_and_two_developers ): no_of_members_before = len(gitlab.get_group_members(group)) user_to_remove = f"{users[2]}" remove_users = f""" projects_and_groups: {group}/*: enforce_group_members: true group_members: {users[0]}: access_level: {AccessLevel.OWNER.value} {users[1]}: access_level: {AccessLevel.DEVELOPER.value} """ run_gitlabform(remove_users, group) members = gitlab.get_group_members(group) assert len(members) == no_of_members_before - 1 members_usernames = [member["username"] for member in members] assert user_to_remove not in members_usernames
def test__replace_existing_schedules(self, gitlab, group_and_project, schedules): replace_schedules = f""" projects_and_groups: {group_and_project}: schedules: "Existing schedule to replace": ref: scheduled/new-feature cron: "0 */3 * * *" cron_timezone: "London" active: true """ run_gitlabform(replace_schedules, group_and_project) schedules = self.__find_pipeline_schedules_by_description( gitlab, group_and_project, "Existing schedule to replace") assert schedules is not None assert len(schedules) == 1 assert schedules[0]["description"] == "Existing schedule to replace" assert schedules[0]["ref"] == "scheduled/new-feature" assert schedules[0]["cron"] == "0 */3 * * *" assert schedules[0]["cron_timezone"] == "London" assert schedules[0]["active"] is True
def test__unprotect_when_the_rest_of_the_parameters_are_still_specified_old_api( self, gitlab, group_and_project, branch): config_protect_branch_with_old_api = f""" projects_and_groups: {group_and_project}: branches: {branch}: protected: true developers_can_push: true developers_can_merge: true """ run_gitlabform(config_protect_branch_with_old_api, group_and_project) the_branch = gitlab.get_branch(group_and_project, branch) assert the_branch["protected"] is True assert the_branch["developers_can_push"] is True assert the_branch["developers_can_merge"] is True config_unprotect_branch_with_old_api = f""" projects_and_groups: {group_and_project}: branches: {branch}: protected: false developers_can_push: true developers_can_merge: true """ run_gitlabform(config_unprotect_branch_with_old_api, group_and_project) the_branch = gitlab.get_branch(group_and_project, branch) assert the_branch["protected"] is False
def test__add_user_with_access_level_names( self, gitlab, group_and_project, three_members, outsider_user ): members_before = gitlab.get_project_members(group_and_project) assert len(members_before) > 0 members_usernames_before = [member["username"] for member in members_before] assert outsider_user not in members_usernames_before add_users = f""" projects_and_groups: {group_and_project}: members: users: {outsider_user}: # new user access_level: maintainer """ run_gitlabform(add_users, group_and_project) members = gitlab.get_project_members(group_and_project) assert len(members) == len(members_usernames_before) + 1 members_usernames = [member["username"] for member in members] assert outsider_user in members_usernames
def test__change_group_access(self, gitlab, group, groups, users, one_owner): change_some_users_access = f""" projects_and_groups: {group}/*: group_members: users: {users[0]}: access_level: {AccessLevel.OWNER.value} groups: {groups[0]}: group_access: {AccessLevel.DEVELOPER.value} {groups[1]}: group_access: {AccessLevel.OWNER.value} """ run_gitlabform(change_some_users_access, group) shared_with = gitlab.get_group_shared_with(group) for shared_with_group in shared_with: if shared_with_group["group_name"] == f"{groups[0]}": assert (shared_with_group["group_access_level"] == AccessLevel.DEVELOPER.value) if shared_with_group["group_name"] == f"{groups[1]}": assert (shared_with_group["group_access_level"] == AccessLevel.OWNER.value)
def test__if_push_events_true_works(self, gitlab, group_and_project): config_service_push_events_true = f""" projects_and_groups: {group_and_project}: services: asana: api_key: foo push_events: true slack: webhook: http://foo.bar.com push_events: true redmine: new_issue_url: http://foo.bar.com project_url: http://foo.bar.com issues_url: http://foo.bar.com push_events: true """ run_gitlabform(config_service_push_events_true, group_and_project) services = [] for service_name in ["asana", "slack", "redmine"]: service = gitlab.get_service(group_and_project, service_name) services.append(service) assert all([service["active"] for service in services]) is True assert all([service["push_events"] for service in services]) is True
def test__change_owner(self, gitlab, group, users, one_owner_and_two_developers): change_owner = f""" projects_and_groups: {group}/*: group_members: users: {users[0]}: access_level: {AccessLevel.DEVELOPER.value} # only developer now {users[1]}: access_level: {AccessLevel.OWNER.value} # new owner {users[2]}: access_level: {AccessLevel.DEVELOPER.value} """ run_gitlabform(change_owner, group) members = gitlab.get_group_members(group) assert len(members) == 3 for member in members: if member["username"] == f"{users[0]}": assert ( member["access_level"] == AccessLevel.DEVELOPER.value ) # only developer now if member["username"] == f"{users[1]}": assert member["access_level"] == AccessLevel.OWNER.value # new owner if member["username"] == f"{users[2]}": assert member["access_level"] == AccessLevel.DEVELOPER.value
def test__add_user_with_access_level_name( self, gitlab, group, users, one_owner_and_two_developers ): no_of_members_before = len(gitlab.get_group_members(group)) user_to_add = f"{users[3]}" add_users = f""" projects_and_groups: {group}/*: group_members: {users[0]}: access_level: owner {users[1]}: access_level: developer {users[2]}: access_level: developer {user_to_add}: # new user 1 access_level: developer """ run_gitlabform(add_users, group) members = gitlab.get_group_members(group) assert len(members) == no_of_members_before + 1 members_usernames = [member["username"] for member in members] assert members_usernames.count(user_to_add) == 1
def test__change_some_users_access( self, gitlab, group, users, one_owner_and_two_developers ): new_access_level = AccessLevel.MAINTAINER.value change_some_users_access = f""" projects_and_groups: {group}/*: group_members: users: {users[0]}: access_level: {AccessLevel.OWNER.value} {users[1]}: access_level: {new_access_level} # changed level {users[2]}: access_level: {new_access_level} # changed level """ run_gitlabform(change_some_users_access, group) members = gitlab.get_group_members(group) for member in members: if member["username"] == f"{users[0]}": assert member["access_level"] == AccessLevel.OWNER.value if member["username"] == f"{users[1]}": assert member["access_level"] == new_access_level if member["username"] == f"{users[2]}": assert member["access_level"] == new_access_level
def test__add_user_old_syntax( self, gitlab, group, users, one_owner_and_two_developers ): no_of_members_before = len(gitlab.get_group_members(group)) user_to_add = f"{users[3]}" add_users = f""" projects_and_groups: {group}/*: group_members: {users[0]}: access_level: {AccessLevel.OWNER.value} {users[1]}: access_level: {AccessLevel.DEVELOPER.value} {users[2]}: access_level: {AccessLevel.DEVELOPER.value} {user_to_add}: # new user 1 access_level: {AccessLevel.DEVELOPER.value} """ run_gitlabform(add_users, group) members = gitlab.get_group_members(group) assert len(members) == no_of_members_before + 1 members_usernames = [member["username"] for member in members] assert members_usernames.count(user_to_add) == 1
def test__set_file_all_branches(self, gitlab, group_and_project, branch, other_branch): set_file_all_branches = f""" projects_and_groups: {group_and_project}: branches: {branch}: protected: true developers_can_push: false developers_can_merge: true {other_branch}: protected: false files: "README.md": overwrite: true branches: all content: "Content for all branches" """ run_gitlabform(set_file_all_branches, group_and_project) for some_branch in [ "main", branch, other_branch, ]: file_content = gitlab.get_file(group_and_project, some_branch, "README.md") assert file_content == "Content for all branches" # check that this branch remains unprotected for some_branch in [ other_branch, ]: some_branch = gitlab.get_branch(group_and_project, some_branch) assert some_branch["protected"] is False
def test__badges_delete(self, gitlab, group): config = f""" projects_and_groups: {group}/*: group_badges: pipeline-status: name: "Group Badge" link_url: "https://gitlab.example.com/%{{project_path}}/-/commits/%{{default_branch}}/foo" image_url: "https://gitlab.example.com/%{{project_path}}/badges/%{{default_branch}}/pipeline.svg" """ run_gitlabform(config, group) badges = gitlab.get_group_badges(group) assert len(badges) == 1 assert badges[0]["name"] == "Group Badge" config = f""" projects_and_groups: {group}/*: group_badges: pipeline-status: name: "Group Badge" delete: true """ run_gitlabform(config, group) badges = gitlab.get_group_badges(group) assert len(badges) == 0
def test__badges_update(self, gitlab, group): config = f""" projects_and_groups: {group}/*: group_badges: pipeline-status: name: "Group Badge" link_url: "https://gitlab.example.com/foo" image_url: "https://gitlab.example.com/pipeline.svg" """ run_gitlabform(config, group) badges = gitlab.get_group_badges(group) assert len(badges) == 1 assert badges[0]["link_url"].endswith("foo") config = f""" projects_and_groups: {group}/*: group_badges: pipeline-status: name: "Group Badge" link_url: "https://gitlab.example.com/bar" image_url: "https://gitlab.example.com/pipeline.svg" """ run_gitlabform(config, group) badges = gitlab.get_group_badges(group) assert len(badges) == 1 assert badges[0]["link_url"].endswith("bar")
def test__dont_edit_archived_project(self, gitlab, group, project): group_and_project = f"{group}/{project}" archive_project = f""" projects_and_groups: {group_and_project}: project: archive: true """ run_gitlabform(archive_project, group_and_project) project = gitlab.get_project(group_and_project) assert project["archived"] is True edit_archived_project = f""" # the project has to be configured as archived # for other configs for it to be ignored projects_and_groups: {group_and_project}: project: archive: true {group}/*: files: README.md: overwrite: true branches: - main content: | Some other content that the default one """ run_gitlabform(edit_archived_project, group_and_project)
def test__sub_group_old_syntax(self, gitlab, group, users, sub_group, one_owner): no_of_members_before = len(gitlab.get_group_members(group)) add_shared_with = f""" projects_and_groups: {group}/*: group_members: {users[0]}: access_level: {AccessLevel.OWNER.value} group_shared_with: {sub_group}: group_access_level: {AccessLevel.DEVELOPER.value} """ run_gitlabform(add_shared_with, group) members = gitlab.get_group_members(group) assert len(members) == no_of_members_before, members shared_with = gitlab.get_group_shared_with(group) assert len(shared_with) == 1 # test second run (issue #236) run_gitlabform(add_shared_with, group)
def test__protect_single_tag(self, gitlab, group_and_project, tags): config = f""" projects_and_groups: {group_and_project}: tags: tag1: protected: true create_access_level: {AccessLevel.MAINTAINER.value} """ run_gitlabform(config, group_and_project) tags = gitlab.get_tags(group_and_project) for tag in tags: if tag["name"] == "tag1": assert tag["protected"] else: assert not tag["protected"] protected_tags = gitlab.get_protected_tags(group_and_project) assert len(protected_tags) == 1 assert protected_tags[0]["name"] == "tag1" assert (protected_tags[0]["create_access_levels"][0]["access_level"] == AccessLevel.MAINTAINER.value)
def test__config_with_access_level_names(self, gitlab, group_and_project, branch): config_with_access_levels_names = f""" projects_and_groups: {group_and_project}: branches: {branch}: protected: true push_access_level: no_access # note "_" or " " and the various merge_access_level: Developer # case in each line. it should not unprotect_access_level: MAINTAINER # matter as we allow any case. """ run_gitlabform(config_with_access_levels_names, group_and_project) ( push_access_level, merge_access_level, push_access_user_ids, merge_access_user_ids, unprotect_access_level, ) = gitlab.get_only_branch_access_levels(group_and_project, branch) assert push_access_level == [AccessLevel.NO_ACCESS.value] assert merge_access_level == [AccessLevel.DEVELOPER.value] assert push_access_user_ids == [] assert merge_access_user_ids == [] assert unprotect_access_level is AccessLevel.MAINTAINER.value
def test__unprotect_when_the_rest_of_the_parameters_are_still_specified_new_api( self, gitlab, group_and_project, branch): config_protect_branch_with_new_api = f""" projects_and_groups: {group_and_project}: branches: {branch}: protected: true push_access_level: {AccessLevel.NO_ACCESS.value} merge_access_level: {AccessLevel.MAINTAINER.value} unprotect_access_level: {AccessLevel.MAINTAINER.value} """ run_gitlabform(config_protect_branch_with_new_api, group_and_project) ( push_access_levels, merge_access_levels, push_access_user_ids, merge_access_user_ids, unprotect_access_level, ) = gitlab.get_only_branch_access_levels(group_and_project, branch) assert push_access_levels == [AccessLevel.NO_ACCESS.value] assert merge_access_levels == [AccessLevel.MAINTAINER.value] assert push_access_user_ids == [] assert merge_access_user_ids == [] assert unprotect_access_level is AccessLevel.MAINTAINER.value config_unprotect_branch_with_new_api = f""" projects_and_groups: {group_and_project}: branches: {branch}: protected: false push_access_level: {AccessLevel.NO_ACCESS.value} merge_access_level: {AccessLevel.MAINTAINER.value} unprotect_access_level: {AccessLevel.MAINTAINER.value} """ run_gitlabform(config_unprotect_branch_with_new_api, group_and_project) # old API branch = gitlab.get_branch(group_and_project, branch) assert branch["protected"] is False # new API ( push_access_levels, merge_access_levels, push_access_user_ids, merge_access_user_ids, unprotect_access_level, ) = gitlab.get_only_branch_access_levels(group_and_project, branch) assert push_access_levels is None assert merge_access_levels is None assert push_access_user_ids is None assert merge_access_user_ids is None assert unprotect_access_level is None
def test__archive_project(self, gitlab, group_and_project): config = f""" projects_and_groups: {group_and_project}: project: archive: true """ run_gitlabform(config, group_and_project) project = gitlab.get_project(group_and_project) assert project["archived"] is True
def test__no_groups_and_no_users(self, gitlab, group_and_project): config_with_error = f""" projects_and_groups: {group_and_project}: members: # there should be a sub-key 'users' here, not directly a user some_user1: access_level: {AccessLevel.DEVELOPER.value} """ with pytest.raises(SystemExit): run_gitlabform(config_with_error, group_and_project)
def test__builds_for_private_projects(self, gitlab, group_and_project): settings = gitlab.get_project_settings(group_and_project) assert settings["visibility"] == "private" config_builds_for_private_projects = f""" projects_and_groups: {group_and_project}: project_settings: visibility: internal """ run_gitlabform(config_builds_for_private_projects, group_and_project) settings = gitlab.get_project_settings(group_and_project) assert settings["visibility"] == "internal"
def test__ALL(self, gitlab, group, project, other_project): config = f""" projects_and_groups: '*': project_settings: request_access_enabled: true """ run_gitlabform(config, "ALL") project = gitlab.get_project(f"{group}/{project}") assert project["request_access_enabled"] is True other_project = gitlab.get_project(f"{group}/{other_project}") assert other_project["request_access_enabled"] is True
def test__delete_schedule(self, gitlab, group_and_project, schedules): delete_schedule = f""" projects_and_groups: {group_and_project}: schedules: "Redundant schedule": delete: True """ run_gitlabform(delete_schedule, group_and_project) schedule = self.__find_pipeline_schedule_by_description_and_get_first( gitlab, group_and_project, "Redundant schedule") assert schedule is None
def test__remove_all(self, gitlab, group, users, one_owner): no_shared_with = f""" projects_and_groups: {group}/*: group_members: enforce: true users: {users[0]}: access_level: {AccessLevel.OWNER.value} """ run_gitlabform(no_shared_with, group) shared_with = gitlab.get_group_shared_with(group) assert len(shared_with) == 0
def test__allow_user_ids( self, gitlab, group_and_project, branch, make_user, ): user_allowed_to_push = make_user(AccessLevel.DEVELOPER) user_allowed_to_merge = make_user(AccessLevel.DEVELOPER) user_allowed_to_push_and_merge = make_user(AccessLevel.DEVELOPER) config_with_user_ids = f""" projects_and_groups: {group_and_project}: branches: {branch}: protected: true allowed_to_push: - user_id: {user_allowed_to_push.id} - access_level: {AccessLevel.NO_ACCESS.value} - user: {user_allowed_to_push_and_merge.name} allowed_to_merge: - access_level: {AccessLevel.DEVELOPER.value} - user_id: {user_allowed_to_merge.id} - user: {user_allowed_to_push_and_merge.name} """ run_gitlabform(config_with_user_ids, group_and_project) ( push_access_levels, merge_access_levels, push_access_user_ids, merge_access_user_ids, _, ) = gitlab.get_only_branch_access_levels(group_and_project, branch) assert push_access_levels == [AccessLevel.NO_ACCESS.value] assert merge_access_levels == [AccessLevel.DEVELOPER.value] assert push_access_user_ids == sorted([ user_allowed_to_push.id, user_allowed_to_push_and_merge.id, ]) assert merge_access_user_ids == sorted([ user_allowed_to_merge.id, user_allowed_to_push_and_merge.id, ])
def test__badges_add(self, gitlab, group_and_project): config = f""" projects_and_groups: {group_and_project}: badges: pipeline-status: name: "Project Badge" link_url: "https://gitlab.example.com/%{{project_path}}/-/commits/%{{default_branch}}/foo" image_url: "https://gitlab.example.com/%{{project_path}}/badges/%{{default_branch}}/pipeline.svg" """ run_gitlabform(config, group_and_project) badges = gitlab.get_project_badges(group_and_project) assert len(badges) == 1 assert badges[0]["name"] == "Project Badge"