--- /dev/null
+All methods require admin authorization.\r
+\r
+## List system hooks\r
+\r
+Get list of system hooks\r
+\r
+```\r
+GET /hooks\r
+```\r
+\r
+Will return hooks with status `200 OK` on success, or `404 Not found` on fail.\r
+\r
+## Add new system hook hook\r
+\r
+```\r
+POST /hooks\r
+```\r
+\r
+Parameters:\r
+\r
++ `url` (required) - The hook URL\r
+\r
+Will return status `201 Created` on success, or `404 Not found` on fail.\r
+\r
+## Test system hook\r
+\r
+```\r
+GET /hooks/:id\r
+```\r
+\r
+Parameters:\r
+\r
++ `id` (required) - The ID of hook\r
+\r
+Will return hook with status `200 OK` on success, or `404 Not found` on fail.\r
+\r
+## Delete system hook\r
+\r
+```\r
+DELETE /hooks/:id\r
+```\r
+\r
+Parameters:\r
+\r
++ `id` (required) - The ID of hook\r
+\r
+Will return status `200 OK` on success, or `404 Not found` on fail.
\ No newline at end of file
--- /dev/null
+module Gitlab\r
+ # Hooks API\r
+ class SystemHooks < Grape::API\r
+ before { authenticated_as_admin! }\r
+\r
+ resource :hooks do\r
+ # Get the list of system hooks\r
+ #\r
+ # Example Request:\r
+ # GET /hooks\r
+ get do\r
+ @hooks = SystemHook.all\r
+ present @hooks, with: Entities::Hook\r
+ end\r
+\r
+ # Create new system hook\r
+ #\r
+ # Parameters:\r
+ # url (required) - url for system hook\r
+ # Example Request\r
+ # POST /hooks\r
+ post do\r
+ attrs = attributes_for_keys [:url]\r
+ @hook = SystemHook.new attrs\r
+ if @hook.save\r
+ present @hook, with: Entities::Hook\r
+ else\r
+ not_found!\r
+ end\r
+ end\r
+\r
+ # Test a hook\r
+ #\r
+ # Example Request\r
+ # GET /hooks/:id\r
+ get ":id" do\r
+ @hook = SystemHook.find(params[:id])\r
+ data = {\r
+ event_name: "project_create",\r
+ name: "Ruby",\r
+ path: "ruby",\r
+ project_id: 1,\r
+ owner_name: "Someone",\r
+ owner_email: "example@gitlabhq.com"\r
+ }\r
+ @hook.execute(data)\r
+ data\r
+ end\r
+\r
+ # Delete a hook\r
+ #\r
+ # Example Request:\r
+ # DELETE /hooks/:id\r
+ delete ":id" do\r
+ @hook = SystemHook.find(params[:id])\r
+ @hook.destroy\r
+ end\r
+ end\r
+ end\r
+end
\ No newline at end of file
--- /dev/null
+require 'spec_helper'\r
+\r
+describe Gitlab::API do\r
+ include ApiHelpers\r
+\r
+ let(:user) { create(:user) }\r
+ let(:admin) { create(:admin) }\r
+ let!(:hook) { create(:system_hook, url: "http://example.com") }\r
+\r
+ before { stub_request(:post, hook.url) }\r
+\r
+ describe "GET /hooks" do\r
+ context "when not an admin" do\r
+ it "should return forbidden error" do\r
+ get api("/hooks", user)\r
+ response.status.should == 403\r
+ end\r
+ end\r
+\r
+ context "when authenticated as admin" do\r
+ it "should return an array of hooks" do\r
+ get api("/hooks", admin)\r
+ response.status.should == 200\r
+ json_response.should be_an Array\r
+ json_response.first['url'].should == hook.url\r
+ end\r
+ end\r
+ end\r
+\r
+ describe "POST /hooks" do\r
+ it "should create new hook" do\r
+ expect {\r
+ post api("/hooks", admin), url: 'http://example.com'\r
+ }.to change { SystemHook.count }.by(1)\r
+ end\r
+\r
+ it "should respond with 404 on failure" do\r
+ post api("/hooks", admin)\r
+ response.status.should == 404\r
+ end\r
+\r
+ it "should not create new hook without url" do\r
+ expect {\r
+ post api("/hooks", admin)\r
+ }.to_not change { SystemHook.count }\r
+ end\r
+ end\r
+\r
+ describe "GET /hooks/:id" do\r
+ it "should return hook by id" do\r
+ get api("/hooks/#{hook.id}", admin)\r
+ response.status.should == 200\r
+ json_response['event_name'].should == 'project_create'\r
+ end\r
+\r
+ it "should return 404 on failure" do\r
+ get api("/hooks/404", admin)\r
+ response.status.should == 404\r
+ end\r
+ end\r
+\r
+ describe "DELETE /hooks/:id" do\r
+ it "should delete a hook" do\r
+ expect {\r
+ delete api("/hooks/#{hook.id}", admin)\r
+ }.to change { SystemHook.count }.by(-1)\r
+ end\r
+ end\r
+end
\ No newline at end of file