Commit 4bfb98ddc90bcc6076e2819619fec7607e74358b

Authored by Dmitriy Zaporozhets
2 parents 0a20f7e7 33c48ecd

Merge pull request #2877 from former03/feature_groups_api

Add groups api
doc/api/README.md
... ... @@ -32,6 +32,7 @@ When listing resources you can pass the following parameters:
32 32 + [Users](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/users.md)
33 33 + [Session](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/session.md)
34 34 + [Projects](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/projects.md)
  35 ++ [Groups](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/groups.md)
35 36 + [Snippets](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/snippets.md)
36 37 + [Repositories](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/repositories.md)
37 38 + [Issues](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/issues.md)
... ...
doc/api/groups.md 0 → 100644
... ... @@ -0,0 +1,45 @@
  1 +## List project groups
  2 +
  3 +Get a list of groups. (As user: my groups, as admin: all groups)
  4 +
  5 +```
  6 +GET /groups
  7 +```
  8 +
  9 +```json
  10 +[
  11 + {
  12 + "id": 1,
  13 + "name": "Foobar Group",
  14 + "path": "foo-bar",
  15 + "owner_id": 18
  16 + }
  17 +]
  18 +```
  19 +
  20 +## Details of group
  21 +
  22 +Get all details of a group.
  23 +
  24 +```
  25 +GET /groups/:id
  26 +```
  27 +
  28 +Parameters:
  29 +
  30 ++ `id` (required) - The ID of a group
  31 +
  32 +## New group
  33 +
  34 +Create a new project group. Available only for admin
  35 +
  36 +```
  37 +POST /groups
  38 +```
  39 +
  40 +Parameters:
  41 ++ `name` (required) - Email
  42 ++ `path` - Password
  43 +
  44 +Will return created group with status `201 Created` on success, or `404 Not found` on fail.
  45 +
... ...
lib/api.rb
... ... @@ -11,7 +11,8 @@ module Gitlab
11 11 format :json
12 12 error_format :json
13 13 helpers APIHelpers
14   -
  14 +
  15 + mount Groups
15 16 mount Users
16 17 mount Projects
17 18 mount Issues
... ...
lib/api/entities.rb
... ... @@ -32,6 +32,15 @@ module Gitlab
32 32 end
33 33 end
34 34  
  35 + class Group < Grape::Entity
  36 + expose :id, :name, :path, :owner_id
  37 + end
  38 +
  39 + class GroupDetail < Group
  40 + expose :projects, using: Entities::Project
  41 + end
  42 +
  43 +
35 44 class RepoObject < Grape::Entity
36 45 expose :name, :commit
37 46 expose :protected do |repo, options|
... ...
lib/api/groups.rb 0 → 100644
... ... @@ -0,0 +1,56 @@
  1 +module Gitlab
  2 + # groups API
  3 + class Groups < Grape::API
  4 + before { authenticate! }
  5 +
  6 + resource :groups do
  7 + # Get a groups list
  8 + #
  9 + # Example Request:
  10 + # GET /groups
  11 + get do
  12 + if current_user.admin
  13 + @groups = paginate Group
  14 + else
  15 + @groups = paginate current_user.groups
  16 + end
  17 + present @groups, with: Entities::Group
  18 + end
  19 +
  20 + # Create group. Available only for admin
  21 + #
  22 + # Parameters:
  23 + # name (required) - Name
  24 + # path (required) - Path
  25 + # Example Request:
  26 + # POST /groups
  27 + post do
  28 + authenticated_as_admin!
  29 + attrs = attributes_for_keys [:name, :path]
  30 + @group = Group.new(attrs)
  31 + @group.owner = current_user
  32 +
  33 + if @group.save
  34 + present @group, with: Entities::Group
  35 + else
  36 + not_found!
  37 + end
  38 + end
  39 +
  40 + # Get a single group, with containing projects
  41 + #
  42 + # Parameters:
  43 + # id (required) - The ID of a group
  44 + # Example Request:
  45 + # GET /groups/:id
  46 + get ":id" do
  47 + @group = Group.find(params[:id])
  48 + if current_user.admin or current_user.groups.include? @group
  49 + present @group, with: Entities::GroupDetail
  50 + else
  51 + not_found!
  52 + end
  53 + end
  54 + end
  55 + end
  56 +end
... ...
spec/requests/api/groups_spec.rb 0 → 100644
... ... @@ -0,0 +1,93 @@
  1 +require 'spec_helper'
  2 +
  3 +describe Gitlab::API do
  4 + include ApiHelpers
  5 +
  6 + let(:user1) { create(:user) }
  7 + let(:user2) { create(:user) }
  8 + let(:admin) { create(:admin) }
  9 + let!(:group1) { create(:group, owner: user1) }
  10 + let!(:group2) { create(:group, owner: user2) }
  11 +
  12 + describe "GET /groups" do
  13 + context "when unauthenticated" do
  14 + it "should return authentication error" do
  15 + get api("/groups")
  16 + response.status.should == 401
  17 + end
  18 + end
  19 +
  20 + context "when authenticated as user" do
  21 + it "normal user: should return an array of groups of user1" do
  22 + get api("/groups", user1)
  23 + response.status.should == 200
  24 + json_response.should be_an Array
  25 + json_response.length.should == 1
  26 + json_response.first['name'].should == group1.name
  27 + end
  28 + end
  29 +
  30 + context "when authenticated as admin" do
  31 + it "admin: should return an array of all groups" do
  32 + get api("/groups", admin)
  33 + response.status.should == 200
  34 + json_response.should be_an Array
  35 + json_response.length.should == 2
  36 + end
  37 + end
  38 + end
  39 +
  40 + describe "GET /groups/:id" do
  41 + context "when authenticated as user" do
  42 + it "should return one of user1's groups" do
  43 + get api("/groups/#{group1.id}", user1)
  44 + response.status.should == 200
  45 + json_response['name'] == group1.name
  46 + end
  47 +
  48 + it "should not return a non existing group" do
  49 + get api("/groups/1328", user1)
  50 + response.status.should == 404
  51 + end
  52 +
  53 + it "should not return a group not attached to user1" do
  54 + get api("/groups/#{group2.id}", user1)
  55 + response.status.should == 404
  56 + end
  57 + end
  58 +
  59 + context "when authenticated as admin" do
  60 + it "should return any existing group" do
  61 + get api("/groups/#{group2.id}", admin)
  62 + response.status.should == 200
  63 + json_response['name'] == group2.name
  64 + end
  65 +
  66 + it "should not return a non existing group" do
  67 + get api("/groups/1328", admin)
  68 + response.status.should == 404
  69 + end
  70 + end
  71 + end
  72 +
  73 + describe "POST /groups" do
  74 + context "when authenticated as user" do
  75 + it "should not create group" do
  76 + post api("/groups", user1), attributes_for(:group)
  77 + response.status.should == 403
  78 + end
  79 + end
  80 +
  81 + context "when authenticated as admin" do
  82 + it "should create group" do
  83 + post api("/groups", admin), attributes_for(:group)
  84 + response.status.should == 201
  85 + end
  86 +
  87 + it "should not create group, duplicate" do
  88 + post api("/groups", admin), {:name => "Duplicate Test", :path => group2.path}
  89 + response.status.should == 404
  90 + end
  91 + end
  92 + end
  93 +end
... ...