diff options
-rw-r--r-- | app/helpers/application_helper.rb | 2 | ||||
-rw-r--r-- | app/helpers/branches_helper.rb | 6 | ||||
-rw-r--r-- | app/helpers/preferences_helper.rb | 26 | ||||
-rw-r--r-- | app/helpers/projects_helper.rb | 307 | ||||
-rw-r--r-- | app/helpers/tree_helper.rb | 2 | ||||
-rw-r--r-- | app/models/project.rb | 7 | ||||
-rw-r--r-- | app/presenters/project_presenter.rb | 359 | ||||
-rw-r--r-- | app/views/projects/_readme.html.haml | 2 | ||||
-rw-r--r-- | app/views/projects/buttons/_koding.html.haml | 2 | ||||
-rw-r--r-- | app/views/projects/empty.html.haml | 5 | ||||
-rw-r--r-- | app/views/projects/show.html.haml | 8 | ||||
-rw-r--r-- | app/views/shared/issuable/_form.html.haml | 2 | ||||
-rw-r--r-- | spec/features/projects/show_project_spec.rb | 12 | ||||
-rw-r--r-- | spec/helpers/projects_helper_spec.rb | 26 | ||||
-rw-r--r-- | spec/presenters/project_presenter_spec.rb | 31 |
15 files changed, 416 insertions, 381 deletions
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 6530327698b..479797231cc 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -34,7 +34,7 @@ module ApplicationHelper def project_icon(project_id, options = {}) project = - if project_id.is_a?(Project) + if project_id.is_a?(Project) || project_id.is_a?(ProjectPresenter) project_id else Project.find_by_full_path(project_id) diff --git a/app/helpers/branches_helper.rb b/app/helpers/branches_helper.rb index 2641a98e29e..00b9a0e00eb 100644 --- a/app/helpers/branches_helper.rb +++ b/app/helpers/branches_helper.rb @@ -10,12 +10,6 @@ module BranchesHelper project_branches_path(@project, @id, options) end - def can_push_branch?(project, branch_name) - return false unless project.repository.branch_exists?(branch_name) - - ::Gitlab::UserAccess.new(current_user, project: project).can_push_to_branch?(branch_name) - end - def project_branches options_for_select(@project.repository.branch_names, @project.default_branch) end diff --git a/app/helpers/preferences_helper.rb b/app/helpers/preferences_helper.rb index aaee6eaeedd..373dfd457f7 100644 --- a/app/helpers/preferences_helper.rb +++ b/app/helpers/preferences_helper.rb @@ -48,30 +48,4 @@ module PreferencesHelper def user_color_scheme Gitlab::ColorSchemes.for_user(current_user).css_class end - - def default_project_view - return anonymous_project_view unless current_user - - user_view = current_user.project_view - - if can?(current_user, :download_code, @project) - user_view - elsif user_view == "activity" - "activity" - elsif can?(current_user, :read_wiki, @project) - "wiki" - elsif @project.feature_available?(:issues, current_user) - "projects/issues/issues" - else - "customize_workflow" - end - end - - def anonymous_project_view - if !@project.empty_repo? && can?(current_user, :download_code, @project) - 'files' - else - 'activity' - end - end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 0c64b8abec3..fa6811dccbf 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -153,11 +153,6 @@ module ProjectsHelper end end - def license_short_name(project) - license = project.repository.license - license&.nickname || license&.name || 'LICENSE' - end - def last_push_event current_user&.recent_push(@project) end @@ -386,55 +381,6 @@ module ProjectsHelper end end - def add_special_file_path(project, file_name:, commit_message: nil, branch_name: nil, context: nil) - commit_message ||= s_("CommitMessage|Add %{file_name}") % { file_name: file_name } - project_new_blob_path( - project, - project.default_branch || 'master', - file_name: file_name, - commit_message: commit_message, - branch_name: branch_name, - context: context - ) - end - - def add_koding_stack_path(project) - project_new_blob_path( - project, - project.default_branch || 'master', - file_name: '.koding.yml', - commit_message: "Add Koding stack script", - content: <<-CONTENT.strip_heredoc - provider: - aws: - access_key: '${var.aws_access_key}' - secret_key: '${var.aws_secret_key}' - resource: - aws_instance: - #{project.path}-vm: - instance_type: t2.nano - user_data: |- - - # Created by GitLab UI for :> - - echo _KD_NOTIFY_@Installing Base packages...@ - - apt-get update -y - apt-get install git -y - - echo _KD_NOTIFY_@Cloning #{project.name}...@ - - export KODING_USER=${var.koding_user_username} - export REPO_URL=#{root_url}${var.koding_queryString_repo}.git - export BRANCH=${var.koding_queryString_branch} - - sudo -i -u $KODING_USER git clone $REPO_URL -b $BRANCH - - echo _KD_NOTIFY_@#{project.name} cloned.@ - CONTENT - ) - end - def koding_project_url(project = nil, branch = nil, sha = nil) if project import_path = "/Home/Stacks/import" @@ -451,36 +397,6 @@ module ProjectsHelper Gitlab::CurrentSettings.koding_url end - def contribution_guide_path(project) - if project && contribution_guide = project.repository.contribution_guide - project_blob_path( - project, - tree_join(project.default_branch, - contribution_guide.name) - ) - end - end - - def readme_path(project) - filename_path(project, :readme) - end - - def changelog_path(project) - filename_path(project, :changelog) - end - - def license_path(project) - filename_path(project, :license_blob) - end - - def version_path(project) - filename_path(project, :version) - end - - def ci_configuration_path(project) - filename_path(project, :gitlab_ci_yml) - end - def project_wiki_path_with_version(proj, page, version, is_newest) url_params = is_newest ? {} : { version_id: version } project_wiki_path(proj, page, url_params) @@ -506,15 +422,6 @@ module ProjectsHelper @ref || @repository.try(:root_ref) end - def filename_path(project, filename) - if project && blob = project.repository.public_send(filename) # rubocop:disable GitlabSecurity/PublicSend - project_blob_path( - project, - tree_join(project.default_branch, blob.name) - ) - end - end - def sanitize_repo_path(project, message) return '' unless message.present? @@ -604,218 +511,4 @@ module ProjectsHelper project_find_file_path(@project, ref) end - - def can_current_user_push_code?(project) - project.empty_repo? ? can?(current_user, :push_code, project) : can_push_branch?(project, project.default_branch) - end - - def files_anchor_data(project) - { - enabled: true, - label: _('Files (%{human_size})') % { human_size: storage_counter(@project.statistics.total_repository_size) }, - link: project_tree_path(@project) - } - end - - def commits_anchor_data(project) - { - enabled: true, - label: n_('Commit (%{commit_count})', 'Commits (%{commit_count})', @project.statistics.commit_count) % { commit_count: number_with_delimiter(@project.statistics.commit_count) }, - link: project_commits_path(@project, current_ref) - } - end - - def branches_anchor_data(project) - { - enabled: true, - label: n_('Branch (%{branch_count})', 'Branches (%{branch_count})', @repository.branch_count) % { branch_count: number_with_delimiter(@repository.branch_count) }, - link: project_branches_path(@project) - } - end - - def tags_anchor_data(project) - { - enabled: true, - label: n_('Tag (%{tag_count})', 'Tags (%{tag_count})', @repository.tag_count) % { tag_count: number_with_delimiter(@repository.tag_count) }, - link: project_tags_path(@project) - } - end - - def new_file_anchor_data(project) - if current_user && can_current_user_push_code?(project) - { - enabled: false, - label: _('New file'), - link: project_new_blob_path(project, project.default_branch || 'master'), - class_modifier: 'new' - } - end - end - - def readme_anchor_data(project) - if current_user && can_current_user_push_code?(project) && project.repository.readme.blank? - { - enabled: false, - label: _('Add Readme'), - link: add_special_file_path(project, file_name: 'README.md') - } - elsif project.repository.readme.present? - { - enabled: true, - label: _('Readme'), - link: default_project_view != 'readme' ? readme_path(@project) : '#readme' - } - end - end - - def changelog_anchor_data(project) - if current_user && can_current_user_push_code?(project) && project.repository.changelog.blank? - { - enabled: false, - label: _('Add Changelog'), - link: add_special_file_path(project, file_name: 'CHANGELOG') - } - elsif project.repository.changelog.present? - { - enabled: true, - label: _('Changelog'), - link: changelog_path(project) - } - end - end - - def license_anchor_data(project) - if current_user && can_current_user_push_code?(project) && project.repository.license_blob.blank? - { - enabled: false, - label: _('Add License'), - link: add_special_file_path(project, file_name: 'LICENSE') - } - elsif project.repository.license_blob.present? - { - enabled: true, - label: license_short_name(project), - link: license_path(project) - } - end - end - - def contribution_guide_anchor_data(project) - if current_user && can_current_user_push_code?(project) && project.repository.contribution_guide.blank? - { - enabled: false, - label: _('Add Contribution guide'), - link: add_special_file_path(project, file_name: 'CONTRIBUTING.md', commit_message: 'Add contribution guide') - } - elsif project.repository.contribution_guide.present? - { - enabled: true, - label: _('Contribution guide'), - link: contribution_guide_path(@project) - } - end - end - - def autodevops_anchor_data(project, ignore_callout: false) - if current_user && can?(current_user, :admin_pipeline, project) && project.repository.gitlab_ci_yml.blank? && (ignore_callout || !show_auto_devops_callout?(project)) - { - enabled: project.auto_devops_enabled?, - label: project.auto_devops_enabled? ? _('Auto DevOps enabled') : _('Enable Auto DevOps'), - link: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings') - } - elsif project.auto_devops_enabled? - { - enabled: true, - label: _('Auto DevOps enabled'), - link: nil - } - end - end - - def kubernetes_cluster_anchor_data(project) - if current_user && can?(current_user, :create_cluster, project) - cluster_link = project.clusters.size == 1 ? project_cluster_path(project, project.clusters.first) : project_clusters_path(project) - - if project.clusters.empty? - cluster_link = new_project_cluster_path(project) - end - - { - enabled: !project.clusters.empty?, - label: project.clusters.empty? ? _('Add Kubernetes cluster') : n_('Kubernetes cluster', 'Kubernetes clusters', project.clusters.size), - link: cluster_link - } - end - end - - def gitlab_ci_anchor_data(project) - if current_user && can_current_user_push_code?(project) && project.repository.gitlab_ci_yml.blank? && !project.auto_devops_enabled? - { - enabled: false, - label: _('Set up CI/CD'), - link: add_special_file_path(project, file_name: '.gitlab-ci.yml') - } - elsif project.repository.gitlab_ci_yml.present? - { - enabled: true, - label: _('CI/CD configuration'), - link: ci_configuration_path(@project) - } - end - end - - def koding_anchor_data(project) - if current_user && can_current_user_push_code?(project) && koding_enabled? && project.repository.koding_yml.blank? - { - enabled: false, - label: _('Set up Koding'), - link: add_koding_stack_path(project) - } - end - end - - def empty_project_stat_anchor_items(project) - [ - autodevops_anchor_data(project, ignore_callout: true), - kubernetes_cluster_anchor_data(project) - ].compact.reject { |i| !i[:enabled] } - end - - def empty_project_stat_button_items(project) - [ - new_file_anchor_data(project), - readme_anchor_data(project), - license_anchor_data(project), - autodevops_anchor_data(project, ignore_callout: true), - kubernetes_cluster_anchor_data(project) - ].compact.reject { |i| i[:enabled] } - end - - def project_stat_anchor_items(project) - [ - files_anchor_data(project), - commits_anchor_data(project), - branches_anchor_data(project), - tags_anchor_data(project), - readme_anchor_data(project), - changelog_anchor_data(project), - license_anchor_data(project), - contribution_guide_anchor_data(project), - gitlab_ci_anchor_data(project), - autodevops_anchor_data(project), - kubernetes_cluster_anchor_data(project) - ].compact.reject { |i| !i[:enabled] } - end - - def project_stat_button_items(project) - [ - changelog_anchor_data(project), - license_anchor_data(project), - contribution_guide_anchor_data(project), - autodevops_anchor_data(project), - kubernetes_cluster_anchor_data(project), - gitlab_ci_anchor_data(project), - koding_anchor_data(project) - ].compact.reject { |i| i[:enabled] } - end end diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb index d39cac0f510..0a4da0ef3fc 100644 --- a/app/helpers/tree_helper.rb +++ b/app/helpers/tree_helper.rb @@ -55,7 +55,7 @@ module TreeHelper def tree_edit_branch(project = @project, ref = @ref) return unless can_edit_tree?(project, ref) - if can_push_branch?(project, ref) + if project.user_can_push_to_branch?(current_user, ref) ref else project = tree_edit_project(project) diff --git a/app/models/project.rb b/app/models/project.rb index 3893b1818f3..03640d7d18b 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -15,6 +15,7 @@ class Project < ActiveRecord::Base include ValidAttribute include ProjectFeaturesCompatibility include SelectForProjectAuthorization + include Presentable include Routable include GroupDescendant include Gitlab::SQL::Pattern @@ -1015,6 +1016,12 @@ class Project < ActiveRecord::Base !ProtectedBranch.default_branch_protected? || team.max_member_access(user.id) > Gitlab::Access::DEVELOPER end + def user_can_push_to_branch?(user, branch_name) + return false unless repository.branch_exists?(branch_name) + + ::Gitlab::UserAccess.new(user, project: self).can_push_to_branch?(branch_name) + end + def forked? return true if fork_network && fork_network.root_project != self diff --git a/app/presenters/project_presenter.rb b/app/presenters/project_presenter.rb new file mode 100644 index 00000000000..c76a529f56b --- /dev/null +++ b/app/presenters/project_presenter.rb @@ -0,0 +1,359 @@ +class ProjectPresenter < Gitlab::View::Presenter::Delegated + include ActionView::Helpers::NumberHelper + include ActionView::Helpers::UrlHelper + include GitlabRoutingHelper + include StorageHelper + include TreeHelper + + presents :project + + def project_stat_anchor_items(show_auto_devops_callout:) + [ + files_anchor_data, + commits_anchor_data, + branches_anchor_data, + tags_anchor_data, + readme_anchor_data, + changelog_anchor_data, + license_anchor_data, + contribution_guide_anchor_data, + gitlab_ci_anchor_data, + autodevops_anchor_data(show_auto_devops_callout: show_auto_devops_callout), + kubernetes_cluster_anchor_data + ].compact.reject { |i| !i[:enabled] } + end + + def project_stat_button_items(show_auto_devops_callout:) + [ + changelog_anchor_data, + license_anchor_data, + contribution_guide_anchor_data, + autodevops_anchor_data(show_auto_devops_callout: show_auto_devops_callout), + kubernetes_cluster_anchor_data, + gitlab_ci_anchor_data, + koding_anchor_data + ].compact.reject { |i| i[:enabled] } + end + + def empty_project_stat_anchor_items + [ + autodevops_anchor_data, + kubernetes_cluster_anchor_data + ].compact.reject { |i| !i[:enabled] } + end + + def empty_project_stat_button_items + [ + new_file_anchor_data, + readme_anchor_data, + license_anchor_data, + autodevops_anchor_data, + kubernetes_cluster_anchor_data + ].compact.reject { |i| i[:enabled] } + end + + def default_project_view + return anonymous_project_view unless current_user + + user_view = current_user.project_view + + if can?(current_user, :download_code, project) + user_view + elsif user_view == "activity" + "activity" + elsif can?(current_user, :read_wiki, project) + "wiki" + elsif feature_available?(:issues, current_user) + "projects/issues/issues" + else + "customize_workflow" + end + end + + def readme_path + filename_path(:readme) + end + + def changelog_path + filename_path(:changelog) + end + + def license_path + filename_path(:license_blob) + end + + def ci_configuration_path + filename_path(:gitlab_ci_yml) + end + + def contribution_guide_path + if project && contribution_guide = repository.contribution_guide + project_blob_path( + project, + tree_join(project.default_branch, + contribution_guide.name) + ) + end + end + + def add_license_path + add_special_file_path(file_name: 'LICENSE') + end + + def add_ci_yml_path + add_special_file_path(file_name: '.gitlab-ci.yml') + end + + def add_readme_path + add_special_file_path(file_name: 'README.md') + end + + def add_koding_stack_path + project_new_blob_path( + project, + default_branch || 'master', + file_name: '.koding.yml', + commit_message: "Add Koding stack script", + content: <<-CONTENT.strip_heredoc + provider: + aws: + access_key: '${var.aws_access_key}' + secret_key: '${var.aws_secret_key}' + resource: + aws_instance: + #{project.path}-vm: + instance_type: t2.nano + user_data: |- + + # Created by GitLab UI for :> + + echo _KD_NOTIFY_@Installing Base packages...@ + + apt-get update -y + apt-get install git -y + + echo _KD_NOTIFY_@Cloning #{project.name}...@ + + export KODING_USER=${var.koding_user_username} + export REPO_URL=#{root_url}${var.koding_queryString_repo}.git + export BRANCH=${var.koding_queryString_branch} + + sudo -i -u $KODING_USER git clone $REPO_URL -b $BRANCH + + echo _KD_NOTIFY_@#{project.name} cloned.@ + CONTENT + ) + end + + def license_short_name + license = repository.license + license&.nickname || license&.name || 'LICENSE' + end + + private + + def filename_path(filename) + if blob = repository.public_send(filename) # rubocop:disable GitlabSecurity/PublicSend + project_blob_path( + project, + tree_join(default_branch, blob.name) + ) + end + end + + def anonymous_project_view + if !project.empty_repo? && can?(current_user, :download_code, project) + 'files' + else + 'activity' + end + end + + def add_special_file_path(file_name:, commit_message: nil, branch_name: nil) + commit_message ||= s_("CommitMessage|Add %{file_name}") % { file_name: file_name } + project_new_blob_path( + project, + project.default_branch || 'master', + file_name: file_name, + commit_message: commit_message, + branch_name: branch_name + ) + end + + def can_current_user_push_code? + if empty_repo? + can?(current_user, :push_code, project) + else + user_can_push_to_branch?(current_user, default_branch) + end + end + + def files_anchor_data + { + enabled: true, + label: _('Files (%{human_size})') % { human_size: storage_counter(statistics.total_repository_size) }, + link: project_tree_path(project) + } + end + + def commits_anchor_data + { + enabled: true, + label: n_('Commit (%{commit_count})', 'Commits (%{commit_count})', statistics.commit_count) % { commit_count: number_with_delimiter(statistics.commit_count) }, + link: project_commits_path(project, repository.root_ref) + } + end + + def branches_anchor_data + { + enabled: true, + label: n_('Branch (%{branch_count})', 'Branches (%{branch_count})', repository.branch_count) % { branch_count: number_with_delimiter(repository.branch_count) }, + link: project_branches_path(project) + } + end + + def tags_anchor_data + { + enabled: true, + label: n_('Tag (%{tag_count})', 'Tags (%{tag_count})', repository.tag_count) % { tag_count: number_with_delimiter(repository.tag_count) }, + link: project_tags_path(project) + } + end + + def new_file_anchor_data + if current_user && can_current_user_push_code? + { + enabled: false, + label: _('New file'), + link: project_new_blob_path(project, default_branch || 'master'), + class_modifier: 'new' + } + end + end + + def readme_anchor_data + if current_user && can_current_user_push_code? && repository.readme.blank? + { + enabled: false, + label: _('Add Readme'), + link: add_readme_path + } + elsif repository.readme.present? + { + enabled: true, + label: _('Readme'), + link: default_project_view != 'readme' ? readme_path : '#readme' + } + end + end + + def changelog_anchor_data + if current_user && can_current_user_push_code? && repository.changelog.blank? + { + enabled: false, + label: _('Add Changelog'), + link: add_special_file_path(file_name: 'CHANGELOG') + } + elsif repository.changelog.present? + { + enabled: true, + label: _('Changelog'), + link: changelog_path + } + end + end + + def license_anchor_data + if current_user && can_current_user_push_code? && repository.license_blob.blank? + { + enabled: false, + label: _('Add License'), + link: add_license_path + } + elsif repository.license_blob.present? + { + enabled: true, + label: license_short_name, + link: license_path + } + end + end + + def contribution_guide_anchor_data + if current_user && can_current_user_push_code? && repository.contribution_guide.blank? + { + enabled: false, + label: _('Add Contribution guide'), + link: add_special_file_path(file_name: 'CONTRIBUTING.md', commit_message: 'Add contribution guide') + } + elsif repository.contribution_guide.present? + { + enabled: true, + label: _('Contribution guide'), + link: contribution_guide_path + } + end + end + + def autodevops_anchor_data(show_auto_devops_callout: false) + if current_user && can?(current_user, :admin_pipeline, project) && repository.gitlab_ci_yml.blank? && !show_auto_devops_callout + { + enabled: auto_devops_enabled?, + label: auto_devops_enabled? ? _('Auto DevOps enabled') : _('Enable Auto DevOps'), + link: project_settings_ci_cd_path(project, anchor: 'js-general-pipeline-settings') + } + elsif auto_devops_enabled? + { + enabled: true, + label: _('Auto DevOps enabled'), + link: nil + } + end + end + + def kubernetes_cluster_anchor_data + if current_user && can?(current_user, :create_cluster, project) + cluster_link = clusters.size == 1 ? project_cluster_path(project, clusters.first) : project_clusters_path(project) + + if clusters.empty? + cluster_link = new_project_cluster_path(project) + end + + { + enabled: !clusters.empty?, + label: clusters.empty? ? _('Add Kubernetes cluster') : n_('Kubernetes cluster', 'Kubernetes clusters', clusters.size), + link: cluster_link + } + end + end + + def gitlab_ci_anchor_data + if current_user && can_current_user_push_code? && repository.gitlab_ci_yml.blank? && !auto_devops_enabled? + { + enabled: false, + label: _('Set up CI/CD'), + link: add_ci_yml_path + } + elsif repository.gitlab_ci_yml.present? + { + enabled: true, + label: _('CI/CD configuration'), + link: ci_configuration_path + } + end + end + + def koding_anchor_data + if current_user && can_current_user_push_code? && koding_enabled? && repository.koding_yml.blank? + { + enabled: false, + label: _('Set up Koding'), + link: add_koding_stack_path + } + end + end + + def koding_enabled? + Gitlab::CurrentSettings.koding_enabled? + end +end diff --git a/app/views/projects/_readme.html.haml b/app/views/projects/_readme.html.haml index aebdfbc8218..705338c083e 100644 --- a/app/views/projects/_readme.html.haml +++ b/app/views/projects/_readme.html.haml @@ -20,4 +20,4 @@ distributed with computer software, forming part of its documentation. GitLab will render it here instead of this message. %p - = link_to "Add Readme", add_special_file_path(@project, file_name: 'README.md'), class: 'btn btn-new' + = link_to "Add Readme", @project.add_readme_path, class: 'btn btn-new' diff --git a/app/views/projects/buttons/_koding.html.haml b/app/views/projects/buttons/_koding.html.haml index de2d61d4aa3..b9cec834ab4 100644 --- a/app/views/projects/buttons/_koding.html.haml +++ b/app/views/projects/buttons/_koding.html.haml @@ -1,3 +1,3 @@ -- if koding_enabled? && current_user && @repository.koding_yml && can_push_branch?(@project, @project.default_branch) +- if koding_enabled? && current_user && @repository.koding_yml && @project.user_can_push_to_branch?(current_user, @project.default_branch) = link_to koding_project_url(@project), class: 'btn project-action-button inline', target: '_blank', rel: 'noopener noreferrer' do _('Run in IDE (Koding)') diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml index 01fb9dab313..b4f91f447f9 100644 --- a/app/views/projects/empty.html.haml +++ b/app/views/projects/empty.html.haml @@ -1,5 +1,6 @@ - @no_container = true - breadcrumb_title "Details" +- @project = @project.present(current_user: current_user) = render partial: 'flash_messages', locals: { project: @project } @@ -32,8 +33,8 @@ .prepend-top-20 %nav.project-stats{ class: container_class } - = render 'stat_anchor_list', anchors: empty_project_stat_anchor_items(@project) - = render 'stat_anchor_list', anchors: empty_project_stat_button_items(@project) + = render 'stat_anchor_list', anchors: @project.empty_project_stat_anchor_items + = render 'stat_anchor_list', anchors: @project.empty_project_stat_button_items - if can?(current_user, :push_code, @project) %div{ class: [container_class, ("limit-container-width-sm" unless fluid_layout)] } diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index 3d23b19b815..385a3b490a4 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -1,6 +1,8 @@ +- project_stat_items_args = { show_auto_devops_callout: show_auto_devops_callout?(@project) } - @no_container = true - breadcrumb_title "Details" - @content_class = "limit-container-width" unless fluid_layout +- @project = @project.present(current_user: current_user) = content_for :meta_tags do = auto_discovery_link_tag(:atom, project_path(@project, rss_url_options), title: "#{@project.name} activity") @@ -14,8 +16,8 @@ - if can?(current_user, :download_code, @project) %nav.project-stats{ class: container_class } - = render 'stat_anchor_list', anchors: project_stat_anchor_items(@project) - = render 'stat_anchor_list', anchors: project_stat_button_items(@project) + = render 'stat_anchor_list', anchors: @project.project_stat_anchor_items(project_stat_items_args) + = render 'stat_anchor_list', anchors: @project.project_stat_button_items(project_stat_items_args) %div{ class: [container_class, ("limit-container-width" unless fluid_layout)] } @@ -25,7 +27,7 @@ = icon("exclamation-triangle fw") #{ _('Archived project! Repository is read-only') } - - view_path = default_project_view + - view_path = @project.default_project_view - if show_auto_devops_callout?(@project) = render 'shared/auto_devops_callout' diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index 79021a08719..6dfabd7ba4c 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -69,7 +69,7 @@ - else = form.submit 'Save changes', class: 'btn btn-save' - - if !issuable.persisted? && !issuable.project.empty_repo? && (guide_url = contribution_guide_path(issuable.project)) + - if !issuable.persisted? && !issuable.project.empty_repo? && (guide_url = issuable.project.present.contribution_guide_path) .inline.prepend-top-10 Please review the %strong= link_to('contribution guidelines', guide_url) diff --git a/spec/features/projects/show_project_spec.rb b/spec/features/projects/show_project_spec.rb index f5f2bbb49e0..0bd13a17dc9 100644 --- a/spec/features/projects/show_project_spec.rb +++ b/spec/features/projects/show_project_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe 'Project show page', :feature do - include ProjectsHelper - context 'when project pending delete' do let(:project) { create(:project, :empty_repo, pending_delete: true) } @@ -29,6 +27,7 @@ describe 'Project show page', :feature do describe 'empty project' do let(:project) { create(:project, :public, :empty_repo) } + let(:presenter) { project.present(current_user: user) } describe 'as a normal user' do before do @@ -71,13 +70,13 @@ describe 'Project show page', :feature do it '"Add Readme" button linked to new file populated for a readme' do page.within('.project-stats') do - expect(page).to have_link('Add Readme', href: add_special_file_path(project, file_name: 'README.md')) + expect(page).to have_link('Add Readme', href: presenter.add_readme_path) end end it '"Add License" button linked to new file populated for a license' do page.within('.project-stats') do - expect(page).to have_link('Add License', href: add_special_file_path(project, file_name: 'LICENSE')) + expect(page).to have_link('Add License', href: presenter.add_license_path) end end @@ -121,6 +120,7 @@ describe 'Project show page', :feature do describe 'populated project' do let(:project) { create(:project, :public, :repository) } + let(:presenter) { project.present(current_user: user) } describe 'as a normal user' do before do @@ -192,7 +192,7 @@ describe 'Project show page', :feature do expect(project.repository.gitlab_ci_yml).to be_nil page.within('.project-stats') do - expect(page).to have_link('Set up CI/CD', href: add_special_file_path(project, file_name: '.gitlab-ci.yml')) + expect(page).to have_link('Set up CI/CD', href: presenter.add_ci_yml_path) end end @@ -327,7 +327,7 @@ describe 'Project show page', :feature do visit project_path(project) page.within('.project-stats') do - expect(page).to have_link('Set up Koding', href: add_koding_stack_path(project)) + expect(page).to have_link('Set up Koding', href: presenter.add_koding_stack_path) end end end diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index c0251bf7dc0..ffe4266b51a 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -264,32 +264,6 @@ describe ProjectsHelper do end end - describe '#license_short_name' do - let(:project) { create(:project) } - - 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(helper.license_short_name(project)).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(helper.license_short_name(project)).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(helper.license_short_name(project)).to eq('LICENSE') - end - end - end - describe '#sanitized_import_error' do let(:project) { create(:project, :repository) } diff --git a/spec/presenters/project_presenter_spec.rb b/spec/presenters/project_presenter_spec.rb new file mode 100644 index 00000000000..49822693f3e --- /dev/null +++ b/spec/presenters/project_presenter_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +describe ProjectPresenter do + let(:user) { create(:user) } + let(:project) { create(:project) } + let(:presenter) { described_class.new(project, current_user: user) } + + 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 +end |