2019-12-26 22:10:19 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2018-03-27 19:54:05 +05:30
|
|
|
require 'spec_helper'
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
RSpec.describe ProjectPresenter do
|
2018-03-27 19:54:05 +05:30
|
|
|
let(:user) { create(:user) }
|
2020-03-13 15:44:24 +05:30
|
|
|
let(:project) { create(:project) }
|
|
|
|
let(:presenter) { described_class.new(project, current_user: user) }
|
2018-03-27 19:54:05 +05:30
|
|
|
|
|
|
|
describe '#license_short_name' do
|
|
|
|
context 'when project.repository has a license_key' do
|
|
|
|
it 'returns the nickname of the license if present' do
|
|
|
|
allow(project.repository).to receive(:license_key).and_return('agpl-3.0')
|
|
|
|
|
|
|
|
expect(presenter.license_short_name).to eq('GNU AGPLv3')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns the name of the license if nickname is not present' do
|
|
|
|
allow(project.repository).to receive(:license_key).and_return('mit')
|
|
|
|
|
|
|
|
expect(presenter.license_short_name).to eq('MIT License')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when project.repository has no license_key but a license_blob' do
|
|
|
|
it 'returns LICENSE' do
|
|
|
|
allow(project.repository).to receive(:license_key).and_return(nil)
|
|
|
|
|
|
|
|
expect(presenter.license_short_name).to eq('LICENSE')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#default_view' do
|
|
|
|
context 'user not signed in' do
|
2020-03-13 15:44:24 +05:30
|
|
|
let_it_be(:user) { nil }
|
2018-03-27 19:54:05 +05:30
|
|
|
|
|
|
|
context 'when repository is empty' do
|
2020-03-13 15:44:24 +05:30
|
|
|
let_it_be(:project) { create(:project_empty_repo, :public) }
|
2018-03-27 19:54:05 +05:30
|
|
|
|
2021-01-03 14:25:43 +05:30
|
|
|
it 'returns wiki if user has repository access and can read wiki, which exists' do
|
|
|
|
allow(project).to receive(:wiki_repository_exists?).and_return(true)
|
2018-03-27 19:54:05 +05:30
|
|
|
allow(presenter).to receive(:can?).with(nil, :download_code, project).and_return(true)
|
2021-01-03 14:25:43 +05:30
|
|
|
allow(presenter).to receive(:can?).with(nil, :read_wiki, project).and_return(true)
|
|
|
|
allow(presenter).to receive(:can?).with(nil, :read_issue, project).and_return(false)
|
|
|
|
|
|
|
|
expect(presenter.default_view).to eq('wiki')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns activity if user has repository access and can read wiki, which does not exist' do
|
|
|
|
allow(presenter).to receive(:can?).with(nil, :download_code, project).and_return(true)
|
|
|
|
allow(presenter).to receive(:can?).with(nil, :read_wiki, project).and_return(true)
|
|
|
|
allow(presenter).to receive(:can?).with(nil, :read_issue, project).and_return(false)
|
2018-03-27 19:54:05 +05:30
|
|
|
|
|
|
|
expect(presenter.default_view).to eq('activity')
|
|
|
|
end
|
|
|
|
|
2021-01-03 14:25:43 +05:30
|
|
|
it 'returns issues if user does not have repository access, but can read issues' do
|
|
|
|
allow(presenter).to receive(:can?).with(nil, :download_code, project).and_return(false)
|
|
|
|
allow(presenter).to receive(:can?).with(nil, :read_issue, project).and_call_original
|
|
|
|
|
|
|
|
expect(presenter.default_view).to eq('projects/issues/issues')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns activity if user can read neither wiki nor issues' do
|
|
|
|
allow(presenter).to receive(:can?).with(nil, :download_code, project).and_return(false)
|
|
|
|
allow(presenter).to receive(:can?).with(nil, :read_issue, project).and_return(false)
|
2018-03-27 19:54:05 +05:30
|
|
|
|
|
|
|
expect(presenter.default_view).to eq('activity')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when repository is not empty' do
|
2020-03-13 15:44:24 +05:30
|
|
|
let_it_be(:project) { create(:project, :public, :repository) }
|
2021-06-08 01:23:25 +05:30
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
let(:release) { create(:release, project: project, author: user) }
|
2018-03-27 19:54:05 +05:30
|
|
|
|
|
|
|
it 'returns files and readme if user has repository access' do
|
|
|
|
allow(presenter).to receive(:can?).with(nil, :download_code, project).and_return(true)
|
|
|
|
|
|
|
|
expect(presenter.default_view).to eq('files')
|
|
|
|
end
|
|
|
|
|
2021-01-03 14:25:43 +05:30
|
|
|
it 'returns wiki if user does not have repository access and can read wiki, which exists' do
|
|
|
|
allow(project).to receive(:wiki_repository_exists?).and_return(true)
|
2018-03-27 19:54:05 +05:30
|
|
|
allow(presenter).to receive(:can?).with(nil, :download_code, project).and_return(false)
|
2021-01-03 14:25:43 +05:30
|
|
|
allow(presenter).to receive(:can?).with(nil, :read_wiki, project).and_return(true)
|
|
|
|
|
|
|
|
expect(presenter.default_view).to eq('wiki')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns activity if user does not have repository or wiki access' do
|
|
|
|
allow(presenter).to receive(:can?).with(nil, :download_code, project).and_return(false)
|
|
|
|
allow(presenter).to receive(:can?).with(nil, :read_issue, project).and_return(false)
|
|
|
|
allow(presenter).to receive(:can?).with(nil, :read_wiki, project).and_return(false)
|
2018-03-27 19:54:05 +05:30
|
|
|
|
|
|
|
expect(presenter.default_view).to eq('activity')
|
|
|
|
end
|
2020-03-13 15:44:24 +05:30
|
|
|
|
|
|
|
it 'returns releases anchor' do
|
|
|
|
expect(release).to be_truthy
|
|
|
|
expect(presenter.releases_anchor_data).to have_attributes(
|
|
|
|
is_link: true,
|
|
|
|
label: a_string_including("#{project.releases.count}"),
|
|
|
|
link: presenter.project_releases_path(project)
|
|
|
|
)
|
|
|
|
end
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'user signed in' do
|
|
|
|
let(:user) { create(:user, :readme) }
|
|
|
|
let(:project) { create(:project, :public, :repository) }
|
|
|
|
|
|
|
|
context 'when the user is allowed to see the code' do
|
|
|
|
it 'returns the project view' do
|
|
|
|
allow(presenter).to receive(:can?).with(user, :download_code, project).and_return(true)
|
|
|
|
|
|
|
|
expect(presenter.default_view).to eq('readme')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with wikis enabled and the right policy for the user' do
|
|
|
|
before do
|
|
|
|
project.project_feature.update_attribute(:issues_access_level, 0)
|
|
|
|
allow(presenter).to receive(:can?).with(user, :download_code, project).and_return(false)
|
|
|
|
end
|
|
|
|
|
2021-01-03 14:25:43 +05:30
|
|
|
it 'returns wiki if the user has the right policy and the wiki exists' do
|
|
|
|
allow(project).to receive(:wiki_repository_exists?).and_return(true)
|
2018-03-27 19:54:05 +05:30
|
|
|
allow(presenter).to receive(:can?).with(user, :read_wiki, project).and_return(true)
|
|
|
|
|
|
|
|
expect(presenter.default_view).to eq('wiki')
|
|
|
|
end
|
|
|
|
|
2021-01-03 14:25:43 +05:30
|
|
|
it 'returns activity if the user does not have the right policy' do
|
2018-03-27 19:54:05 +05:30
|
|
|
allow(presenter).to receive(:can?).with(user, :read_wiki, project).and_return(false)
|
2021-01-03 14:25:43 +05:30
|
|
|
allow(presenter).to receive(:can?).with(user, :read_issue, project).and_return(false)
|
2018-03-27 19:54:05 +05:30
|
|
|
|
2021-01-03 14:25:43 +05:30
|
|
|
expect(presenter.default_view).to eq('activity')
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with issues as a feature available' do
|
|
|
|
it 'return issues' do
|
|
|
|
allow(presenter).to receive(:can?).with(user, :download_code, project).and_return(false)
|
2021-01-03 14:25:43 +05:30
|
|
|
allow(presenter).to receive(:can?).with(user, :read_issue, project).and_return(true)
|
2018-03-27 19:54:05 +05:30
|
|
|
allow(presenter).to receive(:can?).with(user, :read_wiki, project).and_return(false)
|
|
|
|
|
|
|
|
expect(presenter.default_view).to eq('projects/issues/issues')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with no activity, no wikies and no issues' do
|
2021-01-03 14:25:43 +05:30
|
|
|
it 'returns activity as default' do
|
2018-03-27 19:54:05 +05:30
|
|
|
project.project_feature.update_attribute(:issues_access_level, 0)
|
|
|
|
allow(presenter).to receive(:can?).with(user, :download_code, project).and_return(false)
|
|
|
|
allow(presenter).to receive(:can?).with(user, :read_wiki, project).and_return(false)
|
2021-01-03 14:25:43 +05:30
|
|
|
allow(presenter).to receive(:can?).with(user, :read_issue, project).and_return(false)
|
2018-03-27 19:54:05 +05:30
|
|
|
|
2021-01-03 14:25:43 +05:30
|
|
|
expect(presenter.default_view).to eq('activity')
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#can_current_user_push_code?' do
|
|
|
|
context 'empty repo' do
|
2020-03-13 15:44:24 +05:30
|
|
|
let_it_be(:project) { create(:project) }
|
2018-03-27 19:54:05 +05:30
|
|
|
|
|
|
|
it 'returns true if user can push_code' do
|
|
|
|
project.add_developer(user)
|
|
|
|
|
|
|
|
expect(presenter.can_current_user_push_code?).to be(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns false if user cannot push_code' do
|
|
|
|
project.add_reporter(user)
|
|
|
|
|
|
|
|
expect(presenter.can_current_user_push_code?).to be(false)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'not empty repo' do
|
|
|
|
let(:project) { create(:project, :repository) }
|
|
|
|
|
2021-04-17 20:07:23 +05:30
|
|
|
context 'if no current user' do
|
|
|
|
let(:user) { nil }
|
|
|
|
|
|
|
|
it 'returns false' do
|
|
|
|
expect(presenter.can_current_user_push_code?).to be(false)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-03-27 19:54:05 +05:30
|
|
|
it 'returns true if user can push to default branch' do
|
|
|
|
project.add_developer(user)
|
|
|
|
|
|
|
|
expect(presenter.can_current_user_push_code?).to be(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns false if default branch is protected' do
|
|
|
|
project.add_developer(user)
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2018-03-27 19:54:05 +05:30
|
|
|
create(:protected_branch, project: project, name: project.default_branch)
|
|
|
|
|
|
|
|
expect(presenter.can_current_user_push_code?).to be(false)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-11-20 20:47:30 +05:30
|
|
|
context 'statistics anchors (empty repo)' do
|
2020-03-13 15:44:24 +05:30
|
|
|
let_it_be(:project) { create(:project, :empty_repo) }
|
2018-11-20 20:47:30 +05:30
|
|
|
|
|
|
|
describe '#files_anchor_data' do
|
|
|
|
it 'returns files data' do
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.files_anchor_data).to have_attributes(
|
|
|
|
is_link: true,
|
|
|
|
label: a_string_including('0 Bytes'),
|
|
|
|
link: nil
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-04-22 19:07:51 +05:30
|
|
|
describe '#storage_anchor_data' do
|
|
|
|
it 'returns storage data' do
|
|
|
|
expect(presenter.storage_anchor_data).to have_attributes(
|
|
|
|
is_link: true,
|
|
|
|
label: a_string_including('0 Bytes'),
|
|
|
|
link: nil
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
describe '#releases_anchor_data' do
|
|
|
|
it 'does not return release count' do
|
|
|
|
expect(presenter.releases_anchor_data).to be_nil
|
2018-11-20 20:47:30 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#commits_anchor_data' do
|
|
|
|
it 'returns commits data' do
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.commits_anchor_data).to have_attributes(
|
|
|
|
is_link: true,
|
|
|
|
label: a_string_including('0'),
|
|
|
|
link: nil
|
|
|
|
)
|
2018-11-20 20:47:30 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#branches_anchor_data' do
|
|
|
|
it 'returns branches data' do
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.branches_anchor_data).to have_attributes(
|
|
|
|
is_link: true,
|
|
|
|
label: a_string_including('0'),
|
|
|
|
link: nil
|
|
|
|
)
|
2018-11-20 20:47:30 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#tags_anchor_data' do
|
|
|
|
it 'returns tags data' do
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.tags_anchor_data).to have_attributes(
|
|
|
|
is_link: true,
|
|
|
|
label: a_string_including('0'),
|
|
|
|
link: nil
|
|
|
|
)
|
2018-11-20 20:47:30 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-03-27 19:54:05 +05:30
|
|
|
context 'statistics anchors' do
|
2020-03-13 15:44:24 +05:30
|
|
|
let_it_be(:user) { create(:user) }
|
|
|
|
let_it_be(:project) { create(:project, :repository) }
|
|
|
|
let_it_be(:release) { create(:release, project: project, author: user) }
|
2021-06-08 01:23:25 +05:30
|
|
|
|
2018-03-27 19:54:05 +05:30
|
|
|
let(:presenter) { described_class.new(project, current_user: user) }
|
|
|
|
|
|
|
|
describe '#files_anchor_data' do
|
|
|
|
it 'returns files data' do
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.files_anchor_data).to have_attributes(
|
|
|
|
is_link: true,
|
|
|
|
label: a_string_including('0 Bytes'),
|
|
|
|
link: presenter.project_tree_path(project)
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-04-22 19:07:51 +05:30
|
|
|
describe '#storage_anchor_data' do
|
|
|
|
it 'returns storage data' do
|
|
|
|
expect(presenter.storage_anchor_data).to have_attributes(
|
|
|
|
is_link: true,
|
|
|
|
label: a_string_including('0 Bytes'),
|
|
|
|
link: presenter.project_tree_path(project)
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
describe '#releases_anchor_data' do
|
|
|
|
it 'returns release count if user can read release' do
|
|
|
|
project.add_maintainer(user)
|
|
|
|
|
|
|
|
expect(release).to be_truthy
|
|
|
|
expect(presenter.releases_anchor_data).to have_attributes(
|
|
|
|
is_link: true,
|
|
|
|
label: a_string_including("#{project.releases.count}"),
|
|
|
|
link: presenter.project_releases_path(project)
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns nil if user cannot read release' do
|
|
|
|
expect(release).to be_truthy
|
|
|
|
expect(presenter.releases_anchor_data).to be_nil
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'user not signed in' do
|
|
|
|
let_it_be(:user) { nil }
|
|
|
|
|
|
|
|
it 'returns nil if user is signed out' do
|
|
|
|
expect(release).to be_truthy
|
|
|
|
expect(presenter.releases_anchor_data).to be_nil
|
|
|
|
end
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#commits_anchor_data' do
|
|
|
|
it 'returns commits data' do
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.commits_anchor_data).to have_attributes(
|
|
|
|
is_link: true,
|
|
|
|
label: a_string_including('0'),
|
|
|
|
link: presenter.project_commits_path(project, project.repository.root_ref)
|
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#branches_anchor_data' do
|
|
|
|
it 'returns branches data' do
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.branches_anchor_data).to have_attributes(
|
|
|
|
is_link: true,
|
|
|
|
label: a_string_including("#{project.repository.branches.size}"),
|
|
|
|
link: presenter.project_branches_path(project)
|
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#tags_anchor_data' do
|
|
|
|
it 'returns tags data' do
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.tags_anchor_data).to have_attributes(
|
|
|
|
is_link: true,
|
|
|
|
label: a_string_including("#{project.repository.tags.size}"),
|
|
|
|
link: presenter.project_tags_path(project)
|
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#new_file_anchor_data' do
|
|
|
|
it 'returns new file data if user can push' do
|
|
|
|
project.add_developer(user)
|
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.new_file_anchor_data).to have_attributes(
|
|
|
|
is_link: false,
|
|
|
|
label: a_string_including("New file"),
|
|
|
|
link: presenter.project_new_blob_path(project, 'master'),
|
2021-04-17 20:07:23 +05:30
|
|
|
class_modifier: 'btn-dashed'
|
2020-03-13 15:44:24 +05:30
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns nil if user cannot push' do
|
|
|
|
expect(presenter.new_file_anchor_data).to be_nil
|
|
|
|
end
|
2018-05-09 12:01:36 +05:30
|
|
|
|
|
|
|
context 'when the project is empty' do
|
2020-03-13 15:44:24 +05:30
|
|
|
let_it_be(:project) { create(:project, :empty_repo) }
|
2018-05-09 12:01:36 +05:30
|
|
|
|
|
|
|
# Since we protect the default branch for empty repos
|
|
|
|
it 'is empty for a developer' do
|
|
|
|
project.add_developer(user)
|
|
|
|
|
|
|
|
expect(presenter.new_file_anchor_data).to be_nil
|
|
|
|
end
|
|
|
|
end
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
describe '#readme_anchor_data' do
|
|
|
|
context 'when user can push and README does not exists' do
|
|
|
|
it 'returns anchor data' do
|
|
|
|
project.add_developer(user)
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2021-02-22 17:27:13 +05:30
|
|
|
allow(project.repository).to receive(:readme_path).and_return(nil)
|
2018-03-27 19:54:05 +05:30
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.readme_anchor_data).to have_attributes(
|
|
|
|
is_link: false,
|
|
|
|
label: a_string_including('Add README'),
|
|
|
|
link: presenter.add_readme_path
|
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when README exists' do
|
|
|
|
it 'returns anchor data' do
|
2021-02-22 17:27:13 +05:30
|
|
|
allow(project.repository).to receive(:readme_path).and_return('readme')
|
2018-03-27 19:54:05 +05:30
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.readme_anchor_data).to have_attributes(
|
|
|
|
is_link: false,
|
|
|
|
label: a_string_including('README'),
|
|
|
|
link: presenter.readme_path
|
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#changelog_anchor_data' do
|
2019-02-15 15:39:39 +05:30
|
|
|
context 'when user can push and CHANGELOG does not exist' do
|
2018-03-27 19:54:05 +05:30
|
|
|
it 'returns anchor data' do
|
|
|
|
project.add_developer(user)
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2018-03-27 19:54:05 +05:30
|
|
|
allow(project.repository).to receive(:changelog).and_return(nil)
|
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.changelog_anchor_data).to have_attributes(
|
|
|
|
is_link: false,
|
|
|
|
label: a_string_including('Add CHANGELOG'),
|
|
|
|
link: presenter.add_changelog_path
|
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when CHANGELOG exists' do
|
|
|
|
it 'returns anchor data' do
|
|
|
|
allow(project.repository).to receive(:changelog).and_return(double(name: 'foo'))
|
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.changelog_anchor_data).to have_attributes(
|
|
|
|
is_link: false,
|
|
|
|
label: a_string_including('CHANGELOG'),
|
|
|
|
link: presenter.changelog_path
|
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#license_anchor_data' do
|
2019-02-15 15:39:39 +05:30
|
|
|
context 'when user can push and LICENSE does not exist' do
|
2018-03-27 19:54:05 +05:30
|
|
|
it 'returns anchor data' do
|
|
|
|
project.add_developer(user)
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2018-03-27 19:54:05 +05:30
|
|
|
allow(project.repository).to receive(:license_blob).and_return(nil)
|
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.license_anchor_data).to have_attributes(
|
|
|
|
is_link: false,
|
|
|
|
label: a_string_including('Add LICENSE'),
|
|
|
|
link: presenter.add_license_path
|
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when LICENSE exists' do
|
|
|
|
it 'returns anchor data' do
|
|
|
|
allow(project.repository).to receive(:license_blob).and_return(double(name: 'foo'))
|
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.license_anchor_data).to have_attributes(
|
|
|
|
is_link: false,
|
|
|
|
label: a_string_including(presenter.license_short_name),
|
|
|
|
link: presenter.license_path
|
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#contribution_guide_anchor_data' do
|
2019-02-15 15:39:39 +05:30
|
|
|
context 'when user can push and CONTRIBUTING does not exist' do
|
2018-03-27 19:54:05 +05:30
|
|
|
it 'returns anchor data' do
|
|
|
|
project.add_developer(user)
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2018-03-27 19:54:05 +05:30
|
|
|
allow(project.repository).to receive(:contribution_guide).and_return(nil)
|
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.contribution_guide_anchor_data).to have_attributes(
|
|
|
|
is_link: false,
|
|
|
|
label: a_string_including('Add CONTRIBUTING'),
|
|
|
|
link: presenter.add_contribution_guide_path
|
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when CONTRIBUTING exists' do
|
|
|
|
it 'returns anchor data' do
|
|
|
|
allow(project.repository).to receive(:contribution_guide).and_return(double(name: 'foo'))
|
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.contribution_guide_anchor_data).to have_attributes(
|
|
|
|
is_link: false,
|
|
|
|
label: a_string_including('CONTRIBUTING'),
|
|
|
|
link: presenter.contribution_guide_path
|
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#autodevops_anchor_data' do
|
|
|
|
context 'when Auto Devops is enabled' do
|
|
|
|
it 'returns anchor data' do
|
|
|
|
allow(project).to receive(:auto_devops_enabled?).and_return(true)
|
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.autodevops_anchor_data).to have_attributes(
|
|
|
|
is_link: false,
|
|
|
|
label: a_string_including('Auto DevOps enabled'),
|
|
|
|
link: nil
|
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-02-15 15:39:39 +05:30
|
|
|
context 'when user can admin pipeline and CI yml does not exist' do
|
2018-03-27 19:54:05 +05:30
|
|
|
it 'returns anchor data' do
|
2018-11-18 11:00:15 +05:30
|
|
|
project.add_maintainer(user)
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2018-03-27 19:54:05 +05:30
|
|
|
allow(project).to receive(:auto_devops_enabled?).and_return(false)
|
|
|
|
allow(project.repository).to receive(:gitlab_ci_yml).and_return(nil)
|
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.autodevops_anchor_data).to have_attributes(
|
|
|
|
is_link: false,
|
|
|
|
label: a_string_including('Enable Auto DevOps'),
|
|
|
|
link: presenter.project_settings_ci_cd_path(project, anchor: 'autodevops-settings')
|
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#kubernetes_cluster_anchor_data' do
|
|
|
|
context 'when user can create Kubernetes cluster' do
|
|
|
|
it 'returns link to cluster if only one exists' do
|
2018-11-18 11:00:15 +05:30
|
|
|
project.add_maintainer(user)
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2018-03-27 19:54:05 +05:30
|
|
|
cluster = create(:cluster, projects: [project])
|
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.kubernetes_cluster_anchor_data).to have_attributes(
|
|
|
|
is_link: false,
|
|
|
|
label: a_string_including('Kubernetes'),
|
|
|
|
link: presenter.project_cluster_path(project, cluster)
|
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns link to clusters page if more than one exists' do
|
2018-11-18 11:00:15 +05:30
|
|
|
project.add_maintainer(user)
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2018-05-01 15:08:00 +05:30
|
|
|
create(:cluster, :production_environment, projects: [project])
|
2018-03-27 19:54:05 +05:30
|
|
|
create(:cluster, projects: [project])
|
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.kubernetes_cluster_anchor_data).to have_attributes(
|
|
|
|
is_link: false,
|
|
|
|
label: a_string_including('Kubernetes'),
|
|
|
|
link: presenter.project_clusters_path(project)
|
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns link to create a cluster if no cluster exists' do
|
2018-11-18 11:00:15 +05:30
|
|
|
project.add_maintainer(user)
|
2018-03-27 19:54:05 +05:30
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(presenter.kubernetes_cluster_anchor_data).to have_attributes(
|
|
|
|
is_link: false,
|
|
|
|
label: a_string_including('Add Kubernetes cluster'),
|
|
|
|
link: presenter.new_project_cluster_path(project)
|
|
|
|
)
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when user cannot create Kubernetes cluster' do
|
|
|
|
it 'returns nil' do
|
|
|
|
expect(presenter.kubernetes_cluster_anchor_data).to be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2021-04-17 20:07:23 +05:30
|
|
|
|
|
|
|
describe '#upload_anchor_data' do
|
|
|
|
context 'with empty_repo_upload enabled' do
|
|
|
|
before do
|
|
|
|
stub_experiments(empty_repo_upload: :candidate)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'user can push to branch' do
|
|
|
|
before do
|
|
|
|
project.add_developer(user)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns upload_anchor_data' do
|
|
|
|
expect(presenter.upload_anchor_data).to have_attributes(
|
|
|
|
is_link: false,
|
|
|
|
label: a_string_including('Upload file'),
|
|
|
|
data: {
|
|
|
|
"can_push_code" => "true",
|
|
|
|
"original_branch" => "master",
|
|
|
|
"path" => "/#{project.full_path}/-/create/master",
|
2021-09-04 01:27:46 +05:30
|
|
|
"project_path" => project.full_path,
|
2021-04-17 20:07:23 +05:30
|
|
|
"target_branch" => "master"
|
|
|
|
}
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'user cannot push to branch' do
|
|
|
|
it 'returns nil' do
|
|
|
|
expect(presenter.upload_anchor_data).to be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with empty_repo_upload disabled' do
|
|
|
|
before do
|
|
|
|
stub_experiments(empty_repo_upload: :control)
|
|
|
|
project.add_developer(user)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns nil' do
|
|
|
|
expect(presenter.upload_anchor_data).to be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|
2019-07-31 22:56:46 +05:30
|
|
|
|
|
|
|
describe '#statistics_buttons' do
|
2020-10-24 23:57:45 +05:30
|
|
|
let(:project) { build_stubbed(:project) }
|
2019-07-31 22:56:46 +05:30
|
|
|
|
|
|
|
it 'orders the items correctly' do
|
2021-02-22 17:27:13 +05:30
|
|
|
allow(project.repository).to receive(:readme_path).and_return('readme')
|
2019-12-26 22:10:19 +05:30
|
|
|
allow(project.repository).to receive(:license_blob).and_return(nil)
|
2019-07-31 22:56:46 +05:30
|
|
|
allow(project.repository).to receive(:changelog).and_return(nil)
|
|
|
|
allow(project.repository).to receive(:contribution_guide).and_return(double(name: 'foo'))
|
|
|
|
allow(presenter).to receive(:filename_path).and_return('fake/path')
|
|
|
|
allow(presenter).to receive(:contribution_guide_path).and_return('fake_path')
|
|
|
|
|
|
|
|
buttons = presenter.statistics_buttons(show_auto_devops_callout: false)
|
|
|
|
expect(buttons.map(&:label)).to start_with(
|
|
|
|
a_string_including('README'),
|
|
|
|
a_string_including('CONTRIBUTING')
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
2019-12-21 20:55:43 +05:30
|
|
|
|
2019-12-26 22:10:19 +05:30
|
|
|
describe '#repo_statistics_buttons' do
|
2019-12-21 20:55:43 +05:30
|
|
|
subject(:empty_repo_statistics_buttons) { presenter.empty_repo_statistics_buttons }
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(project).to receive(:auto_devops_enabled?).and_return(false)
|
|
|
|
end
|
|
|
|
|
2019-12-26 22:10:19 +05:30
|
|
|
context 'empty repo' do
|
|
|
|
let(:project) { create(:project, :stubbed_repository)}
|
|
|
|
|
|
|
|
context 'for a guest user' do
|
|
|
|
it 'orders the items correctly' do
|
|
|
|
expect(empty_repo_statistics_buttons.map(&:label)).to start_with(
|
|
|
|
a_string_including('No license')
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-04-17 20:07:23 +05:30
|
|
|
describe 'experiment(:repo_integrations_link)' do
|
|
|
|
context 'when enabled' do
|
|
|
|
before do
|
|
|
|
stub_experiments(repo_integrations_link: :candidate)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'includes a button to configure integrations for maintainers' do
|
|
|
|
project.add_maintainer(user)
|
|
|
|
|
|
|
|
expect(empty_repo_statistics_buttons.map(&:label)).to include(
|
|
|
|
a_string_including('Configure Integration')
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not include a button if not a maintainer' do
|
|
|
|
expect(empty_repo_statistics_buttons.map(&:label)).not_to include(
|
|
|
|
a_string_including('Configure Integration')
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when disabled' do
|
|
|
|
it 'does not include a button' do
|
|
|
|
project.add_maintainer(user)
|
|
|
|
|
|
|
|
expect(empty_repo_statistics_buttons.map(&:label)).not_to include(
|
|
|
|
a_string_including('Configure Integration')
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-12-26 22:10:19 +05:30
|
|
|
context 'for a developer' do
|
|
|
|
before do
|
|
|
|
project.add_developer(user)
|
2021-04-17 20:07:23 +05:30
|
|
|
stub_experiments(empty_repo_upload: :candidate)
|
2019-12-26 22:10:19 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it 'orders the items correctly' do
|
|
|
|
expect(empty_repo_statistics_buttons.map(&:label)).to start_with(
|
2021-04-17 20:07:23 +05:30
|
|
|
a_string_including('Upload'),
|
2019-12-26 22:10:19 +05:30
|
|
|
a_string_including('New'),
|
|
|
|
a_string_including('README'),
|
|
|
|
a_string_including('LICENSE'),
|
|
|
|
a_string_including('CHANGELOG'),
|
|
|
|
a_string_including('CONTRIBUTING'),
|
|
|
|
a_string_including('CI/CD')
|
|
|
|
)
|
|
|
|
end
|
2021-04-17 20:07:23 +05:30
|
|
|
|
|
|
|
context 'when not in the upload experiment' do
|
|
|
|
before do
|
|
|
|
stub_experiments(empty_repo_upload: :control)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not include upload button' do
|
|
|
|
expect(empty_repo_statistics_buttons.map(&:label)).not_to start_with(a_string_including('Upload'))
|
|
|
|
end
|
|
|
|
end
|
2019-12-26 22:10:19 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'initialized repo' do
|
2020-03-13 15:44:24 +05:30
|
|
|
let_it_be(:project) { create(:project, :repository) }
|
2019-12-26 22:10:19 +05:30
|
|
|
|
|
|
|
it 'orders the items correctly' do
|
|
|
|
expect(empty_repo_statistics_buttons.map(&:label)).to start_with(
|
|
|
|
a_string_including('README'),
|
|
|
|
a_string_including('License'),
|
|
|
|
a_string_including('CHANGELOG'),
|
|
|
|
a_string_including('CONTRIBUTING')
|
|
|
|
)
|
|
|
|
end
|
2019-12-21 20:55:43 +05:30
|
|
|
end
|
|
|
|
end
|
2020-03-13 15:44:24 +05:30
|
|
|
|
|
|
|
describe '#can_setup_review_app?' do
|
|
|
|
subject { presenter.can_setup_review_app? }
|
|
|
|
|
|
|
|
context 'when the ci/cd file is missing' do
|
|
|
|
before do
|
|
|
|
allow(presenter).to receive(:cicd_missing?).and_return(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
it { is_expected.to be_truthy }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the ci/cd file is not missing' do
|
|
|
|
before do
|
|
|
|
allow(presenter).to receive(:cicd_missing?).and_return(false)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'and the user can create a cluster' do
|
|
|
|
before do
|
|
|
|
allow(Ability).to receive(:allowed?).and_call_original
|
|
|
|
allow(Ability).to receive(:allowed?).with(user, :create_cluster, project).and_return(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'and there is no cluster associated to this project' do
|
|
|
|
let(:project) { create(:project, clusters: []) }
|
|
|
|
|
|
|
|
it { is_expected.to be_truthy }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'and there is already a cluster associated to this project' do
|
|
|
|
let(:project) { create(:project, clusters: [build(:cluster, :providing_by_gcp)]) }
|
|
|
|
|
|
|
|
it { is_expected.to be_falsey }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when a group cluster is instantiated' do
|
|
|
|
let_it_be(:cluster) { create(:cluster, :group) }
|
|
|
|
let_it_be(:group) { cluster.group }
|
|
|
|
|
|
|
|
context 'and the project belongs to this group' do
|
|
|
|
let!(:project) { create(:project, group: group) }
|
|
|
|
|
|
|
|
it { is_expected.to be_falsey }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'and the project does not belong to this group' do
|
|
|
|
it { is_expected.to be_truthy }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'and there is already an instance cluster' do
|
|
|
|
it 'is false' do
|
|
|
|
create(:cluster, :instance)
|
|
|
|
|
|
|
|
is_expected.to be_falsey
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'and the user cannot create a cluster' do
|
|
|
|
before do
|
|
|
|
allow(Ability).to receive(:allowed?).and_call_original
|
|
|
|
allow(Ability).to receive(:allowed?).with(user, :create_cluster, project).and_return(false)
|
|
|
|
end
|
|
|
|
|
|
|
|
it { is_expected.to be_falsey }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2021-04-17 20:07:23 +05:30
|
|
|
|
2021-06-08 01:23:25 +05:30
|
|
|
describe '#add_code_quality_ci_yml_path' do
|
|
|
|
subject { presenter.add_code_quality_ci_yml_path }
|
|
|
|
|
|
|
|
it { is_expected.to match(/code_quality_walkthrough=true.*template=Code-Quality/) }
|
|
|
|
end
|
|
|
|
|
2021-04-17 20:07:23 +05:30
|
|
|
describe 'empty_repo_upload_experiment?' do
|
|
|
|
subject { presenter.empty_repo_upload_experiment? }
|
|
|
|
|
|
|
|
it 'returns false when upload_anchor_data is nil' do
|
|
|
|
allow(presenter).to receive(:upload_anchor_data).and_return(nil)
|
|
|
|
|
|
|
|
expect(subject).to be false
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns true when upload_anchor_data exists' do
|
|
|
|
allow(presenter).to receive(:upload_anchor_data).and_return(true)
|
|
|
|
|
|
|
|
expect(subject).to be true
|
|
|
|
end
|
|
|
|
end
|
2018-03-27 19:54:05 +05:30
|
|
|
end
|