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
aa621050
Commit
aa621050
authored
Mar 03, 2021
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab master
parents
058e5f4b
ef48555e
Changes
32
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
440 additions
and
55 deletions
+440
-55
app/assets/javascripts/ref/components/ref_results_section.vue
...assets/javascripts/ref/components/ref_results_section.vue
+7
-1
app/assets/javascripts/ref/components/ref_selector.vue
app/assets/javascripts/ref/components/ref_selector.vue
+51
-7
app/assets/javascripts/ref/constants.js
app/assets/javascripts/ref/constants.js
+5
-0
app/assets/javascripts/ref/stores/actions.js
app/assets/javascripts/ref/stores/actions.js
+13
-4
app/assets/javascripts/ref/stores/mutation_types.js
app/assets/javascripts/ref/stores/mutation_types.js
+2
-0
app/assets/javascripts/ref/stores/mutations.js
app/assets/javascripts/ref/stores/mutations.js
+3
-0
app/assets/javascripts/ref/stores/state.js
app/assets/javascripts/ref/stores/state.js
+10
-15
app/controllers/root_controller.rb
app/controllers/root_controller.rb
+2
-0
app/helpers/preferences_helper.rb
app/helpers/preferences_helper.rb
+1
-0
app/models/user.rb
app/models/user.rb
+1
-1
app/views/shared/milestones/_milestone.html.haml
app/views/shared/milestones/_milestone.html.haml
+5
-1
changelogs/unreleased/add-ollowed-user-activity-as-dashboard-user-choices.yml
...d/add-ollowed-user-activity-as-dashboard-user-choices.yml
+5
-0
changelogs/unreleased/runners-api-context-metadata.yml
changelogs/unreleased/runners-api-context-metadata.yml
+5
-0
doc/api/graphql/index.md
doc/api/graphql/index.md
+1
-2
doc/user/profile/preferences.md
doc/user/profile/preferences.md
+2
-1
ee/app/models/ci/minutes/namespace_monthly_usage.rb
ee/app/models/ci/minutes/namespace_monthly_usage.rb
+5
-1
ee/app/models/ci/minutes/project_monthly_usage.rb
ee/app/models/ci/minutes/project_monthly_usage.rb
+5
-1
ee/changelogs/unreleased/nfriend-fix-301002-group-milestone-bug.yml
...ogs/unreleased/nfriend-fix-301002-group-milestone-bug.yml
+6
-0
ee/spec/models/ci/minutes/namespace_monthly_usage_spec.rb
ee/spec/models/ci/minutes/namespace_monthly_usage_spec.rb
+3
-3
ee/spec/models/ci/minutes/project_monthly_usage_spec.rb
ee/spec/models/ci/minutes/project_monthly_usage_spec.rb
+3
-3
ee/spec/views/shared/milestones/_milestone.html.haml_spec.rb
ee/spec/views/shared/milestones/_milestone.html.haml_spec.rb
+54
-0
lib/api/ci/runner.rb
lib/api/ci/runner.rb
+5
-10
lib/api/helpers/runner.rb
lib/api/helpers/runner.rb
+20
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-0
spec/controllers/root_controller_spec.rb
spec/controllers/root_controller_spec.rb
+12
-0
spec/frontend/ref/components/ref_selector_spec.js
spec/frontend/ref/components/ref_selector_spec.js
+91
-1
spec/frontend/ref/stores/actions_spec.js
spec/frontend/ref/stores/actions_spec.js
+21
-1
spec/frontend/ref/stores/mutations_spec.js
spec/frontend/ref/stores/mutations_spec.js
+10
-1
spec/helpers/preferences_helper_spec.rb
spec/helpers/preferences_helper_spec.rb
+1
-0
spec/requests/api/ci/runner/jobs_request_post_spec.rb
spec/requests/api/ci/runner/jobs_request_post_spec.rb
+44
-0
spec/requests/api/ci/runner/runners_post_spec.rb
spec/requests/api/ci/runner/runners_post_spec.rb
+28
-2
spec/support/shared_examples/requests/api/logging_application_context_shared_examples.rb
...quests/api/logging_application_context_shared_examples.rb
+16
-0
No files found.
app/assets/javascripts/ref/components/ref_results_section.vue
View file @
aa621050
...
@@ -11,6 +11,12 @@ export default {
...
@@ -11,6 +11,12 @@ export default {
GlIcon
,
GlIcon
,
},
},
props
:
{
props
:
{
showHeader
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
sectionTitle
:
{
sectionTitle
:
{
type
:
String
,
type
:
String
,
required
:
true
,
required
:
true
,
...
@@ -84,7 +90,7 @@ export default {
...
@@ -84,7 +90,7 @@ export default {
<
template
>
<
template
>
<div>
<div>
<gl-dropdown-section-header>
<gl-dropdown-section-header
v-if=
"showHeader"
>
<div
class=
"gl-display-flex align-items-center"
data-testid=
"section-header"
>
<div
class=
"gl-display-flex align-items-center"
data-testid=
"section-header"
>
<span
class=
"gl-mr-2 gl-mb-1"
>
{{
sectionTitle
}}
</span>
<span
class=
"gl-mr-2 gl-mb-1"
>
{{
sectionTitle
}}
</span>
<gl-badge
variant=
"neutral"
>
{{
totalCountText
}}
</gl-badge>
<gl-badge
variant=
"neutral"
>
{{
totalCountText
}}
</gl-badge>
...
...
app/assets/javascripts/ref/components/ref_selector.vue
View file @
aa621050
...
@@ -8,9 +8,16 @@ import {
...
@@ -8,9 +8,16 @@ import {
GlIcon
,
GlIcon
,
GlLoadingIcon
,
GlLoadingIcon
,
}
from
'
@gitlab/ui
'
;
}
from
'
@gitlab/ui
'
;
import
{
debounce
}
from
'
lodash
'
;
import
{
debounce
,
isArray
}
from
'
lodash
'
;
import
{
mapActions
,
mapGetters
,
mapState
}
from
'
vuex
'
;
import
{
mapActions
,
mapGetters
,
mapState
}
from
'
vuex
'
;
import
{
SEARCH_DEBOUNCE_MS
,
DEFAULT_I18N
}
from
'
../constants
'
;
import
{
ALL_REF_TYPES
,
SEARCH_DEBOUNCE_MS
,
DEFAULT_I18N
,
REF_TYPE_BRANCHES
,
REF_TYPE_TAGS
,
REF_TYPE_COMMITS
,
}
from
'
../constants
'
;
import
createStore
from
'
../stores
'
;
import
createStore
from
'
../stores
'
;
import
RefResultsSection
from
'
./ref_results_section.vue
'
;
import
RefResultsSection
from
'
./ref_results_section.vue
'
;
...
@@ -28,6 +35,20 @@ export default {
...
@@ -28,6 +35,20 @@ export default {
RefResultsSection
,
RefResultsSection
,
},
},
props
:
{
props
:
{
enabledRefTypes
:
{
type
:
Array
,
required
:
false
,
default
:
()
=>
ALL_REF_TYPES
,
validator
:
(
val
)
=>
// It has to be an arrray
isArray
(
val
)
&&
// with at least one item
val
.
length
>
0
&&
// and only "REF_TYPE_BRANCHES", "REF_TYPE_TAGS", and "REF_TYPE_COMMITS" are allowed
val
.
every
((
item
)
=>
ALL_REF_TYPES
.
includes
(
item
))
&&
// and no duplicates are allowed
val
.
length
===
new
Set
(
val
).
size
,
},
value
:
{
value
:
{
type
:
String
,
type
:
String
,
required
:
false
,
required
:
false
,
...
@@ -62,17 +83,29 @@ export default {
...
@@ -62,17 +83,29 @@ export default {
};
};
},
},
showBranchesSection
()
{
showBranchesSection
()
{
return
Boolean
(
this
.
matches
.
branches
.
totalCount
>
0
||
this
.
matches
.
branches
.
error
);
return
(
this
.
enabledRefTypes
.
includes
(
REF_TYPE_BRANCHES
)
&&
Boolean
(
this
.
matches
.
branches
.
totalCount
>
0
||
this
.
matches
.
branches
.
error
)
);
},
},
showTagsSection
()
{
showTagsSection
()
{
return
Boolean
(
this
.
matches
.
tags
.
totalCount
>
0
||
this
.
matches
.
tags
.
error
);
return
(
this
.
enabledRefTypes
.
includes
(
REF_TYPE_TAGS
)
&&
Boolean
(
this
.
matches
.
tags
.
totalCount
>
0
||
this
.
matches
.
tags
.
error
)
);
},
},
showCommitsSection
()
{
showCommitsSection
()
{
return
Boolean
(
this
.
matches
.
commits
.
totalCount
>
0
||
this
.
matches
.
commits
.
error
);
return
(
this
.
enabledRefTypes
.
includes
(
REF_TYPE_COMMITS
)
&&
Boolean
(
this
.
matches
.
commits
.
totalCount
>
0
||
this
.
matches
.
commits
.
error
)
);
},
},
showNoResults
()
{
showNoResults
()
{
return
!
this
.
showBranchesSection
&&
!
this
.
showTagsSection
&&
!
this
.
showCommitsSection
;
return
!
this
.
showBranchesSection
&&
!
this
.
showTagsSection
&&
!
this
.
showCommitsSection
;
},
},
showSectionHeaders
()
{
return
this
.
enabledRefTypes
.
length
>
1
;
},
},
},
watch
:
{
watch
:
{
// Keep the Vuex store synchronized if the parent
// Keep the Vuex store synchronized if the parent
...
@@ -97,10 +130,18 @@ export default {
...
@@ -97,10 +130,18 @@ export default {
},
SEARCH_DEBOUNCE_MS
);
},
SEARCH_DEBOUNCE_MS
);
this
.
setProjectId
(
this
.
projectId
);
this
.
setProjectId
(
this
.
projectId
);
this
.
search
(
this
.
query
);
this
.
$watch
(
'
enabledRefTypes
'
,
()
=>
{
this
.
setEnabledRefTypes
(
this
.
enabledRefTypes
);
this
.
search
(
this
.
query
);
},
{
immediate
:
true
},
);
},
},
methods
:
{
methods
:
{
...
mapActions
([
'
setProjectId
'
,
'
setSelectedRef
'
,
'
search
'
]),
...
mapActions
([
'
set
EnabledRefTypes
'
,
'
set
ProjectId
'
,
'
setSelectedRef
'
,
'
search
'
]),
focusSearchBox
()
{
focusSearchBox
()
{
this
.
$refs
.
searchBox
.
$el
.
querySelector
(
'
input
'
).
focus
();
this
.
$refs
.
searchBox
.
$el
.
querySelector
(
'
input
'
).
focus
();
},
},
...
@@ -170,6 +211,7 @@ export default {
...
@@ -170,6 +211,7 @@ export default {
:selected-ref=
"selectedRef"
:selected-ref=
"selectedRef"
:error=
"matches.branches.error"
:error=
"matches.branches.error"
:error-message=
"i18n.branchesErrorMessage"
:error-message=
"i18n.branchesErrorMessage"
:show-header=
"showSectionHeaders"
data-testid=
"branches-section"
data-testid=
"branches-section"
@
selected=
"selectRef($event)"
@
selected=
"selectRef($event)"
/>
/>
...
@@ -185,6 +227,7 @@ export default {
...
@@ -185,6 +227,7 @@ export default {
:selected-ref=
"selectedRef"
:selected-ref=
"selectedRef"
:error=
"matches.tags.error"
:error=
"matches.tags.error"
:error-message=
"i18n.tagsErrorMessage"
:error-message=
"i18n.tagsErrorMessage"
:show-header=
"showSectionHeaders"
data-testid=
"tags-section"
data-testid=
"tags-section"
@
selected=
"selectRef($event)"
@
selected=
"selectRef($event)"
/>
/>
...
@@ -200,6 +243,7 @@ export default {
...
@@ -200,6 +243,7 @@ export default {
:selected-ref=
"selectedRef"
:selected-ref=
"selectedRef"
:error=
"matches.commits.error"
:error=
"matches.commits.error"
:error-message=
"i18n.commitsErrorMessage"
:error-message=
"i18n.commitsErrorMessage"
:show-header=
"showSectionHeaders"
data-testid=
"commits-section"
data-testid=
"commits-section"
@
selected=
"selectRef($event)"
@
selected=
"selectRef($event)"
/>
/>
...
...
app/assets/javascripts/ref/constants.js
View file @
aa621050
import
{
__
}
from
'
~/locale
'
;
import
{
__
}
from
'
~/locale
'
;
export
const
REF_TYPE_BRANCHES
=
'
REF_TYPE_BRANCHES
'
;
export
const
REF_TYPE_TAGS
=
'
REF_TYPE_TAGS
'
;
export
const
REF_TYPE_COMMITS
=
'
REF_TYPE_COMMITS
'
;
export
const
ALL_REF_TYPES
=
Object
.
freeze
([
REF_TYPE_BRANCHES
,
REF_TYPE_TAGS
,
REF_TYPE_COMMITS
]);
export
const
X_TOTAL_HEADER
=
'
x-total
'
;
export
const
X_TOTAL_HEADER
=
'
x-total
'
;
export
const
SEARCH_DEBOUNCE_MS
=
250
;
export
const
SEARCH_DEBOUNCE_MS
=
250
;
...
...
app/assets/javascripts/ref/stores/actions.js
View file @
aa621050
import
Api
from
'
~/api
'
;
import
Api
from
'
~/api
'
;
import
{
REF_TYPE_BRANCHES
,
REF_TYPE_TAGS
,
REF_TYPE_COMMITS
}
from
'
../constants
'
;
import
*
as
types
from
'
./mutation_types
'
;
import
*
as
types
from
'
./mutation_types
'
;
export
const
setEnabledRefTypes
=
({
commit
},
refTypes
)
=>
commit
(
types
.
SET_ENABLED_REF_TYPES
,
refTypes
);
export
const
setProjectId
=
({
commit
},
projectId
)
=>
commit
(
types
.
SET_PROJECT_ID
,
projectId
);
export
const
setProjectId
=
({
commit
},
projectId
)
=>
commit
(
types
.
SET_PROJECT_ID
,
projectId
);
export
const
setSelectedRef
=
({
commit
},
selectedRef
)
=>
export
const
setSelectedRef
=
({
commit
},
selectedRef
)
=>
commit
(
types
.
SET_SELECTED_REF
,
selectedRef
);
commit
(
types
.
SET_SELECTED_REF
,
selectedRef
);
export
const
search
=
({
dispatch
,
commit
},
query
)
=>
{
export
const
search
=
({
state
,
dispatch
,
commit
},
query
)
=>
{
commit
(
types
.
SET_QUERY
,
query
);
commit
(
types
.
SET_QUERY
,
query
);
dispatch
(
'
searchBranches
'
);
const
dispatchIfRefTypeEnabled
=
(
refType
,
action
)
=>
{
dispatch
(
'
searchTags
'
);
if
(
state
.
enabledRefTypes
.
includes
(
refType
))
{
dispatch
(
'
searchCommits
'
);
dispatch
(
action
);
}
};
dispatchIfRefTypeEnabled
(
REF_TYPE_BRANCHES
,
'
searchBranches
'
);
dispatchIfRefTypeEnabled
(
REF_TYPE_TAGS
,
'
searchTags
'
);
dispatchIfRefTypeEnabled
(
REF_TYPE_COMMITS
,
'
searchCommits
'
);
};
};
export
const
searchBranches
=
({
commit
,
state
})
=>
{
export
const
searchBranches
=
({
commit
,
state
})
=>
{
...
...
app/assets/javascripts/ref/stores/mutation_types.js
View file @
aa621050
export
const
SET_ENABLED_REF_TYPES
=
'
SET_ENABLED_REF_TYPES
'
;
export
const
SET_PROJECT_ID
=
'
SET_PROJECT_ID
'
;
export
const
SET_PROJECT_ID
=
'
SET_PROJECT_ID
'
;
export
const
SET_SELECTED_REF
=
'
SET_SELECTED_REF
'
;
export
const
SET_SELECTED_REF
=
'
SET_SELECTED_REF
'
;
export
const
SET_QUERY
=
'
SET_QUERY
'
;
export
const
SET_QUERY
=
'
SET_QUERY
'
;
...
...
app/assets/javascripts/ref/stores/mutations.js
View file @
aa621050
...
@@ -4,6 +4,9 @@ import { X_TOTAL_HEADER } from '../constants';
...
@@ -4,6 +4,9 @@ import { X_TOTAL_HEADER } from '../constants';
import
*
as
types
from
'
./mutation_types
'
;
import
*
as
types
from
'
./mutation_types
'
;
export
default
{
export
default
{
[
types
.
SET_ENABLED_REF_TYPES
](
state
,
refTypes
)
{
state
.
enabledRefTypes
=
refTypes
;
},
[
types
.
SET_PROJECT_ID
](
state
,
projectId
)
{
[
types
.
SET_PROJECT_ID
](
state
,
projectId
)
{
state
.
projectId
=
projectId
;
state
.
projectId
=
projectId
;
},
},
...
...
app/assets/javascripts/ref/stores/state.js
View file @
aa621050
const
createRefTypeState
=
()
=>
({
list
:
[],
totalCount
:
0
,
error
:
null
,
});
export
default
()
=>
({
export
default
()
=>
({
enabledRefTypes
:
[],
projectId
:
null
,
projectId
:
null
,
query
:
''
,
query
:
''
,
matches
:
{
matches
:
{
branches
:
{
branches
:
createRefTypeState
(),
list
:
[],
tags
:
createRefTypeState
(),
totalCount
:
0
,
commits
:
createRefTypeState
(),
error
:
null
,
},
tags
:
{
list
:
[],
totalCount
:
0
,
error
:
null
,
},
commits
:
{
list
:
[],
totalCount
:
0
,
error
:
null
,
},
},
},
selectedRef
:
null
,
selectedRef
:
null
,
requestCount
:
0
,
requestCount
:
0
,
...
...
app/controllers/root_controller.rb
View file @
aa621050
...
@@ -46,6 +46,8 @@ class RootController < Dashboard::ProjectsController
...
@@ -46,6 +46,8 @@ class RootController < Dashboard::ProjectsController
redirect_to
(
activity_dashboard_path
)
redirect_to
(
activity_dashboard_path
)
when
'starred_project_activity'
when
'starred_project_activity'
redirect_to
(
activity_dashboard_path
(
filter:
'starred'
))
redirect_to
(
activity_dashboard_path
(
filter:
'starred'
))
when
'followed_user_activity'
redirect_to
(
activity_dashboard_path
(
filter:
'followed'
))
when
'groups'
when
'groups'
redirect_to
(
dashboard_groups_path
)
redirect_to
(
dashboard_groups_path
)
when
'todos'
when
'todos'
...
...
app/helpers/preferences_helper.rb
View file @
aa621050
...
@@ -29,6 +29,7 @@ module PreferencesHelper
...
@@ -29,6 +29,7 @@ module PreferencesHelper
stars:
_
(
"Starred Projects"
),
stars:
_
(
"Starred Projects"
),
project_activity:
_
(
"Your Projects' Activity"
),
project_activity:
_
(
"Your Projects' Activity"
),
starred_project_activity:
_
(
"Starred Projects' Activity"
),
starred_project_activity:
_
(
"Starred Projects' Activity"
),
followed_user_activity:
_
(
"Followed Users' Activity"
),
groups:
_
(
"Your Groups"
),
groups:
_
(
"Your Groups"
),
todos:
_
(
"Your To-Do List"
),
todos:
_
(
"Your To-Do List"
),
issues:
_
(
"Assigned Issues"
),
issues:
_
(
"Assigned Issues"
),
...
...
app/models/user.rb
View file @
aa621050
...
@@ -272,7 +272,7 @@ class User < ApplicationRecord
...
@@ -272,7 +272,7 @@ class User < ApplicationRecord
enum
layout:
{
fixed:
0
,
fluid:
1
}
enum
layout:
{
fixed:
0
,
fluid:
1
}
# User's Dashboard preference
# User's Dashboard preference
enum
dashboard:
{
projects:
0
,
stars:
1
,
project_activity:
2
,
starred_project_activity:
3
,
groups:
4
,
todos:
5
,
issues:
6
,
merge_requests:
7
,
operations:
8
}
enum
dashboard:
{
projects:
0
,
stars:
1
,
project_activity:
2
,
starred_project_activity:
3
,
groups:
4
,
todos:
5
,
issues:
6
,
merge_requests:
7
,
operations:
8
,
followed_user_activity:
9
}
# User's Project preference
# User's Project preference
enum
project_view:
{
readme:
0
,
activity:
1
,
files:
2
}
enum
project_view:
{
readme:
0
,
activity:
1
,
files:
2
}
...
...
app/views/shared/milestones/_milestone.html.haml
View file @
aa621050
...
@@ -25,7 +25,11 @@
...
@@ -25,7 +25,11 @@
•
•
-
if
total_count
>
recent_releases
.
count
-
if
total_count
>
recent_releases
.
count
•
•
=
link_to
n_
(
'%{count} more release'
,
'%{count} more releases'
,
more_count
)
%
{
count:
more_count
},
project_releases_path
(
milestone
.
project
)
-
more_text
=
n_
(
'%{count} more release'
,
'%{count} more releases'
,
more_count
)
%
{
count:
more_count
}
-
if
milestone
.
project_milestone?
=
link_to
more_text
,
project_releases_path
(
milestone
.
project
)
-
else
=
more_text
%div
%div
=
render
(
'shared/milestone_expired'
,
milestone:
milestone
)
=
render
(
'shared/milestone_expired'
,
milestone:
milestone
)
-
if
milestone
.
group_milestone?
-
if
milestone
.
group_milestone?
...
...
changelogs/unreleased/add-ollowed-user-activity-as-dashboard-user-choices.yml
0 → 100644
View file @
aa621050
---
title
:
"
Add
'Followed
User
Activity'
as
dashboard
user
choices"
merge_request
:
55165
author
:
Benj Fassbind @randombenj
type
:
added
changelogs/unreleased/runners-api-context-metadata.yml
0 → 100644
View file @
aa621050
---
title
:
Add runners api context metadata
merge_request
:
55089
author
:
type
:
changed
doc/api/graphql/index.md
View file @
aa621050
...
@@ -171,8 +171,7 @@ certain arguments may also increase the complexity of a query.
...
@@ -171,8 +171,7 @@ certain arguments may also increase the complexity of a query.
NOTE:
NOTE:
The complexity limits may be revised in future, and additionally, the complexity
The complexity limits may be revised in future, and additionally, the complexity
of a query may be altered. Changes to complexity can happen on
`X.0`
or
`X.6`
of a query may be altered.
releases without a deprecation period.
### Request timeout
### Request timeout
...
...
doc/user/profile/preferences.md
View file @
aa621050
...
@@ -108,12 +108,13 @@ select few, the amount of activity on the default Dashboard page can be
...
@@ -108,12 +108,13 @@ select few, the amount of activity on the default Dashboard page can be
overwhelming. Changing this setting allows you to redefine your default
overwhelming. Changing this setting allows you to redefine your default
dashboard.
dashboard.
You
have 8 options here that you can use
for your default dashboard view:
You
can include the following options
for your default dashboard view:
-
Your projects (default)
-
Your projects (default)
-
Starred projects
-
Starred projects
-
Your projects' activity
-
Your projects' activity
-
Starred projects' activity
-
Starred projects' activity
-
Followed Users' Activity
-
Your groups
-
Your groups
-
Your
[
To-Do List
](
../todos.md
)
-
Your
[
To-Do List
](
../todos.md
)
-
Assigned Issues
-
Assigned Issues
...
...
ee/app/models/ci/minutes/namespace_monthly_usage.rb
View file @
aa621050
...
@@ -9,7 +9,11 @@ module Ci
...
@@ -9,7 +9,11 @@ module Ci
belongs_to
:namespace
belongs_to
:namespace
scope
:current_month
,
->
{
where
(
date:
Time
.
current
.
utc
.
beginning_of_month
)
}
scope
:current_month
,
->
{
where
(
date:
beginning_of_month
)
}
def
self
.
beginning_of_month
(
time
=
Time
.
current
)
time
.
utc
.
beginning_of_month
end
# We should pretty much always use this method to access data for the current month
# We should pretty much always use this method to access data for the current month
# since this will lazily create an entry if it doesn't exist.
# since this will lazily create an entry if it doesn't exist.
...
...
ee/app/models/ci/minutes/project_monthly_usage.rb
View file @
aa621050
...
@@ -9,7 +9,11 @@ module Ci
...
@@ -9,7 +9,11 @@ module Ci
belongs_to
:project
belongs_to
:project
scope
:current_month
,
->
{
where
(
date:
Time
.
current
.
beginning_of_month
)
}
scope
:current_month
,
->
{
where
(
date:
beginning_of_month
)
}
def
self
.
beginning_of_month
(
time
=
Time
.
current
)
time
.
utc
.
beginning_of_month
end
# We should pretty much always use this method to access data for the current month
# We should pretty much always use this method to access data for the current month
# since this will lazily create an entry if it doesn't exist.
# since this will lazily create an entry if it doesn't exist.
...
...
ee/changelogs/unreleased/nfriend-fix-301002-group-milestone-bug.yml
0 → 100644
View file @
aa621050
---
title
:
Fix 500 error on group milestones page when milestones are associated to more
than 3 releases
merge_request
:
55540
author
:
type
:
fixed
ee/spec/models/ci/minutes/namespace_monthly_usage_spec.rb
View file @
aa621050
...
@@ -16,7 +16,7 @@ RSpec.describe Ci::Minutes::NamespaceMonthlyUsage do
...
@@ -16,7 +16,7 @@ RSpec.describe Ci::Minutes::NamespaceMonthlyUsage do
end
end
it
'does not raise exception if unique index is not violated'
do
it
'does not raise exception if unique index is not violated'
do
expect
{
create
(
:ci_namespace_monthly_usage
,
namespace:
namespace
,
date:
1
.
month
.
ago
.
utc
.
beginning_of_month
)
}
expect
{
create
(
:ci_namespace_monthly_usage
,
namespace:
namespace
,
date:
described_class
.
beginning_of_month
(
1
.
month
.
ago
)
)
}
.
to
change
{
described_class
.
count
}.
by
(
1
)
.
to
change
{
described_class
.
count
}.
by
(
1
)
end
end
end
end
...
@@ -31,7 +31,7 @@ RSpec.describe Ci::Minutes::NamespaceMonthlyUsage do
...
@@ -31,7 +31,7 @@ RSpec.describe Ci::Minutes::NamespaceMonthlyUsage do
expect
(
subject
.
amount_used
).
to
eq
(
0
)
expect
(
subject
.
amount_used
).
to
eq
(
0
)
expect
(
subject
.
namespace
).
to
eq
(
namespace
)
expect
(
subject
.
namespace
).
to
eq
(
namespace
)
expect
(
subject
.
date
).
to
eq
(
Time
.
current
.
beginning_of_month
)
expect
(
subject
.
date
).
to
eq
(
described_class
.
beginning_of_month
)
end
end
end
end
end
end
...
@@ -42,7 +42,7 @@ RSpec.describe Ci::Minutes::NamespaceMonthlyUsage do
...
@@ -42,7 +42,7 @@ RSpec.describe Ci::Minutes::NamespaceMonthlyUsage do
context
'when namespace usage exists for previous months'
do
context
'when namespace usage exists for previous months'
do
before
do
before
do
create
(
:ci_namespace_monthly_usage
,
namespace:
namespace
,
date:
2
.
months
.
ago
.
utc
.
beginning_of_month
)
create
(
:ci_namespace_monthly_usage
,
namespace:
namespace
,
date:
described_class
.
beginning_of_month
(
2
.
months
.
ago
)
)
end
end
it_behaves_like
'creates usage record'
it_behaves_like
'creates usage record'
...
...
ee/spec/models/ci/minutes/project_monthly_usage_spec.rb
View file @
aa621050
...
@@ -16,7 +16,7 @@ RSpec.describe Ci::Minutes::ProjectMonthlyUsage do
...
@@ -16,7 +16,7 @@ RSpec.describe Ci::Minutes::ProjectMonthlyUsage do
end
end
it
'does not raise exception if unique index is not violated'
do
it
'does not raise exception if unique index is not violated'
do
expect
{
create
(
:ci_project_monthly_usage
,
project:
project
,
date:
1
.
month
.
ago
.
utc
.
beginning_of_month
)
}
expect
{
create
(
:ci_project_monthly_usage
,
project:
project
,
date:
described_class
.
beginning_of_month
(
1
.
month
.
ago
)
)
}
.
to
change
{
described_class
.
count
}.
by
(
1
)
.
to
change
{
described_class
.
count
}.
by
(
1
)
end
end
end
end
...
@@ -31,7 +31,7 @@ RSpec.describe Ci::Minutes::ProjectMonthlyUsage do
...
@@ -31,7 +31,7 @@ RSpec.describe Ci::Minutes::ProjectMonthlyUsage do
expect
(
subject
.
amount_used
).
to
eq
(
0
)
expect
(
subject
.
amount_used
).
to
eq
(
0
)
expect
(
subject
.
project
).
to
eq
(
project
)
expect
(
subject
.
project
).
to
eq
(
project
)
expect
(
subject
.
date
).
to
eq
(
Time
.
current
.
beginning_of_month
)
expect
(
subject
.
date
).
to
eq
(
described_class
.
beginning_of_month
)
end
end
end
end
end
end
...
@@ -42,7 +42,7 @@ RSpec.describe Ci::Minutes::ProjectMonthlyUsage do
...
@@ -42,7 +42,7 @@ RSpec.describe Ci::Minutes::ProjectMonthlyUsage do
context
'when project usage exists for previous months'
do
context
'when project usage exists for previous months'
do
before
do
before
do
create
(
:ci_project_monthly_usage
,
project:
project
,
date:
2
.
months
.
ago
.
utc
.
beginning_of_month
)
create
(
:ci_project_monthly_usage
,
project:
project
,
date:
described_class
.
beginning_of_month
(
2
.
months
.
ago
)
)
end
end
it_behaves_like
'creates usage record'
it_behaves_like
'creates usage record'
...
...
ee/spec/views/shared/milestones/_milestone.html.haml_spec.rb
0 → 100644
View file @
aa621050
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
'shared/milestones/_milestone.html.haml'
do
let_it_be
(
:group
)
{
create
(
:group
)
}
let_it_be
(
:project
)
{
create
(
:project
,
group:
group
)
}
let_it_be
(
:user
)
{
create
(
:user
).
tap
{
|
user
|
project
.
add_maintainer
(
user
)
}
}
let_it_be
(
:releases
)
{
create_list
(
:release
,
4
,
project:
project
)
}
let_it_be
(
:milestone
)
{
nil
}
let
(
:more_text
)
{
'1 more release'
}
let
(
:link_href
)
{
project_releases_path
(
project
)
}
before
do
stub_licensed_features
(
group_milestone_project_releases:
true
)
allow
(
view
).
to
receive
(
:current_user
).
and_return
(
user
)
allow
(
view
).
to
receive
(
:milestone
).
and_return
(
milestone
)
allow
(
view
).
to
receive
(
:issues_path
).
and_return
(
'path/to/issues'
)
allow
(
view
).
to
receive
(
:merge_requests_path
).
and_return
(
'path/to/merge_requests'
)
end
context
'when a milestone is associated to a lot of releases'
do
context
'when viewing a project milestone'
do
let
(
:milestone
)
{
create
(
:milestone
,
project:
project
,
releases:
releases
)
}
before
do
assign
(
:project
,
project
)
end
it
'renders "1 more release" as a link to the project\'s Releases page'
do
render
expect
(
rendered
).
to
have_link
(
more_text
,
href:
link_href
)
end
end
context
'when viewing a group milestone'
do
let
(
:milestone
)
{
create
(
:milestone
,
group:
group
,
releases:
releases
)
}
before
do
assign
(
:group
,
group
)
end
it
'renders "1 more release" as plain text instead of as a link'
,
:aggregate_failures
do
render
expect
(
rendered
).
not_to
have_link
(
more_text
,
href:
link_href
)
expect
(
rendered
).
to
have_content
(
more_text
)
end
end
end
end
lib/api/ci/runner.rb
View file @
aa621050
...
@@ -34,12 +34,12 @@ module API
...
@@ -34,12 +34,12 @@ module API
if
runner_registration_token_valid?
if
runner_registration_token_valid?
# Create shared runner. Requires admin access
# Create shared runner. Requires admin access
attributes
.
merge
(
runner_type: :instance_type
)
attributes
.
merge
(
runner_type: :instance_type
)
elsif
project
=
Project
.
find_by_runners_token
(
params
[
:token
])
elsif
@
project
=
Project
.
find_by_runners_token
(
params
[
:token
])
# Create a specific runner for the project
# Create a specific runner for the project
attributes
.
merge
(
runner_type: :project_type
,
projects:
[
project
])
attributes
.
merge
(
runner_type: :project_type
,
projects:
[
@
project
])
elsif
group
=
Group
.
find_by_runners_token
(
params
[
:token
])
elsif
@
group
=
Group
.
find_by_runners_token
(
params
[
:token
])
# Create a specific runner for the group
# Create a specific runner for the group
attributes
.
merge
(
runner_type: :group_type
,
groups:
[
group
])
attributes
.
merge
(
runner_type: :group_type
,
groups:
[
@
group
])
else
else
forbidden!
forbidden!
end
end
...
@@ -81,12 +81,7 @@ module API
...
@@ -81,12 +81,7 @@ module API
end
end
resource
:jobs
do
resource
:jobs
do
before
do
before
{
set_application_context
}
Gitlab
::
ApplicationContext
.
push
(
user:
->
{
current_job
&
.
user
},
project:
->
{
current_job
&
.
project
}
)
end
desc
'Request a job'
do
desc
'Request a job'
do
success
Entities
::
JobRequest
::
Response
success
Entities
::
JobRequest
::
Response
...
...
lib/api/helpers/runner.rb
View file @
aa621050
...
@@ -71,6 +71,26 @@ module API
...
@@ -71,6 +71,26 @@ module API
header
'Job-Status'
,
job
.
status
header
'Job-Status'
,
job
.
status
forbidden!
(
reason
)
forbidden!
(
reason
)
end
end
def
set_application_context
if
current_job
Gitlab
::
ApplicationContext
.
push
(
user:
->
{
current_job
.
user
},
project:
->
{
current_job
.
project
}
)
elsif
current_runner
&
.
project_type?
Gitlab
::
ApplicationContext
.
push
(
project:
->
do
projects
=
current_runner
.
projects
.
limit
(
2
)
# rubocop: disable CodeReuse/ActiveRecord
projects
.
first
if
projects
.
length
==
1
end
)
elsif
current_runner
&
.
group_type?
Gitlab
::
ApplicationContext
.
push
(
namespace:
->
{
current_runner
.
groups
.
first
}
)
end
end
end
end
end
end
end
end
locale/gitlab.pot
View file @
aa621050
...
@@ -13201,6 +13201,9 @@ msgstr ""
...
@@ -13201,6 +13201,9 @@ msgstr ""
msgid "Follow"
msgid "Follow"
msgstr ""
msgstr ""
msgid "Followed Users' Activity"
msgstr ""
msgid "Followed users"
msgid "Followed users"
msgstr ""
msgstr ""
...
...
spec/controllers/root_controller_spec.rb
View file @
aa621050
...
@@ -68,6 +68,18 @@ RSpec.describe RootController do
...
@@ -68,6 +68,18 @@ RSpec.describe RootController do
end
end
end
end
context
'who has customized their dashboard setting for followed user activities'
do
before
do
user
.
dashboard
=
'followed_user_activity'
end
it
'redirects to the activity list'
do
get
:index
expect
(
response
).
to
redirect_to
activity_dashboard_path
(
filter:
'followed'
)
end
end
context
'who has customized their dashboard setting for groups'
do
context
'who has customized their dashboard setting for groups'
do
before
do
before
do
user
.
dashboard
=
'groups'
user
.
dashboard
=
'groups'
...
...
spec/frontend/ref/components/ref_selector_spec.js
View file @
aa621050
...
@@ -7,7 +7,13 @@ import { trimText } from 'helpers/text_helper';
...
@@ -7,7 +7,13 @@ import { trimText } from 'helpers/text_helper';
import
{
ENTER_KEY
}
from
'
~/lib/utils/keys
'
;
import
{
ENTER_KEY
}
from
'
~/lib/utils/keys
'
;
import
{
sprintf
}
from
'
~/locale
'
;
import
{
sprintf
}
from
'
~/locale
'
;
import
RefSelector
from
'
~/ref/components/ref_selector.vue
'
;
import
RefSelector
from
'
~/ref/components/ref_selector.vue
'
;
import
{
X_TOTAL_HEADER
,
DEFAULT_I18N
}
from
'
~/ref/constants
'
;
import
{
X_TOTAL_HEADER
,
DEFAULT_I18N
,
REF_TYPE_BRANCHES
,
REF_TYPE_TAGS
,
REF_TYPE_COMMITS
,
}
from
'
~/ref/constants
'
;
import
createStore
from
'
~/ref/stores/
'
;
import
createStore
from
'
~/ref/stores/
'
;
const
localVue
=
createLocalVue
();
const
localVue
=
createLocalVue
();
...
@@ -26,6 +32,7 @@ describe('Ref selector component', () => {
...
@@ -26,6 +32,7 @@ describe('Ref selector component', () => {
let
branchesApiCallSpy
;
let
branchesApiCallSpy
;
let
tagsApiCallSpy
;
let
tagsApiCallSpy
;
let
commitApiCallSpy
;
let
commitApiCallSpy
;
let
requestSpies
;
const
createComponent
=
(
props
=
{},
attrs
=
{})
=>
{
const
createComponent
=
(
props
=
{},
attrs
=
{})
=>
{
wrapper
=
mount
(
RefSelector
,
{
wrapper
=
mount
(
RefSelector
,
{
...
@@ -58,6 +65,7 @@ describe('Ref selector component', () => {
...
@@ -58,6 +65,7 @@ describe('Ref selector component', () => {
.
mockReturnValue
([
200
,
fixtures
.
branches
,
{
[
X_TOTAL_HEADER
]:
'
123
'
}]);
.
mockReturnValue
([
200
,
fixtures
.
branches
,
{
[
X_TOTAL_HEADER
]:
'
123
'
}]);
tagsApiCallSpy
=
jest
.
fn
().
mockReturnValue
([
200
,
fixtures
.
tags
,
{
[
X_TOTAL_HEADER
]:
'
456
'
}]);
tagsApiCallSpy
=
jest
.
fn
().
mockReturnValue
([
200
,
fixtures
.
tags
,
{
[
X_TOTAL_HEADER
]:
'
456
'
}]);
commitApiCallSpy
=
jest
.
fn
().
mockReturnValue
([
200
,
fixtures
.
commit
]);
commitApiCallSpy
=
jest
.
fn
().
mockReturnValue
([
200
,
fixtures
.
commit
]);
requestSpies
=
{
branchesApiCallSpy
,
tagsApiCallSpy
,
commitApiCallSpy
};
mock
mock
.
onGet
(
`/api/v4/projects/
${
projectId
}
/repository/branches`
)
.
onGet
(
`/api/v4/projects/
${
projectId
}
/repository/branches`
)
...
@@ -592,4 +600,86 @@ describe('Ref selector component', () => {
...
@@ -592,4 +600,86 @@ describe('Ref selector component', () => {
});
});
});
});
});
});
describe
(
'
with non-default ref types
'
,
()
=>
{
it
.
each
`
enabledRefTypes | reqsCalled | reqsNotCalled
${[
REF_TYPE_BRANCHES
]}
|
${[
'
branchesApiCallSpy
'
]}
|
${[
'
tagsApiCallSpy
'
,
'
commitApiCallSpy
'
]}
${[
REF_TYPE_TAGS
]}
|
${[
'
tagsApiCallSpy
'
]}
|
${[
'
branchesApiCallSpy
'
,
'
commitApiCallSpy
'
]}
${[
REF_TYPE_COMMITS
]}
|
${[]}
|
${[
'
branchesApiCallSpy
'
,
'
tagsApiCallSpy
'
,
'
commitApiCallSpy
'
]}
${[
REF_TYPE_TAGS
,
REF_TYPE_COMMITS
]}
|
${[
'
tagsApiCallSpy
'
]}
|
${[
'
branchesApiCallSpy
'
,
'
commitApiCallSpy
'
]}
`
(
'
only calls $reqsCalled requests when $enabledRefTypes are enabled
'
,
async
({
enabledRefTypes
,
reqsCalled
,
reqsNotCalled
})
=>
{
createComponent
({
enabledRefTypes
});
await
waitForRequests
();
reqsCalled
.
forEach
((
req
)
=>
expect
(
requestSpies
[
req
]).
toHaveBeenCalledTimes
(
1
));
reqsNotCalled
.
forEach
((
req
)
=>
expect
(
requestSpies
[
req
]).
not
.
toHaveBeenCalled
());
},
);
it
(
'
only calls commitApiCallSpy when REF_TYPE_COMMITS is enabled
'
,
async
()
=>
{
createComponent
({
enabledRefTypes
:
[
REF_TYPE_COMMITS
]
});
updateQuery
(
'
abcd1234
'
);
await
waitForRequests
();
expect
(
commitApiCallSpy
).
toHaveBeenCalledTimes
(
1
);
expect
(
branchesApiCallSpy
).
not
.
toHaveBeenCalled
();
expect
(
tagsApiCallSpy
).
not
.
toHaveBeenCalled
();
});
it
(
'
triggers another search if enabled ref types change
'
,
async
()
=>
{
createComponent
({
enabledRefTypes
:
[
REF_TYPE_BRANCHES
]
});
await
waitForRequests
();
expect
(
branchesApiCallSpy
).
toHaveBeenCalledTimes
(
1
);
expect
(
tagsApiCallSpy
).
not
.
toHaveBeenCalled
();
wrapper
.
setProps
({
enabledRefTypes
:
[
REF_TYPE_BRANCHES
,
REF_TYPE_TAGS
],
});
await
waitForRequests
();
expect
(
branchesApiCallSpy
).
toHaveBeenCalledTimes
(
2
);
expect
(
tagsApiCallSpy
).
toHaveBeenCalledTimes
(
1
);
});
it
(
'
if a ref type becomes disabled, its section is hidden, even if it had some results in store
'
,
async
()
=>
{
createComponent
({
enabledRefTypes
:
[
REF_TYPE_BRANCHES
,
REF_TYPE_COMMITS
]
});
updateQuery
(
'
abcd1234
'
);
await
waitForRequests
();
expect
(
findBranchesSection
().
exists
()).
toBe
(
true
);
expect
(
findCommitsSection
().
exists
()).
toBe
(
true
);
wrapper
.
setProps
({
enabledRefTypes
:
[
REF_TYPE_COMMITS
]
});
await
waitForRequests
();
expect
(
findBranchesSection
().
exists
()).
toBe
(
false
);
expect
(
findCommitsSection
().
exists
()).
toBe
(
true
);
});
it
.
each
`
enabledRefType | findVisibleSection | findHiddenSections
${
REF_TYPE_BRANCHES
}
|
${
findBranchesSection
}
|
${[
findTagsSection
,
findCommitsSection
]}
${
REF_TYPE_TAGS
}
|
${
findTagsSection
}
|
${[
findBranchesSection
,
findCommitsSection
]}
${
REF_TYPE_COMMITS
}
|
${
findCommitsSection
}
|
${[
findBranchesSection
,
findTagsSection
]}
`
(
'
hides section headers if a single ref type is enabled
'
,
async
({
enabledRefType
,
findVisibleSection
,
findHiddenSections
})
=>
{
createComponent
({
enabledRefTypes
:
[
enabledRefType
]
});
updateQuery
(
'
abcd1234
'
);
await
waitForRequests
();
expect
(
findVisibleSection
().
exists
()).
toBe
(
true
);
expect
(
findVisibleSection
().
find
(
'
[data-testid="section-header"]
'
).
exists
()).
toBe
(
false
);
findHiddenSections
.
forEach
((
findHiddenSection
)
=>
expect
(
findHiddenSection
().
exists
()).
toBe
(
false
),
);
},
);
});
});
});
spec/frontend/ref/stores/actions_spec.js
View file @
aa621050
import
testAction
from
'
helpers/vuex_action_helper
'
;
import
testAction
from
'
helpers/vuex_action_helper
'
;
import
{
ALL_REF_TYPES
,
REF_TYPE_BRANCHES
,
REF_TYPE_TAGS
,
REF_TYPE_COMMITS
}
from
'
~/ref/constants
'
;
import
*
as
actions
from
'
~/ref/stores/actions
'
;
import
*
as
actions
from
'
~/ref/stores/actions
'
;
import
*
as
types
from
'
~/ref/stores/mutation_types
'
;
import
*
as
types
from
'
~/ref/stores/mutation_types
'
;
import
createState
from
'
~/ref/stores/state
'
;
import
createState
from
'
~/ref/stores/state
'
;
...
@@ -25,6 +26,14 @@ describe('Ref selector Vuex store actions', () => {
...
@@ -25,6 +26,14 @@ describe('Ref selector Vuex store actions', () => {
state
=
createState
();
state
=
createState
();
});
});
describe
(
'
setEnabledRefTypes
'
,
()
=>
{
it
(
`commits
${
types
.
SET_ENABLED_REF_TYPES
}
with the enabled ref types`
,
()
=>
{
testAction
(
actions
.
setProjectId
,
ALL_REF_TYPES
,
state
,
[
{
type
:
types
.
SET_PROJECT_ID
,
payload
:
ALL_REF_TYPES
},
]);
});
});
describe
(
'
setProjectId
'
,
()
=>
{
describe
(
'
setProjectId
'
,
()
=>
{
it
(
`commits
${
types
.
SET_PROJECT_ID
}
with the new project ID`
,
()
=>
{
it
(
`commits
${
types
.
SET_PROJECT_ID
}
with the new project ID`
,
()
=>
{
const
projectId
=
'
4
'
;
const
projectId
=
'
4
'
;
...
@@ -46,12 +55,23 @@ describe('Ref selector Vuex store actions', () => {
...
@@ -46,12 +55,23 @@ describe('Ref selector Vuex store actions', () => {
describe
(
'
search
'
,
()
=>
{
describe
(
'
search
'
,
()
=>
{
it
(
`commits
${
types
.
SET_QUERY
}
with the new search query`
,
()
=>
{
it
(
`commits
${
types
.
SET_QUERY
}
with the new search query`
,
()
=>
{
const
query
=
'
hello
'
;
const
query
=
'
hello
'
;
testAction
(
actions
.
search
,
query
,
state
,
[{
type
:
types
.
SET_QUERY
,
payload
:
query
}]);
});
it
.
each
`
enabledRefTypes | expectedActions
${[
REF_TYPE_BRANCHES
]}
|
${[
'
searchBranches
'
]}
${[
REF_TYPE_COMMITS
]}
|
${[
'
searchCommits
'
]}
${[
REF_TYPE_BRANCHES
,
REF_TYPE_TAGS
,
REF_TYPE_COMMITS
]}
|
${[
'
searchBranches
'
,
'
searchTags
'
,
'
searchCommits
'
]}
`
(
`dispatches fetch actions for enabled ref types`
,
({
enabledRefTypes
,
expectedActions
})
=>
{
const
query
=
'
hello
'
;
state
.
enabledRefTypes
=
enabledRefTypes
;
testAction
(
testAction
(
actions
.
search
,
actions
.
search
,
query
,
query
,
state
,
state
,
[{
type
:
types
.
SET_QUERY
,
payload
:
query
}],
[{
type
:
types
.
SET_QUERY
,
payload
:
query
}],
[{
type
:
'
searchBranches
'
},
{
type
:
'
searchTags
'
},
{
type
:
'
searchCommits
'
}]
,
expectedActions
.
map
((
type
)
=>
({
type
}))
,
);
);
});
});
});
});
...
...
spec/frontend/ref/stores/mutations_spec.js
View file @
aa621050
import
{
X_TOTAL_HEADER
}
from
'
~/ref/constants
'
;
import
{
X_TOTAL_HEADER
,
ALL_REF_TYPES
}
from
'
~/ref/constants
'
;
import
*
as
types
from
'
~/ref/stores/mutation_types
'
;
import
*
as
types
from
'
~/ref/stores/mutation_types
'
;
import
mutations
from
'
~/ref/stores/mutations
'
;
import
mutations
from
'
~/ref/stores/mutations
'
;
import
createState
from
'
~/ref/stores/state
'
;
import
createState
from
'
~/ref/stores/state
'
;
...
@@ -13,6 +13,7 @@ describe('Ref selector Vuex store mutations', () => {
...
@@ -13,6 +13,7 @@ describe('Ref selector Vuex store mutations', () => {
describe
(
'
initial state
'
,
()
=>
{
describe
(
'
initial state
'
,
()
=>
{
it
(
'
is created with the correct structure and initial values
'
,
()
=>
{
it
(
'
is created with the correct structure and initial values
'
,
()
=>
{
expect
(
state
).
toEqual
({
expect
(
state
).
toEqual
({
enabledRefTypes
:
[],
projectId
:
null
,
projectId
:
null
,
query
:
''
,
query
:
''
,
...
@@ -39,6 +40,14 @@ describe('Ref selector Vuex store mutations', () => {
...
@@ -39,6 +40,14 @@ describe('Ref selector Vuex store mutations', () => {
});
});
});
});
describe
(
`
${
types
.
SET_ENABLED_REF_TYPES
}
`
,
()
=>
{
it
(
'
sets the enabled ref types
'
,
()
=>
{
mutations
[
types
.
SET_ENABLED_REF_TYPES
](
state
,
ALL_REF_TYPES
);
expect
(
state
.
enabledRefTypes
).
toBe
(
ALL_REF_TYPES
);
});
});
describe
(
`
${
types
.
SET_PROJECT_ID
}
`
,
()
=>
{
describe
(
`
${
types
.
SET_PROJECT_ID
}
`
,
()
=>
{
it
(
'
updates the project ID
'
,
()
=>
{
it
(
'
updates the project ID
'
,
()
=>
{
const
newProjectId
=
'
4
'
;
const
newProjectId
=
'
4
'
;
...
...
spec/helpers/preferences_helper_spec.rb
View file @
aa621050
...
@@ -29,6 +29,7 @@ RSpec.describe PreferencesHelper do
...
@@ -29,6 +29,7 @@ RSpec.describe PreferencesHelper do
[
'Starred Projects'
,
'stars'
],
[
'Starred Projects'
,
'stars'
],
[
"Your Projects' Activity"
,
'project_activity'
],
[
"Your Projects' Activity"
,
'project_activity'
],
[
"Starred Projects' Activity"
,
'starred_project_activity'
],
[
"Starred Projects' Activity"
,
'starred_project_activity'
],
[
"Followed Users' Activity"
,
'followed_user_activity'
],
[
"Your Groups"
,
'groups'
],
[
"Your Groups"
,
'groups'
],
[
"Your To-Do List"
,
'todos'
],
[
"Your To-Do List"
,
'todos'
],
[
"Assigned Issues"
,
'issues'
],
[
"Assigned Issues"
,
'issues'
],
...
...
spec/requests/api/ci/runner/jobs_request_post_spec.rb
View file @
aa621050
...
@@ -797,6 +797,50 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
...
@@ -797,6 +797,50 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
end
end
end
end
describe
'setting the application context'
do
subject
{
request_job
}
context
'when triggered by a user'
do
let
(
:job
)
{
create
(
:ci_build
,
user:
user
,
project:
project
)
}
subject
{
request_job
(
id:
job
.
id
)
}
it_behaves_like
'storing arguments in the application context'
do
let
(
:expected_params
)
{
{
user:
user
.
username
,
project:
project
.
full_path
}
}
end
it_behaves_like
'not executing any extra queries for the application context'
,
3
do
# Extra queries: User, Project, Route
let
(
:subject_proc
)
{
proc
{
request_job
(
id:
job
.
id
)
}
}
end
end
context
'when the runner is of project type'
do
it_behaves_like
'storing arguments in the application context'
do
let
(
:expected_params
)
{
{
project:
project
.
full_path
}
}
end
it_behaves_like
'not executing any extra queries for the application context'
,
2
do
# Extra queries: Project, Route
let
(
:subject_proc
)
{
proc
{
request_job
}
}
end
end
context
'when the runner is of group type'
do
let
(
:group
)
{
create
(
:group
)
}
let
(
:runner
)
{
create
(
:ci_runner
,
:group
,
groups:
[
group
])
}
it_behaves_like
'storing arguments in the application context'
do
let
(
:expected_params
)
{
{
root_namespace:
group
.
full_path_components
.
first
}
}
end
it_behaves_like
'not executing any extra queries for the application context'
,
2
do
# Extra queries: Group, Route
let
(
:subject_proc
)
{
proc
{
request_job
}
}
end
end
end
def
request_job
(
token
=
runner
.
token
,
**
params
)
def
request_job
(
token
=
runner
.
token
,
**
params
)
new_params
=
params
.
merge
(
token:
token
,
last_update:
last_update
)
new_params
=
params
.
merge
(
token:
token
,
last_update:
last_update
)
post
api
(
'/jobs/request'
),
params:
new_params
.
to_json
,
headers:
{
'User-Agent'
=>
user_agent
,
'Content-Type'
:
'application/json'
}
post
api
(
'/jobs/request'
),
params:
new_params
.
to_json
,
headers:
{
'User-Agent'
=>
user_agent
,
'Content-Type'
:
'application/json'
}
...
...
spec/requests/api/ci/runner/runners_post_spec.rb
View file @
aa621050
...
@@ -35,6 +35,10 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
...
@@ -35,6 +35,10 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
end
end
context
'when valid token is provided'
do
context
'when valid token is provided'
do
def
request
post
api
(
'/runners'
),
params:
{
token:
token
}
end
it
'creates runner with default values'
do
it
'creates runner with default values'
do
post
api
(
'/runners'
),
params:
{
token:
registration_token
}
post
api
(
'/runners'
),
params:
{
token:
registration_token
}
...
@@ -51,9 +55,10 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
...
@@ -51,9 +55,10 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
context
'when project token is used'
do
context
'when project token is used'
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:token
)
{
project
.
runners_token
}
it
'creates project runner'
do
it
'creates project runner'
do
post
api
(
'/runners'
),
params:
{
token:
project
.
runners_token
}
request
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
project
.
runners
.
size
).
to
eq
(
1
)
expect
(
project
.
runners
.
size
).
to
eq
(
1
)
...
@@ -62,13 +67,24 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
...
@@ -62,13 +67,24 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
expect
(
runner
.
token
).
not_to
eq
(
project
.
runners_token
)
expect
(
runner
.
token
).
not_to
eq
(
project
.
runners_token
)
expect
(
runner
).
to
be_project_type
expect
(
runner
).
to
be_project_type
end
end
it_behaves_like
'storing arguments in the application context'
do
subject
{
request
}
let
(
:expected_params
)
{
{
project:
project
.
full_path
}
}
end
it_behaves_like
'not executing any extra queries for the application context'
do
let
(
:subject_proc
)
{
proc
{
request
}
}
end
end
end
context
'when group token is used'
do
context
'when group token is used'
do
let
(
:group
)
{
create
(
:group
)
}
let
(
:group
)
{
create
(
:group
)
}
let
(
:token
)
{
group
.
runners_token
}
it
'creates a group runner'
do
it
'creates a group runner'
do
post
api
(
'/runners'
),
params:
{
token:
group
.
runners_token
}
request
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
group
.
runners
.
reload
.
size
).
to
eq
(
1
)
expect
(
group
.
runners
.
reload
.
size
).
to
eq
(
1
)
...
@@ -77,6 +93,16 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
...
@@ -77,6 +93,16 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
expect
(
runner
.
token
).
not_to
eq
(
group
.
runners_token
)
expect
(
runner
.
token
).
not_to
eq
(
group
.
runners_token
)
expect
(
runner
).
to
be_group_type
expect
(
runner
).
to
be_group_type
end
end
it_behaves_like
'storing arguments in the application context'
do
subject
{
request
}
let
(
:expected_params
)
{
{
root_namespace:
group
.
full_path_components
.
first
}
}
end
it_behaves_like
'not executing any extra queries for the application context'
do
let
(
:subject_proc
)
{
proc
{
request
}
}
end
end
end
end
end
...
...
spec/support/shared_examples/requests/api/logging_application_context_shared_examples.rb
View file @
aa621050
...
@@ -22,3 +22,19 @@ RSpec.shared_examples 'storing arguments in the application context' do
...
@@ -22,3 +22,19 @@ RSpec.shared_examples 'storing arguments in the application context' do
hash
.
transform_keys!
{
|
key
|
"meta.
#{
key
}
"
}
hash
.
transform_keys!
{
|
key
|
"meta.
#{
key
}
"
}
end
end
end
end
RSpec
.
shared_examples
'not executing any extra queries for the application context'
do
|
expected_extra_queries
=
0
|
it
'does not execute more queries than without adding anything to the application context'
do
# Call the subject once to memoize all factories being used for the spec, so they won't
# add any queries to the expectation.
subject_proc
.
call
expect
do
allow
(
Gitlab
::
ApplicationContext
).
to
receive
(
:push
).
and_call_original
subject_proc
.
call
end
.
to
issue_same_number_of_queries_as
{
allow
(
Gitlab
::
ApplicationContext
).
to
receive
(
:push
)
subject_proc
.
call
}.
with_threshold
(
expected_extra_queries
).
ignoring_cached_queries
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