test merge request rebase
This commit is contained in:
parent
8cfa5ccf53
commit
73e5039573
|
@ -227,7 +227,8 @@ export default {
|
||||||
@click="handleMergeButtonClick()"
|
@click="handleMergeButtonClick()"
|
||||||
:disabled="isMergeButtonDisabled"
|
:disabled="isMergeButtonDisabled"
|
||||||
:class="mergeButtonClass"
|
:class="mergeButtonClass"
|
||||||
type="button">
|
type="button"
|
||||||
|
class="qa-merge-button">
|
||||||
<i
|
<i
|
||||||
v-if="isMakingRequest"
|
v-if="isMakingRequest"
|
||||||
class="fa fa-spinner fa-spin"
|
class="fa fa-spinner fa-spin"
|
||||||
|
|
|
@ -110,7 +110,7 @@
|
||||||
js-toggle-container accept-action media space-children">
|
js-toggle-container accept-action media space-children">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-sm btn-reopen btn-success"
|
class="btn btn-sm btn-reopen btn-success qa-mr-rebase-button"
|
||||||
:disabled="isMakingRequest"
|
:disabled="isMakingRequest"
|
||||||
@click="rebase"
|
@click="rebase"
|
||||||
>
|
>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
.radio
|
.radio
|
||||||
= label_tag :project_merge_method_ff do
|
= label_tag :project_merge_method_ff do
|
||||||
= form.radio_button :merge_method, :ff, class: "js-merge-method-radio"
|
= form.radio_button :merge_method, :ff, class: "js-merge-method-radio qa-radio-button-merge-ff"
|
||||||
%strong Fast-forward merge
|
%strong Fast-forward merge
|
||||||
%br
|
%br
|
||||||
%span.descr
|
%span.descr
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
.settings-content
|
.settings-content
|
||||||
= form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "merge-request-settings-form" }, authenticity_token: true do |f|
|
= form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "merge-request-settings-form" }, authenticity_token: true do |f|
|
||||||
= render 'merge_request_settings', form: f
|
= render 'merge_request_settings', form: f
|
||||||
= f.submit 'Save changes', class: "btn btn-save"
|
= f.submit 'Save changes', class: "btn btn-save qa-save-merge-request-changes"
|
||||||
|
|
||||||
= render 'export', project: @project
|
= render 'export', project: @project
|
||||||
|
|
||||||
|
|
2
qa/qa.rb
2
qa/qa.rb
|
@ -130,6 +130,7 @@ module QA
|
||||||
autoload :DeployKeys, 'qa/page/project/settings/deploy_keys'
|
autoload :DeployKeys, 'qa/page/project/settings/deploy_keys'
|
||||||
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'
|
||||||
end
|
end
|
||||||
|
|
||||||
module Issue
|
module Issue
|
||||||
|
@ -145,6 +146,7 @@ module QA
|
||||||
|
|
||||||
module MergeRequest
|
module MergeRequest
|
||||||
autoload :New, 'qa/page/merge_request/new'
|
autoload :New, 'qa/page/merge_request/new'
|
||||||
|
autoload :Show, 'qa/page/merge_request/show'
|
||||||
end
|
end
|
||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
|
|
|
@ -22,7 +22,7 @@ module QA
|
||||||
|
|
||||||
factory.fabricate!(*args)
|
factory.fabricate!(*args)
|
||||||
|
|
||||||
return Factory::Product.populate!(self)
|
return Factory::Product.populate!(factory)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,9 @@ module QA
|
||||||
|
|
||||||
def self.populate!(factory)
|
def self.populate!(factory)
|
||||||
new.tap do |product|
|
new.tap do |product|
|
||||||
factory.attributes.each_value do |attribute|
|
factory.class.attributes.each_value do |attribute|
|
||||||
product.instance_exec(&attribute.block).tap do |value|
|
product.instance_exec(factory, attribute.block) do |factory, block|
|
||||||
product.define_singleton_method(attribute.name) { value }
|
product.define_singleton_method(attribute.name) { block.call(factory) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@ module QA
|
||||||
module Factory
|
module Factory
|
||||||
module Repository
|
module Repository
|
||||||
class Push < Factory::Base
|
class Push < Factory::Base
|
||||||
attr_writer :file_name, :file_content, :commit_message, :branch_name
|
attr_writer :file_name, :file_content, :commit_message, :branch_name, :new_branch
|
||||||
|
|
||||||
dependency Factory::Resource::Project, as: :project do |project|
|
dependency Factory::Resource::Project, as: :project do |project|
|
||||||
project.name = 'project-with-code'
|
project.name = 'project-with-code'
|
||||||
|
@ -14,6 +14,7 @@ module QA
|
||||||
@file_content = '# This is test project'
|
@file_content = '# This is test project'
|
||||||
@commit_message = "Add #{@file_name}"
|
@commit_message = "Add #{@file_name}"
|
||||||
@branch_name = 'master'
|
@branch_name = 'master'
|
||||||
|
@new_branch = true
|
||||||
end
|
end
|
||||||
|
|
||||||
def fabricate!
|
def fabricate!
|
||||||
|
@ -29,6 +30,7 @@ module QA
|
||||||
repository.clone
|
repository.clone
|
||||||
repository.configure_identity('GitLab QA', 'root@gitlab.com')
|
repository.configure_identity('GitLab QA', 'root@gitlab.com')
|
||||||
|
|
||||||
|
repository.checkout(@branch_name) unless @new_branch
|
||||||
repository.add_file(@file_name, @file_content)
|
repository.add_file(@file_name, @file_content)
|
||||||
repository.commit(@commit_message)
|
repository.commit(@commit_message)
|
||||||
repository.push_changes(@branch_name)
|
repository.push_changes(@branch_name)
|
||||||
|
|
|
@ -9,11 +9,20 @@ module QA
|
||||||
:source_branch,
|
:source_branch,
|
||||||
:target_branch
|
:target_branch
|
||||||
|
|
||||||
|
product :project do |factory|
|
||||||
|
factory.project
|
||||||
|
end
|
||||||
|
|
||||||
|
product :source_branch do |factory|
|
||||||
|
factory.source_branch
|
||||||
|
end
|
||||||
|
|
||||||
dependency Factory::Resource::Project, as: :project do |project|
|
dependency Factory::Resource::Project, as: :project do |project|
|
||||||
project.name = 'project-with-merge-request'
|
project.name = 'project-with-merge-request'
|
||||||
end
|
end
|
||||||
|
|
||||||
dependency Factory::Repository::Push, as: :target do |push, factory|
|
dependency Factory::Repository::Push, as: :target do |push, factory|
|
||||||
|
factory.project.visit!
|
||||||
push.project = factory.project
|
push.project = factory.project
|
||||||
push.branch_name = "master:#{factory.target_branch}"
|
push.branch_name = "master:#{factory.target_branch}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -36,6 +36,10 @@ module QA
|
||||||
`git clone #{opts} #{@uri.to_s} ./ #{suppress_output}`
|
`git clone #{opts} #{@uri.to_s} ./ #{suppress_output}`
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def checkout(branch_name)
|
||||||
|
`git checkout "#{branch_name}"`
|
||||||
|
end
|
||||||
|
|
||||||
def shallow_clone
|
def shallow_clone
|
||||||
clone('--depth 1')
|
clone('--depth 1')
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
module QA
|
||||||
|
module Page
|
||||||
|
module MergeRequest
|
||||||
|
class Show < Page::Base
|
||||||
|
view 'app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js' do
|
||||||
|
element :merge_button
|
||||||
|
end
|
||||||
|
|
||||||
|
view 'app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.vue' do
|
||||||
|
element :merged_status, 'The changes were merged into'
|
||||||
|
end
|
||||||
|
|
||||||
|
view 'app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue' do
|
||||||
|
element :mr_rebase_button
|
||||||
|
element :fast_forward_nessage, "Fast-forward merge is not possible"
|
||||||
|
end
|
||||||
|
|
||||||
|
def rebase!
|
||||||
|
wait(reload: false) do
|
||||||
|
click_element :mr_rebase_button
|
||||||
|
|
||||||
|
has_text?("The source branch HEAD has recently changed.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def fast_forward_possible?
|
||||||
|
!page.has_text?("Fast-forward merge is not possible")
|
||||||
|
end
|
||||||
|
|
||||||
|
def has_merge_button?
|
||||||
|
refresh
|
||||||
|
|
||||||
|
has_selector?('.accept-merge-request')
|
||||||
|
end
|
||||||
|
|
||||||
|
def merge!
|
||||||
|
wait(reload: false) do
|
||||||
|
click_element :merge_button
|
||||||
|
|
||||||
|
has_text?("The changes were merged into")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,27 @@
|
||||||
|
module QA
|
||||||
|
module Page
|
||||||
|
module Project
|
||||||
|
module Settings
|
||||||
|
class MergeRequest < QA::Page::Base
|
||||||
|
include Common
|
||||||
|
|
||||||
|
view 'app/views/projects/_merge_request_fast_forward_settings.html.haml' do
|
||||||
|
element :radio_button_merge_ff
|
||||||
|
end
|
||||||
|
|
||||||
|
view 'app/views/projects/edit.html.haml' do
|
||||||
|
element :merge_request_settings, 'Merge request settings'
|
||||||
|
element :save_merge_request_changes
|
||||||
|
end
|
||||||
|
|
||||||
|
def enable_ff_only
|
||||||
|
expand_section('Merge request settings') do
|
||||||
|
click_element :radio_button_merge_ff
|
||||||
|
click_element :save_merge_request_changes
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,39 @@
|
||||||
|
module QA
|
||||||
|
feature 'merge request rebase', :core do
|
||||||
|
scenario 'rebases source branch of merge request' do
|
||||||
|
Runtime::Browser.visit(:gitlab, Page::Main::Login)
|
||||||
|
Page::Main::Login.act { sign_in_using_credentials }
|
||||||
|
|
||||||
|
project = Factory::Resource::Project.fabricate! do |project|
|
||||||
|
project.name = "no-fast-forward"
|
||||||
|
end
|
||||||
|
|
||||||
|
Page::Menu::Side.act { go_to_settings }
|
||||||
|
Page::Project::Settings::MergeRequest.act { enable_ff_only }
|
||||||
|
|
||||||
|
merge_request = Factory::Resource::MergeRequest.fabricate! do |merge_request|
|
||||||
|
merge_request.project = project
|
||||||
|
merge_request.title = 'Needs rebasing'
|
||||||
|
end
|
||||||
|
|
||||||
|
Factory::Repository::Push.fabricate! do |push|
|
||||||
|
push.project = project
|
||||||
|
push.file_name = "other.txt"
|
||||||
|
push.file_content = "New file added!"
|
||||||
|
end
|
||||||
|
|
||||||
|
merge_request.visit!
|
||||||
|
|
||||||
|
Page::MergeRequest::Show.perform do |merge_request|
|
||||||
|
expect(merge_request).to have_content('Needs rebasing')
|
||||||
|
expect(merge_request).not_to be_fast_forward_possible
|
||||||
|
expect(merge_request).not_to have_merge_button
|
||||||
|
|
||||||
|
merge_request.rebase!
|
||||||
|
|
||||||
|
expect(merge_request).to have_merge_button
|
||||||
|
expect(merge_request.fast_forward_possible?).to be_truthy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -7,6 +7,7 @@ describe QA::Factory::Base do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(QA::Factory::Product).to receive(:new).and_return(product)
|
allow(QA::Factory::Product).to receive(:new).and_return(product)
|
||||||
|
allow(QA::Factory::Product).to receive(:populate!).and_return(product)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'instantiates the factory and calls factory method' do
|
it 'instantiates the factory and calls factory method' do
|
||||||
|
@ -76,6 +77,7 @@ describe QA::Factory::Base do
|
||||||
allow(subject).to receive(:new).and_return(instance)
|
allow(subject).to receive(:new).and_return(instance)
|
||||||
allow(instance).to receive(:mydep).and_return(nil)
|
allow(instance).to receive(:mydep).and_return(nil)
|
||||||
allow(QA::Factory::Product).to receive(:new)
|
allow(QA::Factory::Product).to receive(:new)
|
||||||
|
allow(QA::Factory::Product).to receive(:populate!)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'builds all dependencies first' do
|
it 'builds all dependencies first' do
|
||||||
|
@ -89,8 +91,16 @@ describe QA::Factory::Base do
|
||||||
describe '.product' do
|
describe '.product' do
|
||||||
subject do
|
subject do
|
||||||
Class.new(described_class) do
|
Class.new(described_class) do
|
||||||
|
def fabricate!
|
||||||
|
"any"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Defined only to be stubbed
|
||||||
|
def self.find_page
|
||||||
|
end
|
||||||
|
|
||||||
product :token do
|
product :token do
|
||||||
page.do_something_on_page!
|
find_page.do_something_on_page!
|
||||||
'resulting value'
|
'resulting value'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -105,16 +115,17 @@ describe QA::Factory::Base do
|
||||||
let(:page) { spy('page') }
|
let(:page) { spy('page') }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(subject).to receive(:new).and_return(factory)
|
allow(factory).to receive(:class).and_return(subject)
|
||||||
allow(QA::Factory::Product).to receive(:new).and_return(product)
|
allow(QA::Factory::Product).to receive(:new).and_return(product)
|
||||||
allow(product).to receive(:page).and_return(page)
|
allow(product).to receive(:page).and_return(page)
|
||||||
|
allow(subject).to receive(:find_page).and_return(page)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'populates product after fabrication' do
|
it 'populates product after fabrication' do
|
||||||
subject.fabricate!
|
subject.fabricate!
|
||||||
|
|
||||||
expect(page).to have_received(:do_something_on_page!)
|
|
||||||
expect(product.token).to eq 'resulting value'
|
expect(product.token).to eq 'resulting value'
|
||||||
|
expect(page).to have_received(:do_something_on_page!)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,20 @@
|
||||||
describe QA::Factory::Product do
|
describe QA::Factory::Product do
|
||||||
let(:factory) { spy('factory') }
|
let(:factory) do
|
||||||
|
QA::Factory::Base.new
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:attributes) do
|
||||||
|
{ test: QA::Factory::Product::Attribute.new(:test, proc { 'returned' }) }
|
||||||
|
end
|
||||||
|
|
||||||
let(:product) { spy('product') }
|
let(:product) { spy('product') }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(QA::Factory::Base).to receive(:attributes).and_return(attributes)
|
||||||
|
end
|
||||||
|
|
||||||
describe '.populate!' do
|
describe '.populate!' do
|
||||||
it 'returns a fabrication product' do
|
it 'returns a fabrication product and define factory attributes as its methods' do
|
||||||
expect(described_class).to receive(:new).and_return(product)
|
expect(described_class).to receive(:new).and_return(product)
|
||||||
|
|
||||||
result = described_class.populate!(factory) do |instance|
|
result = described_class.populate!(factory) do |instance|
|
||||||
|
@ -11,6 +22,7 @@ describe QA::Factory::Product do
|
||||||
end
|
end
|
||||||
|
|
||||||
expect(result).to be product
|
expect(result).to be product
|
||||||
|
expect(result.test).to eq('returned')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue