Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
48166eb0
Commit
48166eb0
authored
Oct 28, 2021
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab master
parents
10d28998
b829ab9f
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
421 additions
and
78 deletions
+421
-78
.rubocop_manual_todo.yml
.rubocop_manual_todo.yml
+0
-1
app/controllers/projects/branches_controller.rb
app/controllers/projects/branches_controller.rb
+1
-2
app/helpers/learn_gitlab_helper.rb
app/helpers/learn_gitlab_helper.rb
+21
-1
app/models/ci/build_metadata.rb
app/models/ci/build_metadata.rb
+9
-0
app/models/concerns/ci/metadatable.rb
app/models/concerns/ci/metadatable.rb
+2
-0
app/models/uploads/fog.rb
app/models/uploads/fog.rb
+11
-3
config/feature_flags/experiment/change_continuous_onboarding_link_urls.yml
...ags/experiment/change_continuous_onboarding_link_urls.yml
+8
-0
ee/app/finders/epics_finder.rb
ee/app/finders/epics_finder.rb
+12
-2
ee/app/graphql/resolvers/epic_ancestors_resolver.rb
ee/app/graphql/resolvers/epic_ancestors_resolver.rb
+7
-1
ee/app/helpers/ee/learn_gitlab_helper.rb
ee/app/helpers/ee/learn_gitlab_helper.rb
+29
-0
ee/app/models/ee/epic.rb
ee/app/models/ee/epic.rb
+2
-2
ee/spec/finders/epics_finder_spec.rb
ee/spec/finders/epics_finder_spec.rb
+37
-20
ee/spec/graphql/resolvers/epic_ancestors_resolver_spec.rb
ee/spec/graphql/resolvers/epic_ancestors_resolver_spec.rb
+2
-2
ee/spec/helpers/ee/learn_gitlab_helper_spec.rb
ee/spec/helpers/ee/learn_gitlab_helper_spec.rb
+71
-0
ee/spec/models/epic_spec.rb
ee/spec/models/epic_spec.rb
+17
-9
ee/spec/requests/api/graphql/epics/epic_resolver_spec.rb
ee/spec/requests/api/graphql/epics/epic_resolver_spec.rb
+33
-0
spec/controllers/projects/branches_controller_spec.rb
spec/controllers/projects/branches_controller_spec.rb
+3
-3
spec/helpers/learn_gitlab_helper_spec.rb
spec/helpers/learn_gitlab_helper_spec.rb
+101
-27
spec/models/ci/build_metadata_spec.rb
spec/models/ci/build_metadata_spec.rb
+12
-0
spec/models/ci/build_spec.rb
spec/models/ci/build_spec.rb
+21
-0
spec/models/uploads/fog_spec.rb
spec/models/uploads/fog_spec.rb
+22
-5
No files found.
.rubocop_manual_todo.yml
View file @
48166eb0
...
...
@@ -32,7 +32,6 @@ Rails/SaveBang:
-
'
ee/spec/models/approval_project_rule_spec.rb'
-
'
ee/spec/models/burndown_spec.rb'
-
'
ee/spec/models/elasticsearch_indexed_namespace_spec.rb'
-
'
ee/spec/models/epic_spec.rb'
-
'
ee/spec/models/gitlab_subscription_spec.rb'
-
'
ee/spec/models/issue_spec.rb'
-
'
ee/spec/models/label_note_spec.rb'
...
...
app/controllers/projects/branches_controller.rb
View file @
48166eb0
...
...
@@ -105,8 +105,7 @@ class Projects::BranchesController < Projects::ApplicationController
# rubocop: enable CodeReuse/ActiveRecord
def
destroy
@branch_name
=
Addressable
::
URI
.
unescape
(
params
[
:id
])
result
=
::
Branches
::
DeleteService
.
new
(
project
,
current_user
).
execute
(
@branch_name
)
result
=
::
Branches
::
DeleteService
.
new
(
project
,
current_user
).
execute
(
params
[
:id
])
respond_to
do
|
format
|
format
.
html
do
...
...
app/helpers/learn_gitlab_helper.rb
View file @
48166eb0
...
...
@@ -10,7 +10,14 @@ module LearnGitlabHelper
def
onboarding_actions_data
(
project
)
attributes
=
onboarding_progress
(
project
).
attributes
.
symbolize_keys
action_urls
.
to_h
do
|
action
,
url
|
urls_to_use
=
nil
experiment
(
:change_continuous_onboarding_link_urls
)
do
|
e
|
e
.
use
{
urls_to_use
=
action_urls
}
e
.
try
{
urls_to_use
=
new_action_urls
(
project
)
}
end
urls_to_use
.
to_h
do
|
action
,
url
|
[
action
,
url:
url
,
...
...
@@ -46,6 +53,17 @@ module LearnGitlabHelper
.
merge
(
LearnGitlab
::
Onboarding
::
ACTION_DOC_URLS
)
end
def
new_action_urls
(
project
)
action_urls
.
merge
(
issue_created:
project_issues_path
(
project
),
git_write:
project_path
(
project
),
pipeline_created:
project_pipelines_path
(
project
),
merge_request_created:
project_merge_requests_path
(
project
),
user_added:
project_members_url
(
project
),
security_scan_enabled:
project_security_configuration_path
(
project
)
)
end
def
learn_gitlab_project
@learn_gitlab_project
||=
LearnGitlab
::
Project
.
new
(
current_user
).
project
end
...
...
@@ -54,3 +72,5 @@ module LearnGitlabHelper
OnboardingProgress
.
find_by
(
namespace:
project
.
namespace
)
# rubocop: disable CodeReuse/ActiveRecord
end
end
LearnGitlabHelper
.
prepend_mod_with
(
'LearnGitlabHelper'
)
app/models/ci/build_metadata.rb
View file @
48166eb0
...
...
@@ -23,6 +23,7 @@ module Ci
serialize
:config_options
,
Serializers
::
SymbolizedJson
# rubocop:disable Cop/ActiveRecordSerialize
serialize
:config_variables
,
Serializers
::
SymbolizedJson
# rubocop:disable Cop/ActiveRecordSerialize
serialize
:runtime_runner_features
,
Serializers
::
SymbolizedJson
# rubocop:disable Cop/ActiveRecordSerialize
chronic_duration_attr_reader
:timeout_human_readable
,
:timeout
...
...
@@ -47,6 +48,14 @@ module Ci
update
(
timeout:
timeout
.
value
,
timeout_source:
timeout
.
source
)
end
def
set_cancel_gracefully
runtime_runner_features
.
merge!
(
{
cancel_gracefully:
true
}
)
end
def
cancel_gracefully?
runtime_runner_features
[
:cancel_gracefully
]
==
true
end
private
def
set_build_project
...
...
app/models/concerns/ci/metadatable.rb
View file @
48166eb0
...
...
@@ -20,6 +20,8 @@ module Ci
delegate
:interruptible
,
to: :metadata
,
prefix:
false
,
allow_nil:
true
delegate
:has_exposed_artifacts?
,
to: :metadata
,
prefix:
false
,
allow_nil:
true
delegate
:environment_auto_stop_in
,
to: :metadata
,
prefix:
false
,
allow_nil:
true
delegate
:set_cancel_gracefully
,
to: :metadata
,
prefix:
false
,
allow_nil:
false
delegate
:cancel_gracefully?
,
to: :metadata
,
prefix:
false
,
allow_nil:
false
before_create
:ensure_metadata
end
...
...
app/models/uploads/fog.rb
View file @
48166eb0
...
...
@@ -15,13 +15,21 @@ module Uploads
end
def
delete_keys
(
keys
)
keys
.
each
do
|
key
|
connection
.
delete_object
(
bucket_name
,
key
)
end
keys
.
each
{
|
key
|
delete_object
(
key
)
}
end
private
def
delete_object
(
key
)
connection
.
delete_object
(
bucket_name
,
key
)
# So far, only GoogleCloudStorage raises an exception when the file is not found.
# Other providers support idempotent requests and does not raise an error
# when the file is missing.
rescue
::
Google
::
Apis
::
ClientError
=>
e
Gitlab
::
ErrorTracking
.
log_exception
(
e
)
end
def
object_store
Gitlab
.
config
.
uploads
.
object_store
end
...
...
config/feature_flags/experiment/change_continuous_onboarding_link_urls.yml
0 → 100644
View file @
48166eb0
---
name
:
change_continuous_onboarding_link_urls
introduced_by_url
:
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71408
rollout_issue_url
:
milestone
:
'
14.5'
type
:
experiment
group
:
group::conversion
default_enabled
:
false
ee/app/finders/epics_finder.rb
View file @
48166eb0
...
...
@@ -27,6 +27,7 @@
# include_descendant_groups: boolean
# starts_with_iid: string (containing a number)
# confidential: boolean
# hierarchy_order: :desc or :acs, default :acs when searched by child_id
class
EpicsFinder
<
IssuableFinder
include
TimeFrameFilter
...
...
@@ -198,8 +199,10 @@ class EpicsFinder < IssuableFinder
def
by_child
(
items
)
return
items
unless
child_id?
ancestor_ids
=
Epic
.
find
(
params
[
:child_id
]).
ancestors
.
reselect
(
:id
)
items
.
where
(
id:
ancestor_ids
)
hierarchy_order
=
params
[
:hierarchy_order
]
||
:asc
ancestors
=
Epic
.
find
(
params
[
:child_id
]).
ancestors
(
hierarchy_order:
hierarchy_order
)
ancestors
.
where
(
id:
items
.
select
(
:id
))
end
# rubocop: enable CodeReuse/ActiveRecord
...
...
@@ -272,4 +275,11 @@ class EpicsFinder < IssuableFinder
def
feature_flag_scope
params
.
group
end
override
:sort
def
sort
(
items
)
return
items
if
params
[
:hierarchy_order
]
super
end
end
ee/app/graphql/resolvers/epic_ancestors_resolver.rb
View file @
48166eb0
...
...
@@ -9,12 +9,18 @@ module Resolvers
description:
'Include epics from ancestor groups.'
,
default_value:
true
def
resolve_with_lookahead
(
**
args
)
items
=
super
offset_pagination
(
items
)
end
private
def
relative_param
return
{}
unless
parent
{
child_id:
parent
.
id
}
{
child_id:
parent
.
id
,
hierarchy_order: :desc
}
end
end
end
ee/app/helpers/ee/learn_gitlab_helper.rb
0 → 100644
View file @
48166eb0
# frozen_string_literal: true
module
EE
module
LearnGitlabHelper
extend
::
Gitlab
::
Utils
::
Override
GITLAB_COM
=
'gitlab.com'
ONBOARDING_START_TRIAL
=
'onboarding-start-trial'
ONBOARDING_REQUIRE_MR_APPROVALS
=
'onboarding-require-merge-approvals'
ONBOARDING_CODE_OWNERS
=
'onboarding-code-owners'
private
override
:new_action_urls
def
new_action_urls
(
project
)
urls
=
super
(
project
)
return
urls
unless
::
Gitlab
::
CurrentSettings
.
should_check_namespace_plan?
glm_params
=
{
glm_source:
GITLAB_COM
}
urls
.
merge
(
trial_started:
new_trial_path
(
glm_params
.
merge
(
glm_content:
ONBOARDING_START_TRIAL
)),
required_mr_approvals_enabled:
new_trial_path
(
glm_params
.
merge
(
glm_content:
ONBOARDING_REQUIRE_MR_APPROVALS
)),
code_owners_enabled:
new_trial_path
(
glm_params
.
merge
(
glm_content:
ONBOARDING_CODE_OWNERS
))
)
end
end
end
ee/app/models/ee/epic.rb
View file @
48166eb0
...
...
@@ -425,10 +425,10 @@ module EE
end
end
def
ancestors
def
ancestors
(
hierarchy_order: :asc
)
return
self
.
class
.
none
unless
parent_id
hierarchy
.
ancestors
(
hierarchy_order:
:asc
)
hierarchy
.
ancestors
(
hierarchy_order:
hierarchy_order
)
end
def
max_hierarchy_depth_achieved?
...
...
ee/spec/finders/epics_finder_spec.rb
View file @
48166eb0
...
...
@@ -9,8 +9,9 @@ RSpec.describe EpicsFinder do
let_it_be
(
:another_group
)
{
create
(
:group
)
}
let_it_be
(
:reference_time
)
{
Time
.
parse
(
'2020-09-15 01:00'
)
}
# Arbitrary time used for time/date range filters
let_it_be
(
:epic1
)
{
create
(
:epic
,
:opened
,
group:
group
,
title:
'This is awesome epic'
,
created_at:
1
.
week
.
before
(
reference_time
),
end_date:
10
.
days
.
before
(
reference_time
))
}
let_it_be
(
:epic2
)
{
create
(
:epic
,
:opened
,
group:
group
,
created_at:
4
.
days
.
before
(
reference_time
),
author:
user
,
start_date:
2
.
days
.
before
(
reference_time
),
end_date:
3
.
days
.
since
(
reference_time
),
parent:
epic1
)
}
let_it_be
(
:epic3
)
{
create
(
:epic
,
:closed
,
group:
group
,
description:
'not so awesome'
,
start_date:
5
.
days
.
before
(
reference_time
),
end_date:
3
.
days
.
before
(
reference_time
),
parent:
epic2
)
}
let_it_be
(
:epic3
,
reload:
true
)
{
create
(
:epic
,
:closed
,
group:
group
,
description:
'not so awesome'
,
start_date:
5
.
days
.
before
(
reference_time
),
end_date:
3
.
days
.
before
(
reference_time
))
}
let_it_be
(
:epic2
,
reload:
true
)
{
create
(
:epic
,
:opened
,
group:
group
,
created_at:
4
.
days
.
before
(
reference_time
),
author:
user
,
start_date:
2
.
days
.
before
(
reference_time
),
end_date:
3
.
days
.
since
(
reference_time
))
}
let_it_be
(
:epic5
)
{
create
(
:epic
,
group:
group
,
start_date:
6
.
days
.
before
(
reference_time
),
end_date:
6
.
days
.
before
(
reference_time
),
parent:
epic3
)
}
let_it_be
(
:epic4
)
{
create
(
:epic
,
:closed
,
group:
another_group
)
}
describe
'#execute'
do
...
...
@@ -55,7 +56,7 @@ RSpec.describe EpicsFinder do
end
it
'returns all epics that belong to the given group'
do
expect
(
epics
).
to
contain_exactly
(
epic1
,
epic2
,
epic3
)
expect
(
epics
).
to
contain_exactly
(
epic1
,
epic2
,
epic3
,
epic5
)
end
it
'does not execute more than 5 SQL queries'
do
...
...
@@ -64,11 +65,11 @@ RSpec.describe EpicsFinder do
context
'sorting'
do
it
'sorts correctly when supported sorting param provided'
do
expect
(
epics
(
sort: :start_date_asc
)).
to
eq
([
epic3
,
epic2
,
epic1
])
expect
(
epics
(
sort: :start_date_asc
)).
to
eq
([
epic
5
,
epic
3
,
epic2
,
epic1
])
end
it
'sorts by id when not supported sorting param provided'
do
expect
(
epics
(
sort: :not_supported_param
)).
to
eq
([
epic
3
,
epic2
,
epic1
])
expect
(
epics
(
sort: :not_supported_param
)).
to
eq
([
epic
5
,
epic2
,
epic3
,
epic1
])
end
end
...
...
@@ -78,7 +79,7 @@ RSpec.describe EpicsFinder do
end
it
'returns all epics created after the given date'
do
expect
(
epics
(
created_after:
2
.
days
.
before
(
reference_time
))).
to
contain_exactly
(
epic3
)
expect
(
epics
(
created_after:
2
.
days
.
before
(
reference_time
))).
to
contain_exactly
(
epic3
,
epic5
)
end
it
'returns all epics created within the given interval'
do
...
...
@@ -146,7 +147,7 @@ RSpec.describe EpicsFinder do
end
it
'does not add any filter'
do
expect
(
epics
(
or:
{
author_username:
[
epic2
.
author
.
username
,
epic3
.
author
.
username
]
})).
to
contain_exactly
(
epic1
,
epic2
,
epic3
)
expect
(
epics
(
or:
{
author_username:
[
epic2
.
author
.
username
,
epic3
.
author
.
username
]
})).
to
contain_exactly
(
epic1
,
epic2
,
epic3
,
epic5
)
end
end
end
...
...
@@ -195,7 +196,7 @@ RSpec.describe EpicsFinder do
end
it
'returns all epics that belong to the given group and its subgroups'
do
expect
(
epics
).
to
contain_exactly
(
epic1
,
epic2
,
epic3
,
subgroup_epic
,
subgroup2_epic
)
expect
(
epics
).
to
contain_exactly
(
epic1
,
epic2
,
epic3
,
subgroup_epic
,
subgroup2_epic
,
epic5
)
end
describe
'hierarchy params'
do
...
...
@@ -223,7 +224,7 @@ RSpec.describe EpicsFinder do
subject
{
finder
.
execute
}
it
'gets only epics from the project ancestor groups'
do
is_expected
.
to
contain_exactly
(
epic1
,
epic2
,
epic3
,
subgroup3_epic
)
is_expected
.
to
contain_exactly
(
epic1
,
epic2
,
epic3
,
subgroup3_epic
,
epic5
)
end
end
...
...
@@ -237,7 +238,7 @@ RSpec.describe EpicsFinder do
context
'and include_ancestor_groups is true'
do
let
(
:finder_params
)
{
{
include_descendant_groups:
false
,
include_ancestor_groups:
true
}
}
it
{
is_expected
.
to
contain_exactly
(
subgroup_epic
,
epic1
,
epic2
,
epic3
)
}
it
{
is_expected
.
to
contain_exactly
(
subgroup_epic
,
epic1
,
epic2
,
epic3
,
epic5
)
}
context
"when user does not have permission to view ancestor groups"
do
let
(
:finder_params
)
{
{
group_id:
subgroup
.
id
,
include_descendant_groups:
false
,
include_ancestor_groups:
true
}
}
...
...
@@ -259,7 +260,7 @@ RSpec.describe EpicsFinder do
context
'and include_ancestor_groups is true'
do
let
(
:finder_params
)
{
{
include_ancestor_groups:
true
}
}
it
{
is_expected
.
to
contain_exactly
(
subgroup_epic
,
subgroup2_epic
,
epic1
,
epic2
,
epic3
)
}
it
{
is_expected
.
to
contain_exactly
(
subgroup_epic
,
subgroup2_epic
,
epic1
,
epic2
,
epic3
,
epic5
)
}
context
"when user does not have permission to view ancestor groups"
do
let
(
:finder_params
)
{
{
group_id:
subgroup
.
id
,
include_ancestor_groups:
true
}
}
...
...
@@ -344,6 +345,11 @@ RSpec.describe EpicsFinder do
end
context
'by parent'
do
before
do
epic3
.
update!
(
parent_id:
epic2
.
id
)
epic2
.
update!
(
parent_id:
epic1
.
id
)
end
it
'returns direct children of the parent'
do
params
=
{
parent_id:
epic1
.
id
}
...
...
@@ -352,10 +358,21 @@ RSpec.describe EpicsFinder do
end
context
'by child'
do
it
'returns ancestors of the child epic'
do
params
=
{
child_id:
epic3
.
id
}
before
do
epic3
.
update!
(
parent_id:
epic2
.
id
)
epic2
.
update!
(
parent_id:
epic1
.
id
)
end
expect
(
epics
(
params
)).
to
contain_exactly
(
epic1
,
epic2
)
it
'returns ancestors of the child epic ordered from the bottom'
do
params
=
{
child_id:
epic5
.
id
,
hierarchy_order: :asc
}
expect
(
epics
(
params
)).
to
eq
([
epic3
,
epic2
,
epic1
])
end
it
'returns ancestors of the child epic ordered from the top if requested'
do
params
=
{
child_id:
epic5
.
id
,
hierarchy_order: :desc
}
expect
(
epics
(
params
)).
to
eq
([
epic1
,
epic2
,
epic3
])
end
end
...
...
@@ -741,11 +758,11 @@ RSpec.describe EpicsFinder do
let_it_be
(
:params
)
{
{
not:
{
label_name:
[
label
.
title
,
label2
.
title
].
join
(
','
)
}
}
}
it
'returns all epics if no negated labels are present'
do
expect
(
epics
).
to
contain_exactly
(
negated_epic
,
negated_epic2
,
epic1
,
epic2
,
epic3
)
expect
(
epics
).
to
contain_exactly
(
negated_epic
,
negated_epic2
,
epic1
,
epic2
,
epic3
,
epic5
)
end
it
'returns all epics without negated label'
do
expect
(
epics
(
params
)).
to
contain_exactly
(
epic1
,
epic2
,
epic3
)
expect
(
epics
(
params
)).
to
contain_exactly
(
epic1
,
epic2
,
epic3
,
epic5
)
end
end
...
...
@@ -755,11 +772,11 @@ RSpec.describe EpicsFinder do
let_it_be
(
:params
)
{
{
not:
{
author_id:
author
.
id
}
}
}
it
'returns all epics if no negated author is present'
do
expect
(
epics
).
to
contain_exactly
(
authored_epic
,
epic1
,
epic2
,
epic3
)
expect
(
epics
).
to
contain_exactly
(
authored_epic
,
epic1
,
epic2
,
epic3
,
epic5
)
end
it
'returns all epics without given author'
do
expect
(
epics
(
params
)).
to
contain_exactly
(
epic1
,
epic2
,
epic3
)
expect
(
epics
(
params
)).
to
contain_exactly
(
epic1
,
epic2
,
epic3
,
epic5
)
end
end
...
...
@@ -768,7 +785,7 @@ RSpec.describe EpicsFinder do
let_it_be
(
:params
)
{
{
not:
{
my_reaction_emoji:
awarded_emoji
.
name
}
}
}
it
'returns all epics without given emoji name'
do
expect
(
epics
(
params
)).
to
contain_exactly
(
epic1
,
epic2
)
expect
(
epics
(
params
)).
to
contain_exactly
(
epic1
,
epic2
,
epic5
)
end
end
end
...
...
@@ -820,7 +837,7 @@ RSpec.describe EpicsFinder do
it
'returns correct counts'
do
results
=
described_class
.
new
(
search_user
,
group_id:
group
.
id
).
count_by_state
expect
(
results
).
to
eq
(
'opened'
=>
2
,
'closed'
=>
1
,
'all'
=>
3
)
expect
(
results
).
to
eq
(
'opened'
=>
3
,
'closed'
=>
1
,
'all'
=>
4
)
end
it
'returns -1 if the query times out'
do
...
...
ee/spec/graphql/resolvers/epic_ancestors_resolver_spec.rb
View file @
48166eb0
...
...
@@ -54,8 +54,8 @@ RSpec.describe Resolvers::EpicAncestorsResolver do
sub_group
.
add_developer
(
current_user
)
end
it
'returns all ancestors'
do
expect
(
resolve_ancestors
(
epic4
,
args
)).
to
contain_exactly
(
epic1
,
epic2
,
epic3
)
it
'returns all ancestors
in the correct order
'
do
expect
(
resolve_ancestors
(
epic4
,
args
)).
to
eq
([
epic1
,
epic2
,
epic3
]
)
end
it
'does not return parent group epics when include_ancestor_groups is false'
do
...
...
ee/spec/helpers/ee/learn_gitlab_helper_spec.rb
0 → 100644
View file @
48166eb0
# frozen_string_literal: true
require
'spec_helper'
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
(
:namespace
)
{
project
.
namespace
}
before
do
allow_next_instance_of
(
LearnGitlab
::
Project
)
do
|
learn_gitlab
|
allow
(
learn_gitlab
).
to
receive
(
:project
).
and_return
(
project
)
end
OnboardingProgress
.
onboard
(
namespace
)
end
describe
'#onboarding_actions_data'
do
subject
(
:onboarding_actions_data
)
{
helper
.
onboarding_actions_data
(
project
)
}
context
'when in the new action URLs experiment'
do
before
do
stub_experiments
(
change_continuous_onboarding_link_urls: :candidate
)
end
context
'for trial- and subscription-related actions'
do
context
'when namespace plans are not enabled'
do
before
do
stub_application_setting
(
check_namespace_plan:
false
)
end
it
'provides the default URLs'
do
expect
(
onboarding_actions_data
).
to
include
(
trial_started:
a_hash_including
(
url:
a_string_matching
(
%r{
#{
namespace
.
path
}
/learn_gitlab/-/issues/2}
)
),
code_owners_enabled:
a_hash_including
(
url:
a_string_matching
(
%r{
#{
namespace
.
path
}
/learn_gitlab/-/issues/10}
)
),
required_mr_approvals_enabled:
a_hash_including
(
url:
a_string_matching
(
%r{
#{
namespace
.
path
}
/learn_gitlab/-/issues/11}
)
)
)
end
end
context
'when namespace plans are enabled'
do
before
do
stub_application_setting
(
check_namespace_plan:
true
)
end
it
'provides URLs to start a trial for the appropariate actions'
do
expect
(
onboarding_actions_data
).
to
include
(
trial_started:
a_hash_including
(
url:
new_trial_path
(
glm_source:
'gitlab.com'
,
glm_content:
'onboarding-start-trial'
)
),
code_owners_enabled:
a_hash_including
(
url:
new_trial_path
(
glm_source:
'gitlab.com'
,
glm_content:
'onboarding-code-owners'
)
),
required_mr_approvals_enabled:
a_hash_including
(
url:
new_trial_path
(
glm_source:
'gitlab.com'
,
glm_content:
'onboarding-require-merge-approvals'
)
)
)
end
end
end
end
end
end
ee/spec/models/epic_spec.rb
View file @
48166eb0
...
...
@@ -361,13 +361,22 @@ RSpec.describe Epic do
end
context
'hierarchy'
do
let
(
:epic1
)
{
create
(
:epic
,
group:
group
)
}
let
(
:epic2
)
{
create
(
:epic
,
group:
group
,
parent:
epic1
)
}
let
(
:epic3
)
{
create
(
:epic
,
group:
group
,
parent:
epic2
)
}
let_it_be
(
:epic2
,
reload:
true
)
{
create
(
:epic
,
group:
group
)
}
let_it_be
(
:epic3
)
{
create
(
:epic
,
group:
group
,
parent:
epic2
)
}
let_it_be
(
:epic4
)
{
create
(
:epic
,
group:
group
,
parent:
epic3
)
}
let_it_be
(
:epic1
)
{
create
(
:epic
,
group:
group
)
}
before
do
epic2
.
update!
(
parent_id:
epic1
.
id
)
end
describe
'#ancestors'
do
it
'returns all ancestors for an epic'
do
expect
(
epic3
.
ancestors
).
to
eq
[
epic2
,
epic1
]
it
'returns all ancestors for an epic ordered correctly'
do
expect
(
epic4
.
ancestors
).
to
eq
([
epic3
,
epic2
,
epic1
])
end
it
'returns all ancestors for an epic ordered correctly with the hierarchy_order param'
do
expect
(
epic4
.
ancestors
(
hierarchy_order: :desc
)).
to
eq
([
epic1
,
epic2
,
epic3
])
end
it
'returns an empty array if an epic does not have any parent'
do
...
...
@@ -377,11 +386,11 @@ RSpec.describe Epic do
describe
'#descendants'
do
it
'returns all descendants for an epic'
do
expect
(
epic1
.
descendants
).
to
match_array
([
epic2
,
epic3
])
expect
(
epic1
.
descendants
).
to
match_array
([
epic2
,
epic3
,
epic4
])
end
it
'returns an empty array if an epic does not have any descendants'
do
expect
(
epic
3
.
descendants
).
to
be_empty
expect
(
epic
4
.
descendants
).
to
be_empty
end
end
end
...
...
@@ -705,8 +714,7 @@ RSpec.describe Epic do
end
before
do
epic
.
description
=
ref_text
epic
.
save
epic
.
update!
(
description:
ref_text
)
end
it
'creates new system notes for cross references'
do
...
...
ee/spec/requests/api/graphql/epics/epic_resolver_spec.rb
View file @
48166eb0
...
...
@@ -106,6 +106,21 @@ RSpec.describe 'getting epics information' do
end
end
context
'query for epics with ancestors'
do
let_it_be
(
:parent_epic
)
{
create
(
:epic
,
group:
group
)
}
let_it_be
(
:epic
)
{
create
(
:epic
,
group:
group
,
parent:
parent_epic
)
}
it
'returns the ancestors'
do
query_epic_with_ancestors
(
epic
.
iid
)
ancestors
=
graphql_data
[
'group'
][
'epic'
][
'ancestors'
][
'nodes'
]
expect
(
ancestors
.
count
).
to
eq
(
1
)
expect
(
ancestors
.
first
[
'id'
]).
to
eq
(
parent_epic
.
to_global_id
.
to_s
)
expect
(
graphql_errors
).
to
be_nil
end
end
describe
'N+1 query checks'
do
let_it_be
(
:epic_a
)
{
create
(
:epic
,
group:
group
)
}
let_it_be
(
:epic_b
)
{
create
(
:epic
,
group:
group
)
}
...
...
@@ -157,6 +172,24 @@ RSpec.describe 'getting epics information' do
)
end
def
query_epic_with_ancestors
(
epic_iid
)
epics_field
=
<<~
NODE
epic(iid:
#{
epic_iid
}
) {
id
ancestors {
nodes {
id
}
}
}
NODE
post_graphql
(
graphql_query_for
(
'group'
,
{
'fullPath'
=>
group
.
full_path
},
epics_field
),
current_user:
user
)
end
def
epics_query
(
group
,
field
,
value
)
epics_query_by_hash
(
group
,
field
=>
value
)
end
...
...
spec/controllers/projects/branches_controller_spec.rb
View file @
48166eb0
...
...
@@ -356,7 +356,7 @@ RSpec.describe Projects::BranchesController do
context
"valid branch name with encoded slashes"
do
let
(
:branch
)
{
"improve%2Fawesome"
}
it
{
expect
(
response
).
to
have_gitlab_http_status
(
:
ok
)
}
it
{
expect
(
response
).
to
have_gitlab_http_status
(
:
not_found
)
}
it
{
expect
(
response
.
body
).
to
be_blank
}
end
...
...
@@ -396,10 +396,10 @@ RSpec.describe Projects::BranchesController do
let
(
:branch
)
{
'improve%2Fawesome'
}
it
'returns JSON response with message'
do
expect
(
json_response
).
to
eql
(
'message'
=>
'
Branch was deleted
'
)
expect
(
json_response
).
to
eql
(
'message'
=>
'
No such branch
'
)
end
it
{
expect
(
response
).
to
have_gitlab_http_status
(
:
ok
)
}
it
{
expect
(
response
).
to
have_gitlab_http_status
(
:
not_found
)
}
end
context
'invalid branch name, valid ref'
do
...
...
spec/helpers/learn_gitlab_helper_spec.rb
View file @
48166eb0
...
...
@@ -11,9 +11,6 @@ RSpec.describe LearnGitlabHelper do
let_it_be
(
:namespace
)
{
project
.
namespace
}
before
do
project
.
add_developer
(
user
)
allow
(
helper
).
to
receive
(
:user
).
and_return
(
user
)
allow_next_instance_of
(
LearnGitlab
::
Project
)
do
|
learn_gitlab
|
allow
(
learn_gitlab
).
to
receive
(
:project
).
and_return
(
project
)
end
...
...
@@ -22,38 +19,115 @@ RSpec.describe LearnGitlabHelper do
OnboardingProgress
.
register
(
namespace
,
:git_write
)
end
describe
'
.
onboarding_actions_data'
do
describe
'
#
onboarding_actions_data'
do
subject
(
:onboarding_actions_data
)
{
helper
.
onboarding_actions_data
(
project
)
}
it
'has all actions'
do
expect
(
onboarding_actions_data
.
keys
).
to
contain_exactly
(
:issue_created
,
:git_write
,
:pipeline_created
,
:merge_request_created
,
:user_added
,
:trial_started
,
:required_mr_approvals_enabled
,
:code_owners_enabled
,
:security_scan_enabled
)
shared_examples
'has all actions'
do
it
'has all actions'
do
expect
(
onboarding_actions_data
.
keys
).
to
contain_exactly
(
:issue_created
,
:git_write
,
:pipeline_created
,
:merge_request_created
,
:user_added
,
:trial_started
,
:required_mr_approvals_enabled
,
:code_owners_enabled
,
:security_scan_enabled
)
end
end
it
'sets correct path and completion status'
do
expect
(
onboarding_actions_data
[
:git_write
]).
to
eq
({
url:
project_issue_url
(
project
,
LearnGitlab
::
Onboarding
::
ACTION_ISSUE_IDS
[
:git_write
]),
completed:
true
,
svg:
helper
.
image_path
(
"learn_gitlab/git_write.svg"
)
it_behaves_like
'has all actions'
it
'sets correct paths'
do
expect
(
onboarding_actions_data
).
to
match
({
trial_started:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab/-/issues/2
\z
}
)
),
issue_created:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab/-/issues/4
\z
}
)
),
git_write:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab/-/issues/6
\z
}
)
),
pipeline_created:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab/-/issues/7
\z
}
)
),
user_added:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab/-/issues/8
\z
}
)
),
merge_request_created:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab/-/issues/9
\z
}
)
),
code_owners_enabled:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab/-/issues/10
\z
}
)
),
required_mr_approvals_enabled:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab/-/issues/11
\z
}
)
),
security_scan_enabled:
a_hash_including
(
url:
a_string_matching
(
%r{docs
\.
gitlab
\.
com/ee/user/application_security/security_dashboard/#gitlab-security-dashboard-security-center-and-vulnerability-reports
\z
}
)
)
})
expect
(
onboarding_actions_data
[
:pipeline_created
]).
to
eq
({
url:
project_issue_url
(
project
,
LearnGitlab
::
Onboarding
::
ACTION_ISSUE_IDS
[
:pipeline_created
]),
completed:
false
,
svg:
helper
.
image_path
(
"learn_gitlab/pipeline_created.svg"
)
end
it
'sets correct completion statuses'
do
expect
(
onboarding_actions_data
).
to
match
({
issue_created:
a_hash_including
(
completed:
false
),
git_write:
a_hash_including
(
completed:
true
),
pipeline_created:
a_hash_including
(
completed:
false
),
merge_request_created:
a_hash_including
(
completed:
false
),
user_added:
a_hash_including
(
completed:
false
),
trial_started:
a_hash_including
(
completed:
false
),
required_mr_approvals_enabled:
a_hash_including
(
completed:
false
),
code_owners_enabled:
a_hash_including
(
completed:
false
),
security_scan_enabled:
a_hash_including
(
completed:
false
)
})
end
context
'when in the new action URLs experiment'
do
before
do
stub_experiments
(
change_continuous_onboarding_link_urls: :candidate
)
end
it_behaves_like
'has all actions'
it
'sets mostly new paths'
do
expect
(
onboarding_actions_data
).
to
match
({
trial_started:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab/-/issues/2
\z
}
)
),
issue_created:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab/-/issues
\z
}
)
),
git_write:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab
\z
}
)
),
pipeline_created:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab/-/pipelines
\z
}
)
),
user_added:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab/-/project_members
\z
}
)
),
merge_request_created:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab/-/merge_requests
\z
}
)
),
code_owners_enabled:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab/-/issues/10
\z
}
)
),
required_mr_approvals_enabled:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab/-/issues/11
\z
}
)
),
security_scan_enabled:
a_hash_including
(
url:
a_string_matching
(
%r{/learn_gitlab/-/security/configuration
\z
}
)
)
})
end
end
end
describe
'
.
learn_gitlab_enabled?'
do
describe
'
#
learn_gitlab_enabled?'
do
using
RSpec
::
Parameterized
::
TableSyntax
let_it_be
(
:user
)
{
create
(
:user
)
}
...
...
@@ -89,7 +163,7 @@ RSpec.describe LearnGitlabHelper do
end
end
describe
'
.
onboarding_sections_data'
do
describe
'
#
onboarding_sections_data'
do
subject
(
:sections
)
{
helper
.
onboarding_sections_data
}
it
'has the right keys'
do
...
...
spec/models/ci/build_metadata_spec.rb
View file @
48166eb0
...
...
@@ -121,4 +121,16 @@ RSpec.describe Ci::BuildMetadata do
end
end
end
describe
'set_cancel_gracefully'
do
it
'sets cancel_gracefully'
do
build
.
set_cancel_gracefully
expect
(
build
.
cancel_gracefully?
).
to
be
true
end
it
'returns false'
do
expect
(
build
.
cancel_gracefully?
).
to
be
false
end
end
end
spec/models/ci/build_spec.rb
View file @
48166eb0
...
...
@@ -35,6 +35,8 @@ RSpec.describe Ci::Build do
it
{
is_expected
.
to
respond_to
(
:has_trace?
)
}
it
{
is_expected
.
to
respond_to
(
:trace
)
}
it
{
is_expected
.
to
respond_to
(
:set_cancel_gracefully
)
}
it
{
is_expected
.
to
respond_to
(
:cancel_gracefully?
)
}
it
{
is_expected
.
to
delegate_method
(
:merge_request?
).
to
(
:pipeline
)
}
it
{
is_expected
.
to
delegate_method
(
:merge_request_ref?
).
to
(
:pipeline
)
}
...
...
@@ -5386,4 +5388,23 @@ RSpec.describe Ci::Build do
create
(
:ci_build
)
end
end
describe
'#runner_features'
do
subject
do
build
.
save!
build
.
cancel_gracefully?
end
let_it_be
(
:build
)
{
create
(
:ci_build
,
pipeline:
pipeline
)
}
it
'cannot cancel gracefully'
do
expect
(
subject
).
to
be
false
end
it
'can cancel gracefully'
do
build
.
set_cancel_gracefully
expect
(
subject
).
to
be
true
end
end
end
spec/models/uploads/fog_spec.rb
View file @
48166eb0
...
...
@@ -40,7 +40,9 @@ RSpec.describe Uploads::Fog do
end
describe
'#delete_keys'
do
let
(
:connection
)
{
::
Fog
::
Storage
.
new
(
FileUploader
.
object_store_credentials
)
}
let
(
:keys
)
{
data_store
.
keys
(
relation
)
}
let
(
:paths
)
{
relation
.
pluck
(
:path
)
}
let!
(
:uploads
)
{
create_list
(
:upload
,
2
,
:with_file
,
:issuable_upload
,
model:
project
)
}
subject
{
data_store
.
delete_keys
(
keys
)
}
...
...
@@ -50,17 +52,32 @@ RSpec.describe Uploads::Fog do
end
it
'deletes multiple data'
do
paths
=
relation
.
pluck
(
:path
)
paths
.
each
do
|
path
|
expect
(
connection
.
get_object
(
'uploads'
,
path
)[
:body
]).
not_to
be_nil
end
subject
paths
.
each
do
|
path
|
expect
{
connection
.
get_object
(
'uploads'
,
path
)[
:body
]
}.
to
raise_error
(
Excon
::
Error
::
NotFound
)
end
end
::
Fog
::
Storage
.
new
(
FileUploader
.
object_store_credentials
).
tap
do
|
connection
|
context
'when one of keys is missing'
do
let
(
:keys
)
{
[
'unknown'
]
+
super
()
}
it
'deletes only existing keys'
do
paths
.
each
do
|
path
|
expect
(
connection
.
get_object
(
'uploads'
,
path
)[
:body
]).
not_to
be_nil
end
end
subject
expect_next_instance_of
(
::
Fog
::
Storage
)
do
|
storage
|
allow
(
storage
).
to
receive
(
:delete_object
).
and_call_original
expect
(
storage
).
to
receive
(
:delete_object
).
with
(
'uploads'
,
keys
.
first
).
and_raise
(
::
Google
::
Apis
::
ClientError
,
'NotFound'
)
end
subject
::
Fog
::
Storage
.
new
(
FileUploader
.
object_store_credentials
).
tap
do
|
connection
|
paths
.
each
do
|
path
|
expect
{
connection
.
get_object
(
'uploads'
,
path
)[
:body
]
}.
to
raise_error
(
Excon
::
Error
::
NotFound
)
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment