require 'spec_helper' describe ProjectsHelper do include ProjectForksHelper describe "#project_status_css_class" do it "returns appropriate class" do expect(project_status_css_class("started")).to eq("table-active") expect(project_status_css_class("failed")).to eq("table-danger") expect(project_status_css_class("finished")).to eq("table-success") end end describe "can_change_visibility_level?" do let(:project) { create(:project) } let(:user) { create(:project_member, :reporter, user: create(:user), project: project).user } let(:forked_project) { fork_project(project, user) } it "returns false if there are no appropriate permissions" do allow(helper).to receive(:can?) { false } expect(helper.can_change_visibility_level?(project, user)).to be_falsey end it "returns true if there are permissions and it is not fork" do allow(helper).to receive(:can?) { true } expect(helper.can_change_visibility_level?(project, user)).to be_truthy end it 'allows visibility level to be changed if the project is forked' do allow(helper).to receive(:can?).with(user, :change_visibility_level, project) { true } project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) fork_project(project) expect(helper.can_change_visibility_level?(project, user)).to be_truthy end context "forks" do it "returns false if there are permissions and origin project is PRIVATE" do allow(helper).to receive(:can?) { true } project.update(visibility_level: Gitlab::VisibilityLevel::PRIVATE) expect(helper.can_change_visibility_level?(forked_project, user)).to be_falsey end it "returns true if there are permissions and origin project is INTERNAL" do allow(helper).to receive(:can?) { true } project.update(visibility_level: Gitlab::VisibilityLevel::INTERNAL) expect(helper.can_change_visibility_level?(forked_project, user)).to be_truthy end end end describe "readme_cache_key" do let(:project) { create(:project, :repository) } before do helper.instance_variable_set(:@project, project) end it "returns a valid cach key" do expect(helper.send(:readme_cache_key)).to eq("#{project.full_path}-#{project.commit.id}-readme") end it "returns a valid cache key if HEAD does not exist" do allow(project).to receive(:commit) { nil } expect(helper.send(:readme_cache_key)).to eq("#{project.full_path}-nil-readme") end end describe "#project_list_cache_key", :clean_gitlab_redis_shared_state do let(:project) { create(:project, :repository) } let(:user) { create(:user) } before do allow(helper).to receive(:current_user).and_return(user) allow(helper).to receive(:can?).with(user, :read_cross_project) { true } allow(user).to receive(:max_member_access_for_project).and_return(40) end it "includes the route" do expect(helper.project_list_cache_key(project)).to include(project.route.cache_key) end it "includes the project" do expect(helper.project_list_cache_key(project)).to include(project.cache_key) end it "includes the last activity date" do expect(helper.project_list_cache_key(project)).to include(project.last_activity_date) end it "includes the controller name" do expect(helper.controller).to receive(:controller_name).and_return("testcontroller") expect(helper.project_list_cache_key(project)).to include("testcontroller") end it "includes the controller action" do expect(helper.controller).to receive(:action_name).and_return("testaction") expect(helper.project_list_cache_key(project)).to include("testaction") end it "includes the application settings" do settings = Gitlab::CurrentSettings.current_application_settings expect(helper.project_list_cache_key(project)).to include(settings.cache_key) end it "includes a version" do expect(helper.project_list_cache_key(project).last).to start_with('v') end it 'includes wether or not the user can read cross project' do expect(helper.project_list_cache_key(project)).to include('cross-project:true') end it "includes the pipeline status when there is a status" do create(:ci_pipeline, :success, project: project, sha: project.commit.sha) expect(helper.project_list_cache_key(project)).to include("pipeline-status/#{project.commit.sha}-success") end it "includes the user max member access" do expect(helper.project_list_cache_key(project)).to include('access:40') end end describe '#load_pipeline_status' do it 'loads the pipeline status in batch' do project = build(:project) helper.load_pipeline_status([project]) # Skip lazy loading of the `pipeline_status` attribute pipeline_status = project.instance_variable_get('@pipeline_status') expect(pipeline_status).to be_a(Gitlab::Cache::Ci::ProjectPipelineStatus) end end describe '#show_no_ssh_key_message?' do let(:user) { create(:user) } before do allow(helper).to receive(:current_user).and_return(user) end context 'user has no keys' do it 'returns true' do expect(helper.show_no_ssh_key_message?).to be_truthy end end context 'user has an ssh key' do it 'returns false' do create(:personal_key, user: user) expect(helper.show_no_ssh_key_message?).to be_falsey end end end describe '#show_no_password_message?' do let(:user) { create(:user) } before do allow(helper).to receive(:current_user).and_return(user) end context 'user has password set' do it 'returns false' do expect(helper.show_no_password_message?).to be_falsey end end context 'user has hidden the message' do it 'returns false' do allow(helper).to receive(:cookies).and_return(hide_no_password_message: true) expect(helper.show_no_password_message?).to be_falsey end end context 'user requires a password for Git' do it 'returns true' do allow(user).to receive(:require_password_creation_for_git?).and_return(true) expect(helper.show_no_password_message?).to be_truthy end end context 'user requires a personal access token for Git' do it 'returns true' do allow(user).to receive(:require_password_creation_for_git?).and_return(false) allow(user).to receive(:require_personal_access_token_creation_for_git_auth?).and_return(true) expect(helper.show_no_password_message?).to be_truthy end end end describe '#link_to_set_password' do let(:user) { create(:user, password_automatically_set: true) } before do allow(helper).to receive(:current_user).and_return(user) end context 'password authentication is enabled for Git' do it 'returns link to set a password' do stub_application_setting(password_authentication_enabled_for_git?: true) expect(helper.link_to_set_password).to match %r{set a password} end end context 'password authentication is disabled for Git' do it 'returns link to create a personal access token' do stub_application_setting(password_authentication_enabled_for_git?: false) expect(helper.link_to_set_password).to match %r{create a personal access token} end end end describe '#link_to_member_avatar' do let(:user) { build_stubbed(:user) } let(:expected) { double } before do expect(helper).to receive(:avatar_icon_for_user).with(user, 16).and_return(expected) end it 'returns image tag for member avatar' do expect(helper).to receive(:image_tag).with(expected, { width: 16, class: ["avatar", "avatar-inline", "s16"], alt: "", "data-src" => anything }) helper.link_to_member_avatar(user) end it 'returns image tag with avatar class' do expect(helper).to receive(:image_tag).with(expected, { width: 16, class: ["avatar", "avatar-inline", "s16", "any-avatar-class"], alt: "", "data-src" => anything }) helper.link_to_member_avatar(user, avatar_class: "any-avatar-class") end end describe '#link_to_member' do let(:group) { build_stubbed(:group) } let(:project) { build_stubbed(:project, group: group) } let(:user) { build_stubbed(:user, name: '