tags_spec.rb 9.4 KB
Newer Older
1 2 3
require 'spec_helper'
require 'mime/types'

4
describe API::Tags, api: true  do
5 6 7 8 9
  include ApiHelpers
  include RepoHelpers

  let(:user) { create(:user) }
  let(:user2) { create(:user) }
10
  let!(:project) { create(:project, :repository, creator: user) }
11 12
  let!(:master) { create(:project_member, :master, user: user, project: project) }
  let!(:guest) { create(:project_member, :guest, user: user2, project: project) }
13 14

  describe "GET /projects/:id/repository/tags" do
15 16 17
    let(:tag_name) { project.repository.tag_names.sort.reverse.first }
    let(:description) { 'Awesome release!' }

18 19 20 21 22
    shared_examples_for 'repository tags' do
      it 'returns the repository tags' do
        get api("/projects/#{project.id}/repository/tags", current_user)

        expect(response).to have_http_status(200)
23 24 25
        expect(response).to include_pagination_headers
        expect(json_response).to be_an Array
        expect(json_response.first['name']).to eq(tag_name)
26 27 28 29 30
      end
    end

    context 'when unauthenticated' do
      it_behaves_like 'repository tags' do
31
        let(:project) { create(:project, :public, :repository) }
32 33 34 35 36 37 38 39 40 41
        let(:current_user) { nil }
      end
    end

    context 'when authenticated' do
      it_behaves_like 'repository tags' do
        let(:current_user) { user }
      end
    end

42
    context 'without releases' do
43
      it "returns an array of project tags" do
44
        get api("/projects/#{project.id}/repository/tags", user)
45

Z
Z.J. van de Weg 已提交
46
        expect(response).to have_http_status(200)
47
        expect(response).to include_pagination_headers
48 49 50 51 52 53 54 55 56 57 58
        expect(json_response).to be_an Array
        expect(json_response.first['name']).to eq(tag_name)
      end
    end

    context 'with releases' do
      before do
        release = project.releases.find_or_initialize_by(tag: tag_name)
        release.update_attributes(description: description)
      end

59
      it "returns an array of project tags with release info" do
60
        get api("/projects/#{project.id}/repository/tags", user)
61

Z
Z.J. van de Weg 已提交
62
        expect(response).to have_http_status(200)
63
        expect(response).to include_pagination_headers
64 65
        expect(json_response).to be_an Array
        expect(json_response.first['name']).to eq(tag_name)
66
        expect(json_response.first['message']).to eq('Version 1.1.0')
67 68
        expect(json_response.first['release']['description']).to eq(description)
      end
69 70 71
    end
  end

72
  describe 'GET /projects/:id/repository/tags/:tag_name' do
73 74
    let(:tag_name) { project.repository.tag_names.sort.reverse.first }

75 76 77 78 79 80 81 82
    shared_examples_for 'repository tag' do
      it 'returns the repository tag' do
        get api("/projects/#{project.id}/repository/tags/#{tag_name}", current_user)

        expect(response).to have_http_status(200)

        expect(json_response['name']).to eq(tag_name)
      end
83

84 85 86 87 88
      it 'returns 404 for an invalid tag name' do
        get api("/projects/#{project.id}/repository/tags/foobar", current_user)

        expect(response).to have_http_status(404)
      end
89 90
    end

91 92
    context 'when unauthenticated' do
      it_behaves_like 'repository tag' do
93
        let(:project) { create(:project, :public, :repository) }
94 95 96
        let(:current_user) { nil }
      end
    end
97

98 99 100 101
    context 'when authenticated' do
      it_behaves_like 'repository tag' do
        let(:current_user) { user }
      end
102 103 104
    end
  end

105 106
  describe 'POST /projects/:id/repository/tags' do
    context 'lightweight tags' do
107
      it 'creates a new tag' do
108 109 110 111
        post api("/projects/#{project.id}/repository/tags", user),
             tag_name: 'v7.0.1',
             ref: 'master'

Z
Z.J. van de Weg 已提交
112
        expect(response).to have_http_status(201)
113 114 115 116
        expect(json_response['name']).to eq('v7.0.1')
      end
    end

117
    context 'lightweight tags with release notes' do
118
      it 'creates a new tag' do
119 120 121 122 123
        post api("/projects/#{project.id}/repository/tags", user),
             tag_name: 'v7.0.1',
             ref: 'master',
             release_description: 'Wow'

Z
Z.J. van de Weg 已提交
124
        expect(response).to have_http_status(201)
125 126 127 128 129
        expect(json_response['name']).to eq('v7.0.1')
        expect(json_response['release']['description']).to eq('Wow')
      end
    end

R
Robert Schilling 已提交
130 131 132 133 134 135 136 137
    describe 'DELETE /projects/:id/repository/tags/:tag_name' do
      let(:tag_name) { project.repository.tag_names.sort.reverse.first }

      before do
        allow_any_instance_of(Repository).to receive(:rm_tag).and_return(true)
      end

      context 'delete tag' do
138
        it 'deletes an existing tag' do
R
Robert Schilling 已提交
139
          delete api("/projects/#{project.id}/repository/tags/#{tag_name}", user)
140 141

          expect(response).to have_http_status(204)
R
Robert Schilling 已提交
142 143
        end

144
        it 'raises 404 if the tag does not exist' do
R
Robert Schilling 已提交
145
          delete api("/projects/#{project.id}/repository/tags/foobar", user)
Z
Z.J. van de Weg 已提交
146
          expect(response).to have_http_status(404)
R
Robert Schilling 已提交
147 148 149 150
        end
      end
    end

151
    context 'annotated tag' do
152
      it 'creates a new annotated tag' do
153 154 155 156 157 158 159 160 161 162
        # Identity must be set in .gitconfig to create annotated tag.
        repo_path = project.repository.path_to_repo
        system(*%W(#{Gitlab.config.git.bin_path} --git-dir=#{repo_path} config user.name #{user.name}))
        system(*%W(#{Gitlab.config.git.bin_path} --git-dir=#{repo_path} config user.email #{user.email}))

        post api("/projects/#{project.id}/repository/tags", user),
             tag_name: 'v7.1.0',
             ref: 'master',
             message: 'Release 7.1.0'

Z
Z.J. van de Weg 已提交
163
        expect(response).to have_http_status(201)
164 165 166 167 168
        expect(json_response['name']).to eq('v7.1.0')
        expect(json_response['message']).to eq('Release 7.1.0')
      end
    end

169
    it 'denies for user without push access' do
170 171 172
      post api("/projects/#{project.id}/repository/tags", user2),
           tag_name: 'v1.9.0',
           ref: '621491c677087aa243f165eab467bfdfbee00be1'
Z
Z.J. van de Weg 已提交
173
      expect(response).to have_http_status(403)
174 175
    end

176
    it 'returns 400 if tag name is invalid' do
177 178 179
      post api("/projects/#{project.id}/repository/tags", user),
           tag_name: 'v 1.0.0',
           ref: 'master'
Z
Z.J. van de Weg 已提交
180
      expect(response).to have_http_status(400)
181 182 183
      expect(json_response['message']).to eq('Tag name invalid')
    end

184
    it 'returns 400 if tag already exists' do
185 186 187
      post api("/projects/#{project.id}/repository/tags", user),
           tag_name: 'v8.0.0',
           ref: 'master'
Z
Z.J. van de Weg 已提交
188
      expect(response).to have_http_status(201)
189 190 191
      post api("/projects/#{project.id}/repository/tags", user),
           tag_name: 'v8.0.0',
           ref: 'master'
Z
Z.J. van de Weg 已提交
192
      expect(response).to have_http_status(400)
193
      expect(json_response['message']).to eq('Tag v8.0.0 already exists')
194 195
    end

196
    it 'returns 400 if ref name is invalid' do
197 198 199
      post api("/projects/#{project.id}/repository/tags", user),
           tag_name: 'mytag',
           ref: 'foo'
Z
Z.J. van de Weg 已提交
200
      expect(response).to have_http_status(400)
201
      expect(json_response['message']).to eq('Target foo is invalid')
202 203
    end
  end
D
Dmitriy Zaporozhets 已提交
204

205
  describe 'POST /projects/:id/repository/tags/:tag_name/release' do
D
Dmitriy Zaporozhets 已提交
206 207 208
    let(:tag_name) { project.repository.tag_names.first }
    let(:description) { 'Awesome release!' }

209
    it 'creates description for existing git tag' do
210
      post api("/projects/#{project.id}/repository/tags/#{tag_name}/release", user),
D
Dmitriy Zaporozhets 已提交
211 212
        description: description

Z
Z.J. van de Weg 已提交
213
      expect(response).to have_http_status(201)
214
      expect(json_response['tag_name']).to eq(tag_name)
D
Dmitriy Zaporozhets 已提交
215 216
      expect(json_response['description']).to eq(description)
    end
217

218
    it 'returns 404 if the tag does not exist' do
219
      post api("/projects/#{project.id}/repository/tags/foobar/release", user),
220 221
        description: description

Z
Z.J. van de Weg 已提交
222
      expect(response).to have_http_status(404)
223 224
      expect(json_response['message']).to eq('Tag does not exist')
    end
225 226 227 228 229 230 231

    context 'on tag with existing release' do
      before do
        release = project.releases.find_or_initialize_by(tag: tag_name)
        release.update_attributes(description: description)
      end

232
      it 'returns 409 if there is already a release' do
233 234 235
        post api("/projects/#{project.id}/repository/tags/#{tag_name}/release", user),
          description: description

Z
Z.J. van de Weg 已提交
236
        expect(response).to have_http_status(409)
237 238 239
        expect(json_response['message']).to eq('Release already exists')
      end
    end
D
Dmitriy Zaporozhets 已提交
240
  end
241 242 243 244 245 246 247 248 249 250 251 252

  describe 'PUT id/repository/tags/:tag_name/release' do
    let(:tag_name) { project.repository.tag_names.first }
    let(:description) { 'Awesome release!' }
    let(:new_description) { 'The best release!' }

    context 'on tag with existing release' do
      before do
        release = project.releases.find_or_initialize_by(tag: tag_name)
        release.update_attributes(description: description)
      end

253
      it 'updates the release description' do
254 255 256
        put api("/projects/#{project.id}/repository/tags/#{tag_name}/release", user),
          description: new_description

Z
Z.J. van de Weg 已提交
257
        expect(response).to have_http_status(200)
258 259 260 261 262
        expect(json_response['tag_name']).to eq(tag_name)
        expect(json_response['description']).to eq(new_description)
      end
    end

263
    it 'returns 404 if the tag does not exist' do
264 265 266
      put api("/projects/#{project.id}/repository/tags/foobar/release", user),
        description: new_description

Z
Z.J. van de Weg 已提交
267
      expect(response).to have_http_status(404)
268 269 270
      expect(json_response['message']).to eq('Tag does not exist')
    end

271
    it 'returns 404 if the release does not exist' do
272 273 274
      put api("/projects/#{project.id}/repository/tags/#{tag_name}/release", user),
        description: new_description

Z
Z.J. van de Weg 已提交
275
      expect(response).to have_http_status(404)
276 277 278
      expect(json_response['message']).to eq('Release does not exist')
    end
  end
279
end