From c2102e6e3bf4fa5220d5fa4d3a4c1549f7385162 Mon Sep 17 00:00:00 2001
From: Oswaldo Ferreira <oswaldo@gitlab.com>
Date: Thu, 2 Feb 2017 15:57:34 -0200
Subject: [PATCH] Move /projects/fork/:id to /projects/:id/fork

---
 .../unreleased/14492-change-fork-endpoint.yml |   4 +
 doc/api/projects.md                           |   2 +-
 doc/api/v3_to_v4.md                           |   1 +
 lib/api/projects.rb                           |   2 +-
 spec/requests/api/fork_spec.rb                | 134 ------------------
 spec/requests/api/projects_spec.rb            | 126 ++++++++++++++++
 6 files changed, 133 insertions(+), 136 deletions(-)
 create mode 100644 changelogs/unreleased/14492-change-fork-endpoint.yml
 delete mode 100644 spec/requests/api/fork_spec.rb

diff --git a/changelogs/unreleased/14492-change-fork-endpoint.yml b/changelogs/unreleased/14492-change-fork-endpoint.yml
new file mode 100644
index 00000000000..39024b51b54
--- /dev/null
+++ b/changelogs/unreleased/14492-change-fork-endpoint.yml
@@ -0,0 +1,4 @@
+---
+title: Move /projects/fork/:id to /projects/:id/fork
+merge_request: 8940
+author:
diff --git a/doc/api/projects.md b/doc/api/projects.md
index bad238f57d7..e579b89d836 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -705,7 +705,7 @@ Parameters:
 Forks a project into the user namespace of the authenticated user or the one provided.
 
 ```
-POST /projects/fork/:id
+POST /projects/:id/fork
 ```
 
 Parameters:
diff --git a/doc/api/v3_to_v4.md b/doc/api/v3_to_v4.md
index 0ae07b5d3de..7811025f34e 100644
--- a/doc/api/v3_to_v4.md
+++ b/doc/api/v3_to_v4.md
@@ -22,4 +22,5 @@ changes are in V4:
   - `/gitignores/:key`
   - `/gitlab_ci_ymls/:key`
   - `/dockerfiles/:key`
+- Moved `/projects/fork/:id` to `/projects/:id/fork`
 
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index bd4b23195ac..2cacb246db8 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -220,7 +220,7 @@ module API
       params do
         optional :namespace, type: String, desc: 'The ID or name of the namespace that the project will be forked into'
       end
-      post 'fork/:id' do
+      post ':id/fork' do
         fork_params = declared_params(include_missing: false)
         namespace_id = fork_params[:namespace]
 
diff --git a/spec/requests/api/fork_spec.rb b/spec/requests/api/fork_spec.rb
deleted file mode 100644
index 92ac4fd334d..00000000000
--- a/spec/requests/api/fork_spec.rb
+++ /dev/null
@@ -1,134 +0,0 @@
-require 'spec_helper'
-
-describe API::Projects, api: true  do
-  include ApiHelpers
-  let(:user)  { create(:user) }
-  let(:user2) { create(:user) }
-  let(:admin) { create(:admin) }
-  let(:group) { create(:group) }
-  let(:group2) do
-    group = create(:group, name: 'group2_name')
-    group.add_owner(user2)
-    group
-  end
-
-  describe 'POST /projects/fork/:id' do
-    let(:project) do
-      create(:project, :repository, creator: user, namespace: user.namespace)
-    end
-
-    before do
-      project.add_reporter(user2)
-    end
-
-    context 'when authenticated' do
-      it 'forks if user has sufficient access to project' do
-        post api("/projects/fork/#{project.id}", user2)
-
-        expect(response).to have_http_status(201)
-        expect(json_response['name']).to eq(project.name)
-        expect(json_response['path']).to eq(project.path)
-        expect(json_response['owner']['id']).to eq(user2.id)
-        expect(json_response['namespace']['id']).to eq(user2.namespace.id)
-        expect(json_response['forked_from_project']['id']).to eq(project.id)
-      end
-
-      it 'forks if user is admin' do
-        post api("/projects/fork/#{project.id}", admin)
-
-        expect(response).to have_http_status(201)
-        expect(json_response['name']).to eq(project.name)
-        expect(json_response['path']).to eq(project.path)
-        expect(json_response['owner']['id']).to eq(admin.id)
-        expect(json_response['namespace']['id']).to eq(admin.namespace.id)
-        expect(json_response['forked_from_project']['id']).to eq(project.id)
-      end
-
-      it 'fails on missing project access for the project to fork' do
-        new_user = create(:user)
-        post api("/projects/fork/#{project.id}", new_user)
-
-        expect(response).to have_http_status(404)
-        expect(json_response['message']).to eq('404 Project Not Found')
-      end
-
-      it 'fails if forked project exists in the user namespace' do
-        post api("/projects/fork/#{project.id}", user)
-
-        expect(response).to have_http_status(409)
-        expect(json_response['message']['name']).to eq(['has already been taken'])
-        expect(json_response['message']['path']).to eq(['has already been taken'])
-      end
-
-      it 'fails if project to fork from does not exist' do
-        post api('/projects/fork/424242', user)
-
-        expect(response).to have_http_status(404)
-        expect(json_response['message']).to eq('404 Project Not Found')
-      end
-
-      it 'forks with explicit own user namespace id' do
-        post api("/projects/fork/#{project.id}", user2), namespace: user2.namespace.id
-
-        expect(response).to have_http_status(201)
-        expect(json_response['owner']['id']).to eq(user2.id)
-      end
-
-      it 'forks with explicit own user name as namespace' do
-        post api("/projects/fork/#{project.id}", user2), namespace: user2.username
-
-        expect(response).to have_http_status(201)
-        expect(json_response['owner']['id']).to eq(user2.id)
-      end
-
-      it 'forks to another user when admin' do
-        post api("/projects/fork/#{project.id}", admin), namespace: user2.username
-
-        expect(response).to have_http_status(201)
-        expect(json_response['owner']['id']).to eq(user2.id)
-      end
-
-      it 'fails if trying to fork to another user when not admin' do
-        post api("/projects/fork/#{project.id}", user2), namespace: admin.namespace.id
-
-        expect(response).to have_http_status(404)
-      end
-
-      it 'fails if trying to fork to non-existent namespace' do
-        post api("/projects/fork/#{project.id}", user2), namespace: 42424242
-
-        expect(response).to have_http_status(404)
-        expect(json_response['message']).to eq('404 Target Namespace Not Found')
-      end
-
-      it 'forks to owned group' do
-        post api("/projects/fork/#{project.id}", user2), namespace: group2.name
-
-        expect(response).to have_http_status(201)
-        expect(json_response['namespace']['name']).to eq(group2.name)
-      end
-
-      it 'fails to fork to not owned group' do
-        post api("/projects/fork/#{project.id}", user2), namespace: group.name
-
-        expect(response).to have_http_status(404)
-      end
-
-      it 'forks to not owned group when admin' do
-        post api("/projects/fork/#{project.id}", admin), namespace: group.name
-
-        expect(response).to have_http_status(201)
-        expect(json_response['namespace']['name']).to eq(group.name)
-      end
-    end
-
-    context 'when unauthenticated' do
-      it 'returns authentication error' do
-        post api("/projects/fork/#{project.id}")
-
-        expect(response).to have_http_status(401)
-        expect(json_response['message']).to eq('401 Unauthorized')
-      end
-    end
-  end
-end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index ac0bbec44e0..17b5e372bdc 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -1332,4 +1332,130 @@ describe API::Projects, api: true  do
       end
     end
   end
+
+  describe 'POST /projects/:id/fork' do
+    let(:project) do
+      create(:project, :repository, creator: user, namespace: user.namespace)
+    end
+    let(:group) { create(:group) }
+    let(:group2) do
+      group = create(:group, name: 'group2_name')
+      group.add_owner(user2)
+      group
+    end
+
+    before do
+      project.add_reporter(user2)
+    end
+
+    context 'when authenticated' do
+      it 'forks if user has sufficient access to project' do
+        post api("/projects/#{project.id}/fork", user2)
+
+        expect(response).to have_http_status(201)
+        expect(json_response['name']).to eq(project.name)
+        expect(json_response['path']).to eq(project.path)
+        expect(json_response['owner']['id']).to eq(user2.id)
+        expect(json_response['namespace']['id']).to eq(user2.namespace.id)
+        expect(json_response['forked_from_project']['id']).to eq(project.id)
+      end
+
+      it 'forks if user is admin' do
+        post api("/projects/#{project.id}/fork", admin)
+
+        expect(response).to have_http_status(201)
+        expect(json_response['name']).to eq(project.name)
+        expect(json_response['path']).to eq(project.path)
+        expect(json_response['owner']['id']).to eq(admin.id)
+        expect(json_response['namespace']['id']).to eq(admin.namespace.id)
+        expect(json_response['forked_from_project']['id']).to eq(project.id)
+      end
+
+      it 'fails on missing project access for the project to fork' do
+        new_user = create(:user)
+        post api("/projects/#{project.id}/fork", new_user)
+
+        expect(response).to have_http_status(404)
+        expect(json_response['message']).to eq('404 Project Not Found')
+      end
+
+      it 'fails if forked project exists in the user namespace' do
+        post api("/projects/#{project.id}/fork", user)
+
+        expect(response).to have_http_status(409)
+        expect(json_response['message']['name']).to eq(['has already been taken'])
+        expect(json_response['message']['path']).to eq(['has already been taken'])
+      end
+
+      it 'fails if project to fork from does not exist' do
+        post api('/projects/424242/fork', user)
+
+        expect(response).to have_http_status(404)
+        expect(json_response['message']).to eq('404 Project Not Found')
+      end
+
+      it 'forks with explicit own user namespace id' do
+        post api("/projects/#{project.id}/fork", user2), namespace: user2.namespace.id
+
+        expect(response).to have_http_status(201)
+        expect(json_response['owner']['id']).to eq(user2.id)
+      end
+
+      it 'forks with explicit own user name as namespace' do
+        post api("/projects/#{project.id}/fork", user2), namespace: user2.username
+
+        expect(response).to have_http_status(201)
+        expect(json_response['owner']['id']).to eq(user2.id)
+      end
+
+      it 'forks to another user when admin' do
+        post api("/projects/#{project.id}/fork", admin), namespace: user2.username
+
+        expect(response).to have_http_status(201)
+        expect(json_response['owner']['id']).to eq(user2.id)
+      end
+
+      it 'fails if trying to fork to another user when not admin' do
+        post api("/projects/#{project.id}/fork", user2), namespace: admin.namespace.id
+
+        expect(response).to have_http_status(404)
+      end
+
+      it 'fails if trying to fork to non-existent namespace' do
+        post api("/projects/#{project.id}/fork", user2), namespace: 42424242
+
+        expect(response).to have_http_status(404)
+        expect(json_response['message']).to eq('404 Target Namespace Not Found')
+      end
+
+      it 'forks to owned group' do
+        post api("/projects/#{project.id}/fork", user2), namespace: group2.name
+
+        expect(response).to have_http_status(201)
+        expect(json_response['namespace']['name']).to eq(group2.name)
+      end
+
+      it 'fails to fork to not owned group' do
+        post api("/projects/#{project.id}/fork", user2), namespace: group.name
+
+        expect(response).to have_http_status(404)
+      end
+
+      it 'forks to not owned group when admin' do
+        post api("/projects/#{project.id}/fork", admin), namespace: group.name
+
+        expect(response).to have_http_status(201)
+        expect(json_response['namespace']['name']).to eq(group.name)
+      end
+    end
+
+    context 'when unauthenticated' do
+      it 'returns authentication error' do
+        post api("/projects/#{project.id}/fork")
+
+        expect(response).to have_http_status(401)
+        expect(json_response['message']).to eq('401 Unauthorized')
+      end
+    end
+  end
 end
-- 
GitLab