diff options
72 files changed, 598 insertions, 274 deletions
diff --git a/app/assets/javascripts/shortcuts_navigation.js b/app/assets/javascripts/shortcuts_navigation.js index 542cd586df0..73db8c10b99 100644 --- a/app/assets/javascripts/shortcuts_navigation.js +++ b/app/assets/javascripts/shortcuts_navigation.js @@ -16,9 +16,6 @@ require('./shortcuts'); Mousetrap.bind('g p', function() { return ShortcutsNavigation.findAndFollowLink('.shortcuts-project'); }); - Mousetrap.bind('g e', function() { - return ShortcutsNavigation.findAndFollowLink('.shortcuts-project-activity'); - }); Mousetrap.bind('g f', function() { return ShortcutsNavigation.findAndFollowLink('.shortcuts-tree'); }); @@ -31,9 +28,6 @@ require('./shortcuts'); Mousetrap.bind('g n', function() { return ShortcutsNavigation.findAndFollowLink('.shortcuts-network'); }); - Mousetrap.bind('g g', function() { - return ShortcutsNavigation.findAndFollowLink('.shortcuts-graphs'); - }); Mousetrap.bind('g i', function() { return ShortcutsNavigation.findAndFollowLink('.shortcuts-issues'); }); diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss index e4487dbcb87..8d1063fc26f 100644 --- a/app/assets/stylesheets/pages/tree.scss +++ b/app/assets/stylesheets/pages/tree.scss @@ -178,3 +178,29 @@ margin-left: $btn-side-margin; } } + +.repo-charts { + .sub-header { + margin: 20px 0; + } + + .sub-header-block.border-top { + margin-top: 20px; + padding: 0; + border-top: 1px solid $white-dark; + border-bottom: none; + } + + .commit-stats li { + font-size: 16px; + } + + .tree-ref-header { + margin-bottom: 20px; + + h4 { + margin: 0; + line-height: 36px; + } + } +} diff --git a/app/controllers/projects/graphs_controller.rb b/app/controllers/projects/graphs_controller.rb index 923e7340e69..43fc0c39801 100644 --- a/app/controllers/projects/graphs_controller.rb +++ b/app/controllers/projects/graphs_controller.rb @@ -17,6 +17,25 @@ class Projects::GraphsController < Projects::ApplicationController end def commits + redirect_to action: 'charts' + end + + def languages + redirect_to action: 'charts' + end + + def charts + get_commits + get_languages + end + + def ci + redirect_to charts_namespace_project_pipelines_path(@project.namespace, @project) + end + + private + + def get_commits @commits = @project.repository.commits(@ref, limit: 2000, skip_merges: true) @commits_graph = Gitlab::Graphs::Commits.new(@commits) @commits_per_week_days = @commits_graph.commits_per_week_days @@ -24,15 +43,7 @@ class Projects::GraphsController < Projects::ApplicationController @commits_per_month = @commits_graph.commits_per_month end - def ci - @charts = {} - @charts[:week] = Ci::Charts::WeekChart.new(project) - @charts[:month] = Ci::Charts::MonthChart.new(project) - @charts[:year] = Ci::Charts::YearChart.new(project) - @charts[:build_times] = Ci::Charts::BuildTime.new(project) - end - - def languages + def get_languages @languages = Linguist::Repository.new(@repository.rugged, @repository.rugged.head.target_id).languages total = @languages.map(&:last).sum @@ -52,8 +63,6 @@ class Projects::GraphsController < Projects::ApplicationController end end - private - def fetch_graph @commits = @project.repository.commits(@ref, limit: 6000, skip_merges: true) @log = [] diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index 8657bc4dfdc..718d9e86bea 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -1,9 +1,10 @@ class Projects::PipelinesController < Projects::ApplicationController - before_action :pipeline, except: [:index, :new, :create] + before_action :pipeline, except: [:index, :new, :create, :charts] before_action :commit, only: [:show, :builds] before_action :authorize_read_pipeline! before_action :authorize_create_pipeline!, only: [:new, :create] before_action :authorize_update_pipeline!, only: [:retry, :cancel] + before_action :builds_enabled, only: :charts def index @scope = params[:scope] @@ -92,6 +93,14 @@ class Projects::PipelinesController < Projects::ApplicationController redirect_back_or_default default: namespace_project_pipelines_path(project.namespace, project) end + def charts + @charts = {} + @charts[:week] = Ci::Charts::WeekChart.new(project) + @charts[:month] = Ci::Charts::MonthChart.new(project) + @charts[:year] = Ci::Charts::YearChart.new(project) + @charts[:build_times] = Ci::Charts::BuildTime.new(project) + end + private def create_params diff --git a/app/helpers/rss_helper.rb b/app/helpers/rss_helper.rb new file mode 100644 index 00000000000..ea5d2932ef4 --- /dev/null +++ b/app/helpers/rss_helper.rb @@ -0,0 +1,5 @@ +module RssHelper + def rss_url_options + { format: :atom, private_token: current_user.try(:private_token) } + end +end diff --git a/app/models/project.rb b/app/models/project.rb index fa031b061d8..1ac4a178a9b 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -113,6 +113,7 @@ class Project < ActiveRecord::Base has_one :gitlab_issue_tracker_service, dependent: :destroy, inverse_of: :project has_one :external_wiki_service, dependent: :destroy has_one :kubernetes_service, dependent: :destroy, inverse_of: :project + has_one :mock_ci_service, dependent: :destroy has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id" has_one :forked_from_project, through: :forked_project_link diff --git a/app/views/dashboard/_activities.html.haml b/app/views/dashboard/_activities.html.haml index 0dbb0ca6958..89d991abe54 100644 --- a/app/views/dashboard/_activities.html.haml +++ b/app/views/dashboard/_activities.html.haml @@ -2,10 +2,9 @@ = render "events/event_last_push", event: @last_push .nav-block - - if current_user - .controls - = link_to dashboard_projects_path(:atom, { private_token: current_user.private_token }), class: 'btn rss-btn has-tooltip', title: 'Subscribe' do - %i.fa.fa-rss + .controls + = link_to dashboard_projects_path(rss_url_options), class: 'btn rss-btn has-tooltip', title: 'Subscribe' do + %i.fa.fa-rss = render 'shared/event_filter' .content_list diff --git a/app/views/dashboard/activity.html.haml b/app/views/dashboard/activity.html.haml index aa57df14c23..190ad4b40a5 100644 --- a/app/views/dashboard/activity.html.haml +++ b/app/views/dashboard/activity.html.haml @@ -1,6 +1,5 @@ = content_for :meta_tags do - - if current_user - = auto_discovery_link_tag(:atom, dashboard_projects_url(format: :atom, private_token: current_user.private_token), title: "All activity") + = auto_discovery_link_tag(:atom, dashboard_projects_url(rss_url_options), title: "All activity") - page_title "Activity" - header_title "Activity", activity_dashboard_path diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml index 653052f7c54..9a4e423f896 100644 --- a/app/views/dashboard/issues.html.haml +++ b/app/views/dashboard/issues.html.haml @@ -1,17 +1,15 @@ - page_title "Issues" - header_title "Issues", issues_dashboard_path(assignee_id: current_user.id) = content_for :meta_tags do - - if current_user - = auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{current_user.name} issues") + = auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{current_user.name} issues") .top-area = render 'shared/issuable/nav', type: :issues .nav-controls - - if current_user - = link_to url_for(params.merge(format: :atom, private_token: current_user.private_token)), class: 'btn' do - = icon('rss') - %span.icon-label - Subscribe + = link_to params.merge(rss_url_options), class: 'btn' do + = icon('rss') + %span.icon-label + Subscribe = render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue" = render 'shared/issuable/filter', type: :issues diff --git a/app/views/dashboard/projects/index.atom.builder b/app/views/dashboard/projects/index.atom.builder index fb5be63b472..13f7a8ddcec 100644 --- a/app/views/dashboard/projects/index.atom.builder +++ b/app/views/dashboard/projects/index.atom.builder @@ -1,7 +1,7 @@ xml.instruct! xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.title "Activity" - xml.link href: dashboard_projects_url(format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml" + xml.link href: dashboard_projects_url(rss_url_options), rel: "self", type: "application/atom+xml" xml.link href: dashboard_projects_url, rel: "alternate", type: "text/html" xml.id dashboard_projects_url xml.updated @events[0].updated_at.xmlschema if @events[0] diff --git a/app/views/dashboard/projects/index.html.haml b/app/views/dashboard/projects/index.html.haml index b82b933c3ad..f0adbad8412 100644 --- a/app/views/dashboard/projects/index.html.haml +++ b/app/views/dashboard/projects/index.html.haml @@ -1,6 +1,5 @@ = content_for :meta_tags do - - if current_user - = auto_discovery_link_tag(:atom, dashboard_projects_url(format: :atom, private_token: current_user.private_token), title: "All activity") + = auto_discovery_link_tag(:atom, dashboard_projects_url(rss_url_options), title: "All activity") - page_title "Projects" - header_title "Projects", dashboard_projects_path diff --git a/app/views/groups/_activities.html.haml b/app/views/groups/_activities.html.haml index c442cf056c3..d7851c79990 100644 --- a/app/views/groups/_activities.html.haml +++ b/app/views/groups/_activities.html.haml @@ -2,10 +2,9 @@ = render "events/event_last_push", event: @last_push .nav-block - - if current_user - .controls - = link_to group_path(@group, format: :atom, private_token: current_user.private_token), class: 'btn rss-btn has-tooltip' , title: 'Subscribe' do - %i.fa.fa-rss + .controls + = link_to group_path(@group, rss_url_options), class: 'btn rss-btn has-tooltip' , title: 'Subscribe' do + %i.fa.fa-rss = render 'shared/event_filter' .content_list diff --git a/app/views/groups/activity.html.haml b/app/views/groups/activity.html.haml index d7375b23524..3969e56f937 100644 --- a/app/views/groups/activity.html.haml +++ b/app/views/groups/activity.html.haml @@ -1,6 +1,5 @@ = content_for :meta_tags do - - if current_user - = auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity") + = auto_discovery_link_tag(:atom, group_url(@group, rss_url_options), title: "#{@group.name} activity") - page_title "Activity" = render 'groups/head' diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml index 939bddf3fe9..f4c17dc2d16 100644 --- a/app/views/groups/issues.html.haml +++ b/app/views/groups/issues.html.haml @@ -1,19 +1,17 @@ - page_title "Issues" = render "head_issues" = content_for :meta_tags do - - if current_user - = auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{@group.name} issues") + = auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{@group.name} issues") - if group_issues(@group).exists? .top-area = render 'shared/issuable/nav', type: :issues - - if current_user - .nav-controls - = link_to url_for(params.merge(format: :atom, private_token: current_user.private_token)), class: 'btn' do - = icon('rss') - %span.icon-label - Subscribe - = render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue" + .nav-controls + = link_to params.merge(rss_url_options), class: 'btn' do + = icon('rss') + %span.icon-label + Subscribe + = render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue" = render 'shared/issuable/filter', type: :issues diff --git a/app/views/groups/show.atom.builder b/app/views/groups/show.atom.builder index b68bf444d27..914091dfd15 100644 --- a/app/views/groups/show.atom.builder +++ b/app/views/groups/show.atom.builder @@ -1,7 +1,7 @@ xml.instruct! xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.title "#{@group.name} activity" - xml.link href: group_url(@group, format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml" + xml.link href: group_url(@group, rss_url_options), rel: "self", type: "application/atom+xml" xml.link href: group_url(@group), rel: "alternate", type: "text/html" xml.id group_url(@group) xml.updated @events[0].updated_at.xmlschema if @events[0] diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 3d7b469660a..8f0f2708194 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -1,8 +1,7 @@ - @no_container = true = content_for :meta_tags do - - if current_user - = auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity") + = auto_discovery_link_tag(:atom, group_url(@group, rss_url_options), title: "#{@group.name} activity") = render 'groups/head' = render 'groups/home_panel' diff --git a/app/views/help/_shortcuts.html.haml b/app/views/help/_shortcuts.html.haml index 705e20112fa..5d1369c2010 100644 --- a/app/views/help/_shortcuts.html.haml +++ b/app/views/help/_shortcuts.html.haml @@ -131,12 +131,6 @@ %tr %td.shortcut .key g - .key e - %td - Go to the project's activity feed - %tr - %td.shortcut - .key g .key f %td Go to files @@ -161,12 +155,6 @@ %tr %td.shortcut .key g - .key g - %td - Go to graphs - %tr - %td.shortcut - .key g .key i %td Go to issues diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml index 7883823b21e..2335d467389 100644 --- a/app/views/layouts/nav/_project.html.haml +++ b/app/views/layouts/nav/_project.html.haml @@ -21,40 +21,23 @@ .fade-right = icon('angle-right') %ul.nav-links.scrolling-tabs - = nav_link(path: 'projects#show', html_options: {class: 'home'}) do + = nav_link(path: ['projects#show', 'projects#activity', 'cycle_analytics#show'], html_options: { class: 'home' }) do = link_to project_path(@project), title: 'Project', class: 'shortcuts-project' do %span Project - = nav_link(path: 'projects#activity') do - = link_to activity_project_path(@project), title: 'Activity', class: 'shortcuts-project-activity' do - %span - Activity - - if project_nav_tab? :files - = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file commit commits compare repositories tags branches releases network)) do + = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file commit commits compare repositories tags branches releases graphs network)) do = link_to project_files_path(@project), title: 'Repository', class: 'shortcuts-tree' do %span Repository - - if project_nav_tab? :pipelines - = nav_link(controller: [:pipelines, :builds, :environments, :cycle_analytics]) do - = link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do - %span - Pipelines - - if project_nav_tab? :container_registry = nav_link(controller: %w(container_registry)) do = link_to project_container_registry_path(@project), title: 'Container Registry', class: 'shortcuts-container-registry' do %span Registry - - if project_nav_tab? :graphs - = nav_link(controller: %w(graphs)) do - = link_to namespace_project_graph_path(@project.namespace, @project, current_ref), title: 'Graphs', class: 'shortcuts-graphs' do - %span - Graphs - - if project_nav_tab? :issues = nav_link(controller: [:issues, :labels, :milestones, :boards]) do = link_to namespace_project_issues_path(@project.namespace, @project), title: 'Issues', class: 'shortcuts-issues' do @@ -70,6 +53,12 @@ Merge Requests %span.badge.count.merge_counter= number_with_delimiter(MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened.count) + - if project_nav_tab? :pipelines + = nav_link(controller: [:pipelines, :builds, :environments]) do + = link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do + %span + Pipelines + - if project_nav_tab? :wiki = nav_link(controller: :wikis) do = link_to get_project_wiki_path(@project), title: 'Wiki', class: 'shortcuts-wiki' do diff --git a/app/views/projects/_activity.html.haml b/app/views/projects/_activity.html.haml index 4268337fd6d..fb990dd9592 100644 --- a/app/views/projects/_activity.html.haml +++ b/app/views/projects/_activity.html.haml @@ -1,11 +1,11 @@ - @no_container = true += render "projects/head" %div{ class: container_class } .nav-block.activity-filter-block - - if current_user - .controls - = link_to namespace_project_path(@project.namespace, @project, format: :atom, private_token: current_user.private_token), title: "Subscribe", class: 'btn rss-btn has-tooltip' do - = icon('rss') + .controls + = link_to namespace_project_path(@project.namespace, @project, rss_url_options), title: "Subscribe", class: 'btn rss-btn has-tooltip' do + = icon('rss') = render 'shared/event_filter' diff --git a/app/views/projects/_head.html.haml b/app/views/projects/_head.html.haml new file mode 100644 index 00000000000..db08b77c8e0 --- /dev/null +++ b/app/views/projects/_head.html.haml @@ -0,0 +1,20 @@ += content_for :sub_nav do + .scrolling-tabs-container.sub-nav-scroll + = render 'shared/nav_scroll' + .nav-links.sub-nav.scrolling-tabs + %ul{ class: container_class } + = nav_link(path: 'projects#show') do + = link_to project_path(@project), title: 'Project home', class: 'shortcuts-project' do + %span + Home + + = nav_link(path: 'projects#activity') do + = link_to activity_project_path(@project), title: 'Activity', class: 'shortcuts-project-activity' do + %span + Activity + + - if can?(current_user, :read_cycle_analytics, @project) + = nav_link(path: 'cycle_analytics#show') do + = link_to project_cycle_analytics_path(@project), title: 'Cycle Analytics', class: 'shortcuts-project-cycle-analytics' do + %span + Cycle Analytics diff --git a/app/views/projects/commits/_head.html.haml b/app/views/projects/commits/_head.html.haml index 80763ce67ca..dd6797f10c0 100644 --- a/app/views/projects/commits/_head.html.haml +++ b/app/views/projects/commits/_head.html.haml @@ -11,14 +11,6 @@ = link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do Commits - = nav_link(controller: %w(network)) do - = link_to namespace_project_network_path(@project.namespace, @project, current_ref) do - Network - - = nav_link(controller: :compare) do - = link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: current_ref) do - Compare - = nav_link(html_options: {class: branches_tab_class}) do = link_to namespace_project_branches_path(@project.namespace, @project) do Branches @@ -26,3 +18,19 @@ = nav_link(controller: [:tags, :releases]) do = link_to namespace_project_tags_path(@project.namespace, @project) do Tags + + = nav_link(path: 'graphs#show') do + = link_to namespace_project_graph_path(@project.namespace, @project, current_ref) do + Contributors + + = nav_link(controller: %w(network)) do + = link_to namespace_project_network_path(@project.namespace, @project, current_ref) do + Graph + + = nav_link(controller: :compare) do + = link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: current_ref) do + Compare + + = nav_link(path: 'graphs#charts') do + = link_to charts_namespace_project_graph_path(@project.namespace, @project, current_ref) do + Charts diff --git a/app/views/projects/commits/show.atom.builder b/app/views/projects/commits/show.atom.builder index 30bb7412073..2f0b6e39800 100644 --- a/app/views/projects/commits/show.atom.builder +++ b/app/views/projects/commits/show.atom.builder @@ -1,7 +1,7 @@ xml.instruct! xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.title "#{@project.name}:#{@ref} commits" - xml.link href: namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml" + xml.link href: namespace_project_commits_url(@project.namespace, @project, @ref, rss_url_options), rel: "self", type: "application/atom+xml" xml.link href: namespace_project_commits_url(@project.namespace, @project, @ref), rel: "alternate", type: "text/html" xml.id namespace_project_commits_url(@project.namespace, @project, @ref) xml.updated @commits.first.committed_date.xmlschema if @commits.any? diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml index 08cb8a04413..38dbf2ac10b 100644 --- a/app/views/projects/commits/show.html.haml +++ b/app/views/projects/commits/show.html.haml @@ -2,8 +2,7 @@ - page_title "Commits", @ref = content_for :meta_tags do - - if current_user - = auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), title: "#{@project.name}:#{@ref} commits") + = auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, rss_url_options), title: "#{@project.name}:#{@ref} commits") = content_for :sub_nav do = render "head" @@ -27,10 +26,9 @@ .control = form_tag(namespace_project_commits_path(@project.namespace, @project, @id), method: :get, class: 'commits-search-form') do = search_field_tag :search, params[:search], { placeholder: 'Filter by commit message', id: 'commits-search', class: 'form-control search-text-input input-short', spellcheck: false } - - if current_user && current_user.private_token - .control - = link_to namespace_project_commits_path(@project.namespace, @project, @ref, { format: :atom, private_token: current_user.private_token }), title: "Commits Feed", class: 'btn' do - = icon("rss") + .control + = link_to namespace_project_commits_path(@project.namespace, @project, @ref, rss_url_options), title: "Commits Feed", class: 'btn' do + = icon("rss") %div{ id: dom_id(@project) } %ol#commits-list.list-unstyled.content_list diff --git a/app/views/projects/cycle_analytics/show.html.haml b/app/views/projects/cycle_analytics/show.html.haml index 5405ff16bea..be17f2c764e 100644 --- a/app/views/projects/cycle_analytics/show.html.haml +++ b/app/views/projects/cycle_analytics/show.html.haml @@ -3,7 +3,7 @@ - content_for :page_specific_javascripts do = page_specific_javascript_bundle_tag('cycle_analytics') -= render "projects/pipelines/head" += render "projects/head" #cycle-analytics{ class: container_class, "v-cloak" => "true", data: { request_path: project_cycle_analytics_path(@project) } } - if @cycle_analytics_no_data diff --git a/app/views/projects/graphs/_head.html.haml b/app/views/projects/graphs/_head.html.haml deleted file mode 100644 index 67018aaa2ac..00000000000 --- a/app/views/projects/graphs/_head.html.haml +++ /dev/null @@ -1,19 +0,0 @@ -= content_for :sub_nav do - .scrolling-tabs-container.sub-nav-scroll - = render 'shared/nav_scroll' - .nav-links.sub-nav.scrolling-tabs - %ul{ class: (container_class) } - - - content_for :page_specific_javascripts do - = page_specific_javascript_bundle_tag('lib_chart') - = page_specific_javascript_bundle_tag('graphs') - = nav_link(action: :show) do - = link_to 'Contributors', namespace_project_graph_path - = nav_link(action: :commits) do - = link_to 'Commits', commits_namespace_project_graph_path - = nav_link(action: :languages) do - = link_to 'Languages', languages_namespace_project_graph_path - - if @project.feature_available?(:builds, current_user) - = nav_link(action: :ci) do - = link_to ci_namespace_project_graph_path do - Continuous Integration diff --git a/app/views/projects/graphs/commits.html.haml b/app/views/projects/graphs/charts.html.haml index c8a82f7bca3..d3bce45e974 100644 --- a/app/views/projects/graphs/commits.html.haml +++ b/app/views/projects/graphs/charts.html.haml @@ -1,38 +1,58 @@ - @no_container = true -- page_title "Commits", "Graphs" -= render 'head' +- page_title "Charts" +- content_for :page_specific_javascripts do + = page_specific_javascript_bundle_tag('lib_chart') + = page_specific_javascript_bundle_tag('graphs') += render "projects/commits/head" -%div{ class: container_class } - .sub-header-block - .tree-ref-holder - = render 'shared/ref_switcher', destination: 'graphs_commits' - %ul.breadcrumb.repo-breadcrumb - = commits_breadcrumbs +.repo-charts{ class: container_class } + %h4.sub-header + Programming languages used in this repository - %p.lead - Commit statistics for - %strong= @ref - #{@commits_graph.start_date.strftime('%b %d')} - #{@commits_graph.end_date.strftime('%b %d')} + .row + .col-md-4 + %ul.bordered-list + - @languages.each do |language| + %li + %span{ style: "color: #{language[:color]}" } + = icon('circle') + + = language[:label] + .pull-right + = language[:value] + \% + .col-md-8 + %canvas#languages-chart{ height: 400 } + +.repo-charts{ class: container_class } + .sub-header-block.border-top + + .row.tree-ref-header + .col-md-6 + %h4 + Commit statistics for + %strong= @ref + #{@commits_graph.start_date.strftime('%b %d')} - #{@commits_graph.end_date.strftime('%b %d')} + + .col-md-6 + .tree-ref-container + .tree-ref-holder + = render 'shared/ref_switcher', destination: 'graphs_commits' + %ul.breadcrumb.repo-breadcrumb + = commits_breadcrumbs .row .col-md-6 - %ul + %ul.commit-stats %li - %p.lead - %strong= @commits_graph.commits.size - commits during - %strong= @commits_graph.duration - days + Total: + %strong #{@commits_graph.commits.size} commits %li - %p.lead - Average - %strong= @commits_graph.commit_per_day - commits per day + Average per day: + %strong #{@commits_graph.commit_per_day} commits %li - %p.lead - Contributed by - %strong= @commits_graph.authors - authors + Authors: + %strong= @commits_graph.authors .col-md-6 %div %p.slead @@ -40,15 +60,18 @@ %canvas#month-chart .row .col-md-6 - %div - %p.slead - Commits per day hour (UTC) - %canvas#hour-chart .col-md-6 %div %p.slead Commits per weekday %canvas#weekday-chart + .row + .col-md-6 + .col-md-6 + %div + %p.slead + Commits per day hour (UTC) + %canvas#hour-chart :javascript var responsiveChart = function (selector, data) { @@ -93,3 +116,12 @@ var monthData = chartData(#{@commits_per_month.keys.to_json}, #{@commits_per_month.values.to_json}); responsiveChart($('#month-chart'), monthData); + + var data = #{@languages.to_json}; + var ctx = $("#languages-chart").get(0).getContext("2d"); + var options = { + scaleOverlay: true, + responsive: true, + maintainAspectRatio: false + } + var myPieChart = new Chart(ctx).Pie(data, options); diff --git a/app/views/projects/graphs/ci.html.haml b/app/views/projects/graphs/ci.html.haml deleted file mode 100644 index 6be4273b6ab..00000000000 --- a/app/views/projects/graphs/ci.html.haml +++ /dev/null @@ -1,18 +0,0 @@ -- @no_container = true -- page_title "Continuous Integration", "Graphs" -= render 'head' - -%div{ class: container_class } - .sub-header-block - .oneline - A collection of graphs for Continuous Integration - - #charts.ci-charts - .row - .col-md-6 - = render 'projects/graphs/ci/overall' - .col-md-6 - = render 'projects/graphs/ci/build_times' - - %hr - = render 'projects/graphs/ci/builds' diff --git a/app/views/projects/graphs/languages.html.haml b/app/views/projects/graphs/languages.html.haml deleted file mode 100644 index fcfcae0be20..00000000000 --- a/app/views/projects/graphs/languages.html.haml +++ /dev/null @@ -1,33 +0,0 @@ -- @no_container = true -- page_title "Languages", "Graphs" -= render 'head' - -%div{ class: container_class } - .sub-header-block - .oneline - Programming languages used in this repository - - .row - .col-md-8 - %canvas#languages-chart{ height: 400 } - .col-md-4 - %ul.bordered-list - - @languages.each do |language| - %li - %span{ style: "color: #{language[:color]}" } - = icon('circle') - - = language[:label] - .pull-right - = language[:value] - \% - -:javascript - var data = #{@languages.to_json}; - var ctx = $("#languages-chart").get(0).getContext("2d"); - var options = { - scaleOverlay: true, - responsive: true, - maintainAspectRatio: false - } - var myPieChart = new Chart(ctx).Pie(data, options); diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml index 5ebb939a109..d89dfe31e47 100644 --- a/app/views/projects/graphs/show.html.haml +++ b/app/views/projects/graphs/show.html.haml @@ -1,6 +1,9 @@ - @no_container = true -- page_title "Contributors", "Graphs" -= render 'head' +- page_title "Contributors" +- content_for :page_specific_javascripts do + = page_specific_javascript_bundle_tag('lib_chart') + = page_specific_javascript_bundle_tag('graphs') += render 'projects/commits/head' %div{ class: container_class } .sub-header-block diff --git a/app/views/projects/issues/_head.html.haml b/app/views/projects/issues/_head.html.haml index 4825820c4d9..7a188cb6445 100644 --- a/app/views/projects/issues/_head.html.haml +++ b/app/views/projects/issues/_head.html.haml @@ -7,7 +7,7 @@ = nav_link(controller: :issues) do = link_to namespace_project_issues_path(@project.namespace, @project), title: 'Issues' do %span - Issues + List = nav_link(controller: :boards) do = link_to namespace_project_boards_path(@project.namespace, @project), title: 'Board' do diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml index 8ea1a3a45e1..7b7d7b1e00e 100644 --- a/app/views/projects/issues/index.html.haml +++ b/app/views/projects/issues/index.html.haml @@ -10,17 +10,15 @@ = page_specific_javascript_bundle_tag('filtered_search') = content_for :meta_tags do - - if current_user - = auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{@project.name} issues") + = auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{@project.name} issues") - if project_issues(@project).exists? %div{ class: (container_class) } .top-area = render 'shared/issuable/nav', type: :issues .nav-controls - - if current_user - = link_to url_for(params.merge(format: :atom, private_token: current_user.private_token)), class: 'btn append-right-10 has-tooltip', title: 'Subscribe' do - = icon('rss') + = link_to params.merge(rss_url_options), class: 'btn append-right-10 has-tooltip', title: 'Subscribe' do + = icon('rss') - if can? current_user, :create_issue, @project = link_to new_namespace_project_issue_path(@project.namespace, @project, diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml index 83e6c026ba7..8a96c8dacf6 100644 --- a/app/views/projects/merge_requests/index.html.haml +++ b/app/views/projects/merge_requests/index.html.haml @@ -2,7 +2,6 @@ - @bulk_edit = can?(current_user, :admin_merge_request, @project) - page_title "Merge Requests" -= render "projects/issues/head" = render 'projects/last_push' - content_for :page_specific_javascripts do diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml index b88eef65cef..a4a24a217d3 100644 --- a/app/views/projects/network/show.html.haml +++ b/app/views/projects/network/show.html.haml @@ -1,4 +1,4 @@ -- page_title "Network", @ref +- page_title "Graph", @ref - content_for :page_specific_javascripts do = page_specific_javascript_tag('lib/raphael.js') = page_specific_javascript_bundle_tag('network') diff --git a/app/views/projects/pipelines/_head.html.haml b/app/views/projects/pipelines/_head.html.haml index 721a9b6beb5..a5acb7ac4a5 100644 --- a/app/views/projects/pipelines/_head.html.haml +++ b/app/views/projects/pipelines/_head.html.haml @@ -4,25 +4,25 @@ .nav-links.sub-nav.scrolling-tabs{ class: ('build' if local_assigns.fetch(:build_subnav, false)) } %ul{ class: (container_class) } - if project_nav_tab? :pipelines - = nav_link(controller: :pipelines) do + = nav_link(path: 'pipelines#index', controller: :pipelines) do = link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do %span Pipelines - if project_nav_tab? :builds - = nav_link(controller: %w(builds)) do + = nav_link(path: 'builds#index', controller: :builds) do = link_to project_builds_path(@project), title: 'Jobs', class: 'shortcuts-builds' do %span Jobs - if project_nav_tab? :environments - = nav_link(controller: %w(environments)) do + = nav_link(path: 'environments#index', controller: :environments) do = link_to project_environments_path(@project), title: 'Environments', class: 'shortcuts-environments' do %span Environments - - if can?(current_user, :read_cycle_analytics, @project) - = nav_link(controller: %w(cycle_analytics)) do - = link_to project_cycle_analytics_path(@project), title: 'Cycle Analytics' do + - if @project.feature_available?(:builds, current_user) && !@project.empty_repo? + = nav_link(path: 'pipelines#charts') do + = link_to charts_namespace_project_pipelines_path(@project.namespace, @project), title: 'Charts', class: 'shortcuts-pipelines-charts' do %span - Cycle Analytics + Charts diff --git a/app/views/projects/pipelines/charts.html.haml b/app/views/projects/pipelines/charts.html.haml new file mode 100644 index 00000000000..8ffdfa1a2cf --- /dev/null +++ b/app/views/projects/pipelines/charts.html.haml @@ -0,0 +1,21 @@ +- @no_container = true +- page_title "Charts", "Pipelines" +- content_for :page_specific_javascripts do + = page_specific_javascript_bundle_tag('lib_chart') + = page_specific_javascript_bundle_tag('graphs') += render 'head' + +%div{ class: container_class } + .sub-header-block + .oneline + A collection of graphs for Continuous Integration + + #charts.ci-charts + .row + .col-md-6 + = render 'projects/pipelines/charts/overall' + .col-md-6 + = render 'projects/pipelines/charts/build_times' + + %hr + = render 'projects/pipelines/charts/builds' diff --git a/app/views/projects/graphs/ci/_build_times.haml b/app/views/projects/pipelines/charts/_build_times.haml index bb0975a9535..bb0975a9535 100644 --- a/app/views/projects/graphs/ci/_build_times.haml +++ b/app/views/projects/pipelines/charts/_build_times.haml diff --git a/app/views/projects/graphs/ci/_builds.haml b/app/views/projects/pipelines/charts/_builds.haml index b6f453b9736..b6f453b9736 100644 --- a/app/views/projects/graphs/ci/_builds.haml +++ b/app/views/projects/pipelines/charts/_builds.haml diff --git a/app/views/projects/graphs/ci/_overall.haml b/app/views/projects/pipelines/charts/_overall.haml index edc4f7b079f..edc4f7b079f 100644 --- a/app/views/projects/graphs/ci/_overall.haml +++ b/app/views/projects/pipelines/charts/_overall.haml diff --git a/app/views/projects/show.atom.builder b/app/views/projects/show.atom.builder index 11310d5e1e1..5c7f2e315f0 100644 --- a/app/views/projects/show.atom.builder +++ b/app/views/projects/show.atom.builder @@ -1,7 +1,7 @@ xml.instruct! xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.title "#{@project.name} activity" - xml.link href: namespace_project_url(@project.namespace, @project, format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml" + xml.link href: namespace_project_url(@project.namespace, @project, rss_url_options), rel: "self", type: "application/atom+xml" xml.link href: namespace_project_url(@project.namespace, @project), rel: "alternate", type: "text/html" xml.id namespace_project_url(@project.namespace, @project) xml.updated @events[0].updated_at.xmlschema if @events[0] diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index 80d4081dd7b..30d185e6556 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -1,15 +1,15 @@ - @no_container = true = content_for :meta_tags do - - if current_user - = auto_discovery_link_tag(:atom, namespace_project_path(@project.namespace, @project, format: :atom, private_token: current_user.private_token), title: "#{@project.name} activity") + = auto_discovery_link_tag(:atom, namespace_project_path(@project.namespace, @project, rss_url_options), title: "#{@project.name} activity") = content_for :flash_message do - if current_user && can?(current_user, :download_code, @project) = render 'shared/no_ssh' = render 'shared/no_password' -= render 'projects/last_push' += render "projects/head" += render "projects/last_push" = render "home_panel" - if current_user && can?(current_user, :download_code, @project) diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml index 9864be3562a..a2a26039220 100644 --- a/app/views/projects/tree/show.html.haml +++ b/app/views/projects/tree/show.html.haml @@ -2,8 +2,7 @@ - page_title @path.presence || "Files", @ref = content_for :meta_tags do - - if current_user - = auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), title: "#{@project.name}:#{@ref} commits") + = auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, rss_url_options), title: "#{@project.name}:#{@ref} commits") = render "projects/commits/head" = render 'projects/last_push' diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index c130f3d9e17..af091f9ab88 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -24,13 +24,12 @@ = link_to new_abuse_report_path(user_id: @user.id, ref_url: request.referrer), class: 'btn btn-gray', title: 'Report abuse', data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do = icon('exclamation-circle') - - if current_user - = link_to user_path(@user, :atom, { private_token: current_user.private_token }), class: 'btn btn-gray' do - = icon('rss') - - if current_user.admin? - = link_to [:admin, @user], class: 'btn btn-gray', title: 'View user in admin area', - data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do - = icon('users') + = link_to user_path(@user, rss_url_options), class: 'btn btn-gray' do + = icon('rss') + - if current_user && current_user.admin? + = link_to [:admin, @user], class: 'btn btn-gray', title: 'View user in admin area', + data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do + = icon('users') .profile-header .avatar-holder diff --git a/changelogs/unreleased/2629-show-public-rss-feeds-to-anonymous-users.yml b/changelogs/unreleased/2629-show-public-rss-feeds-to-anonymous-users.yml new file mode 100644 index 00000000000..6ee8e5724bc --- /dev/null +++ b/changelogs/unreleased/2629-show-public-rss-feeds-to-anonymous-users.yml @@ -0,0 +1,4 @@ +--- +title: Show public RSS feeds to anonymous users +merge_request: 9596 +author: Michael Kozono diff --git a/changelogs/unreleased/26348-cleanup-navigation-order.yml b/changelogs/unreleased/26348-cleanup-navigation-order.yml new file mode 100644 index 00000000000..d5324f9e025 --- /dev/null +++ b/changelogs/unreleased/26348-cleanup-navigation-order.yml @@ -0,0 +1,4 @@ +--- +title: Clean-up Project navigation order +merge_request: 9272 +author: diff --git a/config/routes/project.rb b/config/routes/project.rb index 94841639823..2703bf4ab46 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -58,6 +58,7 @@ constraints(ProjectUrlConstrainer.new) do resources :graphs, only: [:show], constraints: { id: Gitlab::Regex.git_reference_regex } do member do + get :charts get :commits get :ci get :languages @@ -140,6 +141,7 @@ constraints(ProjectUrlConstrainer.new) do resources :pipelines, only: [:index, :new, :create, :show] do collection do resource :pipelines_settings, path: 'settings', only: [:show, :update] + get :charts end member do diff --git a/doc/workflow/shortcuts.md b/doc/workflow/shortcuts.md index 2a5e622dc7d..65e67aa1512 100644 --- a/doc/workflow/shortcuts.md +++ b/doc/workflow/shortcuts.md @@ -42,12 +42,10 @@ You can see GitLab's keyboard shortcuts by using 'shift + ?' | Keyboard Shortcut | Description | | ----------------- | ----------- | | <kbd>g</kbd> + <kbd>p</kbd> | Go to the project's home page | -| <kbd>g</kbd> + <kbd>e</kbd> | Go to the project's activity feed | | <kbd>g</kbd> + <kbd>f</kbd> | Go to files | | <kbd>g</kbd> + <kbd>c</kbd> | Go to commits | | <kbd>g</kbd> + <kbd>b</kbd> | Go to jobs | | <kbd>g</kbd> + <kbd>n</kbd> | Go to network graph | -| <kbd>g</kbd> + <kbd>g</kbd> | Go to graphs | | <kbd>g</kbd> + <kbd>i</kbd> | Go to issues | | <kbd>g</kbd> + <kbd>m</kbd> | Go to merge requests | | <kbd>g</kbd> + <kbd>s</kbd> | Go to snippets | diff --git a/features/project/active_tab.feature b/features/project/active_tab.feature index 5c14c5db665..1dd2bdd9b36 100644 --- a/features/project/active_tab.feature +++ b/features/project/active_tab.feature @@ -80,9 +80,9 @@ Feature: Project Active Tab And no other sub tabs should be active And the active main tab should be Repository - Scenario: On Project Repository/Network - Given I visit my project's network page - Then the active sub tab should be Network + Scenario: On Project Repository/Graph + Given I visit my project's graph page + Then the active sub tab should be Graph And no other sub tabs should be active And the active main tab should be Repository diff --git a/features/project/graph.feature b/features/project/graph.feature index 63793d6f989..b25c73ad870 100644 --- a/features/project/graph.feature +++ b/features/project/graph.feature @@ -9,9 +9,10 @@ Feature: Project Graph Then page should have graphs @javascript - Scenario: I should see project commits graphs + Scenario: I should see project languages & commits graphs on commits graph url When I visit project "Shop" commits graph page Then page should have commits graphs + Then page should have languages graphs @javascript Scenario: I should see project ci graphs @@ -20,6 +21,13 @@ Feature: Project Graph Then page should have CI graphs @javascript - Scenario: I should see project languages graphs + Scenario: I should see project languages & commits graphs on language graph url When I visit project "Shop" languages graph page Then page should have languages graphs + Then page should have commits graphs + + @javascript + Scenario: I should see project languages & commits graphs on charts url + When I visit project "Shop" chart page + Then page should have languages graphs + Then page should have commits graphs diff --git a/features/project/shortcuts.feature b/features/project/shortcuts.feature index f71f69ef060..95de63ba21a 100644 --- a/features/project/shortcuts.feature +++ b/features/project/shortcuts.feature @@ -19,17 +19,12 @@ Feature: Project Shortcuts Then the active sub tab should be Commits @javascript - Scenario: Navigate to network tab + Scenario: Navigate to graph tab Given I press "g" and "n" - Then the active sub tab should be Network + Then the active sub tab should be Graph And the active main tab should be Repository @javascript - Scenario: Navigate to graphs tab - Given I press "g" and "g" - Then the active main tab should be Graphs - - @javascript Scenario: Navigate to issues tab Given I press "g" and "i" Then the active main tab should be Issues @@ -53,8 +48,3 @@ Feature: Project Shortcuts Scenario: Navigate to project home Given I press "g" and "p" Then the active main tab should be Home - - @javascript - Scenario: Navigate to project feed - Given I press "g" and "e" - Then the active main tab should be Activity diff --git a/features/steps/project/graph.rb b/features/steps/project/graph.rb index 48ac7a98f0d..176d04d721c 100644 --- a/features/steps/project/graph.rb +++ b/features/steps/project/graph.rb @@ -18,6 +18,10 @@ class Spinach::Features::ProjectGraph < Spinach::FeatureSteps visit languages_namespace_project_graph_path(project.namespace, project, "master") end + step 'I visit project "Shop" chart page' do + visit charts_namespace_project_graph_path(project.namespace, project, "master") + end + step 'page should have languages graphs' do expect(page).to have_content /Ruby 66.* %/ expect(page).to have_content /JavaScript 22.* %/ diff --git a/features/steps/project/network_graph.rb b/features/steps/project/network_graph.rb index ff9251615c9..370e46265c7 100644 --- a/features/steps/project/network_graph.rb +++ b/features/steps/project/network_graph.rb @@ -66,7 +66,7 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps end step 'page should have "v1.0.0" in title' do - expect(page).to have_css 'title', text: 'Network · v1.0.0', visible: false + expect(page).to have_css 'title', text: 'Graph · v1.0.0', visible: false end step 'page should only have content from "v1.0.0"' do diff --git a/features/steps/project/project_shortcuts.rb b/features/steps/project/project_shortcuts.rb index 8143b01ca40..02c08b784bc 100644 --- a/features/steps/project/project_shortcuts.rb +++ b/features/steps/project/project_shortcuts.rb @@ -34,9 +34,4 @@ class Spinach::Features::ProjectShortcuts < Spinach::FeatureSteps find('body').native.send_key('g') find('body').native.send_key('w') end - - step 'I press "g" and "e"' do - find('body').native.send_key('g') - find('body').native.send_key('e') - end end diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index 718cf924729..d5b3bb34d7a 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -232,7 +232,7 @@ module SharedPaths visit stats_namespace_project_repository_path(@project.namespace, @project) end - step "I visit my project's network page" do + step "I visit my project's graph page" do # Stub Graph max_size to speed up test (10 commits vs. 650) Network::Graph.stub(max_count: 10) diff --git a/features/steps/shared/project_tab.rb b/features/steps/shared/project_tab.rb index d6024212601..83446afe424 100644 --- a/features/steps/shared/project_tab.rb +++ b/features/steps/shared/project_tab.rb @@ -12,10 +12,6 @@ module SharedProjectTab ensure_active_main_tab('Repository') end - step 'the active main tab should be Graphs' do - ensure_active_main_tab('Graphs') - end - step 'the active main tab should be Issues' do ensure_active_main_tab('Issues') end @@ -40,12 +36,8 @@ module SharedProjectTab expect(page).to have_selector('.layout-nav .nav-links > li.active', count: 0) end - step 'the active main tab should be Activity' do - ensure_active_main_tab('Activity') - end - - step 'the active sub tab should be Network' do - ensure_active_sub_tab('Network') + step 'the active sub tab should be Graph' do + ensure_active_sub_tab('Graph') end step 'the active sub tab should be Files' do diff --git a/spec/controllers/projects/graphs_controller_spec.rb b/spec/controllers/projects/graphs_controller_spec.rb index c4a7aa7d63e..049bae1899d 100644 --- a/spec/controllers/projects/graphs_controller_spec.rb +++ b/spec/controllers/projects/graphs_controller_spec.rb @@ -9,7 +9,23 @@ describe Projects::GraphsController do project.team << [user, :master] end - describe 'GET #languages' do + describe 'GET languages' do + it "redirects_to action charts" do + get(:commits, namespace_id: project.namespace.path, project_id: project.path, id: 'master') + + expect(response).to redirect_to action: :charts + end + end + + describe 'GET commits' do + it "redirects_to action charts" do + get(:commits, namespace_id: project.namespace.path, project_id: project.path, id: 'master') + + expect(response).to redirect_to action: :charts + end + end + + describe 'GET charts' do let(:linguist_repository) do double(languages: { 'Ruby' => 1000, @@ -34,7 +50,7 @@ describe Projects::GraphsController do end it 'sets the correct colour according to language' do - get(:languages, namespace_id: project.namespace, project_id: project, id: 'master') + get(:charts, namespace_id: project.namespace, project_id: project, id: 'master') expected_values.each do |val| expect(assigns(:languages)).to include(a_hash_including(val)) diff --git a/spec/features/dashboard/activity_spec.rb b/spec/features/dashboard/activity_spec.rb new file mode 100644 index 00000000000..c977f266296 --- /dev/null +++ b/spec/features/dashboard/activity_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +RSpec.describe 'Dashboard Activity', feature: true do + before do + login_as(create :user) + visit activity_dashboard_path + end + + it_behaves_like "it has an RSS button with current_user's private token" + it_behaves_like "an autodiscoverable RSS feed with current_user's private token" +end diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb index 2db1cf71209..f4420814c3a 100644 --- a/spec/features/dashboard/issues_spec.rb +++ b/spec/features/dashboard/issues_spec.rb @@ -45,4 +45,7 @@ RSpec.describe 'Dashboard Issues', feature: true do expect(page).to have_content(assigned_issue.title) expect(page).to have_content(other_issue.title) end + + it_behaves_like "it has an RSS button with current_user's private token" + it_behaves_like "an autodiscoverable RSS feed with current_user's private token" end diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb new file mode 100644 index 00000000000..63eb5c697c2 --- /dev/null +++ b/spec/features/dashboard/projects_spec.rb @@ -0,0 +1,10 @@ +require 'spec_helper' + +RSpec.describe 'Dashboard Projects', feature: true do + before do + login_as(create :user) + visit dashboard_projects_path + end + + it_behaves_like "an autodiscoverable RSS feed with current_user's private token" +end diff --git a/spec/features/groups/activity_spec.rb b/spec/features/groups/activity_spec.rb new file mode 100644 index 00000000000..3b481cba424 --- /dev/null +++ b/spec/features/groups/activity_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +feature 'Group activity page', feature: true do + let(:group) { create(:group) } + let(:path) { activity_group_path(group) } + + context 'when signed in' do + before do + user = create(:group_member, :developer, user: create(:user), group: group ).user + login_as(user) + visit path + end + + it_behaves_like "it has an RSS button with current_user's private token" + it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + end + + context 'when signed out' do + before do + visit path + end + + it_behaves_like "it has an RSS button without a private token" + it_behaves_like "an autodiscoverable RSS feed without a private token" + end +end diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb index 476eca17a9d..1b3747c390b 100644 --- a/spec/features/groups/issues_spec.rb +++ b/spec/features/groups/issues_spec.rb @@ -5,4 +5,22 @@ feature 'Group issues page', feature: true do let(:issuable) { create(:issue, project: project, title: "this is my created issuable")} include_examples 'project features apply to issuables', Issue + + context 'rss feed' do + let(:access_level) { ProjectFeature::ENABLED } + + context 'when signed in' do + let(:user) { user_in_group } + + it_behaves_like "it has an RSS button with current_user's private token" + it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + end + + context 'when signed out' do + let(:user) { nil } + + it_behaves_like "it has an RSS button without a private token" + it_behaves_like "an autodiscoverable RSS feed without a private token" + end + end end diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb new file mode 100644 index 00000000000..fb39693e8ca --- /dev/null +++ b/spec/features/groups/show_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +feature 'Group show page', feature: true do + let(:group) { create(:group) } + let(:path) { group_path(group) } + + context 'when signed in' do + before do + user = create(:group_member, :developer, user: create(:user), group: group ).user + login_as(user) + visit path + end + + it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + end + + context 'when signed out' do + before do + visit path + end + + it_behaves_like "an autodiscoverable RSS feed without a private token" + end +end diff --git a/spec/features/projects/activity/rss_spec.rb b/spec/features/projects/activity/rss_spec.rb new file mode 100644 index 00000000000..b47c6d431eb --- /dev/null +++ b/spec/features/projects/activity/rss_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +feature 'Project Activity RSS' do + let(:project) { create(:empty_project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } + let(:path) { activity_namespace_project_path(project.namespace, project) } + + before do + create(:issue, project: project) + end + + context 'when signed in' do + before do + user = create(:user) + project.team << [user, :developer] + login_as(user) + visit path + end + + it_behaves_like "it has an RSS button with current_user's private token" + end + + context 'when signed out' do + before do + visit path + end + + it_behaves_like "it has an RSS button without a private token" + end +end diff --git a/spec/features/projects/commit/rss_spec.rb b/spec/features/projects/commit/rss_spec.rb new file mode 100644 index 00000000000..6e0e1916f87 --- /dev/null +++ b/spec/features/projects/commit/rss_spec.rb @@ -0,0 +1,27 @@ +require 'spec_helper' + +feature 'Project Commits RSS' do + let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } + let(:path) { namespace_project_commits_path(project.namespace, project, :master) } + + context 'when signed in' do + before do + user = create(:user) + project.team << [user, :developer] + login_as(user) + visit path + end + + it_behaves_like "it has an RSS button with current_user's private token" + it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + end + + context 'when signed out' do + before do + visit path + end + + it_behaves_like "it has an RSS button without a private token" + it_behaves_like "an autodiscoverable RSS feed without a private token" + end +end diff --git a/spec/features/projects/guest_navigation_menu_spec.rb b/spec/features/projects/guest_navigation_menu_spec.rb index 8120a51c515..726469daba4 100644 --- a/spec/features/projects/guest_navigation_menu_spec.rb +++ b/spec/features/projects/guest_navigation_menu_spec.rb @@ -15,13 +15,11 @@ describe "Guest navigation menu" do within(".nav-links") do expect(page).to have_content 'Project' - expect(page).to have_content 'Activity' expect(page).to have_content 'Issues' expect(page).to have_content 'Wiki' expect(page).not_to have_content 'Repository' expect(page).not_to have_content 'Pipelines' - expect(page).not_to have_content 'Graphs' expect(page).not_to have_content 'Merge Requests' end end diff --git a/spec/features/projects/issues/rss_spec.rb b/spec/features/projects/issues/rss_spec.rb new file mode 100644 index 00000000000..71429f00095 --- /dev/null +++ b/spec/features/projects/issues/rss_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +feature 'Project Issues RSS' do + let(:project) { create(:empty_project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } + let(:path) { namespace_project_issues_path(project.namespace, project) } + + before do + create(:issue, project: project) + end + + context 'when signed in' do + before do + user = create(:user) + project.team << [user, :developer] + login_as(user) + visit path + end + + it_behaves_like "it has an RSS button with current_user's private token" + it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + end + + context 'when signed out' do + before do + visit path + end + + it_behaves_like "it has an RSS button without a private token" + it_behaves_like "an autodiscoverable RSS feed without a private token" + end +end diff --git a/spec/features/projects/main/rss_spec.rb b/spec/features/projects/main/rss_spec.rb new file mode 100644 index 00000000000..b1a3af612a1 --- /dev/null +++ b/spec/features/projects/main/rss_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +feature 'Project RSS' do + let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } + let(:path) { namespace_project_path(project.namespace, project) } + + context 'when signed in' do + before do + user = create(:user) + project.team << [user, :developer] + login_as(user) + visit path + end + + it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + end + + context 'when signed out' do + before do + visit path + end + + it_behaves_like "an autodiscoverable RSS feed without a private token" + end +end diff --git a/spec/features/projects/tree/rss_spec.rb b/spec/features/projects/tree/rss_spec.rb new file mode 100644 index 00000000000..9ac51997d65 --- /dev/null +++ b/spec/features/projects/tree/rss_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +feature 'Project Tree RSS' do + let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } + let(:path) { namespace_project_tree_path(project.namespace, project, :master) } + + context 'when signed in' do + before do + user = create(:user) + project.team << [user, :developer] + login_as(user) + visit path + end + + it_behaves_like "an autodiscoverable RSS feed with current_user's private token" + end + + context 'when signed out' do + before do + visit path + end + + it_behaves_like "an autodiscoverable RSS feed without a private token" + end +end diff --git a/spec/features/users/rss_spec.rb b/spec/features/users/rss_spec.rb new file mode 100644 index 00000000000..14564abb16d --- /dev/null +++ b/spec/features/users/rss_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +feature 'User RSS' do + let(:path) { user_path(create(:user)) } + + context 'when signed in' do + before do + login_as(create(:user)) + visit path + end + + it_behaves_like "it has an RSS button with current_user's private token" + end + + context 'when signed out' do + before do + visit path + end + + it_behaves_like "it has an RSS button without a private token" + end +end diff --git a/spec/helpers/rss_helper_spec.rb b/spec/helpers/rss_helper_spec.rb new file mode 100644 index 00000000000..f3f174f3d14 --- /dev/null +++ b/spec/helpers/rss_helper_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe RssHelper do + describe '#rss_url_options' do + context 'when signed in' do + it "includes the current_user's private_token" do + current_user = create(:user) + allow(helper).to receive(:current_user).and_return(current_user) + expect(helper.rss_url_options).to include private_token: current_user.private_token + end + end + + context 'when signed out' do + it "does not have a private_token" do + allow(helper).to receive(:current_user).and_return(nil) + expect(helper.rss_url_options[:private_token]).to be_nil + end + end + end +end diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 06617f3b007..eef283c2460 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -153,6 +153,7 @@ project: - gitlab_issue_tracker_service - external_wiki_service - kubernetes_service +- mock_ci_service - forked_project_link - forked_from_project - forked_project_links diff --git a/spec/support/features/rss_shared_examples.rb b/spec/support/features/rss_shared_examples.rb new file mode 100644 index 00000000000..9a3b0a731ad --- /dev/null +++ b/spec/support/features/rss_shared_examples.rb @@ -0,0 +1,23 @@ +shared_examples "an autodiscoverable RSS feed with current_user's private token" do + it "has an RSS autodiscovery link tag with current_user's private token" do + expect(page).to have_css("link[type*='atom+xml'][href*='private_token=#{Thread.current[:current_user].private_token}']", visible: false) + end +end + +shared_examples "it has an RSS button with current_user's private token" do + it "shows the RSS button with current_user's private token" do + expect(page).to have_css("a:has(.fa-rss)[href*='private_token=#{Thread.current[:current_user].private_token}']") + end +end + +shared_examples "an autodiscoverable RSS feed without a private token" do + it "has an RSS autodiscovery link tag without a private token" do + expect(page).to have_css("link[type*='atom+xml']:not([href*='private_token'])", visible: false) + end +end + +shared_examples "it has an RSS button without a private token" do + it "shows the RSS button without a private token" do + expect(page).to have_css("a:has(.fa-rss):not([href*='private_token'])") + end +end diff --git a/spec/support/project_features_apply_to_issuables_shared_examples.rb b/spec/support/project_features_apply_to_issuables_shared_examples.rb index 4621d17549b..f8b7d0527ba 100644 --- a/spec/support/project_features_apply_to_issuables_shared_examples.rb +++ b/spec/support/project_features_apply_to_issuables_shared_examples.rb @@ -18,7 +18,7 @@ shared_examples 'project features apply to issuables' do |klass| before do _ = issuable - login_as(user) + login_as(user) if user visit path end |