Commit a2108973 authored by Stan Hu's avatar Stan Hu Committed by Mayra Cabrera

Fix project creation with templates using /projects/user/:id API

Previously creation with an instance or group template with POST
`/api/v4/projects worked`, but `/api/v4/projects/user/:id` did not
because the latter did not accept the `use_custom_templates` parameter
due to an oversight.

This commit fixes this by adding the `optional_create_project_params`
Grape API and add tests for project creation via the user endpoint.

Closes https://gitlab.com/gitlab-org/gitlab/issues/37004
parent 3fe00c56
---
title: Fix project creation with templates using /projects/user/:id API
merge_request: 20590
author:
type: fixed
...@@ -182,7 +182,11 @@ describe API::Projects do ...@@ -182,7 +182,11 @@ describe API::Projects do
end end
end end
describe 'POST /projects' do # Assumes the following variables are defined:
# group
# project
# new_project_name
# api_call
shared_examples 'creates projects with templates' do shared_examples 'creates projects with templates' do
before do before do
group.add_maintainer(user) group.add_maintainer(user)
...@@ -194,8 +198,7 @@ describe API::Projects do ...@@ -194,8 +198,7 @@ describe API::Projects do
expect(ProjectExportWorker).to receive(:perform_async).and_call_original expect(ProjectExportWorker).to receive(:perform_async).and_call_original
Sidekiq::Testing.fake! do Sidekiq::Testing.fake! do
expect { post api('/projects', user), params: project_params } expect { api_call }.to change { Project.count }.by(1)
.to change { Project.count }.by(1)
end end
expect(response).to have_gitlab_http_status(201) expect(response).to have_gitlab_http_status(201)
...@@ -208,8 +211,7 @@ describe API::Projects do ...@@ -208,8 +211,7 @@ describe API::Projects do
project_params.delete(:template_project_id) project_params.delete(:template_project_id)
project_params[:template_name] = 'bogus-template' project_params[:template_name] = 'bogus-template'
expect { post api('/projects', user), params: project_params } expect { api_call }.not_to change { Project.count }
.not_to change { Project.count }
expect(response).to have_gitlab_http_status(400) expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['template_name']).to eq(["'bogus-template' is unknown or invalid"]) expect(json_response['message']['template_name']).to eq(["'bogus-template' is unknown or invalid"])
...@@ -220,20 +222,22 @@ describe API::Projects do ...@@ -220,20 +222,22 @@ describe API::Projects do
new_project = create(:project) new_project = create(:project)
project_params[:template_project_id] = new_project.id project_params[:template_project_id] = new_project.id
expect { post api('/projects', user), params: project_params } expect { api_call }.not_to change { Project.count }
.not_to change { Project.count }
expect(response).to have_gitlab_http_status(400) expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['template_project_id']).to eq(["#{new_project.id} is unknown or invalid"]) expect(json_response['message']['template_project_id']).to eq(["#{new_project.id} is unknown or invalid"])
end end
end end
context 'with instance-level templates' do shared_context 'base instance template models' do
let(:group) { create(:group) } let(:group) { create(:group) }
let!(:project) { create(:project, :public, namespace: group) } let!(:project) { create(:project, :public, namespace: group) }
let(:new_project_name) { "project-#{SecureRandom.hex}" } let(:new_project_name) { "project-#{SecureRandom.hex}" }
end
shared_context 'instance template name' do
include_context 'base instance template models'
context 'using template name' do
let(:project_params) do let(:project_params) do
{ {
template_name: project.name, template_name: project.name,
...@@ -243,11 +247,11 @@ describe API::Projects do ...@@ -243,11 +247,11 @@ describe API::Projects do
namespace_id: group.id namespace_id: group.id
} }
end end
it_behaves_like 'creates projects with templates'
end end
context 'using template project ID' do shared_context 'instance template ID' do
include_context 'base instance template models'
let(:project_params) do let(:project_params) do
{ {
template_project_id: project.id, template_project_id: project.id,
...@@ -257,19 +261,19 @@ describe API::Projects do ...@@ -257,19 +261,19 @@ describe API::Projects do
namespace_id: group.id namespace_id: group.id
} }
end end
it_behaves_like 'creates projects with templates'
end
end end
context 'with group templates' do shared_context 'base group template models' do
let(:parent_group) { create(:group) } let(:parent_group) { create(:group) }
let(:subgroup) { create(:group, :public, parent: parent_group) } let(:subgroup) { create(:group, :public, parent: parent_group) }
let(:group) { subgroup } let(:group) { subgroup }
let!(:project) { create(:project, :public, namespace: subgroup) } let!(:project) { create(:project, :public, namespace: subgroup) }
let(:new_project_name) { "project-#{SecureRandom.hex}" } let(:new_project_name) { "project-#{SecureRandom.hex}" }
end
shared_context 'group template name' do
include_context 'base group template models'
context 'using template name' do
let(:project_params) do let(:project_params) do
{ {
template_name: project.name, template_name: project.name,
...@@ -280,11 +284,11 @@ describe API::Projects do ...@@ -280,11 +284,11 @@ describe API::Projects do
namespace_id: subgroup.id namespace_id: subgroup.id
} }
end end
it_behaves_like 'creates projects with templates'
end end
context 'using template project ID' do shared_context 'group template ID' do
include_context 'base group template models'
let(:project_params) do let(:project_params) do
{ {
template_project_id: project.id, template_project_id: project.id,
...@@ -295,7 +299,48 @@ describe API::Projects do ...@@ -295,7 +299,48 @@ describe API::Projects do
namespace_id: subgroup.id namespace_id: subgroup.id
} }
end end
end
describe 'POST /projects/user/:id' do
let(:admin) { create(:admin) }
let(:api_call) { post api("/projects/user/#{user.id}", admin), params: project_params }
context 'with templates' do
include_context 'instance template name' do
it_behaves_like 'creates projects with templates'
end
include_context 'instance template ID' do
it_behaves_like 'creates projects with templates'
end
include_context 'group template name' do
it_behaves_like 'creates projects with templates'
end
include_context 'group template ID' do
it_behaves_like 'creates projects with templates'
end
end
end
describe 'POST /projects' do
let(:api_call) { post api('/projects', user), params: project_params }
context 'with templates' do
include_context 'instance template name' do
it_behaves_like 'creates projects with templates'
end
include_context 'instance template ID' do
it_behaves_like 'creates projects with templates'
end
include_context 'group template name' do
it_behaves_like 'creates projects with templates'
end
include_context 'group template ID' do
it_behaves_like 'creates projects with templates' it_behaves_like 'creates projects with templates'
end end
end end
......
...@@ -191,6 +191,7 @@ module API ...@@ -191,6 +191,7 @@ module API
optional :path, type: String, desc: 'The path of the repository' optional :path, type: String, desc: 'The path of the repository'
optional :default_branch, type: String, desc: 'The default branch of the project' optional :default_branch, type: String, desc: 'The default branch of the project'
use :optional_project_params use :optional_project_params
use :optional_create_project_params
use :create_params use :create_params
end end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment