Add QA tests for protected branches
This commit is contained in:
parent
3a1b961dfa
commit
55e4867d8b
|
|
@ -22,7 +22,7 @@
|
|||
= author_avatar(commit, size: 36)
|
||||
|
||||
.commit-detail.flex-list
|
||||
.commit-content
|
||||
.commit-content.qa-commit-content
|
||||
- if view_details && merge_request
|
||||
= link_to commit.title, project_commit_path(project, commit.id, merge_request_iid: merge_request.iid), class: "commit-row-message item-title"
|
||||
- else
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
- content_for :push_access_levels do
|
||||
.push_access_levels-container
|
||||
= dropdown_tag('Select',
|
||||
options: { toggle_class: 'js-allowed-to-push wide',
|
||||
dropdown_class: 'dropdown-menu-selectable capitalize-header',
|
||||
options: { toggle_class: 'js-allowed-to-push qa-allowed-to-push-select wide',
|
||||
dropdown_class: 'dropdown-menu-selectable qa-allowed-to-push-dropdown capitalize-header',
|
||||
data: { field_name: 'protected_branch[push_access_levels_attributes][0][access_level]', input_id: 'push_access_levels_attributes' }})
|
||||
|
||||
= render 'projects/protected_branches/shared/create_protected_branch'
|
||||
|
|
|
|||
|
|
@ -6,5 +6,5 @@
|
|||
%td
|
||||
= hidden_field_tag "allowed_to_push_#{protected_branch.id}", protected_branch.push_access_levels.first.access_level
|
||||
= dropdown_tag( (protected_branch.push_access_levels.first.humanize || 'Select') ,
|
||||
options: { toggle_class: 'js-allowed-to-push', dropdown_class: 'dropdown-menu-selectable js-allowed-to-push-container capitalize-header',
|
||||
options: { toggle_class: 'js-allowed-to-push qa-allowed-to-push', dropdown_class: 'dropdown-menu-selectable js-allowed-to-push-container capitalize-header',
|
||||
data: { field_name: "allowed_to_push_#{protected_branch.id}", access_level_id: protected_branch.push_access_levels.first.id }})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.protected-branches-list.js-protected-branches-list
|
||||
.protected-branches-list.js-protected-branches-list.qa-protected-branches-list
|
||||
- if @protected_branches.empty?
|
||||
.panel-heading
|
||||
%h3.panel-title
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
= f.hidden_field(:name)
|
||||
|
||||
= dropdown_tag('Select branch or create wildcard',
|
||||
options: { toggle_class: 'js-protected-branch-select js-filter-submit wide git-revision-dropdown-toggle',
|
||||
filter: true, dropdown_class: "dropdown-menu-selectable git-revision-dropdown", placeholder: "Search protected branches",
|
||||
options: { toggle_class: 'js-protected-branch-select js-filter-submit wide git-revision-dropdown-toggle qa-protected-branch-select',
|
||||
filter: true, dropdown_class: "dropdown-menu-selectable git-revision-dropdown qa-protected-branch-dropdown", placeholder: "Search protected branches",
|
||||
footer_content: true,
|
||||
data: { show_no: true, show_any: true, show_upcoming: true,
|
||||
selected: params[:protected_branch_name],
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
.settings-header
|
||||
%h4
|
||||
Protected Branches
|
||||
%button.btn.js-settings-toggle{ type: 'button' }
|
||||
%button.btn.js-settings-toggle.qa-expand-protected-branches{ type: 'button' }
|
||||
= expanded ? 'Collapse' : 'Expand'
|
||||
%p
|
||||
Keep stable branches secure and force developers to use merge requests.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
%tr.js-protected-branch-edit-form{ data: { url: namespace_project_protected_branch_path(@project.namespace, @project, protected_branch) } }
|
||||
%td
|
||||
%span.ref-name= protected_branch.name
|
||||
%span.ref-name.qa-protected-branch-name= protected_branch.name
|
||||
|
||||
- if @project.root_ref?(protected_branch.name)
|
||||
%span.label.label-info.prepend-left-5 default
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
- @options && @options.each do |key, value|
|
||||
= hidden_field_tag key, value, id: nil
|
||||
.dropdown
|
||||
= dropdown_toggle dropdown_toggle_text, { toggle: "dropdown", selected: dropdown_toggle_text, ref: @ref, refs_url: refs_project_path(@project, sort: 'updated_desc'), field_name: 'ref', submit_form_on_click: true, visit: true }, { toggle_class: "js-project-refs-dropdown" }
|
||||
.dropdown-menu.dropdown-menu-selectable.git-revision-dropdown.dropdown-menu-paging{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) }
|
||||
= dropdown_toggle dropdown_toggle_text, { toggle: "dropdown", selected: dropdown_toggle_text, ref: @ref, refs_url: refs_project_path(@project, sort: 'updated_desc'), field_name: 'ref', submit_form_on_click: true, visit: true }, { toggle_class: "js-project-refs-dropdown qa-branches-select" }
|
||||
.dropdown-menu.dropdown-menu-selectable.git-revision-dropdown.dropdown-menu-paging.qa-branches-dropdown{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) }
|
||||
.dropdown-page-one
|
||||
= dropdown_title _("Switch branch/tag")
|
||||
= dropdown_filter _("Search branches and tags")
|
||||
|
|
|
|||
2
qa/qa.rb
2
qa/qa.rb
|
|
@ -31,6 +31,7 @@ module QA
|
|||
autoload :Project, 'qa/factory/resource/project'
|
||||
autoload :MergeRequest, 'qa/factory/resource/merge_request'
|
||||
autoload :DeployKey, 'qa/factory/resource/deploy_key'
|
||||
autoload :Branch, 'qa/factory/resource/branch'
|
||||
autoload :SecretVariable, 'qa/factory/resource/secret_variable'
|
||||
autoload :Runner, 'qa/factory/resource/runner'
|
||||
autoload :PersonalAccessToken, 'qa/factory/resource/personal_access_token'
|
||||
|
|
@ -132,6 +133,7 @@ module QA
|
|||
autoload :Repository, 'qa/page/project/settings/repository'
|
||||
autoload :CICD, 'qa/page/project/settings/ci_cd'
|
||||
autoload :DeployKeys, 'qa/page/project/settings/deploy_keys'
|
||||
autoload :ProtectedBranches, 'qa/page/project/settings/protected_branches'
|
||||
autoload :SecretVariables, 'qa/page/project/settings/secret_variables'
|
||||
autoload :Runners, 'qa/page/project/settings/runners'
|
||||
autoload :MergeRequest, 'qa/page/project/settings/merge_request'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
module QA
|
||||
module Factory
|
||||
module Resource
|
||||
class Branch < Factory::Base
|
||||
attr_accessor :project, :branch_name, :allow_to_push, :protected
|
||||
|
||||
dependency Factory::Resource::Project, as: :project do |project|
|
||||
project.name = 'protected-branch-project'
|
||||
end
|
||||
|
||||
product :name do
|
||||
Page::Project::Settings::Repository.act do
|
||||
expand_protected_branches(&:last_branch_name)
|
||||
end
|
||||
end
|
||||
|
||||
product :push_allowance do
|
||||
Page::Project::Settings::Repository.act do
|
||||
expand_protected_branches(&:last_push_allowance)
|
||||
end
|
||||
end
|
||||
|
||||
def initialize
|
||||
@branch_name = 'test/branch'
|
||||
@allow_to_push = true
|
||||
@protected = false
|
||||
end
|
||||
|
||||
def fabricate!
|
||||
project.visit!
|
||||
|
||||
Factory::Repository::Push.fabricate! do |resource|
|
||||
resource.project = project
|
||||
resource.file_name = 'kick-off.txt'
|
||||
resource.commit_message = 'First commit'
|
||||
end
|
||||
|
||||
branch = Factory::Repository::Push.fabricate! do |resource|
|
||||
resource.project = project
|
||||
resource.file_name = 'README.md'
|
||||
resource.commit_message = 'Add readme'
|
||||
resource.branch_name = "master:#{@branch_name}"
|
||||
end
|
||||
|
||||
Page::Project::Show.act { wait_for_push }
|
||||
|
||||
# The upcoming process will make it access the Protected Branches page,
|
||||
# select the already created branch and protect it according
|
||||
# to `allow_to_push` variable.
|
||||
return branch unless @protected
|
||||
|
||||
Page::Menu::Side.act do
|
||||
click_repository_settings
|
||||
end
|
||||
|
||||
Page::Project::Settings::Repository.perform do |setting|
|
||||
setting.expand_protected_branches do |page|
|
||||
page.select_branch(branch_name)
|
||||
|
||||
if allow_to_push
|
||||
page.allow_devs_and_masters_to_push
|
||||
else
|
||||
page.allow_no_one_to_push
|
||||
end
|
||||
|
||||
page.protect_branch
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
require 'cgi'
|
||||
require 'uri'
|
||||
require 'open3'
|
||||
|
||||
module QA
|
||||
module Git
|
||||
class Repository
|
||||
include Scenario::Actable
|
||||
|
||||
attr_reader :push_error
|
||||
|
||||
def self.perform(*args)
|
||||
Dir.mktmpdir do |dir|
|
||||
Dir.chdir(dir) { super }
|
||||
|
|
@ -65,7 +68,8 @@ module QA
|
|||
end
|
||||
|
||||
def push_changes(branch = 'master')
|
||||
`git push #{@uri.to_s} #{branch} #{suppress_output}`
|
||||
# capture3 returns stdout, stderr and status.
|
||||
_, @push_error, _ = Open3.capture3("git push #{@uri} #{branch} #{suppress_output}")
|
||||
end
|
||||
|
||||
def commits
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
module QA
|
||||
module Page
|
||||
module Project
|
||||
module Settings
|
||||
class ProtectedBranches < Page::Base
|
||||
view 'app/views/projects/protected_branches/shared/_dropdown.html.haml' do
|
||||
element :protected_branch_select
|
||||
element :protected_branch_dropdown
|
||||
end
|
||||
|
||||
view 'app/views/projects/protected_branches/_create_protected_branch.html.haml' do
|
||||
element :allowed_to_push_select
|
||||
element :allowed_to_push_dropdown
|
||||
end
|
||||
|
||||
view 'app/views/projects/protected_branches/shared/_branches_list.html.haml' do
|
||||
element :protected_branches_list
|
||||
end
|
||||
|
||||
view 'app/views/projects/protected_branches/shared/_protected_branch.html.haml' do
|
||||
element :protected_branch_name
|
||||
end
|
||||
|
||||
def select_branch(branch_name)
|
||||
click_element :protected_branch_select
|
||||
|
||||
within_element(:protected_branch_dropdown) do
|
||||
click_on branch_name
|
||||
end
|
||||
end
|
||||
|
||||
def allow_no_one_to_push
|
||||
allow_to_push('No one')
|
||||
end
|
||||
|
||||
def allow_devs_and_masters_to_push
|
||||
allow_to_push('Developers + Masters')
|
||||
end
|
||||
|
||||
def protect_branch
|
||||
click_on 'Protect'
|
||||
end
|
||||
|
||||
def last_branch_name
|
||||
within_element(:protected_branches_list) do
|
||||
all('.qa-protected-branch-name').last
|
||||
end
|
||||
end
|
||||
|
||||
def last_push_allowance
|
||||
within_element(:protected_branches_list) do
|
||||
all('.qa-allowed-to-push').last
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def allow_to_push(text)
|
||||
click_element :allowed_to_push_select
|
||||
|
||||
within_element(:allowed_to_push_dropdown) do
|
||||
click_on text
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -14,6 +14,12 @@ module QA
|
|||
DeployKeys.perform(&block)
|
||||
end
|
||||
end
|
||||
|
||||
def expand_protected_branches(&block)
|
||||
expand_section('Protected Branches') do
|
||||
ProtectedBranches.perform(&block)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,6 +21,11 @@ module QA
|
|||
element :new_issue_link, "link_to 'New issue', new_project_issue_path(@project)"
|
||||
end
|
||||
|
||||
view 'app/views/shared/_ref_switcher.html.haml' do
|
||||
element :branches_select
|
||||
element :branches_dropdown
|
||||
end
|
||||
|
||||
def choose_repository_clone_http
|
||||
choose_repository_clone('HTTP', 'http')
|
||||
end
|
||||
|
|
@ -44,6 +49,18 @@ module QA
|
|||
find('.qa-project-name').text
|
||||
end
|
||||
|
||||
def switch_to_branch(branch_name)
|
||||
find_element(:branches_select).click
|
||||
|
||||
within_element(:branches_dropdown) do
|
||||
click_on branch_name
|
||||
end
|
||||
end
|
||||
|
||||
def last_commit_content
|
||||
find_element(:commit_content).text
|
||||
end
|
||||
|
||||
def new_merge_request
|
||||
wait(reload: true) do
|
||||
has_css?(element_selector_css(:create_merge_request))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
module QA
|
||||
feature 'branch protection support', :core do
|
||||
given(:branch_name) { 'protected-branch' }
|
||||
given(:commit_message) { 'Protected push commit message' }
|
||||
given(:project) do
|
||||
Factory::Resource::Project.fabricate! do |resource|
|
||||
resource.name = 'protected-branch-project'
|
||||
end
|
||||
end
|
||||
given(:location) do
|
||||
Page::Project::Show.act do
|
||||
choose_repository_clone_http
|
||||
repository_location
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
Runtime::Browser.visit(:gitlab, Page::Main::Login)
|
||||
Page::Main::Login.act { sign_in_using_credentials }
|
||||
end
|
||||
|
||||
scenario 'user is able to protect a branch' do
|
||||
protected_branch = Factory::Resource::Branch.fabricate! do |resource|
|
||||
resource.branch_name = branch_name
|
||||
resource.project = project
|
||||
resource.allow_to_push = true
|
||||
resource.protected = true
|
||||
end
|
||||
|
||||
expect(protected_branch.name).to have_content(branch_name)
|
||||
expect(protected_branch.push_allowance).to have_content('Developers + Masters')
|
||||
end
|
||||
|
||||
scenario 'users without authorization cannot push to protected branch' do
|
||||
Factory::Resource::Branch.fabricate! do |resource|
|
||||
resource.branch_name = branch_name
|
||||
resource.project = project
|
||||
resource.allow_to_push = false
|
||||
resource.protected = true
|
||||
end
|
||||
|
||||
project.visit!
|
||||
|
||||
Git::Repository.perform do |repository|
|
||||
repository.location = location
|
||||
repository.use_default_credentials
|
||||
|
||||
repository.act do
|
||||
clone
|
||||
configure_identity('GitLab QA', 'root@gitlab.com')
|
||||
checkout('protected-branch')
|
||||
commit_file('README.md', 'readme content', 'Add a readme')
|
||||
push_changes('protected-branch')
|
||||
end
|
||||
|
||||
expect(repository.push_error)
|
||||
.to match(/remote\: GitLab\: You are not allowed to push code to protected branches on this project/)
|
||||
expect(repository.push_error)
|
||||
.to match(/\[remote rejected\] #{branch_name} -> #{branch_name} \(pre-receive hook declined\)/)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue