Commit b5f1e4e4 authored by Robert Speicher's avatar Robert Speicher

Merge branch 'rc/improve-projects-factory-ee' into 'master'

[EE] Improve the Project factory to make `creator` defaults to `namespace.owner`

See merge request !2651
parents 16fedb4d d8e86194
require 'spec_helper'
describe AutocompleteController do
let(:project) { create(:project) }
let(:user) { project.owner }
context 'GET users' do
let!(:user2) { create(:user) }
let!(:non_member) { create(:user) }
context 'project members' do
before do
project.add_developer(user2)
sign_in(user)
end
describe "GET #users that can push to protected branches" do
before do
get(:users, project_id: project.id, push_code_to_protected_branches: 'true')
end
it 'returns authorized users' do
expect(json_response).to be_kind_of(Array)
expect(json_response.size).to eq(1)
expect(json_response.map { |u| u["username"] }).to match_array([user.username])
end
end
describe "GET #users that can push code" do
let(:reporter_user) { create(:user) }
before do
project.add_reporter(reporter_user)
get(:users, project_id: project.id, push_code: 'true')
end
it 'returns authorized users' do
expect(json_response).to be_kind_of(Array)
expect(json_response.size).to eq(2)
expect(json_response.map { |user| user["username"] }).to match_array([user.username, user2.username])
end
end
describe "GET #users that can push to protected branches, including the current user" do
before do
get(:users, project_id: project.id, push_code_to_protected_branches: true, current_user: true)
end
it 'returns authorized users' do
expect(json_response).to be_kind_of(Array)
expect(json_response.size).to eq(1)
expect(json_response.map { |u| u["username"] }).to match_array([user.username])
end
end
end
end
context "groups" do
let(:matching_group) { create(:group) }
let(:non_matching_group) { create(:group) }
let(:user2) { create(:user) }
before do
project.invited_groups << matching_group
end
context "while fetching all groups belonging to a project" do
before do
sign_in(user)
get(:project_groups, project_id: project.id)
end
it 'returns a single group' do
expect(json_response).to be_kind_of(Array)
expect(json_response.size).to eq(1)
expect(json_response.first.values_at('id', 'name')).to eq [matching_group.id, matching_group.name]
end
end
context "while fetching all groups belonging to a project the current user cannot access" do
before do
sign_in(user2)
get(:project_groups, project_id: project.id)
end
it { expect(response).to be_not_found }
end
context "while fetching all groups belonging to an invalid project ID" do
before do
sign_in(user)
get(:project_groups, project_id: 'invalid')
end
it { expect(response).to be_not_found }
end
end
end
......@@ -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
......@@ -81,30 +116,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')
......@@ -171,44 +204,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
......
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) }
......
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
......
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
......
......@@ -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) }
......
......@@ -2,8 +2,8 @@ require 'spec_helper'
describe AdminEmailsWorker do
context "recipients" do
let(:group) { create :group }
let(:project) { create :project }
let(:group) { create(:group) }
let(:project) { create(:project) }
before do
2.times do
......@@ -26,8 +26,9 @@ describe AdminEmailsWorker do
it "sends email to subscribed users" do
perform_enqueued_jobs do
described_class.new.perform(recipient_id, 'subject', 'body')
expect(ActionMailer::Base.deliveries.count).to be 2
subject.perform(recipient_id, 'subject', 'body')
expect(ActionMailer::Base.deliveries.count).to eq(2)
end
end
end
......@@ -37,8 +38,9 @@ describe AdminEmailsWorker do
it "sends email to subscribed users" do
perform_enqueued_jobs do
described_class.new.perform(recipient_id, 'subject', 'body')
expect(ActionMailer::Base.deliveries.count).to be 3
subject.perform(recipient_id, 'subject', 'body')
expect(ActionMailer::Base.deliveries.count).to eq(3)
end
end
end
......@@ -48,8 +50,9 @@ describe AdminEmailsWorker do
it "sends email to subscribed users" do
perform_enqueued_jobs do
described_class.new.perform(recipient_id, 'subject', 'body')
expect(ActionMailer::Base.deliveries.count).to be 4
subject.perform(recipient_id, 'subject', 'body')
expect(ActionMailer::Base.deliveries.count).to eq(3)
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment