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
0b402e11
Commit
0b402e11
authored
Feb 20, 2017
by
Robert Schilling
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove deprecated `upvotes` and `downvotes` from the notes API
parent
87411889
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
723 additions
and
25 deletions
+723
-25
changelogs/unreleased/api-notes-entity-fields.yml
changelogs/unreleased/api-notes-entity-fields.yml
+4
-0
doc/api/notes.md
doc/api/notes.md
+3
-15
doc/api/projects.md
doc/api/projects.md
+0
-2
doc/api/users.md
doc/api/users.md
+0
-2
doc/api/v3_to_v4.md
doc/api/v3_to_v4.md
+1
-1
lib/api/api.rb
lib/api/api.rb
+1
-0
lib/api/entities.rb
lib/api/entities.rb
+0
-3
lib/api/v3/entities.rb
lib/api/v3/entities.rb
+34
-0
lib/api/v3/notes.rb
lib/api/v3/notes.rb
+148
-0
lib/api/v3/projects.rb
lib/api/v3/projects.rb
+2
-2
lib/api/v3/users.rb
lib/api/v3/users.rb
+21
-0
spec/requests/api/v3/notes_spec.rb
spec/requests/api/v3/notes_spec.rb
+432
-0
spec/requests/api/v3/users_spec.rb
spec/requests/api/v3/users_spec.rb
+77
-0
No files found.
changelogs/unreleased/api-notes-entity-fields.yml
0 → 100644
View file @
0b402e11
---
title
:
'
API:
Remove
deprecated
fields
Notes#upvotes
and
Notes#downvotes'
merge_request
:
9384
author
:
Robert Schilling
doc/api/notes.md
View file @
0b402e11
...
@@ -34,8 +34,6 @@ Parameters:
...
@@ -34,8 +34,6 @@ Parameters:
"created_at"
:
"2013-10-02T09:22:45Z"
,
"created_at"
:
"2013-10-02T09:22:45Z"
,
"updated_at"
:
"2013-10-02T10:22:45Z"
,
"updated_at"
:
"2013-10-02T10:22:45Z"
,
"system"
:
true
,
"system"
:
true
,
"upvote"
:
false
,
"downvote"
:
false
,
"noteable_id"
:
377
,
"noteable_id"
:
377
,
"noteable_type"
:
"Issue"
"noteable_type"
:
"Issue"
},
},
...
@@ -54,8 +52,6 @@ Parameters:
...
@@ -54,8 +52,6 @@ Parameters:
"created_at"
:
"2013-10-02T09:56:03Z"
,
"created_at"
:
"2013-10-02T09:56:03Z"
,
"updated_at"
:
"2013-10-02T09:56:03Z"
,
"updated_at"
:
"2013-10-02T09:56:03Z"
,
"system"
:
true
,
"system"
:
true
,
"upvote"
:
false
,
"downvote"
:
false
,
"noteable_id"
:
121
,
"noteable_id"
:
121
,
"noteable_type"
:
"Issue"
"noteable_type"
:
"Issue"
}
}
...
@@ -147,9 +143,7 @@ Example Response:
...
@@ -147,9 +143,7 @@ Example Response:
"created_at"
:
"2016-04-05T22:10:44.164Z"
,
"created_at"
:
"2016-04-05T22:10:44.164Z"
,
"system"
:
false
,
"system"
:
false
,
"noteable_id"
:
11
,
"noteable_id"
:
11
,
"noteable_type"
:
"Issue"
,
"noteable_type"
:
"Issue"
"upvote"
:
false
,
"downvote"
:
false
}
}
```
```
...
@@ -271,9 +265,7 @@ Example Response:
...
@@ -271,9 +265,7 @@ Example Response:
"created_at"
:
"2016-04-06T16:51:53.239Z"
,
"created_at"
:
"2016-04-06T16:51:53.239Z"
,
"system"
:
false
,
"system"
:
false
,
"noteable_id"
:
52
,
"noteable_id"
:
52
,
"noteable_type"
:
"Snippet"
,
"noteable_type"
:
"Snippet"
"upvote"
:
false
,
"downvote"
:
false
}
}
```
```
...
@@ -322,8 +314,6 @@ Parameters:
...
@@ -322,8 +314,6 @@ Parameters:
"created_at"
:
"2013-10-02T08:57:14Z"
,
"created_at"
:
"2013-10-02T08:57:14Z"
,
"updated_at"
:
"2013-10-02T08:57:14Z"
,
"updated_at"
:
"2013-10-02T08:57:14Z"
,
"system"
:
false
,
"system"
:
false
,
"upvote"
:
false
,
"downvote"
:
false
,
"noteable_id"
:
2
,
"noteable_id"
:
2
,
"noteable_type"
:
"MergeRequest"
"noteable_type"
:
"MergeRequest"
}
}
...
@@ -400,8 +390,6 @@ Example Response:
...
@@ -400,8 +390,6 @@ Example Response:
"created_at"
:
"2016-04-05T22:11:59.923Z"
,
"created_at"
:
"2016-04-05T22:11:59.923Z"
,
"system"
:
false
,
"system"
:
false
,
"noteable_id"
:
7
,
"noteable_id"
:
7
,
"noteable_type"
:
"MergeRequest"
,
"noteable_type"
:
"MergeRequest"
"upvote"
:
false
,
"downvote"
:
false
}
}
```
```
doc/api/projects.md
View file @
0b402e11
...
@@ -407,8 +407,6 @@ Parameters:
...
@@ -407,8 +407,6 @@ Parameters:
},
},
"created_at"
:
"2015-12-04T10:33:56.698Z"
,
"created_at"
:
"2015-12-04T10:33:56.698Z"
,
"system"
:
false
,
"system"
:
false
,
"upvote"
:
false
,
"downvote"
:
false
,
"noteable_id"
:
377
,
"noteable_id"
:
377
,
"noteable_type"
:
"Issue"
"noteable_type"
:
"Issue"
},
},
...
...
doc/api/users.md
View file @
0b402e11
...
@@ -812,8 +812,6 @@ Example response:
...
@@ -812,8 +812,6 @@ Example response:
},
},
"created_at"
:
"2015-12-04T10:33:56.698Z"
,
"created_at"
:
"2015-12-04T10:33:56.698Z"
,
"system"
:
false
,
"system"
:
false
,
"upvote"
:
false
,
"downvote"
:
false
,
"noteable_id"
:
377
,
"noteable_id"
:
377
,
"noteable_type"
:
"Issue"
"noteable_type"
:
"Issue"
},
},
...
...
doc/api/v3_to_v4.md
View file @
0b402e11
...
@@ -36,4 +36,4 @@ changes are in V4:
...
@@ -36,4 +36,4 @@ changes are in V4:
-
POST
`:id/repository/commits`
-
POST
`:id/repository/commits`
-
POST/PUT/DELETE
`:id/repository/files`
-
POST/PUT/DELETE
`:id/repository/files`
-
Renamed
`branch_name`
to
`branch`
on DELETE
`id/repository/branches/:branch`
response
-
Renamed
`branch_name`
to
`branch`
on DELETE
`id/repository/branches/:branch`
response
-
Notes do not return deprecated field
`upvote`
and
`downvote`
[
!9384
](
https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9384
)
lib/api/api.rb
View file @
0b402e11
...
@@ -15,6 +15,7 @@ module API
...
@@ -15,6 +15,7 @@ module API
mount
::
API
::
V3
::
Members
mount
::
API
::
V3
::
Members
mount
::
API
::
V3
::
MergeRequestDiffs
mount
::
API
::
V3
::
MergeRequestDiffs
mount
::
API
::
V3
::
MergeRequests
mount
::
API
::
V3
::
MergeRequests
mount
::
API
::
V3
::
Notes
mount
::
API
::
V3
::
ProjectHooks
mount
::
API
::
V3
::
ProjectHooks
mount
::
API
::
V3
::
Projects
mount
::
API
::
V3
::
Projects
mount
::
API
::
V3
::
ProjectSnippets
mount
::
API
::
V3
::
ProjectSnippets
...
...
lib/api/entities.rb
View file @
0b402e11
...
@@ -339,9 +339,6 @@ module API
...
@@ -339,9 +339,6 @@ module API
expose
:created_at
,
:updated_at
expose
:created_at
,
:updated_at
expose
:system?
,
as: :system
expose
:system?
,
as: :system
expose
:noteable_id
,
:noteable_type
expose
:noteable_id
,
:noteable_type
# upvote? and downvote? are deprecated, always return false
expose
(
:upvote?
)
{
|
note
|
false
}
expose
(
:downvote?
)
{
|
note
|
false
}
end
end
class
AwardEmoji
<
Grape
::
Entity
class
AwardEmoji
<
Grape
::
Entity
...
...
lib/api/v3/entities.rb
View file @
0b402e11
...
@@ -11,6 +11,40 @@ module API
...
@@ -11,6 +11,40 @@ module API
Gitlab
::
UrlBuilder
.
build
(
snippet
)
Gitlab
::
UrlBuilder
.
build
(
snippet
)
end
end
end
end
class
Note
<
Grape
::
Entity
expose
:id
expose
:note
,
as: :body
expose
:attachment_identifier
,
as: :attachment
expose
:author
,
using:
::
API
::
Entities
::
UserBasic
expose
:created_at
,
:updated_at
expose
:system?
,
as: :system
expose
:noteable_id
,
:noteable_type
# upvote? and downvote? are deprecated, always return false
expose
(
:upvote?
)
{
|
note
|
false
}
expose
(
:downvote?
)
{
|
note
|
false
}
end
class
Event
<
Grape
::
Entity
expose
:title
,
:project_id
,
:action_name
expose
:target_id
,
:target_type
,
:author_id
expose
:data
,
:target_title
expose
:created_at
expose
:note
,
using:
Entities
::
Note
,
if:
->
(
event
,
options
)
{
event
.
note?
}
expose
:author
,
using:
::
API
::
Entities
::
UserBasic
,
if:
->
(
event
,
options
)
{
event
.
author
}
expose
:author_username
do
|
event
,
options
|
event
.
author
&
.
username
end
end
class
AwardEmoji
<
Grape
::
Entity
expose
:id
expose
:name
expose
:user
,
using:
::
API
::
Entities
::
UserBasic
expose
:created_at
,
:updated_at
expose
:awardable_id
,
:awardable_type
end
end
end
end
end
end
end
lib/api/v3/notes.rb
0 → 100644
View file @
0b402e11
module
API
module
V3
class
Notes
<
Grape
::
API
include
PaginationParams
before
{
authenticate!
}
NOTEABLE_TYPES
=
[
Issue
,
MergeRequest
,
Snippet
]
params
do
requires
:id
,
type:
String
,
desc:
'The ID of a project'
end
resource
:projects
do
NOTEABLE_TYPES
.
each
do
|
noteable_type
|
noteables_str
=
noteable_type
.
to_s
.
underscore
.
pluralize
desc
'Get a list of project +noteable+ notes'
do
success
::
API
::
V3
::
Entities
::
Note
end
params
do
requires
:noteable_id
,
type:
Integer
,
desc:
'The ID of the noteable'
use
:pagination
end
get
":id/
#{
noteables_str
}
/:noteable_id/notes"
do
noteable
=
user_project
.
send
(
noteables_str
.
to_sym
).
find
(
params
[
:noteable_id
])
if
can?
(
current_user
,
noteable_read_ability_name
(
noteable
),
noteable
)
# We exclude notes that are cross-references and that cannot be viewed
# by the current user. By doing this exclusion at this level and not
# at the DB query level (which we cannot in that case), the current
# page can have less elements than :per_page even if
# there's more than one page.
notes
=
# paginate() only works with a relation. This could lead to a
# mismatch between the pagination headers info and the actual notes
# array returned, but this is really a edge-case.
paginate
(
noteable
.
notes
).
reject
{
|
n
|
n
.
cross_reference_not_visible_for?
(
current_user
)
}
present
notes
,
with:
::
API
::
V3
::
Entities
::
Note
else
not_found!
(
"Notes"
)
end
end
desc
'Get a single +noteable+ note'
do
success
::
API
::
V3
::
Entities
::
Note
end
params
do
requires
:note_id
,
type:
Integer
,
desc:
'The ID of a note'
requires
:noteable_id
,
type:
Integer
,
desc:
'The ID of the noteable'
end
get
":id/
#{
noteables_str
}
/:noteable_id/notes/:note_id"
do
noteable
=
user_project
.
send
(
noteables_str
.
to_sym
).
find
(
params
[
:noteable_id
])
note
=
noteable
.
notes
.
find
(
params
[
:note_id
])
can_read_note
=
can?
(
current_user
,
noteable_read_ability_name
(
noteable
),
noteable
)
&&
!
note
.
cross_reference_not_visible_for?
(
current_user
)
if
can_read_note
present
note
,
with:
::
API
::
V3
::
Entities
::
Note
else
not_found!
(
"Note"
)
end
end
desc
'Create a new +noteable+ note'
do
success
::
API
::
V3
::
Entities
::
Note
end
params
do
requires
:noteable_id
,
type:
Integer
,
desc:
'The ID of the noteable'
requires
:body
,
type:
String
,
desc:
'The content of a note'
optional
:created_at
,
type:
String
,
desc:
'The creation date of the note'
end
post
":id/
#{
noteables_str
}
/:noteable_id/notes"
do
opts
=
{
note:
params
[
:body
],
noteable_type:
noteables_str
.
classify
,
noteable_id:
params
[
:noteable_id
]
}
noteable
=
user_project
.
send
(
noteables_str
.
to_sym
).
find
(
params
[
:noteable_id
])
if
can?
(
current_user
,
noteable_read_ability_name
(
noteable
),
noteable
)
if
params
[
:created_at
]
&&
(
current_user
.
is_admin?
||
user_project
.
owner
==
current_user
)
opts
[
:created_at
]
=
params
[
:created_at
]
end
note
=
::
Notes
::
CreateService
.
new
(
user_project
,
current_user
,
opts
).
execute
if
note
.
valid?
present
note
,
with:
::
API
::
V3
::
Entities
::
const_get
(
note
.
class
.
name
)
else
not_found!
(
"Note
#{
note
.
errors
.
messages
}
"
)
end
else
not_found!
(
"Note"
)
end
end
desc
'Update an existing +noteable+ note'
do
success
::
API
::
V3
::
Entities
::
Note
end
params
do
requires
:noteable_id
,
type:
Integer
,
desc:
'The ID of the noteable'
requires
:note_id
,
type:
Integer
,
desc:
'The ID of a note'
requires
:body
,
type:
String
,
desc:
'The content of a note'
end
put
":id/
#{
noteables_str
}
/:noteable_id/notes/:note_id"
do
note
=
user_project
.
notes
.
find
(
params
[
:note_id
])
authorize!
:admin_note
,
note
opts
=
{
note:
params
[
:body
]
}
note
=
::
Notes
::
UpdateService
.
new
(
user_project
,
current_user
,
opts
).
execute
(
note
)
if
note
.
valid?
present
note
,
with:
::
API
::
V3
::
Entities
::
Note
else
render_api_error!
(
"Failed to save note
#{
note
.
errors
.
messages
}
"
,
400
)
end
end
desc
'Delete a +noteable+ note'
do
success
::
API
::
V3
::
Entities
::
Note
end
params
do
requires
:noteable_id
,
type:
Integer
,
desc:
'The ID of the noteable'
requires
:note_id
,
type:
Integer
,
desc:
'The ID of a note'
end
delete
":id/
#{
noteables_str
}
/:noteable_id/notes/:note_id"
do
note
=
user_project
.
notes
.
find
(
params
[
:note_id
])
authorize!
:admin_note
,
note
::
Notes
::
DestroyService
.
new
(
user_project
,
current_user
).
execute
(
note
)
present
note
,
with:
::
API
::
V3
::
Entities
::
Note
end
end
end
helpers
do
def
noteable_read_ability_name
(
noteable
)
"read_
#{
noteable
.
class
.
to_s
.
underscore
}
"
.
to_sym
end
end
end
end
end
lib/api/v3/projects.rb
View file @
0b402e11
...
@@ -232,13 +232,13 @@ module API
...
@@ -232,13 +232,13 @@ module API
end
end
desc
'Get events for a single project'
do
desc
'Get events for a single project'
do
success
::
API
::
Entities
::
Event
success
::
API
::
V3
::
Entities
::
Event
end
end
params
do
params
do
use
:pagination
use
:pagination
end
end
get
":id/events"
do
get
":id/events"
do
present
paginate
(
user_project
.
events
.
recent
),
with:
::
API
::
Entities
::
Event
present
paginate
(
user_project
.
events
.
recent
),
with:
::
API
::
V3
::
Entities
::
Event
end
end
desc
'Fork new project for the current user or provided namespace.'
do
desc
'Fork new project for the current user or provided namespace.'
do
...
...
lib/api/v3/users.rb
View file @
0b402e11
...
@@ -71,6 +71,27 @@ module API
...
@@ -71,6 +71,27 @@ module API
user
.
activate
user
.
activate
end
end
end
end
desc
'Get the contribution events of a specified user'
do
detail
'This feature was introduced in GitLab 8.13.'
success
::
API
::
V3
::
Entities
::
Event
end
params
do
requires
:id
,
type:
Integer
,
desc:
'The ID of the user'
use
:pagination
end
get
':id/events'
do
user
=
User
.
find_by
(
id:
params
[
:id
])
not_found!
(
'User'
)
unless
user
events
=
user
.
events
.
merge
(
ProjectsFinder
.
new
.
execute
(
current_user
)).
references
(
:project
).
with_associations
.
recent
present
paginate
(
events
),
with:
::
API
::
V3
::
Entities
::
Event
end
end
end
resource
:user
do
resource
:user
do
...
...
spec/requests/api/v3/notes_spec.rb
0 → 100644
View file @
0b402e11
require
'spec_helper'
describe
API
::
V3
::
Notes
,
api:
true
do
include
ApiHelpers
let
(
:user
)
{
create
(
:user
)
}
let!
(
:project
)
{
create
(
:empty_project
,
:public
,
namespace:
user
.
namespace
)
}
let!
(
:issue
)
{
create
(
:issue
,
project:
project
,
author:
user
)
}
let!
(
:merge_request
)
{
create
(
:merge_request
,
source_project:
project
,
target_project:
project
,
author:
user
)
}
let!
(
:snippet
)
{
create
(
:project_snippet
,
project:
project
,
author:
user
)
}
let!
(
:issue_note
)
{
create
(
:note
,
noteable:
issue
,
project:
project
,
author:
user
)
}
let!
(
:merge_request_note
)
{
create
(
:note
,
noteable:
merge_request
,
project:
project
,
author:
user
)
}
let!
(
:snippet_note
)
{
create
(
:note
,
noteable:
snippet
,
project:
project
,
author:
user
)
}
# For testing the cross-reference of a private issue in a public issue
let
(
:private_user
)
{
create
(
:user
)
}
let
(
:private_project
)
do
create
(
:empty_project
,
namespace:
private_user
.
namespace
).
tap
{
|
p
|
p
.
team
<<
[
private_user
,
:master
]
}
end
let
(
:private_issue
)
{
create
(
:issue
,
project:
private_project
)
}
let
(
:ext_proj
)
{
create
(
:empty_project
,
:public
)
}
let
(
:ext_issue
)
{
create
(
:issue
,
project:
ext_proj
)
}
let!
(
:cross_reference_note
)
do
create
:note
,
noteable:
ext_issue
,
project:
ext_proj
,
note:
"mentioned in issue
#{
private_issue
.
to_reference
(
ext_proj
)
}
"
,
system:
true
end
before
{
project
.
team
<<
[
user
,
:reporter
]
}
describe
"GET /projects/:id/noteable/:noteable_id/notes"
do
context
"when noteable is an Issue"
do
it
"returns an array of issue notes"
do
get
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/notes"
,
user
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
response
).
to
include_pagination_headers
expect
(
json_response
).
to
be_an
Array
expect
(
json_response
.
first
[
'body'
]).
to
eq
(
issue_note
.
note
)
expect
(
json_response
.
first
[
'upvote'
]).
to
be_falsey
expect
(
json_response
.
first
[
'downvote'
]).
to
be_falsey
end
it
"returns a 404 error when issue id not found"
do
get
v3_api
(
"/projects/
#{
project
.
id
}
/issues/12345/notes"
,
user
)
expect
(
response
).
to
have_http_status
(
404
)
end
context
"and current user cannot view the notes"
do
it
"returns an empty array"
do
get
v3_api
(
"/projects/
#{
ext_proj
.
id
}
/issues/
#{
ext_issue
.
id
}
/notes"
,
user
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
response
).
to
include_pagination_headers
expect
(
json_response
).
to
be_an
Array
expect
(
json_response
).
to
be_empty
end
context
"and issue is confidential"
do
before
{
ext_issue
.
update_attributes
(
confidential:
true
)
}
it
"returns 404"
do
get
v3_api
(
"/projects/
#{
ext_proj
.
id
}
/issues/
#{
ext_issue
.
id
}
/notes"
,
user
)
expect
(
response
).
to
have_http_status
(
404
)
end
end
context
"and current user can view the note"
do
it
"returns an empty array"
do
get
v3_api
(
"/projects/
#{
ext_proj
.
id
}
/issues/
#{
ext_issue
.
id
}
/notes"
,
private_user
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
response
).
to
include_pagination_headers
expect
(
json_response
).
to
be_an
Array
expect
(
json_response
.
first
[
'body'
]).
to
eq
(
cross_reference_note
.
note
)
end
end
end
end
context
"when noteable is a Snippet"
do
it
"returns an array of snippet notes"
do
get
v3_api
(
"/projects/
#{
project
.
id
}
/snippets/
#{
snippet
.
id
}
/notes"
,
user
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
response
).
to
include_pagination_headers
expect
(
json_response
).
to
be_an
Array
expect
(
json_response
.
first
[
'body'
]).
to
eq
(
snippet_note
.
note
)
end
it
"returns a 404 error when snippet id not found"
do
get
v3_api
(
"/projects/
#{
project
.
id
}
/snippets/42/notes"
,
user
)
expect
(
response
).
to
have_http_status
(
404
)
end
it
"returns 404 when not authorized"
do
get
v3_api
(
"/projects/
#{
project
.
id
}
/snippets/
#{
snippet
.
id
}
/notes"
,
private_user
)
expect
(
response
).
to
have_http_status
(
404
)
end
end
context
"when noteable is a Merge Request"
do
it
"returns an array of merge_requests notes"
do
get
v3_api
(
"/projects/
#{
project
.
id
}
/merge_requests/
#{
merge_request
.
id
}
/notes"
,
user
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
response
).
to
include_pagination_headers
expect
(
json_response
).
to
be_an
Array
expect
(
json_response
.
first
[
'body'
]).
to
eq
(
merge_request_note
.
note
)
end
it
"returns a 404 error if merge request id not found"
do
get
v3_api
(
"/projects/
#{
project
.
id
}
/merge_requests/4444/notes"
,
user
)
expect
(
response
).
to
have_http_status
(
404
)
end
it
"returns 404 when not authorized"
do
get
v3_api
(
"/projects/
#{
project
.
id
}
/merge_requests/4444/notes"
,
private_user
)
expect
(
response
).
to
have_http_status
(
404
)
end
end
end
describe
"GET /projects/:id/noteable/:noteable_id/notes/:note_id"
do
context
"when noteable is an Issue"
do
it
"returns an issue note by id"
do
get
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/notes/
#{
issue_note
.
id
}
"
,
user
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
json_response
[
'body'
]).
to
eq
(
issue_note
.
note
)
end
it
"returns a 404 error if issue note not found"
do
get
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/notes/12345"
,
user
)
expect
(
response
).
to
have_http_status
(
404
)
end
context
"and current user cannot view the note"
do
it
"returns a 404 error"
do
get
v3_api
(
"/projects/
#{
ext_proj
.
id
}
/issues/
#{
ext_issue
.
id
}
/notes/
#{
cross_reference_note
.
id
}
"
,
user
)
expect
(
response
).
to
have_http_status
(
404
)
end
context
"when issue is confidential"
do
before
{
issue
.
update_attributes
(
confidential:
true
)
}
it
"returns 404"
do
get
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/notes/
#{
issue_note
.
id
}
"
,
private_user
)
expect
(
response
).
to
have_http_status
(
404
)
end
end
context
"and current user can view the note"
do
it
"returns an issue note by id"
do
get
v3_api
(
"/projects/
#{
ext_proj
.
id
}
/issues/
#{
ext_issue
.
id
}
/notes/
#{
cross_reference_note
.
id
}
"
,
private_user
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
json_response
[
'body'
]).
to
eq
(
cross_reference_note
.
note
)
end
end
end
end
context
"when noteable is a Snippet"
do
it
"returns a snippet note by id"
do
get
v3_api
(
"/projects/
#{
project
.
id
}
/snippets/
#{
snippet
.
id
}
/notes/
#{
snippet_note
.
id
}
"
,
user
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
json_response
[
'body'
]).
to
eq
(
snippet_note
.
note
)
end
it
"returns a 404 error if snippet note not found"
do
get
v3_api
(
"/projects/
#{
project
.
id
}
/snippets/
#{
snippet
.
id
}
/notes/12345"
,
user
)
expect
(
response
).
to
have_http_status
(
404
)
end
end
end
describe
"POST /projects/:id/noteable/:noteable_id/notes"
do
context
"when noteable is an Issue"
do
it
"creates a new issue note"
do
post
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/notes"
,
user
),
body:
'hi!'
expect
(
response
).
to
have_http_status
(
201
)
expect
(
json_response
[
'body'
]).
to
eq
(
'hi!'
)
expect
(
json_response
[
'author'
][
'username'
]).
to
eq
(
user
.
username
)
end
it
"returns a 400 bad request error if body not given"
do
post
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/notes"
,
user
)
expect
(
response
).
to
have_http_status
(
400
)
end
it
"returns a 401 unauthorized error if user not authenticated"
do
post
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/notes"
),
body:
'hi!'
expect
(
response
).
to
have_http_status
(
401
)
end
context
'when an admin or owner makes the request'
do
it
'accepts the creation date to be set'
do
creation_time
=
2
.
weeks
.
ago
post
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/notes"
,
user
),
body:
'hi!'
,
created_at:
creation_time
expect
(
response
).
to
have_http_status
(
201
)
expect
(
json_response
[
'body'
]).
to
eq
(
'hi!'
)
expect
(
json_response
[
'author'
][
'username'
]).
to
eq
(
user
.
username
)
expect
(
Time
.
parse
(
json_response
[
'created_at'
])).
to
be_like_time
(
creation_time
)
end
end
context
'when the user is posting an award emoji on an issue created by someone else'
do
let
(
:issue2
)
{
create
(
:issue
,
project:
project
)
}
it
'returns an award emoji'
do
post
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue2
.
id
}
/notes"
,
user
),
body:
':+1:'
expect
(
response
).
to
have_http_status
(
201
)
expect
(
json_response
[
'awardable_id'
]).
to
eq
issue2
.
id
end
end
context
'when the user is posting an award emoji on his/her own issue'
do
it
'creates a new issue note'
do
post
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/notes"
,
user
),
body:
':+1:'
expect
(
response
).
to
have_http_status
(
201
)
expect
(
json_response
[
'body'
]).
to
eq
(
':+1:'
)
end
end
end
context
"when noteable is a Snippet"
do
it
"creates a new snippet note"
do
post
v3_api
(
"/projects/
#{
project
.
id
}
/snippets/
#{
snippet
.
id
}
/notes"
,
user
),
body:
'hi!'
expect
(
response
).
to
have_http_status
(
201
)
expect
(
json_response
[
'body'
]).
to
eq
(
'hi!'
)
expect
(
json_response
[
'author'
][
'username'
]).
to
eq
(
user
.
username
)
end
it
"returns a 400 bad request error if body not given"
do
post
v3_api
(
"/projects/
#{
project
.
id
}
/snippets/
#{
snippet
.
id
}
/notes"
,
user
)
expect
(
response
).
to
have_http_status
(
400
)
end
it
"returns a 401 unauthorized error if user not authenticated"
do
post
v3_api
(
"/projects/
#{
project
.
id
}
/snippets/
#{
snippet
.
id
}
/notes"
),
body:
'hi!'
expect
(
response
).
to
have_http_status
(
401
)
end
end
context
'when user does not have access to read the noteable'
do
it
'responds with 404'
do
project
=
create
(
:empty_project
,
:private
)
{
|
p
|
p
.
add_guest
(
user
)
}
issue
=
create
(
:issue
,
:confidential
,
project:
project
)
post
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/notes"
,
user
),
body:
'Foo'
expect
(
response
).
to
have_http_status
(
404
)
end
end
context
'when user does not have access to create noteable'
do
let
(
:private_issue
)
{
create
(
:issue
,
project:
create
(
:empty_project
,
:private
))
}
##
# We are posting to project user has access to, but we use issue id
# from a different project, see #15577
#
before
do
post
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
private_issue
.
id
}
/notes"
,
user
),
body:
'Hi!'
end
it
'responds with resource not found error'
do
expect
(
response
.
status
).
to
eq
404
end
it
'does not create new note'
do
expect
(
private_issue
.
notes
.
reload
).
to
be_empty
end
end
end
describe
"POST /projects/:id/noteable/:noteable_id/notes to test observer on create"
do
it
"creates an activity event when an issue note is created"
do
expect
(
Event
).
to
receive
(
:create
)
post
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/notes"
,
user
),
body:
'hi!'
end
end
describe
'PUT /projects/:id/noteable/:noteable_id/notes/:note_id'
do
context
'when noteable is an Issue'
do
it
'returns modified note'
do
put
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/"
\
"notes/
#{
issue_note
.
id
}
"
,
user
),
body:
'Hello!'
expect
(
response
).
to
have_http_status
(
200
)
expect
(
json_response
[
'body'
]).
to
eq
(
'Hello!'
)
end
it
'returns a 404 error when note id not found'
do
put
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/notes/12345"
,
user
),
body:
'Hello!'
expect
(
response
).
to
have_http_status
(
404
)
end
it
'returns a 400 bad request error if body not given'
do
put
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/"
\
"notes/
#{
issue_note
.
id
}
"
,
user
)
expect
(
response
).
to
have_http_status
(
400
)
end
end
context
'when noteable is a Snippet'
do
it
'returns modified note'
do
put
v3_api
(
"/projects/
#{
project
.
id
}
/snippets/
#{
snippet
.
id
}
/"
\
"notes/
#{
snippet_note
.
id
}
"
,
user
),
body:
'Hello!'
expect
(
response
).
to
have_http_status
(
200
)
expect
(
json_response
[
'body'
]).
to
eq
(
'Hello!'
)
end
it
'returns a 404 error when note id not found'
do
put
v3_api
(
"/projects/
#{
project
.
id
}
/snippets/
#{
snippet
.
id
}
/"
\
"notes/12345"
,
user
),
body:
"Hello!"
expect
(
response
).
to
have_http_status
(
404
)
end
end
context
'when noteable is a Merge Request'
do
it
'returns modified note'
do
put
v3_api
(
"/projects/
#{
project
.
id
}
/merge_requests/
#{
merge_request
.
id
}
/"
\
"notes/
#{
merge_request_note
.
id
}
"
,
user
),
body:
'Hello!'
expect
(
response
).
to
have_http_status
(
200
)
expect
(
json_response
[
'body'
]).
to
eq
(
'Hello!'
)
end
it
'returns a 404 error when note id not found'
do
put
v3_api
(
"/projects/
#{
project
.
id
}
/merge_requests/
#{
merge_request
.
id
}
/"
\
"notes/12345"
,
user
),
body:
"Hello!"
expect
(
response
).
to
have_http_status
(
404
)
end
end
end
describe
'DELETE /projects/:id/noteable/:noteable_id/notes/:note_id'
do
context
'when noteable is an Issue'
do
it
'deletes a note'
do
delete
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/"
\
"notes/
#{
issue_note
.
id
}
"
,
user
)
expect
(
response
).
to
have_http_status
(
200
)
# Check if note is really deleted
delete
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/"
\
"notes/
#{
issue_note
.
id
}
"
,
user
)
expect
(
response
).
to
have_http_status
(
404
)
end
it
'returns a 404 error when note id not found'
do
delete
v3_api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/notes/12345"
,
user
)
expect
(
response
).
to
have_http_status
(
404
)
end
end
context
'when noteable is a Snippet'
do
it
'deletes a note'
do
delete
v3_api
(
"/projects/
#{
project
.
id
}
/snippets/
#{
snippet
.
id
}
/"
\
"notes/
#{
snippet_note
.
id
}
"
,
user
)
expect
(
response
).
to
have_http_status
(
200
)
# Check if note is really deleted
delete
v3_api
(
"/projects/
#{
project
.
id
}
/snippets/
#{
snippet
.
id
}
/"
\
"notes/
#{
snippet_note
.
id
}
"
,
user
)
expect
(
response
).
to
have_http_status
(
404
)
end
it
'returns a 404 error when note id not found'
do
delete
v3_api
(
"/projects/
#{
project
.
id
}
/snippets/
#{
snippet
.
id
}
/"
\
"notes/12345"
,
user
)
expect
(
response
).
to
have_http_status
(
404
)
end
end
context
'when noteable is a Merge Request'
do
it
'deletes a note'
do
delete
v3_api
(
"/projects/
#{
project
.
id
}
/merge_requests/"
\
"
#{
merge_request
.
id
}
/notes/
#{
merge_request_note
.
id
}
"
,
user
)
expect
(
response
).
to
have_http_status
(
200
)
# Check if note is really deleted
delete
v3_api
(
"/projects/
#{
project
.
id
}
/merge_requests/"
\
"
#{
merge_request
.
id
}
/notes/
#{
merge_request_note
.
id
}
"
,
user
)
expect
(
response
).
to
have_http_status
(
404
)
end
it
'returns a 404 error when note id not found'
do
delete
v3_api
(
"/projects/
#{
project
.
id
}
/merge_requests/"
\
"
#{
merge_request
.
id
}
/notes/12345"
,
user
)
expect
(
response
).
to
have_http_status
(
404
)
end
end
end
end
spec/requests/api/v3/users_spec.rb
View file @
0b402e11
...
@@ -186,4 +186,81 @@ describe API::V3::Users, api: true do
...
@@ -186,4 +186,81 @@ describe API::V3::Users, api: true do
expect
(
response
).
to
have_http_status
(
404
)
expect
(
response
).
to
have_http_status
(
404
)
end
end
end
end
describe
'GET /users/:id/events'
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:note
)
{
create
(
:note_on_issue
,
note:
'What an awesome day!'
,
project:
project
)
}
before
do
project
.
add_user
(
user
,
:developer
)
EventCreateService
.
new
.
leave_note
(
note
,
user
)
end
context
"as a user than cannot see the event's project"
do
it
'returns no events'
do
other_user
=
create
(
:user
)
get
api
(
"/users/
#{
user
.
id
}
/events"
,
other_user
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
json_response
).
to
be_empty
end
end
context
"as a user than can see the event's project"
do
context
'joined event'
do
it
'returns the "joined" event'
do
get
v3_api
(
"/users/
#{
user
.
id
}
/events"
,
user
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
response
).
to
include_pagination_headers
expect
(
json_response
).
to
be_an
Array
comment_event
=
json_response
.
find
{
|
e
|
e
[
'action_name'
]
==
'commented on'
}
expect
(
comment_event
[
'project_id'
].
to_i
).
to
eq
(
project
.
id
)
expect
(
comment_event
[
'author_username'
]).
to
eq
(
user
.
username
)
expect
(
comment_event
[
'note'
][
'id'
]).
to
eq
(
note
.
id
)
expect
(
comment_event
[
'note'
][
'body'
]).
to
eq
(
'What an awesome day!'
)
joined_event
=
json_response
.
find
{
|
e
|
e
[
'action_name'
]
==
'joined'
}
expect
(
joined_event
[
'project_id'
].
to_i
).
to
eq
(
project
.
id
)
expect
(
joined_event
[
'author_username'
]).
to
eq
(
user
.
username
)
expect
(
joined_event
[
'author'
][
'name'
]).
to
eq
(
user
.
name
)
end
end
context
'when there are multiple events from different projects'
do
let
(
:second_note
)
{
create
(
:note_on_issue
,
project:
create
(
:empty_project
))
}
let
(
:third_note
)
{
create
(
:note_on_issue
,
project:
project
)
}
before
do
second_note
.
project
.
add_user
(
user
,
:developer
)
[
second_note
,
third_note
].
each
do
|
note
|
EventCreateService
.
new
.
leave_note
(
note
,
user
)
end
end
it
'returns events in the correct order (from newest to oldest)'
do
get
v3_api
(
"/users/
#{
user
.
id
}
/events"
,
user
)
comment_events
=
json_response
.
select
{
|
e
|
e
[
'action_name'
]
==
'commented on'
}
expect
(
comment_events
[
0
][
'target_id'
]).
to
eq
(
third_note
.
id
)
expect
(
comment_events
[
1
][
'target_id'
]).
to
eq
(
second_note
.
id
)
expect
(
comment_events
[
2
][
'target_id'
]).
to
eq
(
note
.
id
)
end
end
end
it
'returns a 404 error if not found'
do
get
v3_api
(
'/users/42/events'
,
user
)
expect
(
response
).
to
have_http_status
(
404
)
expect
(
json_response
[
'message'
]).
to
eq
(
'404 User Not Found'
)
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