Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
7c0e5472c8
commit
dc22d7faa2
|
|
@ -391,7 +391,6 @@ Layout/ArgumentAlignment:
|
|||
- 'ee/spec/features/projects/environments/environments_spec.rb'
|
||||
- 'ee/spec/features/projects/merge_requests/user_edits_merge_request_spec.rb'
|
||||
- 'ee/spec/features/projects/pipelines/pipeline_spec.rb'
|
||||
- 'ee/spec/features/uncompleted_learn_gitlab_link_spec.rb'
|
||||
- 'ee/spec/finders/security/pipeline_vulnerabilities_finder_spec.rb'
|
||||
- 'ee/spec/frontend/fixtures/search.rb'
|
||||
- 'ee/spec/graphql/mutations/requirements_management/export_requirements_spec.rb'
|
||||
|
|
|
|||
|
|
@ -1979,7 +1979,6 @@ Layout/LineLength:
|
|||
- 'ee/spec/features/search/elastic/snippet_search_spec.rb'
|
||||
- 'ee/spec/features/subscriptions_spec.rb'
|
||||
- 'ee/spec/features/trial_registrations/company_information_spec.rb'
|
||||
- 'ee/spec/features/uncompleted_learn_gitlab_link_spec.rb'
|
||||
- 'ee/spec/features/users/login_spec.rb'
|
||||
- 'ee/spec/finders/analytics/devops_adoption/enabled_namespaces_finder_spec.rb'
|
||||
- 'ee/spec/finders/analytics/devops_adoption/snapshots_finder_spec.rb'
|
||||
|
|
@ -5159,7 +5158,6 @@ Layout/LineLength:
|
|||
- 'spec/lib/grafana/validator_spec.rb'
|
||||
- 'spec/lib/kramdown/kramdown_spec.rb'
|
||||
- 'spec/lib/kramdown/parser/atlassian_document_format_spec.rb'
|
||||
- 'spec/lib/learn_gitlab/project_spec.rb'
|
||||
- 'spec/lib/mattermost/command_spec.rb'
|
||||
- 'spec/lib/microsoft_teams/notifier_spec.rb'
|
||||
- 'spec/lib/object_storage/config_spec.rb'
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ Rails/IndexWith:
|
|||
- 'spec/lib/gitlab/import_export/model_configuration_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/project/tree_restorer_spec.rb'
|
||||
- 'spec/lib/google_api/cloud_platform/client_spec.rb'
|
||||
- 'spec/lib/learn_gitlab/onboarding_spec.rb'
|
||||
- 'spec/models/event_spec.rb'
|
||||
- 'spec/presenters/projects/security/configuration_presenter_spec.rb'
|
||||
- 'spec/support/database/multiple_databases.rb'
|
||||
|
|
|
|||
|
|
@ -311,12 +311,10 @@ RSpec/ExpectInHook:
|
|||
- 'spec/lib/gitlab/verify/uploads_spec.rb'
|
||||
- 'spec/lib/gitlab/zentao/query_spec.rb'
|
||||
- 'spec/lib/gitlab_spec.rb'
|
||||
- 'spec/lib/learn_gitlab/onboarding_spec.rb'
|
||||
- 'spec/lib/omni_auth/strategies/jwt_spec.rb'
|
||||
- 'spec/lib/prometheus/pid_provider_spec.rb'
|
||||
- 'spec/lib/sidebars/projects/menus/external_issue_tracker_menu_spec.rb'
|
||||
- 'spec/lib/sidebars/projects/menus/external_wiki_menu_spec.rb'
|
||||
- 'spec/lib/sidebars/projects/menus/learn_gitlab_menu_spec.rb'
|
||||
- 'spec/mailers/emails/service_desk_spec.rb'
|
||||
- 'spec/metrics_server/metrics_server_spec.rb'
|
||||
- 'spec/migrations/20210406144743_backfill_total_tuple_count_for_batched_migrations_spec.rb'
|
||||
|
|
|
|||
|
|
@ -3,6 +3,5 @@ Style/FloatDivision:
|
|||
Exclude:
|
||||
- 'ee/app/models/geo_node_status.rb'
|
||||
- 'ee/app/models/namespaces/storage/root_size.rb'
|
||||
- 'lib/learn_gitlab/onboarding.rb'
|
||||
- 'qa/qa/support/formatters/allure_metadata_formatter.rb'
|
||||
- 'qa/qa/tools/reliable_report.rb'
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ Style/HashAsLastArrayItem:
|
|||
- 'app/graphql/resolvers/concerns/issue_resolver_arguments.rb'
|
||||
- 'app/graphql/types/boards/board_issuable_input_base_type.rb'
|
||||
- 'app/graphql/types/boards/board_issue_input_base_type.rb'
|
||||
- 'app/helpers/learn_gitlab_helper.rb'
|
||||
- 'app/helpers/namespaces_helper.rb'
|
||||
- 'app/models/customer_relations/contact.rb'
|
||||
- 'app/models/customer_relations/organization.rb'
|
||||
|
|
|
|||
|
|
@ -239,7 +239,6 @@ Style/SymbolProc:
|
|||
- 'spec/graphql/mutations/releases/create_spec.rb'
|
||||
- 'spec/graphql/types/work_items/widget_type_enum_spec.rb'
|
||||
- 'spec/helpers/instance_configuration_helper_spec.rb'
|
||||
- 'spec/helpers/learn_gitlab_helper_spec.rb'
|
||||
- 'spec/helpers/members_helper_spec.rb'
|
||||
- 'spec/lib/backup/gitaly_backup_spec.rb'
|
||||
- 'spec/lib/gitlab/database/dynamic_model_helpers_spec.rb'
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ input[type='checkbox']:hover {
|
|||
}
|
||||
|
||||
&.header-search-is-active {
|
||||
.navbar-collapse {
|
||||
.global-search-container {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
|
|
@ -59,12 +59,6 @@ input[type='checkbox']:hover {
|
|||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(xl) {
|
||||
.navbar-nav {
|
||||
padding-left: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2088,6 +2088,12 @@ body.gl-dark {
|
|||
.gl-pt-0 {
|
||||
padding-top: 0;
|
||||
}
|
||||
.gl-mr-auto {
|
||||
margin-right: auto;
|
||||
}
|
||||
.gl-mr-3 {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
.gl-ml-n2 {
|
||||
margin-left: -0.25rem;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1739,6 +1739,12 @@ svg.s16 {
|
|||
.gl-pt-0 {
|
||||
padding-top: 0;
|
||||
}
|
||||
.gl-mr-auto {
|
||||
margin-right: auto;
|
||||
}
|
||||
.gl-mr-3 {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
.gl-ml-n2 {
|
||||
margin-left: -0.25rem;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ module LearnGitlabHelper
|
|||
|
||||
def learn_gitlab_onboarding_available?(project)
|
||||
Onboarding::Progress.onboarding?(project.namespace) &&
|
||||
LearnGitlab::Project.new(current_user).available?
|
||||
Onboarding::LearnGitlab.new(current_user).available?
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -33,10 +33,12 @@ module LearnGitlabHelper
|
|||
action_urls(project).to_h do |action, url|
|
||||
[
|
||||
action,
|
||||
url: url,
|
||||
completed: attributes[Onboarding::Progress.column_name(action)].present?,
|
||||
svg: image_path("learn_gitlab/#{action}.svg"),
|
||||
enabled: true
|
||||
{
|
||||
url: url,
|
||||
completed: attributes[Onboarding::Progress.column_name(action)].present?,
|
||||
svg: image_path("learn_gitlab/#{action}.svg"),
|
||||
enabled: true
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
@ -70,11 +72,14 @@ module LearnGitlabHelper
|
|||
end
|
||||
|
||||
def action_issue_urls
|
||||
LearnGitlab::Onboarding::ACTION_ISSUE_IDS.transform_values { |id| project_issue_url(learn_gitlab_project, id) }
|
||||
Onboarding::Completion::ACTION_ISSUE_IDS.transform_values do |id|
|
||||
project_issue_url(learn_gitlab_project, id)
|
||||
end
|
||||
end
|
||||
|
||||
def deploy_section_action_urls(project)
|
||||
experiment(:security_actions_continuous_onboarding,
|
||||
experiment(
|
||||
:security_actions_continuous_onboarding,
|
||||
namespace: project.namespace,
|
||||
user: current_user,
|
||||
sticky_to: current_user
|
||||
|
|
@ -91,7 +96,7 @@ module LearnGitlabHelper
|
|||
end
|
||||
|
||||
def learn_gitlab_project
|
||||
@learn_gitlab_project ||= LearnGitlab::Project.new(current_user).project
|
||||
@learn_gitlab_project ||= Onboarding::LearnGitlab.new(current_user).project
|
||||
end
|
||||
|
||||
def onboarding_progress(project)
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ module Nav
|
|||
id: 'general_new_group',
|
||||
title: _('New group'),
|
||||
href: new_group_path,
|
||||
data: { track_action: 'click_link_new_group', track_label: 'plus_menu_dropdown' }
|
||||
data: { track_action: 'click_link_new_group', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_group_link' }
|
||||
)
|
||||
)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -281,52 +281,74 @@ module Nav
|
|||
end
|
||||
|
||||
def projects_submenu_items(builder:)
|
||||
# These project links come from `app/views/layouts/nav/projects_dropdown/_show.html.haml`
|
||||
[
|
||||
{ id: 'your', title: _('Your projects'), href: dashboard_projects_path },
|
||||
{ id: 'starred', title: _('Starred projects'), href: starred_dashboard_projects_path },
|
||||
{ id: 'explore', title: _('Explore projects'), href: explore_root_path },
|
||||
{ id: 'topics', title: _('Explore topics'), href: topics_explore_projects_path }
|
||||
].each do |item|
|
||||
if Feature.enabled?(:remove_extra_primary_submenu_options)
|
||||
title = _('View all projects')
|
||||
|
||||
builder.add_primary_menu_item(
|
||||
**item,
|
||||
data: { qa_selector: 'menu_item_link', qa_title: item[:title], **menu_data_tracking_attrs(item[:title]) }
|
||||
id: 'your',
|
||||
title: title,
|
||||
href: dashboard_projects_path,
|
||||
data: { qa_selector: 'menu_item_link', qa_title: title, **menu_data_tracking_attrs(title) }
|
||||
)
|
||||
else
|
||||
# These project links come from `app/views/layouts/nav/projects_dropdown/_show.html.haml`
|
||||
[
|
||||
{ id: 'your', title: _('Your projects'), href: dashboard_projects_path },
|
||||
{ id: 'starred', title: _('Starred projects'), href: starred_dashboard_projects_path },
|
||||
{ id: 'explore', title: _('Explore projects'), href: explore_root_path },
|
||||
{ id: 'topics', title: _('Explore topics'), href: topics_explore_projects_path }
|
||||
].each do |item|
|
||||
builder.add_primary_menu_item(
|
||||
**item,
|
||||
data: { qa_selector: 'menu_item_link', qa_title: item[:title], **menu_data_tracking_attrs(item[:title]) }
|
||||
)
|
||||
end
|
||||
|
||||
title = _('Create new project')
|
||||
|
||||
builder.add_secondary_menu_item(
|
||||
id: 'create',
|
||||
title: title,
|
||||
href: new_project_path,
|
||||
data: { qa_selector: 'menu_item_link', qa_title: title, **menu_data_tracking_attrs(title) }
|
||||
)
|
||||
end
|
||||
|
||||
title = _('Create new project')
|
||||
|
||||
builder.add_secondary_menu_item(
|
||||
id: 'create',
|
||||
title: title,
|
||||
href: new_project_path,
|
||||
data: { qa_selector: 'menu_item_link', qa_title: title, **menu_data_tracking_attrs(title) }
|
||||
)
|
||||
end
|
||||
|
||||
def groups_submenu
|
||||
# These group links come from `app/views/layouts/nav/groups_dropdown/_show.html.haml`
|
||||
builder = ::Gitlab::Nav::TopNavMenuBuilder.new
|
||||
|
||||
[
|
||||
{ id: 'your', title: _('Your groups'), href: dashboard_groups_path },
|
||||
{ id: 'explore', title: _('Explore groups'), href: explore_groups_path }
|
||||
].each do |item|
|
||||
if Feature.enabled?(:remove_extra_primary_submenu_options)
|
||||
title = _('View all groups')
|
||||
|
||||
builder.add_primary_menu_item(
|
||||
**item,
|
||||
data: { qa_selector: 'menu_item_link', qa_title: item[:title], **menu_data_tracking_attrs(item[:title]) }
|
||||
)
|
||||
end
|
||||
|
||||
if current_user.can_create_group?
|
||||
title = _('Create group')
|
||||
|
||||
builder.add_secondary_menu_item(
|
||||
id: 'create',
|
||||
id: 'your',
|
||||
title: title,
|
||||
href: new_group_path,
|
||||
href: dashboard_groups_path,
|
||||
data: { qa_selector: 'menu_item_link', qa_title: title, **menu_data_tracking_attrs(title) }
|
||||
)
|
||||
else
|
||||
[
|
||||
{ id: 'your', title: _('Your groups'), href: dashboard_groups_path },
|
||||
{ id: 'explore', title: _('Explore groups'), href: explore_groups_path }
|
||||
].each do |item|
|
||||
builder.add_primary_menu_item(
|
||||
**item,
|
||||
data: { qa_selector: 'menu_item_link', qa_title: item[:title], **menu_data_tracking_attrs(item[:title]) }
|
||||
)
|
||||
end
|
||||
|
||||
if current_user.can_create_group?
|
||||
title = _('Create group')
|
||||
|
||||
builder.add_secondary_menu_item(
|
||||
id: 'create',
|
||||
title: title,
|
||||
href: new_group_path,
|
||||
data: { qa_selector: 'menu_item_link', qa_title: title, **menu_data_tracking_attrs(title) }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
builder.build
|
||||
|
|
|
|||
|
|
@ -13,33 +13,17 @@ module Ci
|
|||
end
|
||||
|
||||
def within_freeze_period?(period)
|
||||
# previous_freeze_end, ..., previous_freeze_start, ..., NOW, ..., next_freeze_end, ..., next_freeze_start
|
||||
# Current time is within a freeze period if
|
||||
# it falls between a previous freeze start and next freeze end
|
||||
start_freeze = Gitlab::Ci::CronParser.new(period.freeze_start, period.cron_timezone)
|
||||
end_freeze = Gitlab::Ci::CronParser.new(period.freeze_end, period.cron_timezone)
|
||||
start_freeze_cron = Gitlab::Ci::CronParser.new(period.freeze_start, period.cron_timezone)
|
||||
end_freeze_cron = Gitlab::Ci::CronParser.new(period.freeze_end, period.cron_timezone)
|
||||
|
||||
previous_freeze_start = previous_time(start_freeze)
|
||||
previous_freeze_end = previous_time(end_freeze)
|
||||
next_freeze_start = next_time(start_freeze)
|
||||
next_freeze_end = next_time(end_freeze)
|
||||
start_freeze = start_freeze_cron.previous_time_from(time_zone_now)
|
||||
end_freeze = end_freeze_cron.next_time_from(start_freeze)
|
||||
|
||||
previous_freeze_end < previous_freeze_start &&
|
||||
previous_freeze_start <= time_zone_now &&
|
||||
time_zone_now <= next_freeze_end &&
|
||||
next_freeze_end < next_freeze_start
|
||||
start_freeze <= time_zone_now && time_zone_now <= end_freeze
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def previous_time(cron_parser)
|
||||
cron_parser.previous_time_from(time_zone_now)
|
||||
end
|
||||
|
||||
def next_time(cron_parser)
|
||||
cron_parser.next_time_from(time_zone_now)
|
||||
end
|
||||
|
||||
def time_zone_now
|
||||
@time_zone_now ||= Time.zone.now
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module LearnGitlab
|
||||
class Onboarding
|
||||
module Onboarding
|
||||
class Completion
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
include Gitlab::Experiment::Dsl
|
||||
|
||||
|
|
@ -24,7 +24,7 @@ module LearnGitlab
|
|||
@current_user = current_user
|
||||
end
|
||||
|
||||
def completed_percentage
|
||||
def percentage
|
||||
return 0 unless onboarding_progress
|
||||
|
||||
attributes = onboarding_progress.attributes.symbolize_keys
|
||||
|
|
@ -32,14 +32,14 @@ module LearnGitlab
|
|||
total_actions = action_columns.count
|
||||
completed_actions = action_columns.count { |column| attributes[column].present? }
|
||||
|
||||
(completed_actions.to_f / total_actions.to_f * 100).round
|
||||
(completed_actions.to_f / total_actions * 100).round
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def onboarding_progress
|
||||
strong_memoize(:onboarding_progress) do
|
||||
::Onboarding::Progress.find_by(namespace: namespace) # rubocop: disable CodeReuse/ActiveRecord
|
||||
::Onboarding::Progress.find_by(namespace: namespace)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -54,7 +54,8 @@ module LearnGitlab
|
|||
end
|
||||
|
||||
def deploy_section_tracked_actions
|
||||
experiment(:security_actions_continuous_onboarding,
|
||||
experiment(
|
||||
:security_actions_continuous_onboarding,
|
||||
namespace: namespace,
|
||||
user: current_user,
|
||||
sticky_to: current_user
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module LearnGitlab
|
||||
class Project
|
||||
module Onboarding
|
||||
class LearnGitlab
|
||||
PROJECT_NAME = 'Learn GitLab'
|
||||
PROJECT_NAME_ULTIMATE_TRIAL = 'Learn GitLab - Ultimate trial'
|
||||
BOARD_NAME = 'GitLab onboarding'
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
%a.gl-sr-only.gl-accessibility{ href: "#content-body" } Skip to content
|
||||
.container-fluid
|
||||
.header-content.js-header-content
|
||||
.title-container.hide-when-top-nav-responsive-open.gl-transition-medium.gl-display-flex.gl-align-items-stretch.gl-pt-0
|
||||
.title-container.hide-when-top-nav-responsive-open.gl-transition-medium.gl-display-flex.gl-align-items-stretch.gl-pt-0.gl-mr-3
|
||||
.title
|
||||
%span.gl-sr-only GitLab
|
||||
= link_to root_path, title: _('Dashboard'), id: 'logo', class: 'has-tooltip', **tracking_attrs('main_navigation', 'click_gitlab_logo_link', 'navigation') do
|
||||
|
|
@ -28,11 +28,25 @@
|
|||
.gl-display-none.gl-sm-display-block
|
||||
= render "layouts/nav/top_nav"
|
||||
|
||||
.navbar-collapse.gl-transition-medium.collapse
|
||||
- if top_nav_show_search && Feature.enabled?(:new_navbar_layout)
|
||||
.navbar-collapse.gl-transition-medium.collapse.gl-mr-auto.global-search-container.hide-when-top-nav-responsive-open
|
||||
- search_menu_item = top_nav_search_menu_item_attrs
|
||||
%ul.nav.navbar-nav.gl-w-full.gl-align-items-center
|
||||
%li.nav-item.header-search-new.gl-display-none.gl-lg-display-block.gl-w-full
|
||||
- unless current_controller?(:search)
|
||||
- if Feature.enabled?(:new_header_search)
|
||||
= render 'layouts/header_search'
|
||||
- else
|
||||
= render 'layouts/search'
|
||||
%li.nav-item{ class: 'd-none d-sm-inline-block d-lg-none' }
|
||||
= link_to search_menu_item.fetch(:href), title: search_menu_item.fetch(:title), aria: { label: search_menu_item.fetch(:title) }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
|
||||
= sprite_icon(search_menu_item.fetch(:icon))
|
||||
|
||||
.navbar-collapse.gl-transition-medium.collapse{ class: ('global-search-container' unless Feature.enabled?(:new_navbar_layout)) }
|
||||
%ul.nav.navbar-nav.gl-w-full.gl-align-items-center.gl-justify-content-end
|
||||
- if current_user
|
||||
= render 'layouts/header/new_dropdown', class: 'gl-display-none gl-sm-display-block gl-white-space-nowrap gl-text-right'
|
||||
- if top_nav_show_search
|
||||
- if top_nav_show_search && Feature.disabled?(:new_navbar_layout)
|
||||
- search_menu_item = top_nav_search_menu_item_attrs
|
||||
%li.nav-item.header-search-new.gl-display-none.gl-lg-display-block.gl-w-full
|
||||
- unless current_controller?(:search)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
name: new_navbar_layout
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96853
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/366082
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/373078
|
||||
milestone: '15.4'
|
||||
type: development
|
||||
group: group::foundations
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: remove_extra_primary_submenu_options
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96931
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/373078
|
||||
milestone: '15.4'
|
||||
type: development
|
||||
group: group::foundations
|
||||
default_enabled: true
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
key_path: redis_hll_counters.quickactions.i_quickactions_timeline_monthly
|
||||
name: quickactions_timeline_monthly
|
||||
description: Count of MAU using the `/timeline` quick action
|
||||
product_section: ops
|
||||
product_stage: monitor
|
||||
product_group: respond
|
||||
product_category: incident_management
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.4"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97020
|
||||
time_frame: 28d
|
||||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- i_quickactions_timeline
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
key_path: redis_hll_counters.quickactions.i_quickactions_timeline_weekly
|
||||
name: quickactions_timeline_weekly
|
||||
description: Count of WAU using the `/timeline` quick action
|
||||
product_section: ops
|
||||
product_stage: monitor
|
||||
product_group: respond
|
||||
product_category: incident_management
|
||||
value_type: number
|
||||
status: active
|
||||
milestone: "15.4"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97020
|
||||
time_frame: 7d
|
||||
data_source: redis_hll
|
||||
data_category: optional
|
||||
instrumentation_class: RedisHLLMetric
|
||||
options:
|
||||
events:
|
||||
- i_quickactions_timeline
|
||||
performance_indicator_type: []
|
||||
distribution:
|
||||
- ce
|
||||
- ee
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddDismissalReasonToVulnerabilityStateTransitions < Gitlab::Database::Migration[2.0]
|
||||
def change
|
||||
add_column :vulnerability_state_transitions, :dismissal_reason, :smallint
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
34e485c0c94960fc07a3f529aed749c2bbc1a72bb49d064225a37b85134f70f2
|
||||
|
|
@ -22823,6 +22823,7 @@ CREATE TABLE vulnerability_state_transitions (
|
|||
updated_at timestamp with time zone NOT NULL,
|
||||
author_id bigint,
|
||||
comment text,
|
||||
dismissal_reason smallint,
|
||||
CONSTRAINT check_fca4a7ca39 CHECK ((char_length(comment) <= 255))
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,12 @@ To create a timeline event:
|
|||
1. Complete the required fields.
|
||||
1. Select **Save** or **Save and add another event**.
|
||||
|
||||
### Using a quick action
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/368721) in GitLab 15.4.
|
||||
|
||||
You can create a timeline event using the `/timeline` [quick action](../../user/project/quick_actions.md).
|
||||
|
||||
### From a comment on the incident
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/344058) in GitLab 15.4.
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ and apply those changes to another branch. Cherry-picks can help you:
|
|||
You can cherry-pick commits from the command line. In the GitLab user interface,
|
||||
you can also:
|
||||
|
||||
- Cherry-pick [all changes from a merge request](../../user/project/merge_requests/cherry_pick_changes.md#cherry-pick-a-merge-request).
|
||||
- Cherry-pick [a single commit](../../user/project/merge_requests/cherry_pick_changes.md#cherry-pick-a-commit).
|
||||
- Cherry-pick [all changes from a merge request](../../user/project/merge_requests/cherry_pick_changes.md#cherry-pick-all-changes-from-a-merge-request).
|
||||
- Cherry-pick [a single commit](../../user/project/merge_requests/cherry_pick_changes.md#cherry-pick-a-single-commit).
|
||||
- Cherry-pick [from a fork to the upstream repository](../../user/project/merge_requests/cherry_pick_changes.md#cherry-pick-into-a-project).
|
||||
|
||||
## Cherry-pick from the command line
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ The following resources can help you get started with Git:
|
|||
- [GitLab Git Cheat Sheet (download)](https://about.gitlab.com/images/press/git-cheat-sheet.pdf)
|
||||
- Commits:
|
||||
- [Revert a commit](../../user/project/merge_requests/revert_changes.md#revert-a-commit)
|
||||
- [Cherry-picking a commit](../../user/project/merge_requests/cherry_pick_changes.md#cherry-pick-a-commit)
|
||||
- [Cherry-picking a commit](../../user/project/merge_requests/cherry_pick_changes.md)
|
||||
- [Squashing commits](../gitlab_flow.md#squashing-commits-with-rebase)
|
||||
- [Squash-and-merge](../../user/project/merge_requests/squash_and_merge.md)
|
||||
- [Signing commits](../../user/project/repository/gpg_signed_commits/index.md)
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ To recover from multiple incorrect commits:
|
|||
The commits are now `A-B-C-D-E`.
|
||||
|
||||
Alternatively, with GitLab,
|
||||
you can [cherry-pick](../../../user/project/merge_requests/cherry_pick_changes.md#cherry-pick-a-commit)
|
||||
you can [cherry-pick](../../../user/project/merge_requests/cherry_pick_changes.md#cherry-pick-a-single-commit)
|
||||
that commit into a new merge request.
|
||||
|
||||
NOTE:
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ group: Configure
|
|||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Migrate from GitLab Managed Apps to Cluster Management Projects **(FREE)**
|
||||
# Migrate from GitLab Managed Apps to Cluster Management Projects (DEPRECATED) **(FREE)**
|
||||
|
||||
The GitLab Managed Apps were deprecated in GitLab 14.0
|
||||
in favor of user-controlled Cluster Management projects.
|
||||
|
|
|
|||
|
|
@ -7,61 +7,79 @@ type: reference, concepts
|
|||
|
||||
# Cherry-pick changes **(FREE)**
|
||||
|
||||
GitLab implements Git's powerful feature to
|
||||
[cherry-pick any commit](https://git-scm.com/docs/git-cherry-pick "Git cherry-pick documentation")
|
||||
with a **Cherry-pick** button in merge requests and commit details.
|
||||
In Git, *cherry-picking* is taking a single commit from one branch and adding it
|
||||
as the latest commit on another branch. The rest of the commits in the source branch
|
||||
are not added to the target. You should cherry-pick a commit when you need the
|
||||
change contained in a single commit, but you can't or don't want to pull the
|
||||
entire contents of that branch into another.
|
||||
|
||||
## Cherry-pick a merge request
|
||||
|
||||
After the merge request has been merged, a **Cherry-pick** button displays
|
||||
to cherry-pick the changes introduced by that merge request.
|
||||
|
||||

|
||||
|
||||
After you select that button, a modal displays a
|
||||
[branch filter search box](../repository/branches/index.md#branch-filter-search-box)
|
||||
where you can choose to either:
|
||||
|
||||
- Cherry-pick the changes directly into the selected branch.
|
||||
- Create a new merge request with the cherry-picked changes.
|
||||
|
||||
### Track a cherry-pick
|
||||
|
||||
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2675) in GitLab 12.9.
|
||||
|
||||
When you cherry-pick a merge commit, GitLab displays a system note to the related merge
|
||||
request thread. It crosslinks the new commit and the existing merge request.
|
||||
|
||||

|
||||
|
||||
Each deployment's [list of associated merge requests](../../../api/deployments.md#list-of-merge-requests-associated-with-a-deployment) includes cherry-picked merge commits.
|
||||
You can use the GitLab UI to cherry-pick single commits or entire merge requests.
|
||||
You can even cherry-pick a commit from [a fork of your project](#cherry-pick-into-a-project).
|
||||
|
||||
NOTE:
|
||||
We only track cherry-pick executed from GitLab (both UI and API). Support for tracking cherry-picked commits through the command line
|
||||
Support for tracking commits cherry-picked from the command line
|
||||
is tracked [in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/202215).
|
||||
|
||||
## Cherry-pick a commit
|
||||
## Cherry-pick all changes from a merge request
|
||||
|
||||
You can cherry-pick a commit from the commit details page:
|
||||
After a merge request is merged, you can cherry-pick all changes introduced
|
||||
by the merge request:
|
||||
|
||||

|
||||
1. On the top bar, select **Menu > Projects** and find your project.
|
||||
1. On the left sidebar, select **Merge requests**, and find your merge request.
|
||||
1. Scroll to the merge request reports section, and find the **Merged by** report.
|
||||
1. In the top right, select **Cherry-pick**:
|
||||
|
||||
Similar to cherry-picking a merge request, you can cherry-pick the changes
|
||||
directly into the target branch or create a new merge request to cherry-pick the
|
||||
changes.
|
||||

|
||||
1. In the modal window, select the project and branch to cherry-pick into.
|
||||
1. Optional. Select **Start a new merge request with these changes**.
|
||||
1. Select **Cherry-pick**.
|
||||
|
||||
When cherry-picking merge commits, the mainline is always the
|
||||
first parent. If you want to use a different mainline, you need to do that
|
||||
from the command line.
|
||||
## Cherry-pick a single commit
|
||||
|
||||
Here's a quick example to cherry-pick a merge commit using the second parent as the
|
||||
mainline:
|
||||
You can cherry-pick a single commit from multiple locations in your GitLab project.
|
||||
|
||||
```shell
|
||||
git cherry-pick -m 2 7a39eb0
|
||||
```
|
||||
### From a project's commit list
|
||||
|
||||
### Cherry-pick into a project
|
||||
To cherry-pick a commit from the list of all commits for a project:
|
||||
|
||||
1. On the top bar, select **Menu > Projects** and find your project.
|
||||
1. On the left sidebar, select **Repository > Commits**.
|
||||
1. Select the title of the commit you want to cherry-pick.
|
||||
1. In the modal window, select the project and branch to cherry-pick into.
|
||||
1. Optional. Select **Start a new merge request with these changes**.
|
||||
1. Select **Cherry-pick**.
|
||||
|
||||
### From a merge request
|
||||
|
||||
You can cherry-pick commits from any merge request in your project, regardless of
|
||||
whether the merge request is open or closed. To cherry-pick a commit from the
|
||||
list of commits included in a merge request:
|
||||
|
||||
1. On the top bar, select **Menu > Projects** and find your project.
|
||||
1. On the left sidebar, select **Merge requests**, and find your merge request.
|
||||
1. In the merge request's secondary menu, select **Commits** to display the commit details page.
|
||||
1. Select the title of the commit you want to cherry-pick.
|
||||
1. In the top right corner, select **Options > Cherry-pick** to show the cherry-pick modal.
|
||||
1. In the modal window, select the project and branch to cherry-pick into.
|
||||
1. Optional. Select **Start a new merge request with these changes**.
|
||||
1. Select **Cherry-pick**.
|
||||
|
||||
### From the file view of a repository
|
||||
|
||||
You can cherry-pick from the list of previous commits affecting an individual file
|
||||
when you view that file in your project's Git repository:
|
||||
|
||||
1. On the top bar, select **Menu > Projects** and find your project.
|
||||
1. On the left sidebar, select **Repository > Files** and go to the file
|
||||
changed by the commit.
|
||||
1. Select **History**, then select the title of the commit you want to cherry-pick.
|
||||
1. In the top right corner, select **Options > Cherry-pick** to show the cherry-pick modal.
|
||||
1. In the modal window, select the project and branch to cherry-pick into.
|
||||
1. Optional. Select **Start a new merge request with these changes**.
|
||||
1. Select **Cherry-pick**.
|
||||
|
||||
## Cherry-pick into a project
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21268) in GitLab 13.11 behind a [feature flag](../../feature_flags.md), disabled by default.
|
||||
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/324154) in GitLab 14.0.
|
||||
|
|
@ -70,25 +88,38 @@ You can cherry-pick merge requests from the same project, or forks of the same
|
|||
project, from the GitLab user interface:
|
||||
|
||||
1. In the merge request's secondary menu, select **Commits** to display the commit details page.
|
||||
1. Select the **Options** dropdown and select **Cherry-pick** to show the cherry-pick modal.
|
||||
1. In the top right corner, select **Options > Cherry-pick** to show the cherry-pick modal.
|
||||
1. In **Pick into project** and **Pick into branch**, select the destination project and branch:
|
||||

|
||||
1. Optional. Select **Start a new merge request** if you're ready to create a merge request.
|
||||
1. Select **Cherry-pick**.
|
||||
|
||||
## View system notes for cherry-picked commits
|
||||
|
||||
When you cherry-pick a merge commit in the GitLab UI or API, GitLab adds a system note
|
||||
to the related merge request thread in the format **{cherry-pick-commit}**
|
||||
`[USER]` **picked the changes into the branch** `[BRANCHNAME]` with commit** `[SHA]` `[DATE]`:
|
||||
|
||||

|
||||
|
||||
The system note crosslinks the new commit and the existing merge request.
|
||||
Each deployment's [list of associated merge requests](../../../api/deployments.md#list-of-merge-requests-associated-with-a-deployment) includes cherry-picked merge commits.
|
||||
|
||||
## Related topics
|
||||
|
||||
- The [Commits API](../../../api/commits.md) enables you to add custom messages
|
||||
to changes you cherry-pick through the API.
|
||||
- Use the [Commits API](../../../api/commits.md) to add custom messages
|
||||
to changes when you use the API to cherry-pick.
|
||||
|
||||
<!-- ## Troubleshooting
|
||||
## Troubleshooting
|
||||
|
||||
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
|
||||
one might have when setting this up, or when something is changed, or on upgrading, it's
|
||||
important to describe those, too. Think of things that may go wrong and include them here.
|
||||
This is important to minimize requests for support, and to avoid doc comments with
|
||||
questions that you know someone might ask.
|
||||
### Selecting a different parent commit when cherry-picking
|
||||
|
||||
Each scenario can be a third-level heading, e.g. `### Getting error message X`.
|
||||
If you have none to add when creating a doc, leave this section in place
|
||||
but commented out to help encourage others to add to it in the future. -->
|
||||
When you cherry-pick a merge commit in the GitLab UI, the mainline is always the
|
||||
first parent. Use the command line to cherry-pick with a different mainline.
|
||||
|
||||
Here's a quick example to cherry-pick a merge commit using the second parent as the
|
||||
mainline:
|
||||
|
||||
```shell
|
||||
git cherry-pick -m 2 7a39eb0
|
||||
```
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.0 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 29 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 7.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.9 KiB |
|
|
@ -110,6 +110,7 @@ threads. Some quick actions might not be available to all subscription tiers.
|
|||
| `/tableflip <comment>` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Append the comment with `(╯°□°)╯︵ ┻━┻`. |
|
||||
| `/target_branch <local branch name>` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Set target branch. |
|
||||
| `/title <new title>` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Change title. |
|
||||
| `/timeline <timeline comment> \| <date(YYYY-MM-DD)> <time(HH:MM)>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Add a timeline event to this incident. For example, `/timeline DB load spiked \| 2022-09-07 09:30`. ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/368721) in GitLab 15.4). |
|
||||
| `/todo` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Add a to-do item. |
|
||||
| `/unapprove` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Unapprove the merge request. ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8103) in GitLab 14.3 |
|
||||
| `/unassign @user1 @user2` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Remove specific assignees. |
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ to a branch in the repository. When you use the command line, you can commit mul
|
|||
on their respective thread.
|
||||
- **Cherry-pick a commit:**
|
||||
In GitLab, you can
|
||||
[cherry-pick a commit](../merge_requests/cherry_pick_changes.md#cherry-pick-a-commit)
|
||||
[cherry-pick a commit](../merge_requests/cherry_pick_changes.md#cherry-pick-a-single-commit)
|
||||
from the UI.
|
||||
- **Revert a commit:**
|
||||
[Revert a commit](../merge_requests/revert_changes.md#revert-a-commit)
|
||||
|
|
|
|||
|
|
@ -317,6 +317,30 @@ module Gitlab
|
|||
command :remove_contacts do |contact_emails|
|
||||
@updates[:remove_contacts] = contact_emails.split(' ')
|
||||
end
|
||||
|
||||
desc { _('Add a timeline event to incident') }
|
||||
explanation { _('Adds a timeline event to incident.') }
|
||||
params '<timeline comment> | <date(YYYY-MM-DD)> <time(HH:MM)>'
|
||||
types Issue
|
||||
condition do
|
||||
quick_action_target.incident? &&
|
||||
current_user.can?(:admin_incident_management_timeline_event, quick_action_target)
|
||||
end
|
||||
parse_params do |event_params|
|
||||
Gitlab::QuickActions::TimelineTextAndDateTimeSeparator.new(event_params).execute
|
||||
end
|
||||
command :timeline do |event_text, date_time|
|
||||
if event_text && date_time
|
||||
timeline_event = timeline_event_create_service(event_text, date_time).execute
|
||||
|
||||
@execution_message[:timeline] =
|
||||
if timeline_event.success?
|
||||
_('Timeline event added successfully.')
|
||||
else
|
||||
_('Something went wrong while adding timeline event.')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -336,6 +360,10 @@ module Gitlab
|
|||
def merge_updates(result, update_hash)
|
||||
update_hash.merge!(result.payload) if result.payload
|
||||
end
|
||||
|
||||
def timeline_event_create_service(event_text, event_date_time)
|
||||
::IncidentManagement::TimelineEvents::CreateService.new(quick_action_target, current_user, { note: event_text, occurred_at: event_date_time, editable: true })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module QuickActions
|
||||
class TimelineTextAndDateTimeSeparator
|
||||
DATETIME_REGEX = %r{(\d{2,4}[\-.]\d{1,2}[\-.]\d{1,2} \d{1,2}:\d{2})}.freeze
|
||||
MIXED_DELIMITER = %r{([/.])}.freeze
|
||||
TIME_REGEX = %r{(\d{1,2}:\d{2})}.freeze
|
||||
|
||||
def initialize(timeline_event_arg)
|
||||
@timeline_event_arg = timeline_event_arg
|
||||
@timeline_text = get_text
|
||||
@timeline_date_string = get_raw_date_string
|
||||
end
|
||||
|
||||
def execute
|
||||
return if @timeline_event_arg.blank?
|
||||
return if date_contains_mixed_delimiters?
|
||||
return [@timeline_text, get_current_date_time] unless date_time_present?
|
||||
return unless valid_date?
|
||||
|
||||
[@timeline_text, get_actual_date_time]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_text
|
||||
@timeline_event_arg.split('|')[0]&.strip
|
||||
end
|
||||
|
||||
def get_raw_date_string
|
||||
@timeline_event_arg.split('|')[1]&.strip
|
||||
end
|
||||
|
||||
def get_current_date_time
|
||||
DateTime.current.strftime("%Y-%m-%d %H:%M:00 UTC")
|
||||
end
|
||||
|
||||
def get_actual_date_time
|
||||
DateTime.parse(@timeline_date_string)
|
||||
end
|
||||
|
||||
def date_time_present?
|
||||
DATETIME_REGEX =~ @timeline_date_string || TIME_REGEX =~ @timeline_date_string
|
||||
end
|
||||
|
||||
def date_contains_mixed_delimiters?
|
||||
MIXED_DELIMITER =~ @timeline_date_string
|
||||
end
|
||||
|
||||
def valid_date?
|
||||
get_actual_date_time
|
||||
rescue Date::Error
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -127,6 +127,10 @@
|
|||
category: quickactions
|
||||
redis_slot: quickactions
|
||||
aggregation: weekly
|
||||
- name: i_quickactions_timeline
|
||||
category: quickactions
|
||||
redis_slot: quickactions
|
||||
aggregation: weekly
|
||||
- name: i_quickactions_page
|
||||
category: quickactions
|
||||
redis_slot: quickactions
|
||||
|
|
|
|||
|
|
@ -29,10 +29,10 @@ module Sidebars
|
|||
override :pill_count
|
||||
def pill_count
|
||||
strong_memoize(:pill_count) do
|
||||
percentage = LearnGitlab::Onboarding.new(
|
||||
percentage = Onboarding::Completion.new(
|
||||
context.project.namespace,
|
||||
context.current_user
|
||||
).completed_percentage
|
||||
).percentage
|
||||
|
||||
"#{percentage}%"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2201,6 +2201,9 @@ msgstr ""
|
|||
msgid "Add a table"
|
||||
msgstr ""
|
||||
|
||||
msgid "Add a timeline event to incident"
|
||||
msgstr ""
|
||||
|
||||
msgid "Add a title..."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -2471,6 +2474,9 @@ msgstr ""
|
|||
msgid "Adds a Zoom meeting."
|
||||
msgstr ""
|
||||
|
||||
msgid "Adds a timeline event to incident."
|
||||
msgstr ""
|
||||
|
||||
msgid "Adds a to do."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -37111,6 +37117,9 @@ msgstr ""
|
|||
msgid "Something went wrong when reordering designs. Please try again"
|
||||
msgstr ""
|
||||
|
||||
msgid "Something went wrong while adding timeline event."
|
||||
msgstr ""
|
||||
|
||||
msgid "Something went wrong while adding your award. Please try again."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -40971,6 +40980,9 @@ msgstr ""
|
|||
msgid "Timeago|right now"
|
||||
msgstr ""
|
||||
|
||||
msgid "Timeline event added successfully."
|
||||
msgstr ""
|
||||
|
||||
msgid "Timeline|Turn recent updates view off"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -43386,9 +43398,15 @@ msgstr ""
|
|||
msgid "View all environments."
|
||||
msgstr ""
|
||||
|
||||
msgid "View all groups"
|
||||
msgstr ""
|
||||
|
||||
msgid "View all issues"
|
||||
msgstr ""
|
||||
|
||||
msgid "View all projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "View blame"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -53,28 +53,45 @@ module QA
|
|||
element :search_term_field
|
||||
end
|
||||
|
||||
view 'app/views/layouts/header/_new_dropdown.html.haml' do
|
||||
element :new_menu_toggle
|
||||
end
|
||||
|
||||
view 'app/helpers/nav/new_dropdown_helper.rb' do
|
||||
element :global_new_group_link
|
||||
element :global_new_project_link
|
||||
end
|
||||
|
||||
def go_to_groups
|
||||
within_groups_menu do
|
||||
click_element(:menu_item_link, title: 'Your groups')
|
||||
# Remove if statement once :remove_extra_primary_submenu_options ff is enabled by default
|
||||
if has_element?(:menu_item_link, title: 'Your groups')
|
||||
click_element(:menu_item_link, title: 'Your groups')
|
||||
else
|
||||
click_element(:menu_item_link, title: 'View all groups')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def go_to_create_group
|
||||
within_groups_menu do
|
||||
click_element(:menu_item_link, title: 'Create group')
|
||||
end
|
||||
click_element(:new_menu_toggle)
|
||||
click_element(:global_new_group_link)
|
||||
end
|
||||
|
||||
def go_to_projects
|
||||
within_projects_menu do
|
||||
click_element(:menu_item_link, title: 'Your projects')
|
||||
# Remove if statement once :remove_extra_primary_submenu_options ff is enabled by default
|
||||
if has_element?(:menu_item_link, title: 'Your projects')
|
||||
click_element(:menu_item_link, title: 'Your projects')
|
||||
else
|
||||
click_element(:menu_item_link, title: 'View all projects')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def go_to_create_project
|
||||
within_projects_menu do
|
||||
click_element(:menu_item_link, title: 'Create new project')
|
||||
end
|
||||
click_element(:new_menu_toggle)
|
||||
click_element(:global_new_project_link)
|
||||
end
|
||||
|
||||
def go_to_menu_dropdown_option(option_name)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ RSpec.describe 'Admin mode', :js do
|
|||
open_top_nav_projects
|
||||
|
||||
within_top_nav do
|
||||
click_link('Your projects')
|
||||
click_link('View all projects')
|
||||
end
|
||||
|
||||
expect(page).to have_current_path(dashboard_projects_path)
|
||||
|
|
@ -99,7 +99,7 @@ RSpec.describe 'Admin mode', :js do
|
|||
open_top_nav_projects
|
||||
|
||||
within_top_nav do
|
||||
click_link('Your projects')
|
||||
click_link('View all projects')
|
||||
end
|
||||
|
||||
expect(page).to have_current_path(dashboard_projects_path)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'Incidents > User uses quick actions', :js do
|
||||
include Spec::Support::Helpers::Features::NotesHelpers
|
||||
|
||||
describe 'incident-only commands' do
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:issue, reload: true) { create(:incident, project: project) }
|
||||
|
||||
before do
|
||||
project.add_developer(user)
|
||||
sign_in(user)
|
||||
visit project_issue_path(project, issue)
|
||||
wait_for_all_requests
|
||||
end
|
||||
|
||||
after do
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
it_behaves_like 'timeline quick action'
|
||||
end
|
||||
end
|
||||
|
|
@ -339,7 +339,7 @@ RSpec.describe 'User page' do
|
|||
|
||||
subject
|
||||
|
||||
page.within '.navbar-nav' do
|
||||
page.within '.navbar-gitlab' do
|
||||
expect(page).to have_link('Sign in')
|
||||
end
|
||||
end
|
||||
|
|
@ -351,7 +351,7 @@ RSpec.describe 'User page' do
|
|||
|
||||
subject
|
||||
|
||||
page.within '.navbar-nav' do
|
||||
page.within '.navbar-gitlab' do
|
||||
expect(page).to have_link('Sign in / Register')
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ RSpec.describe LearnGitlabHelper do
|
|||
include Devise::Test::ControllerHelpers
|
||||
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:project) { create(:project, name: LearnGitlab::Project::PROJECT_NAME, namespace: user.namespace) }
|
||||
let_it_be(:project) { create(:project, name: Onboarding::LearnGitlab::PROJECT_NAME, namespace: user.namespace) }
|
||||
let_it_be(:namespace) { project.namespace }
|
||||
|
||||
before do
|
||||
allow_next_instance_of(LearnGitlab::Project) do |learn_gitlab|
|
||||
allow_next_instance_of(Onboarding::LearnGitlab) do |learn_gitlab|
|
||||
allow(learn_gitlab).to receive(:project).and_return(project)
|
||||
end
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ RSpec.describe LearnGitlabHelper do
|
|||
with_them do
|
||||
before do
|
||||
allow(Onboarding::Progress).to receive(:onboarding?).with(project.namespace).and_return(onboarding)
|
||||
allow_next(LearnGitlab::Project, user).to receive(:available?).and_return(learn_gitlab_available)
|
||||
allow_next(Onboarding::LearnGitlab, user).to receive(:available?).and_return(learn_gitlab_available)
|
||||
end
|
||||
|
||||
context 'when signed in' do
|
||||
|
|
@ -81,7 +81,7 @@ RSpec.describe LearnGitlabHelper do
|
|||
|
||||
it 'has all section data', :aggregate_failures do
|
||||
expect(onboarding_sections_data.keys).to contain_exactly(:deploy, :plan, :workspace)
|
||||
expect(onboarding_sections_data.values.map { |section| section.keys }).to match_array([[:svg]] * 3)
|
||||
expect(onboarding_sections_data.values.map(&:keys)).to match_array([[:svg]] * 3)
|
||||
end
|
||||
|
||||
it 'has all project data', :aggregate_failures do
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ RSpec.describe Nav::NewDropdownHelper do
|
|||
id: 'general_new_group',
|
||||
title: 'New group',
|
||||
href: '/groups/new',
|
||||
data: { track_action: 'click_link_new_group', track_label: 'plus_menu_dropdown' }
|
||||
data: { qa_selector: 'global_new_group_link', track_action: 'click_link_new_group', track_label: 'plus_menu_dropdown' }
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -161,61 +161,87 @@ RSpec.describe Nav::TopNavHelper do
|
|||
::Gitlab::Nav::TopNavMenuItem.build(
|
||||
data: {
|
||||
qa_selector: 'menu_item_link',
|
||||
qa_title: 'Your projects',
|
||||
**menu_data_tracking_attrs('your_projects')
|
||||
qa_title: 'View all projects',
|
||||
**menu_data_tracking_attrs('view_all_projects')
|
||||
},
|
||||
href: '/dashboard/projects',
|
||||
id: 'your',
|
||||
title: 'Your projects'
|
||||
),
|
||||
::Gitlab::Nav::TopNavMenuItem.build(
|
||||
data: {
|
||||
qa_selector: 'menu_item_link',
|
||||
qa_title: 'Starred projects',
|
||||
**menu_data_tracking_attrs('starred_projects')
|
||||
},
|
||||
href: '/dashboard/projects/starred',
|
||||
id: 'starred',
|
||||
title: 'Starred projects'
|
||||
),
|
||||
::Gitlab::Nav::TopNavMenuItem.build(
|
||||
data: {
|
||||
qa_selector: 'menu_item_link',
|
||||
qa_title: 'Explore projects',
|
||||
**menu_data_tracking_attrs('explore_projects')
|
||||
},
|
||||
href: '/explore',
|
||||
id: 'explore',
|
||||
title: 'Explore projects'
|
||||
),
|
||||
::Gitlab::Nav::TopNavMenuItem.build(
|
||||
data: {
|
||||
qa_selector: 'menu_item_link',
|
||||
qa_title: 'Explore topics',
|
||||
**menu_data_tracking_attrs('explore_topics')
|
||||
},
|
||||
href: '/explore/projects/topics',
|
||||
id: 'topics',
|
||||
title: 'Explore topics'
|
||||
title: 'View all projects'
|
||||
)
|
||||
]
|
||||
expect(projects_view[:linksPrimary]).to eq(expected_links_primary)
|
||||
end
|
||||
|
||||
it 'has expected :linksSecondary' do
|
||||
expected_links_secondary = [
|
||||
::Gitlab::Nav::TopNavMenuItem.build(
|
||||
data: {
|
||||
qa_selector: 'menu_item_link',
|
||||
qa_title: 'Create new project',
|
||||
**menu_data_tracking_attrs('create_new_project')
|
||||
},
|
||||
href: '/projects/new',
|
||||
id: 'create',
|
||||
title: 'Create new project'
|
||||
)
|
||||
]
|
||||
expect(projects_view[:linksSecondary]).to eq(expected_links_secondary)
|
||||
it 'does not have any :linksSecondary' do
|
||||
expect(projects_view[:linksSecondary]).to eq([])
|
||||
end
|
||||
|
||||
context 'when extra submenu options are not hidden' do
|
||||
before do
|
||||
stub_feature_flags(remove_extra_primary_submenu_options: false)
|
||||
end
|
||||
|
||||
it 'has expected :linksPrimary' do
|
||||
expected_links_primary = [
|
||||
::Gitlab::Nav::TopNavMenuItem.build(
|
||||
data: {
|
||||
qa_selector: 'menu_item_link',
|
||||
qa_title: 'Your projects',
|
||||
**menu_data_tracking_attrs('your_projects')
|
||||
},
|
||||
href: '/dashboard/projects',
|
||||
id: 'your',
|
||||
title: 'Your projects'
|
||||
),
|
||||
::Gitlab::Nav::TopNavMenuItem.build(
|
||||
data: {
|
||||
qa_selector: 'menu_item_link',
|
||||
qa_title: 'Starred projects',
|
||||
**menu_data_tracking_attrs('starred_projects')
|
||||
},
|
||||
href: '/dashboard/projects/starred',
|
||||
id: 'starred',
|
||||
title: 'Starred projects'
|
||||
),
|
||||
::Gitlab::Nav::TopNavMenuItem.build(
|
||||
data: {
|
||||
qa_selector: 'menu_item_link',
|
||||
qa_title: 'Explore projects',
|
||||
**menu_data_tracking_attrs('explore_projects')
|
||||
},
|
||||
href: '/explore',
|
||||
id: 'explore',
|
||||
title: 'Explore projects'
|
||||
),
|
||||
::Gitlab::Nav::TopNavMenuItem.build(
|
||||
data: {
|
||||
qa_selector: 'menu_item_link',
|
||||
qa_title: 'Explore topics',
|
||||
**menu_data_tracking_attrs('explore_topics')
|
||||
},
|
||||
href: '/explore/projects/topics',
|
||||
id: 'topics',
|
||||
title: 'Explore topics'
|
||||
)
|
||||
]
|
||||
expect(projects_view[:linksPrimary]).to eq(expected_links_primary)
|
||||
end
|
||||
|
||||
it 'has expected :linksSecondary' do
|
||||
expected_links_secondary = [
|
||||
::Gitlab::Nav::TopNavMenuItem.build(
|
||||
data: {
|
||||
qa_selector: 'menu_item_link',
|
||||
qa_title: 'Create new project',
|
||||
**menu_data_tracking_attrs('create_new_project')
|
||||
},
|
||||
href: '/projects/new',
|
||||
id: 'create',
|
||||
title: 'Create new project'
|
||||
)
|
||||
]
|
||||
expect(projects_view[:linksSecondary]).to eq(expected_links_secondary)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with current nav as project' do
|
||||
|
|
@ -300,41 +326,67 @@ RSpec.describe Nav::TopNavHelper do
|
|||
::Gitlab::Nav::TopNavMenuItem.build(
|
||||
data: {
|
||||
qa_selector: 'menu_item_link',
|
||||
qa_title: 'Your groups',
|
||||
**menu_data_tracking_attrs('your_groups')
|
||||
qa_title: 'View all groups',
|
||||
**menu_data_tracking_attrs('view_all_groups')
|
||||
},
|
||||
href: '/dashboard/groups',
|
||||
id: 'your',
|
||||
title: 'Your groups'
|
||||
),
|
||||
::Gitlab::Nav::TopNavMenuItem.build(
|
||||
data: {
|
||||
qa_selector: 'menu_item_link',
|
||||
qa_title: 'Explore groups',
|
||||
**menu_data_tracking_attrs('explore_groups')
|
||||
},
|
||||
href: '/explore/groups',
|
||||
id: 'explore',
|
||||
title: 'Explore groups'
|
||||
title: 'View all groups'
|
||||
)
|
||||
]
|
||||
expect(groups_view[:linksPrimary]).to eq(expected_links_primary)
|
||||
end
|
||||
|
||||
it 'has expected :linksSecondary' do
|
||||
expected_links_secondary = [
|
||||
::Gitlab::Nav::TopNavMenuItem.build(
|
||||
data: {
|
||||
qa_selector: 'menu_item_link',
|
||||
qa_title: 'Create group',
|
||||
**menu_data_tracking_attrs('create_group')
|
||||
},
|
||||
href: '/groups/new',
|
||||
id: 'create',
|
||||
title: 'Create group'
|
||||
)
|
||||
]
|
||||
expect(groups_view[:linksSecondary]).to eq(expected_links_secondary)
|
||||
it 'does not have any :linksSecondary' do
|
||||
expect(groups_view[:linksSecondary]).to eq([])
|
||||
end
|
||||
|
||||
context 'when extra submenu options are not hidden' do
|
||||
before do
|
||||
stub_feature_flags(remove_extra_primary_submenu_options: false)
|
||||
end
|
||||
|
||||
it 'has expected :linksPrimary' do
|
||||
expected_links_primary = [
|
||||
::Gitlab::Nav::TopNavMenuItem.build(
|
||||
data: {
|
||||
qa_selector: 'menu_item_link',
|
||||
qa_title: 'Your groups',
|
||||
**menu_data_tracking_attrs('your_groups')
|
||||
},
|
||||
href: '/dashboard/groups',
|
||||
id: 'your',
|
||||
title: 'Your groups'
|
||||
),
|
||||
::Gitlab::Nav::TopNavMenuItem.build(
|
||||
data: {
|
||||
qa_selector: 'menu_item_link',
|
||||
qa_title: 'Explore groups',
|
||||
**menu_data_tracking_attrs('explore_groups')
|
||||
},
|
||||
href: '/explore/groups',
|
||||
id: 'explore',
|
||||
title: 'Explore groups'
|
||||
)
|
||||
]
|
||||
expect(groups_view[:linksPrimary]).to eq(expected_links_primary)
|
||||
end
|
||||
|
||||
it 'has expected :linksSecondary' do
|
||||
expected_links_secondary = [
|
||||
::Gitlab::Nav::TopNavMenuItem.build(
|
||||
data: {
|
||||
qa_selector: 'menu_item_link',
|
||||
qa_title: 'Create group',
|
||||
**menu_data_tracking_attrs('create_group')
|
||||
},
|
||||
href: '/groups/new',
|
||||
id: 'create',
|
||||
title: 'Create group'
|
||||
)
|
||||
]
|
||||
expect(groups_view[:linksSecondary]).to eq(expected_links_secondary)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with external user' do
|
||||
|
|
|
|||
|
|
@ -0,0 +1,94 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::QuickActions::TimelineTextAndDateTimeSeparator do
|
||||
subject(:timeline_text_and_datetime_separator) { described_class }
|
||||
|
||||
shared_examples 'arg line with invalid parameters' do
|
||||
it 'returns nil' do
|
||||
expect(timeline_text_and_datetime_separator.new(invalid_arg).execute).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'arg line with valid parameters' do
|
||||
it 'returns text and date time array' do
|
||||
freeze_time do
|
||||
expect(timeline_text_and_datetime_separator.new(valid_arg).execute).to eq(expected_response)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'execute' do
|
||||
context 'with invalid parameters in arg line' do
|
||||
context 'with empty arg line' do
|
||||
it_behaves_like 'arg line with invalid parameters' do
|
||||
let(:invalid_arg) { '' }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with invalid date' do
|
||||
it_behaves_like 'arg line with invalid parameters' do
|
||||
let(:invalid_arg) { 'timeline comment | 2022-13-13 09:30' }
|
||||
end
|
||||
|
||||
it_behaves_like 'arg line with invalid parameters' do
|
||||
let(:invalid_arg) { 'timeline comment | 2022-09/09 09:30' }
|
||||
end
|
||||
|
||||
it_behaves_like 'arg line with invalid parameters' do
|
||||
let(:invalid_arg) { 'timeline comment | 2022-09.09 09:30' }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with invalid time' do
|
||||
it_behaves_like 'arg line with invalid parameters' do
|
||||
let(:invalid_arg) { 'timeline comment | 2022-11-13 29:30' }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when date is invalid in arg line' do
|
||||
let(:invalid_arg) { 'timeline comment | wrong data type' }
|
||||
|
||||
it 'return current date' do
|
||||
timeline_args = timeline_text_and_datetime_separator.new(invalid_arg).execute
|
||||
|
||||
expect(timeline_args).to be_an_instance_of(Array)
|
||||
expect(timeline_args.first).to eq('timeline comment')
|
||||
expect(timeline_args.second).to match(Gitlab::QuickActions::TimelineTextAndDateTimeSeparator::DATETIME_REGEX)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with valid parameters' do
|
||||
context 'when only timeline text present in arg line' do
|
||||
it_behaves_like 'arg line with valid parameters' do
|
||||
let(:timeline_text) { 'timeline comment' }
|
||||
let(:valid_arg) { timeline_text }
|
||||
let(:date) { DateTime.current.strftime("%Y-%m-%d %H:%M:00 UTC") }
|
||||
let(:expected_response) { [timeline_text, date] }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when only timeline text and time present in arg line' do
|
||||
it_behaves_like 'arg line with valid parameters' do
|
||||
let(:timeline_text) { 'timeline comment' }
|
||||
let(:date) { '09:30' }
|
||||
let(:valid_arg) { "#{timeline_text} | #{date}" }
|
||||
let(:parsed_date) { DateTime.parse(date) }
|
||||
let(:expected_response) { [timeline_text, parsed_date] }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when timeline text and date is present in arg line' do
|
||||
it_behaves_like 'arg line with valid parameters' do
|
||||
let(:timeline_text) { 'timeline comment' }
|
||||
let(:date) { '2022-06-05 09:30' }
|
||||
let(:valid_arg) { "#{timeline_text} | #{date}" }
|
||||
let(:parsed_date) { DateTime.parse(date) }
|
||||
let(:expected_response) { [timeline_text, parsed_date] }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -68,13 +68,11 @@ RSpec.describe Sidebars::Projects::Menus::LearnGitlabMenu do
|
|||
end
|
||||
|
||||
describe '#pill_count' do
|
||||
before do
|
||||
expect_next_instance_of(LearnGitlab::Onboarding) do |onboarding|
|
||||
expect(onboarding).to receive(:completed_percentage).and_return(20)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns pill count' do
|
||||
expect_next_instance_of(Onboarding::Completion) do |onboarding|
|
||||
expect(onboarding).to receive(:percentage).and_return(20)
|
||||
end
|
||||
|
||||
expect(subject.pill_count).to eq '20%'
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -59,4 +59,13 @@ RSpec.describe Ci::FreezePeriodStatus do
|
|||
|
||||
it_behaves_like 'outside freeze period', Time.utc(2020, 4, 13, 8, 1)
|
||||
end
|
||||
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/370472
|
||||
context 'when period overlaps with itself' do
|
||||
let!(:freeze_period) { create(:ci_freeze_period, project: project, freeze_start: '* * * 8 *', freeze_end: '* * * 10 *') }
|
||||
|
||||
it_behaves_like 'within freeze period', Time.utc(2020, 8, 11, 0, 0)
|
||||
|
||||
it_behaves_like 'outside freeze period', Time.utc(2020, 10, 11, 0, 0)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,13 +2,11 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe LearnGitlab::Onboarding do
|
||||
describe '#completed_percentage' do
|
||||
RSpec.describe Onboarding::Completion do
|
||||
describe '#percentage' do
|
||||
let(:completed_actions) { {} }
|
||||
let(:onboarding_progress) { build(:onboarding_progress, namespace: namespace, **completed_actions) }
|
||||
let(:namespace) { create(:namespace) }
|
||||
|
||||
let_it_be(:tracked_action_columns) do
|
||||
let!(:onboarding_progress) { create(:onboarding_progress, namespace: namespace, **completed_actions) }
|
||||
let(:tracked_action_columns) do
|
||||
[
|
||||
*described_class::ACTION_ISSUE_IDS.keys,
|
||||
*described_class::ACTION_PATHS,
|
||||
|
|
@ -16,14 +14,12 @@ RSpec.describe LearnGitlab::Onboarding do
|
|||
].map { |key| ::Onboarding::Progress.column_name(key) }
|
||||
end
|
||||
|
||||
before do
|
||||
expect(::Onboarding::Progress).to receive(:find_by).with(namespace: namespace).and_return(onboarding_progress)
|
||||
end
|
||||
let_it_be(:namespace) { create(:namespace) }
|
||||
|
||||
subject { described_class.new(namespace).completed_percentage }
|
||||
subject { described_class.new(namespace).percentage }
|
||||
|
||||
context 'when no onboarding_progress exists' do
|
||||
let(:onboarding_progress) { nil }
|
||||
subject { described_class.new(build(:namespace)).percentage }
|
||||
|
||||
it { is_expected.to eq(0) }
|
||||
end
|
||||
|
|
@ -34,13 +30,13 @@ RSpec.describe LearnGitlab::Onboarding do
|
|||
|
||||
context 'when all tracked actions have been completed' do
|
||||
let(:completed_actions) do
|
||||
tracked_action_columns.to_h { |action| [action, Time.current] }
|
||||
tracked_action_columns.index_with { Time.current }
|
||||
end
|
||||
|
||||
it { is_expected.to eq(100) }
|
||||
end
|
||||
|
||||
describe 'security_actions_continuous_onboarding experiment' do
|
||||
context 'with security_actions_continuous_onboarding experiment' do
|
||||
let(:completed_actions) { Hash[tracked_action_columns.first, Time.current] }
|
||||
|
||||
context 'when control' do
|
||||
|
|
@ -2,17 +2,17 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe LearnGitlab::Project do
|
||||
RSpec.describe Onboarding::LearnGitlab do
|
||||
let_it_be(:current_user) { create(:user) }
|
||||
let_it_be(:learn_gitlab_project) { create(:project, name: LearnGitlab::Project::PROJECT_NAME) }
|
||||
let_it_be(:learn_gitlab_board) { create(:board, project: learn_gitlab_project, name: LearnGitlab::Project::BOARD_NAME) }
|
||||
let_it_be(:learn_gitlab_label) { create(:label, project: learn_gitlab_project, name: LearnGitlab::Project::LABEL_NAME) }
|
||||
let_it_be(:learn_gitlab_project) { create(:project, name: described_class::PROJECT_NAME) }
|
||||
let_it_be(:learn_gitlab_board) { create(:board, project: learn_gitlab_project, name: described_class::BOARD_NAME) }
|
||||
let_it_be(:learn_gitlab_label) { create(:label, project: learn_gitlab_project, name: described_class::LABEL_NAME) }
|
||||
|
||||
before do
|
||||
learn_gitlab_project.add_developer(current_user)
|
||||
end
|
||||
|
||||
describe '.available?' do
|
||||
describe '#available?' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
where(:project, :board, :label, :expected_result) do
|
||||
|
|
@ -41,25 +41,27 @@ RSpec.describe LearnGitlab::Project do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.project' do
|
||||
describe '#project' do
|
||||
subject { described_class.new(current_user).project }
|
||||
|
||||
it { is_expected.to eq learn_gitlab_project }
|
||||
|
||||
context 'when it is created during trial signup' do
|
||||
let_it_be(:learn_gitlab_project) { create(:project, name: LearnGitlab::Project::PROJECT_NAME_ULTIMATE_TRIAL, path: 'learn-gitlab-ultimate-trial') }
|
||||
let_it_be(:learn_gitlab_project) do
|
||||
create(:project, name: described_class::PROJECT_NAME_ULTIMATE_TRIAL, path: 'learn-gitlab-ultimate-trial')
|
||||
end
|
||||
|
||||
it { is_expected.to eq learn_gitlab_project }
|
||||
end
|
||||
end
|
||||
|
||||
describe '.board' do
|
||||
describe '#board' do
|
||||
subject { described_class.new(current_user).board }
|
||||
|
||||
it { is_expected.to eq learn_gitlab_board }
|
||||
end
|
||||
|
||||
describe '.label' do
|
||||
describe '#label' do
|
||||
subject { described_class.new(current_user).label }
|
||||
|
||||
it { is_expected.to eq learn_gitlab_label }
|
||||
|
|
@ -537,7 +537,6 @@
|
|||
- './ee/spec/features/trials/capture_lead_spec.rb'
|
||||
- './ee/spec/features/trials/select_namespace_spec.rb'
|
||||
- './ee/spec/features/trials/show_trial_banner_spec.rb'
|
||||
- './ee/spec/features/uncompleted_learn_gitlab_link_spec.rb'
|
||||
- './ee/spec/features/users/arkose_labs_csp_spec.rb'
|
||||
- './ee/spec/features/users/login_spec.rb'
|
||||
- './ee/spec/features/users/signup_spec.rb'
|
||||
|
|
@ -5459,7 +5458,6 @@
|
|||
- './spec/helpers/keyset_helper_spec.rb'
|
||||
- './spec/helpers/labels_helper_spec.rb'
|
||||
- './spec/helpers/lazy_image_tag_helper_spec.rb'
|
||||
- './spec/helpers/learn_gitlab_helper_spec.rb'
|
||||
- './spec/helpers/listbox_helper_spec.rb'
|
||||
- './spec/helpers/markup_helper_spec.rb'
|
||||
- './spec/helpers/members_helper_spec.rb'
|
||||
|
|
@ -7756,8 +7754,6 @@
|
|||
- './spec/lib/json_web_token/token_spec.rb'
|
||||
- './spec/lib/kramdown/kramdown_spec.rb'
|
||||
- './spec/lib/kramdown/parser/atlassian_document_format_spec.rb'
|
||||
- './spec/lib/learn_gitlab/onboarding_spec.rb'
|
||||
- './spec/lib/learn_gitlab/project_spec.rb'
|
||||
- './spec/lib/marginalia_spec.rb'
|
||||
- './spec/lib/mattermost/client_spec.rb'
|
||||
- './spec/lib/mattermost/command_spec.rb'
|
||||
|
|
@ -7824,7 +7820,6 @@
|
|||
- './spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb'
|
||||
- './spec/lib/sidebars/projects/menus/invite_team_members_menu_spec.rb'
|
||||
- './spec/lib/sidebars/projects/menus/issues_menu_spec.rb'
|
||||
- './spec/lib/sidebars/projects/menus/learn_gitlab_menu_spec.rb'
|
||||
- './spec/lib/sidebars/projects/menus/merge_requests_menu_spec.rb'
|
||||
- './spec/lib/sidebars/projects/menus/monitor_menu_spec.rb'
|
||||
- './spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.shared_examples 'timeline quick action' do
|
||||
describe '/timeline' do
|
||||
context 'with valid args' do
|
||||
where(:timeline_text, :date_time_arg) do
|
||||
[
|
||||
['timeline comment', '2022-09-09 09:30'],
|
||||
['new timeline comment', '09:30'],
|
||||
['another timeline comment', ' 2022-09-09 09:15']
|
||||
]
|
||||
end
|
||||
|
||||
with_them do
|
||||
it 'adds a timeline event' do
|
||||
add_note("/timeline #{timeline_text} | #{date_time_arg}")
|
||||
|
||||
expect(page).to have_content('Timeline event added successfully.')
|
||||
expect(issue.incident_management_timeline_events.first.note).to eq(timeline_text)
|
||||
expect(issue.incident_management_timeline_events.first.occurred_at).to eq(DateTime.parse(date_time_arg))
|
||||
end
|
||||
end
|
||||
|
||||
it 'adds a timeline event when no date is passed' do
|
||||
freeze_time do
|
||||
add_note('/timeline timeline event with not date')
|
||||
|
||||
expect(page).to have_content('Timeline event added successfully.')
|
||||
expect(issue.incident_management_timeline_events.first.note).to eq('timeline event with not date')
|
||||
expect(issue.incident_management_timeline_events.first.occurred_at).to eq(DateTime
|
||||
.current.strftime("%Y-%m-%d %H:%M:00 UTC"))
|
||||
end
|
||||
end
|
||||
|
||||
it 'adds a timeline event when only date is passed' do
|
||||
freeze_time do
|
||||
add_note('/timeline timeline event with not date | 2022-10-11')
|
||||
|
||||
expect(page).to have_content('Timeline event added successfully.')
|
||||
expect(issue.incident_management_timeline_events.first.note).to eq('timeline event with not date')
|
||||
expect(issue.incident_management_timeline_events.first.occurred_at).to eq(DateTime
|
||||
.current.strftime("%Y-%m-%d %H:%M:00 UTC"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with invalid args' do
|
||||
where(:timeline_text, :date_time_arg) do
|
||||
[
|
||||
['timeline comment', '2022-13-13 09:30'],
|
||||
['timeline comment 2', '2022-09-06 24:30']
|
||||
]
|
||||
end
|
||||
|
||||
with_them do
|
||||
it 'does not add a timeline event' do
|
||||
add_note("/timeline #{timeline_text} | #{date_time_arg}")
|
||||
|
||||
expect(page).to have_content('Failed to apply commands.')
|
||||
expect(issue.incident_management_timeline_events.length).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when create service fails' do
|
||||
before do
|
||||
allow_next_instance_of(::IncidentManagement::TimelineEvents::CreateService) do |service|
|
||||
allow(service).to receive(:execute).and_return(
|
||||
ServiceResponse.error(payload: { timeline_event: nil }, message: 'Some error')
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not add a timeline event' do
|
||||
add_note('/timeline text | 2022-09-10 09:30')
|
||||
|
||||
expect(page).to have_content('Something went wrong while adding timeline event.')
|
||||
expect(issue.incident_management_timeline_events.length).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -70,8 +70,8 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
|
|||
describe 'Learn GitLab' do
|
||||
it 'has a link to the learn GitLab' do
|
||||
allow(view).to receive(:learn_gitlab_enabled?).and_return(true)
|
||||
allow_next_instance_of(LearnGitlab::Onboarding) do |onboarding|
|
||||
expect(onboarding).to receive(:completed_percentage).and_return(20)
|
||||
allow_next_instance_of(Onboarding::Completion) do |onboarding|
|
||||
expect(onboarding).to receive(:percentage).and_return(20)
|
||||
end
|
||||
|
||||
render
|
||||
|
|
|
|||
Loading…
Reference in New Issue