Commit 068cf2f467ee76d5a371694b41b3247d04377cb9
1 parent
bbaa0fcc
Exists in
master
and in
4 other branches
split repositories and projects api
Showing
5 changed files
with
268 additions
and
235 deletions
Show diff stats
lib/api/api.rb
lib/api/projects.rb
... | ... | @@ -286,95 +286,6 @@ module API |
286 | 286 | end |
287 | 287 | end |
288 | 288 | |
289 | - # Get a project repository branches | |
290 | - # | |
291 | - # Parameters: | |
292 | - # id (required) - The ID of a project | |
293 | - # Example Request: | |
294 | - # GET /projects/:id/repository/branches | |
295 | - get ":id/repository/branches" do | |
296 | - present user_project.repo.heads.sort_by(&:name), with: Entities::RepoObject, project: user_project | |
297 | - end | |
298 | - | |
299 | - # Get a single branch | |
300 | - # | |
301 | - # Parameters: | |
302 | - # id (required) - The ID of a project | |
303 | - # branch (required) - The name of the branch | |
304 | - # Example Request: | |
305 | - # GET /projects/:id/repository/branches/:branch | |
306 | - get ":id/repository/branches/:branch" do | |
307 | - @branch = user_project.repo.heads.find { |item| item.name == params[:branch] } | |
308 | - not_found!("Branch does not exist") if @branch.nil? | |
309 | - present @branch, with: Entities::RepoObject, project: user_project | |
310 | - end | |
311 | - | |
312 | - # Protect a single branch | |
313 | - # | |
314 | - # Parameters: | |
315 | - # id (required) - The ID of a project | |
316 | - # branch (required) - The name of the branch | |
317 | - # Example Request: | |
318 | - # PUT /projects/:id/repository/branches/:branch/protect | |
319 | - put ":id/repository/branches/:branch/protect" do | |
320 | - @branch = user_project.repo.heads.find { |item| item.name == params[:branch] } | |
321 | - not_found! unless @branch | |
322 | - protected = user_project.protected_branches.find_by_name(@branch.name) | |
323 | - | |
324 | - unless protected | |
325 | - user_project.protected_branches.create(name: @branch.name) | |
326 | - end | |
327 | - | |
328 | - present @branch, with: Entities::RepoObject, project: user_project | |
329 | - end | |
330 | - | |
331 | - # Unprotect a single branch | |
332 | - # | |
333 | - # Parameters: | |
334 | - # id (required) - The ID of a project | |
335 | - # branch (required) - The name of the branch | |
336 | - # Example Request: | |
337 | - # PUT /projects/:id/repository/branches/:branch/unprotect | |
338 | - put ":id/repository/branches/:branch/unprotect" do | |
339 | - @branch = user_project.repo.heads.find { |item| item.name == params[:branch] } | |
340 | - not_found! unless @branch | |
341 | - protected = user_project.protected_branches.find_by_name(@branch.name) | |
342 | - | |
343 | - if protected | |
344 | - protected.destroy | |
345 | - end | |
346 | - | |
347 | - present @branch, with: Entities::RepoObject, project: user_project | |
348 | - end | |
349 | - | |
350 | - # Get a project repository tags | |
351 | - # | |
352 | - # Parameters: | |
353 | - # id (required) - The ID of a project | |
354 | - # Example Request: | |
355 | - # GET /projects/:id/repository/tags | |
356 | - get ":id/repository/tags" do | |
357 | - present user_project.repo.tags.sort_by(&:name).reverse, with: Entities::RepoObject | |
358 | - end | |
359 | - | |
360 | - # Get a project repository commits | |
361 | - # | |
362 | - # Parameters: | |
363 | - # id (required) - The ID of a project | |
364 | - # ref_name (optional) - The name of a repository branch or tag, if not given the default branch is used | |
365 | - # Example Request: | |
366 | - # GET /projects/:id/repository/commits | |
367 | - get ":id/repository/commits" do | |
368 | - authorize! :download_code, user_project | |
369 | - | |
370 | - page = params[:page] || 0 | |
371 | - per_page = (params[:per_page] || 20).to_i | |
372 | - ref = params[:ref_name] || user_project.try(:default_branch) || 'master' | |
373 | - | |
374 | - commits = user_project.repository.commits(ref, nil, per_page, page * per_page) | |
375 | - present commits, with: Entities::RepoCommit | |
376 | - end | |
377 | - | |
378 | 289 | # Get a project snippets |
379 | 290 | # |
380 | 291 | # Parameters: |
... | ... | @@ -479,32 +390,6 @@ module API |
479 | 390 | present @snippet.content |
480 | 391 | end |
481 | 392 | |
482 | - # Get a raw file contents | |
483 | - # | |
484 | - # Parameters: | |
485 | - # id (required) - The ID of a project | |
486 | - # sha (required) - The commit or branch name | |
487 | - # filepath (required) - The path to the file to display | |
488 | - # Example Request: | |
489 | - # GET /projects/:id/repository/commits/:sha/blob | |
490 | - get ":id/repository/commits/:sha/blob" do | |
491 | - authorize! :download_code, user_project | |
492 | - required_attributes! [:filepath] | |
493 | - | |
494 | - ref = params[:sha] | |
495 | - | |
496 | - repo = user_project.repository | |
497 | - | |
498 | - commit = repo.commit(ref) | |
499 | - not_found! "Commit" unless commit | |
500 | - | |
501 | - blob = Gitlab::Git::Blob.new(repo, commit.id, ref, params[:filepath]) | |
502 | - not_found! "File" unless blob.exists? | |
503 | - | |
504 | - content_type blob.mime_type | |
505 | - present blob.data | |
506 | - end | |
507 | - | |
508 | 393 | # Get a specific project's keys |
509 | 394 | # |
510 | 395 | # Example Request: | ... | ... |
... | ... | @@ -0,0 +1,133 @@ |
1 | +module API | |
2 | + # Projects API | |
3 | + class Repositories < Grape::API | |
4 | + before { authenticate! } | |
5 | + | |
6 | + resource :projects do | |
7 | + helpers do | |
8 | + def handle_project_member_errors(errors) | |
9 | + if errors[:project_access].any? | |
10 | + error!(errors[:project_access], 422) | |
11 | + end | |
12 | + not_found! | |
13 | + end | |
14 | + end | |
15 | + | |
16 | + # Get a project repository branches | |
17 | + # | |
18 | + # Parameters: | |
19 | + # id (required) - The ID of a project | |
20 | + # Example Request: | |
21 | + # GET /projects/:id/repository/branches | |
22 | + get ":id/repository/branches" do | |
23 | + present user_project.repo.heads.sort_by(&:name), with: Entities::RepoObject, project: user_project | |
24 | + end | |
25 | + | |
26 | + # Get a single branch | |
27 | + # | |
28 | + # Parameters: | |
29 | + # id (required) - The ID of a project | |
30 | + # branch (required) - The name of the branch | |
31 | + # Example Request: | |
32 | + # GET /projects/:id/repository/branches/:branch | |
33 | + get ":id/repository/branches/:branch" do | |
34 | + @branch = user_project.repo.heads.find { |item| item.name == params[:branch] } | |
35 | + not_found!("Branch does not exist") if @branch.nil? | |
36 | + present @branch, with: Entities::RepoObject, project: user_project | |
37 | + end | |
38 | + | |
39 | + # Protect a single branch | |
40 | + # | |
41 | + # Parameters: | |
42 | + # id (required) - The ID of a project | |
43 | + # branch (required) - The name of the branch | |
44 | + # Example Request: | |
45 | + # PUT /projects/:id/repository/branches/:branch/protect | |
46 | + put ":id/repository/branches/:branch/protect" do | |
47 | + @branch = user_project.repo.heads.find { |item| item.name == params[:branch] } | |
48 | + not_found! unless @branch | |
49 | + protected = user_project.protected_branches.find_by_name(@branch.name) | |
50 | + | |
51 | + unless protected | |
52 | + user_project.protected_branches.create(name: @branch.name) | |
53 | + end | |
54 | + | |
55 | + present @branch, with: Entities::RepoObject, project: user_project | |
56 | + end | |
57 | + | |
58 | + # Unprotect a single branch | |
59 | + # | |
60 | + # Parameters: | |
61 | + # id (required) - The ID of a project | |
62 | + # branch (required) - The name of the branch | |
63 | + # Example Request: | |
64 | + # PUT /projects/:id/repository/branches/:branch/unprotect | |
65 | + put ":id/repository/branches/:branch/unprotect" do | |
66 | + @branch = user_project.repo.heads.find { |item| item.name == params[:branch] } | |
67 | + not_found! unless @branch | |
68 | + protected = user_project.protected_branches.find_by_name(@branch.name) | |
69 | + | |
70 | + if protected | |
71 | + protected.destroy | |
72 | + end | |
73 | + | |
74 | + present @branch, with: Entities::RepoObject, project: user_project | |
75 | + end | |
76 | + | |
77 | + # Get a project repository tags | |
78 | + # | |
79 | + # Parameters: | |
80 | + # id (required) - The ID of a project | |
81 | + # Example Request: | |
82 | + # GET /projects/:id/repository/tags | |
83 | + get ":id/repository/tags" do | |
84 | + present user_project.repo.tags.sort_by(&:name).reverse, with: Entities::RepoObject | |
85 | + end | |
86 | + | |
87 | + # Get a project repository commits | |
88 | + # | |
89 | + # Parameters: | |
90 | + # id (required) - The ID of a project | |
91 | + # ref_name (optional) - The name of a repository branch or tag, if not given the default branch is used | |
92 | + # Example Request: | |
93 | + # GET /projects/:id/repository/commits | |
94 | + get ":id/repository/commits" do | |
95 | + authorize! :download_code, user_project | |
96 | + | |
97 | + page = params[:page] || 0 | |
98 | + per_page = (params[:per_page] || 20).to_i | |
99 | + ref = params[:ref_name] || user_project.try(:default_branch) || 'master' | |
100 | + | |
101 | + commits = user_project.repository.commits(ref, nil, per_page, page * per_page) | |
102 | + present commits, with: Entities::RepoCommit | |
103 | + end | |
104 | + | |
105 | + # Get a raw file contents | |
106 | + # | |
107 | + # Parameters: | |
108 | + # id (required) - The ID of a project | |
109 | + # sha (required) - The commit or branch name | |
110 | + # filepath (required) - The path to the file to display | |
111 | + # Example Request: | |
112 | + # GET /projects/:id/repository/commits/:sha/blob | |
113 | + get ":id/repository/commits/:sha/blob" do | |
114 | + authorize! :download_code, user_project | |
115 | + required_attributes! [:filepath] | |
116 | + | |
117 | + ref = params[:sha] | |
118 | + | |
119 | + repo = user_project.repository | |
120 | + | |
121 | + commit = repo.commit(ref) | |
122 | + not_found! "Commit" unless commit | |
123 | + | |
124 | + blob = Gitlab::Git::Blob.new(repo, commit.id, ref, params[:filepath]) | |
125 | + not_found! "File" unless blob.exists? | |
126 | + | |
127 | + content_type blob.mime_type | |
128 | + present blob.data | |
129 | + end | |
130 | + end | |
131 | + end | |
132 | +end | |
133 | + | ... | ... |
spec/requests/api/projects_spec.rb
... | ... | @@ -173,75 +173,6 @@ describe API::API do |
173 | 173 | end |
174 | 174 | end |
175 | 175 | |
176 | - describe "GET /projects/:id/repository/branches" do | |
177 | - it "should return an array of project branches" do | |
178 | - get api("/projects/#{project.id}/repository/branches", user) | |
179 | - response.status.should == 200 | |
180 | - json_response.should be_an Array | |
181 | - json_response.first['name'].should == project.repo.heads.sort_by(&:name).first.name | |
182 | - end | |
183 | - end | |
184 | - | |
185 | - describe "GET /projects/:id/repository/branches/:branch" do | |
186 | - it "should return the branch information for a single branch" do | |
187 | - get api("/projects/#{project.id}/repository/branches/new_design", user) | |
188 | - response.status.should == 200 | |
189 | - | |
190 | - json_response['name'].should == 'new_design' | |
191 | - json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' | |
192 | - json_response['protected'].should == false | |
193 | - end | |
194 | - | |
195 | - it "should return a 404 error if branch is not available" do | |
196 | - get api("/projects/#{project.id}/repository/branches/unknown", user) | |
197 | - response.status.should == 404 | |
198 | - end | |
199 | - end | |
200 | - | |
201 | - describe "PUT /projects/:id/repository/branches/:branch/protect" do | |
202 | - it "should protect a single branch" do | |
203 | - put api("/projects/#{project.id}/repository/branches/new_design/protect", user) | |
204 | - response.status.should == 200 | |
205 | - | |
206 | - json_response['name'].should == 'new_design' | |
207 | - json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' | |
208 | - json_response['protected'].should == true | |
209 | - end | |
210 | - | |
211 | - it "should return a 404 error if branch not found" do | |
212 | - put api("/projects/#{project.id}/repository/branches/unknown/protect", user) | |
213 | - response.status.should == 404 | |
214 | - end | |
215 | - | |
216 | - it "should return success when protect branch again" do | |
217 | - put api("/projects/#{project.id}/repository/branches/new_design/protect", user) | |
218 | - put api("/projects/#{project.id}/repository/branches/new_design/protect", user) | |
219 | - response.status.should == 200 | |
220 | - end | |
221 | - end | |
222 | - | |
223 | - describe "PUT /projects/:id/repository/branches/:branch/unprotect" do | |
224 | - it "should unprotect a single branch" do | |
225 | - put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user) | |
226 | - response.status.should == 200 | |
227 | - | |
228 | - json_response['name'].should == 'new_design' | |
229 | - json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' | |
230 | - json_response['protected'].should == false | |
231 | - end | |
232 | - | |
233 | - it "should return success when unprotect branch" do | |
234 | - put api("/projects/#{project.id}/repository/branches/unknown/unprotect", user) | |
235 | - response.status.should == 404 | |
236 | - end | |
237 | - | |
238 | - it "should return success when unprotect branch again" do | |
239 | - put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user) | |
240 | - put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user) | |
241 | - response.status.should == 200 | |
242 | - end | |
243 | - end | |
244 | - | |
245 | 176 | describe "GET /projects/:id/members" do |
246 | 177 | it "should return project team members" do |
247 | 178 | get api("/projects/#{project.id}/members", user) |
... | ... | @@ -491,35 +422,6 @@ describe API::API do |
491 | 422 | end |
492 | 423 | end |
493 | 424 | |
494 | - describe "GET /projects/:id/repository/tags" do | |
495 | - it "should return an array of project tags" do | |
496 | - get api("/projects/#{project.id}/repository/tags", user) | |
497 | - response.status.should == 200 | |
498 | - json_response.should be_an Array | |
499 | - json_response.first['name'].should == project.repo.tags.sort_by(&:name).reverse.first.name | |
500 | - end | |
501 | - end | |
502 | - | |
503 | - describe "GET /projects/:id/repository/commits" do | |
504 | - context "authorized user" do | |
505 | - before { project.team << [user2, :reporter] } | |
506 | - | |
507 | - it "should return project commits" do | |
508 | - get api("/projects/#{project.id}/repository/commits", user) | |
509 | - response.status.should == 200 | |
510 | - | |
511 | - json_response.should be_an Array | |
512 | - json_response.first['id'].should == project.repository.commit.id | |
513 | - end | |
514 | - end | |
515 | - | |
516 | - context "unauthorized user" do | |
517 | - it "should not return project commits" do | |
518 | - get api("/projects/#{project.id}/repository/commits") | |
519 | - response.status.should == 401 | |
520 | - end | |
521 | - end | |
522 | - end | |
523 | 425 | |
524 | 426 | describe "GET /projects/:id/snippets" do |
525 | 427 | it "should return an array of project snippets" do |
... | ... | @@ -613,28 +515,6 @@ describe API::API do |
613 | 515 | end |
614 | 516 | end |
615 | 517 | |
616 | - describe "GET /projects/:id/repository/commits/:sha/blob" do | |
617 | - it "should get the raw file contents" do | |
618 | - get api("/projects/#{project.id}/repository/commits/master/blob?filepath=README.md", user) | |
619 | - response.status.should == 200 | |
620 | - end | |
621 | - | |
622 | - it "should return 404 for invalid branch_name" do | |
623 | - get api("/projects/#{project.id}/repository/commits/invalid_branch_name/blob?filepath=README.md", user) | |
624 | - response.status.should == 404 | |
625 | - end | |
626 | - | |
627 | - it "should return 404 for invalid file" do | |
628 | - get api("/projects/#{project.id}/repository/commits/master/blob?filepath=README.invalid", user) | |
629 | - response.status.should == 404 | |
630 | - end | |
631 | - | |
632 | - it "should return a 400 error if filepath is missing" do | |
633 | - get api("/projects/#{project.id}/repository/commits/master/blob", user) | |
634 | - response.status.should == 400 | |
635 | - end | |
636 | - end | |
637 | - | |
638 | 518 | describe :deploy_keys do |
639 | 519 | let(:deploy_keys_project) { create(:deploy_keys_project, project: project) } |
640 | 520 | let(:deploy_key) { deploy_keys_project.deploy_key } | ... | ... |
... | ... | @@ -0,0 +1,134 @@ |
1 | +require 'spec_helper' | |
2 | + | |
3 | +describe API::API do | |
4 | + include ApiHelpers | |
5 | + before(:each) { enable_observers } | |
6 | + | |
7 | + let(:user) { create(:user) } | |
8 | + let!(:project) { create(:project_with_code, creator_id: user.id) } | |
9 | + let!(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) } | |
10 | + | |
11 | + before { project.team << [user, :reporter] } | |
12 | + | |
13 | + | |
14 | + describe "GET /projects/:id/repository/branches" do | |
15 | + it "should return an array of project branches" do | |
16 | + get api("/projects/#{project.id}/repository/branches", user) | |
17 | + response.status.should == 200 | |
18 | + json_response.should be_an Array | |
19 | + json_response.first['name'].should == project.repo.heads.sort_by(&:name).first.name | |
20 | + end | |
21 | + end | |
22 | + | |
23 | + describe "GET /projects/:id/repository/branches/:branch" do | |
24 | + it "should return the branch information for a single branch" do | |
25 | + get api("/projects/#{project.id}/repository/branches/new_design", user) | |
26 | + response.status.should == 200 | |
27 | + | |
28 | + json_response['name'].should == 'new_design' | |
29 | + json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' | |
30 | + json_response['protected'].should == false | |
31 | + end | |
32 | + | |
33 | + it "should return a 404 error if branch is not available" do | |
34 | + get api("/projects/#{project.id}/repository/branches/unknown", user) | |
35 | + response.status.should == 404 | |
36 | + end | |
37 | + end | |
38 | + | |
39 | + describe "PUT /projects/:id/repository/branches/:branch/protect" do | |
40 | + it "should protect a single branch" do | |
41 | + put api("/projects/#{project.id}/repository/branches/new_design/protect", user) | |
42 | + response.status.should == 200 | |
43 | + | |
44 | + json_response['name'].should == 'new_design' | |
45 | + json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' | |
46 | + json_response['protected'].should == true | |
47 | + end | |
48 | + | |
49 | + it "should return a 404 error if branch not found" do | |
50 | + put api("/projects/#{project.id}/repository/branches/unknown/protect", user) | |
51 | + response.status.should == 404 | |
52 | + end | |
53 | + | |
54 | + it "should return success when protect branch again" do | |
55 | + put api("/projects/#{project.id}/repository/branches/new_design/protect", user) | |
56 | + put api("/projects/#{project.id}/repository/branches/new_design/protect", user) | |
57 | + response.status.should == 200 | |
58 | + end | |
59 | + end | |
60 | + | |
61 | + describe "PUT /projects/:id/repository/branches/:branch/unprotect" do | |
62 | + it "should unprotect a single branch" do | |
63 | + put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user) | |
64 | + response.status.should == 200 | |
65 | + | |
66 | + json_response['name'].should == 'new_design' | |
67 | + json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' | |
68 | + json_response['protected'].should == false | |
69 | + end | |
70 | + | |
71 | + it "should return success when unprotect branch" do | |
72 | + put api("/projects/#{project.id}/repository/branches/unknown/unprotect", user) | |
73 | + response.status.should == 404 | |
74 | + end | |
75 | + | |
76 | + it "should return success when unprotect branch again" do | |
77 | + put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user) | |
78 | + put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user) | |
79 | + response.status.should == 200 | |
80 | + end | |
81 | + end | |
82 | + | |
83 | + describe "GET /projects/:id/repository/tags" do | |
84 | + it "should return an array of project tags" do | |
85 | + get api("/projects/#{project.id}/repository/tags", user) | |
86 | + response.status.should == 200 | |
87 | + json_response.should be_an Array | |
88 | + json_response.first['name'].should == project.repo.tags.sort_by(&:name).reverse.first.name | |
89 | + end | |
90 | + end | |
91 | + | |
92 | + describe "GET /projects/:id/repository/commits" do | |
93 | + context "authorized user" do | |
94 | + before { project.team << [user2, :reporter] } | |
95 | + | |
96 | + it "should return project commits" do | |
97 | + get api("/projects/#{project.id}/repository/commits", user) | |
98 | + response.status.should == 200 | |
99 | + | |
100 | + json_response.should be_an Array | |
101 | + json_response.first['id'].should == project.repository.commit.id | |
102 | + end | |
103 | + end | |
104 | + | |
105 | + context "unauthorized user" do | |
106 | + it "should not return project commits" do | |
107 | + get api("/projects/#{project.id}/repository/commits") | |
108 | + response.status.should == 401 | |
109 | + end | |
110 | + end | |
111 | + end | |
112 | + | |
113 | + describe "GET /projects/:id/repository/commits/:sha/blob" do | |
114 | + it "should get the raw file contents" do | |
115 | + get api("/projects/#{project.id}/repository/commits/master/blob?filepath=README.md", user) | |
116 | + response.status.should == 200 | |
117 | + end | |
118 | + | |
119 | + it "should return 404 for invalid branch_name" do | |
120 | + get api("/projects/#{project.id}/repository/commits/invalid_branch_name/blob?filepath=README.md", user) | |
121 | + response.status.should == 404 | |
122 | + end | |
123 | + | |
124 | + it "should return 404 for invalid file" do | |
125 | + get api("/projects/#{project.id}/repository/commits/master/blob?filepath=README.invalid", user) | |
126 | + response.status.should == 404 | |
127 | + end | |
128 | + | |
129 | + it "should return a 400 error if filepath is missing" do | |
130 | + get api("/projects/#{project.id}/repository/commits/master/blob", user) | |
131 | + response.status.should == 400 | |
132 | + end | |
133 | + end | |
134 | +end | ... | ... |