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
a2358aaf
Commit
a2358aaf
authored
Nov 21, 2019
by
Francisco Javier López
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add Snippet GraphQL resolver API
Added resolvers for project and user snippets.
parent
6c1f03fe
Changes
33
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
33 changed files
with
2449 additions
and
251 deletions
+2449
-251
app/graphql/resolvers/concerns/resolves_snippets.rb
app/graphql/resolvers/concerns/resolves_snippets.rb
+57
-0
app/graphql/resolvers/projects/snippets_resolver.rb
app/graphql/resolvers/projects/snippets_resolver.rb
+23
-0
app/graphql/resolvers/snippets_resolver.rb
app/graphql/resolvers/snippets_resolver.rb
+45
-0
app/graphql/resolvers/users/snippets_resolver.rb
app/graphql/resolvers/users/snippets_resolver.rb
+21
-0
app/graphql/types/notes/noteable_type.rb
app/graphql/types/notes/noteable_type.rb
+2
-0
app/graphql/types/permission_types/project.rb
app/graphql/types/permission_types/project.rb
+7
-1
app/graphql/types/permission_types/snippet.rb
app/graphql/types/permission_types/snippet.rb
+15
-0
app/graphql/types/permission_types/user.rb
app/graphql/types/permission_types/user.rb
+15
-0
app/graphql/types/project_type.rb
app/graphql/types/project_type.rb
+6
-0
app/graphql/types/query_type.rb
app/graphql/types/query_type.rb
+6
-0
app/graphql/types/snippet_type.rb
app/graphql/types/snippet_type.rb
+69
-0
app/graphql/types/snippets/type_enum.rb
app/graphql/types/snippets/type_enum.rb
+10
-0
app/graphql/types/snippets/visibility_scopes_enum.rb
app/graphql/types/snippets/visibility_scopes_enum.rb
+11
-0
app/graphql/types/user_type.rb
app/graphql/types/user_type.rb
+8
-0
app/policies/personal_snippet_policy.rb
app/policies/personal_snippet_policy.rb
+3
-0
app/policies/project_snippet_policy.rb
app/policies/project_snippet_policy.rb
+3
-0
app/presenters/snippet_presenter.rb
app/presenters/snippet_presenter.rb
+35
-0
changelogs/unreleased/fj-36079-snippet-graphql-endpoints.yml
changelogs/unreleased/fj-36079-snippet-graphql-endpoints.yml
+5
-0
doc/api/graphql/index.md
doc/api/graphql/index.md
+1
-0
doc/api/graphql/reference/gitlab_schema.graphql
doc/api/graphql/reference/gitlab_schema.graphql
+342
-2
doc/api/graphql/reference/gitlab_schema.json
doc/api/graphql/reference/gitlab_schema.json
+1225
-244
doc/api/graphql/reference/index.md
doc/api/graphql/reference/index.md
+37
-1
spec/graphql/resolvers/projects/snippets_resolver_spec.rb
spec/graphql/resolvers/projects/snippets_resolver_spec.rb
+83
-0
spec/graphql/resolvers/snippets_resolver_spec.rb
spec/graphql/resolvers/snippets_resolver_spec.rb
+128
-0
spec/graphql/resolvers/users/snippets_resolver_spec.rb
spec/graphql/resolvers/users/snippets_resolver_spec.rb
+84
-0
spec/graphql/types/permission_types/project_spec.rb
spec/graphql/types/permission_types/project_spec.rb
+1
-1
spec/graphql/types/permission_types/snippet_spec.rb
spec/graphql/types/permission_types/snippet_spec.rb
+15
-0
spec/graphql/types/permission_types/user_spec.rb
spec/graphql/types/permission_types/user_spec.rb
+15
-0
spec/graphql/types/project_type_spec.rb
spec/graphql/types/project_type_spec.rb
+10
-1
spec/graphql/types/query_type_spec.rb
spec/graphql/types/query_type_spec.rb
+1
-1
spec/graphql/types/snippet_type_spec.rb
spec/graphql/types/snippet_type_spec.rb
+19
-0
spec/graphql/types/user_type_spec.rb
spec/graphql/types/user_type_spec.rb
+17
-0
spec/presenters/snippet_presenter_spec.rb
spec/presenters/snippet_presenter_spec.rb
+130
-0
No files found.
app/graphql/resolvers/concerns/resolves_snippets.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
module
ResolvesSnippets
extend
ActiveSupport
::
Concern
included
do
type
Types
::
SnippetType
,
null:
false
argument
:ids
,
[
GraphQL
::
ID_TYPE
],
required:
false
,
description:
'Array of global snippet ids, e.g., "gid://gitlab/ProjectSnippet/1"'
argument
:visibility
,
Types
::
Snippets
::
VisibilityScopesEnum
,
required:
false
,
description:
'The visibility of the snippet'
end
def
resolve
(
**
args
)
resolve_snippets
(
args
)
end
private
def
resolve_snippets
(
args
)
SnippetsFinder
.
new
(
context
[
:current_user
],
snippet_finder_params
(
args
)).
execute
end
def
snippet_finder_params
(
args
)
{
ids:
resolve_ids
(
args
[
:ids
]),
scope:
args
[
:visibility
]
}.
merge
(
options_by_type
(
args
[
:type
]))
end
def
resolve_ids
(
ids
)
Array
.
wrap
(
ids
).
map
{
|
id
|
resolve_gid
(
id
,
:id
)
}
end
def
resolve_gid
(
gid
,
argument
)
return
unless
gid
.
present?
GlobalID
.
parse
(
gid
)
&
.
model_id
.
tap
do
|
id
|
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
"Invalid global id format for param
#{
argument
}
"
if
id
.
nil?
end
end
def
options_by_type
(
type
)
case
type
when
'personal'
{
only_personal:
true
}
when
'project'
{
only_project:
true
}
else
{}
end
end
end
app/graphql/resolvers/projects/snippets_resolver.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
module
Resolvers
module
Projects
class
SnippetsResolver
<
BaseResolver
include
ResolvesSnippets
alias_method
:project
,
:object
def
resolve
(
**
args
)
return
Snippet
.
none
if
project
.
nil?
super
end
private
def
snippet_finder_params
(
args
)
super
.
merge
(
project:
project
)
end
end
end
end
app/graphql/resolvers/snippets_resolver.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
module
Resolvers
class
SnippetsResolver
<
BaseResolver
include
ResolvesSnippets
ERROR_MESSAGE
=
'Filtering by both an author and a project is not supported'
alias_method
:user
,
:object
argument
:author_id
,
GraphQL
::
ID_TYPE
,
required:
false
,
description:
'The ID of an author'
argument
:project_id
,
GraphQL
::
ID_TYPE
,
required:
false
,
description:
'The ID of a project'
argument
:type
,
Types
::
Snippets
::
TypeEnum
,
required:
false
,
description:
'The type of snippet'
argument
:explore
,
GraphQL
::
BOOLEAN_TYPE
,
required:
false
,
description:
'Explore personal snippets'
def
resolve
(
**
args
)
if
args
[
:author_id
].
present?
&&
args
[
:project_id
].
present?
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
ERROR_MESSAGE
end
super
end
private
def
snippet_finder_params
(
args
)
super
.
merge
(
author:
resolve_gid
(
args
[
:author_id
],
:author
),
project:
resolve_gid
(
args
[
:project_id
],
:project
),
explore:
args
[
:explore
])
end
end
end
app/graphql/resolvers/users/snippets_resolver.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
module
Resolvers
module
Users
class
SnippetsResolver
<
BaseResolver
include
ResolvesSnippets
alias_method
:user
,
:object
argument
:type
,
Types
::
Snippets
::
TypeEnum
,
required:
false
,
description:
'The type of snippet'
private
def
snippet_finder_params
(
args
)
super
.
merge
(
author:
user
)
end
end
end
end
app/graphql/types/notes/noteable_type.rb
View file @
a2358aaf
...
...
@@ -15,6 +15,8 @@ module Types
Types
::
IssueType
when
MergeRequest
Types
::
MergeRequestType
when
Snippet
Types
::
SnippetType
else
raise
"Unknown GraphQL type for
#{
object
}
"
end
...
...
app/graphql/types/permission_types/project.rb
View file @
a2358aaf
...
...
@@ -10,13 +10,19 @@ module Types
:remove_pages
,
:read_project
,
:create_merge_request_in
,
:read_wiki
,
:read_project_member
,
:create_issue
,
:upload_file
,
:read_cycle_analytics
,
:download_code
,
:download_wiki_code
,
:fork_project
,
:
create_project_snippet
,
:
read_commit_status
,
:fork_project
,
:read_commit_status
,
:request_access
,
:create_pipeline
,
:create_pipeline_schedule
,
:create_merge_request_from
,
:create_wiki
,
:push_code
,
:create_deployment
,
:push_to_delete_protected_branch
,
:admin_wiki
,
:admin_project
,
:update_pages
,
:admin_remote_mirror
,
:create_label
,
:update_wiki
,
:destroy_wiki
,
:create_pages
,
:destroy_pages
,
:read_pages_content
,
:admin_operations
permission_field
:create_snippet
def
create_snippet
Ability
.
allowed?
(
context
[
:current_user
],
:create_project_snippet
,
object
)
end
end
end
end
...
...
app/graphql/types/permission_types/snippet.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
module
Types
module
PermissionTypes
class
Snippet
<
BasePermissionType
graphql_name
'SnippetPermissions'
abilities
:create_note
,
:award_emoji
permission_field
:read_snippet
,
method: :can_read_snippet?
permission_field
:update_snippet
,
method: :can_update_snippet?
permission_field
:admin_snippet
,
method: :can_admin_snippet?
end
end
end
app/graphql/types/permission_types/user.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
module
Types
module
PermissionTypes
class
User
<
BasePermissionType
graphql_name
'UserPermissions'
permission_field
:create_snippet
def
create_snippet
Ability
.
allowed?
(
context
[
:current_user
],
:create_personal_snippet
)
end
end
end
end
app/graphql/types/project_type.rb
View file @
a2358aaf
...
...
@@ -151,5 +151,11 @@ module Types
null:
true
,
description:
'Detailed version of a Sentry error on the project'
,
resolver:
Resolvers
::
ErrorTracking
::
SentryDetailedErrorResolver
field
:snippets
,
Types
::
SnippetType
.
connection_type
,
null:
true
,
description:
'Snippets of the project'
,
resolver:
Resolvers
::
Projects
::
SnippetsResolver
end
end
app/graphql/types/query_type.rb
View file @
a2358aaf
...
...
@@ -29,6 +29,12 @@ module Types
resolver:
Resolvers
::
MetadataResolver
,
description:
'Metadata about GitLab'
field
:snippets
,
Types
::
SnippetType
.
connection_type
,
null:
true
,
resolver:
Resolvers
::
SnippetsResolver
,
description:
'Find Snippets visible to the current user'
field
:echo
,
GraphQL
::
STRING_TYPE
,
null:
false
,
resolver:
Resolvers
::
EchoResolver
# rubocop:disable Graphql/Descriptions
end
end
app/graphql/types/snippet_type.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
module
Types
class
SnippetType
<
BaseObject
graphql_name
'Snippet'
description
'Represents a snippet entry'
implements
(
Types
::
Notes
::
NoteableType
)
present_using
SnippetPresenter
authorize
:read_snippet
expose_permissions
Types
::
PermissionTypes
::
Snippet
field
:id
,
GraphQL
::
ID_TYPE
,
description:
'Id of the snippet'
,
null:
false
field
:title
,
GraphQL
::
STRING_TYPE
,
description:
'Title of the snippet'
,
null:
false
field
:project
,
Types
::
ProjectType
,
description:
'The project the snippet is associated with'
,
null:
true
,
authorize: :read_project
,
resolve:
->
(
snippet
,
args
,
context
)
{
Gitlab
::
Graphql
::
Loaders
::
BatchModelLoader
.
new
(
Project
,
snippet
.
project_id
).
find
}
field
:author
,
Types
::
UserType
,
description:
'The owner of the snippet'
,
null:
false
,
resolve:
->
(
snippet
,
args
,
context
)
{
Gitlab
::
Graphql
::
Loaders
::
BatchModelLoader
.
new
(
User
,
snippet
.
author_id
).
find
}
field
:file_name
,
GraphQL
::
STRING_TYPE
,
description:
'File Name of the snippet'
,
null:
true
field
:content
,
GraphQL
::
STRING_TYPE
,
description:
'Content of the snippet'
,
null:
false
field
:description
,
GraphQL
::
STRING_TYPE
,
description:
'Description of the snippet'
,
null:
true
field
:visibility
,
GraphQL
::
STRING_TYPE
,
description:
'Visibility of the snippet'
,
null:
false
field
:created_at
,
Types
::
TimeType
,
description:
'Timestamp this snippet was created'
,
null:
false
field
:updated_at
,
Types
::
TimeType
,
description:
'Timestamp this snippet was updated'
,
null:
false
field
:web_url
,
type:
GraphQL
::
STRING_TYPE
,
description:
'Web URL of the snippet'
,
null:
false
field
:raw_url
,
type:
GraphQL
::
STRING_TYPE
,
description:
'Raw URL of the snippet'
,
null:
false
markdown_field
:description_html
,
null:
true
,
method: :description
end
end
app/graphql/types/snippets/type_enum.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
module
Types
module
Snippets
class
TypeEnum
<
BaseEnum
value
'personal'
,
value:
'personal'
value
'project'
,
value:
'project'
end
end
end
app/graphql/types/snippets/visibility_scopes_enum.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
module
Types
module
Snippets
class
VisibilityScopesEnum
<
BaseEnum
value
'private'
,
value:
'are_private'
value
'internal'
,
value:
'are_internal'
value
'public'
,
value:
'are_public'
end
end
end
app/graphql/types/user_type.rb
View file @
a2358aaf
...
...
@@ -8,6 +8,8 @@ module Types
present_using
UserPresenter
expose_permissions
Types
::
PermissionTypes
::
User
field
:name
,
GraphQL
::
STRING_TYPE
,
null:
false
,
description:
'Human-readable name of the user'
field
:username
,
GraphQL
::
STRING_TYPE
,
null:
false
,
...
...
@@ -19,5 +21,11 @@ module Types
field
:todos
,
Types
::
TodoType
.
connection_type
,
null:
false
,
resolver:
Resolvers
::
TodoResolver
,
description:
'Todos of the user'
field
:snippets
,
Types
::
SnippetType
.
connection_type
,
null:
true
,
description:
'Snippets authored by the user'
,
resolver:
Resolvers
::
Users
::
SnippetsResolver
end
end
app/policies/personal_snippet_policy.rb
View file @
a2358aaf
...
...
@@ -27,4 +27,7 @@ class PersonalSnippetPolicy < BasePolicy
rule
{
can?
(
:create_note
)
}.
enable
:award_emoji
rule
{
can?
(
:read_all_resources
)
}.
enable
:read_personal_snippet
# Aliasing the ability to ease GraphQL permissions check
rule
{
can?
(
:read_personal_snippet
)
}.
enable
:read_snippet
end
app/policies/project_snippet_policy.rb
View file @
a2358aaf
...
...
@@ -45,6 +45,9 @@ class ProjectSnippetPolicy < BasePolicy
end
rule
{
~
can?
(
:read_project_snippet
)
}.
prevent
:create_note
# Aliasing the ability to ease GraphQL permissions check
rule
{
can?
(
:read_project_snippet
)
}.
enable
:read_snippet
end
ProjectSnippetPolicy
.
prepend_if_ee
(
'EE::ProjectSnippetPolicy'
)
app/presenters/snippet_presenter.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
class
SnippetPresenter
<
Gitlab
::
View
::
Presenter
::
Delegated
presents
:snippet
def
web_url
Gitlab
::
UrlBuilder
.
build
(
snippet
)
end
def
raw_url
Gitlab
::
UrlBuilder
.
build
(
snippet
,
raw:
true
)
end
def
can_read_snippet?
can_access_resource?
(
"read"
)
end
def
can_update_snippet?
can_access_resource?
(
"update"
)
end
def
can_admin_snippet?
can_access_resource?
(
"admin"
)
end
private
def
can_access_resource?
(
ability_prefix
)
can?
(
current_user
,
ability_name
(
ability_prefix
),
snippet
)
end
def
ability_name
(
ability_prefix
)
"
#{
ability_prefix
}
_
#{
snippet
.
class
.
underscore
}
"
.
to_sym
end
end
changelogs/unreleased/fj-36079-snippet-graphql-endpoints.yml
0 → 100644
View file @
a2358aaf
---
title
:
Add Snippet GraphQL resolver endpoints
merge_request
:
20613
author
:
type
:
added
doc/api/graphql/index.md
View file @
a2358aaf
...
...
@@ -61,6 +61,7 @@ The GraphQL API includes the following queries at the root level:
1.
`namespace`
: Within a namespace it is also possible to fetch
`projects`
.
1.
`currentUser`
: Information about the currently logged in user.
1.
`metaData`
: Metadata about GitLab and the GraphQL API.
1.
`snippets`
: Snippets visible to the currently logged in user.
Root-level queries are defined in
[
`app/graphql/types/query_type.rb`
](
https://gitlab.com/gitlab-org/gitlab/blob/master/app/graphql/types/query_type.rb
)
.
...
...
doc/api/graphql/reference/gitlab_schema.graphql
View file @
a2358aaf
...
...
@@ -4512,6 +4512,41 @@ type Project {
"""
sharedRunnersEnabled
:
Boolean
"""
Snippets
of
the
project
"""
snippets
(
"""
Returns
the
elements
in
the
list
that
come
after
the
specified
cursor
.
"""
after
:
String
"""
Returns
the
elements
in
the
list
that
come
before
the
specified
cursor
.
"""
before
:
String
"""
Returns
the
first
_n_
elements
from
the
list
.
"""
first
:
Int
"""
Array
of
global
snippet
ids
,
e
.
g
.
,
"
gid
:
//
gitlab
/
ProjectSnippet
/1"
"""
ids
:
[
ID
!]
"""
Returns
the
last
_n_
elements
from
the
list
.
"""
last
:
Int
"""
The
visibility
of
the
snippet
"""
visibility
:
VisibilityScopesEnum
):
SnippetConnection
"""
(
deprecated
)
Does
this
project
have
snippets
enabled
?.
Use
`
snippets_access_level
`
instead
"""
...
...
@@ -4675,9 +4710,9 @@ type ProjectPermissions {
createPipelineSchedule
:
Boolean
!
"""
Whether
or
not
a
user
can
perform
`
create_
project_
snippet
`
on
this
resource
Whether
or
not
a
user
can
perform
`
create_snippet
`
on
this
resource
"""
create
Project
Snippet
:
Boolean
!
createSnippet
:
Boolean
!
"""
Whether
or
not
a
user
can
perform
`
create_wiki
`
on
this
resource
...
...
@@ -4882,6 +4917,61 @@ type Query {
"""
fullPath
:
ID
!
):
Project
"""
Find
Snippets
visible
to
the
current
user
"""
snippets
(
"""
Returns
the
elements
in
the
list
that
come
after
the
specified
cursor
.
"""
after
:
String
"""
The
ID
of
an
author
"""
authorId
:
ID
"""
Returns
the
elements
in
the
list
that
come
before
the
specified
cursor
.
"""
before
:
String
"""
Explore
personal
snippets
"""
explore
:
Boolean
"""
Returns
the
first
_n_
elements
from
the
list
.
"""
first
:
Int
"""
Array
of
global
snippet
ids
,
e
.
g
.
,
"
gid
:
//
gitlab
/
ProjectSnippet
/1"
"""
ids
:
[
ID
!]
"""
Returns
the
last
_n_
elements
from
the
list
.
"""
last
:
Int
"""
The
ID
of
a
project
"""
projectId
:
ID
"""
The
type
of
snippet
"""
type
:
TypeEnum
"""
The
visibility
of
the
snippet
"""
visibility
:
VisibilityScopesEnum
):
SnippetConnection
}
"""
...
...
@@ -5137,6 +5227,193 @@ enum SentryErrorStatus {
UNRESOLVED
}
"""
Represents a snippet entry
"""
type
Snippet
implements
Noteable
{
"""
The
owner
of
the
snippet
"""
author
:
User
!
"""
Content
of
the
snippet
"""
content
:
String
!
"""
Timestamp
this
snippet
was
created
"""
createdAt
:
Time
!
"""
Description
of
the
snippet
"""
description
:
String
"""
The
GitLab
Flavored
Markdown
rendering
of
`
description
`
"""
descriptionHtml
:
String
"""
All
discussions
on
this
noteable
"""
discussions
(
"""
Returns
the
elements
in
the
list
that
come
after
the
specified
cursor
.
"""
after
:
String
"""
Returns
the
elements
in
the
list
that
come
before
the
specified
cursor
.
"""
before
:
String
"""
Returns
the
first
_n_
elements
from
the
list
.
"""
first
:
Int
"""
Returns
the
last
_n_
elements
from
the
list
.
"""
last
:
Int
):
DiscussionConnection
!
"""
File
Name
of
the
snippet
"""
fileName
:
String
"""
Id
of
the
snippet
"""
id
:
ID
!
"""
All
notes
on
this
noteable
"""
notes
(
"""
Returns
the
elements
in
the
list
that
come
after
the
specified
cursor
.
"""
after
:
String
"""
Returns
the
elements
in
the
list
that
come
before
the
specified
cursor
.
"""
before
:
String
"""
Returns
the
first
_n_
elements
from
the
list
.
"""
first
:
Int
"""
Returns
the
last
_n_
elements
from
the
list
.
"""
last
:
Int
):
NoteConnection
!
"""
The
project
the
snippet
is
associated
with
"""
project
:
Project
"""
Raw
URL
of
the
snippet
"""
rawUrl
:
String
!
"""
Title
of
the
snippet
"""
title
:
String
!
"""
Timestamp
this
snippet
was
updated
"""
updatedAt
:
Time
!
"""
Permissions
for
the
current
user
on
the
resource
"""
userPermissions
:
SnippetPermissions
!
"""
Visibility
of
the
snippet
"""
visibility
:
String
!
"""
Web
URL
of
the
snippet
"""
webUrl
:
String
!
}
"""
The connection type for Snippet.
"""
type
SnippetConnection
{
"""
A
list
of
edges
.
"""
edges
:
[
SnippetEdge
]
"""
A
list
of
nodes
.
"""
nodes
:
[
Snippet
]
"""
Information
to
aid
in
pagination
.
"""
pageInfo
:
PageInfo
!
}
"""
An edge in a connection.
"""
type
SnippetEdge
{
"""
A
cursor
for
use
in
pagination
.
"""
cursor
:
String
!
"""
The
item
at
the
end
of
the
edge
.
"""
node
:
Snippet
}
type
SnippetPermissions
{
"""
Whether
or
not
a
user
can
perform
`
admin_snippet
`
on
this
resource
"""
adminSnippet
:
Boolean
!
"""
Whether
or
not
a
user
can
perform
`
award_emoji
`
on
this
resource
"""
awardEmoji
:
Boolean
!
"""
Whether
or
not
a
user
can
perform
`
create_note
`
on
this
resource
"""
createNote
:
Boolean
!
"""
Whether
or
not
a
user
can
perform
`
read_snippet
`
on
this
resource
"""
readSnippet
:
Boolean
!
"""
Whether
or
not
a
user
can
perform
`
update_snippet
`
on
this
resource
"""
updateSnippet
:
Boolean
!
}
type
Submodule
implements
Entry
{
flatPath
:
String
!
id
:
ID
!
...
...
@@ -5602,6 +5879,11 @@ type TreeEntryEdge {
node
:
TreeEntry
}
enum
TypeEnum
{
personal
project
}
"""
Autogenerated input type of UpdateEpic
"""
...
...
@@ -5740,6 +6022,46 @@ type User {
"""
name
:
String
!
"""
Snippets
authored
by
the
user
"""
snippets
(
"""
Returns
the
elements
in
the
list
that
come
after
the
specified
cursor
.
"""
after
:
String
"""
Returns
the
elements
in
the
list
that
come
before
the
specified
cursor
.
"""
before
:
String
"""
Returns
the
first
_n_
elements
from
the
list
.
"""
first
:
Int
"""
Array
of
global
snippet
ids
,
e
.
g
.
,
"
gid
:
//
gitlab
/
ProjectSnippet
/1"
"""
ids
:
[
ID
!]
"""
Returns
the
last
_n_
elements
from
the
list
.
"""
last
:
Int
"""
The
type
of
snippet
"""
type
:
TypeEnum
"""
The
visibility
of
the
snippet
"""
visibility
:
VisibilityScopesEnum
):
SnippetConnection
"""
Todos
of
the
user
"""
...
...
@@ -5795,6 +6117,11 @@ type User {
type
:
[
TodoTargetEnum
!]
):
TodoConnection
!
"""
Permissions
for
the
current
user
on
the
resource
"""
userPermissions
:
UserPermissions
!
"""
Username
of
the
user
.
Unique
within
this
instance
of
GitLab
"""
...
...
@@ -5839,4 +6166,17 @@ type UserEdge {
The
item
at
the
end
of
the
edge
.
"""
node
:
User
}
type
UserPermissions
{
"""
Whether
or
not
a
user
can
perform
`
create_snippet
`
on
this
resource
"""
createSnippet
:
Boolean
!
}
enum
VisibilityScopesEnum
{
internal
private
public
}
\ No newline at end of file
doc/api/graphql/reference/gitlab_schema.json
View file @
a2358aaf
This diff is collapsed.
Click to expand it.
doc/api/graphql/reference/index.md
View file @
a2358aaf
...
...
@@ -689,7 +689,6 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
|
`downloadCode`
| Boolean! | Whether or not a user can perform
`download_code`
on this resource |
|
`downloadWikiCode`
| Boolean! | Whether or not a user can perform
`download_wiki_code`
on this resource |
|
`forkProject`
| Boolean! | Whether or not a user can perform
`fork_project`
on this resource |
|
`createProjectSnippet`
| Boolean! | Whether or not a user can perform
`create_project_snippet`
on this resource |
|
`readCommitStatus`
| Boolean! | Whether or not a user can perform
`read_commit_status`
on this resource |
|
`requestAccess`
| Boolean! | Whether or not a user can perform
`request_access`
on this resource |
|
`createPipeline`
| Boolean! | Whether or not a user can perform
`create_pipeline`
on this resource |
...
...
@@ -710,6 +709,7 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
|
`destroyPages`
| Boolean! | Whether or not a user can perform
`destroy_pages`
on this resource |
|
`readPagesContent`
| Boolean! | Whether or not a user can perform
`read_pages_content`
on this resource |
|
`adminOperations`
| Boolean! | Whether or not a user can perform
`admin_operations`
on this resource |
|
`createSnippet`
| Boolean! | Whether or not a user can perform
`create_snippet`
on this resource |
|
`readDesign`
| Boolean! | Whether or not a user can perform
`read_design`
on this resource |
|
`createDesign`
| Boolean! | Whether or not a user can perform
`create_design`
on this resource |
|
`destroyDesign`
| Boolean! | Whether or not a user can perform
`destroy_design`
on this resource |
...
...
@@ -787,6 +787,35 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
|
`time`
| Time! | Time the error frequency stats were recorded |
|
`count`
| Int! | Count of errors received since the previously recorded time |
### Snippet
| Name | Type | Description |
| --- | ---- | ---------- |
|
`userPermissions`
| SnippetPermissions! | Permissions for the current user on the resource |
|
`id`
| ID! | Id of the snippet |
|
`title`
| String! | Title of the snippet |
|
`project`
| Project | The project the snippet is associated with |
|
`author`
| User! | The owner of the snippet |
|
`fileName`
| String | File Name of the snippet |
|
`content`
| String! | Content of the snippet |
|
`description`
| String | Description of the snippet |
|
`visibility`
| String! | Visibility of the snippet |
|
`createdAt`
| Time! | Timestamp this snippet was created |
|
`updatedAt`
| Time! | Timestamp this snippet was updated |
|
`webUrl`
| String! | Web URL of the snippet |
|
`rawUrl`
| String! | Raw URL of the snippet |
|
`descriptionHtml`
| String | The GitLab Flavored Markdown rendering of
`description`
|
### SnippetPermissions
| Name | Type | Description |
| --- | ---- | ---------- |
|
`createNote`
| Boolean! | Whether or not a user can perform
`create_note`
on this resource |
|
`awardEmoji`
| Boolean! | Whether or not a user can perform
`award_emoji`
on this resource |
|
`readSnippet`
| Boolean! | Whether or not a user can perform
`read_snippet`
on this resource |
|
`updateSnippet`
| Boolean! | Whether or not a user can perform
`update_snippet`
on this resource |
|
`adminSnippet`
| Boolean! | Whether or not a user can perform
`admin_snippet`
on this resource |
### Submodule
| Name | Type | Description |
...
...
@@ -892,7 +921,14 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| Name | Type | Description |
| --- | ---- | ---------- |
|
`userPermissions`
| UserPermissions! | Permissions for the current user on the resource |
|
`name`
| String! | Human-readable name of the user |
|
`username`
| String! | Username of the user. Unique within this instance of GitLab |
|
`avatarUrl`
| String! | URL of the user's avatar |
|
`webUrl`
| String! | Web URL of the user |
### UserPermissions
| Name | Type | Description |
| --- | ---- | ---------- |
|
`createSnippet`
| Boolean! | Whether or not a user can perform
`create_snippet`
on this resource |
spec/graphql/resolvers/projects/snippets_resolver_spec.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
require
'spec_helper'
describe
Resolvers
::
Projects
::
SnippetsResolver
do
include
GraphqlHelpers
describe
'#resolve'
do
let_it_be
(
:current_user
)
{
create
(
:user
)
}
let_it_be
(
:other_user
)
{
create
(
:user
)
}
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:personal_snippet
)
{
create
(
:personal_snippet
,
:private
,
author:
current_user
)
}
let_it_be
(
:project_snippet
)
{
create
(
:project_snippet
,
:internal
,
author:
current_user
,
project:
project
)
}
let_it_be
(
:other_project_snippet
)
{
create
(
:project_snippet
,
:public
,
author:
other_user
,
project:
project
)
}
before
do
project
.
add_developer
(
current_user
)
end
it
'calls SnippetsFinder'
do
expect_next_instance_of
(
SnippetsFinder
)
do
|
finder
|
expect
(
finder
).
to
receive
(
:execute
)
end
resolve_snippets
end
context
'when using no filter'
do
it
'returns expected snippets'
do
expect
(
resolve_snippets
).
to
contain_exactly
(
project_snippet
,
other_project_snippet
)
end
end
context
'when using filters'
do
it
'returns the snippets by visibility'
do
aggregate_failures
do
expect
(
resolve_snippets
(
args:
{
visibility:
'are_private'
})).
to
be_empty
expect
(
resolve_snippets
(
args:
{
visibility:
'are_internal'
})).
to
contain_exactly
(
project_snippet
)
expect
(
resolve_snippets
(
args:
{
visibility:
'are_public'
})).
to
contain_exactly
(
other_project_snippet
)
end
end
it
'returns the snippets by gid'
do
snippets
=
resolve_snippets
(
args:
{
ids:
project_snippet
.
to_global_id
})
expect
(
snippets
).
to
contain_exactly
(
project_snippet
)
end
it
'returns the snippets by array of gid'
do
args
=
{
ids:
[
project_snippet
.
to_global_id
,
other_project_snippet
.
to_global_id
]
}
snippets
=
resolve_snippets
(
args:
args
)
expect
(
snippets
).
to
contain_exactly
(
project_snippet
,
other_project_snippet
)
end
it
'returns an error if the gid is invalid'
do
expect
do
resolve_snippets
(
args:
{
ids:
'foo'
})
end
.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ArgumentError
)
end
end
context
'when no project is provided'
do
it
'returns no snippets'
do
expect
(
resolve_snippets
(
obj:
nil
)).
to
be_empty
end
end
context
'when provided user is not current user'
do
it
'returns no snippets'
do
expect
(
resolve_snippets
(
context:
{
current_user:
other_user
},
args:
{
ids:
project_snippet
.
to_global_id
})).
to
be_empty
end
end
end
def
resolve_snippets
(
args:
{},
context:
{
current_user:
current_user
},
obj:
project
)
resolve
(
described_class
,
obj:
obj
,
args:
args
,
ctx:
context
)
end
end
spec/graphql/resolvers/snippets_resolver_spec.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
require
'spec_helper'
describe
Resolvers
::
SnippetsResolver
do
include
GraphqlHelpers
describe
'#resolve'
do
let_it_be
(
:current_user
)
{
create
(
:user
)
}
let_it_be
(
:other_user
)
{
create
(
:user
)
}
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:personal_snippet
)
{
create
(
:personal_snippet
,
:private
,
author:
current_user
)
}
let_it_be
(
:other_personal_snippet
)
{
create
(
:personal_snippet
,
:internal
,
author:
other_user
)
}
let_it_be
(
:project_snippet
)
{
create
(
:project_snippet
,
:internal
,
author:
current_user
,
project:
project
)
}
let_it_be
(
:other_project_snippet
)
{
create
(
:project_snippet
,
:public
,
author:
other_user
,
project:
project
)
}
before
do
project
.
add_developer
(
current_user
)
end
it
'calls SnippetsFinder'
do
expect_next_instance_of
(
SnippetsFinder
)
do
|
finder
|
expect
(
finder
).
to
receive
(
:execute
)
end
resolve_snippets
end
context
'when using no filter'
do
it
'returns expected snippets'
do
expect
(
resolve_snippets
).
to
contain_exactly
(
personal_snippet
,
other_personal_snippet
,
project_snippet
,
other_project_snippet
)
end
end
context
'when using filters'
do
context
'by author id'
do
it
'returns the snippets'
do
snippets
=
resolve_snippets
(
args:
{
author_id:
current_user
.
to_global_id
})
expect
(
snippets
).
to
contain_exactly
(
personal_snippet
,
project_snippet
)
end
it
'returns an error if the param id is invalid'
do
expect
do
resolve_snippets
(
args:
{
author_id:
'foo'
})
end
.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ArgumentError
)
end
end
it
'returns the snippets by type'
do
aggregate_failures
do
expect
(
resolve_snippets
(
args:
{
type:
'personal'
})).
to
contain_exactly
(
personal_snippet
,
other_personal_snippet
)
expect
(
resolve_snippets
(
args:
{
type:
'project'
})).
to
contain_exactly
(
project_snippet
,
other_project_snippet
)
end
end
context
'by project id'
do
it
'returns the snippets'
do
snippets
=
resolve_snippets
(
args:
{
project_id:
project
.
to_global_id
})
expect
(
snippets
).
to
contain_exactly
(
project_snippet
,
other_project_snippet
)
end
it
'returns an error if the param id is invalid'
do
expect
do
resolve_snippets
(
args:
{
project_id:
'foo'
})
end
.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ArgumentError
)
end
end
it
'returns the snippets by visibility'
do
aggregate_failures
do
expect
(
resolve_snippets
(
args:
{
visibility:
'are_private'
})).
to
contain_exactly
(
personal_snippet
)
expect
(
resolve_snippets
(
args:
{
visibility:
'are_internal'
})).
to
contain_exactly
(
project_snippet
,
other_personal_snippet
)
expect
(
resolve_snippets
(
args:
{
visibility:
'are_public'
})).
to
contain_exactly
(
other_project_snippet
)
end
end
it
'returns snippets to explore'
do
snippets
=
resolve_snippets
(
args:
{
explore:
true
})
expect
(
snippets
).
to
contain_exactly
(
other_personal_snippet
)
end
it
'returns the snippets by single gid'
do
snippets
=
resolve_snippets
(
args:
{
ids:
personal_snippet
.
to_global_id
})
expect
(
snippets
).
to
contain_exactly
(
personal_snippet
)
end
it
'returns the snippets by array of gid'
do
args
=
{
ids:
[
personal_snippet
.
to_global_id
,
project_snippet
.
to_global_id
]
}
snippets
=
resolve_snippets
(
args:
args
)
expect
(
snippets
).
to
contain_exactly
(
personal_snippet
,
project_snippet
)
end
it
'returns an error if the gid is invalid'
do
args
=
{
ids:
[
personal_snippet
.
to_global_id
,
'foo'
]
}
expect
do
resolve_snippets
(
args:
args
)
end
.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ArgumentError
)
end
it
'returns an error if both project and author are provided'
do
expect
do
args
=
{
author_id:
current_user
.
to_global_id
,
project_id:
project
.
to_global_id
}
resolve_snippets
(
args:
args
)
end
.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ArgumentError
)
end
end
end
def
resolve_snippets
(
args:
{})
resolve
(
described_class
,
obj:
nil
,
args:
args
,
ctx:
{
current_user:
current_user
})
end
end
spec/graphql/resolvers/users/snippets_resolver_spec.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
require
'spec_helper'
describe
Resolvers
::
Users
::
SnippetsResolver
do
include
GraphqlHelpers
describe
'#resolve'
do
let_it_be
(
:current_user
)
{
create
(
:user
)
}
let_it_be
(
:other_user
)
{
create
(
:user
)
}
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:private_personal_snippet
)
{
create
(
:personal_snippet
,
:private
,
author:
current_user
)
}
let_it_be
(
:public_personal_snippet
)
{
create
(
:personal_snippet
,
:public
,
author:
current_user
)
}
let_it_be
(
:other_personal_snippet
)
{
create
(
:personal_snippet
,
:internal
,
author:
other_user
)
}
let_it_be
(
:internal_project_snippet
)
{
create
(
:project_snippet
,
:internal
,
author:
current_user
,
project:
project
)
}
let_it_be
(
:other_project_snippet
)
{
create
(
:project_snippet
,
:public
,
author:
other_user
,
project:
project
)
}
before
do
project
.
add_developer
(
current_user
)
end
it
'calls SnippetsFinder'
do
expect_next_instance_of
(
SnippetsFinder
)
do
|
finder
|
expect
(
finder
).
to
receive
(
:execute
)
end
resolve_snippets
end
context
'when using no filter'
do
it
'returns expected authored snippets'
do
expect
(
resolve_snippets
).
to
contain_exactly
(
private_personal_snippet
,
public_personal_snippet
,
internal_project_snippet
)
end
end
context
'when using filters'
do
it
'returns the snippets by visibility'
do
aggregate_failures
do
expect
(
resolve_snippets
(
args:
{
visibility:
'are_private'
})).
to
contain_exactly
(
private_personal_snippet
)
expect
(
resolve_snippets
(
args:
{
visibility:
'are_internal'
})).
to
contain_exactly
(
internal_project_snippet
)
expect
(
resolve_snippets
(
args:
{
visibility:
'are_public'
})).
to
contain_exactly
(
public_personal_snippet
)
end
end
it
'returns the snippets by type'
do
aggregate_failures
do
expect
(
resolve_snippets
(
args:
{
type:
'personal'
})).
to
contain_exactly
(
private_personal_snippet
,
public_personal_snippet
)
expect
(
resolve_snippets
(
args:
{
type:
'project'
})).
to
contain_exactly
(
internal_project_snippet
)
end
end
it
'returns the snippets by single gid'
do
snippets
=
resolve_snippets
(
args:
{
ids:
private_personal_snippet
.
to_global_id
})
expect
(
snippets
).
to
contain_exactly
(
private_personal_snippet
)
end
it
'returns the snippets by array of gid'
do
args
=
{
ids:
[
private_personal_snippet
.
to_global_id
,
public_personal_snippet
.
to_global_id
]
}
snippets
=
resolve_snippets
(
args:
args
)
expect
(
snippets
).
to
contain_exactly
(
private_personal_snippet
,
public_personal_snippet
)
end
it
'returns an error if the gid is invalid'
do
args
=
{
ids:
[
private_personal_snippet
.
to_global_id
,
'foo'
]
}
expect
do
resolve_snippets
(
args:
args
)
end
.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ArgumentError
)
end
end
end
def
resolve_snippets
(
args:
{})
resolve
(
described_class
,
args:
args
,
ctx:
{
current_user:
current_user
},
obj:
current_user
)
end
end
spec/graphql/types/permission_types/project_spec.rb
View file @
a2358aaf
...
...
@@ -8,7 +8,7 @@ describe Types::PermissionTypes::Project do
:change_namespace
,
:change_visibility_level
,
:rename_project
,
:remove_project
,
:archive_project
,
:remove_fork_project
,
:remove_pages
,
:read_project
,
:create_merge_request_in
,
:read_wiki
,
:read_project_member
,
:create_issue
,
:upload_file
,
:read_cycle_analytics
,
:download_code
,
:download_wiki_code
,
:fork_project
,
:create_
project_
snippet
,
:download_code
,
:download_wiki_code
,
:fork_project
,
:create_snippet
,
:read_commit_status
,
:request_access
,
:create_pipeline
,
:create_pipeline_schedule
,
:create_merge_request_from
,
:create_wiki
,
:push_code
,
:create_deployment
,
:push_to_delete_protected_branch
,
:admin_wiki
,
:admin_project
,
:update_pages
,
:admin_remote_mirror
,
:create_label
,
...
...
spec/graphql/types/permission_types/snippet_spec.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
require
'spec_helper'
describe
Types
::
PermissionTypes
::
Snippet
do
it
'returns the snippets permissions'
do
expected_permissions
=
[
:create_note
,
:award_emoji
,
:read_snippet
,
:update_snippet
,
:admin_snippet
]
expected_permissions
.
each
do
|
permission
|
expect
(
described_class
).
to
have_graphql_field
(
permission
)
end
end
end
spec/graphql/types/permission_types/user_spec.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
require
'spec_helper'
describe
Types
::
PermissionTypes
::
User
do
it
'returns user permissions'
do
expected_permissions
=
[
:create_snippet
]
expected_permissions
.
each
do
|
permission
|
expect
(
described_class
).
to
have_graphql_field
(
permission
)
end
end
end
spec/graphql/types/project_type_spec.rb
View file @
a2358aaf
...
...
@@ -22,7 +22,7 @@ describe GitlabSchema.types['Project'] do
only_allow_merge_if_pipeline_succeeds request_access_enabled
only_allow_merge_if_all_discussions_are_resolved printing_merge_request_link_enabled
namespace group statistics repository merge_requests merge_request issues
issue pipelines removeSourceBranchAfterMerge sentryDetailedError
issue pipelines removeSourceBranchAfterMerge sentryDetailedError
snippets
]
is_expected
.
to
have_graphql_fields
(
*
expected_fields
)
...
...
@@ -63,4 +63,13 @@ describe GitlabSchema.types['Project'] do
is_expected
.
to
have_graphql_resolver
(
Resolvers
::
MergeRequestsResolver
)
end
end
describe
'snippets field'
do
subject
{
described_class
.
fields
[
'snippets'
]
}
it
'returns snippets'
do
is_expected
.
to
have_graphql_type
(
Types
::
SnippetType
.
connection_type
)
is_expected
.
to
have_graphql_resolver
(
Resolvers
::
Projects
::
SnippetsResolver
)
end
end
end
spec/graphql/types/query_type_spec.rb
View file @
a2358aaf
...
...
@@ -7,7 +7,7 @@ describe GitlabSchema.types['Query'] do
expect
(
described_class
.
graphql_name
).
to
eq
(
'Query'
)
end
it
{
is_expected
.
to
have_graphql_fields
(
:project
,
:namespace
,
:group
,
:echo
,
:metadata
,
:current_user
)
}
it
{
is_expected
.
to
have_graphql_fields
(
:project
,
:namespace
,
:group
,
:echo
,
:metadata
,
:current_user
,
:snippets
)
}
describe
'namespace field'
do
subject
{
described_class
.
fields
[
'namespace'
]
}
...
...
spec/graphql/types/snippet_type_spec.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
require
'spec_helper'
describe
GitlabSchema
.
types
[
'Snippet'
]
do
it
'has the correct fields'
do
expected_fields
=
[
:id
,
:title
,
:project
,
:author
,
:file_name
,
:content
,
:description
,
:visibility
,
:created_at
,
:updated_at
,
:web_url
,
:raw_url
,
:notes
,
:discussions
,
:user_permissions
,
:description_html
]
is_expected
.
to
have_graphql_fields
(
*
expected_fields
)
end
describe
'authorizations'
do
it
{
expect
(
described_class
).
to
require_graphql_authorizations
(
:read_snippet
)
}
end
end
spec/graphql/types/user_type_spec.rb
View file @
a2358aaf
...
...
@@ -6,4 +6,21 @@ describe GitlabSchema.types['User'] do
it
{
expect
(
described_class
.
graphql_name
).
to
eq
(
'User'
)
}
it
{
expect
(
described_class
).
to
require_graphql_authorizations
(
:read_user
)
}
it
'has the expected fields'
do
expected_fields
=
%w[
user_permissions snippets name username avatarUrl webUrl todos
]
is_expected
.
to
have_graphql_fields
(
*
expected_fields
)
end
describe
'snippets field'
do
subject
{
described_class
.
fields
[
'snippets'
]
}
it
'returns snippets'
do
is_expected
.
to
have_graphql_type
(
Types
::
SnippetType
.
connection_type
)
is_expected
.
to
have_graphql_resolver
(
Resolvers
::
Users
::
SnippetsResolver
)
end
end
end
spec/presenters/snippet_presenter_spec.rb
0 → 100644
View file @
a2358aaf
# frozen_string_literal: true
require
'spec_helper'
describe
SnippetPresenter
do
include
Gitlab
::
Routing
.
url_helpers
let_it_be
(
:user
)
{
create
(
:user
)
}
let_it_be
(
:personal_snippet
)
{
create
(
:personal_snippet
,
author:
user
)
}
let_it_be
(
:project_snippet
)
{
create
(
:project_snippet
,
author:
user
)
}
let
(
:project
)
{
project_snippet
.
project
}
let
(
:presenter
)
{
described_class
.
new
(
snippet
,
current_user:
user
)
}
before
do
project
.
add_developer
(
user
)
end
describe
'#web_url'
do
subject
{
presenter
.
web_url
}
context
'with PersonalSnippet'
do
let
(
:snippet
)
{
personal_snippet
}
it
'returns snippet web url'
do
expect
(
subject
).
to
match
"/snippets/
#{
snippet
.
id
}
"
end
end
context
'with ProjectSnippet'
do
let
(
:snippet
)
{
project_snippet
}
it
'returns snippet web url'
do
expect
(
subject
).
to
match
"/
#{
project
.
full_path
}
/snippets/
#{
snippet
.
id
}
"
end
end
end
describe
'#raw_url'
do
subject
{
presenter
.
raw_url
}
context
'with PersonalSnippet'
do
let
(
:snippet
)
{
personal_snippet
}
it
'returns snippet web url'
do
expect
(
subject
).
to
match
"/snippets/
#{
snippet
.
id
}
/raw"
end
end
context
'with ProjectSnippet'
do
let
(
:snippet
)
{
project_snippet
}
it
'returns snippet web url'
do
expect
(
subject
).
to
match
"/
#{
project
.
full_path
}
/snippets/
#{
snippet
.
id
}
/raw"
end
end
end
describe
'#can_read_snippet?'
do
subject
{
presenter
.
can_read_snippet?
}
context
'with PersonalSnippet'
do
let
(
:snippet
)
{
personal_snippet
}
it
'checks read_personal_snippet'
do
expect
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:read_personal_snippet
,
snippet
)
subject
end
end
context
'with ProjectSnippet'
do
let
(
:snippet
)
{
project_snippet
}
it
'checks read_project_snippet '
do
expect
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:read_project_snippet
,
snippet
)
subject
end
end
end
describe
'#can_update_snippet?'
do
subject
{
presenter
.
can_update_snippet?
}
context
'with PersonalSnippet'
do
let
(
:snippet
)
{
personal_snippet
}
it
'checks update_personal_snippet'
do
expect
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:update_personal_snippet
,
snippet
)
subject
end
end
context
'with ProjectSnippet'
do
let
(
:snippet
)
{
project_snippet
}
it
'checks update_project_snippet '
do
expect
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:update_project_snippet
,
snippet
)
subject
end
end
end
describe
'#can_admin_snippet?'
do
subject
{
presenter
.
can_admin_snippet?
}
context
'with PersonalSnippet'
do
let
(
:snippet
)
{
personal_snippet
}
it
'checks admin_personal_snippet'
do
expect
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:admin_personal_snippet
,
snippet
)
subject
end
end
context
'with ProjectSnippet'
do
let
(
:snippet
)
{
project_snippet
}
it
'checks admin_project_snippet '
do
expect
(
presenter
).
to
receive
(
:can?
).
with
(
user
,
:admin_project_snippet
,
snippet
)
subject
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment