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
048aa1c7
Commit
048aa1c7
authored
Apr 16, 2020
by
Doug Stull
Committed by
Dmytro Zaporozhets
Apr 16, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add logic to show buy ci minutes link
- needed for experiment
parent
20d1bda1
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
396 additions
and
345 deletions
+396
-345
app/views/layouts/header/_current_user_dropdown.html.haml
app/views/layouts/header/_current_user_dropdown.html.haml
+1
-1
ee/app/helpers/ee/runners_helper.rb
ee/app/helpers/ee/runners_helper.rb
+18
-6
ee/app/models/ci/minutes/context.rb
ee/app/models/ci/minutes/context.rb
+21
-0
ee/app/models/ci/minutes/threshold.rb
ee/app/models/ci/minutes/threshold.rb
+34
-0
ee/app/models/ee/project.rb
ee/app/models/ee/project.rb
+2
-1
ee/app/services/ci/minutes_notification_service.rb
ee/app/services/ci/minutes_notification_service.rb
+0
-78
ee/app/views/layouts/header/_buy_ci_minutes.html.haml
ee/app/views/layouts/header/_buy_ci_minutes.html.haml
+1
-1
ee/app/views/layouts/header/_user_notification_dot.html.haml
ee/app/views/layouts/header/_user_notification_dot.html.haml
+1
-1
ee/app/views/shared/_shared_runners_minutes_limit.html.haml
ee/app/views/shared/_shared_runners_minutes_limit.html.haml
+5
-4
ee/spec/helpers/ee/runners_helper_spec.rb
ee/spec/helpers/ee/runners_helper_spec.rb
+84
-41
ee/spec/models/ci/minutes/context_spec.rb
ee/spec/models/ci/minutes/context_spec.rb
+50
-0
ee/spec/models/ci/minutes/threshold_spec.rb
ee/spec/models/ci/minutes/threshold_spec.rb
+177
-0
ee/spec/models/project_spec.rb
ee/spec/models/project_spec.rb
+1
-0
ee/spec/services/ci/minutes_notification_service_spec.rb
ee/spec/services/ci/minutes_notification_service_spec.rb
+0
-211
ee/spec/views/layouts/application.html.haml_spec.rb
ee/spec/views/layouts/application.html.haml_spec.rb
+1
-1
No files found.
app/views/layouts/header/_current_user_dropdown.html.haml
View file @
048aa1c7
...
...
@@ -26,7 +26,7 @@
-
if
current_user_menu?
(
:settings
)
%li
=
link_to
s_
(
"CurrentUser|Settings"
),
profile_path
,
data:
{
qa_selector:
'settings_link'
}
=
render_if_exists
'layouts/header/buy_ci_minutes'
=
render_if_exists
'layouts/header/buy_ci_minutes'
,
project:
@project
,
namespace:
@group
-
if
current_user_menu?
(
:help
)
%li
.divider.d-md-none
...
...
ee/app/helpers/ee/runners_helper.rb
View file @
048aa1c7
# frozen_string_literal: true
module
EE
module
RunnersHelper
include
::
Gitlab
::
Utils
::
StrongMemoize
def
ci_usage_warning_message
(
namespace
,
project
)
message
=
[
ci_usage_base_message
(
namespace
)]
...
...
@@ -15,20 +17,30 @@ module EE
message
.
join
(
' '
).
html_safe
end
def
show_buy_ci_minutes?
experiment_enabled?
(
:buy_ci_minutes_version_a
)
def
show_buy_ci_minutes?
(
project
,
namespace
)
return
false
unless
experiment_enabled?
(
:ci_notification_dot
)
||
experiment_enabled?
(
:buy_ci_minutes_version_a
)
show_out_of_ci_minutes_notification?
(
project
,
namespace
)
end
def
show_
user
_notification_dot?
(
project
,
namespace
)
def
show_
ci_minutes
_notification_dot?
(
project
,
namespace
)
return
false
unless
experiment_enabled?
(
:ci_notification_dot
)
return
false
unless
project
&
.
persisted?
||
namespace
&
.
persisted?
::
Ci
::
MinutesNotificationService
.
call
(
current_user
,
project
,
namespace
).
show_notification?
&&
current_user
.
pipelines
.
any?
show_out_of_ci_minutes_notification?
(
project
,
namespace
)
end
private
def
show_out_of_ci_minutes_notification?
(
project
,
namespace
)
strong_memoize
(
:show_out_of_ci_minutes_notification
)
do
next
unless
project
&
.
persisted?
||
namespace
&
.
persisted?
context
=
::
Ci
::
Minutes
::
Context
.
new
(
project
,
namespace
)
threshold
=
::
Ci
::
Minutes
::
Threshold
.
new
(
current_user
,
context
.
level
)
threshold
.
warning_reached?
&&
context
.
namespace
.
all_pipelines
.
for_user
(
current_user
).
any?
end
end
def
purchase_shared_runner_minutes_link
link
=
link_to
(
_
(
"Click here"
),
EE
::
SUBSCRIPTIONS_PLANS_URL
,
target:
'_blank'
,
rel:
'noopener'
)
...
...
ee/app/models/ci/minutes/context.rb
0 → 100644
View file @
048aa1c7
# frozen_string_literal: true
module
Ci
module
Minutes
class
Context
attr_reader
:namespace
,
:level
delegate
:full_path
,
to: :level
def
initialize
(
project
,
namespace
)
@project
=
project
@namespace
=
project
&
.
shared_runners_limit_namespace
||
namespace
@level
=
project
||
namespace
end
private
attr_reader
:project
end
end
end
ee/app/models/ci/minutes/threshold.rb
0 → 100644
View file @
048aa1c7
# frozen_string_literal: true
module
Ci
module
Minutes
class
Threshold
include
Gitlab
::
Allowable
def
initialize
(
user
,
context_level
)
@context_level
=
context_level
@user
=
user
end
def
warning_reached?
show_limit?
&&
context_level
.
shared_runners_remaining_minutes_below_threshold?
end
def
alert_reached?
show_limit?
&&
context_level
.
shared_runners_minutes_used?
end
private
attr_reader
:user
,
:context_level
def
show_limit?
context_level
.
shared_runners_minutes_limit_enabled?
&&
can_see_status?
end
def
can_see_status?
context_level
.
is_a?
(
Namespace
)
||
can?
(
user
,
:create_pipeline
,
context_level
)
end
end
end
end
ee/app/models/ee/project.rb
View file @
048aa1c7
...
...
@@ -155,7 +155,8 @@ module EE
to: :statistics
,
allow_nil:
true
delegate
:actual_shared_runners_minutes_limit
,
:shared_runners_minutes_used?
,
to: :shared_runners_limit_namespace
:shared_runners_minutes_used?
,
:shared_runners_remaining_minutes_below_threshold?
,
to: :shared_runners_limit_namespace
delegate
:last_update_succeeded?
,
:last_update_failed?
,
:ever_updated_successfully?
,
:hard_failed?
,
...
...
ee/app/services/ci/minutes_notification_service.rb
deleted
100644 → 0
View file @
20d1bda1
# frozen_string_literal: true
module
Ci
class
MinutesNotificationService
include
Gitlab
::
Allowable
attr_reader
:namespace
def
self
.
call
(
*
args
)
new
(
*
args
).
call
end
def
initialize
(
current_user
,
project
,
namespace
)
@current_user
=
current_user
@project
=
project
@namespace
=
namespace
end
def
call
calculate
self
end
def
show_notification?
can_see_limit_reached?
&&
namespace
.
shared_runners_remaining_minutes_below_threshold?
end
def
show_alert?
can_see_limit_reached?
&&
below_threshold?
end
def
scope
level
.
full_path
end
private
attr_reader
:project
,
:can_see_status
,
:has_limit
,
:current_user
,
:level
def
calculate
if
at_namespace_level?
calculate_from_namespace_level
else
calculate_from_project_level
end
@has_limit
=
level
.
shared_runners_minutes_limit_enabled?
end
def
at_namespace_level?
namespace
&&
!
project
end
def
calculate_from_namespace_level
@level
=
namespace
@can_see_status
=
true
end
def
calculate_from_project_level
@level
=
project
@namespace
=
project
.
shared_runners_limit_namespace
@can_see_status
=
can?
(
current_user
,
:create_pipeline
,
project
)
end
def
can_see_limit_reached?
has_limit
&&
can_see_status
end
def
below_threshold?
namespace
.
shared_runners_minutes_used?
||
namespace
.
shared_runners_remaining_minutes_below_threshold?
end
end
end
ee/app/views/layouts/header/_buy_ci_minutes.html.haml
View file @
048aa1c7
-
return
unless
show_buy_ci_minutes?
-
return
unless
show_buy_ci_minutes?
(
project
,
namespace
)
%li
=
link_to
profile_pipeline_quota_path
,
...
...
ee/app/views/layouts/header/_user_notification_dot.html.haml
View file @
048aa1c7
-
return
unless
show_
user
_notification_dot?
(
project
,
namespace
)
-
return
unless
show_
ci_minutes
_notification_dot?
(
project
,
namespace
)
-# Tracking events from the template is not ideal and we are moving this to the client in https://gitlab.com/gitlab-org/gitlab/-/issues/213712
-
track_event
(
'show_buy_ci_minutes_notification'
,
label:
current_user
.
namespace
.
actual_plan_name
,
property:
'user_dropdown'
)
...
...
ee/app/views/shared/_shared_runners_minutes_limit.html.haml
View file @
048aa1c7
-
notification_service
=
::
Ci
::
MinutesNotificationService
.
call
(
current_user
,
local_assigns
.
dig
(
:project
),
local_assigns
.
dig
(
:namespace
))
-
context
=
::
Ci
::
Minutes
::
Context
.
new
(
local_assigns
.
dig
(
:project
),
local_assigns
.
dig
(
:namespace
))
-
threshold
=
::
Ci
::
Minutes
::
Threshold
.
new
(
current_user
,
context
.
level
)
-
if
notification_service
.
show_alert
?
-
if
threshold
.
warning_reached?
||
threshold
.
alert_reached
?
%div
{
class:
[
"pt-2"
,
(
classes
if
defined?
classes
)]
}
.bs-callout.shared-runner-quota-message.d-none.d-sm-block.bs-callout-danger
{
data:
{
scope:
notification_service
.
scope
}
}
.bs-callout.shared-runner-quota-message.d-none.d-sm-block.bs-callout-danger
{
data:
{
scope:
context
.
full_path
}
}
%p
=
ci_usage_warning_message
(
notification_service
.
namespace
,
project
)
=
ci_usage_warning_message
(
context
.
namespace
,
project
)
=
link_to
_
(
'Purchase more minutes'
),
::
EE
::
SUBSCRIPTIONS_MORE_MINUTES_URL
,
class:
"btn btn-danger btn-inverted"
ee/spec/helpers/ee/runners_helper_spec.rb
View file @
048aa1c7
...
...
@@ -3,7 +3,11 @@
require
"spec_helper"
describe
EE
::
RunnersHelper
do
let_it_be
(
:user
)
{
create
(
:user
)
}
let_it_be
(
:user
,
reload:
true
)
{
create
(
:user
)
}
before
do
allow
(
helper
).
to
receive
(
:current_user
).
and_return
(
user
)
end
describe
'.ci_usage_warning_message'
do
let
(
:project
)
{
create
(
:project
,
namespace:
namespace
)
}
...
...
@@ -140,43 +144,23 @@ describe EE::RunnersHelper do
end
end
describe
'.show_buy_ci_minutes?
'
do
subject
{
helper
.
show_buy_ci_minutes?
}
context
'when experiment is disabled'
do
before
do
allow
(
helper
).
to
receive
(
:experiment_enabled?
).
with
(
:buy_ci_minutes_version_a
).
and_return
(
false
)
end
it
{
is_expected
.
to
be_falsey
}
end
shared_examples_for
'minutes notification
'
do
let_it_be
(
:namespace
)
{
create
(
:namespace
,
owner:
user
)
}
let_it_be
(
:project
)
{
create
(
:project
,
namespace:
namespace
)
}
let
(
:injected_project
)
{
project
}
let
(
:injected_namespace
)
{
namespace
}
let
(
:show_warning
)
{
true
}
let
(
:context_level
)
{
project
}
let
(
:context
)
{
double
(
'Ci::Minutes::Context'
,
level:
context_level
,
namespace:
namespace
)
}
let
(
:threshold
)
{
double
(
'Ci::Minutes::Threshold'
,
warning_reached?:
show_warning
)
}
let!
(
:user_pipeline
)
{
create
(
:ci_pipeline
,
user:
user
,
project:
project
)
}
context
'when experiment is enabled'
do
before
do
allow
(
helper
).
to
receive
(
:experiment_enabled?
).
with
(
:buy_ci_minutes_version_a
).
and_return
(
true
)
end
it
{
is_expected
.
to
be_truthy
}
end
end
describe
'.show_user_notification_dot?'
do
let
(
:experiment_status
)
{
true
}
let
(
:ci_minutes_show
)
{
true
}
let!
(
:user_pipelines
)
{
create
(
:ci_pipeline
,
user:
user
,
project:
nil
)
}
subject
{
helper
.
show_user_notification_dot?
(
project
,
namespace
)
}
before
do
allow
(
helper
).
to
receive
(
:current_user
).
and_return
(
user
)
allow
(
helper
).
to
receive
(
:experiment_enabled?
).
with
(
:ci_notification_dot
).
and_return
(
experiment_status
)
allow
(
::
Ci
::
MinutesNotificationService
).
to
receive_message_chain
(
:call
,
:show_notification?
).
and_return
(
ci_minutes_show
)
allow
(
::
Ci
::
Minutes
::
Context
).
to
receive
(
:new
).
and_return
(
context
)
allow
(
::
Ci
::
Minutes
::
Threshold
).
to
receive
(
:new
).
and_return
(
threshold
)
end
context
'with a project and namespace'
do
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:namespace
)
{
create
(
:namespace
)
}
context
'when experiment is disabled'
do
let
(
:experiment_status
)
{
false
}
...
...
@@ -186,38 +170,97 @@ describe EE::RunnersHelper do
context
'when experiment is enabled with user pipelines'
do
it
{
is_expected
.
to
be_truthy
}
context
'without a project'
do
let
(
:project
)
{
build
(
:project
)
}
context
'without a persisted project passed'
do
let
(
:injected_project
)
{
build
(
:project
)
}
let
(
:context_level
)
{
namespace
}
it
{
is_expected
.
to
be_truthy
}
end
context
'without a
namespace
'
do
let
(
:namespace
)
{
build
(
:namespace
)
}
context
'without a
persisted namespace passed
'
do
let
(
:
injected_
namespace
)
{
build
(
:namespace
)
}
it
{
is_expected
.
to
be_truthy
}
end
context
'with neither a project nor a namespace'
do
let
(
:project
)
{
build
(
:project
)
}
let
(
:namespace
)
{
build
(
:namespace
)
}
let
(
:
injected_
project
)
{
build
(
:project
)
}
let
(
:
injected_
namespace
)
{
build
(
:namespace
)
}
it
{
is_expected
.
to
be_falsey
}
context
'when show_ci_minutes_notification_dot? has been called before'
do
it
'does not do all the notification and query work again'
do
expect
(
threshold
).
not_to
receive
(
:warning_reached?
)
expect
(
injected_project
).
to
receive
(
:persisted?
).
once
helper
.
show_ci_minutes_notification_dot?
(
injected_project
,
injected_namespace
)
expect
(
subject
).
to
be_falsey
end
end
end
context
'when show notification is falsey'
do
let
(
:
ci_minutes_show
)
{
false
}
let
(
:
show_warning
)
{
false
}
it
{
is_expected
.
to
be_falsey
}
end
context
'without user pipelines'
do
before
do
user
.
pipelines
.
clear
user
.
pipelines
.
clear
# this forces us to reload user for let_it_be
end
it
{
is_expected
.
to
be_falsey
}
end
context
'when show_ci_minutes_notification_dot? has been called before'
do
it
'does not do all the notification and query work again'
do
expect
(
threshold
).
to
receive
(
:warning_reached?
).
once
expect
(
project
).
to
receive
(
:persisted?
).
once
helper
.
show_ci_minutes_notification_dot?
(
project
,
namespace
)
expect
(
subject
).
to
be_truthy
end
end
end
end
end
context
'with pipelines'
do
let
(
:experiment_status
)
{
true
}
describe
'.show_buy_ci_minutes?'
do
subject
{
helper
.
show_buy_ci_minutes?
(
injected_project
,
injected_namespace
)
}
context
'when experiment is "ci_notification_dot"'
do
it_behaves_like
'minutes notification'
do
before
do
allow
(
helper
).
to
receive
(
:experiment_enabled?
).
with
(
:ci_notification_dot
).
and_return
(
experiment_status
)
allow
(
helper
).
to
receive
(
:experiment_enabled?
).
with
(
:buy_ci_minutes_version_a
).
and_return
(
false
)
end
end
end
context
'when experiment is "ci_minutes_version_a"'
do
it_behaves_like
'minutes notification'
do
before
do
allow
(
helper
).
to
receive
(
:experiment_enabled?
).
with
(
:ci_notification_dot
).
and_return
(
false
)
allow
(
helper
).
to
receive
(
:experiment_enabled?
).
with
(
:buy_ci_minutes_version_a
).
and_return
(
experiment_status
)
end
end
end
end
describe
'.show_ci_minutes_notification_dot?'
do
subject
{
helper
.
show_ci_minutes_notification_dot?
(
injected_project
,
injected_namespace
)
}
it_behaves_like
'minutes notification'
do
before
do
allow
(
helper
).
to
receive
(
:experiment_enabled?
).
with
(
:ci_notification_dot
).
and_return
(
experiment_status
)
end
end
end
end
...
...
ee/spec/models/ci/minutes/context_spec.rb
0 → 100644
View file @
048aa1c7
# frozen_string_literal: true
require
'spec_helper'
describe
Ci
::
Minutes
::
Context
do
let_it_be
(
:group
)
{
create
(
:group
)
}
let
(
:project
)
{
build
(
:project
,
namespace:
group
)
}
shared_examples
'full path'
do
describe
'#full_path'
do
it
'shows full path'
do
expect
(
subject
.
full_path
).
to
eq
context
.
full_path
end
end
describe
'#level'
do
it
'assigns correct level of namespace or project'
do
expect
(
subject
.
level
).
to
eq
context
end
end
end
shared_examples
'captures root namespace'
do
describe
'#namespace'
do
it
'assigns the namespace'
do
expect
(
subject
.
namespace
).
to
eq
group
end
end
end
context
'when at project level'
do
subject
{
described_class
.
new
(
project
,
nil
)
}
it_behaves_like
'captures root namespace'
it_behaves_like
'full path'
do
let
(
:context
)
{
project
}
end
end
context
'when at namespace level'
do
subject
{
described_class
.
new
(
nil
,
group
)
}
it_behaves_like
'captures root namespace'
it_behaves_like
'full path'
do
let
(
:context
)
{
group
}
end
end
end
ee/spec/models/ci/minutes/threshold_spec.rb
0 → 100644
View file @
048aa1c7
# frozen_string_literal: true
require
'spec_helper'
describe
Ci
::
Minutes
::
Threshold
do
let_it_be
(
:user
)
{
create
(
:user
)
}
let
(
:shared_runners_enabled
)
{
true
}
let!
(
:project
)
{
create
(
:project
,
:repository
,
namespace:
group
,
shared_runners_enabled:
shared_runners_enabled
)
}
let_it_be
(
:group
)
{
create
(
:group
)
}
let
(
:injected_group
)
{
group
}
let
(
:injected_project
)
{
project
}
shared_examples
'queries for warning being reached'
do
context
'without limit'
do
it
{
is_expected
.
to
be_falsey
}
end
context
'when limit is defined'
do
context
'when usage has reached a notification level'
do
before
do
group
.
shared_runners_minutes_limit
=
10
allow
(
group
).
to
receive
(
:shared_runners_remaining_minutes
).
and_return
(
2
)
end
context
'when over the limit'
do
before
do
group
.
last_ci_minutes_usage_notification_level
=
30
end
it
{
is_expected
.
to
be_truthy
}
end
context
'when right at the limit for notification'
do
before
do
group
.
last_ci_minutes_usage_notification_level
=
20
end
it
{
is_expected
.
to
be_truthy
}
end
end
context
'when limit not yet exceeded'
do
let
(
:group
)
{
create
(
:group
,
:with_not_used_build_minutes_limit
)
}
it
{
is_expected
.
to
be_falsey
}
end
context
'when minutes are not yet set'
do
let
(
:group
)
{
create
(
:group
,
:with_build_minutes_limit
)
}
it
{
is_expected
.
to
be_falsey
}
end
end
end
shared_examples
'queries for alert being reached'
do
context
'without limit'
do
it
{
is_expected
.
to
be_falsey
}
end
context
'when limit is defined'
do
context
'when usage has exceeded the limit'
do
let
(
:group
)
{
create
(
:group
,
:with_used_build_minutes_limit
)
}
it
{
is_expected
.
to
be_truthy
}
end
context
'when limit not yet exceeded'
do
let
(
:group
)
{
create
(
:group
,
:with_not_used_build_minutes_limit
)
}
it
{
is_expected
.
to
be_falsey
}
end
context
'when minutes are not yet set'
do
let
(
:group
)
{
create
(
:group
,
:with_build_minutes_limit
)
}
it
{
is_expected
.
to
be_falsey
}
end
end
end
shared_examples
'cannot see if warning reached'
do
before
do
group
.
last_ci_minutes_usage_notification_level
=
30
group
.
shared_runners_minutes_limit
=
10
allow
(
group
).
to
receive
(
:shared_runners_remaining_minutes
).
and_return
(
2
)
end
context
'when usage has not reached a warning level'
do
it
{
is_expected
.
to
be_falsey
}
end
end
shared_examples
'cannot see if alert reached'
do
let
(
:group
)
{
create
(
:group
,
:with_used_build_minutes_limit
)
}
context
'when usage has reached an alert level'
do
it
{
is_expected
.
to
be_falsey
}
end
end
context
'when at project level'
do
describe
'#warning_reached?'
do
subject
do
threshold
=
described_class
.
new
(
user
,
injected_project
)
threshold
.
warning_reached?
end
context
'when project member'
do
it_behaves_like
'queries for warning being reached'
do
before
do
group
.
add_developer
(
user
)
end
end
end
context
'when not a project member'
do
it_behaves_like
'cannot see if warning reached'
end
end
describe
'#alert_reached?'
do
subject
do
threshold
=
described_class
.
new
(
user
,
injected_project
)
threshold
.
alert_reached?
end
context
'when project member'
do
it_behaves_like
'queries for alert being reached'
do
before
do
group
.
add_developer
(
user
)
end
end
end
context
'when not a project member'
do
it_behaves_like
'cannot see if alert reached'
end
end
end
context
'when at namespace level'
do
describe
'#warning_reached?'
do
subject
do
threshold
=
described_class
.
new
(
user
,
injected_group
)
threshold
.
warning_reached?
end
context
'with a project that has runners enabled inside namespace'
do
it_behaves_like
'queries for warning being reached'
end
context
'with no projects that have runners enabled inside namespace'
do
it_behaves_like
'cannot see if warning reached'
do
let
(
:shared_runners_enabled
)
{
false
}
end
end
end
describe
'#alert_reached?'
do
subject
do
threshold
=
described_class
.
new
(
user
,
injected_group
)
threshold
.
alert_reached?
end
context
'with a project that has runners enabled inside namespace'
do
it_behaves_like
'queries for alert being reached'
end
context
'with no projects that have runners enabled inside namespace'
do
it_behaves_like
'cannot see if alert reached'
do
let
(
:shared_runners_enabled
)
{
false
}
end
end
end
end
end
ee/spec/models/project_spec.rb
View file @
048aa1c7
...
...
@@ -17,6 +17,7 @@ describe Project do
it
{
is_expected
.
to
delegate_method
(
:actual_shared_runners_minutes_limit
).
to
(
:shared_runners_limit_namespace
)
}
it
{
is_expected
.
to
delegate_method
(
:shared_runners_minutes_limit_enabled?
).
to
(
:shared_runners_limit_namespace
)
}
it
{
is_expected
.
to
delegate_method
(
:shared_runners_minutes_used?
).
to
(
:shared_runners_limit_namespace
)
}
it
{
is_expected
.
to
delegate_method
(
:shared_runners_remaining_minutes_below_threshold?
).
to
(
:shared_runners_limit_namespace
)
}
it
{
is_expected
.
to
belong_to
(
:deleting_user
)
}
...
...
ee/spec/services/ci/minutes_notification_service_spec.rb
deleted
100644 → 0
View file @
20d1bda1
# frozen_string_literal: true
require
'spec_helper'
describe
Ci
::
MinutesNotificationService
do
describe
'.call'
do
let_it_be
(
:user
)
{
create
(
:user
)
}
let
(
:shared_runners_enabled
)
{
true
}
let!
(
:project
)
{
create
(
:project
,
:repository
,
namespace:
group
,
shared_runners_enabled:
shared_runners_enabled
)
}
let_it_be
(
:group
)
{
create
(
:group
)
}
let
(
:namespace
)
{
group
}
let
(
:prj
)
{
project
}
subject
{
described_class
.
call
(
user
,
prj
,
namespace
)
}
shared_examples
'showing notification'
do
context
'without limit'
do
it
'returns falsey'
do
expect
(
subject
.
show_notification?
).
to
be_falsey
end
end
context
'when limit is defined'
do
context
'when usage has reached a notification level'
do
before
do
group
.
last_ci_minutes_usage_notification_level
=
30
group
.
shared_runners_minutes_limit
=
10
allow_any_instance_of
(
EE
::
Namespace
).
to
receive
(
:shared_runners_remaining_minutes
).
and_return
(
2
)
end
it
'returns truthy'
do
expect
(
subject
.
show_notification?
).
to
be_truthy
end
end
context
'when limit not yet exceeded'
do
let
(
:group
)
{
create
(
:group
,
:with_not_used_build_minutes_limit
)
}
it
'returns falsey'
do
expect
(
subject
.
show_notification?
).
to
be_falsey
end
end
context
'when minutes are not yet set'
do
let
(
:group
)
{
create
(
:group
,
:with_build_minutes_limit
)
}
it
'returns falsey'
do
expect
(
subject
.
show_notification?
).
to
be_falsey
end
end
end
end
shared_examples
'showing alert'
do
context
'without limit'
do
it
'returns falsey'
do
expect
(
subject
.
show_notification?
).
to
be_falsey
end
end
context
'when limit is defined'
do
context
'when usage has reached a notification level'
do
before
do
group
.
last_ci_minutes_usage_notification_level
=
30
group
.
shared_runners_minutes_limit
=
10
allow_any_instance_of
(
EE
::
Namespace
).
to
receive
(
:shared_runners_remaining_minutes
).
and_return
(
2
)
end
it
'returns truthy'
do
expect
(
subject
.
show_notification?
).
to
be_truthy
end
end
context
'when usage has exceeded the limit'
do
let
(
:group
)
{
create
(
:group
,
:with_used_build_minutes_limit
)
}
it
'returns truthy'
do
expect
(
subject
.
show_notification?
).
to
be_truthy
end
end
context
'when limit not yet exceeded'
do
let
(
:group
)
{
create
(
:group
,
:with_not_used_build_minutes_limit
)
}
it
'returns falsey'
do
expect
(
subject
.
show_notification?
).
to
be_falsey
end
end
context
'when minutes are not yet set'
do
let
(
:group
)
{
create
(
:group
,
:with_build_minutes_limit
)
}
it
'returns falsey'
do
expect
(
subject
.
show_notification?
).
to
be_falsey
end
end
end
end
shared_examples
'scoping'
do
describe
'#scope'
do
it
'shows full path'
do
expect
(
subject
.
scope
).
to
eq
level
.
full_path
end
end
end
shared_examples
'show notification project constraints'
do
before
do
group
.
last_ci_minutes_usage_notification_level
=
30
group
.
shared_runners_minutes_limit
=
10
allow_any_instance_of
(
EE
::
Namespace
).
to
receive
(
:shared_runners_remaining_minutes
).
and_return
(
2
)
end
context
'when usage has reached a notification level'
do
it
'returns falsey'
do
expect
(
subject
.
show_notification?
).
to
be_falsey
end
end
end
shared_examples
'show alert project constraints'
do
let
(
:group
)
{
create
(
:group
,
:with_used_build_minutes_limit
)
}
context
'when usage has reached a notification level'
do
it
'returns falsey'
do
expect
(
subject
.
show_alert?
).
to
be_falsey
end
end
end
shared_examples
'class level items'
do
it
'assigns the namespace'
do
expect
(
subject
.
namespace
).
to
eq
group
end
end
context
'when at project level'
do
let
(
:namespace
)
{
nil
}
let
(
:prj
)
{
project
}
it_behaves_like
'class level items'
describe
'#show_notification?'
do
context
'when project member'
do
it_behaves_like
'showing notification'
do
before
do
group
.
add_developer
(
user
)
end
end
end
context
'when not a project member'
do
it_behaves_like
'show notification project constraints'
end
end
describe
'#show_alert?'
do
context
'when project member'
do
it_behaves_like
'showing alert'
do
before
do
group
.
add_developer
(
user
)
end
end
end
context
'when not a project member'
do
it_behaves_like
'show alert project constraints'
end
end
it_behaves_like
'scoping'
do
let
(
:level
)
{
project
}
end
end
context
'when at namespace level'
do
let
(
:prj
)
{
nil
}
it_behaves_like
'class level items'
describe
'#show_notification?'
do
context
'with a project that has runners enabled inside namespace'
do
it_behaves_like
'showing notification'
end
context
'with no projects that have runners enabled inside namespace'
do
it_behaves_like
'show notification project constraints'
do
let
(
:shared_runners_enabled
)
{
false
}
end
end
end
describe
'#show_alert?'
do
context
'with a project that has runners enabled inside namespace'
do
it_behaves_like
'showing alert'
end
context
'with no projects that have runners enabled inside namespace'
do
it_behaves_like
'show alert project constraints'
do
let
(
:shared_runners_enabled
)
{
false
}
end
end
end
it_behaves_like
'scoping'
do
let
(
:level
)
{
group
}
end
end
end
end
ee/spec/views/layouts/application.html.haml_spec.rb
View file @
048aa1c7
...
...
@@ -12,7 +12,7 @@ describe 'layouts/application' do
allow
(
view
).
to
receive
(
:user_signed_in?
).
and_return
(
true
)
allow
(
view
).
to
receive
(
:current_user
).
and_return
(
user
)
allow
(
view
).
to
receive
(
:current_user_mode
).
and_return
(
Gitlab
::
Auth
::
CurrentUserMode
.
new
(
user
))
allow
(
view
).
to
receive
(
:show_
user
_notification_dot?
).
and_return
(
show_notification_dot
)
allow
(
view
).
to
receive
(
:show_
ci_minutes
_notification_dot?
).
and_return
(
show_notification_dot
)
end
describe
'layouts/_user_notification_dot'
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