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
edfe463a
Commit
edfe463a
authored
Dec 14, 2020
by
Heinrich Lee Yu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle showing of iteration lists in boards
Also handles moving of issues to / from an iteration list
parent
2503be2f
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
282 additions
and
47 deletions
+282
-47
doc/api/graphql/reference/gitlab_schema.graphql
doc/api/graphql/reference/gitlab_schema.graphql
+5
-0
doc/api/graphql/reference/gitlab_schema.json
doc/api/graphql/reference/gitlab_schema.json
+14
-0
doc/api/graphql/reference/index.md
doc/api/graphql/reference/index.md
+1
-0
ee/app/graphql/ee/types/board_list_type.rb
ee/app/graphql/ee/types/board_list_type.rb
+6
-0
ee/app/models/ee/list.rb
ee/app/models/ee/list.rb
+5
-1
ee/app/models/license.rb
ee/app/models/license.rb
+1
-0
ee/app/services/ee/boards/issues/list_service.rb
ee/app/services/ee/boards/issues/list_service.rb
+27
-0
ee/app/services/ee/boards/issues/move_service.rb
ee/app/services/ee/boards/issues/move_service.rb
+14
-5
ee/app/services/ee/boards/lists/create_service.rb
ee/app/services/ee/boards/lists/create_service.rb
+1
-10
ee/app/services/ee/boards/lists/list_service.rb
ee/app/services/ee/boards/lists/list_service.rb
+5
-6
ee/spec/controllers/boards/lists_controller_spec.rb
ee/spec/controllers/boards/lists_controller_spec.rb
+2
-2
ee/spec/factories/lists.rb
ee/spec/factories/lists.rb
+6
-1
ee/spec/graphql/ee/mutations/boards/lists/create_spec.rb
ee/spec/graphql/ee/mutations/boards/lists/create_spec.rb
+2
-2
ee/spec/graphql/ee/types/board_list_type_spec.rb
ee/spec/graphql/ee/types/board_list_type_spec.rb
+1
-1
ee/spec/models/ee/list_spec.rb
ee/spec/models/ee/list_spec.rb
+1
-1
ee/spec/services/ee/boards/issues/list_service_spec.rb
ee/spec/services/ee/boards/issues/list_service_spec.rb
+44
-2
ee/spec/services/ee/boards/issues/move_service_spec.rb
ee/spec/services/ee/boards/issues/move_service_spec.rb
+92
-2
ee/spec/services/ee/boards/lists/create_service_spec.rb
ee/spec/services/ee/boards/lists/create_service_spec.rb
+2
-2
ee/spec/services/ee/boards/lists/list_service_spec.rb
ee/spec/services/ee/boards/lists/list_service_spec.rb
+51
-10
ee/spec/support/shared_examples/requests/api/iteration_board_list_shared_examples.rb
...ples/requests/api/iteration_board_list_shared_examples.rb
+2
-2
No files found.
doc/api/graphql/reference/gitlab_schema.graphql
View file @
edfe463a
...
...
@@ -2029,6 +2029,11 @@ type BoardList {
"""
issuesCount
:
Int
"""
Iteration
of
the
list
"""
iteration
:
Iteration
"""
Label
of
the
list
"""
...
...
doc/api/graphql/reference/gitlab_schema.json
View file @
edfe463a
...
...
@@ -5351,6 +5351,20 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "iteration",
"description": "Iteration of the list",
"args": [
],
"type": {
"kind": "OBJECT",
"name": "Iteration",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "label",
"description": "Label of the list",
doc/api/graphql/reference/index.md
View file @
edfe463a
...
...
@@ -325,6 +325,7 @@ Represents a list for an issue board.
|
`id`
| ID! | ID (global ID) of the list |
|
`issues`
| IssueConnection | Board issues |
|
`issuesCount`
| Int | Count of issues in the list |
|
`iteration`
| Iteration | Iteration of the list |
|
`label`
| Label | Label of the list |
|
`limitMetric`
| ListLimitMetric | The current limit metric for the list |
|
`listType`
| String! | Type of the list |
...
...
ee/app/graphql/ee/types/board_list_type.rb
View file @
edfe463a
...
...
@@ -8,6 +8,8 @@ module EE
prepended
do
field
:milestone
,
::
Types
::
MilestoneType
,
null:
true
,
description:
'Milestone of the list'
field
:iteration
,
::
Types
::
IterationType
,
null:
true
,
description:
'Iteration of the list'
field
:max_issue_count
,
GraphQL
::
INT_TYPE
,
null:
true
,
description:
'Maximum number of issues in the list'
field
:max_issue_weight
,
GraphQL
::
INT_TYPE
,
null:
true
,
...
...
@@ -23,6 +25,10 @@ module EE
::
Gitlab
::
Graphql
::
Loaders
::
BatchModelLoader
.
new
(
::
Milestone
,
object
.
milestone_id
).
find
end
def
iteration
::
Gitlab
::
Graphql
::
Loaders
::
BatchModelLoader
.
new
(
::
Iteration
,
object
.
iteration_id
).
find
end
def
assignee
object
.
assignee?
?
object
.
user
:
nil
end
...
...
ee/app/models/ee/list.rb
View file @
edfe463a
...
...
@@ -8,6 +8,10 @@ module EE
LIMIT_METRIC_TYPES
=
%w[all_metrics issue_count issue_weights]
.
freeze
# When adding a new licensed type, make sure to also add
# it on license.rb with the pattern "board_<list_type>_lists"
LICENSED_LIST_TYPES
=
%i[assignee milestone iteration]
.
freeze
# ActiveSupport::Concern does not prepend the ClassMethods,
# so we cannot call `super` if we use it.
def
self
.
prepended
(
base
)
...
...
@@ -42,7 +46,7 @@ module EE
unless:
->
{
board
&
.
resource_parent
&
.
feature_available?
(
:board_milestone_lists
)
}
base
.
validates
:list_type
,
exclusion:
{
in:
%w[iteration]
,
message:
->
(
_object
,
_data
)
{
_
(
'Iteration lists not available with your current license'
)
}
},
unless:
->
{
board
&
.
resource_parent
&
.
feature_available?
(
:
iteration
s
)
}
unless:
->
{
board
&
.
resource_parent
&
.
feature_available?
(
:
board_iteration_list
s
)
}
base
.
scope
:without_types
,
->
(
list_types
)
{
where
.
not
(
list_type:
list_types
)
}
end
...
...
ee/app/models/license.rb
View file @
edfe463a
...
...
@@ -14,6 +14,7 @@ class License < ApplicationRecord
EES_FEATURES
=
%i[
audit_events
blocked_issues
board_iteration_lists
code_owners
code_review_analytics
contribution_analytics
...
...
ee/app/services/ee/boards/issues/list_service.rb
View file @
edfe463a
...
...
@@ -13,6 +13,7 @@ module EE
unless
list
&
.
movable?
||
list
&
.
closed?
issues
=
without_assignees_from_lists
(
issues
)
issues
=
without_milestones_from_lists
(
issues
)
issues
=
without_iterations_from_lists
(
issues
)
end
case
list
&
.
list_type
...
...
@@ -20,6 +21,8 @@ module EE
with_assignee
(
super
)
when
'milestone'
with_milestone
(
super
)
when
'iteration'
with_iteration
(
super
)
else
super
end
...
...
@@ -58,6 +61,18 @@ module EE
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
all_iteration_lists
# Note that the names are very similar but these are different.
# One is a license name and the other is a feature flag
if
parent
.
feature_available?
(
:board_iteration_lists
)
&&
::
Feature
.
enabled?
(
:iteration_board_lists
,
parent
)
board
.
lists
.
iteration
.
where
.
not
(
iteration_id:
nil
)
else
::
List
.
none
end
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
without_assignees_from_lists
(
issues
)
return
issues
if
all_assignee_lists
.
empty?
...
...
@@ -85,6 +100,14 @@ module EE
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
without_iterations_from_lists
(
issues
)
return
issues
if
all_iteration_lists
.
empty?
issues
.
not_in_iterations
(
all_iteration_lists
.
select
(
:iteration_id
))
end
# rubocop: enable CodeReuse/ActiveRecord
def
with_assignee
(
issues
)
issues
.
assigned_to
(
list
.
user
)
end
...
...
@@ -95,6 +118,10 @@ module EE
end
# rubocop: enable CodeReuse/ActiveRecord
def
with_iteration
(
issues
)
issues
.
in_iterations
(
list
.
iteration_id
)
end
# Prevent filtering by milestone stubs
# like Milestone::Upcoming, Milestone::Started etc
def
has_valid_milestone?
...
...
ee/app/services/ee/boards/issues/move_service.rb
View file @
edfe463a
...
...
@@ -34,19 +34,28 @@ module EE
assignee_ids
=
assignee_ids
(
issue
)
milestone_id
=
milestone_id
(
issue
)
{
movement_args
=
{
assignee_ids:
assignee_ids
,
milestone_id:
milestone_id
}
movement_args
[
:sprint_id
]
=
iteration_id
(
issue
)
if
::
Feature
.
enabled?
(
:iteration_board_lists
,
parent
)
movement_args
end
def
milestone_id
(
issue
)
# We want to nullify the issue milestone.
return
if
moving_to_list
.
backlog?
&&
moving_from_list
.
milestone?
return
moving_to_list
.
milestone_id
if
moving_to_list
.
milestone?
issue
.
milestone_id
end
def
iteration_id
(
issue
)
return
if
moving_to_list
.
backlog?
&&
moving_from_list
.
iteration?
return
moving_to_list
.
iteration_id
if
moving_to_list
.
iteration?
# Moving to a list which is not a 'milestone list' will keep
# the already existent milestone.
[
issue
.
milestone_id
,
moving_to_list
.
milestone_id
].
compact
.
last
issue
.
sprint_id
end
def
assignee_ids
(
issue
)
...
...
ee/app/services/ee/boards/lists/create_service.rb
View file @
edfe463a
...
...
@@ -19,16 +19,7 @@ module EE
private
def
valid_license?
(
parent
)
license_name
=
case
type
when
:assignee
:board_assignee_lists
when
:milestone
:board_milestone_lists
when
:iteration
:iterations
end
license_name
.
nil?
||
parent
.
feature_available?
(
license_name
)
List
::
LICENSED_LIST_TYPES
.
exclude?
(
type
)
||
parent
.
feature_available?
(
:"board_
#{
type
}
_lists"
)
end
def
license_validation_error
...
...
ee/app/services/ee/boards/lists/list_service.rb
View file @
edfe463a
...
...
@@ -6,10 +6,6 @@ module EE
module
ListService
extend
::
Gitlab
::
Utils
::
Override
# When adding a new licensed type, make sure to also add
# it on license.rb with the pattern "board_<list_type>_lists"
LICENSED_LIST_TYPES
=
%i[assignee milestone]
.
freeze
override
:execute
def
execute
(
board
,
create_default_lists:
true
)
list_types
=
unavailable_list_types_for
(
board
)
...
...
@@ -20,7 +16,10 @@ module EE
private
def
unavailable_list_types_for
(
board
)
(
hidden_lists_for
(
board
)
+
unlicensed_lists_for
(
board
)).
uniq
list_types
=
hidden_lists_for
(
board
)
+
unlicensed_lists_for
(
board
)
list_types
<<
::
List
.
list_types
[
:iteration
]
if
::
Feature
.
disabled?
(
:iteration_board_lists
,
board
.
resource_parent
)
list_types
.
uniq
end
def
hidden_lists_for
(
board
)
...
...
@@ -35,7 +34,7 @@ module EE
def
unlicensed_lists_for
(
board
)
parent
=
board
.
resource_parent
LICENSED_LIST_TYPES
.
each_with_object
([])
do
|
list_type
,
lists
|
L
ist
::
L
ICENSED_LIST_TYPES
.
each_with_object
([])
do
|
list_type
,
lists
|
list_type_key
=
::
List
.
list_types
[
list_type
]
lists
<<
list_type_key
unless
parent
&
.
feature_available?
(
:"board_
#{
list_type
}
_lists"
)
end
...
...
ee/spec/controllers/boards/lists_controller_spec.rb
View file @
edfe463a
...
...
@@ -79,7 +79,7 @@ RSpec.describe Boards::ListsController do
context
'when license is available'
do
before
do
stub_licensed_features
(
iteration
s:
true
)
stub_licensed_features
(
board_iteration_list
s:
true
)
end
it
'returns a successful 200 response'
do
...
...
@@ -92,7 +92,7 @@ RSpec.describe Boards::ListsController do
context
'when license is unavailable'
do
before
do
stub_licensed_features
(
iteration
s:
false
)
stub_licensed_features
(
board_iteration_list
s:
false
)
end
it
'returns an error'
do
...
...
ee/spec/factories/lists.rb
View file @
edfe463a
...
...
@@ -10,7 +10,12 @@ FactoryBot.define do
factory
:milestone_list
,
parent: :list
do
list_type
{
:milestone
}
label
{
nil
}
user
{
nil
}
milestone
end
factory
:iteration_list
,
parent: :list
do
list_type
{
:iteration
}
label
{
nil
}
iteration
end
end
ee/spec/graphql/ee/mutations/boards/lists/create_spec.rb
View file @
edfe463a
...
...
@@ -21,7 +21,7 @@ RSpec.describe Mutations::Boards::Lists::Create do
end
before
do
stub_licensed_features
(
board_assignee_lists:
true
,
board_milestone_lists:
true
,
iteration
s:
true
)
stub_licensed_features
(
board_assignee_lists:
true
,
board_milestone_lists:
true
,
board_iteration_list
s:
true
)
end
subject
{
mutation
.
resolve
(
board_id:
board
.
to_global_id
.
to_s
,
**
list_create_params
)
}
...
...
@@ -108,7 +108,7 @@ RSpec.describe Mutations::Boards::Lists::Create do
context
'when feature unavailable'
do
it
'returns an error'
do
stub_licensed_features
(
iteration
s:
false
)
stub_licensed_features
(
board_iteration_list
s:
false
)
expect
(
subject
[
:errors
]).
to
include
'Iteration lists not available with your current license'
end
...
...
ee/spec/graphql/ee/types/board_list_type_spec.rb
View file @
edfe463a
...
...
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec
.
describe
GitlabSchema
.
types
[
'BoardList'
]
do
it
'has specific fields'
do
expected_fields
=
%w[milestone max_issue_count max_issue_weight assignee total_weight]
expected_fields
=
%w[milestone
iteration
max_issue_count max_issue_weight assignee total_weight]
expect
(
described_class
).
to
include_graphql_fields
(
*
expected_fields
)
end
...
...
ee/spec/models/ee/list_spec.rb
View file @
edfe463a
...
...
@@ -88,7 +88,7 @@ RSpec.describe List do
it
{
is_expected
.
to
validate_presence_of
(
:iteration
)
}
it
'is invalid when feature is not available'
do
stub_licensed_features
(
iteration
s:
false
)
stub_licensed_features
(
board_iteration_list
s:
false
)
expect
(
subject
).
to
be_invalid
expect
(
subject
.
errors
[
:list_type
])
...
...
ee/spec/services/ee/boards/issues/list_service_spec.rb
View file @
edfe463a
...
...
@@ -22,6 +22,7 @@ RSpec.describe Boards::Issues::ListService, services: true do
let_it_be
(
:p3
)
{
create
(
:group_label
,
title:
'P3'
,
group:
group
)
}
let_it_be
(
:milestone
)
{
create
(
:milestone
,
group:
group
)
}
let_it_be
(
:iteration
)
{
create
(
:iteration
,
group:
group
)
}
let_it_be
(
:opened_issue1
)
{
create
(
:labeled_issue
,
project:
project
,
milestone:
m1
,
weight:
9
,
title:
'Issue 1'
,
labels:
[
bug
])
}
let_it_be
(
:opened_issue2
)
{
create
(
:labeled_issue
,
project:
project
,
milestone:
m2
,
weight:
1
,
title:
'Issue 2'
,
labels:
[
p2
])
}
...
...
@@ -42,15 +43,16 @@ RSpec.describe Boards::Issues::ListService, services: true do
let
(
:parent
)
{
group
}
before
do
stub_licensed_features
(
board_assignee_lists:
true
,
board_milestone_lists:
true
)
stub_licensed_features
(
board_assignee_lists:
true
,
board_milestone_lists:
true
,
board_iteration_lists:
true
)
parent
.
add_developer
(
user
)
opened_issue3
.
assignees
.
push
(
user_list
.
user
)
end
context
'with assignee, milestone and label lists present'
do
context
'with assignee, milestone
, iteration
and label lists present'
do
let!
(
:user_list
)
{
create
(
:user_list
,
board:
board
,
position:
2
)
}
let!
(
:milestone_list
)
{
create
(
:milestone_list
,
board:
board
,
position:
3
,
milestone:
milestone
)
}
let!
(
:iteration_list
)
{
create
(
:iteration_list
,
board:
board
,
position:
4
,
iteration:
iteration
)
}
let!
(
:backlog
)
{
create
(
:backlog_list
,
board:
board
)
}
let!
(
:list1
)
{
create
(
:list
,
board:
board
,
label:
development
,
position:
0
)
}
let!
(
:list2
)
{
create
(
:list
,
board:
board
,
label:
testing
,
position:
1
)
}
...
...
@@ -80,6 +82,46 @@ RSpec.describe Boards::Issues::ListService, services: true do
end
end
context
'iteration lists'
do
let!
(
:iteration_issue
)
{
create
(
:labeled_issue
,
project:
project
,
iteration:
iteration
,
labels:
[
p3
])
}
let
(
:params
)
{
{
board_id:
board
.
id
,
id:
iteration_list
.
id
}
}
subject
(
:issues
)
{
described_class
.
new
(
parent
.
class
.
find
(
parent
.
id
),
user
,
params
).
execute
}
it
'returns issues from iteration persisted in the list'
do
expect
(
issues
).
to
contain_exactly
(
iteration_issue
)
end
context
'backlog list'
do
let
(
:params
)
{
{
board_id:
board
.
id
,
id:
backlog
.
id
}
}
it
'excludes issues in the iteration list'
do
expect
(
issues
).
not_to
include
(
iteration_issue
)
end
context
'when feature is disabled'
do
before
do
stub_licensed_features
(
board_iteration_lists:
false
)
end
it
'includes issues in the iteration list'
do
expect
(
issues
).
to
include
(
iteration_issue
)
end
end
context
'when feature flag is disabled'
do
before
do
stub_feature_flags
(
iteration_board_lists:
false
)
end
it
'includes issues in the iteration list'
do
expect
(
issues
).
to
include
(
iteration_issue
)
end
end
end
end
describe
'#metadata'
do
it
'returns issues count and weight for list'
do
params
=
{
board_id:
board
.
id
,
id:
backlog
.
id
}
...
...
ee/spec/services/ee/boards/issues/move_service_spec.rb
View file @
edfe463a
...
...
@@ -103,6 +103,87 @@ RSpec.describe Boards::Issues::MoveService, services: true do
end
end
shared_examples
'moving an issue to/from iteration lists'
do
context
'from backlog to iteration list'
do
let!
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
let
(
:params
)
{
{
board_id:
board1
.
id
,
from_list_id:
backlog
.
id
,
to_list_id:
iteration_list1
.
id
}
}
it
'assigns the iteration'
do
expect
{
described_class
.
new
(
parent
,
user
,
params
).
execute
(
issue
)
}
.
to
change
{
issue
.
reload
.
iteration
}
.
from
(
nil
)
.
to
(
iteration_list1
.
iteration
)
end
context
'when feature flag is disabled'
do
before
do
stub_feature_flags
(
iteration_board_lists:
false
)
end
it
'does not assign the iteration'
do
expect
{
described_class
.
new
(
parent
,
user
,
params
).
execute
(
issue
)
}
.
not_to
change
{
issue
.
reload
.
iteration
}
end
end
end
context
'from iteration to backlog list'
do
let!
(
:issue
)
{
create
(
:issue
,
project:
project
,
iteration:
iteration_list1
.
iteration
)
}
it
'removes the iteration'
do
params
=
{
board_id:
board1
.
id
,
from_list_id:
iteration_list1
.
id
,
to_list_id:
backlog
.
id
}
expect
{
described_class
.
new
(
parent
,
user
,
params
).
execute
(
issue
)
}
.
to
change
{
issue
.
reload
.
iteration
}
.
from
(
iteration_list1
.
iteration
)
.
to
(
nil
)
end
end
context
'from label to iteration list'
do
let
(
:issue
)
{
create
(
:labeled_issue
,
project:
project
,
labels:
[
bug
,
development
])
}
it
'assigns the iteration and keeps labels'
do
params
=
{
board_id:
board1
.
id
,
from_list_id:
label_list1
.
id
,
to_list_id:
iteration_list1
.
id
}
expect
{
described_class
.
new
(
parent
,
user
,
params
).
execute
(
issue
)
}
.
to
change
{
issue
.
reload
.
iteration
}
.
from
(
nil
)
.
to
(
iteration_list1
.
iteration
)
expect
(
issue
.
labels
).
to
contain_exactly
(
bug
,
development
)
end
end
context
'from iteration to label list'
do
let!
(
:issue
)
do
create
(
:labeled_issue
,
project:
project
,
iteration:
iteration_list1
.
iteration
,
labels:
[
bug
,
development
])
end
it
'adds labels and keeps iteration'
do
params
=
{
board_id:
board1
.
id
,
from_list_id:
iteration_list1
.
id
,
to_list_id:
label_list2
.
id
}
expect
{
described_class
.
new
(
parent
,
user
,
params
).
execute
(
issue
)
}
.
not_to
change
{
issue
.
reload
.
iteration
}
expect
(
issue
.
labels
).
to
contain_exactly
(
bug
,
development
,
testing
)
end
end
context
'between iteration lists'
do
let!
(
:issue
)
{
create
(
:issue
,
project:
project
,
iteration:
iteration_list1
.
iteration
)
}
it
'replaces previous list iteration to targeting list iteration'
do
params
=
{
board_id:
board1
.
id
,
from_list_id:
iteration_list1
.
id
,
to_list_id:
iteration_list2
.
id
}
expect
{
described_class
.
new
(
parent
,
user
,
params
).
execute
(
issue
)
}
.
to
change
{
issue
.
reload
.
iteration
}
.
from
(
iteration_list1
.
iteration
)
.
to
(
iteration_list2
.
iteration
)
end
end
end
shared_examples
'moving an issue to/from assignee lists'
do
let
(
:issue
)
{
create
(
:labeled_issue
,
project:
project
,
labels:
[
bug
,
development
],
milestone:
milestone1
)
}
let
(
:params
)
{
{
board_id:
board1
.
id
,
from_list_id:
label_list1
.
id
,
to_list_id:
label_list2
.
id
}
}
...
...
@@ -193,15 +274,20 @@ RSpec.describe Boards::Issues::MoveService, services: true do
let
(
:user_list2
)
{
create
(
:user_list
,
board:
board1
,
user:
user
,
position:
3
)
}
let
(
:milestone_list1
)
{
create
(
:milestone_list
,
board:
board1
,
milestone:
milestone1
,
position:
4
)
}
let
(
:milestone_list2
)
{
create
(
:milestone_list
,
board:
board1
,
milestone:
milestone2
,
position:
5
)
}
let
(
:iteration_list1
)
{
create
(
:iteration_list
,
board:
board1
,
iteration:
iteration1
,
position:
6
)
}
let
(
:iteration_list2
)
{
create
(
:iteration_list
,
board:
board1
,
iteration:
iteration2
,
position:
7
)
}
let
(
:closed
)
{
create
(
:closed_list
,
board:
board1
)
}
let
(
:backlog
)
{
create
(
:backlog_list
,
board:
board1
)
}
context
'when parent is a project'
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:group
)
{
create
(
:group
)
}
let
(
:project
)
{
create
(
:project
,
namespace:
group
)
}
let
(
:parent_attr
)
{
{
project:
project
}
}
let
(
:parent
)
{
project
}
let
(
:milestone1
)
{
create
(
:milestone
,
project:
project
)
}
let
(
:milestone2
)
{
create
(
:milestone
,
project:
project
)
}
let
(
:iteration1
)
{
create
(
:iteration
,
group:
group
)
}
let
(
:iteration2
)
{
create
(
:iteration
,
group:
group
)
}
let
(
:bug
)
{
create
(
:label
,
project:
project
,
name:
'Bug'
)
}
let
(
:development
)
{
create
(
:label
,
project:
project
,
name:
'Development'
)
}
...
...
@@ -209,13 +295,14 @@ RSpec.describe Boards::Issues::MoveService, services: true do
let
(
:regression
)
{
create
(
:label
,
project:
project
,
name:
'Regression'
)
}
before
do
stub_licensed_features
(
board_assignee_lists:
true
,
board_milestone_lists:
true
)
stub_licensed_features
(
board_assignee_lists:
true
,
board_milestone_lists:
true
,
board_iteration_lists:
true
)
parent
.
add_developer
(
user
)
parent
.
add_developer
(
user_list1
.
user
)
end
it_behaves_like
'moving an issue to/from assignee lists'
it_behaves_like
'moving an issue to/from milestone lists'
it_behaves_like
'moving an issue to/from iteration lists'
end
context
'when parent is a group'
do
...
...
@@ -225,6 +312,8 @@ RSpec.describe Boards::Issues::MoveService, services: true do
let
(
:parent
)
{
group
}
let
(
:milestone1
)
{
create
(
:milestone
,
group:
group
)
}
let
(
:milestone2
)
{
create
(
:milestone
,
group:
group
)
}
let
(
:iteration1
)
{
create
(
:iteration
,
group:
group
)
}
let
(
:iteration2
)
{
create
(
:iteration
,
group:
group
)
}
let
(
:bug
)
{
create
(
:group_label
,
group:
group
,
name:
'Bug'
)
}
let
(
:development
)
{
create
(
:group_label
,
group:
group
,
name:
'Development'
)
}
...
...
@@ -239,6 +328,7 @@ RSpec.describe Boards::Issues::MoveService, services: true do
it_behaves_like
'moving an issue to/from assignee lists'
it_behaves_like
'moving an issue to/from milestone lists'
it_behaves_like
'moving an issue to/from iteration lists'
context
'when moving to same list'
do
let
(
:subgroup
)
{
create
(
:group
,
parent:
group
)
}
...
...
ee/spec/services/ee/boards/lists/create_service_spec.rb
View file @
edfe463a
...
...
@@ -62,7 +62,7 @@ RSpec.describe Boards::Lists::CreateService do
subject
(
:service
)
{
described_class
.
new
(
project
,
user
,
'iteration_id'
=>
iteration
.
id
)
}
before
do
stub_licensed_features
(
iteration
s:
true
)
stub_licensed_features
(
board_iteration_list
s:
true
)
end
it
'creates an iteration list when param is valid'
do
...
...
@@ -93,7 +93,7 @@ RSpec.describe Boards::Lists::CreateService do
end
it
'returns an error when license is unavailable'
do
stub_licensed_features
(
iteration
s:
false
)
stub_licensed_features
(
board_iteration_list
s:
false
)
response
=
service
.
execute
(
board
)
...
...
ee/spec/services/ee/boards/lists/list_service_spec.rb
View file @
edfe463a
...
...
@@ -4,6 +4,14 @@ require 'spec_helper'
RSpec
.
describe
Boards
::
Lists
::
ListService
do
describe
'#execute'
do
before
do
stub_licensed_features
(
board_assignee_lists:
false
,
board_milestone_lists:
false
,
board_iteration_lists:
false
)
end
def
execute_service
service
.
execute
(
Board
.
find
(
board
.
id
))
end
shared_examples
'list service for board with assignee lists'
do
let!
(
:assignee_list
)
{
build
(
:user_list
,
board:
board
).
tap
{
|
l
|
l
.
save
(
validate:
false
)
}
}
let!
(
:backlog_list
)
{
create
(
:backlog_list
,
board:
board
)
}
...
...
@@ -11,18 +19,17 @@ RSpec.describe Boards::Lists::ListService do
context
'when the feature is enabled'
do
before
do
allow
(
board
.
resource_parent
).
to
receive
(
:feature_available?
).
with
(
:board_assignee_lists
).
and_return
(
true
)
allow
(
board
.
resource_parent
).
to
receive
(
:feature_available?
).
with
(
:board_milestone_lists
).
and_return
(
false
)
stub_licensed_features
(
board_assignee_lists:
true
)
end
it
'returns all lists'
do
expect
(
service
.
execute
(
board
)
).
to
match_array
[
backlog_list
,
list
,
assignee_list
,
board
.
closed_list
]
expect
(
execute_service
).
to
match_array
[
backlog_list
,
list
,
assignee_list
,
board
.
closed_list
]
end
end
context
'when the feature is disabled'
do
it
'filters out assignee lists that might have been created while subscribed'
do
expect
(
service
.
execute
(
board
)
).
to
match_array
[
backlog_list
,
list
,
board
.
closed_list
]
expect
(
execute_service
).
to
match_array
[
backlog_list
,
list
,
board
.
closed_list
]
end
end
end
...
...
@@ -34,19 +41,51 @@ RSpec.describe Boards::Lists::ListService do
context
'when the feature is enabled'
do
before
do
allow
(
board
.
resource_parent
).
to
receive
(
:feature_available?
).
with
(
:board_assignee_lists
).
and_return
(
false
)
allow
(
board
.
resource_parent
).
to
receive
(
:feature_available?
).
with
(
:board_milestone_lists
).
and_return
(
true
)
stub_licensed_features
(
board_milestone_lists:
true
)
end
it
'returns all lists'
do
expect
(
service
.
execute
(
board
)
)
expect
(
execute_service
)
.
to
match_array
([
backlog_list
,
list
,
milestone_list
,
board
.
closed_list
])
end
end
context
'when the feature is disabled'
do
it
'filters out assignee lists that might have been created while subscribed'
do
expect
(
service
.
execute
(
board
)).
to
match_array
[
backlog_list
,
list
,
board
.
closed_list
]
expect
(
execute_service
).
to
match_array
[
backlog_list
,
list
,
board
.
closed_list
]
end
end
end
shared_examples
'list service for board with iteration lists'
do
let!
(
:iteration_list
)
{
build
(
:iteration_list
,
board:
board
).
tap
{
|
l
|
l
.
save
(
validate:
false
)
}
}
let!
(
:backlog_list
)
{
create
(
:backlog_list
,
board:
board
)
}
let!
(
:list
)
{
create
(
:list
,
board:
board
,
label:
label
)
}
context
'when the feature is enabled'
do
before
do
stub_licensed_features
(
board_iteration_lists:
true
)
end
it
'returns all lists'
do
expect
(
execute_service
)
.
to
match_array
([
backlog_list
,
list
,
iteration_list
,
board
.
closed_list
])
end
context
'when the feature flag is disabled'
do
before
do
stub_feature_flags
(
iteration_board_lists:
false
)
end
it
'filters out iteration lists that might have been created while subscribed'
do
expect
(
execute_service
).
to
match_array
[
backlog_list
,
list
,
board
.
closed_list
]
end
end
end
context
'when feature is disabled'
do
it
'filters out iteration lists that might have been created while subscribed'
do
expect
(
execute_service
).
to
match_array
[
backlog_list
,
list
,
board
.
closed_list
]
end
end
end
...
...
@@ -58,7 +97,7 @@ RSpec.describe Boards::Lists::ListService do
it
'hides backlog list'
do
board
.
update
(
hide_backlog_list:
true
)
expect
(
service
.
execute
(
board
)
).
to
match_array
([
board
.
closed_list
,
list
])
expect
(
execute_service
).
to
match_array
([
board
.
closed_list
,
list
])
end
end
...
...
@@ -66,7 +105,7 @@ RSpec.describe Boards::Lists::ListService do
it
'hides closed list'
do
board
.
update
(
hide_closed_list:
true
)
expect
(
service
.
execute
(
board
)
).
to
match_array
([
board
.
backlog_list
,
list
])
expect
(
execute_service
).
to
match_array
([
board
.
backlog_list
,
list
])
end
end
end
...
...
@@ -80,6 +119,7 @@ RSpec.describe Boards::Lists::ListService do
it_behaves_like
'list service for board with assignee lists'
it_behaves_like
'list service for board with milestone lists'
it_behaves_like
'list service for board with iteration lists'
it_behaves_like
'hidden lists'
end
...
...
@@ -92,6 +132,7 @@ RSpec.describe Boards::Lists::ListService do
it_behaves_like
'list service for board with assignee lists'
it_behaves_like
'list service for board with milestone lists'
it_behaves_like
'list service for board with iteration lists'
it_behaves_like
'hidden lists'
end
end
...
...
ee/spec/support/shared_examples/requests/api/iteration_board_list_shared_examples.rb
View file @
edfe463a
...
...
@@ -2,7 +2,7 @@
RSpec
.
shared_examples
'iteration board list'
do
before
do
stub_licensed_features
(
iteration
s:
true
)
stub_licensed_features
(
board_iteration_list
s:
true
)
end
context
'when iteration_id is sent'
do
...
...
@@ -24,7 +24,7 @@ RSpec.shared_examples 'iteration board list' do
end
it
'returns 400 if not licensed'
do
stub_licensed_features
(
iteration
s:
false
)
stub_licensed_features
(
board_iteration_list
s:
false
)
post
api
(
url
,
user
),
params:
{
iteration_id:
iteration
.
id
}
...
...
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