summaryrefslogtreecommitdiff
path: root/spec/features/merge_request/user_creates_merge_request_spec.rb
blob: 50629f1195953102c10602179605c88bbddd8ba7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'User creates a merge request', :js, feature_category: :code_review do
  include ProjectForksHelper

  shared_examples 'creates a merge request' do
    specify do
      visit(project_new_merge_request_path(project))

      compare_source_and_target('fix', 'feature')

      page.within('.merge-request-form') do
        expect(page.find('#merge_request_description')['placeholder']).to eq 'Describe the goal of the changes and what reviewers should be aware of.'
      end

      fill_in('Title', with: title)
      click_button('Create merge request')

      page.within('.merge-request') do
        expect(page).to have_content(title)
      end
    end
  end

  shared_examples 'renders not found' do
    specify do
      visit project_new_merge_request_path(project)

      expect(page).to have_title('Not Found')
      expect(page).to have_content('Page Not Found')
    end
  end

  context 'when user is a direct project member' do
    let_it_be(:project) { create(:project, :repository) }
    let_it_be(:user) { create(:user) }

    let(:title) { 'Some feature' }

    before do
      project.add_maintainer(user)
      sign_in(user)
    end

    it_behaves_like 'creates a merge request'

    context 'with XSS branch name' do
      before do
        project.repository.create_branch("<img/src='x'/onerror=alert('oops')>", 'master')
      end

      it 'does not execute the suspicious branch name' do
        visit(project_new_merge_request_path(project))

        compare_source_and_target("<img/src='x'/onerror=alert('oops')>", 'feature')

        expect { page.driver.browser.switch_to.alert }.to raise_error(Selenium::WebDriver::Error::NoSuchAlertError)
      end
    end

    context 'to a forked project' do
      let(:forked_project) { fork_project(project, user, namespace: user.namespace, repository: true) }

      it 'creates a merge request', :sidekiq_might_not_need_inline do
        visit(project_new_merge_request_path(forked_project))

        expect(page).to have_content('Source branch').and have_content('Target branch')
        expect(find('#merge_request_target_project_id', visible: false).value).to eq(project.id.to_s)

        click_button('Compare branches and continue')

        expect(page).to have_content('You must select source and target branch')

        first('.js-source-project').click
        first('.dropdown-source-project a', text: forked_project.full_path)

        first('.js-target-project').click
        first('.dropdown-target-project li', text: project.full_path)

        first('.js-source-branch').click

        wait_for_requests

        source_branch = 'fix'

        first('.js-source-branch-dropdown .dropdown-content a', text: source_branch).click

        click_button('Compare branches and continue')

        expect(page).to have_text _('New merge request')

        page.within('form#new_merge_request') do
          fill_in('Title', with: title)
        end

        expect(find('.js-assignee-search')['data-project-id']).to eq(project.id.to_s)
        find('.js-assignee-search').click

        page.within('.dropdown-menu-user') do
          expect(page).to have_content('Unassigned')
                      .and have_content(user.name)
                      .and have_content(project.users.first.name)
        end
        find('.js-assignee-search').click

        click_button('Create merge request')

        expect(page).to have_content(title).and have_content("requested to merge #{forked_project.full_path}:#{source_branch} into master")
      end
    end
  end

  context 'when user is an inherited member from the group' do
    let_it_be(:group) { create(:group, :public) }

    let(:user) { create(:user) }

    context 'when project is public and merge requests are private' do
      let_it_be(:project) do
        create(:project,
               :public,
               :repository,
               group: group,
               merge_requests_access_level: ProjectFeature::DISABLED)
      end

      context 'and user is a guest' do
        before do
          group.add_guest(user)
          sign_in(user)
        end

        it_behaves_like 'renders not found'
      end
    end

    context 'when project is private' do
      let_it_be(:project) { create(:project, :private, :repository, group: group) }

      context 'and user is a guest' do
        before do
          group.add_guest(user)
          sign_in(user)
        end

        it_behaves_like 'renders not found'
      end
    end
  end

  private

  def compare_source_and_target(source_branch, target_branch)
    find('.js-source-branch').click
    click_link(source_branch)

    find('.js-target-branch').click
    click_link(target_branch)

    click_button('Compare branches')
  end
end