update_service_spec.rb 7.83 KB
Newer Older
1
2
require 'spec_helper'

3
describe Projects::UpdateService do
4
5
  include ProjectForksHelper

6
  let(:user) { create(:user) }
7
  let(:project) do
8
    create(:project, creator: user, namespace: user.namespace)
9
10
  end

11
12
13
  describe '#execute' do
    let(:gitlab_shell) { Gitlab::Shell.new }
    let(:admin) { create(:admin) }
14

15
    context 'when changing visibility level' do
16
17
18
      context 'when visibility_level is INTERNAL' do
        it 'updates the project to internal' do
          result = update_project(project, user, visibility_level: Gitlab::VisibilityLevel::INTERNAL)
19

20
21
          expect(result).to eq({ status: :success })
          expect(project).to be_internal
22
23
24
        end
      end

25
      context 'when visibility_level is PUBLIC' do
26
        it 'updates the project to public' do
27
          result = update_project(project, user, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
28
29
30
31
          expect(result).to eq({ status: :success })
          expect(project).to be_public
        end
      end
32

33
34
35
36
37
38
39
40
41
42
43
      context 'when visibility levels are restricted to PUBLIC only' do
        before do
          stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
        end

        context 'when visibility_level is INTERNAL' do
          it 'updates the project to internal' do
            result = update_project(project, user, visibility_level: Gitlab::VisibilityLevel::INTERNAL)
            expect(result).to eq({ status: :success })
            expect(project).to be_internal
          end
44
45
        end

46
47
48
49
50
51
52
53
54
55
56
57
58
59
        context 'when visibility_level is PUBLIC' do
          it 'does not update the project to public' do
            result = update_project(project, user, visibility_level: Gitlab::VisibilityLevel::PUBLIC)

            expect(result).to eq({ status: :error, message: 'New visibility level not allowed!' })
            expect(project).to be_private
          end

          context 'when updated by an admin' do
            it 'updates the project to public' do
              result = update_project(project, admin, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
              expect(result).to eq({ status: :success })
              expect(project).to be_public
            end
60
          end
61
62
        end
      end
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

      context 'When project visibility is higher than parent group' do
        let(:group) { create(:group, visibility_level: Gitlab::VisibilityLevel::INTERNAL) }

        before do
          project.update(namespace: group, visibility_level: group.visibility_level)
        end

        it 'does not update project visibility level' do
          result = update_project(project, admin, visibility_level: Gitlab::VisibilityLevel::PUBLIC)

          expect(result).to eq({ status: :error, message: 'Visibility level public is not allowed in a internal group.' })
          expect(project.reload).to be_internal
        end
      end
78
    end
79

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    describe 'when updating project that has forks' do
      let(:project) { create(:project, :internal) }
      let(:forked_project) { fork_project(project) }

      it 'updates forks visibility level when parent set to more restrictive' do
        opts = { visibility_level: Gitlab::VisibilityLevel::PRIVATE }

        expect(project).to be_internal
        expect(forked_project).to be_internal

        expect(update_project(project, admin, opts)).to eq({ status: :success })

        expect(project).to be_private
        expect(forked_project.reload).to be_private
      end

      it 'does not update forks visibility level when parent set to less restrictive' do
        opts = { visibility_level: Gitlab::VisibilityLevel::PUBLIC }

        expect(project).to be_internal
        expect(forked_project).to be_internal

        expect(update_project(project, admin, opts)).to eq({ status: :success })
103

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
        expect(project).to be_public
        expect(forked_project.reload).to be_internal
      end
    end

    context 'when updating a default branch' do
      let(:project) { create(:project, :repository) }

      it 'changes a default branch' do
        update_project(project, admin, default_branch: 'feature')

        expect(Project.find(project.id).default_branch).to eq 'feature'
      end

      it 'does not change a default branch' do
        # The branch 'unexisted-branch' does not exist.
        update_project(project, admin, default_branch: 'unexisted-branch')

        expect(Project.find(project.id).default_branch).to eq 'master'
      end
    end

    context 'when updating a project that contains container images' do
127
      before do
128
129
130
        stub_container_registry_config(enabled: true)
        stub_container_registry_tags(repository: /image/, tags: %w[rc1])
        create(:container_repository, project: project, name: :image)
131
132
      end

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
      it 'does not allow to rename the project' do
        result = update_project(project, admin, path: 'renamed')

        expect(result).to include(status: :error)
        expect(result[:message]).to match(/contains container registry tags/)
      end

      it 'allows to update other settings' do
        result = update_project(project, admin, public_builds: true)

        expect(result[:status]).to eq :success
        expect(project.reload.public_builds).to be true
      end
    end

    context 'when renaming a project' do
      let(:repository_storage) { 'default' }
      let(:repository_storage_path) { Gitlab.config.repositories.storages[repository_storage]['path'] }

      context 'with legacy storage' do
        before do
          gitlab_shell.add_repository(repository_storage, "#{user.namespace.full_path}/existing")
        end

        after do
          gitlab_shell.remove_repository(repository_storage_path, "#{user.namespace.full_path}/existing")
        end

        it 'does not allow renaming when new path matches existing repository on disk' do
          result = update_project(project, admin, path: 'existing')
163

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
          expect(result).to include(status: :error)
          expect(result[:message]).to match('There is already a repository with that name on disk')
          expect(project).not_to be_valid
          expect(project.errors.messages).to have_key(:base)
          expect(project.errors.messages[:base]).to include('There is already a repository with that name on disk')
        end
      end

      context 'with hashed storage' do
        let(:project) { create(:project, :repository, creator: user, namespace: user.namespace) }

        before do
          stub_application_setting(hashed_storage_enabled: true)
        end

        it 'does not check if new path matches existing repository on disk' do
          expect(project).not_to receive(:repository_with_same_path_already_exists?)

          result = update_project(project, admin, path: 'existing')

          expect(result).to include(status: :success)
        end
      end
    end

    context 'when passing invalid parameters' do
      it 'returns an error result when record cannot be updated' do
        result = update_project(project, admin, { name: 'foo&bar' })

        expect(result).to eq({
          status: :error,
          message: "Name can contain only letters, digits, emojis, '_', '.', dash, space. It must start with letter, digit, emoji or '_'."
        })
197
198
      end
    end
199
200
  end

201
202
  describe '#run_auto_devops_pipeline?' do
    subject { described_class.new(project, user, params).run_auto_devops_pipeline? }
203

204
205
    context 'when neither pipeline setting is true' do
      let(:params) { {} }
206

207
      it { is_expected.to eq(false) }
208
209
    end

210
211
    context 'when run_auto_devops_pipeline_explicit is true' do
      let(:params) { { run_auto_devops_pipeline_explicit: 'true' } }
212

213
      it { is_expected.to eq(true) }
214
    end
215

216
217
    context 'when run_auto_devops_pipeline_implicit is true' do
      let(:params) { { run_auto_devops_pipeline_implicit: 'true' } }
218

219
      it { is_expected.to eq(true) }
220
    end
221
222
  end

223
  def update_project(project, user, opts)
224
    described_class.new(project, user, opts).execute
225
226
  end
end