Commit 2f2f9bd6 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'osw-add-qa-tests-for-protected-branches' into 'master'

Add QA tests for protected branches

See merge request gitlab-org/gitlab-ce!18301
parents 2675ef2c 55e4867d
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
= author_avatar(commit, size: 36) = author_avatar(commit, size: 36)
.commit-detail.flex-list .commit-detail.flex-list
.commit-content .commit-content.qa-commit-content
- if view_details && merge_request - 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" = link_to commit.title, project_commit_path(project, commit.id, merge_request_iid: merge_request.iid), class: "commit-row-message item-title"
- else - else
......
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
- content_for :push_access_levels do - content_for :push_access_levels do
.push_access_levels-container .push_access_levels-container
= dropdown_tag('Select', = dropdown_tag('Select',
options: { toggle_class: 'js-allowed-to-push wide', options: { toggle_class: 'js-allowed-to-push qa-allowed-to-push-select wide',
dropdown_class: 'dropdown-menu-selectable capitalize-header', 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' }}) 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' = render 'projects/protected_branches/shared/create_protected_branch'
...@@ -6,5 +6,5 @@ ...@@ -6,5 +6,5 @@
%td %td
= hidden_field_tag "allowed_to_push_#{protected_branch.id}", protected_branch.push_access_levels.first.access_level = 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') , = 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 }}) data: { field_name: "allowed_to_push_#{protected_branch.id}", access_level_id: protected_branch.push_access_levels.first.id }})
.protected-branches-list.js-protected-branches-list .protected-branches-list.js-protected-branches-list.qa-protected-branches-list
- if @protected_branches.empty? - if @protected_branches.empty?
.panel-heading .panel-heading
%h3.panel-title %h3.panel-title
......
= f.hidden_field(:name) = f.hidden_field(:name)
= dropdown_tag('Select branch or create wildcard', = dropdown_tag('Select branch or create wildcard',
options: { toggle_class: 'js-protected-branch-select js-filter-submit wide git-revision-dropdown-toggle', 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", placeholder: "Search protected branches", filter: true, dropdown_class: "dropdown-menu-selectable git-revision-dropdown qa-protected-branch-dropdown", placeholder: "Search protected branches",
footer_content: true, footer_content: true,
data: { show_no: true, show_any: true, show_upcoming: true, data: { show_no: true, show_any: true, show_upcoming: true,
selected: params[:protected_branch_name], selected: params[:protected_branch_name],
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
.settings-header .settings-header
%h4 %h4
Protected Branches Protected Branches
%button.btn.js-settings-toggle{ type: 'button' } %button.btn.js-settings-toggle.qa-expand-protected-branches{ type: 'button' }
= expanded ? 'Collapse' : 'Expand' = expanded ? 'Collapse' : 'Expand'
%p %p
Keep stable branches secure and force developers to use merge requests. Keep stable branches secure and force developers to use merge requests.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
%tr.js-protected-branch-edit-form{ data: { url: namespace_project_protected_branch_path(@project.namespace, @project, protected_branch) } } %tr.js-protected-branch-edit-form{ data: { url: namespace_project_protected_branch_path(@project.namespace, @project, protected_branch) } }
%td %td
%span.ref-name= protected_branch.name %span.ref-name.qa-protected-branch-name= protected_branch.name
- if @project.root_ref?(protected_branch.name) - if @project.root_ref?(protected_branch.name)
%span.label.label-info.prepend-left-5 default %span.label.label-info.prepend-left-5 default
......
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
- @options && @options.each do |key, value| - @options && @options.each do |key, value|
= hidden_field_tag key, value, id: nil = hidden_field_tag key, value, id: nil
.dropdown .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_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{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) } .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-page-one
= dropdown_title _("Switch branch/tag") = dropdown_title _("Switch branch/tag")
= dropdown_filter _("Search branches and tags") = dropdown_filter _("Search branches and tags")
......
...@@ -31,6 +31,7 @@ module QA ...@@ -31,6 +31,7 @@ module QA
autoload :Project, 'qa/factory/resource/project' autoload :Project, 'qa/factory/resource/project'
autoload :MergeRequest, 'qa/factory/resource/merge_request' autoload :MergeRequest, 'qa/factory/resource/merge_request'
autoload :DeployKey, 'qa/factory/resource/deploy_key' autoload :DeployKey, 'qa/factory/resource/deploy_key'
autoload :Branch, 'qa/factory/resource/branch'
autoload :SecretVariable, 'qa/factory/resource/secret_variable' autoload :SecretVariable, 'qa/factory/resource/secret_variable'
autoload :Runner, 'qa/factory/resource/runner' autoload :Runner, 'qa/factory/resource/runner'
autoload :PersonalAccessToken, 'qa/factory/resource/personal_access_token' autoload :PersonalAccessToken, 'qa/factory/resource/personal_access_token'
...@@ -132,6 +133,7 @@ module QA ...@@ -132,6 +133,7 @@ module QA
autoload :Repository, 'qa/page/project/settings/repository' autoload :Repository, 'qa/page/project/settings/repository'
autoload :CICD, 'qa/page/project/settings/ci_cd' autoload :CICD, 'qa/page/project/settings/ci_cd'
autoload :DeployKeys, 'qa/page/project/settings/deploy_keys' 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 :SecretVariables, 'qa/page/project/settings/secret_variables'
autoload :Runners, 'qa/page/project/settings/runners' autoload :Runners, 'qa/page/project/settings/runners'
autoload :MergeRequest, 'qa/page/project/settings/merge_request' autoload :MergeRequest, 'qa/page/project/settings/merge_request'
......
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
require 'cgi' require 'cgi'
require 'uri' require 'uri'
require 'open3'
module QA module QA
module Git module Git
class Repository class Repository
include Scenario::Actable include Scenario::Actable
attr_reader :push_error
def self.perform(*args) def self.perform(*args)
Dir.mktmpdir do |dir| Dir.mktmpdir do |dir|
Dir.chdir(dir) { super } Dir.chdir(dir) { super }
...@@ -65,7 +68,8 @@ module QA ...@@ -65,7 +68,8 @@ module QA
end end
def push_changes(branch = 'master') 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 end
def commits def commits
......
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 ...@@ -14,6 +14,12 @@ module QA
DeployKeys.perform(&block) DeployKeys.perform(&block)
end end
end end
def expand_protected_branches(&block)
expand_section('Protected Branches') do
ProtectedBranches.perform(&block)
end
end
end end
end end
end end
......
...@@ -21,6 +21,11 @@ module QA ...@@ -21,6 +21,11 @@ module QA
element :new_issue_link, "link_to 'New issue', new_project_issue_path(@project)" element :new_issue_link, "link_to 'New issue', new_project_issue_path(@project)"
end end
view 'app/views/shared/_ref_switcher.html.haml' do
element :branches_select
element :branches_dropdown
end
def choose_repository_clone_http def choose_repository_clone_http
choose_repository_clone('HTTP', 'http') choose_repository_clone('HTTP', 'http')
end end
...@@ -44,6 +49,18 @@ module QA ...@@ -44,6 +49,18 @@ module QA
find('.qa-project-name').text find('.qa-project-name').text
end 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 def new_merge_request
wait(reload: true) do wait(reload: true) do
has_css?(element_selector_css(:create_merge_request)) has_css?(element_selector_css(:create_merge_request))
......
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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment