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
d7b64118
Commit
d7b64118
authored
Dec 21, 2021
by
Jose Ivan Vargas
Committed by
Mikołaj Wawrzyniak
Dec 21, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add namespace to the ci_minutes_usage resolver
parent
0ecee668
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
194 additions
and
52 deletions
+194
-52
doc/api/graphql/reference/index.md
doc/api/graphql/reference/index.md
+7
-1
ee/app/graphql/ee/types/query_type.rb
ee/app/graphql/ee/types/query_type.rb
+20
-4
ee/app/graphql/types/ci/minutes/namespace_monthly_usage_type.rb
.../graphql/types/ci/minutes/namespace_monthly_usage_type.rb
+1
-0
ee/app/policies/ci/minutes/namespace_monthly_usage_policy.rb
ee/app/policies/ci/minutes/namespace_monthly_usage_policy.rb
+11
-0
ee/spec/policies/ci/minutes/namespace_monthly_usage_policy_spec.rb
...olicies/ci/minutes/namespace_monthly_usage_policy_spec.rb
+48
-0
ee/spec/requests/api/graphql/ci/minutes/usage_spec.rb
ee/spec/requests/api/graphql/ci/minutes/usage_spec.rb
+107
-47
No files found.
doc/api/graphql/reference/index.md
View file @
d7b64118
...
...
@@ -73,7 +73,7 @@ Returns [`CiConfig`](#ciconfig).
### `Query.ciMinutesUsage`
Monthly CI minutes usage data for the current user
.
CI/CD minutes usage data for a namespace
.
Returns [`CiMinutesNamespaceMonthlyUsageConnection`](#ciminutesnamespacemonthlyusageconnection).
...
...
@@ -81,6 +81,12 @@ This field returns a [connection](#connections). It accepts the
four standard [pagination arguments](#connection-pagination-arguments):
`before: String`, `after: String`, `first: Int`, `last: Int`.
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="queryciminutesusagenamespaceid"></a>`namespaceId` | [`NamespaceID`](#namespaceid) | Global ID of the Namespace for the monthly CI/CD minutes usage. |
### `Query.containerRepository`
Find a container repository.
ee/app/graphql/ee/types/query_type.rb
View file @
d7b64118
...
...
@@ -4,7 +4,6 @@ module EE
module
Types
module
QueryType
extend
ActiveSupport
::
Concern
prepended
do
field
:iteration
,
::
Types
::
IterationType
,
null:
true
,
...
...
@@ -70,7 +69,12 @@ module EE
field
:ci_minutes_usage
,
::
Types
::
Ci
::
Minutes
::
NamespaceMonthlyUsageType
.
connection_type
,
null:
true
,
description:
'Monthly CI minutes usage data for the current user.'
description:
'CI/CD minutes usage data for a namespace.'
do
argument
:namespace_id
,
::
Types
::
GlobalIDType
[
::
Namespace
],
required:
false
,
description:
'Global ID of the Namespace for the monthly CI/CD minutes usage.'
end
end
def
vulnerability
(
id
:)
...
...
@@ -87,8 +91,20 @@ module EE
::
GitlabSchema
.
find_by_gid
(
id
)
end
def
ci_minutes_usage
::
Ci
::
Minutes
::
NamespaceMonthlyUsage
.
for_namespace
(
current_user
.
namespace
)
def
ci_minutes_usage
(
namespace_id:
nil
)
root_namespace
=
find_root_namespace
(
namespace_id
)
::
Ci
::
Minutes
::
NamespaceMonthlyUsage
.
for_namespace
(
root_namespace
)
end
private
def
find_root_namespace
(
namespace_id
)
return
current_user
&
.
namespace
unless
namespace_id
namespace
=
::
Gitlab
::
Graphql
::
Lazy
.
force
(
::
GitlabSchema
.
find_by_gid
(
namespace_id
))
return
unless
namespace
&
.
root?
namespace
end
end
end
...
...
ee/app/graphql/types/ci/minutes/namespace_monthly_usage_type.rb
View file @
d7b64118
...
...
@@ -7,6 +7,7 @@ module Types
# this type only exposes data related to the current user
class
NamespaceMonthlyUsageType
<
BaseObject
graphql_name
'CiMinutesNamespaceMonthlyUsage'
authorize
:read_usage
field
:month
,
::
GraphQL
::
Types
::
String
,
null:
true
,
description:
'Month related to the usage data.'
...
...
ee/app/policies/ci/minutes/namespace_monthly_usage_policy.rb
0 → 100644
View file @
d7b64118
# frozen_string_literal: true
module
Ci
module
Minutes
class
NamespaceMonthlyUsagePolicy
<
BasePolicy
delegate
{
@subject
.
namespace
}
rule
{
can?
(
:owner_access
)
}.
enable
:read_usage
end
end
end
ee/spec/policies/ci/minutes/namespace_monthly_usage_policy_spec.rb
0 → 100644
View file @
d7b64118
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Ci
::
Minutes
::
NamespaceMonthlyUsagePolicy
do
let
(
:group
)
{
create
(
:group
,
:private
,
name:
'test'
)
}
let
(
:current_user
)
{
create
(
:user
)
}
let
(
:namespace_monthly_usage
)
do
create
(
:ci_namespace_monthly_usage
,
namespace:
group
)
end
subject
(
:policy
)
do
described_class
.
new
(
current_user
,
namespace_monthly_usage
)
end
context
'with an owner'
do
before
do
group
.
add_owner
(
current_user
)
end
it
{
is_expected
.
to
be_allowed
(
:read_usage
)
}
end
context
'with a developer'
do
before
do
group
.
add_developer
(
current_user
)
end
it
{
is_expected
.
not_to
be_allowed
(
:read_usage
)
}
end
context
"with a user's namespace"
do
let
(
:namespace_monthly_usage
)
do
create
(
:ci_namespace_monthly_usage
,
namespace:
current_user
.
namespace
)
end
it
{
is_expected
.
to
be_allowed
(
:read_usage
)
}
end
context
'with a different namespace'
do
let
(
:namespace_monthly_usage
)
do
create
(
:ci_namespace_monthly_usage
,
namespace:
create
(
:user
).
namespace
)
end
it
{
is_expected
.
not_to
be_allowed
(
:read_usage
)
}
end
end
ee/spec/requests/api/graphql/ci/minutes/usage_spec.rb
View file @
d7b64118
...
...
@@ -6,70 +6,130 @@ RSpec.describe 'Query.ciMinutesUsage' do
include
GraphqlHelpers
let_it_be
(
:user
)
{
create
(
:user
)
}
let_it_be
(
:project
)
{
create
(
:project
,
name:
'Project 1'
,
namespace:
user
.
namespace
)
}
let_it_be
(
:user_project
)
{
create
(
:project
,
name:
'Project 1'
,
namespace:
user
.
namespace
)
}
let_it_be_with_refind
(
:group
)
{
create
(
:group
,
:public
,
name:
'test'
)
}
before
(
:all
)
do
create
(
:ci_namespace_monthly_usage
,
namespace:
user
.
namespace
,
amount_used:
50
,
date:
Date
.
new
(
2021
,
5
,
1
))
create
(
:ci_project_monthly_usage
,
project:
project
,
amount_used:
50
,
date:
Date
.
new
(
2021
,
5
,
1
))
create
(
:ci_project_monthly_usage
,
project:
user_project
,
amount_used:
40
,
date:
Date
.
new
(
2021
,
5
,
1
))
create
(
:ci_namespace_monthly_usage
,
namespace:
group
,
amount_used:
100
,
date:
Date
.
new
(
2021
,
6
,
1
))
end
it
'returns usage data by month for the current user'
do
query
=
<<-
QUERY
{
ciMinutesUsage {
nodes {
minutes
month
projects {
nodes {
name
minutes
subject
(
:result
)
{
post_graphql
(
query
,
current_user:
user
)
}
context
'when no namespace_id is provided'
do
let
(
:query
)
do
<<-
QUERY
{
ciMinutesUsage {
nodes {
minutes
month
projects {
nodes {
name
minutes
}
}
}
}
}
}
QUERY
post_graphql
(
query
,
current_user:
user
)
monthly_usage
=
graphql_data_at
(
:ci_minutes_usage
,
:nodes
)
expect
(
monthly_usage
).
to
contain_exactly
({
'month'
=>
'May'
,
'minutes'
=>
50
,
'projects'
=>
{
'nodes'
=>
[{
'name'
=>
'Project 1'
,
'minutes'
=>
50
}]
}
})
QUERY
end
it
'returns usage data by month for the current user'
do
subject
monthly_usage
=
graphql_data_at
(
:ci_minutes_usage
,
:nodes
)
expect
(
monthly_usage
).
to
contain_exactly
({
'month'
=>
'May'
,
'minutes'
=>
50
,
'projects'
=>
{
'nodes'
=>
[{
'name'
=>
'Project 1'
,
'minutes'
=>
40
}]
}
})
end
it
'does not create N+1 queries'
do
control_count
=
ActiveRecord
::
QueryRecorder
.
new
do
post_graphql
(
query
,
current_user:
user
)
end
expect
(
graphql_errors
).
to
be_nil
project_2
=
create
(
:project
,
name:
'Project 2'
,
namespace:
user
.
namespace
)
create
(
:ci_project_monthly_usage
,
project:
project_2
,
amount_used:
50
,
date:
Date
.
new
(
2021
,
5
,
1
))
expect
do
post_graphql
(
query
,
current_user:
user
)
end
.
not_to
exceed_query_limit
(
control_count
)
expect
(
graphql_errors
).
to
be_nil
end
end
it
'does not create N+1 queries'
do
query
=
<<-
QUERY
{
ciMinutesUsage {
nodes {
projects {
nodes {
name
}
context
'when namespace_id is provided'
do
let
(
:namespace
)
{
group
}
let
(
:query
)
do
<<-
QUERY
{
ciMinutesUsage(namespaceId: "
#{
namespace
.
to_global_id
}
") {
nodes {
minutes
month
}
}
}
}
QUERY
QUERY
end
context
'when group is root'
do
context
'when user is an owner'
do
before
do
group
.
add_owner
(
user
)
end
it
'returns the usage data'
do
subject
monthly_usage
=
graphql_data_at
(
:ci_minutes_usage
,
:nodes
)
expect
(
monthly_usage
).
to
contain_exactly
({
'month'
=>
'June'
,
'minutes'
=>
100
})
end
end
control_count
=
ActiveRecord
::
QueryRecorder
.
new
do
post_graphql
(
query
,
current_user:
user
)
context
'when user is not an owner'
do
before
do
group
.
add_developer
(
user
)
end
it
'does not return usage data'
do
subject
monthly_usage
=
graphql_data_at
(
:ci_minutes_usage
,
:nodes
)
expect
(
monthly_usage
).
to
be_empty
end
end
end
expect
(
graphql_errors
).
to
be_nil
project_2
=
create
(
:project
,
name:
'Project 2'
,
namespace:
user
.
namespace
)
create
(
:ci_project_monthly_usage
,
project:
project_2
,
amount_used:
50
,
date:
Date
.
new
(
2021
,
5
,
1
))
context
'when group is a subgroup'
do
let
(
:subgroup
)
{
create
(
:group
,
:public
,
parent:
group
)
}
let
(
:namespace
)
{
subgroup
}
before
do
create
(
:ci_namespace_monthly_usage
,
namespace:
subgroup
)
subgroup
.
add_owner
(
user
)
end
expect
do
post_graphql
(
query
,
current_user:
user
)
end
.
not_to
exceed_query_limit
(
control_count
)
expect
(
graphql_errors
).
to
be_nil
it
'does not return usage data'
do
subject
monthly_usage
=
graphql_data_at
(
:ci_minutes_usage
,
:nodes
)
expect
(
monthly_usage
).
to
be_empty
end
end
end
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