Merge branch 'api-remove-snippets-expires-at' into 'master'

Remove deprecated 'expires_at' from project snippets API

Closes #14156

See merge request !8723
This commit is contained in:
Sean McGivern 2017-02-07 13:02:56 +00:00
commit f97d7769e0
12 changed files with 416 additions and 88 deletions

View file

@ -0,0 +1,4 @@
---
title: 'API: Remove deprecated ''expires_at'' from project snippets'
merge_request: 8723
author: Robert Schilling

View file

@ -51,7 +51,6 @@ Parameters:
"state": "active", "state": "active",
"created_at": "2012-05-23T08:00:58Z" "created_at": "2012-05-23T08:00:58Z"
}, },
"expires_at": null,
"updated_at": "2012-06-28T10:52:04Z", "updated_at": "2012-06-28T10:52:04Z",
"created_at": "2012-06-28T10:52:04Z", "created_at": "2012-06-28T10:52:04Z",
"web_url": "http://example.com/example/example/snippets/1" "web_url": "http://example.com/example/example/snippets/1"

View file

@ -10,4 +10,4 @@ changes are in V4:
- `iid` filter has been removed from `projects/:id/issues` - `iid` filter has been removed from `projects/:id/issues`
- `projects/:id/merge_requests?iid[]=x&iid[]=y` array filter has been renamed to `iids` - `projects/:id/merge_requests?iid[]=x&iid[]=y` array filter has been renamed to `iids`
- Endpoints under `projects/merge_request/:id` have been removed (use: `projects/merge_requests/:id`) - Endpoints under `projects/merge_request/:id` have been removed (use: `projects/merge_requests/:id`)
- Project snippets do not return deprecated field `expires_at`

View file

@ -8,6 +8,7 @@ module API
mount ::API::V3::Issues mount ::API::V3::Issues
mount ::API::V3::MergeRequests mount ::API::V3::MergeRequests
mount ::API::V3::Projects mount ::API::V3::Projects
mount ::API::V3::ProjectSnippets
end end
before { allow_access_with_scope :api } before { allow_access_with_scope :api }

View file

@ -213,9 +213,6 @@ module API
expose :author, using: Entities::UserBasic expose :author, using: Entities::UserBasic
expose :updated_at, :created_at expose :updated_at, :created_at
# TODO (rspeicher): Deprecated; remove in 9.0
expose(:expires_at) { |snippet| nil }
expose :web_url do |snippet, options| expose :web_url do |snippet, options|
Gitlab::UrlBuilder.build(snippet) Gitlab::UrlBuilder.build(snippet)
end end

16
lib/api/v3/entities.rb Normal file
View file

@ -0,0 +1,16 @@
module API
module V3
module Entities
class ProjectSnippet < Grape::Entity
expose :id, :title, :file_name
expose :author, using: ::API::Entities::UserBasic
expose :updated_at, :created_at
expose(:expires_at) { |snippet| nil }
expose :web_url do |snippet, options|
Gitlab::UrlBuilder.build(snippet)
end
end
end
end
end

View file

@ -50,7 +50,7 @@ module API
resource :issues do resource :issues do
desc "Get currently authenticated user's issues" do desc "Get currently authenticated user's issues" do
success Entities::Issue success ::API::Entities::Issue
end end
params do params do
optional :state, type: String, values: %w[opened closed all], default: 'all', optional :state, type: String, values: %w[opened closed all], default: 'all',
@ -60,7 +60,7 @@ module API
get do get do
issues = find_issues(scope: 'authored') issues = find_issues(scope: 'authored')
present paginate(issues), with: Entities::Issue, current_user: current_user present paginate(issues), with: ::API::Entities::Issue, current_user: current_user
end end
end end
@ -69,7 +69,7 @@ module API
end end
resource :groups do resource :groups do
desc 'Get a list of group issues' do desc 'Get a list of group issues' do
success Entities::Issue success ::API::Entities::Issue
end end
params do params do
optional :state, type: String, values: %w[opened closed all], default: 'opened', optional :state, type: String, values: %w[opened closed all], default: 'opened',
@ -81,7 +81,7 @@ module API
issues = find_issues(group_id: group.id, state: params[:state] || 'opened', match_all_labels: true) issues = find_issues(group_id: group.id, state: params[:state] || 'opened', match_all_labels: true)
present paginate(issues), with: Entities::Issue, current_user: current_user present paginate(issues), with: ::API::Entities::Issue, current_user: current_user
end end
end end
@ -93,7 +93,7 @@ module API
desc 'Get a list of project issues' do desc 'Get a list of project issues' do
detail 'iid filter is deprecated have been removed on V4' detail 'iid filter is deprecated have been removed on V4'
success Entities::Issue success ::API::Entities::Issue
end end
params do params do
optional :state, type: String, values: %w[opened closed all], default: 'all', optional :state, type: String, values: %w[opened closed all], default: 'all',
@ -106,22 +106,22 @@ module API
issues = find_issues(project_id: project.id) issues = find_issues(project_id: project.id)
present paginate(issues), with: Entities::Issue, current_user: current_user, project: user_project present paginate(issues), with: ::API::Entities::Issue, current_user: current_user, project: user_project
end end
desc 'Get a single project issue' do desc 'Get a single project issue' do
success Entities::Issue success ::API::Entities::Issue
end end
params do params do
requires :issue_id, type: Integer, desc: 'The ID of a project issue' requires :issue_id, type: Integer, desc: 'The ID of a project issue'
end end
get ":id/issues/:issue_id" do get ":id/issues/:issue_id" do
issue = find_project_issue(params[:issue_id]) issue = find_project_issue(params[:issue_id])
present issue, with: Entities::Issue, current_user: current_user, project: user_project present issue, with: ::API::Entities::Issue, current_user: current_user, project: user_project
end end
desc 'Create a new project issue' do desc 'Create a new project issue' do
success Entities::Issue success ::API::Entities::Issue
end end
params do params do
requires :title, type: String, desc: 'The title of an issue' requires :title, type: String, desc: 'The title of an issue'
@ -153,14 +153,14 @@ module API
end end
if issue.valid? if issue.valid?
present issue, with: Entities::Issue, current_user: current_user, project: user_project present issue, with: ::API::Entities::Issue, current_user: current_user, project: user_project
else else
render_validation_error!(issue) render_validation_error!(issue)
end end
end end
desc 'Update an existing issue' do desc 'Update an existing issue' do
success Entities::Issue success ::API::Entities::Issue
end end
params do params do
requires :issue_id, type: Integer, desc: 'The ID of a project issue' requires :issue_id, type: Integer, desc: 'The ID of a project issue'
@ -186,14 +186,14 @@ module API
declared_params(include_missing: false)).execute(issue) declared_params(include_missing: false)).execute(issue)
if issue.valid? if issue.valid?
present issue, with: Entities::Issue, current_user: current_user, project: user_project present issue, with: ::API::Entities::Issue, current_user: current_user, project: user_project
else else
render_validation_error!(issue) render_validation_error!(issue)
end end
end end
desc 'Move an existing issue' do desc 'Move an existing issue' do
success Entities::Issue success ::API::Entities::Issue
end end
params do params do
requires :issue_id, type: Integer, desc: 'The ID of a project issue' requires :issue_id, type: Integer, desc: 'The ID of a project issue'
@ -208,7 +208,7 @@ module API
begin begin
issue = ::Issues::MoveService.new(user_project, current_user).execute(issue, new_project) issue = ::Issues::MoveService.new(user_project, current_user).execute(issue, new_project)
present issue, with: Entities::Issue, current_user: current_user, project: user_project present issue, with: ::API::Entities::Issue, current_user: current_user, project: user_project
rescue ::Issues::MoveService::MoveError => error rescue ::Issues::MoveService::MoveError => error
render_api_error!(error.message, 400) render_api_error!(error.message, 400)
end end

View file

@ -39,7 +39,7 @@ module API
desc 'List merge requests' do desc 'List merge requests' do
detail 'iid filter is deprecated have been removed on V4' detail 'iid filter is deprecated have been removed on V4'
success Entities::MergeRequest success ::API::Entities::MergeRequest
end end
params do params do
optional :state, type: String, values: %w[opened closed merged all], default: 'all', optional :state, type: String, values: %w[opened closed merged all], default: 'all',
@ -66,11 +66,11 @@ module API
end end
merge_requests = merge_requests.reorder(params[:order_by] => params[:sort]) merge_requests = merge_requests.reorder(params[:order_by] => params[:sort])
present paginate(merge_requests), with: Entities::MergeRequest, current_user: current_user, project: user_project present paginate(merge_requests), with: ::API::Entities::MergeRequest, current_user: current_user, project: user_project
end end
desc 'Create a merge request' do desc 'Create a merge request' do
success Entities::MergeRequest success ::API::Entities::MergeRequest
end end
params do params do
requires :title, type: String, desc: 'The title of the merge request' requires :title, type: String, desc: 'The title of the merge request'
@ -89,7 +89,7 @@ module API
merge_request = ::MergeRequests::CreateService.new(user_project, current_user, mr_params).execute merge_request = ::MergeRequests::CreateService.new(user_project, current_user, mr_params).execute
if merge_request.valid? if merge_request.valid?
present merge_request, with: Entities::MergeRequest, current_user: current_user, project: user_project present merge_request, with: ::API::Entities::MergeRequest, current_user: current_user, project: user_project
else else
handle_merge_request_errors! merge_request.errors handle_merge_request_errors! merge_request.errors
end end
@ -114,34 +114,34 @@ module API
if status == :deprecated if status == :deprecated
detail DEPRECATION_MESSAGE detail DEPRECATION_MESSAGE
end end
success Entities::MergeRequest success ::API::Entities::MergeRequest
end end
get path do get path do
merge_request = find_merge_request_with_access(params[:merge_request_id]) merge_request = find_merge_request_with_access(params[:merge_request_id])
present merge_request, with: Entities::MergeRequest, current_user: current_user, project: user_project present merge_request, with: ::API::Entities::MergeRequest, current_user: current_user, project: user_project
end end
desc 'Get the commits of a merge request' do desc 'Get the commits of a merge request' do
success Entities::RepoCommit success ::API::Entities::RepoCommit
end end
get "#{path}/commits" do get "#{path}/commits" do
merge_request = find_merge_request_with_access(params[:merge_request_id]) merge_request = find_merge_request_with_access(params[:merge_request_id])
present merge_request.commits, with: Entities::RepoCommit present merge_request.commits, with: ::API::Entities::RepoCommit
end end
desc 'Show the merge request changes' do desc 'Show the merge request changes' do
success Entities::MergeRequestChanges success ::API::Entities::MergeRequestChanges
end end
get "#{path}/changes" do get "#{path}/changes" do
merge_request = find_merge_request_with_access(params[:merge_request_id]) merge_request = find_merge_request_with_access(params[:merge_request_id])
present merge_request, with: Entities::MergeRequestChanges, current_user: current_user present merge_request, with: ::API::Entities::MergeRequestChanges, current_user: current_user
end end
desc 'Update a merge request' do desc 'Update a merge request' do
success Entities::MergeRequest success ::API::Entities::MergeRequest
end end
params do params do
optional :title, type: String, allow_blank: false, desc: 'The title of the merge request' optional :title, type: String, allow_blank: false, desc: 'The title of the merge request'
@ -162,14 +162,14 @@ module API
merge_request = ::MergeRequests::UpdateService.new(user_project, current_user, mr_params).execute(merge_request) merge_request = ::MergeRequests::UpdateService.new(user_project, current_user, mr_params).execute(merge_request)
if merge_request.valid? if merge_request.valid?
present merge_request, with: Entities::MergeRequest, current_user: current_user, project: user_project present merge_request, with: ::API::Entities::MergeRequest, current_user: current_user, project: user_project
else else
handle_merge_request_errors! merge_request.errors handle_merge_request_errors! merge_request.errors
end end
end end
desc 'Merge a merge request' do desc 'Merge a merge request' do
success Entities::MergeRequest success ::API::Entities::MergeRequest
end end
params do params do
optional :merge_commit_message, type: String, desc: 'Custom merge commit message' optional :merge_commit_message, type: String, desc: 'Custom merge commit message'
@ -209,11 +209,11 @@ module API
.execute(merge_request) .execute(merge_request)
end end
present merge_request, with: Entities::MergeRequest, current_user: current_user, project: user_project present merge_request, with: ::API::Entities::MergeRequest, current_user: current_user, project: user_project
end end
desc 'Cancel merge if "Merge When Pipeline Succeeds" is enabled' do desc 'Cancel merge if "Merge When Pipeline Succeeds" is enabled' do
success Entities::MergeRequest success ::API::Entities::MergeRequest
end end
post "#{path}/cancel_merge_when_build_succeeds" do post "#{path}/cancel_merge_when_build_succeeds" do
merge_request = find_project_merge_request(params[:merge_request_id]) merge_request = find_project_merge_request(params[:merge_request_id])
@ -227,19 +227,19 @@ module API
desc 'Get the comments of a merge request' do desc 'Get the comments of a merge request' do
detail 'Duplicate. DEPRECATED and HAS BEEN REMOVED in V4' detail 'Duplicate. DEPRECATED and HAS BEEN REMOVED in V4'
success Entities::MRNote success ::API::Entities::MRNote
end end
params do params do
use :pagination use :pagination
end end
get "#{path}/comments" do get "#{path}/comments" do
merge_request = find_merge_request_with_access(params[:merge_request_id]) merge_request = find_merge_request_with_access(params[:merge_request_id])
present paginate(merge_request.notes.fresh), with: Entities::MRNote present paginate(merge_request.notes.fresh), with: ::API::Entities::MRNote
end end
desc 'Post a comment to a merge request' do desc 'Post a comment to a merge request' do
detail 'Duplicate. DEPRECATED and HAS BEEN REMOVED in V4' detail 'Duplicate. DEPRECATED and HAS BEEN REMOVED in V4'
success Entities::MRNote success ::API::Entities::MRNote
end end
params do params do
requires :note, type: String, desc: 'The text of the comment' requires :note, type: String, desc: 'The text of the comment'
@ -256,14 +256,14 @@ module API
note = ::Notes::CreateService.new(user_project, current_user, opts).execute note = ::Notes::CreateService.new(user_project, current_user, opts).execute
if note.save if note.save
present note, with: Entities::MRNote present note, with: ::API::Entities::MRNote
else else
render_api_error!("Failed to save note #{note.errors.messages}", 400) render_api_error!("Failed to save note #{note.errors.messages}", 400)
end end
end end
desc 'List issues that will be closed on merge' do desc 'List issues that will be closed on merge' do
success Entities::MRNote success ::API::Entities::MRNote
end end
params do params do
use :pagination use :pagination

View file

@ -0,0 +1,135 @@
module API
module V3
class ProjectSnippets < Grape::API
include PaginationParams
before { authenticate! }
params do
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects do
helpers do
def handle_project_member_errors(errors)
if errors[:project_access].any?
error!(errors[:project_access], 422)
end
not_found!
end
def snippets_for_current_user
finder_params = { filter: :by_project, project: user_project }
SnippetsFinder.new.execute(current_user, finder_params)
end
end
desc 'Get all project snippets' do
success ::API::V3::Entities::ProjectSnippet
end
params do
use :pagination
end
get ":id/snippets" do
present paginate(snippets_for_current_user), with: ::API::V3::Entities::ProjectSnippet
end
desc 'Get a single project snippet' do
success ::API::V3::Entities::ProjectSnippet
end
params do
requires :snippet_id, type: Integer, desc: 'The ID of a project snippet'
end
get ":id/snippets/:snippet_id" do
snippet = snippets_for_current_user.find(params[:snippet_id])
present snippet, with: ::API::V3::Entities::ProjectSnippet
end
desc 'Create a new project snippet' do
success ::API::V3::Entities::ProjectSnippet
end
params do
requires :title, type: String, desc: 'The title of the snippet'
requires :file_name, type: String, desc: 'The file name of the snippet'
requires :code, type: String, desc: 'The content of the snippet'
requires :visibility_level, type: Integer,
values: [Gitlab::VisibilityLevel::PRIVATE,
Gitlab::VisibilityLevel::INTERNAL,
Gitlab::VisibilityLevel::PUBLIC],
desc: 'The visibility level of the snippet'
end
post ":id/snippets" do
authorize! :create_project_snippet, user_project
snippet_params = declared_params.merge(request: request, api: true)
snippet_params[:content] = snippet_params.delete(:code)
snippet = CreateSnippetService.new(user_project, current_user, snippet_params).execute
if snippet.persisted?
present snippet, with: ::API::V3::Entities::ProjectSnippet
else
render_validation_error!(snippet)
end
end
desc 'Update an existing project snippet' do
success ::API::V3::Entities::ProjectSnippet
end
params do
requires :snippet_id, type: Integer, desc: 'The ID of a project snippet'
optional :title, type: String, desc: 'The title of the snippet'
optional :file_name, type: String, desc: 'The file name of the snippet'
optional :code, type: String, desc: 'The content of the snippet'
optional :visibility_level, type: Integer,
values: [Gitlab::VisibilityLevel::PRIVATE,
Gitlab::VisibilityLevel::INTERNAL,
Gitlab::VisibilityLevel::PUBLIC],
desc: 'The visibility level of the snippet'
at_least_one_of :title, :file_name, :code, :visibility_level
end
put ":id/snippets/:snippet_id" do
snippet = snippets_for_current_user.find_by(id: params.delete(:snippet_id))
not_found!('Snippet') unless snippet
authorize! :update_project_snippet, snippet
snippet_params = declared_params(include_missing: false)
snippet_params[:content] = snippet_params.delete(:code) if snippet_params[:code].present?
UpdateSnippetService.new(user_project, current_user, snippet,
snippet_params).execute
if snippet.persisted?
present snippet, with: ::API::V3::Entities::ProjectSnippet
else
render_validation_error!(snippet)
end
end
desc 'Delete a project snippet'
params do
requires :snippet_id, type: Integer, desc: 'The ID of a project snippet'
end
delete ":id/snippets/:snippet_id" do
snippet = snippets_for_current_user.find_by(id: params[:snippet_id])
not_found!('Snippet') unless snippet
authorize! :admin_project_snippet, snippet
snippet.destroy
end
desc 'Get a raw project snippet'
params do
requires :snippet_id, type: Integer, desc: 'The ID of a project snippet'
end
get ":id/snippets/:snippet_id/raw" do
snippet = snippets_for_current_user.find_by(id: params[:snippet_id])
not_found!('Snippet') unless snippet
env['api.format'] = :txt
content_type 'text/plain'
present snippet.content
end
end
end
end
end

View file

@ -74,32 +74,32 @@ module API
def present_projects(projects, options = {}) def present_projects(projects, options = {})
options = options.reverse_merge( options = options.reverse_merge(
with: Entities::Project, with: ::API::Entities::Project,
current_user: current_user, current_user: current_user,
simple: params[:simple], simple: params[:simple],
) )
projects = filter_projects(projects) projects = filter_projects(projects)
projects = projects.with_statistics if options[:statistics] projects = projects.with_statistics if options[:statistics]
options[:with] = Entities::BasicProjectDetails if options[:simple] options[:with] = ::API::Entities::BasicProjectDetails if options[:simple]
present paginate(projects), options present paginate(projects), options
end end
end end
desc 'Get a list of visible projects for authenticated user' do desc 'Get a list of visible projects for authenticated user' do
success Entities::BasicProjectDetails success ::API::Entities::BasicProjectDetails
end end
params do params do
use :collection_params use :collection_params
end end
get '/visible' do get '/visible' do
entity = current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails entity = current_user ? ::API::Entities::ProjectWithAccess : ::API::Entities::BasicProjectDetails
present_projects ProjectsFinder.new.execute(current_user), with: entity present_projects ProjectsFinder.new.execute(current_user), with: entity
end end
desc 'Get a projects list for authenticated user' do desc 'Get a projects list for authenticated user' do
success Entities::BasicProjectDetails success ::API::Entities::BasicProjectDetails
end end
params do params do
use :collection_params use :collection_params
@ -108,11 +108,11 @@ module API
authenticate! authenticate!
present_projects current_user.authorized_projects, present_projects current_user.authorized_projects,
with: Entities::ProjectWithAccess with: ::API::Entities::ProjectWithAccess
end end
desc 'Get an owned projects list for authenticated user' do desc 'Get an owned projects list for authenticated user' do
success Entities::BasicProjectDetails success ::API::Entities::BasicProjectDetails
end end
params do params do
use :collection_params use :collection_params
@ -122,12 +122,12 @@ module API
authenticate! authenticate!
present_projects current_user.owned_projects, present_projects current_user.owned_projects,
with: Entities::ProjectWithAccess, with: ::API::Entities::ProjectWithAccess,
statistics: params[:statistics] statistics: params[:statistics]
end end
desc 'Gets starred project for the authenticated user' do desc 'Gets starred project for the authenticated user' do
success Entities::BasicProjectDetails success ::API::Entities::BasicProjectDetails
end end
params do params do
use :collection_params use :collection_params
@ -139,7 +139,7 @@ module API
end end
desc 'Get all projects for admin user' do desc 'Get all projects for admin user' do
success Entities::BasicProjectDetails success ::API::Entities::BasicProjectDetails
end end
params do params do
use :collection_params use :collection_params
@ -148,11 +148,11 @@ module API
get '/all' do get '/all' do
authenticated_as_admin! authenticated_as_admin!
present_projects Project.all, with: Entities::ProjectWithAccess, statistics: params[:statistics] present_projects Project.all, with: ::API::Entities::ProjectWithAccess, statistics: params[:statistics]
end end
desc 'Search for projects the current user has access to' do desc 'Search for projects the current user has access to' do
success Entities::Project success ::API::Entities::Project
end end
params do params do
requires :query, type: String, desc: 'The project name to be searched' requires :query, type: String, desc: 'The project name to be searched'
@ -164,11 +164,11 @@ module API
projects = search_service.objects('projects', params[:page]) projects = search_service.objects('projects', params[:page])
projects = projects.reorder(params[:order_by] => params[:sort]) projects = projects.reorder(params[:order_by] => params[:sort])
present paginate(projects), with: Entities::Project present paginate(projects), with: ::API::Entities::Project
end end
desc 'Create new project' do desc 'Create new project' do
success Entities::Project success ::API::Entities::Project
end end
params do params do
requires :name, type: String, desc: 'The name of the project' requires :name, type: String, desc: 'The name of the project'
@ -181,7 +181,7 @@ module API
project = ::Projects::CreateService.new(current_user, attrs).execute project = ::Projects::CreateService.new(current_user, attrs).execute
if project.saved? if project.saved?
present project, with: Entities::Project, present project, with: ::API::Entities::Project,
user_can_admin_project: can?(current_user, :admin_project, project) user_can_admin_project: can?(current_user, :admin_project, project)
else else
if project.errors[:limit_reached].present? if project.errors[:limit_reached].present?
@ -192,7 +192,7 @@ module API
end end
desc 'Create new project for a specified user. Only available to admin users.' do desc 'Create new project for a specified user. Only available to admin users.' do
success Entities::Project success ::API::Entities::Project
end end
params do params do
requires :name, type: String, desc: 'The name of the project' requires :name, type: String, desc: 'The name of the project'
@ -210,7 +210,7 @@ module API
project = ::Projects::CreateService.new(user, attrs).execute project = ::Projects::CreateService.new(user, attrs).execute
if project.saved? if project.saved?
present project, with: Entities::Project, present project, with: ::API::Entities::Project,
user_can_admin_project: can?(current_user, :admin_project, project) user_can_admin_project: can?(current_user, :admin_project, project)
else else
render_validation_error!(project) render_validation_error!(project)
@ -223,26 +223,26 @@ module API
end end
resource :projects, requirements: { id: /[^\/]+/ } do resource :projects, requirements: { id: /[^\/]+/ } do
desc 'Get a single project' do desc 'Get a single project' do
success Entities::ProjectWithAccess success ::API::Entities::ProjectWithAccess
end end
get ":id" do get ":id" do
entity = current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails entity = current_user ? ::API::Entities::ProjectWithAccess : ::API::Entities::BasicProjectDetails
present user_project, with: entity, current_user: current_user, present user_project, with: entity, current_user: current_user,
user_can_admin_project: can?(current_user, :admin_project, user_project) user_can_admin_project: can?(current_user, :admin_project, user_project)
end end
desc 'Get events for a single project' do desc 'Get events for a single project' do
success Entities::Event success ::API::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: Entities::Event present paginate(user_project.events.recent), with: ::API::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
success Entities::Project success ::API::Entities::Project
end end
params do params do
optional :namespace, type: String, desc: 'The ID or name of the namespace that the project will be forked into' optional :namespace, type: String, desc: 'The ID or name of the namespace that the project will be forked into'
@ -268,13 +268,13 @@ module API
if forked_project.errors.any? if forked_project.errors.any?
conflict!(forked_project.errors.messages) conflict!(forked_project.errors.messages)
else else
present forked_project, with: Entities::Project, present forked_project, with: ::API::Entities::Project,
user_can_admin_project: can?(current_user, :admin_project, forked_project) user_can_admin_project: can?(current_user, :admin_project, forked_project)
end end
end end
desc 'Update an existing project' do desc 'Update an existing project' do
success Entities::Project success ::API::Entities::Project
end end
params do params do
optional :name, type: String, desc: 'The name of the project' optional :name, type: String, desc: 'The name of the project'
@ -298,7 +298,7 @@ module API
result = ::Projects::UpdateService.new(user_project, current_user, attrs).execute result = ::Projects::UpdateService.new(user_project, current_user, attrs).execute
if result[:status] == :success if result[:status] == :success
present user_project, with: Entities::Project, present user_project, with: ::API::Entities::Project,
user_can_admin_project: can?(current_user, :admin_project, user_project) user_can_admin_project: can?(current_user, :admin_project, user_project)
else else
render_validation_error!(user_project) render_validation_error!(user_project)
@ -306,29 +306,29 @@ module API
end end
desc 'Archive a project' do desc 'Archive a project' do
success Entities::Project success ::API::Entities::Project
end end
post ':id/archive' do post ':id/archive' do
authorize!(:archive_project, user_project) authorize!(:archive_project, user_project)
user_project.archive! user_project.archive!
present user_project, with: Entities::Project present user_project, with: ::API::Entities::Project
end end
desc 'Unarchive a project' do desc 'Unarchive a project' do
success Entities::Project success ::API::Entities::Project
end end
post ':id/unarchive' do post ':id/unarchive' do
authorize!(:archive_project, user_project) authorize!(:archive_project, user_project)
user_project.unarchive! user_project.unarchive!
present user_project, with: Entities::Project present user_project, with: ::API::Entities::Project
end end
desc 'Star a project' do desc 'Star a project' do
success Entities::Project success ::API::Entities::Project
end end
post ':id/star' do post ':id/star' do
if current_user.starred?(user_project) if current_user.starred?(user_project)
@ -337,19 +337,19 @@ module API
current_user.toggle_star(user_project) current_user.toggle_star(user_project)
user_project.reload user_project.reload
present user_project, with: Entities::Project present user_project, with: ::API::Entities::Project
end end
end end
desc 'Unstar a project' do desc 'Unstar a project' do
success Entities::Project success ::API::Entities::Project
end end
delete ':id/star' do delete ':id/star' do
if current_user.starred?(user_project) if current_user.starred?(user_project)
current_user.toggle_star(user_project) current_user.toggle_star(user_project)
user_project.reload user_project.reload
present user_project, with: Entities::Project present user_project, with: ::API::Entities::Project
else else
not_modified! not_modified!
end end
@ -390,7 +390,7 @@ module API
end end
desc 'Share the project with a group' do desc 'Share the project with a group' do
success Entities::ProjectGroupLink success ::API::Entities::ProjectGroupLink
end end
params do params do
requires :group_id, type: Integer, desc: 'The ID of a group' requires :group_id, type: Integer, desc: 'The ID of a group'
@ -412,7 +412,7 @@ module API
link = user_project.project_group_links.new(declared_params(include_missing: false)) link = user_project.project_group_links.new(declared_params(include_missing: false))
if link.save if link.save
present link, with: Entities::ProjectGroupLink present link, with: ::API::Entities::ProjectGroupLink
else else
render_api_error!(link.errors.full_messages.first, 409) render_api_error!(link.errors.full_messages.first, 409)
end end
@ -440,7 +440,7 @@ module API
end end
desc 'Get the users list of a project' do desc 'Get the users list of a project' do
success Entities::UserBasic success ::API::Entities::UserBasic
end end
params do params do
optional :search, type: String, desc: 'Return list of users matching the search criteria' optional :search, type: String, desc: 'Return list of users matching the search criteria'
@ -450,7 +450,7 @@ module API
users = user_project.team.users users = user_project.team.users
users = users.search(params[:search]) if params[:search].present? users = users.search(params[:search]) if params[:search].present?
present paginate(users), with: Entities::UserBasic present paginate(users), with: ::API::Entities::UserBasic
end end
end end
end end

View file

@ -7,18 +7,6 @@ describe API::ProjectSnippets, api: true do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:admin) { create(:admin) } let(:admin) { create(:admin) }
describe 'GET /projects/:project_id/snippets/:id' do
# TODO (rspeicher): Deprecated; remove in 9.0
it 'always exposes expires_at as nil' do
snippet = create(:project_snippet, author: admin)
get api("/projects/#{snippet.project.id}/snippets/#{snippet.id}", admin)
expect(json_response).to have_key('expires_at')
expect(json_response['expires_at']).to be_nil
end
end
describe 'GET /projects/:project_id/snippets/' do describe 'GET /projects/:project_id/snippets/' do
let(:user) { create(:user) } let(:user) { create(:user) }

View file

@ -0,0 +1,188 @@
require 'rails_helper'
describe API::ProjectSnippets, api: true do
include ApiHelpers
let(:project) { create(:empty_project, :public) }
let(:user) { create(:user) }
let(:admin) { create(:admin) }
describe 'GET /projects/:project_id/snippets/:id' do
# TODO (rspeicher): Deprecated; remove in 9.0
it 'always exposes expires_at as nil' do
snippet = create(:project_snippet, author: admin)
get v3_api("/projects/#{snippet.project.id}/snippets/#{snippet.id}", admin)
expect(json_response).to have_key('expires_at')
expect(json_response['expires_at']).to be_nil
end
end
describe 'GET /projects/:project_id/snippets/' do
let(:user) { create(:user) }
it 'returns all snippets available to team member' do
project.add_developer(user)
public_snippet = create(:project_snippet, :public, project: project)
internal_snippet = create(:project_snippet, :internal, project: project)
private_snippet = create(:project_snippet, :private, project: project)
get v3_api("/projects/#{project.id}/snippets/", user)
expect(response).to have_http_status(200)
expect(json_response.size).to eq(3)
expect(json_response.map{ |snippet| snippet['id']} ).to include(public_snippet.id, internal_snippet.id, private_snippet.id)
expect(json_response.last).to have_key('web_url')
end
it 'hides private snippets from regular user' do
create(:project_snippet, :private, project: project)
get v3_api("/projects/#{project.id}/snippets/", user)
expect(response).to have_http_status(200)
expect(json_response.size).to eq(0)
end
end
describe 'POST /projects/:project_id/snippets/' do
let(:params) do
{
title: 'Test Title',
file_name: 'test.rb',
code: 'puts "hello world"',
visibility_level: Snippet::PUBLIC
}
end
it 'creates a new snippet' do
post v3_api("/projects/#{project.id}/snippets/", admin), params
expect(response).to have_http_status(201)
snippet = ProjectSnippet.find(json_response['id'])
expect(snippet.content).to eq(params[:code])
expect(snippet.title).to eq(params[:title])
expect(snippet.file_name).to eq(params[:file_name])
expect(snippet.visibility_level).to eq(params[:visibility_level])
end
it 'returns 400 for missing parameters' do
params.delete(:title)
post v3_api("/projects/#{project.id}/snippets/", admin), params
expect(response).to have_http_status(400)
end
context 'when the snippet is spam' do
def create_snippet(project, snippet_params = {})
project.add_developer(user)
post v3_api("/projects/#{project.id}/snippets", user), params.merge(snippet_params)
end
before do
allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true)
end
context 'when the project is private' do
let(:private_project) { create(:project_empty_repo, :private) }
context 'when the snippet is public' do
it 'creates the snippet' do
expect { create_snippet(private_project, visibility_level: Snippet::PUBLIC) }.
to change { Snippet.count }.by(1)
end
end
end
context 'when the project is public' do
context 'when the snippet is private' do
it 'creates the snippet' do
expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }.
to change { Snippet.count }.by(1)
end
end
context 'when the snippet is public' do
it 'rejects the shippet' do
expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }.
not_to change { Snippet.count }
expect(response).to have_http_status(400)
end
it 'creates a spam log' do
expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }.
to change { SpamLog.count }.by(1)
end
end
end
end
end
describe 'PUT /projects/:project_id/snippets/:id/' do
let(:snippet) { create(:project_snippet, author: admin) }
it 'updates snippet' do
new_content = 'New content'
put v3_api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/", admin), code: new_content
expect(response).to have_http_status(200)
snippet.reload
expect(snippet.content).to eq(new_content)
end
it 'returns 404 for invalid snippet id' do
put v3_api("/projects/#{snippet.project.id}/snippets/1234", admin), title: 'foo'
expect(response).to have_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
it 'returns 400 for missing parameters' do
put v3_api("/projects/#{project.id}/snippets/1234", admin)
expect(response).to have_http_status(400)
end
end
describe 'DELETE /projects/:project_id/snippets/:id/' do
let(:snippet) { create(:project_snippet, author: admin) }
it 'deletes snippet' do
admin = create(:admin)
snippet = create(:project_snippet, author: admin)
delete v3_api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/", admin)
expect(response).to have_http_status(200)
end
it 'returns 404 for invalid snippet id' do
delete v3_api("/projects/#{snippet.project.id}/snippets/1234", admin)
expect(response).to have_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
end
describe 'GET /projects/:project_id/snippets/:id/raw' do
let(:snippet) { create(:project_snippet, author: admin) }
it 'returns raw text' do
get v3_api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/raw", admin)
expect(response).to have_http_status(200)
expect(response.content_type).to eq 'text/plain'
expect(response.body).to eq(snippet.content)
end
it 'returns 404 for invalid snippet id' do
delete v3_api("/projects/#{snippet.project.id}/snippets/1234", admin)
expect(response).to have_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
end
end