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
2569cb80
Commit
2569cb80
authored
Dec 02, 2020
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab master
parents
680decd0
93374331
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
592 additions
and
31 deletions
+592
-31
app/finders/group_members_finder.rb
app/finders/group_members_finder.rb
+4
-1
app/finders/members_finder.rb
app/finders/members_finder.rb
+6
-3
app/graphql/resolvers/group_members_resolver.rb
app/graphql/resolvers/group_members_resolver.rb
+5
-0
app/graphql/resolvers/members_resolver.rb
app/graphql/resolvers/members_resolver.rb
+3
-1
app/graphql/resolvers/project_members_resolver.rb
app/graphql/resolvers/project_members_resolver.rb
+5
-0
app/graphql/types/group_member_relation_enum.rb
app/graphql/types/group_member_relation_enum.rb
+12
-0
app/graphql/types/project_member_relation_enum.rb
app/graphql/types/project_member_relation_enum.rb
+12
-0
app/models/alert_management/alert.rb
app/models/alert_management/alert.rb
+2
-0
changelogs/unreleased/allow-filtering-by-member-relations-in-graphql.yml
...leased/allow-filtering-by-member-relations-in-graphql.yml
+5
-0
doc/api/graphql/reference/gitlab_schema.graphql
doc/api/graphql/reference/gitlab_schema.graphql
+55
-0
doc/api/graphql/reference/gitlab_schema.json
doc/api/graphql/reference/gitlab_schema.json
+100
-0
doc/api/graphql/reference/index.md
doc/api/graphql/reference/index.md
+21
-0
doc/ci/environments/index.md
doc/ci/environments/index.md
+26
-0
doc/user/application_security/secret_detection/index.md
doc/user/application_security/secret_detection/index.md
+2
-2
ee/app/models/ee/alert_management/alert.rb
ee/app/models/ee/alert_management/alert.rb
+23
-0
ee/app/views/projects/settings/ci_cd/_auto_rollback.html.haml
...pp/views/projects/settings/ci_cd/_auto_rollback.html.haml
+1
-2
ee/spec/models/ee/alert_management/alert_spec.rb
ee/spec/models/ee/alert_management/alert_spec.rb
+91
-0
lib/api/helpers/members_helpers.rb
lib/api/helpers/members_helpers.rb
+1
-1
spec/finders/members_finder_spec.rb
spec/finders/members_finder_spec.rb
+2
-2
spec/graphql/types/group_member_relation_enum_spec.rb
spec/graphql/types/group_member_relation_enum_spec.rb
+11
-0
spec/graphql/types/project_member_relation_enum_spec.rb
spec/graphql/types/project_member_relation_enum_spec.rb
+11
-0
spec/models/alert_management/alert_spec.rb
spec/models/alert_management/alert_spec.rb
+4
-3
spec/requests/api/graphql/group/group_members_spec.rb
spec/requests/api/graphql/group/group_members_spec.rb
+66
-14
spec/requests/api/graphql/project/project_members_spec.rb
spec/requests/api/graphql/project/project_members_spec.rb
+121
-0
spec/support/shared_examples/graphql/members_shared_examples.rb
...upport/shared_examples/graphql/members_shared_examples.rb
+3
-2
No files found.
app/finders/group_members_finder.rb
View file @
2569cb80
# frozen_string_literal: true
class
GroupMembersFinder
<
UnionFinder
RELATIONS
=
%i(direct inherited descendants)
.
freeze
DEFAULT_RELATIONS
=
%i(direct inherited)
.
freeze
include
CreatedAtFilter
# Params can be any of the following:
...
...
@@ -17,7 +20,7 @@ class GroupMembersFinder < UnionFinder
@params
=
params
end
def
execute
(
include_relations:
[
:inherited
,
:direct
]
)
def
execute
(
include_relations:
DEFAULT_RELATIONS
)
group_members
=
group_members_list
relations
=
[]
...
...
app/finders/members_finder.rb
View file @
2569cb80
# frozen_string_literal: true
class
MembersFinder
RELATIONS
=
%i(direct inherited descendants invited_groups)
.
freeze
DEFAULT_RELATIONS
=
%i(direct inherited)
.
freeze
# Params can be any of the following:
# sort: string
# search: string
...
...
@@ -13,7 +16,7 @@ class MembersFinder
@params
=
params
end
def
execute
(
include_relations:
[
:inherited
,
:direct
]
)
def
execute
(
include_relations:
DEFAULT_RELATIONS
)
members
=
find_members
(
include_relations
)
filter_members
(
members
)
...
...
@@ -56,7 +59,7 @@ class MembersFinder
def
group_union_members
(
include_relations
)
[].
tap
do
|
members
|
members
<<
direct_group_members
(
include_relations
.
include?
(
:descendants
))
if
group
members
<<
project_invited_groups
_members
if
include_relations
.
include?
(
:invited_groups_member
s
)
members
<<
project_invited_groups
if
include_relations
.
include?
(
:invited_group
s
)
end
end
...
...
@@ -66,7 +69,7 @@ class MembersFinder
GroupMembersFinder
.
new
(
group
).
execute
(
include_relations:
requested_relations
).
non_invite
.
non_minimal_access
# rubocop: disable CodeReuse/Finder
end
def
project_invited_groups
_members
def
project_invited_groups
invited_groups_ids_including_ancestors
=
Gitlab
::
ObjectHierarchy
.
new
(
project
.
invited_groups
)
.
base_and_ancestors
...
...
app/graphql/resolvers/group_members_resolver.rb
View file @
2569cb80
...
...
@@ -6,6 +6,11 @@ module Resolvers
authorize
:read_group_member
argument
:relations
,
[
Types
::
GroupMemberRelationEnum
],
description:
'Filter members by the given member relations'
,
required:
false
,
default_value:
GroupMembersFinder
::
DEFAULT_RELATIONS
private
def
preloads
...
...
app/graphql/resolvers/members_resolver.rb
View file @
2569cb80
...
...
@@ -14,7 +14,9 @@ module Resolvers
def
resolve_with_lookahead
(
**
args
)
authorize!
(
object
)
apply_lookahead
(
finder_class
.
new
(
object
,
current_user
,
params:
args
).
execute
)
relations
=
args
.
delete
(
:relations
)
apply_lookahead
(
finder_class
.
new
(
object
,
current_user
,
params:
args
).
execute
(
include_relations:
relations
))
end
private
...
...
app/graphql/resolvers/project_members_resolver.rb
View file @
2569cb80
...
...
@@ -5,6 +5,11 @@ module Resolvers
class
ProjectMembersResolver
<
MembersResolver
authorize
:read_project_member
argument
:relations
,
[
Types
::
ProjectMemberRelationEnum
],
description:
'Filter members by the given member relations'
,
required:
false
,
default_value:
MembersFinder
::
DEFAULT_RELATIONS
private
def
finder_class
...
...
app/graphql/types/group_member_relation_enum.rb
0 → 100644
View file @
2569cb80
# frozen_string_literal: true
module
Types
class
GroupMemberRelationEnum
<
BaseEnum
graphql_name
'GroupMemberRelation'
description
'Group member relation'
::
GroupMembersFinder
::
RELATIONS
.
each
do
|
member_relation
|
value
member_relation
.
to_s
.
upcase
,
value:
member_relation
,
description:
"
#{
member_relation
.
to_s
.
titleize
}
members"
end
end
end
app/graphql/types/project_member_relation_enum.rb
0 → 100644
View file @
2569cb80
# frozen_string_literal: true
module
Types
class
ProjectMemberRelationEnum
<
BaseEnum
graphql_name
'ProjectMemberRelation'
description
'Project member relation'
::
MembersFinder
::
RELATIONS
.
each
do
|
member_relation
|
value
member_relation
.
to_s
.
upcase
,
value:
member_relation
,
description:
"
#{
member_relation
.
to_s
.
titleize
}
members"
end
end
end
app/models/alert_management/alert.rb
View file @
2569cb80
...
...
@@ -263,3 +263,5 @@ module AlertManagement
end
end
end
AlertManagement
::
Alert
.
prepend_if_ee
(
'EE::AlertManagement::Alert'
)
changelogs/unreleased/allow-filtering-by-member-relations-in-graphql.yml
0 → 100644
View file @
2569cb80
---
title
:
Allow filtering project and group members by relationship in GraphQL
merge_request
:
48372
author
:
type
:
changed
doc/api/graphql/reference/gitlab_schema.graphql
View file @
2569cb80
...
...
@@ -9103,6 +9103,11 @@ type Group {
"""
last
:
Int
"""
Filter
members
by
the
given
member
relations
"""
relations
:
[
GroupMemberRelation
!]
=
[
DIRECT
,
INHERITED
]
"""
Search
query
"""
...
...
@@ -10007,6 +10012,26 @@ type GroupMemberEdge {
node
:
GroupMember
}
"""
Group member relation
"""
enum
GroupMemberRelation
{
"""
Descendants
members
"""
DESCENDANTS
"""
Direct
members
"""
DIRECT
"""
Inherited
members
"""
INHERITED
}
type
GroupPermissions
{
"""
Indicates
the
user
can
perform
`
read_group
`
on
this
resource
...
...
@@ -16625,6 +16650,11 @@ type Project {
"""
last
:
Int
"""
Filter
members
by
the
given
member
relations
"""
relations
:
[
ProjectMemberRelation
!]
=
[
DIRECT
,
INHERITED
]
"""
Search
query
"""
...
...
@@ -17262,6 +17292,31 @@ type ProjectMemberEdge {
node
:
ProjectMember
}
"""
Project member relation
"""
enum
ProjectMemberRelation
{
"""
Descendants
members
"""
DESCENDANTS
"""
Direct
members
"""
DIRECT
"""
Inherited
members
"""
INHERITED
"""
Invited
Groups
members
"""
INVITED_GROUPS
}
type
ProjectPermissions
{
"""
Indicates
the
user
can
perform
`
admin_operations
`
on
this
resource
...
...
doc/api/graphql/reference/gitlab_schema.json
View file @
2569cb80
...
...
@@ -25128,6 +25128,24 @@
},
"defaultValue": null
},
{
"name": "relations",
"description": "Filter members by the given member relations",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "GroupMemberRelation",
"ofType": null
}
}
},
"defaultValue": "[DIRECT, INHERITED]"
},
{
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
...
...
@@ -27424,6 +27442,35 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "ENUM",
"name": "GroupMemberRelation",
"description": "Group member relation",
"fields": null,
"inputFields": null,
"interfaces": null,
"enumValues": [
{
"name": "DIRECT",
"description": "Direct members",
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "INHERITED",
"description": "Inherited members",
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "DESCENDANTS",
"description": "Descendants members",
"isDeprecated": false,
"deprecationReason": null
}
],
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "GroupPermissions",
...
...
@@ -48635,6 +48682,24 @@
},
"defaultValue": null
},
{
"name": "relations",
"description": "Filter members by the given member relations",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "ProjectMemberRelation",
"ofType": null
}
}
},
"defaultValue": "[DIRECT, INHERITED]"
},
{
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
...
...
@@ -50363,6 +50428,41 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "ENUM",
"name": "ProjectMemberRelation",
"description": "Project member relation",
"fields": null,
"inputFields": null,
"interfaces": null,
"enumValues": [
{
"name": "DIRECT",
"description": "Direct members",
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "INHERITED",
"description": "Inherited members",
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "DESCENDANTS",
"description": "Descendants members",
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "INVITED_GROUPS",
"description": "Invited Groups members",
"isDeprecated": false,
"deprecationReason": null
}
],
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "ProjectPermissions",
doc/api/graphql/reference/index.md
View file @
2569cb80
...
...
@@ -4078,6 +4078,16 @@ Epic ID wildcard values.
|
`ANY`
| Any epic is assigned |
|
`NONE`
| No epic is assigned |
### GroupMemberRelation
Group member relation.
| Value | Description |
| ----- | ----------- |
|
`DESCENDANTS`
| Descendants members |
|
`DIRECT`
| Direct members |
|
`INHERITED`
| Inherited members |
### HealthStatus
Health status of an issue or epic.
...
...
@@ -4366,6 +4376,17 @@ Values for sorting projects.
|
`SUCCESS`
| |
|
`WAITING_FOR_RESOURCE`
| |
### ProjectMemberRelation
Project member relation.
| Value | Description |
| ----- | ----------- |
|
`DESCENDANTS`
| Descendants members |
|
`DIRECT`
| Direct members |
|
`INHERITED`
| Inherited members |
|
`INVITED_GROUPS`
| Invited Groups members |
### RegistryState
State of a Geo registry.
...
...
doc/ci/environments/index.md
View file @
2569cb80
...
...
@@ -894,6 +894,32 @@ longer visible on the environment page.
If the alert requires a
[
rollback
](
#retrying-and-rolling-back
)
, you can select the
deployment tab from the environment page and select which deployment to roll back to.
#### Auto Rollback **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35404) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.7.
In a typical Continuous Deployment workflow, the CI pipeline tests every commit before deploying to
production. However, problematic code can still make it to production. For example, inefficient code
that is logically correct can pass tests even though it causes severe performance degradation.
Operators and SREs monitor the system to catch such problems as soon as possible. If they find a
problematic deployment, they can roll back to a previous stable version.
GitLab Auto Rollback eases this workflow by automatically triggering a rollback when a
[
critical alert
](
../../operations/incident_management/alerts.md
)
is detected. GitLab selects and redeploys the most recent successful deployment.
Limitations of GitLab Auto Rollback:
-
The rollback is skipped if a deployment is running when the alert is detected.
-
A rollback can happen only once in three minutes. If multiple alerts are detected at once, only
one rollback is performed.
GitLab Auto Rollback is turned off by default. To turn it on:
1.
Visit
**Project > Settings > CI/CD > Automatic deployment rollbacks**
.
1.
Select the checkbox for
**Enable automatic rollbacks**
.
1.
Click
**Save changes**
.
### Monitoring environments
If you have enabled
[
Prometheus for monitoring system and response metrics
](
../../user/project/integrations/prometheus.md
)
,
...
...
doc/user/application_security/secret_detection/index.md
View file @
2569cb80
...
...
@@ -115,7 +115,7 @@ Add the following to your `.gitlab-ci.yml` file:
```
yaml
include
:
-
template
:
Secret-Detection.gitlab-ci.yml
-
template
:
Sec
urity/Sec
ret-Detection.gitlab-ci.yml
```
The included template creates Secret Detection jobs in your CI/CD pipeline and scans
...
...
@@ -153,7 +153,7 @@ override the `secret_detection` job with the `SECRET_DETECTION_HISTORIC_SCAN` va
```
yaml
include
:
-
template
:
Secret-Detection.gitlab-ci.yml
-
template
:
Sec
urity/Sec
ret-Detection.gitlab-ci.yml
secret_detection
:
variables
:
...
...
ee/app/models/ee/alert_management/alert.rb
0 → 100644
View file @
2569cb80
# frozen_string_literal: true
module
EE
module
AlertManagement
module
Alert
extend
ActiveSupport
::
Concern
prepended
do
include
AfterCommitQueue
after_create
do
|
alert
|
run_after_commit
{
alert
.
trigger_auto_rollback
}
end
end
def
trigger_auto_rollback
return
unless
triggered?
&&
critical?
&&
environment
&
.
auto_rollback_enabled?
::
Deployments
::
AutoRollbackWorker
.
perform_async
(
environment
.
id
)
end
end
end
end
ee/app/views/projects/settings/ci_cd/_auto_rollback.html.haml
View file @
2569cb80
...
...
@@ -23,7 +23,6 @@
=
s_
(
'AutoRollback|Enable automatic rollbacks'
)
%small
.form-text.text-gl-muted
=
s_
(
'AutoRollback|Automatic rollbacks start when a critical alert is triggered. If the last successful deployment fails to roll back automatically, it can still be done manually.'
)
-# This will be added once the documentation page has been created
-# = link_to _('More information'), help_page_path('topics/auto_rollback/index.md'), target: '_blank'
=
link_to
_
(
'More information'
),
help_page_path
(
'ci/environments/index.md'
,
anchor:
'auto-rollback'
),
target:
'_blank'
=
f
.
submit
_
(
'Save changes'
),
class:
"gl-button btn btn-success gl-mt-5"
,
data:
{
qa_selector:
'save_changes_button'
}
ee/spec/models/ee/alert_management/alert_spec.rb
0 → 100644
View file @
2569cb80
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
EE
::
AlertManagement
::
Alert
do
let_it_be
(
:project
,
refind:
true
)
{
create
(
:project
)
}
let_it_be
(
:environment
,
refind:
true
)
{
create
(
:environment
,
project:
project
)
}
describe
'after_create'
do
it
'attempts to trigger auto rollback'
do
alert
=
build
(
:alert_management_alert
,
:triggered
,
:critical
)
expect
(
alert
).
to
receive
(
:trigger_auto_rollback
)
alert
.
save!
end
end
describe
'#trigger_auto_rollback'
do
subject
{
alert
.
trigger_auto_rollback
}
let!
(
:alert
)
{
create
(
:alert_management_alert
,
:triggered
,
:critical
,
project:
project
,
environment:
environment
)
}
before
do
stub_licensed_features
(
auto_rollback:
true
)
environment
.
project
.
auto_rollback_enabled
=
true
end
it
'executes AutoRollbackWorker'
do
expect
(
Deployments
::
AutoRollbackWorker
).
to
receive
(
:perform_async
).
with
(
environment
.
id
)
subject
end
context
'when status is not triggered'
do
let!
(
:alert
)
{
create
(
:alert_management_alert
,
:acknowledged
,
:critical
,
project:
project
,
environment:
environment
)
}
it
'does not execute AutoRollbackWorker'
do
expect
(
Deployments
::
AutoRollbackWorker
).
not_to
receive
(
:perform_async
)
subject
end
end
context
'when severity is not critical'
do
let!
(
:alert
)
{
create
(
:alert_management_alert
,
:triggered
,
:high
,
project:
project
,
environment:
environment
)
}
it
'does not execute AutoRollbackWorker'
do
expect
(
Deployments
::
AutoRollbackWorker
).
not_to
receive
(
:perform_async
)
subject
end
end
context
'when project does not enable auto rollback'
do
before
do
environment
.
project
.
auto_rollback_enabled
=
false
end
it
'does not execute AutoRollbackWorker'
do
expect
(
Deployments
::
AutoRollbackWorker
).
not_to
receive
(
:perform_async
)
subject
end
end
context
'when project does not have a license for auto rollback'
do
before
do
stub_licensed_features
(
auto_rollback:
false
)
end
it
'does not execute AutoRollbackWorker'
do
expect
(
Deployments
::
AutoRollbackWorker
).
not_to
receive
(
:perform_async
)
subject
end
end
context
'when feature flag is disabled'
do
before
do
stub_feature_flags
(
cd_auto_rollback:
false
)
end
it
'does not execute AutoRollbackWorker'
do
expect
(
Deployments
::
AutoRollbackWorker
).
not_to
receive
(
:perform_async
)
subject
end
end
end
end
lib/api/helpers/members_helpers.rb
View file @
2569cb80
...
...
@@ -45,7 +45,7 @@ module API
end
def
find_all_members_for_project
(
project
)
MembersFinder
.
new
(
project
,
current_user
).
execute
(
include_relations:
[
:inherited
,
:direct
,
:invited_groups
_members
])
MembersFinder
.
new
(
project
,
current_user
).
execute
(
include_relations:
[
:inherited
,
:direct
,
:invited_groups
])
end
def
find_all_members_for_group
(
group
)
...
...
spec/finders/members_finder_spec.rb
View file @
2569cb80
...
...
@@ -160,8 +160,8 @@ RSpec.describe MembersFinder, '#execute' do
expect
(
result
).
to
eq
([
member3
,
member2
,
member1
])
end
context
'when
include_invited_groups_members == true
'
do
subject
{
described_class
.
new
(
project
,
user2
).
execute
(
include_relations:
[
:inherited
,
:direct
,
:invited_groups
_members
])
}
context
'when
:invited_groups is passed
'
do
subject
{
described_class
.
new
(
project
,
user2
).
execute
(
include_relations:
[
:inherited
,
:direct
,
:invited_groups
])
}
let_it_be
(
:linked_group
)
{
create
(
:group
,
:public
)
}
let_it_be
(
:nested_linked_group
)
{
create
(
:group
,
parent:
linked_group
)
}
...
...
spec/graphql/types/group_member_relation_enum_spec.rb
0 → 100644
View file @
2569cb80
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Types
::
GroupMemberRelationEnum
do
specify
{
expect
(
described_class
.
graphql_name
).
to
eq
(
'GroupMemberRelation'
)
}
it
'exposes all the existing group member relation type values'
do
expect
(
described_class
.
values
.
keys
).
to
contain_exactly
(
'DIRECT'
,
'INHERITED'
,
'DESCENDANTS'
)
end
end
spec/graphql/types/project_member_relation_enum_spec.rb
0 → 100644
View file @
2569cb80
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Types
::
ProjectMemberRelationEnum
do
specify
{
expect
(
described_class
.
graphql_name
).
to
eq
(
'ProjectMemberRelation'
)
}
it
'exposes all the existing project member relation type values'
do
expect
(
described_class
.
values
.
keys
).
to
contain_exactly
(
'DIRECT'
,
'INHERITED'
,
'DESCENDANTS'
,
'INVITED_GROUPS'
)
end
end
spec/models/alert_management/alert_spec.rb
View file @
2569cb80
...
...
@@ -99,7 +99,8 @@ RSpec.describe AlertManagement::Alert do
describe
'fingerprint'
do
let_it_be
(
:fingerprint
)
{
'fingerprint'
}
let
(
:new_alert
)
{
build
(
:alert_management_alert
,
fingerprint:
fingerprint
,
project:
project
)
}
let_it_be
(
:project3
,
refind:
true
)
{
create
(
:project
)
}
let
(
:new_alert
)
{
build
(
:alert_management_alert
,
fingerprint:
fingerprint
,
project:
project3
)
}
subject
{
new_alert
}
...
...
@@ -107,7 +108,7 @@ RSpec.describe AlertManagement::Alert do
context
'same project, various states'
do
using
RSpec
::
Parameterized
::
TableSyntax
let_it_be
(
:existing_alert
)
{
create
(
:alert_management_alert
,
fingerprint:
fingerprint
,
project:
project
)
}
let_it_be
(
:existing_alert
,
refind:
true
)
{
create
(
:alert_management_alert
,
fingerprint:
fingerprint
,
project:
project3
)
}
# We are only validating uniqueness for non-resolved alerts
where
(
:existing_status
,
:new_status
,
:valid
)
do
...
...
@@ -130,7 +131,7 @@ RSpec.describe AlertManagement::Alert do
end
with_them
do
let
(
:new_alert
)
{
build
(
:alert_management_alert
,
new_status
,
fingerprint:
fingerprint
,
project:
project
)
}
let
(
:new_alert
)
{
build
(
:alert_management_alert
,
new_status
,
fingerprint:
fingerprint
,
project:
project
3
)
}
before
do
existing_alert
.
change_status_to
(
existing_status
)
...
...
spec/requests/api/graphql/group/group_members_spec.rb
View file @
2569cb80
...
...
@@ -5,44 +5,95 @@ require 'spec_helper'
RSpec
.
describe
'getting group members information'
do
include
GraphqlHelpers
let_it_be
(
:group
)
{
create
(
:group
,
:public
)
}
let_it_be
(
:
parent_
group
)
{
create
(
:group
,
:public
)
}
let_it_be
(
:user
)
{
create
(
:user
)
}
let_it_be
(
:user_1
)
{
create
(
:user
,
username:
'user'
)
}
let_it_be
(
:user_2
)
{
create
(
:user
,
username:
'test'
)
}
let
(
:member_data
)
{
graphql_data
[
'group'
][
'groupMembers'
][
'edges'
]
}
before
do
[
user_1
,
user_2
].
each
{
|
user
|
group
.
add_guest
(
user
)
}
before
_all
do
[
user_1
,
user_2
].
each
{
|
user
|
parent_
group
.
add_guest
(
user
)
}
end
context
'when the request is correct'
do
it_behaves_like
'a working graphql query'
do
before
do
fetch_members
(
user
)
before
_all
do
fetch_members
end
end
it
'returns group members successfully'
do
fetch_members
(
user
)
fetch_members
expect
(
graphql_errors
).
to
be_nil
expect_array_response
(
user_1
.
to_global_id
.
to_s
,
user_2
.
to_global_id
.
to_s
)
expect_array_response
(
user_1
,
user_2
)
end
it
'returns members that match the search query'
do
fetch_members
(
user
,
{
search:
'test'
})
fetch_members
(
args:
{
search:
'test'
})
expect
(
graphql_errors
).
to
be_nil
expect_array_response
(
user_2
.
to_global_id
.
to_s
)
expect_array_response
(
user_2
)
end
end
def
fetch_members
(
user
=
nil
,
args
=
{})
post_graphql
(
members_query
(
args
),
current_user:
user
)
context
'member relations'
do
let_it_be
(
:child_group
)
{
create
(
:group
,
:public
,
parent:
parent_group
)
}
let_it_be
(
:grandchild_group
)
{
create
(
:group
,
:public
,
parent:
child_group
)
}
let_it_be
(
:child_user
)
{
create
(
:user
)
}
let_it_be
(
:grandchild_user
)
{
create
(
:user
)
}
before_all
do
child_group
.
add_guest
(
child_user
)
grandchild_group
.
add_guest
(
grandchild_user
)
end
it
'returns direct members'
do
fetch_members
(
group:
child_group
,
args:
{
relations:
[
:DIRECT
]
})
expect
(
graphql_errors
).
to
be_nil
expect_array_response
(
child_user
)
end
it
'returns direct and inherited members'
do
fetch_members
(
group:
child_group
,
args:
{
relations:
[
:DIRECT
,
:INHERITED
]
})
expect
(
graphql_errors
).
to
be_nil
expect_array_response
(
child_user
,
user_1
,
user_2
)
end
it
'returns direct, inherited, and descendant members'
do
fetch_members
(
group:
child_group
,
args:
{
relations:
[
:DIRECT
,
:INHERITED
,
:DESCENDANTS
]
})
expect
(
graphql_errors
).
to
be_nil
expect_array_response
(
child_user
,
user_1
,
user_2
,
grandchild_user
)
end
it
'returns an error for an invalid member relation'
do
fetch_members
(
group:
child_group
,
args:
{
relations:
[
:OBLIQUE
]
})
expect
(
graphql_errors
.
first
)
.
to
include
(
'path'
=>
%w[query group groupMembers relations]
,
'message'
=>
a_string_including
(
'invalid value ([OBLIQUE])'
))
end
end
context
'when unauthenticated'
do
it
'returns nothing'
do
fetch_members
(
current_user:
nil
)
expect
(
graphql_errors
).
to
be_nil
expect
(
response
).
to
have_gitlab_http_status
(
:success
)
expect
(
member_data
).
to
be_empty
end
end
def
fetch_members
(
group:
parent_group
,
current_user:
user
,
args:
{})
post_graphql
(
members_query
(
group
.
full_path
,
args
),
current_user:
current_user
)
end
def
members_query
(
args
=
{})
def
members_query
(
group_path
,
args
=
{})
members_node
=
<<~
NODE
edges {
node {
...
...
@@ -54,7 +105,7 @@ RSpec.describe 'getting group members information' do
NODE
graphql_query_for
(
"group"
,
{
full_path:
group
.
full
_path
},
{
full_path:
group_path
},
[
query_graphql_field
(
"groupMembers"
,
args
,
members_node
)]
)
end
...
...
@@ -62,6 +113,7 @@ RSpec.describe 'getting group members information' do
def
expect_array_response
(
*
items
)
expect
(
response
).
to
have_gitlab_http_status
(
:success
)
expect
(
member_data
).
to
be_an
Array
expect
(
member_data
.
map
{
|
node
|
node
[
"node"
][
"user"
][
"id"
]
}).
to
match_array
(
items
)
expect
(
member_data
.
map
{
|
node
|
node
[
"node"
][
"user"
][
"id"
]
})
.
to
match_array
(
items
.
map
{
|
u
|
global_id_of
(
u
)
})
end
end
spec/requests/api/graphql/project/project_members_spec.rb
0 → 100644
View file @
2569cb80
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
'getting project members information'
do
include
GraphqlHelpers
let_it_be
(
:parent_group
)
{
create
(
:group
,
:public
)
}
let_it_be
(
:parent_project
)
{
create
(
:project
,
:public
,
group:
parent_group
)
}
let_it_be
(
:user
)
{
create
(
:user
)
}
let_it_be
(
:user_1
)
{
create
(
:user
,
username:
'user'
)
}
let_it_be
(
:user_2
)
{
create
(
:user
,
username:
'test'
)
}
let
(
:member_data
)
{
graphql_data
[
'project'
][
'projectMembers'
][
'edges'
]
}
before_all
do
[
user_1
,
user_2
].
each
{
|
user
|
parent_group
.
add_guest
(
user
)
}
end
context
'when the request is correct'
do
it_behaves_like
'a working graphql query'
do
before_all
do
fetch_members
(
project:
parent_project
)
end
end
it
'returns project members successfully'
do
fetch_members
(
project:
parent_project
)
expect
(
graphql_errors
).
to
be_nil
expect_array_response
(
user_1
,
user_2
)
end
it
'returns members that match the search query'
do
fetch_members
(
project:
parent_project
,
args:
{
search:
'test'
})
expect
(
graphql_errors
).
to
be_nil
expect_array_response
(
user_2
)
end
end
context
'member relations'
do
let_it_be
(
:child_group
)
{
create
(
:group
,
:public
,
parent:
parent_group
)
}
let_it_be
(
:child_project
)
{
create
(
:project
,
:public
,
group:
child_group
)
}
let_it_be
(
:invited_group
)
{
create
(
:group
,
:public
)
}
let_it_be
(
:child_user
)
{
create
(
:user
)
}
let_it_be
(
:invited_user
)
{
create
(
:user
)
}
let_it_be
(
:group_link
)
{
create
(
:project_group_link
,
project:
child_project
,
group:
invited_group
)
}
before_all
do
child_project
.
add_guest
(
child_user
)
invited_group
.
add_guest
(
invited_user
)
end
it
'returns direct members'
do
fetch_members
(
project:
child_project
,
args:
{
relations:
[
:DIRECT
]
})
expect
(
graphql_errors
).
to
be_nil
expect_array_response
(
child_user
)
end
it
'returns invited members plus inherited members'
do
fetch_members
(
project:
child_project
,
args:
{
relations:
[
:INVITED_GROUPS
]
})
expect
(
graphql_errors
).
to
be_nil
expect_array_response
(
invited_user
,
user_1
,
user_2
)
end
it
'returns direct, inherited, descendant, and invited members'
do
fetch_members
(
project:
child_project
,
args:
{
relations:
[
:DIRECT
,
:INHERITED
,
:DESCENDANTS
,
:INVITED_GROUPS
]
})
expect
(
graphql_errors
).
to
be_nil
expect_array_response
(
child_user
,
user_1
,
user_2
,
invited_user
)
end
it
'returns an error for an invalid member relation'
do
fetch_members
(
project:
child_project
,
args:
{
relations:
[
:OBLIQUE
]
})
expect
(
graphql_errors
.
first
)
.
to
include
(
'path'
=>
%w[query project projectMembers relations]
,
'message'
=>
a_string_including
(
'invalid value ([OBLIQUE])'
))
end
end
context
'when unauthenticated'
do
it
'returns members'
do
fetch_members
(
current_user:
nil
,
project:
parent_project
)
expect
(
graphql_errors
).
to
be_nil
expect_array_response
(
user_1
,
user_2
)
end
end
def
fetch_members
(
project
:,
current_user:
user
,
args:
{})
post_graphql
(
members_query
(
project
.
full_path
,
args
),
current_user:
current_user
)
end
def
members_query
(
group_path
,
args
=
{})
members_node
=
<<~
NODE
edges {
node {
user {
id
}
}
}
NODE
graphql_query_for
(
'project'
,
{
full_path:
group_path
},
[
query_graphql_field
(
'projectMembers'
,
args
,
members_node
)]
)
end
def
expect_array_response
(
*
items
)
expect
(
response
).
to
have_gitlab_http_status
(
:success
)
expect
(
member_data
).
to
be_an
Array
expect
(
member_data
.
map
{
|
node
|
node
[
'node'
][
'user'
][
'id'
]
})
.
to
match_array
(
items
.
map
{
|
u
|
global_id_of
(
u
)
})
end
end
spec/support/shared_examples/graphql/members_shared_examples.rb
View file @
2569cb80
...
...
@@ -36,9 +36,10 @@ RSpec.shared_examples 'querying members with a group' do
let_it_be
(
:group_2_member
)
{
create
(
:group_member
,
user:
user_3
,
group:
group_2
)
}
let
(
:args
)
{
{}
}
let
(
:base_args
)
{
{
relations:
described_class
.
arguments
[
'relations'
].
default_value
}
}
subject
do
resolve
(
described_class
,
obj:
resource
,
args:
args
,
ctx:
{
current_user:
user_4
})
resolve
(
described_class
,
obj:
resource
,
args:
base_args
.
merge
(
args
)
,
ctx:
{
current_user:
user_4
})
end
describe
'#resolve'
do
...
...
@@ -72,7 +73,7 @@ RSpec.shared_examples 'querying members with a group' do
let_it_be
(
:other_user
)
{
create
(
:user
)
}
subject
do
resolve
(
described_class
,
obj:
resource
,
args:
args
,
ctx:
{
current_user:
other_user
})
resolve
(
described_class
,
obj:
resource
,
args:
base_args
.
merge
(
args
)
,
ctx:
{
current_user:
other_user
})
end
it
'raises an error'
do
...
...
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