diff options
-rw-r--r-- | spec/controllers/autocomplete_controller_spec.rb | 133 | ||||
-rw-r--r-- | spec/factories/projects.rb | 99 | ||||
-rw-r--r-- | spec/factories/users.rb | 2 | ||||
-rw-r--r-- | spec/lib/gitlab/template/issue_template_spec.rb | 44 | ||||
-rw-r--r-- | spec/lib/gitlab/template/merge_request_template_spec.rb | 44 | ||||
-rw-r--r-- | spec/requests/api/projects_spec.rb | 4 |
6 files changed, 130 insertions, 196 deletions
diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb index 3c396e36b24..379e3ce690f 100644 --- a/spec/controllers/autocomplete_controller_spec.rb +++ b/spec/controllers/autocomplete_controller_spec.rb @@ -1,8 +1,8 @@ require 'spec_helper' describe AutocompleteController do - let!(:project) { create(:project) } - let!(:user) { create(:user) } + let(:project) { create(:project) } + let(:user) { project.owner } context 'GET users' do let!(:user2) { create(:user) } @@ -11,7 +11,6 @@ describe AutocompleteController do context 'project members' do before do sign_in(user) - project.add_master(user) end describe 'GET #users with project ID' do @@ -19,11 +18,11 @@ describe AutocompleteController do get(:users, project_id: project.id) end - let(:body) { JSON.parse(response.body) } - - it { expect(body).to be_kind_of(Array) } - it { expect(body.size).to eq 2 } - it { expect(body.map { |u| u["username"] }).to include(user.username) } + it 'returns the project members' do + expect(json_response).to be_kind_of(Array) + expect(json_response.size).to eq(1) + expect(json_response.map { |u| u["username"] }).to include(user.username) + end end describe 'GET #users with unknown project' do @@ -39,20 +38,20 @@ describe AutocompleteController do let(:group) { create(:group) } before do - sign_in(user) group.add_owner(user) + sign_in(user) end - let(:body) { JSON.parse(response.body) } - describe 'GET #users with group ID' do before do get(:users, group_id: group.id) end - it { expect(body).to be_kind_of(Array) } - it { expect(body.size).to eq 1 } - it { expect(body.first["username"]).to eq user.username } + it 'returns the group members' do + expect(json_response).to be_kind_of(Array) + expect(json_response.size).to eq(1) + expect(json_response.first["username"]).to eq user.username + end end describe 'GET #users with unknown group ID' do @@ -65,23 +64,22 @@ describe AutocompleteController do end context 'non-member login for public project' do - let!(:project) { create(:project, :public) } + let(:project) { create(:project, :public) } before do sign_in(non_member) - project.add_master(user) end - let(:body) { JSON.parse(response.body) } - describe 'GET #users with project ID' do before do get(:users, project_id: project.id, current_user: true) end - it { expect(body).to be_kind_of(Array) } - it { expect(body.size).to eq 3 } - it { expect(body.map { |u| u['username'] }).to include(user.username, non_member.username) } + it 'returns the project members and non-members' do + expect(json_response).to be_kind_of(Array) + expect(json_response.size).to eq(2) + expect(json_response.map { |u| u['username'] }).to include(user.username, non_member.username) + end end end @@ -91,10 +89,8 @@ describe AutocompleteController do get(:users) end - let(:body) { JSON.parse(response.body) } - - it { expect(body).to be_kind_of(Array) } - it { expect(body.size).to eq User.count } + it { expect(json_response).to be_kind_of(Array) } + it { expect(json_response.size).to eq User.count } end context 'user order' do @@ -106,7 +102,7 @@ describe AutocompleteController do sign_in(user) get(:users, search: 'user') - response_usernames = JSON.parse(response.body).map { |user| user['username'] } + response_usernames = json_response.map { |user| user['username'] } expect(response_usernames.take(3)).to match_array([user.username, reported_user.username, user1.username]) end @@ -120,15 +116,12 @@ describe AutocompleteController do get(:users, per_page: per_page) end - let(:body) { JSON.parse(response.body) } - - it { expect(body).to be_kind_of(Array) } - it { expect(body.size).to eq per_page } + it { expect(json_response).to be_kind_of(Array) } + it { expect(json_response.size).to eq(per_page) } end context 'unauthenticated user' do let(:public_project) { create(:project, :public) } - let(:body) { JSON.parse(response.body) } describe 'GET #users with public project' do before do @@ -136,8 +129,8 @@ describe AutocompleteController do get(:users, project_id: public_project.id) end - it { expect(body).to be_kind_of(Array) } - it { expect(body.size).to eq 2 } + it { expect(json_response).to be_kind_of(Array) } + it { expect(json_response.size).to eq 2 } end describe 'GET #users with project' do @@ -170,8 +163,8 @@ describe AutocompleteController do get(:users) end - it { expect(body).to be_kind_of(Array) } - it { expect(body.size).to eq 0 } + it { expect(json_response).to be_kind_of(Array) } + it { expect(json_response).to be_empty } end describe 'GET #users with todo filter' do @@ -179,14 +172,12 @@ describe AutocompleteController do get :users, todo_filter: true expect(response.status).to eq 200 - expect(body).to be_kind_of(Array) + expect(json_response).to be_kind_of(Array) end end end context 'author of issuable included' do - let(:body) { JSON.parse(response.body) } - context 'authenticated' do before do sign_in(user) @@ -195,13 +186,13 @@ describe AutocompleteController do it 'includes the author' do get(:users, author_id: non_member.id) - expect(body.first["username"]).to eq non_member.username + expect(json_response.first["username"]).to eq non_member.username end it 'rejects non existent user ids' do get(:users, author_id: 99999) - expect(body.collect { |u| u['id'] }).not_to include(99999) + expect(json_response.collect { |u| u['id'] }).not_to include(99999) end end @@ -209,7 +200,7 @@ describe AutocompleteController do it 'returns empty result' do get(:users, author_id: non_member.id) - expect(body).to be_empty + expect(json_response).to be_empty end end end @@ -222,10 +213,9 @@ describe AutocompleteController do it 'skips the user IDs passed' do get(:users, skip_users: [user, user2].map(&:id)) - other_user_ids = [non_member, project.owner, project.creator].map(&:id) - response_user_ids = JSON.parse(response.body).map { |user| user['id'] } + response_user_ids = json_response.map { |user| user['id'] } - expect(response_user_ids).to contain_exactly(*other_user_ids) + expect(response_user_ids).to contain_exactly(non_member.id) end end end @@ -249,17 +239,15 @@ describe AutocompleteController do get(:projects, project_id: project.id) end - let(:body) { JSON.parse(response.body) } + it 'returns projects' do + expect(json_response).to be_kind_of(Array) + expect(json_response.size).to eq(2) - it do - expect(body).to be_kind_of(Array) - expect(body.size).to eq 2 + expect(json_response.first['id']).to eq(0) + expect(json_response.first['name_with_namespace']).to eq 'No project' - expect(body.first['id']).to eq 0 - expect(body.first['name_with_namespace']).to eq 'No project' - - expect(body.last['id']).to eq authorized_project.id - expect(body.last['name_with_namespace']).to eq authorized_project.name_with_namespace + expect(json_response.last['id']).to eq authorized_project.id + expect(json_response.last['name_with_namespace']).to eq authorized_project.name_with_namespace end end end @@ -275,14 +263,12 @@ describe AutocompleteController do get(:projects, project_id: project.id, search: 'rugged') end - let(:body) { JSON.parse(response.body) } - - it do - expect(body).to be_kind_of(Array) - expect(body.size).to eq 2 + it 'returns projects' do + expect(json_response).to be_kind_of(Array) + expect(json_response.size).to eq(2) - expect(body.last['id']).to eq authorized_search_project.id - expect(body.last['name_with_namespace']).to eq authorized_search_project.name_with_namespace + expect(json_response.last['id']).to eq authorized_search_project.id + expect(json_response.last['name_with_namespace']).to eq authorized_search_project.name_with_namespace end end end @@ -304,11 +290,9 @@ describe AutocompleteController do get(:projects, project_id: project.id) end - let(:body) { JSON.parse(response.body) } - - it do - expect(body).to be_kind_of(Array) - expect(body.size).to eq 3 # Of a total of 4 + it 'returns projects' do + expect(json_response).to be_kind_of(Array) + expect(json_response.size).to eq 3 # Of a total of 4 end end end @@ -328,11 +312,9 @@ describe AutocompleteController do get(:projects, project_id: project.id, offset_id: authorized_project.id) end - let(:body) { JSON.parse(response.body) } - - it do - expect(body.detect { |item| item['id'] == 0 }).to be_nil # 'No project' is not there - expect(body.detect { |item| item['id'] == authorized_project.id }).to be_nil # Offset project is not there either + it 'returns "No project"' do + expect(json_response.detect { |item| item['id'] == 0 }).to be_nil # 'No project' is not there + expect(json_response.detect { |item| item['id'] == authorized_project.id }).to be_nil # Offset project is not there either end end end @@ -349,13 +331,10 @@ describe AutocompleteController do get(:projects, project_id: project.id) end - let(:body) { JSON.parse(response.body) } - - it do - expect(body).to be_kind_of(Array) - expect(body.size).to eq 1 # 'No project' - - expect(body.first['id']).to eq 0 + it 'returns a single "No project"' do + expect(json_response).to be_kind_of(Array) + expect(json_response.size).to eq(1) # 'No project' + expect(json_response.first['id']).to eq 0 end end end diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 3f8e7030b1c..4a2034b31b3 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -8,12 +8,47 @@ FactoryGirl.define do factory :project, class: 'Project' do sequence(:name) { |n| "project#{n}" } path { name.downcase.gsub(/\s/, '_') } - namespace - creator - # Behaves differently to nil due to cache_has_external_issue_tracker has_external_issue_tracker false + # Associations + namespace + creator { group ? create(:user) : namespace&.owner } + + # Nest Project Feature attributes + transient do + wiki_access_level ProjectFeature::ENABLED + builds_access_level ProjectFeature::ENABLED + snippets_access_level ProjectFeature::ENABLED + issues_access_level ProjectFeature::ENABLED + merge_requests_access_level ProjectFeature::ENABLED + repository_access_level ProjectFeature::ENABLED + end + + after(:create) do |project, evaluator| + # Builds and MRs can't have higher visibility level than repository access level. + builds_access_level = [evaluator.builds_access_level, evaluator.repository_access_level].min + merge_requests_access_level = [evaluator.merge_requests_access_level, evaluator.repository_access_level].min + + project.project_feature.update_columns( + wiki_access_level: evaluator.wiki_access_level, + builds_access_level: builds_access_level, + snippets_access_level: evaluator.snippets_access_level, + issues_access_level: evaluator.issues_access_level, + merge_requests_access_level: merge_requests_access_level, + repository_access_level: evaluator.repository_access_level) + + # Normally the class Projects::CreateService is used for creating + # projects, and this class takes care of making sure the owner and current + # user have access to the project. Our specs don't use said service class, + # thus we must manually refresh things here. + unless project.group || project.pending_delete + project.add_master(project.owner) + end + + project.group&.refresh_members_authorized_projects + end + trait :public do visibility_level Gitlab::VisibilityLevel::PUBLIC end @@ -67,30 +102,28 @@ FactoryGirl.define do test_repo transient do - create_template nil + create_templates nil end after :create do |project, evaluator| - if evaluator.create_template - args = evaluator.create_template - - project.add_user(args[:user], args[:access]) + if evaluator.create_templates + templates_path = "#{evaluator.create_templates}_templates" project.repository.create_file( - args[:user], - ".gitlab/#{args[:path]}/bug.md", + project.creator, + ".gitlab/#{templates_path}/bug.md", 'something valid', message: 'test 3', branch_name: 'master') project.repository.create_file( - args[:user], - ".gitlab/#{args[:path]}/template_test.md", + project.creator, + ".gitlab/#{templates_path}/template_test.md", 'template_test', message: 'test 1', branch_name: 'master') project.repository.create_file( - args[:user], - ".gitlab/#{args[:path]}/feature_proposal.md", + project.creator, + ".gitlab/#{templates_path}/feature_proposal.md", 'feature_proposal', message: 'test 2', branch_name: 'master') @@ -142,44 +175,6 @@ FactoryGirl.define do trait(:repository_enabled) { repository_access_level ProjectFeature::ENABLED } trait(:repository_disabled) { repository_access_level ProjectFeature::DISABLED } trait(:repository_private) { repository_access_level ProjectFeature::PRIVATE } - - # Nest Project Feature attributes - transient do - wiki_access_level ProjectFeature::ENABLED - builds_access_level ProjectFeature::ENABLED - snippets_access_level ProjectFeature::ENABLED - issues_access_level ProjectFeature::ENABLED - merge_requests_access_level ProjectFeature::ENABLED - repository_access_level ProjectFeature::ENABLED - end - - after(:create) do |project, evaluator| - # Builds and MRs can't have higher visibility level than repository access level. - builds_access_level = [evaluator.builds_access_level, evaluator.repository_access_level].min - merge_requests_access_level = [evaluator.merge_requests_access_level, evaluator.repository_access_level].min - - project.project_feature - .update_attributes!( - wiki_access_level: evaluator.wiki_access_level, - builds_access_level: builds_access_level, - snippets_access_level: evaluator.snippets_access_level, - issues_access_level: evaluator.issues_access_level, - merge_requests_access_level: merge_requests_access_level, - repository_access_level: evaluator.repository_access_level - ) - - # Normally the class Projects::CreateService is used for creating - # projects, and this class takes care of making sure the owner and current - # user have access to the project. Our specs don't use said service class, - # thus we must manually refresh things here. - owner = project.owner - - if owner && owner.is_a?(User) && !project.pending_delete - project.members.create!(user: owner, access_level: Gitlab::Access::MASTER) - end - - project.group&.refresh_members_authorized_projects - end end # Project with empty repository diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 0486a413fb2..4000cd085b7 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -1,5 +1,5 @@ FactoryGirl.define do - factory :user, aliases: [:author, :assignee, :recipient, :owner, :creator, :resource_owner] do + factory :user, aliases: [:author, :assignee, :recipient, :owner, :resource_owner] do email { generate(:email) } name { generate(:name) } username { generate(:username) } diff --git a/spec/lib/gitlab/template/issue_template_spec.rb b/spec/lib/gitlab/template/issue_template_spec.rb index 6e0b1075a89..7098499f996 100644 --- a/spec/lib/gitlab/template/issue_template_spec.rb +++ b/spec/lib/gitlab/template/issue_template_spec.rb @@ -1,41 +1,28 @@ require 'spec_helper' describe Gitlab::Template::IssueTemplate do - subject { described_class } - - let(:user) { create(:user) } - - let(:project) do - create(:project, - :repository, - create_template: { - user: user, - access: Gitlab::Access::MASTER, - path: 'issue_templates' - }) - end + let(:project) { create(:project, :repository, create_templates: :issue) } describe '.all' do it 'strips the md suffix' do - expect(subject.all(project).first.name).not_to end_with('.issue_template') + expect(described_class.all(project).first.name).not_to end_with('.issue_template') end it 'combines the globals and rest' do - all = subject.all(project).map(&:name) + all = described_class.all(project).map(&:name) expect(all).to include('bug') expect(all).to include('feature_proposal') - expect(all).to include('template_test') end end describe '.find' do it 'returns nil if the file does not exist' do - expect { subject.find('mepmep-yadida', project) }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError) + expect { described_class.find('mepmep-yadida', project) }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError) end it 'returns the issue object of a valid file' do - ruby = subject.find('bug', project) + ruby = described_class.find('bug', project) expect(ruby).to be_a described_class expect(ruby.name).to eq('bug') @@ -44,21 +31,17 @@ describe Gitlab::Template::IssueTemplate do describe '.by_category' do it 'return array of templates' do - all = subject.by_category('', project).map(&:name) + all = described_class.by_category('', project).map(&:name) expect(all).to include('bug') expect(all).to include('feature_proposal') - expect(all).to include('template_test') end context 'when repo is bare or empty' do let(:empty_project) { create(:project) } - before do - empty_project.add_user(user, Gitlab::Access::MASTER) - end - it "returns empty array" do - templates = subject.by_category('', empty_project) + templates = described_class.by_category('', empty_project) + expect(templates).to be_empty end end @@ -66,26 +49,23 @@ describe Gitlab::Template::IssueTemplate do describe '#content' do it 'loads the full file' do - issue_template = subject.new('.gitlab/issue_templates/bug.md', project) + issue_template = described_class.new('.gitlab/issue_templates/bug.md', project) expect(issue_template.name).to eq 'bug' expect(issue_template.content).to eq('something valid') end it 'raises error when file is not found' do - issue_template = subject.new('.gitlab/issue_templates/bugnot.md', project) + issue_template = described_class.new('.gitlab/issue_templates/bugnot.md', project) expect { issue_template.content }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError) end context "when repo is empty" do let(:empty_project) { create(:project) } - before do - empty_project.add_user(user, Gitlab::Access::MASTER) - end - it "raises file not found" do - issue_template = subject.new('.gitlab/issue_templates/not_existent.md', empty_project) + issue_template = described_class.new('.gitlab/issue_templates/not_existent.md', empty_project) + expect { issue_template.content }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError) end end diff --git a/spec/lib/gitlab/template/merge_request_template_spec.rb b/spec/lib/gitlab/template/merge_request_template_spec.rb index b952274cd24..bd7ff64aa8a 100644 --- a/spec/lib/gitlab/template/merge_request_template_spec.rb +++ b/spec/lib/gitlab/template/merge_request_template_spec.rb @@ -1,41 +1,28 @@ require 'spec_helper' describe Gitlab::Template::MergeRequestTemplate do - subject { described_class } - - let(:user) { create(:user) } - - let(:project) do - create(:project, - :repository, - create_template: { - user: user, - access: Gitlab::Access::MASTER, - path: 'merge_request_templates' - }) - end + let(:project) { create(:project, :repository, create_templates: :merge_request) } describe '.all' do it 'strips the md suffix' do - expect(subject.all(project).first.name).not_to end_with('.issue_template') + expect(described_class.all(project).first.name).not_to end_with('.issue_template') end it 'combines the globals and rest' do - all = subject.all(project).map(&:name) + all = described_class.all(project).map(&:name) expect(all).to include('bug') expect(all).to include('feature_proposal') - expect(all).to include('template_test') end end describe '.find' do it 'returns nil if the file does not exist' do - expect { subject.find('mepmep-yadida', project) }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError) + expect { described_class.find('mepmep-yadida', project) }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError) end it 'returns the merge request object of a valid file' do - ruby = subject.find('bug', project) + ruby = described_class.find('bug', project) expect(ruby).to be_a described_class expect(ruby.name).to eq('bug') @@ -44,21 +31,17 @@ describe Gitlab::Template::MergeRequestTemplate do describe '.by_category' do it 'return array of templates' do - all = subject.by_category('', project).map(&:name) + all = described_class.by_category('', project).map(&:name) expect(all).to include('bug') expect(all).to include('feature_proposal') - expect(all).to include('template_test') end context 'when repo is bare or empty' do let(:empty_project) { create(:project) } - before do - empty_project.add_user(user, Gitlab::Access::MASTER) - end - it "returns empty array" do - templates = subject.by_category('', empty_project) + templates = described_class.by_category('', empty_project) + expect(templates).to be_empty end end @@ -66,26 +49,23 @@ describe Gitlab::Template::MergeRequestTemplate do describe '#content' do it 'loads the full file' do - issue_template = subject.new('.gitlab/merge_request_templates/bug.md', project) + issue_template = described_class.new('.gitlab/merge_request_templates/bug.md', project) expect(issue_template.name).to eq 'bug' expect(issue_template.content).to eq('something valid') end it 'raises error when file is not found' do - issue_template = subject.new('.gitlab/merge_request_templates/bugnot.md', project) + issue_template = described_class.new('.gitlab/merge_request_templates/bugnot.md', project) expect { issue_template.content }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError) end context "when repo is empty" do let(:empty_project) { create(:project) } - before do - empty_project.add_user(user, Gitlab::Access::MASTER) - end - it "raises file not found" do - issue_template = subject.new('.gitlab/merge_request_templates/not_existent.md', empty_project) + issue_template = described_class.new('.gitlab/merge_request_templates/not_existent.md', empty_project) + expect { issue_template.content }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError) end end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 9baac12821f..6cb27d16fe5 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -8,8 +8,8 @@ describe API::Projects do let(:user2) { create(:user) } let(:user3) { create(:user) } let(:admin) { create(:admin) } - let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) } - let(:project2) { create(:project, path: 'project2', creator_id: user.id, namespace: user.namespace) } + let(:project) { create(:project, namespace: user.namespace) } + let(:project2) { create(:project, path: 'project2', namespace: user.namespace) } let(:snippet) { create(:project_snippet, :public, author: user, project: project, title: 'example') } let(:project_member) { create(:project_member, :developer, user: user3, project: project) } let(:user4) { create(:user) } |