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
cd15d0e6
Commit
cd15d0e6
authored
Dec 06, 2019
by
GitLab Bot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add latest changes from gitlab-org/gitlab@master
parent
dd6afb4b
Changes
60
Hide whitespace changes
Inline
Side-by-side
Showing
60 changed files
with
1216 additions
and
103 deletions
+1216
-103
app/assets/javascripts/confidential_merge_request/components/project_form_group.vue
...fidential_merge_request/components/project_form_group.vue
+17
-13
app/assets/stylesheets/framework/dropdowns.scss
app/assets/stylesheets/framework/dropdowns.scss
+1
-1
app/assets/stylesheets/pages/issues.scss
app/assets/stylesheets/pages/issues.scss
+0
-1
app/graphql/resolvers/error_tracking/sentry_detailed_error_resolver.rb
...esolvers/error_tracking/sentry_detailed_error_resolver.rb
+28
-0
app/graphql/types/error_tracking/sentry_detailed_error_type.rb
...raphql/types/error_tracking/sentry_detailed_error_type.rb
+93
-0
app/graphql/types/error_tracking/sentry_error_frequency_type.rb
...aphql/types/error_tracking/sentry_error_frequency_type.rb
+18
-0
app/graphql/types/error_tracking/sentry_error_status_enum.rb
app/graphql/types/error_tracking/sentry_error_status_enum.rb
+15
-0
app/graphql/types/project_type.rb
app/graphql/types/project_type.rb
+6
-0
app/models/concerns/issuable.rb
app/models/concerns/issuable.rb
+1
-1
app/policies/error_tracking/detailed_error_policy.rb
app/policies/error_tracking/detailed_error_policy.rb
+7
-0
app/presenters/sentry_detailed_error_presenter.rb
app/presenters/sentry_detailed_error_presenter.rb
+15
-0
app/views/projects/issues/_new_branch.html.haml
app/views/projects/issues/_new_branch.html.haml
+1
-1
changelogs/unreleased/34943-graphql-sentry-details.yml
changelogs/unreleased/34943-graphql-sentry-details.yml
+5
-0
changelogs/unreleased/38244-fix-release-filter-on-mr-page.yml
...gelogs/unreleased/38244-fix-release-filter-on-mr-page.yml
+5
-0
changelogs/unreleased/confidential_mr_styling.yml
changelogs/unreleased/confidential_mr_styling.yml
+5
-0
doc/api/graphql/reference/gitlab_schema.graphql
doc/api/graphql/reference/gitlab_schema.graphql
+154
-0
doc/api/graphql/reference/gitlab_schema.json
doc/api/graphql/reference/gitlab_schema.json
+490
-0
doc/api/graphql/reference/index.md
doc/api/graphql/reference/index.md
+34
-0
doc/ci/yaml/README.md
doc/ci/yaml/README.md
+29
-1
lib/gitlab/error_tracking/detailed_error.rb
lib/gitlab/error_tracking/detailed_error.rb
+6
-0
locale/gitlab.pot
locale/gitlab.pot
+5
-2
spec/factories/error_tracking/detailed_error.rb
spec/factories/error_tracking/detailed_error.rb
+8
-4
spec/features/issues/user_creates_confidential_merge_request_spec.rb
...es/issues/user_creates_confidential_merge_request_spec.rb
+1
-1
spec/frontend/confidential_merge_request/components/__snapshots__/project_form_group_spec.js.snap
.../components/__snapshots__/project_form_group_spec.js.snap
+8
-22
spec/graphql/resolvers/error_tracking/sentry_detailed_error_resolver_spec.rb
...ers/error_tracking/sentry_detailed_error_resolver_spec.rb
+62
-0
spec/graphql/types/error_tracking/sentry_detailed_error_type_spec.rb
...l/types/error_tracking/sentry_detailed_error_type_spec.rb
+37
-0
spec/graphql/types/project_type_spec.rb
spec/graphql/types/project_type_spec.rb
+1
-2
spec/javascripts/vue_shared/components/bar_chart_spec.js
spec/javascripts/vue_shared/components/bar_chart_spec.js
+1
-1
spec/javascripts/vue_shared/components/ci_badge_link_spec.js
spec/javascripts/vue_shared/components/ci_badge_link_spec.js
+1
-1
spec/javascripts/vue_shared/components/ci_icon_spec.js
spec/javascripts/vue_shared/components/ci_icon_spec.js
+1
-1
spec/javascripts/vue_shared/components/content_viewer/content_viewer_spec.js
...e_shared/components/content_viewer/content_viewer_spec.js
+2
-2
spec/javascripts/vue_shared/components/deprecated_modal_2_spec.js
...ascripts/vue_shared/components/deprecated_modal_2_spec.js
+1
-1
spec/javascripts/vue_shared/components/deprecated_modal_spec.js
...avascripts/vue_shared/components/deprecated_modal_spec.js
+1
-1
spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js
...pts/vue_shared/components/diff_viewer/diff_viewer_spec.js
+1
-1
spec/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer_spec.js
.../components/diff_viewer/viewers/image_diff_viewer_spec.js
+1
-1
spec/javascripts/vue_shared/components/dropdown/dropdown_button_spec.js
...ts/vue_shared/components/dropdown/dropdown_button_spec.js
+1
-2
spec/javascripts/vue_shared/components/dropdown/dropdown_hidden_input_spec.js
..._shared/components/dropdown/dropdown_hidden_input_spec.js
+1
-2
spec/javascripts/vue_shared/components/dropdown/dropdown_search_input_spec.js
..._shared/components/dropdown/dropdown_search_input_spec.js
+1
-2
spec/javascripts/vue_shared/components/file_finder/index_spec.js
...vascripts/vue_shared/components/file_finder/index_spec.js
+2
-2
spec/javascripts/vue_shared/components/file_finder/item_spec.js
...avascripts/vue_shared/components/file_finder/item_spec.js
+1
-1
spec/javascripts/vue_shared/components/file_row_spec.js
spec/javascripts/vue_shared/components/file_row_spec.js
+1
-1
spec/javascripts/vue_shared/components/filtered_search_dropdown_spec.js
...ts/vue_shared/components/filtered_search_dropdown_spec.js
+1
-1
spec/javascripts/vue_shared/components/header_ci_component_spec.js
...scripts/vue_shared/components/header_ci_component_spec.js
+1
-1
spec/javascripts/vue_shared/components/icon_spec.js
spec/javascripts/vue_shared/components/icon_spec.js
+2
-2
spec/javascripts/vue_shared/components/loading_button_spec.js
.../javascripts/vue_shared/components/loading_button_spec.js
+1
-1
spec/javascripts/vue_shared/components/markdown/toolbar_spec.js
...avascripts/vue_shared/components/markdown/toolbar_spec.js
+1
-1
spec/javascripts/vue_shared/components/navigation_tabs_spec.js
...javascripts/vue_shared/components/navigation_tabs_spec.js
+1
-1
spec/javascripts/vue_shared/components/panel_resizer_spec.js
spec/javascripts/vue_shared/components/panel_resizer_spec.js
+1
-1
spec/javascripts/vue_shared/components/pikaday_spec.js
spec/javascripts/vue_shared/components/pikaday_spec.js
+1
-1
spec/javascripts/vue_shared/components/project_avatar/default_spec.js
...ipts/vue_shared/components/project_avatar/default_spec.js
+2
-2
spec/javascripts/vue_shared/components/project_selector/project_list_item_spec.js
...red/components/project_selector/project_list_item_spec.js
+1
-1
spec/javascripts/vue_shared/components/project_selector/project_selector_spec.js
...ared/components/project_selector/project_selector_spec.js
+2
-2
spec/javascripts/vue_shared/components/smart_virtual_list_spec.js
...ascripts/vue_shared/components/smart_virtual_list_spec.js
+1
-1
spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js
...cripts/vue_shared/components/stacked_progress_bar_spec.js
+1
-2
spec/javascripts/vue_shared/components/toggle_button_spec.js
spec/javascripts/vue_shared/components/toggle_button_spec.js
+1
-1
spec/javascripts/vue_shared/components/user_avatar/user_avatar_svg_spec.js
...vue_shared/components/user_avatar/user_avatar_svg_spec.js
+1
-1
spec/javascripts/vue_shared/translate_spec.js
spec/javascripts/vue_shared/translate_spec.js
+1
-1
spec/models/concerns/issuable_spec.rb
spec/models/concerns/issuable_spec.rb
+31
-15
spec/presenters/sentry_detailed_error_presenter_spec.rb
spec/presenters/sentry_detailed_error_presenter_spec.rb
+29
-0
spec/requests/api/graphql/project/error_tracking/sentry_detailed_error_request_spec.rb
...ject/error_tracking/sentry_detailed_error_request_spec.rb
+69
-0
No files found.
app/assets/javascripts/confidential_merge_request/components/project_form_group.vue
View file @
cd15d0e6
<
script
>
<
script
>
import
{
GlLink
}
from
'
@gitlab/ui
'
;
import
{
GlLink
,
GlSprintf
}
from
'
@gitlab/ui
'
;
import
{
__
,
sprintf
}
from
'
../../locale
'
;
import
{
__
}
from
'
../../locale
'
;
import
createFlash
from
'
../../flash
'
;
import
createFlash
from
'
../../flash
'
;
import
Api
from
'
../../api
'
;
import
Api
from
'
../../api
'
;
import
state
from
'
../state
'
;
import
state
from
'
../state
'
;
...
@@ -9,6 +9,7 @@ import Dropdown from './dropdown.vue';
...
@@ -9,6 +9,7 @@ import Dropdown from './dropdown.vue';
export
default
{
export
default
{
components
:
{
components
:
{
GlLink
,
GlLink
,
GlSprintf
,
Dropdown
,
Dropdown
,
},
},
props
:
{
props
:
{
...
@@ -38,15 +39,6 @@ export default {
...
@@ -38,15 +39,6 @@ export default {
selectedProject
()
{
selectedProject
()
{
return
state
.
selectedProject
;
return
state
.
selectedProject
;
},
},
noForkText
()
{
return
sprintf
(
__
(
"
To protect this issue's confidentiality, %{link_start}fork the project%{link_end} and set the forks visibility to private.
"
,
),
{
link_start
:
`<a href="
${
this
.
newForkPath
}
" class="help-link">`
,
link_end
:
'
</a>
'
},
false
,
);
},
},
},
mounted
()
{
mounted
()
{
this
.
fetchProjects
();
this
.
fetchProjects
();
...
@@ -123,8 +115,20 @@ export default {
...
@@ -123,8 +115,20 @@ export default {
}}
}}
</
template
>
</
template
>
<
template
v-else
>
<
template
v-else
>
{{
__
(
'
No forks available to you.
'
)
}}
<br
/>
{{
__
(
'
No forks are available to you.
'
)
}}
<br
/>
<span
v-html=
"noForkText"
></span>
<gl-sprintf
:message=
"
__(
`To protect this issue's confidentiality, %
{forkLink} and set the fork's visibility to private.`,
)
"
>
<template
#forkLink
>
<a
:href=
"newForkPath"
target=
"_blank"
class=
"help-link"
>
{{
__
(
'
fork this project
'
)
}}
</a>
</
template
>
</gl-sprintf>
</template>
</template>
<gl-link
<gl-link
:href=
"helpPagePath"
:href=
"helpPagePath"
...
...
app/assets/stylesheets/framework/dropdowns.scss
View file @
cd15d0e6
...
@@ -288,7 +288,7 @@
...
@@ -288,7 +288,7 @@
list-style
:
none
;
list-style
:
none
;
padding
:
0
1px
;
padding
:
0
1px
;
a
,
a
:not
(
.help-link
)
,
button
,
button
,
.menu-item
{
.menu-item
{
@include
dropdown-link
;
@include
dropdown-link
;
...
...
app/assets/stylesheets/pages/issues.scss
View file @
cd15d0e6
...
@@ -214,7 +214,6 @@ ul.related-merge-requests > li {
...
@@ -214,7 +214,6 @@ ul.related-merge-requests > li {
}
}
.create-merge-request-dropdown-menu
{
.create-merge-request-dropdown-menu
{
width
:
300px
;
opacity
:
1
;
opacity
:
1
;
visibility
:
visible
;
visibility
:
visible
;
transform
:
translateY
(
0
);
transform
:
translateY
(
0
);
...
...
app/graphql/resolvers/error_tracking/sentry_detailed_error_resolver.rb
0 → 100644
View file @
cd15d0e6
# frozen_string_literal: true
module
Resolvers
module
ErrorTracking
class
SentryDetailedErrorResolver
<
BaseResolver
argument
:id
,
GraphQL
::
ID_TYPE
,
required:
true
,
description:
'ID of the Sentry issue'
def
resolve
(
**
args
)
project
=
object
current_user
=
context
[
:current_user
]
issue_id
=
GlobalID
.
parse
(
args
[
:id
]).
model_id
# Get data from Sentry
response
=
::
ErrorTracking
::
IssueDetailsService
.
new
(
project
,
current_user
,
{
issue_id:
issue_id
}
).
execute
issue
=
response
[
:issue
]
issue
.
gitlab_project
=
project
if
issue
issue
end
end
end
end
app/graphql/types/error_tracking/sentry_detailed_error_type.rb
0 → 100644
View file @
cd15d0e6
# frozen_string_literal: true
module
Types
module
ErrorTracking
class
SentryDetailedErrorType
<
::
Types
::
BaseObject
graphql_name
'SentryDetailedError'
present_using
SentryDetailedErrorPresenter
authorize
:read_sentry_issue
field
:id
,
GraphQL
::
ID_TYPE
,
null:
false
,
description:
"ID (global ID) of the error"
field
:sentry_id
,
GraphQL
::
STRING_TYPE
,
method: :id
,
null:
false
,
description:
"ID (Sentry ID) of the error"
field
:title
,
GraphQL
::
STRING_TYPE
,
null:
false
,
description:
"Title of the error"
field
:type
,
GraphQL
::
STRING_TYPE
,
null:
false
,
description:
"Type of the error"
field
:user_count
,
GraphQL
::
INT_TYPE
,
null:
false
,
description:
"Count of users affected by the error"
field
:count
,
GraphQL
::
INT_TYPE
,
null:
false
,
description:
"Count of occurrences"
field
:first_seen
,
Types
::
TimeType
,
null:
false
,
description:
"Timestamp when the error was first seen"
field
:last_seen
,
Types
::
TimeType
,
null:
false
,
description:
"Timestamp when the error was last seen"
field
:message
,
GraphQL
::
STRING_TYPE
,
null:
true
,
description:
"Sentry metadata message of the error"
field
:culprit
,
GraphQL
::
STRING_TYPE
,
null:
false
,
description:
"Culprit of the error"
field
:external_url
,
GraphQL
::
STRING_TYPE
,
null:
false
,
description:
"External URL of the error"
field
:sentry_project_id
,
GraphQL
::
ID_TYPE
,
method: :project_id
,
null:
false
,
description:
"ID of the project (Sentry project)"
field
:sentry_project_name
,
GraphQL
::
STRING_TYPE
,
method: :project_name
,
null:
false
,
description:
"Name of the project affected by the error"
field
:sentry_project_slug
,
GraphQL
::
STRING_TYPE
,
method: :project_slug
,
null:
false
,
description:
"Slug of the project affected by the error"
field
:short_id
,
GraphQL
::
STRING_TYPE
,
null:
false
,
description:
"Short ID (Sentry ID) of the error"
field
:status
,
Types
::
ErrorTracking
::
SentryErrorStatusEnum
,
null:
false
,
description:
"Status of the error"
field
:frequency
,
[
Types
::
ErrorTracking
::
SentryErrorFrequencyType
],
null:
false
,
description:
"Last 24hr stats of the error"
field
:first_release_last_commit
,
GraphQL
::
STRING_TYPE
,
null:
true
,
description:
"Commit the error was first seen"
field
:last_release_last_commit
,
GraphQL
::
STRING_TYPE
,
null:
true
,
description:
"Commit the error was last seen"
field
:first_release_short_version
,
GraphQL
::
STRING_TYPE
,
null:
true
,
description:
"Release version the error was first seen"
field
:last_release_short_version
,
GraphQL
::
STRING_TYPE
,
null:
true
,
description:
"Release version the error was last seen"
def
first_seen
DateTime
.
parse
(
object
.
first_seen
)
end
def
last_seen
DateTime
.
parse
(
object
.
last_seen
)
end
def
project_id
Gitlab
::
GlobalId
.
build
(
model_name:
'Project'
,
id:
object
.
project_id
).
to_s
end
end
end
end
app/graphql/types/error_tracking/sentry_error_frequency_type.rb
0 → 100644
View file @
cd15d0e6
# frozen_string_literal: true
module
Types
module
ErrorTracking
# rubocop: disable Graphql/AuthorizeTypes
class
SentryErrorFrequencyType
<
::
Types
::
BaseObject
graphql_name
'SentryErrorFrequency'
field
:time
,
Types
::
TimeType
,
null:
false
,
description:
"Time the error frequency stats were recorded"
field
:count
,
GraphQL
::
INT_TYPE
,
null:
false
,
description:
"Count of errors received since the previously recorded time"
end
# rubocop: enable Graphql/AuthorizeTypes
end
end
app/graphql/types/error_tracking/sentry_error_status_enum.rb
0 → 100644
View file @
cd15d0e6
# frozen_string_literal: true
module
Types
module
ErrorTracking
class
SentryErrorStatusEnum
<
::
Types
::
BaseEnum
graphql_name
'SentryErrorStatus'
description
'State of a Sentry error'
value
'RESOLVED'
,
value:
'resolved'
,
description:
'Error has been resolved'
value
'RESOLVED_IN_NEXT_RELEASE'
,
value:
'resolvedInNextRelease'
,
description:
'Error has been ignored until next release'
value
'UNRESOLVED'
,
value:
'unresolved'
,
description:
'Error is unresolved'
value
'IGNORED'
,
value:
'ignored'
,
description:
'Error has been ignored'
end
end
end
app/graphql/types/project_type.rb
View file @
cd15d0e6
...
@@ -145,5 +145,11 @@ module Types
...
@@ -145,5 +145,11 @@ module Types
null:
true
,
null:
true
,
description:
'Build pipelines of the project'
,
description:
'Build pipelines of the project'
,
resolver:
Resolvers
::
ProjectPipelinesResolver
resolver:
Resolvers
::
ProjectPipelinesResolver
field
:sentry_detailed_error
,
Types
::
ErrorTracking
::
SentryDetailedErrorType
,
null:
true
,
description:
'Detailed version of a Sentry error on the project'
,
resolver:
Resolvers
::
ErrorTracking
::
SentryDetailedErrorResolver
end
end
end
end
app/models/concerns/issuable.rb
View file @
cd15d0e6
...
@@ -128,7 +128,7 @@ module Issuable
...
@@ -128,7 +128,7 @@ module Issuable
end
end
scope
:joins_milestone_releases
,
->
do
scope
:joins_milestone_releases
,
->
do
joins
(
"JOIN milestone_releases ON
issues
.milestone_id = milestone_releases.milestone_id
joins
(
"JOIN milestone_releases ON
#{
table_name
}
.milestone_id = milestone_releases.milestone_id
JOIN releases ON milestone_releases.release_id = releases.id"
).
distinct
JOIN releases ON milestone_releases.release_id = releases.id"
).
distinct
end
end
...
...
app/policies/error_tracking/detailed_error_policy.rb
0 → 100644
View file @
cd15d0e6
# frozen_string_literal: true
module
ErrorTracking
class
DetailedErrorPolicy
<
BasePolicy
delegate
{
@subject
.
gitlab_project
}
end
end
app/presenters/sentry_detailed_error_presenter.rb
0 → 100644
View file @
cd15d0e6
# frozen_string_literal: true
class
SentryDetailedErrorPresenter
<
Gitlab
::
View
::
Presenter
::
Delegated
presents
:error
FrequencyStruct
=
Struct
.
new
(
:time
,
:count
,
keyword_init:
true
)
def
frequency
utc_offset
=
Time
.
zone_offset
(
'UTC'
)
error
.
frequency
.
map
do
|
f
|
FrequencyStruct
.
new
(
time:
Time
.
at
(
f
[
0
],
in:
utc_offset
),
count:
f
[
1
])
end
end
end
app/views/projects/issues/_new_branch.html.haml
View file @
cd15d0e6
...
@@ -28,7 +28,7 @@
...
@@ -28,7 +28,7 @@
%ul
#create-merge-request-dropdown
.create-merge-request-dropdown-menu.dropdown-menu.dropdown-menu-right.gl-show-field-errors
{
class:
(
"create-confidential-merge-request-dropdown-menu"
if
can_create_confidential_merge_request?
),
data:
{
dropdown:
true
}
}
%ul
#create-merge-request-dropdown
.create-merge-request-dropdown-menu.dropdown-menu.dropdown-menu-right.gl-show-field-errors
{
class:
(
"create-confidential-merge-request-dropdown-menu"
if
can_create_confidential_merge_request?
),
data:
{
dropdown:
true
}
}
-
if
can_create_merge_request
-
if
can_create_merge_request
%li
.droplab-item-selected
{
role:
'button'
,
data:
{
value:
'create-mr'
,
text:
create_mr_text
}
}
%li
.droplab-item-selected
{
role:
'button'
,
data:
{
value:
'create-mr'
,
text:
create_mr_text
}
}
.menu-item
.menu-item
.text-nowrap
=
icon
(
'check'
,
class:
'icon'
)
=
icon
(
'check'
,
class:
'icon'
)
-
if
can_create_confidential_merge_request?
-
if
can_create_confidential_merge_request?
=
_
(
'Create confidential merge request and branch'
)
=
_
(
'Create confidential merge request and branch'
)
...
...
changelogs/unreleased/34943-graphql-sentry-details.yml
0 → 100644
View file @
cd15d0e6
---
title
:
GraphQL for Sentry rror details
merge_request
:
19733
author
:
type
:
added
changelogs/unreleased/38244-fix-release-filter-on-mr-page.yml
0 → 100644
View file @
cd15d0e6
---
title
:
Fixed query behind release filter on merge request search page.
merge_request
:
38244
author
:
type
:
fixed
changelogs/unreleased/confidential_mr_styling.yml
0 → 100644
View file @
cd15d0e6
---
title
:
Improve create confidential MR dropdown styling.
merge_request
:
20176
author
:
Lee Tickett
type
:
other
doc/api/graphql/reference/gitlab_schema.graphql
View file @
cd15d0e6
...
@@ -4400,6 +4400,16 @@ type Project {
...
@@ -4400,6 +4400,16 @@ type Project {
"""
"""
requestAccessEnabled
:
Boolean
requestAccessEnabled
:
Boolean
"""
Detailed
version
of
a
Sentry
error
on
the
project
"""
sentryDetailedError
(
"""
ID
of
the
Sentry
issue
"""
id
:
ID
!
):
SentryDetailedError
"""
"""
Indicates
if
shared
runners
are
enabled
on
the
project
Indicates
if
shared
runners
are
enabled
on
the
project
"""
"""
...
@@ -4886,6 +4896,150 @@ type RootStorageStatistics {
...
@@ -4886,6 +4896,150 @@ type RootStorageStatistics {
wikiSize
:
Int
!
wikiSize
:
Int
!
}
}
type
SentryDetailedError
{
"""
Count
of
occurrences
"""
count
:
Int
!
"""
Culprit
of
the
error
"""
culprit
:
String
!
"""
External
URL
of
the
error
"""
externalUrl
:
String
!
"""
Commit
the
error
was
first
seen
"""
firstReleaseLastCommit
:
String
"""
Release
version
the
error
was
first
seen
"""
firstReleaseShortVersion
:
String
"""
Timestamp
when
the
error
was
first
seen
"""
firstSeen
:
Time
!
"""
Last
24
hr
stats
of
the
error
"""
frequency
:
[
SentryErrorFrequency
!]!
"""
ID
(
global
ID
)
of
the
error
"""
id
:
ID
!
"""
Commit
the
error
was
last
seen
"""
lastReleaseLastCommit
:
String
"""
Release
version
the
error
was
last
seen
"""
lastReleaseShortVersion
:
String
"""
Timestamp
when
the
error
was
last
seen
"""
lastSeen
:
Time
!
"""
Sentry
metadata
message
of
the
error
"""
message
:
String
"""
ID
(
Sentry
ID
)
of
the
error
"""
sentryId
:
String
!
"""
ID
of
the
project
(
Sentry
project
)
"""
sentryProjectId
:
ID
!
"""
Name
of
the
project
affected
by
the
error
"""
sentryProjectName
:
String
!
"""
Slug
of
the
project
affected
by
the
error
"""
sentryProjectSlug
:
String
!
"""
Short
ID
(
Sentry
ID
)
of
the
error
"""
shortId
:
String
!
"""
Status
of
the
error
"""
status
:
SentryErrorStatus
!
"""
Title
of
the
error
"""
title
:
String
!
"""
Type
of
the
error
"""
type
:
String
!
"""
Count
of
users
affected
by
the
error
"""
userCount
:
Int
!
}
type
SentryErrorFrequency
{
"""
Count
of
errors
received
since
the
previously
recorded
time
"""
count
:
Int
!
"""
Time
the
error
frequency
stats
were
recorded
"""
time
:
Time
!
}
"""
State of a Sentry error
"""
enum
SentryErrorStatus
{
"""
Error
has
been
ignored
"""
IGNORED
"""
Error
has
been
resolved
"""
RESOLVED
"""
Error
has
been
ignored
until
next
release
"""
RESOLVED_IN_NEXT_RELEASE
"""
Error
is
unresolved
"""
UNRESOLVED
}
type
Submodule
implements
Entry
{
type
Submodule
implements
Entry
{
flatPath
:
String
!
flatPath
:
String
!
id
:
ID
!
id
:
ID
!
...
...
doc/api/graphql/reference/gitlab_schema.json
View file @
cd15d0e6
...
@@ -1166,6 +1166,33 @@
...
@@ -1166,6 +1166,33 @@
"isDeprecated"
:
false
,
"isDeprecated"
:
false
,
"deprecationReason"
:
null
"deprecationReason"
:
null
},
},
{
"name"
:
"sentryDetailedError"
,
"description"
:
"Detailed version of a Sentry error on the project"
,
"args"
:
[
{
"name"
:
"id"
,
"description"
:
"ID of the Sentry issue"
,
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"ID"
,
"ofType"
:
null
}
},
"defaultValue"
:
null
}
],
"type"
:
{
"kind"
:
"OBJECT"
,
"name"
:
"SentryDetailedError"
,
"ofType"
:
null
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
{
"name"
:
"sharedRunnersEnabled"
,
"name"
:
"sharedRunnersEnabled"
,
"description"
:
"Indicates if shared runners are enabled on the project"
,
"description"
:
"Indicates if shared runners are enabled on the project"
,
...
@@ -13788,6 +13815,469 @@
...
@@ -13788,6 +13815,469 @@
],
],
"possibleTypes"
:
null
"possibleTypes"
:
null
},
},
{
"kind"
:
"OBJECT"
,
"name"
:
"SentryDetailedError"
,
"description"
:
null
,
"fields"
:
[
{
"name"
:
"count"
,
"description"
:
"Count of occurrences"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"Int"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"culprit"
,
"description"
:
"Culprit of the error"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"externalUrl"
,
"description"
:
"External URL of the error"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"firstReleaseLastCommit"
,
"description"
:
"Commit the error was first seen"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"firstReleaseShortVersion"
,
"description"
:
"Release version the error was first seen"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"firstSeen"
,
"description"
:
"Timestamp when the error was first seen"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"Time"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"frequency"
,
"description"
:
"Last 24hr stats of the error"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"LIST"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"OBJECT"
,
"name"
:
"SentryErrorFrequency"
,
"ofType"
:
null
}
}
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"id"
,
"description"
:
"ID (global ID) of the error"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"ID"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"lastReleaseLastCommit"
,
"description"
:
"Commit the error was last seen"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"lastReleaseShortVersion"
,
"description"
:
"Release version the error was last seen"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"lastSeen"
,
"description"
:
"Timestamp when the error was last seen"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"Time"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"message"
,
"description"
:
"Sentry metadata message of the error"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"sentryId"
,
"description"
:
"ID (Sentry ID) of the error"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"sentryProjectId"
,
"description"
:
"ID of the project (Sentry project)"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"ID"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"sentryProjectName"
,
"description"
:
"Name of the project affected by the error"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"sentryProjectSlug"
,
"description"
:
"Slug of the project affected by the error"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"shortId"
,
"description"
:
"Short ID (Sentry ID) of the error"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"status"
,
"description"
:
"Status of the error"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"ENUM"
,
"name"
:
"SentryErrorStatus"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"title"
,
"description"
:
"Title of the error"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"type"
,
"description"
:
"Type of the error"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"String"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"userCount"
,
"description"
:
"Count of users affected by the error"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"Int"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
}
],
"inputFields"
:
null
,
"interfaces"
:
[
],
"enumValues"
:
null
,
"possibleTypes"
:
null
},
{
"kind"
:
"ENUM"
,
"name"
:
"SentryErrorStatus"
,
"description"
:
"State of a Sentry error"
,
"fields"
:
null
,
"inputFields"
:
null
,
"interfaces"
:
null
,
"enumValues"
:
[
{
"name"
:
"RESOLVED"
,
"description"
:
"Error has been resolved"
,
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"RESOLVED_IN_NEXT_RELEASE"
,
"description"
:
"Error has been ignored until next release"
,
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"UNRESOLVED"
,
"description"
:
"Error is unresolved"
,
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"IGNORED"
,
"description"
:
"Error has been ignored"
,
"isDeprecated"
:
false
,
"deprecationReason"
:
null
}
],
"possibleTypes"
:
null
},
{
"kind"
:
"OBJECT"
,
"name"
:
"SentryErrorFrequency"
,
"description"
:
null
,
"fields"
:
[
{
"name"
:
"count"
,
"description"
:
"Count of errors received since the previously recorded time"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"Int"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
"name"
:
"time"
,
"description"
:
"Time the error frequency stats were recorded"
,
"args"
:
[
],
"type"
:
{
"kind"
:
"NON_NULL"
,
"name"
:
null
,
"ofType"
:
{
"kind"
:
"SCALAR"
,
"name"
:
"Time"
,
"ofType"
:
null
}
},
"isDeprecated"
:
false
,
"deprecationReason"
:
null
}
],
"inputFields"
:
null
,
"interfaces"
:
[
],
"enumValues"
:
null
,
"possibleTypes"
:
null
},
{
{
"kind"
:
"OBJECT"
,
"kind"
:
"OBJECT"
,
"name"
:
"Metadata"
,
"name"
:
"Metadata"
,
...
...
doc/api/graphql/reference/index.md
View file @
cd15d0e6
...
@@ -664,6 +664,7 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
...
@@ -664,6 +664,7 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
|
`repository`
| Repository | Git repository of the project |
|
`repository`
| Repository | Git repository of the project |
|
`mergeRequest`
| MergeRequest | A single merge request of the project |
|
`mergeRequest`
| MergeRequest | A single merge request of the project |
|
`issue`
| Issue | A single issue of the project |
|
`issue`
| Issue | A single issue of the project |
|
`sentryDetailedError`
| SentryDetailedError | Detailed version of a Sentry error on the project |
### ProjectPermissions
### ProjectPermissions
...
@@ -751,6 +752,39 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
...
@@ -751,6 +752,39 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
|
`packagesSize`
| Int! | The packages size in bytes |
|
`packagesSize`
| Int! | The packages size in bytes |
|
`wikiSize`
| Int! | The wiki size in bytes |
|
`wikiSize`
| Int! | The wiki size in bytes |
### SentryDetailedError
| Name | Type | Description |
| --- | ---- | ---------- |
|
`id`
| ID! | ID (global ID) of the error |
|
`sentryId`
| String! | ID (Sentry ID) of the error |
|
`title`
| String! | Title of the error |
|
`type`
| String! | Type of the error |
|
`userCount`
| Int! | Count of users affected by the error |
|
`count`
| Int! | Count of occurrences |
|
`firstSeen`
| Time! | Timestamp when the error was first seen |
|
`lastSeen`
| Time! | Timestamp when the error was last seen |
|
`message`
| String | Sentry metadata message of the error |
|
`culprit`
| String! | Culprit of the error |
|
`externalUrl`
| String! | External URL of the error |
|
`sentryProjectId`
| ID! | ID of the project (Sentry project) |
|
`sentryProjectName`
| String! | Name of the project affected by the error |
|
`sentryProjectSlug`
| String! | Slug of the project affected by the error |
|
`shortId`
| String! | Short ID (Sentry ID) of the error |
|
`status`
| SentryErrorStatus! | Status of the error |
|
`frequency`
| SentryErrorFrequency! => Array | Last 24hr stats of the error |
|
`firstReleaseLastCommit`
| String | Commit the error was first seen |
|
`lastReleaseLastCommit`
| String | Commit the error was last seen |
|
`firstReleaseShortVersion`
| String | Release version the error was first seen |
|
`lastReleaseShortVersion`
| String | Release version the error was last seen |
### SentryErrorFrequency
| Name | Type | Description |
| --- | ---- | ---------- |
|
`time`
| Time! | Time the error frequency stats were recorded |
|
`count`
| Int! | Count of errors received since the previously recorded time |
### Submodule
### Submodule
| Name | Type | Description |
| Name | Type | Description |
...
...
doc/ci/yaml/README.md
View file @
cd15d0e6
...
@@ -203,7 +203,7 @@ job:
...
@@ -203,7 +203,7 @@ job:
You can use
[
YAML anchors
](
#anchors
)
with scripts, which makes it possible to
You can use
[
YAML anchors
](
#anchors
)
with scripts, which makes it possible to
include a predefined list of commands in multiple jobs.
include a predefined list of commands in multiple jobs.
E
xample:
For e
xample:
```
yaml
```
yaml
.something
:
&something
.something
:
&something
...
@@ -1413,6 +1413,11 @@ Also in the example, `GIT_STRATEGY` is set to `none` so that GitLab Runner won
...
@@ -1413,6 +1413,11 @@ Also in the example, `GIT_STRATEGY` is set to `none` so that GitLab Runner won
try to check out the code after the branch is deleted when the
`stop_review_app`
try to check out the code after the branch is deleted when the
`stop_review_app`
job is
[
automatically triggered
](
../environments.md#automatically-stopping-an-environment
)
.
job is
[
automatically triggered
](
../environments.md#automatically-stopping-an-environment
)
.
NOTE:
**Note:**
The above example overwrites global variables. If your stop environment job depends
on global variables, you can use
[
anchor variables
](
#yaml-anchors-for-variables
)
when setting the
`GIT_STRATEGY`
to change it without overriding the global variables.
The
`stop_review_app`
job is
**required**
to have the following keywords defined:
The
`stop_review_app`
job is
**required**
to have the following keywords defined:
-
`when`
-
[
reference
](
#when
)
-
`when`
-
[
reference
](
#when
)
...
@@ -3159,6 +3164,29 @@ which can be set in GitLab's UI.
...
@@ -3159,6 +3164,29 @@ which can be set in GitLab's UI.
Learn more about
[
variables and their priority
][
variables
]
.
Learn more about
[
variables and their priority
][
variables
]
.
#### YAML anchors for variables
[
YAML anchors
](
#anchors
)
can be used with
`variables`
, to easily repeat assignment
of variables across multiple jobs. It can also enable more flexibility when a job
requires a specific
`variables`
block that would otherwise override the global variables.
In the example below, we will override the
`GIT_STRATEGY`
variable without affecting
the use of the
`SAMPLE_VARIABLE`
variable:
```
yaml
# global variables
variables
:
&global-variables
SAMPLE_VARIABLE
:
sample_variable_value
# a job that needs to set the GIT_STRATEGY variable, yet depend on global variables
job_no_git_strategy
:
stage
:
cleanup
variables
:
<<
:
*global-variables
GIT_STRATEGY
:
none
script
:
echo $SAMPLE_VARIABLE
```
#### Git strategy
#### Git strategy
> Introduced in GitLab 8.9 as an experimental feature. May change or be removed
> Introduced in GitLab 8.9 as an experimental feature. May change or be removed
...
...
lib/gitlab/error_tracking/detailed_error.rb
View file @
cd15d0e6
...
@@ -4,6 +4,7 @@ module Gitlab
...
@@ -4,6 +4,7 @@ module Gitlab
module
ErrorTracking
module
ErrorTracking
class
DetailedError
class
DetailedError
include
ActiveModel
::
Model
include
ActiveModel
::
Model
include
GlobalID
::
Identification
attr_accessor
:count
,
attr_accessor
:count
,
:culprit
,
:culprit
,
...
@@ -13,6 +14,7 @@ module Gitlab
...
@@ -13,6 +14,7 @@ module Gitlab
:first_release_short_version
,
:first_release_short_version
,
:first_seen
,
:first_seen
,
:frequency
,
:frequency
,
:gitlab_project
,
:id
,
:id
,
:last_release_last_commit
,
:last_release_last_commit
,
:last_release_short_version
,
:last_release_short_version
,
...
@@ -26,6 +28,10 @@ module Gitlab
...
@@ -26,6 +28,10 @@ module Gitlab
:title
,
:title
,
:type
,
:type
,
:user_count
:user_count
def
self
.
declarative_policy_class
'ErrorTracking::DetailedErrorPolicy'
end
end
end
end
end
end
end
locale/gitlab.pot
View file @
cd15d0e6
...
@@ -11641,7 +11641,7 @@ msgstr ""
...
@@ -11641,7 +11641,7 @@ msgstr ""
msgid "No files found."
msgid "No files found."
msgstr ""
msgstr ""
msgid "No forks available to you."
msgid "No forks a
re a
vailable to you."
msgstr ""
msgstr ""
msgid "No issues for the selected time period."
msgid "No issues for the selected time period."
...
@@ -18447,7 +18447,7 @@ msgstr ""
...
@@ -18447,7 +18447,7 @@ msgstr ""
msgid "To preserve performance only <strong>%{display_size} of %{real_size}</strong> files are displayed."
msgid "To preserve performance only <strong>%{display_size} of %{real_size}</strong> files are displayed."
msgstr ""
msgstr ""
msgid "To protect this issue's confidentiality, %{
link_start}fork the project%{link_end} and set the fork
s visibility to private."
msgid "To protect this issue's confidentiality, %{
forkLink} and set the fork'
s visibility to private."
msgstr ""
msgstr ""
msgid "To protect this issue's confidentiality, a private fork of this project was selected."
msgid "To protect this issue's confidentiality, a private fork of this project was selected."
...
@@ -21049,6 +21049,9 @@ msgstr ""
...
@@ -21049,6 +21049,9 @@ msgstr ""
msgid "for this project"
msgid "for this project"
msgstr ""
msgstr ""
msgid "fork this project"
msgstr ""
msgid "from"
msgid "from"
msgstr ""
msgstr ""
...
...
spec/factories/error_tracking/detailed_error.rb
View file @
cd15d0e6
...
@@ -2,13 +2,13 @@
...
@@ -2,13 +2,13 @@
FactoryBot
.
define
do
FactoryBot
.
define
do
factory
:detailed_error_tracking_error
,
class:
Gitlab
::
ErrorTracking
::
DetailedError
do
factory
:detailed_error_tracking_error
,
class:
Gitlab
::
ErrorTracking
::
DetailedError
do
id
{
'
id
'
}
id
{
'
1
'
}
title
{
'title'
}
title
{
'title'
}
type
{
'error'
}
type
{
'error'
}
user_count
{
1
}
user_count
{
1
}
count
{
2
}
count
{
2
}
first_seen
{
Time
.
now
}
first_seen
{
Time
.
now
.
iso8601
}
last_seen
{
Time
.
now
}
last_seen
{
Time
.
now
.
iso8601
}
message
{
'message'
}
message
{
'message'
}
culprit
{
'culprit'
}
culprit
{
'culprit'
}
external_url
{
'http://example.com/id'
}
external_url
{
'http://example.com/id'
}
...
@@ -18,7 +18,11 @@ FactoryBot.define do
...
@@ -18,7 +18,11 @@ FactoryBot.define do
project_slug
{
'project_name'
}
project_slug
{
'project_name'
}
short_id
{
'ID'
}
short_id
{
'ID'
}
status
{
'unresolved'
}
status
{
'unresolved'
}
frequency
{
[]
}
frequency
do
[
[
Time
.
now
.
to_i
,
10
]
]
end
first_release_last_commit
{
'68c914da9'
}
first_release_last_commit
{
'68c914da9'
}
last_release_last_commit
{
'9ad419c86'
}
last_release_last_commit
{
'9ad419c86'
}
first_release_short_version
{
'abc123'
}
first_release_short_version
{
'abc123'
}
...
...
spec/features/issues/user_creates_confidential_merge_request_spec.rb
View file @
cd15d0e6
...
@@ -29,7 +29,7 @@ describe 'User creates confidential merge request on issue page', :js do
...
@@ -29,7 +29,7 @@ describe 'User creates confidential merge request on issue page', :js do
click_button
'Create confidential merge request'
click_button
'Create confidential merge request'
page
.
within
'.create-confidential-merge-request-dropdown-menu'
do
page
.
within
'.create-confidential-merge-request-dropdown-menu'
do
expect
(
page
).
to
have_content
(
'No forks available to you'
)
expect
(
page
).
to
have_content
(
'No forks a
re a
vailable to you'
)
end
end
end
end
end
end
...
...
spec/frontend/confidential_merge_request/components/__snapshots__/project_form_group_spec.js.snap
View file @
cd15d0e6
...
@@ -15,19 +15,12 @@ exports[`Confidential merge request project form group component renders empty s
...
@@ -15,19 +15,12 @@ exports[`Confidential merge request project form group component renders empty s
class="text-muted mt-1 mb-0"
class="text-muted mt-1 mb-0"
>
>
No forks available to you.
No forks a
re a
vailable to you.
<br />
<br />
<span>
<glsprintf-stub
To protect this issue's confidentiality,
message="To protect this issue's confidentiality, %{forkLink} and set the fork's visibility to private."
<a
/>
class="help-link"
href="https://test.com"
>
fork the project
</a>
and set the forks visibility to private.
</span>
<gllink-stub
<gllink-stub
class="w-auto p-0 d-inline-block text-primary bg-transparent"
class="w-auto p-0 d-inline-block text-primary bg-transparent"
...
@@ -65,19 +58,12 @@ exports[`Confidential merge request project form group component renders fork dr
...
@@ -65,19 +58,12 @@ exports[`Confidential merge request project form group component renders fork dr
class="text-muted mt-1 mb-0"
class="text-muted mt-1 mb-0"
>
>
No forks available to you.
No forks a
re a
vailable to you.
<br />
<br />
<span>
<glsprintf-stub
To protect this issue's confidentiality,
message="To protect this issue's confidentiality, %{forkLink} and set the fork's visibility to private."
<a
/>
class="help-link"
href="https://test.com"
>
fork the project
</a>
and set the forks visibility to private.
</span>
<gllink-stub
<gllink-stub
class="w-auto p-0 d-inline-block text-primary bg-transparent"
class="w-auto p-0 d-inline-block text-primary bg-transparent"
...
...
spec/graphql/resolvers/error_tracking/sentry_detailed_error_resolver_spec.rb
0 → 100644
View file @
cd15d0e6
# frozen_string_literal: true
require
'spec_helper'
describe
Resolvers
::
ErrorTracking
::
SentryDetailedErrorResolver
do
include
GraphqlHelpers
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:current_user
)
{
create
(
:user
)
}
let
(
:issue_details_service
)
{
spy
(
'ErrorTracking::IssueDetailsService'
)
}
before
do
project
.
add_developer
(
current_user
)
allow
(
ErrorTracking
::
IssueDetailsService
)
.
to
receive
(
:new
)
.
and_return
issue_details_service
end
describe
'#resolve'
do
let
(
:args
)
{
{
id:
issue_global_id
(
1234
)
}
}
it
'fetches the data via the sentry API'
do
resolve_error
(
args
)
expect
(
issue_details_service
).
to
have_received
(
:execute
)
end
context
'error matched'
do
let
(
:detailed_error
)
{
build
(
:detailed_error_tracking_error
)
}
before
do
allow
(
issue_details_service
).
to
receive
(
:execute
)
.
and_return
({
issue:
detailed_error
})
end
it
'resolves to a detailed error'
do
expect
(
resolve_error
(
args
)).
to
eq
detailed_error
end
it
'assigns the gitlab project'
do
expect
(
resolve_error
(
args
).
gitlab_project
).
to
eq
project
end
end
it
'resolves to nil if no match'
do
allow
(
issue_details_service
).
to
receive
(
:execute
)
.
and_return
({
issue:
nil
})
result
=
resolve_error
(
args
)
expect
(
result
).
to
eq
nil
end
end
def
resolve_error
(
args
=
{},
context
=
{
current_user:
current_user
})
resolve
(
described_class
,
obj:
project
,
args:
args
,
ctx:
context
)
end
def
issue_global_id
(
issue_id
)
Gitlab
::
ErrorTracking
::
DetailedError
.
new
(
id:
issue_id
).
to_global_id
.
to_s
end
end
spec/graphql/types/error_tracking/sentry_detailed_error_type_spec.rb
0 → 100644
View file @
cd15d0e6
# frozen_string_literal: true
require
'spec_helper'
describe
GitlabSchema
.
types
[
'SentryDetailedError'
]
do
it
{
expect
(
described_class
.
graphql_name
).
to
eq
(
'SentryDetailedError'
)
}
it
{
expect
(
described_class
).
to
require_graphql_authorizations
(
:read_sentry_issue
)
}
it
'exposes the expected fields'
do
expected_fields
=
%i[
id
sentryId
title
type
userCount
count
firstSeen
lastSeen
message
culprit
externalUrl
sentryProjectId
sentryProjectName
sentryProjectSlug
shortId
status
frequency
firstReleaseLastCommit
lastReleaseLastCommit
firstReleaseShortVersion
lastReleaseShortVersion
]
is_expected
.
to
have_graphql_fields
(
*
expected_fields
)
end
end
spec/graphql/types/project_type_spec.rb
View file @
cd15d0e6
...
@@ -22,8 +22,7 @@ describe GitlabSchema.types['Project'] do
...
@@ -22,8 +22,7 @@ describe GitlabSchema.types['Project'] do
only_allow_merge_if_pipeline_succeeds request_access_enabled
only_allow_merge_if_pipeline_succeeds request_access_enabled
only_allow_merge_if_all_discussions_are_resolved printing_merge_request_link_enabled
only_allow_merge_if_all_discussions_are_resolved printing_merge_request_link_enabled
namespace group statistics repository merge_requests merge_request issues
namespace group statistics repository merge_requests merge_request issues
issue pipelines
issue pipelines removeSourceBranchAfterMerge sentryDetailedError
removeSourceBranchAfterMerge
]
]
is_expected
.
to
have_graphql_fields
(
*
expected_fields
)
is_expected
.
to
have_graphql_fields
(
*
expected_fields
)
...
...
spec/javascripts/vue_shared/components/bar_chart_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
BarChart
from
'
~/vue_shared/components/bar_chart.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
BarChart
from
'
~/vue_shared/components/bar_chart.vue
'
;
function
getRandomArbitrary
(
min
,
max
)
{
function
getRandomArbitrary
(
min
,
max
)
{
return
Math
.
random
()
*
(
max
-
min
)
+
min
;
return
Math
.
random
()
*
(
max
-
min
)
+
min
;
...
...
spec/javascripts/vue_shared/components/ci_badge_link_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
ciBadge
from
'
~/vue_shared/components/ci_badge_link.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
ciBadge
from
'
~/vue_shared/components/ci_badge_link.vue
'
;
describe
(
'
CI Badge Link Component
'
,
()
=>
{
describe
(
'
CI Badge Link Component
'
,
()
=>
{
let
CIBadge
;
let
CIBadge
;
...
...
spec/javascripts/vue_shared/components/ci_icon_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
ciIcon
from
'
~/vue_shared/components/ci_icon.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
ciIcon
from
'
~/vue_shared/components/ci_icon.vue
'
;
describe
(
'
CI Icon component
'
,
()
=>
{
describe
(
'
CI Icon component
'
,
()
=>
{
const
Component
=
Vue
.
extend
(
ciIcon
);
const
Component
=
Vue
.
extend
(
ciIcon
);
...
...
spec/javascripts/vue_shared/components/content_viewer/content_viewer_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
contentViewer
from
'
~/vue_shared/components/content_viewer/content_viewer.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
{
GREEN_BOX_IMAGE_URL
}
from
'
spec/test_constants
'
;
import
{
GREEN_BOX_IMAGE_URL
}
from
'
spec/test_constants
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
contentViewer
from
'
~/vue_shared/components/content_viewer/content_viewer.vue
'
;
import
'
~/behaviors/markdown/render_gfm
'
;
import
'
~/behaviors/markdown/render_gfm
'
;
describe
(
'
ContentViewer
'
,
()
=>
{
describe
(
'
ContentViewer
'
,
()
=>
{
...
...
spec/javascripts/vue_shared/components/deprecated_modal_2_spec.js
View file @
cd15d0e6
import
$
from
'
jquery
'
;
import
$
from
'
jquery
'
;
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
DeprecatedModal2
from
'
~/vue_shared/components/deprecated_modal_2.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
DeprecatedModal2
from
'
~/vue_shared/components/deprecated_modal_2.vue
'
;
const
modalComponent
=
Vue
.
extend
(
DeprecatedModal2
);
const
modalComponent
=
Vue
.
extend
(
DeprecatedModal2
);
...
...
spec/javascripts/vue_shared/components/deprecated_modal_spec.js
View file @
cd15d0e6
import
$
from
'
jquery
'
;
import
$
from
'
jquery
'
;
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
DeprecatedModal
from
'
~/vue_shared/components/deprecated_modal.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
DeprecatedModal
from
'
~/vue_shared/components/deprecated_modal.vue
'
;
const
modalComponent
=
Vue
.
extend
(
DeprecatedModal
);
const
modalComponent
=
Vue
.
extend
(
DeprecatedModal
);
...
...
spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
diffViewer
from
'
~/vue_shared/components/diff_viewer/diff_viewer.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
{
GREEN_BOX_IMAGE_URL
,
RED_BOX_IMAGE_URL
}
from
'
spec/test_constants
'
;
import
{
GREEN_BOX_IMAGE_URL
,
RED_BOX_IMAGE_URL
}
from
'
spec/test_constants
'
;
import
diffViewer
from
'
~/vue_shared/components/diff_viewer/diff_viewer.vue
'
;
describe
(
'
DiffViewer
'
,
()
=>
{
describe
(
'
DiffViewer
'
,
()
=>
{
const
requiredProps
=
{
const
requiredProps
=
{
...
...
spec/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
imageDiffViewer
from
'
~/vue_shared/components/diff_viewer/viewers/image_diff_viewer.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
{
GREEN_BOX_IMAGE_URL
,
RED_BOX_IMAGE_URL
}
from
'
spec/test_constants
'
;
import
{
GREEN_BOX_IMAGE_URL
,
RED_BOX_IMAGE_URL
}
from
'
spec/test_constants
'
;
import
imageDiffViewer
from
'
~/vue_shared/components/diff_viewer/viewers/image_diff_viewer.vue
'
;
describe
(
'
ImageDiffViewer
'
,
()
=>
{
describe
(
'
ImageDiffViewer
'
,
()
=>
{
const
requiredProps
=
{
const
requiredProps
=
{
...
...
spec/javascripts/vue_shared/components/dropdown/dropdown_button_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
dropdownButtonComponent
from
'
~/vue_shared/components/dropdown/dropdown_button.vue
'
;
import
{
mountComponentWithSlots
}
from
'
spec/helpers/vue_mount_component_helper
'
;
import
{
mountComponentWithSlots
}
from
'
spec/helpers/vue_mount_component_helper
'
;
import
dropdownButtonComponent
from
'
~/vue_shared/components/dropdown/dropdown_button.vue
'
;
const
defaultLabel
=
'
Select
'
;
const
defaultLabel
=
'
Select
'
;
const
customLabel
=
'
Select project
'
;
const
customLabel
=
'
Select project
'
;
...
...
spec/javascripts/vue_shared/components/dropdown/dropdown_hidden_input_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
dropdownHiddenInputComponent
from
'
~/vue_shared/components/dropdown/dropdown_hidden_input.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
dropdownHiddenInputComponent
from
'
~/vue_shared/components/dropdown/dropdown_hidden_input.vue
'
;
import
{
mockLabels
}
from
'
./mock_data
'
;
import
{
mockLabels
}
from
'
./mock_data
'
;
...
...
spec/javascripts/vue_shared/components/dropdown/dropdown_search_input_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
dropdownSearchInputComponent
from
'
~/vue_shared/components/dropdown/dropdown_search_input.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
dropdownSearchInputComponent
from
'
~/vue_shared/components/dropdown/dropdown_search_input.vue
'
;
const
componentConfig
=
{
const
componentConfig
=
{
placeholderText
:
'
Search something
'
,
placeholderText
:
'
Search something
'
,
...
...
spec/javascripts/vue_shared/components/file_finder/index_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
Mousetrap
from
'
mousetrap
'
;
import
Mousetrap
from
'
mousetrap
'
;
import
FindFileComponent
from
'
~/vue_shared/components/file_finder/index.vue
'
;
import
{
UP_KEY_CODE
,
DOWN_KEY_CODE
,
ENTER_KEY_CODE
,
ESC_KEY_CODE
}
from
'
~/lib/utils/keycodes
'
;
import
{
file
}
from
'
spec/ide/helpers
'
;
import
{
file
}
from
'
spec/ide/helpers
'
;
import
timeoutPromise
from
'
spec/helpers/set_timeout_promise_helper
'
;
import
timeoutPromise
from
'
spec/helpers/set_timeout_promise_helper
'
;
import
FindFileComponent
from
'
~/vue_shared/components/file_finder/index.vue
'
;
import
{
UP_KEY_CODE
,
DOWN_KEY_CODE
,
ENTER_KEY_CODE
,
ESC_KEY_CODE
}
from
'
~/lib/utils/keycodes
'
;
describe
(
'
File finder item spec
'
,
()
=>
{
describe
(
'
File finder item spec
'
,
()
=>
{
const
Component
=
Vue
.
extend
(
FindFileComponent
);
const
Component
=
Vue
.
extend
(
FindFileComponent
);
...
...
spec/javascripts/vue_shared/components/file_finder/item_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
ItemComponent
from
'
~/vue_shared/components/file_finder/item.vue
'
;
import
{
file
}
from
'
spec/ide/helpers
'
;
import
{
file
}
from
'
spec/ide/helpers
'
;
import
ItemComponent
from
'
~/vue_shared/components/file_finder/item.vue
'
;
import
createComponent
from
'
../../../helpers/vue_mount_component_helper
'
;
import
createComponent
from
'
../../../helpers/vue_mount_component_helper
'
;
describe
(
'
File finder item spec
'
,
()
=>
{
describe
(
'
File finder item spec
'
,
()
=>
{
...
...
spec/javascripts/vue_shared/components/file_row_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
{
file
}
from
'
spec/ide/helpers
'
;
import
FileRow
from
'
~/vue_shared/components/file_row.vue
'
;
import
FileRow
from
'
~/vue_shared/components/file_row.vue
'
;
import
FileRowExtra
from
'
~/ide/components/file_row_extra.vue
'
;
import
FileRowExtra
from
'
~/ide/components/file_row_extra.vue
'
;
import
{
file
}
from
'
spec/ide/helpers
'
;
import
mountComponent
from
'
../../helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
../../helpers/vue_mount_component_helper
'
;
describe
(
'
File row component
'
,
()
=>
{
describe
(
'
File row component
'
,
()
=>
{
...
...
spec/javascripts/vue_shared/components/filtered_search_dropdown_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
component
from
'
~/vue_shared/components/filtered_search_dropdown.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
component
from
'
~/vue_shared/components/filtered_search_dropdown.vue
'
;
describe
(
'
Filtered search dropdown
'
,
()
=>
{
describe
(
'
Filtered search dropdown
'
,
()
=>
{
const
Component
=
Vue
.
extend
(
component
);
const
Component
=
Vue
.
extend
(
component
);
...
...
spec/javascripts/vue_shared/components/header_ci_component_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
headerCi
from
'
~/vue_shared/components/header_ci_component.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
headerCi
from
'
~/vue_shared/components/header_ci_component.vue
'
;
describe
(
'
Header CI Component
'
,
()
=>
{
describe
(
'
Header CI Component
'
,
()
=>
{
let
HeaderCi
;
let
HeaderCi
;
...
...
spec/javascripts/vue_shared/components/icon_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
describe
(
'
Sprite Icon Component
'
,
function
()
{
describe
(
'
Sprite Icon Component
'
,
function
()
{
describe
(
'
Initialization
'
,
function
()
{
describe
(
'
Initialization
'
,
function
()
{
...
...
spec/javascripts/vue_shared/components/loading_button_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
loadingButton
from
'
~/vue_shared/components/loading_button.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
loadingButton
from
'
~/vue_shared/components/loading_button.vue
'
;
const
LABEL
=
'
Hello
'
;
const
LABEL
=
'
Hello
'
;
...
...
spec/javascripts/vue_shared/components/markdown/toolbar_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
toolbar
from
'
~/vue_shared/components/markdown/toolbar.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
toolbar
from
'
~/vue_shared/components/markdown/toolbar.vue
'
;
describe
(
'
toolbar
'
,
()
=>
{
describe
(
'
toolbar
'
,
()
=>
{
let
vm
;
let
vm
;
...
...
spec/javascripts/vue_shared/components/navigation_tabs_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
navigationTabs
from
'
~/vue_shared/components/navigation_tabs.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
navigationTabs
from
'
~/vue_shared/components/navigation_tabs.vue
'
;
describe
(
'
navigation tabs component
'
,
()
=>
{
describe
(
'
navigation tabs component
'
,
()
=>
{
let
vm
;
let
vm
;
...
...
spec/javascripts/vue_shared/components/panel_resizer_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
panelResizer
from
'
~/vue_shared/components/panel_resizer.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
panelResizer
from
'
~/vue_shared/components/panel_resizer.vue
'
;
describe
(
'
Panel Resizer component
'
,
()
=>
{
describe
(
'
Panel Resizer component
'
,
()
=>
{
let
vm
;
let
vm
;
...
...
spec/javascripts/vue_shared/components/pikaday_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
datePicker
from
'
~/vue_shared/components/pikaday.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
datePicker
from
'
~/vue_shared/components/pikaday.vue
'
;
describe
(
'
datePicker
'
,
()
=>
{
describe
(
'
datePicker
'
,
()
=>
{
let
vm
;
let
vm
;
...
...
spec/javascripts/vue_shared/components/project_avatar/default_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
ProjectAvatarDefault
from
'
~/vue_shared/components/project_avatar/default.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
{
projectData
}
from
'
spec/ide/mock_data
'
;
import
{
projectData
}
from
'
spec/ide/mock_data
'
;
import
{
getFirstCharacterCapitalized
}
from
'
~/lib/utils/text_utility
'
;
import
{
TEST_HOST
}
from
'
spec/test_constants
'
;
import
{
TEST_HOST
}
from
'
spec/test_constants
'
;
import
{
getFirstCharacterCapitalized
}
from
'
~/lib/utils/text_utility
'
;
import
ProjectAvatarDefault
from
'
~/vue_shared/components/project_avatar/default.vue
'
;
describe
(
'
ProjectAvatarDefault component
'
,
()
=>
{
describe
(
'
ProjectAvatarDefault component
'
,
()
=>
{
const
Component
=
Vue
.
extend
(
ProjectAvatarDefault
);
const
Component
=
Vue
.
extend
(
ProjectAvatarDefault
);
...
...
spec/javascripts/vue_shared/components/project_selector/project_list_item_spec.js
View file @
cd15d0e6
import
ProjectListItem
from
'
~/vue_shared/components/project_selector/project_list_item.vue
'
;
import
{
shallowMount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
{
shallowMount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
{
trimText
}
from
'
spec/helpers/text_helper
'
;
import
{
trimText
}
from
'
spec/helpers/text_helper
'
;
import
ProjectListItem
from
'
~/vue_shared/components/project_selector/project_list_item.vue
'
;
const
localVue
=
createLocalVue
();
const
localVue
=
createLocalVue
();
...
...
spec/javascripts/vue_shared/components/project_selector/project_selector_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
_
from
'
underscore
'
;
import
_
from
'
underscore
'
;
import
ProjectSelector
from
'
~/vue_shared/components/project_selector/project_selector.vue
'
;
import
ProjectListItem
from
'
~/vue_shared/components/project_selector/project_list_item.vue
'
;
import
{
GlSearchBoxByType
,
GlInfiniteScroll
}
from
'
@gitlab/ui
'
;
import
{
GlSearchBoxByType
,
GlInfiniteScroll
}
from
'
@gitlab/ui
'
;
import
{
mount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
{
mount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
{
trimText
}
from
'
spec/helpers/text_helper
'
;
import
{
trimText
}
from
'
spec/helpers/text_helper
'
;
import
ProjectListItem
from
'
~/vue_shared/components/project_selector/project_list_item.vue
'
;
import
ProjectSelector
from
'
~/vue_shared/components/project_selector/project_selector.vue
'
;
const
localVue
=
createLocalVue
();
const
localVue
=
createLocalVue
();
...
...
spec/javascripts/vue_shared/components/smart_virtual_list_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
SmartVirtualScrollList
from
'
~/vue_shared/components/smart_virtual_list.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
SmartVirtualScrollList
from
'
~/vue_shared/components/smart_virtual_list.vue
'
;
describe
(
'
Toggle Button
'
,
()
=>
{
describe
(
'
Toggle Button
'
,
()
=>
{
let
vm
;
let
vm
;
...
...
spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
stackedProgressBarComponent
from
'
~/vue_shared/components/stacked_progress_bar.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
stackedProgressBarComponent
from
'
~/vue_shared/components/stacked_progress_bar.vue
'
;
const
createComponent
=
config
=>
{
const
createComponent
=
config
=>
{
const
Component
=
Vue
.
extend
(
stackedProgressBarComponent
);
const
Component
=
Vue
.
extend
(
stackedProgressBarComponent
);
...
...
spec/javascripts/vue_shared/components/toggle_button_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
toggleButton
from
'
~/vue_shared/components/toggle_button.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
toggleButton
from
'
~/vue_shared/components/toggle_button.vue
'
;
describe
(
'
Toggle Button
'
,
()
=>
{
describe
(
'
Toggle Button
'
,
()
=>
{
let
vm
;
let
vm
;
...
...
spec/javascripts/vue_shared/components/user_avatar/user_avatar_svg_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
UserAvatarSvg
from
'
~/vue_shared/components/user_avatar/user_avatar_svg.vue
'
;
import
avatarSvg
from
'
icons/_icon_random.svg
'
;
import
avatarSvg
from
'
icons/_icon_random.svg
'
;
import
UserAvatarSvg
from
'
~/vue_shared/components/user_avatar/user_avatar_svg.vue
'
;
const
UserAvatarSvgComponent
=
Vue
.
extend
(
UserAvatarSvg
);
const
UserAvatarSvgComponent
=
Vue
.
extend
(
UserAvatarSvg
);
...
...
spec/javascripts/vue_shared/translate_spec.js
View file @
cd15d0e6
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
Jed
from
'
jed
'
;
import
Jed
from
'
jed
'
;
import
{
trimText
}
from
'
spec/helpers/text_helper
'
;
import
locale
from
'
~/locale
'
;
import
locale
from
'
~/locale
'
;
import
Translate
from
'
~/vue_shared/translate
'
;
import
Translate
from
'
~/vue_shared/translate
'
;
import
{
trimText
}
from
'
spec/helpers/text_helper
'
;
describe
(
'
Vue translate filter
'
,
()
=>
{
describe
(
'
Vue translate filter
'
,
()
=>
{
let
el
;
let
el
;
...
...
spec/models/concerns/issuable_spec.rb
View file @
cd15d0e6
...
@@ -3,6 +3,8 @@
...
@@ -3,6 +3,8 @@
require
'spec_helper'
require
'spec_helper'
describe
Issuable
do
describe
Issuable
do
include
ProjectForksHelper
let
(
:issuable_class
)
{
Issue
}
let
(
:issuable_class
)
{
Issue
}
let
(
:issue
)
{
create
(
:issue
,
title:
'An issue'
,
description:
'A description'
)
}
let
(
:issue
)
{
create
(
:issue
,
title:
'An issue'
,
description:
'A description'
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
...
@@ -855,6 +857,7 @@ describe Issuable do
...
@@ -855,6 +857,7 @@ describe Issuable do
describe
'release scopes'
do
describe
'release scopes'
do
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:project
)
{
create
(
:project
)
}
let
(
:forked_project
)
{
fork_project
(
project
)
}
let_it_be
(
:release_1
)
{
create
(
:release
,
tag:
'v1.0'
,
project:
project
)
}
let_it_be
(
:release_1
)
{
create
(
:release
,
tag:
'v1.0'
,
project:
project
)
}
let_it_be
(
:release_2
)
{
create
(
:release
,
tag:
'v2.0'
,
project:
project
)
}
let_it_be
(
:release_2
)
{
create
(
:release
,
tag:
'v2.0'
,
project:
project
)
}
...
@@ -875,52 +878,65 @@ describe Issuable do
...
@@ -875,52 +878,65 @@ describe Issuable do
let_it_be
(
:issue_5
)
{
create
(
:issue
,
milestone:
milestone_6
,
project:
project
)
}
let_it_be
(
:issue_5
)
{
create
(
:issue
,
milestone:
milestone_6
,
project:
project
)
}
let_it_be
(
:issue_6
)
{
create
(
:issue
,
project:
project
)
}
let_it_be
(
:issue_6
)
{
create
(
:issue
,
project:
project
)
}
let_it_be
(
:items
)
{
Issue
.
all
}
let
(
:mr_1
)
{
create
(
:merge_request
,
milestone:
milestone_1
,
target_project:
project
,
source_project:
project
)
}
let
(
:mr_2
)
{
create
(
:merge_request
,
milestone:
milestone_3
,
target_project:
project
,
source_project:
forked_project
)
}
let
(
:mr_3
)
{
create
(
:merge_request
,
source_project:
project
)
}
let_it_be
(
:issue_items
)
{
Issue
.
all
}
let
(
:mr_items
)
{
MergeRequest
.
all
}
describe
'#without_release'
do
describe
'#without_release'
do
it
'returns the issues not tied to any milestone and the ones tied to milestone with no release'
do
it
'returns the issues or mrs not tied to any milestone and the ones tied to milestone with no release'
do
expect
(
items
.
without_release
).
to
contain_exactly
(
issue_5
,
issue_6
)
expect
(
issue_items
.
without_release
).
to
contain_exactly
(
issue_5
,
issue_6
)
expect
(
mr_items
.
without_release
).
to
contain_exactly
(
mr_3
)
end
end
end
end
describe
'#any_release'
do
describe
'#any_release'
do
it
'returns all issues tied to a release'
do
it
'returns all issues or all mrs tied to a release'
do
expect
(
items
.
any_release
).
to
contain_exactly
(
issue_1
,
issue_2
,
issue_3
,
issue_4
)
expect
(
issue_items
.
any_release
).
to
contain_exactly
(
issue_1
,
issue_2
,
issue_3
,
issue_4
)
expect
(
mr_items
.
any_release
).
to
contain_exactly
(
mr_1
,
mr_2
)
end
end
end
end
describe
'#with_release'
do
describe
'#with_release'
do
it
'returns the issues tied a specfic release'
do
it
'returns the issues tied to a specfic release'
do
expect
(
items
.
with_release
(
'v1.0'
,
project
.
id
)).
to
contain_exactly
(
issue_1
,
issue_2
,
issue_3
)
expect
(
issue_items
.
with_release
(
'v1.0'
,
project
.
id
)).
to
contain_exactly
(
issue_1
,
issue_2
,
issue_3
)
end
it
'returns the mrs tied to a specific release'
do
expect
(
mr_items
.
with_release
(
'v1.0'
,
project
.
id
)).
to
contain_exactly
(
mr_1
)
end
end
context
'when a release has a milestone with one issue and another one with no issue'
do
context
'when a release has a milestone with one issue and another one with no issue'
do
it
'returns that one issue'
do
it
'returns that one issue'
do
expect
(
items
.
with_release
(
'v2.0'
,
project
.
id
)).
to
contain_exactly
(
issue_3
)
expect
(
i
ssue_i
tems
.
with_release
(
'v2.0'
,
project
.
id
)).
to
contain_exactly
(
issue_3
)
end
end
context
'when the milestone with no issue is added as a filter'
do
context
'when the milestone with no issue is added as a filter'
do
it
'returns an empty list'
do
it
'returns an empty list'
do
expect
(
items
.
with_release
(
'v2.0'
,
project
.
id
).
with_milestone
(
'm3'
)).
to
be_empty
expect
(
i
ssue_i
tems
.
with_release
(
'v2.0'
,
project
.
id
).
with_milestone
(
'm3'
)).
to
be_empty
end
end
end
end
context
'when the milestone with the issue is added as a filter'
do
context
'when the milestone with the issue is added as a filter'
do
it
'returns this issue'
do
it
'returns this issue'
do
expect
(
items
.
with_release
(
'v2.0'
,
project
.
id
).
with_milestone
(
'm2'
)).
to
contain_exactly
(
issue_3
)
expect
(
i
ssue_i
tems
.
with_release
(
'v2.0'
,
project
.
id
).
with_milestone
(
'm2'
)).
to
contain_exactly
(
issue_3
)
end
end
end
end
end
end
context
'when there is no issue under a specific release'
do
context
'when there is no issue or mr under a specific release'
do
it
'returns no issue'
do
it
'returns no issue or no mr'
do
expect
(
items
.
with_release
(
'v4.0'
,
project
.
id
)).
to
be_empty
expect
(
issue_items
.
with_release
(
'v4.0'
,
project
.
id
)).
to
be_empty
expect
(
mr_items
.
with_release
(
'v4.0'
,
project
.
id
)).
to
be_empty
end
end
end
end
context
'when a non-existent release tag is passed in'
do
context
'when a non-existent release tag is passed in'
do
it
'returns no issue'
do
it
'returns no issue or no mr'
do
expect
(
items
.
with_release
(
'v999.0'
,
project
.
id
)).
to
be_empty
expect
(
issue_items
.
with_release
(
'v999.0'
,
project
.
id
)).
to
be_empty
expect
(
mr_items
.
with_release
(
'v999.0'
,
project
.
id
)).
to
be_empty
end
end
end
end
end
end
...
...
spec/presenters/sentry_detailed_error_presenter_spec.rb
0 → 100644
View file @
cd15d0e6
# frozen_string_literal: true
require
'spec_helper'
describe
SentryDetailedErrorPresenter
do
let
(
:error
)
{
build
(
:detailed_error_tracking_error
)
}
let
(
:presenter
)
{
described_class
.
new
(
error
)
}
describe
'#frequency'
do
subject
{
presenter
.
frequency
}
it
'returns an array of frequency structs'
do
expect
(
subject
).
to
include
(
a_kind_of
(
SentryDetailedErrorPresenter
::
FrequencyStruct
))
end
it
'converts the times into UTC time objects'
do
time
=
subject
.
first
.
time
expect
(
time
).
to
be_a
(
Time
)
expect
(
time
.
strftime
(
'%z'
)).
to
eq
'+0000'
end
it
'returns the correct counts'
do
count
=
subject
.
first
.
count
expect
(
count
).
to
eq
error
.
frequency
.
first
[
1
]
end
end
end
spec/requests/api/graphql/project/error_tracking/sentry_detailed_error_request_spec.rb
0 → 100644
View file @
cd15d0e6
# frozen_string_literal: true
require
'spec_helper'
describe
'getting a detailed sentry error'
do
include
GraphqlHelpers
let_it_be
(
:project
)
{
create
(
:project
,
:repository
)
}
let_it_be
(
:project_setting
)
{
create
(
:project_error_tracking_setting
,
project:
project
)
}
let_it_be
(
:current_user
)
{
project
.
owner
}
let_it_be
(
:sentry_detailed_error
)
{
build
(
:detailed_error_tracking_error
)
}
let
(
:sentry_gid
)
{
sentry_detailed_error
.
to_global_id
.
to_s
}
let
(
:fields
)
do
<<~
QUERY
#{
all_graphql_fields_for
(
'SentryDetailedError'
.
classify
)
}
QUERY
end
let
(
:query
)
do
graphql_query_for
(
'project'
,
{
'fullPath'
=>
project
.
full_path
},
query_graphql_field
(
'sentryDetailedError'
,
{
id:
sentry_gid
},
fields
)
)
end
let
(
:error_data
)
{
graphql_data
[
'project'
][
'sentryDetailedError'
]
}
it_behaves_like
'a working graphql query'
do
before
do
post_graphql
(
query
,
current_user:
current_user
)
end
end
context
'when data is loading via reactive cache'
do
before
do
post_graphql
(
query
,
current_user:
current_user
)
end
it
"is expected to return an empty error"
do
expect
(
error_data
).
to
eq
nil
end
end
context
'reactive cache returns data'
do
before
do
expect_any_instance_of
(
ErrorTracking
::
ProjectErrorTrackingSetting
)
.
to
receive
(
:issue_details
)
.
and_return
({
issue:
sentry_detailed_error
})
post_graphql
(
query
,
current_user:
current_user
)
end
it
"is expected to return a valid error"
do
expect
(
error_data
[
'id'
]).
to
eql
sentry_gid
expect
(
error_data
[
'sentryId'
]).
to
eql
sentry_detailed_error
.
id
.
to_s
expect
(
error_data
[
'status'
]).
to
eql
sentry_detailed_error
.
status
.
upcase
expect
(
error_data
[
'firstSeen'
]).
to
eql
sentry_detailed_error
.
first_seen
expect
(
error_data
[
'lastSeen'
]).
to
eql
sentry_detailed_error
.
last_seen
end
it
'is expected to return the frequency correctly'
do
expect
(
error_data
[
'frequency'
].
count
).
to
eql
sentry_detailed_error
.
frequency
.
count
first_frequency
=
error_data
[
'frequency'
].
first
expect
(
Time
.
parse
(
first_frequency
[
'time'
])).
to
eql
Time
.
at
(
sentry_detailed_error
.
frequency
[
0
][
0
],
in:
0
)
expect
(
first_frequency
[
'count'
]).
to
eql
sentry_detailed_error
.
frequency
[
0
][
1
]
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