summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorStan Hu <stanhu@gmail.com>2019-08-08 04:40:55 +0000
committerStan Hu <stanhu@gmail.com>2019-08-08 04:40:55 +0000
commit3ad34c3a243cda19e73fbda0c9682e0a1c16c10a (patch)
tree38a419d054a0c999449d7837a311e28364e0cc42 /spec
parent4985f6e26d758e7d5e43c3525a4afe4a9459ce8e (diff)
parentd4078b535c9854695e770cdfb5e0f4846a8cf64a (diff)
downloadgitlab-ce-3ad34c3a243cda19e73fbda0c9682e0a1c16c10a.tar.gz
Merge branch '20137-starrers' into 'master'
Add possibilty to view starrers ("stargazers") of a repository & any user's starred repositories Closes #20137 See merge request gitlab-org/gitlab-ce!24690
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/starrers_controller_spec.rb110
-rw-r--r--spec/features/groups/members/search_members_spec.rb4
-rw-r--r--spec/features/groups/members/sort_members_spec.rb18
-rw-r--r--spec/features/projects/members/groups_with_access_list_spec.rb8
-rw-r--r--spec/features/projects/members/sorting_spec.rb18
-rw-r--r--spec/finders/starred_projects_finder_spec.rb41
-rw-r--r--spec/finders/users_star_projects_finder_spec.rb42
-rw-r--r--spec/helpers/users_helper_spec.rb2
-rw-r--r--spec/requests/api/projects_spec.rb101
9 files changed, 319 insertions, 25 deletions
diff --git a/spec/controllers/projects/starrers_controller_spec.rb b/spec/controllers/projects/starrers_controller_spec.rb
new file mode 100644
index 00000000000..59d258e99ce
--- /dev/null
+++ b/spec/controllers/projects/starrers_controller_spec.rb
@@ -0,0 +1,110 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Projects::StarrersController do
+ let(:user) { create(:user) }
+ let(:private_user) { create(:user, private_profile: true) }
+ let(:admin) { create(:user, admin: true) }
+ let(:project) { create(:project, :public, :repository) }
+
+ before do
+ user.toggle_star(project)
+ private_user.toggle_star(project)
+ end
+
+ describe 'GET index' do
+ def get_starrers
+ get :index,
+ params: {
+ namespace_id: project.namespace,
+ project_id: project
+ }
+ end
+
+ context 'when project is public' do
+ before do
+ project.update_attribute(:visibility_level, Project::PUBLIC)
+ end
+
+ context 'when no user is logged in' do
+ before do
+ get_starrers
+ end
+
+ it 'only public starrers are visible' do
+ user_ids = assigns[:starrers].map { |s| s['user_id'] }
+ expect(user_ids).to include(user.id)
+ expect(user_ids).not_to include(private_user.id)
+ end
+
+ it 'public/private starrers counts are correct' do
+ expect(assigns[:public_count]).to eq(1)
+ expect(assigns[:private_count]).to eq(1)
+ end
+ end
+
+ context 'when private user is logged in' do
+ before do
+ sign_in(private_user)
+
+ get_starrers
+ end
+
+ it 'their star is also visible' do
+ user_ids = assigns[:starrers].map { |s| s['user_id'] }
+ expect(user_ids).to include(user.id, private_user.id)
+ end
+
+ it 'public/private starrers counts are correct' do
+ expect(assigns[:public_count]).to eq(1)
+ expect(assigns[:private_count]).to eq(1)
+ end
+ end
+
+ context 'when admin is logged in' do
+ before do
+ sign_in(admin)
+
+ get_starrers
+ end
+
+ it 'all stars are visible' do
+ user_ids = assigns[:starrers].map { |s| s['user_id'] }
+ expect(user_ids).to include(user.id, private_user.id)
+ end
+
+ it 'public/private starrers counts are correct' do
+ expect(assigns[:public_count]).to eq(1)
+ expect(assigns[:private_count]).to eq(1)
+ end
+ end
+ end
+
+ context 'when project is private' do
+ before do
+ project.update(visibility_level: Project::PRIVATE)
+ end
+
+ it 'starrers are not visible for non logged in users' do
+ get_starrers
+
+ expect(assigns[:starrers]).to be_blank
+ end
+
+ context 'when user is logged in' do
+ before do
+ sign_in(project.creator)
+ end
+
+ it 'only public starrers are visible' do
+ get_starrers
+
+ user_ids = assigns[:starrers].map { |s| s['user_id'] }
+ expect(user_ids).to include(user.id)
+ expect(user_ids).not_to include(private_user.id)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/features/groups/members/search_members_spec.rb b/spec/features/groups/members/search_members_spec.rb
index d2d084c9174..9c17aac09e8 100644
--- a/spec/features/groups/members/search_members_spec.rb
+++ b/spec/features/groups/members/search_members_spec.rb
@@ -19,9 +19,9 @@ describe 'Search group member' do
end
it 'renders member users' do
- page.within '.member-search-form' do
+ page.within '.user-search-form' do
fill_in 'search', with: member.name
- find('.member-search-btn').click
+ find('.user-search-btn').click
end
group_members_list = find(".card .content-list")
diff --git a/spec/features/groups/members/sort_members_spec.rb b/spec/features/groups/members/sort_members_spec.rb
index 11770e6ac2a..48b0136227e 100644
--- a/spec/features/groups/members/sort_members_spec.rb
+++ b/spec/features/groups/members/sort_members_spec.rb
@@ -19,7 +19,7 @@ describe 'Groups > Members > Sort members' do
expect(first_member).to include(owner.name)
expect(second_member).to include(developer.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Name, ascending')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Name, ascending')
end
it 'sorts by access level ascending' do
@@ -27,7 +27,7 @@ describe 'Groups > Members > Sort members' do
expect(first_member).to include(developer.name)
expect(second_member).to include(owner.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Access level, ascending')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Access level, ascending')
end
it 'sorts by access level descending' do
@@ -35,7 +35,7 @@ describe 'Groups > Members > Sort members' do
expect(first_member).to include(owner.name)
expect(second_member).to include(developer.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Access level, descending')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Access level, descending')
end
it 'sorts by last joined' do
@@ -43,7 +43,7 @@ describe 'Groups > Members > Sort members' do
expect(first_member).to include(developer.name)
expect(second_member).to include(owner.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Last joined')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Last joined')
end
it 'sorts by oldest joined' do
@@ -51,7 +51,7 @@ describe 'Groups > Members > Sort members' do
expect(first_member).to include(owner.name)
expect(second_member).to include(developer.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Oldest joined')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Oldest joined')
end
it 'sorts by name ascending' do
@@ -59,7 +59,7 @@ describe 'Groups > Members > Sort members' do
expect(first_member).to include(owner.name)
expect(second_member).to include(developer.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Name, ascending')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Name, ascending')
end
it 'sorts by name descending' do
@@ -67,7 +67,7 @@ describe 'Groups > Members > Sort members' do
expect(first_member).to include(developer.name)
expect(second_member).to include(owner.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Name, descending')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Name, descending')
end
it 'sorts by recent sign in', :clean_gitlab_redis_shared_state do
@@ -75,7 +75,7 @@ describe 'Groups > Members > Sort members' do
expect(first_member).to include(owner.name)
expect(second_member).to include(developer.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Recent sign in')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Recent sign in')
end
it 'sorts by oldest sign in', :clean_gitlab_redis_shared_state do
@@ -83,7 +83,7 @@ describe 'Groups > Members > Sort members' do
expect(first_member).to include(developer.name)
expect(second_member).to include(owner.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Oldest sign in')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Oldest sign in')
end
def visit_members_list(sort:)
diff --git a/spec/features/projects/members/groups_with_access_list_spec.rb b/spec/features/projects/members/groups_with_access_list_spec.rb
index 7b1fded1834..6e8d1a945e1 100644
--- a/spec/features/projects/members/groups_with_access_list_spec.rb
+++ b/spec/features/projects/members/groups_with_access_list_spec.rb
@@ -52,18 +52,18 @@ describe 'Projects > Members > Groups with access list', :js do
context 'search in existing members (yes, this filters the groups list as well)' do
it 'finds no results' do
- page.within '.member-search-form' do
+ page.within '.user-search-form' do
fill_in 'search', with: 'testing 123'
- find('.member-search-btn').click
+ find('.user-search-btn').click
end
expect(page).not_to have_selector('.group_member')
end
it 'finds results' do
- page.within '.member-search-form' do
+ page.within '.user-search-form' do
fill_in 'search', with: group.name
- find('.member-search-btn').click
+ find('.user-search-btn').click
end
expect(page).to have_selector('.group_member', count: 1)
diff --git a/spec/features/projects/members/sorting_spec.rb b/spec/features/projects/members/sorting_spec.rb
index 332f07614da..88240fbbedc 100644
--- a/spec/features/projects/members/sorting_spec.rb
+++ b/spec/features/projects/members/sorting_spec.rb
@@ -18,7 +18,7 @@ describe 'Projects > Members > Sorting' do
expect(first_member).to include(maintainer.name)
expect(second_member).to include(developer.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Name, ascending')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Name, ascending')
end
it 'sorts by access level ascending' do
@@ -26,7 +26,7 @@ describe 'Projects > Members > Sorting' do
expect(first_member).to include(developer.name)
expect(second_member).to include(maintainer.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Access level, ascending')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Access level, ascending')
end
it 'sorts by access level descending' do
@@ -34,7 +34,7 @@ describe 'Projects > Members > Sorting' do
expect(first_member).to include(maintainer.name)
expect(second_member).to include(developer.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Access level, descending')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Access level, descending')
end
it 'sorts by last joined' do
@@ -42,7 +42,7 @@ describe 'Projects > Members > Sorting' do
expect(first_member).to include(maintainer.name)
expect(second_member).to include(developer.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Last joined')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Last joined')
end
it 'sorts by oldest joined' do
@@ -50,7 +50,7 @@ describe 'Projects > Members > Sorting' do
expect(first_member).to include(developer.name)
expect(second_member).to include(maintainer.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Oldest joined')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Oldest joined')
end
it 'sorts by name ascending' do
@@ -58,7 +58,7 @@ describe 'Projects > Members > Sorting' do
expect(first_member).to include(maintainer.name)
expect(second_member).to include(developer.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Name, ascending')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Name, ascending')
end
it 'sorts by name descending' do
@@ -66,7 +66,7 @@ describe 'Projects > Members > Sorting' do
expect(first_member).to include(developer.name)
expect(second_member).to include(maintainer.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Name, descending')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Name, descending')
end
it 'sorts by recent sign in', :clean_gitlab_redis_shared_state do
@@ -74,7 +74,7 @@ describe 'Projects > Members > Sorting' do
expect(first_member).to include(maintainer.name)
expect(second_member).to include(developer.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Recent sign in')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Recent sign in')
end
it 'sorts by oldest sign in', :clean_gitlab_redis_shared_state do
@@ -82,7 +82,7 @@ describe 'Projects > Members > Sorting' do
expect(first_member).to include(developer.name)
expect(second_member).to include(maintainer.name)
- expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Oldest sign in')
+ expect(page).to have_css('.user-sort-dropdown .dropdown-toggle-text', text: 'Oldest sign in')
end
def visit_members_list(sort:)
diff --git a/spec/finders/starred_projects_finder_spec.rb b/spec/finders/starred_projects_finder_spec.rb
new file mode 100644
index 00000000000..7aa8251c3ab
--- /dev/null
+++ b/spec/finders/starred_projects_finder_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe StarredProjectsFinder do
+ let(:project1) { create(:project, :public, :empty_repo) }
+ let(:project2) { create(:project, :public, :empty_repo) }
+ let(:other_project) { create(:project, :public, :empty_repo) }
+
+ let(:user) { create(:user) }
+ let(:other_user) { create(:user) }
+
+ before do
+ user.toggle_star(project1)
+ user.toggle_star(project2)
+ end
+
+ describe '#execute' do
+ let(:finder) { described_class.new(user, params: {}, current_user: current_user) }
+
+ subject { finder.execute }
+
+ describe 'as same user' do
+ let(:current_user) { user }
+
+ it { is_expected.to contain_exactly(project1, project2) }
+ end
+
+ describe 'as other user' do
+ let(:current_user) { other_user }
+
+ it { is_expected.to contain_exactly(project1, project2) }
+ end
+
+ describe 'as no user' do
+ let(:current_user) { nil }
+
+ it { is_expected.to contain_exactly(project1, project2) }
+ end
+ end
+end
diff --git a/spec/finders/users_star_projects_finder_spec.rb b/spec/finders/users_star_projects_finder_spec.rb
new file mode 100644
index 00000000000..fb1d8088f44
--- /dev/null
+++ b/spec/finders/users_star_projects_finder_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe UsersStarProjectsFinder do
+ let(:project) { create(:project, :public, :empty_repo) }
+
+ let(:user) { create(:user) }
+ let(:private_user) { create(:user, private_profile: true) }
+ let(:other_user) { create(:user) }
+
+ before do
+ user.toggle_star(project)
+ private_user.toggle_star(project)
+ end
+
+ describe '#execute' do
+ let(:finder) { described_class.new(project, {}, current_user: current_user) }
+ let(:public_stars) { user.users_star_projects }
+ let(:private_stars) { private_user.users_star_projects }
+
+ subject { finder.execute }
+
+ describe 'as same user' do
+ let(:current_user) { private_user }
+
+ it { is_expected.to match_array(private_stars + public_stars) }
+ end
+
+ describe 'as other user' do
+ let(:current_user) { other_user }
+
+ it { is_expected.to match_array(public_stars) }
+ end
+
+ describe 'as no user' do
+ let(:current_user) { nil }
+
+ it { is_expected.to match_array(public_stars) }
+ end
+ end
+end
diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb
index f3649495493..a6623bc7941 100644
--- a/spec/helpers/users_helper_spec.rb
+++ b/spec/helpers/users_helper_spec.rb
@@ -27,7 +27,7 @@ describe UsersHelper do
context 'with public profile' do
it 'includes all the expected tabs' do
- expect(tabs).to include(:activity, :groups, :contributed, :projects, :snippets)
+ expect(tabs).to include(:activity, :groups, :contributed, :projects, :starred, :snippets)
end
end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 5b3a2412aff..1d7ca85cdd2 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -838,6 +838,28 @@ describe API::Projects do
end
end
+ describe 'GET /users/:user_id/starred_projects/' do
+ before do
+ user3.update(starred_projects: [project, project2, project3])
+ end
+
+ it 'returns error when user not found' do
+ get api('/users/9999/starred_projects/')
+
+ expect(response).to have_gitlab_http_status(404)
+ expect(json_response['message']).to eq('404 User Not Found')
+ end
+
+ it 'returns projects filtered by user' do
+ get api("/users/#{user3.id}/starred_projects/", user)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(json_response.map { |project| project['id'] }).to contain_exactly(project.id, project2.id, project3.id)
+ end
+ end
+
describe 'POST /projects/user/:id' do
it 'creates new project without path but with name and return 201' do
expect { post api("/projects/user/#{user.id}", admin), params: { name: 'Foo Project' } }.to change { Project.count }.by(1)
@@ -2148,6 +2170,85 @@ describe API::Projects do
end
end
+ describe 'GET /projects/:id/starrers' do
+ shared_examples_for 'project starrers response' do
+ it 'returns an array of starrers' do
+ get api("/projects/#{public_project.id}/starrers", current_user)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(json_response[0]['starred_since']).to be_present
+ expect(json_response[0]['user']).to be_present
+ end
+
+ it 'returns the proper security headers' do
+ get api('/projects/1/starrers', current_user)
+
+ expect(response).to include_security_headers
+ end
+ end
+
+ let(:public_project) { create(:project, :public) }
+ let(:private_user) { create(:user, private_profile: true) }
+
+ before do
+ user.update(starred_projects: [public_project])
+ private_user.update(starred_projects: [public_project])
+ end
+
+ it 'returns not_found(404) for not existing project' do
+ get api("/projects/9999999999/starrers", user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
+ context 'public project without user' do
+ it_behaves_like 'project starrers response' do
+ let(:current_user) { nil }
+ end
+
+ it 'returns only starrers with a public profile' do
+ get api("/projects/#{public_project.id}/starrers", nil)
+
+ user_ids = json_response.map { |s| s['user']['id'] }
+ expect(user_ids).to include(user.id)
+ expect(user_ids).not_to include(private_user.id)
+ end
+ end
+
+ context 'public project with user with private profile' do
+ it_behaves_like 'project starrers response' do
+ let(:current_user) { private_user }
+ end
+
+ it 'returns current user with a private profile' do
+ get api("/projects/#{public_project.id}/starrers", private_user)
+
+ user_ids = json_response.map { |s| s['user']['id'] }
+ expect(user_ids).to include(user.id, private_user.id)
+ end
+ end
+
+ context 'private project' do
+ context 'with unauthorized user' do
+ it 'returns not_found for existing but unauthorized project' do
+ get api("/projects/#{project3.id}/starrers", user3)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'without user' do
+ it 'returns not_found for existing but unauthorized project' do
+ get api("/projects/#{project3.id}/starrers", nil)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+ end
+
describe 'GET /projects/:id/languages' do
context 'with an authorized user' do
it_behaves_like 'languages and percentages JSON response' do