API: New /users/:id/events endpoint
Signed-off-by: Rémy Coutable <remy@rymai.me>
This commit is contained in:
parent
2e55580b90
commit
33ce197645
|
@ -59,6 +59,7 @@ v 8.13.0 (unreleased)
|
|||
- Stop using a Redis lease when updating the project activity timestamp whenever a new event is created
|
||||
- Add broadcast messages and alerts below sub-nav
|
||||
- Better empty state for Groups view
|
||||
- API: New /users/:id/events endpoint
|
||||
- Update ruby-prof to 0.16.2. !6026 (Elan Ruusamäe)
|
||||
- Replace bootstrap caret with fontawesome caret (ClemMakesApps)
|
||||
- Fix unnecessary escaping of reserved HTML characters in milestone title. !6533
|
||||
|
|
146
doc/api/users.md
146
doc/api/users.md
|
@ -627,3 +627,149 @@ Parameters:
|
|||
|
||||
Will return `200 OK` on success, `404 User Not Found` is user cannot be found or
|
||||
`403 Forbidden` when trying to unblock a user blocked by LDAP synchronization.
|
||||
|
||||
### Get user contribution events
|
||||
|
||||
Get the contribution events for the specified user, sorted from newest to latest.
|
||||
|
||||
```
|
||||
GET /users/:id/events
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `id` | integer | yes | The ID of the user |
|
||||
|
||||
```bash
|
||||
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/user/:id/events
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"title": null,
|
||||
"project_id": 15,
|
||||
"action_name": "closed",
|
||||
"target_id": 830,
|
||||
"target_type": "Issue",
|
||||
"author_id": 1,
|
||||
"data": null,
|
||||
"target_title": "Public project search field",
|
||||
"author": {
|
||||
"name": "Dmitriy Zaporozhets",
|
||||
"username": "root",
|
||||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
},
|
||||
"author_username": "root"
|
||||
},
|
||||
{
|
||||
"title": null,
|
||||
"project_id": 15,
|
||||
"action_name": "opened",
|
||||
"target_id": null,
|
||||
"target_type": null,
|
||||
"author_id": 1,
|
||||
"author": {
|
||||
"name": "Dmitriy Zaporozhets",
|
||||
"username": "root",
|
||||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
},
|
||||
"author_username": "john",
|
||||
"data": {
|
||||
"before": "50d4420237a9de7be1304607147aec22e4a14af7",
|
||||
"after": "c5feabde2d8cd023215af4d2ceeb7a64839fc428",
|
||||
"ref": "refs/heads/master",
|
||||
"user_id": 1,
|
||||
"user_name": "Dmitriy Zaporozhets",
|
||||
"repository": {
|
||||
"name": "gitlabhq",
|
||||
"url": "git@dev.gitlab.org:gitlab/gitlabhq.git",
|
||||
"description": "GitLab: self hosted Git management software. \r\nDistributed under the MIT License.",
|
||||
"homepage": "https://dev.gitlab.org/gitlab/gitlabhq"
|
||||
},
|
||||
"commits": [
|
||||
{
|
||||
"id": "c5feabde2d8cd023215af4d2ceeb7a64839fc428",
|
||||
"message": "Add simple search to projects in public area",
|
||||
"timestamp": "2013-05-13T18:18:08+00:00",
|
||||
"url": "https://dev.gitlab.org/gitlab/gitlabhq/commit/c5feabde2d8cd023215af4d2ceeb7a64839fc428",
|
||||
"author": {
|
||||
"name": "Dmitriy Zaporozhets",
|
||||
"email": "dmitriy.zaporozhets@gmail.com"
|
||||
}
|
||||
}
|
||||
],
|
||||
"total_commits_count": 1
|
||||
},
|
||||
"target_title": null
|
||||
},
|
||||
{
|
||||
"title": null,
|
||||
"project_id": 15,
|
||||
"action_name": "closed",
|
||||
"target_id": 840,
|
||||
"target_type": "Issue",
|
||||
"author_id": 1,
|
||||
"data": null,
|
||||
"target_title": "Finish & merge Code search PR",
|
||||
"author": {
|
||||
"name": "Dmitriy Zaporozhets",
|
||||
"username": "root",
|
||||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
},
|
||||
"author_username": "root"
|
||||
},
|
||||
{
|
||||
"title": null,
|
||||
"project_id": 15,
|
||||
"action_name": "commented on",
|
||||
"target_id": 1312,
|
||||
"target_type": "Note",
|
||||
"author_id": 1,
|
||||
"data": null,
|
||||
"target_title": null,
|
||||
"created_at": "2015-12-04T10:33:58.089Z",
|
||||
"note": {
|
||||
"id": 1312,
|
||||
"body": "What an awesome day!",
|
||||
"attachment": null,
|
||||
"author": {
|
||||
"name": "Dmitriy Zaporozhets",
|
||||
"username": "root",
|
||||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
},
|
||||
"created_at": "2015-12-04T10:33:56.698Z",
|
||||
"system": false,
|
||||
"upvote": false,
|
||||
"downvote": false,
|
||||
"noteable_id": 377,
|
||||
"noteable_type": "Issue"
|
||||
},
|
||||
"author": {
|
||||
"name": "Dmitriy Zaporozhets",
|
||||
"username": "root",
|
||||
"id": 1,
|
||||
"state": "active",
|
||||
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
|
||||
"web_url": "http://localhost:3000/u/root"
|
||||
},
|
||||
"author_username": "root"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
|
|
@ -321,6 +321,26 @@ module API
|
|||
user.activate
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Get contribution events of a specified user' do
|
||||
detail 'This feature was introduced in GitLab 8.13.'
|
||||
success Entities::Event
|
||||
end
|
||||
params do
|
||||
requires :id, type: String, desc: 'The user ID'
|
||||
end
|
||||
get ':id/events' do
|
||||
user = User.find_by(id: declared(params).id)
|
||||
not_found!('User') unless user
|
||||
|
||||
events = user.recent_events.
|
||||
merge(ProjectsFinder.new.execute(current_user)).
|
||||
references(:project).
|
||||
with_associations.
|
||||
page(params[:page])
|
||||
|
||||
present paginate(events), with: Entities::Event
|
||||
end
|
||||
end
|
||||
|
||||
resource :user do
|
||||
|
|
|
@ -895,4 +895,59 @@ describe API::API, api: true do
|
|||
expect{put api("/users/ASDF/block", admin) }.to raise_error(ActionController::RoutingError)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /user/:id/events' do
|
||||
let(:user) { create(:user) }
|
||||
let(:lambda_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
|
||||
get api("/users/#{user.id}/events", lambda_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
|
||||
it_behaves_like 'a paginated resources' do
|
||||
let(:request) { get api("/users/#{user.id}/events", user) }
|
||||
end
|
||||
|
||||
context 'joined event' do
|
||||
it 'returns the "joined" event' do
|
||||
get api("/users/#{user.id}/events", user)
|
||||
|
||||
first_event = json_response.first
|
||||
|
||||
expect(first_event['action_name']).to eq('commented on')
|
||||
expect(first_event['project_id'].to_i).to eq(project.id)
|
||||
expect(first_event['author_username']).to eq(user.username)
|
||||
expect(first_event['note']['id']).to eq(note.id)
|
||||
expect(first_event['note']['body']).to eq('What an awesome day!')
|
||||
|
||||
last_event = json_response.last
|
||||
|
||||
expect(last_event['action_name']).to eq('joined')
|
||||
expect(last_event['project_id'].to_i).to eq(project.id)
|
||||
expect(last_event['author_username']).to eq(user.username)
|
||||
expect(last_event['author']['name']).to eq(user.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns a 404 error if not found' do
|
||||
get 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
|
||||
|
|
Loading…
Reference in New Issue