summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMayra Cabrera <mcabrera@gitlab.com>2019-04-16 11:16:52 -0500
committerMayra Cabrera <mcabrera@gitlab.com>2019-04-18 19:00:48 -0500
commit1dd4a007804fa0e6ea00a00805d08808f6c0be3a (patch)
tree09a6b2520dfea63090b3375f02f36724639951e2
parent86be4a6f466205b415de74330dd495a2e8b3c9d0 (diff)
downloadgitlab-ce-39858-add-group-owned-info-to-projects-api.tar.gz
Adds namespace information to project endpoint39858-add-group-owned-info-to-projects-api
- Namespace now return avatar_url and web_url - NamespaceBasic entity was modified to include avatar_url and web_url, information is fetched differently depending if the Namespace is a user or a group Includes documentation changes Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/39858
-rw-r--r--app/models/namespace.rb5
-rw-r--r--doc/api/projects.md7
-rw-r--r--lib/api/entities.rb10
-rw-r--r--spec/models/namespace_spec.rb22
-rw-r--r--spec/requests/api/projects_spec.rb36
5 files changed, 76 insertions, 4 deletions
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index dea34e812ca..8638c5a9c53 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -51,6 +51,7 @@ class Namespace < ApplicationRecord
validate :nesting_level_allowed
delegate :name, to: :owner, allow_nil: true, prefix: true
+ delegate :avatar_url, to: :owner, allow_nil: true
after_commit :refresh_access_of_projects_invited_groups, on: :update, if: -> { previous_changes.key?('share_with_group_lock') }
@@ -149,6 +150,10 @@ class Namespace < ApplicationRecord
type == 'Group' ? 'group' : 'user'
end
+ def user?
+ kind == 'user'
+ end
+
def find_fork_of(project)
return unless project.fork_network
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 0a950352ecf..951961e45ff 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -494,7 +494,9 @@ GET /projects/:id
"name": "Diaspora",
"path": "diaspora",
"kind": "group",
- "full_path": "diaspora"
+ "full_path": "diaspora",
+ "avatar_url": "http://localhost:3000/uploads/group/avatar/3/foo.jpg",
+ "web_url": "http://localhost:3000/groups/diaspora"
},
"import_status": "none",
"import_error": null,
@@ -561,6 +563,8 @@ GET /projects/:id
}
```
+**Note**: The `web_url` and `avatar_url` attributes on `namespace` were [introduced][ce-27427] in GitLab 11.11.
+
If the project is a fork, and you provide a valid token to authenticate, the
`forked_from_project` field will appear in the response.
@@ -1587,3 +1591,4 @@ GET /projects/:id/snapshot
[eep]: https://about.gitlab.com/pricing/ "Available only in GitLab Premium"
[ee-6137]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/6137
+[ce-27427]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/27427
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 4bdac278add..ee8480122c4 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -922,7 +922,15 @@ module API
end
class NamespaceBasic < Grape::Entity
- expose :id, :name, :path, :kind, :full_path, :parent_id
+ expose :id, :name, :path, :kind, :full_path, :parent_id, :avatar_url
+
+ expose :web_url do |namespace|
+ if namespace.user?
+ Gitlab::Routing.url_helpers.user_url(namespace.owner)
+ else
+ namespace.web_url
+ end
+ end
end
class Namespace < NamespaceBasic
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 387d1221c76..95a4b0f6d71 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -63,6 +63,11 @@ describe Namespace do
end
end
+ describe 'delegate' do
+ it { is_expected.to delegate_method(:name).to(:owner).with_prefix.with_arguments(allow_nil: true) }
+ it { is_expected.to delegate_method(:avatar_url).to(:owner).with_arguments(allow_nil: true) }
+ end
+
describe "Respond to" do
it { is_expected.to respond_to(:human_name) }
it { is_expected.to respond_to(:to_param) }
@@ -801,4 +806,21 @@ describe Namespace do
end
end
end
+
+ describe '#user?' do
+ subject { namespace.user? }
+
+ context 'when type is a user' do
+ let(:user) { create(:user) }
+ let(:namespace) { user.namespace }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when type is a group' do
+ let(:namespace) { create(:group) }
+
+ it { is_expected.to be_falsy }
+ end
+ end
end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 352ea448c00..577f61ae8d0 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -1047,7 +1047,6 @@ describe API::Projects do
expect(json_response['http_url_to_repo']).to be_present
expect(json_response['web_url']).to be_present
expect(json_response['owner']).to be_a Hash
- expect(json_response['owner']).to be_a Hash
expect(json_response['name']).to eq(project.name)
expect(json_response['path']).to be_present
expect(json_response['issues_enabled']).to be_present
@@ -1135,7 +1134,9 @@ describe API::Projects do
'path' => user.namespace.path,
'kind' => user.namespace.kind,
'full_path' => user.namespace.full_path,
- 'parent_id' => nil
+ 'parent_id' => nil,
+ 'avatar_url' => user.avatar_url,
+ 'web_url' => Gitlab::Routing.url_helpers.user_url(user)
})
end
@@ -1337,6 +1338,37 @@ describe API::Projects do
end
end
end
+
+ context 'when project belongs to a group namespace' do
+ let(:group) { create(:group, :with_avatar) }
+ let(:project) { create(:project, namespace: group) }
+ let!(:project_member) { create(:project_member, :developer, user: user, project: project) }
+
+ it 'returns group web_url and avatar_url' do
+ get api("/projects/#{project.id}", user)
+
+ expect(response).to have_gitlab_http_status(200)
+
+ group_data = json_response['namespace']
+ expect(group_data['web_url']).to eq(group.web_url)
+ expect(group_data['avatar_url']).to eq(group.avatar_url)
+ end
+ end
+
+ context 'when project belongs to a user namespace' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, namespace: user.namespace) }
+
+ it 'returns user web_url and avatar_url' do
+ get api("/projects/#{project.id}", user)
+
+ expect(response).to have_gitlab_http_status(200)
+
+ user_data = json_response['namespace']
+ expect(user_data['web_url']).to eq("http://localhost/#{user.username}")
+ expect(user_data['avatar_url']).to eq(user.avatar_url)
+ end
+ end
end
context 'with external authorization' do