Commit b683a71aa1230f17f9df47661c77dfeae27027de
Exists in
master
and in
4 other branches
Merge pull request #1135 from NARKOZ/api
Issues API
Showing
9 changed files
with
406 additions
and
25 deletions
Show diff stats
app/views/help/api.html.haml
| 1 | %h3 API | 1 | %h3 API |
| 2 | .back_link | 2 | .back_link |
| 3 | - = link_to help_path do | 3 | + = link_to help_path do |
| 4 | ← to index | 4 | ← to index |
| 5 | %hr | 5 | %hr |
| 6 | 6 | ||
| 7 | %ol | 7 | %ol |
| 8 | - %li | 8 | + %li |
| 9 | %a{:href => "#README"} README | 9 | %a{:href => "#README"} README |
| 10 | - %li | 10 | + %li |
| 11 | %a{:href => "#projects"} Projects | 11 | %a{:href => "#projects"} Projects |
| 12 | - %li | 12 | + %li |
| 13 | %a{:href => "#users"} Users | 13 | %a{:href => "#users"} Users |
| 14 | + %li | ||
| 15 | + %a{:href => "#issues"} Issues | ||
| 14 | 16 | ||
| 15 | .file_holder#README | 17 | .file_holder#README |
| 16 | .file_title | 18 | .file_title |
| @@ -39,3 +41,13 @@ | @@ -39,3 +41,13 @@ | ||
| 39 | .file_content.wiki | 41 | .file_content.wiki |
| 40 | = preserve do | 42 | = preserve do |
| 41 | = markdown File.read(Rails.root.join("doc", "api", "users.md")) | 43 | = markdown File.read(Rails.root.join("doc", "api", "users.md")) |
| 44 | + | ||
| 45 | +%br | ||
| 46 | + | ||
| 47 | +.file_holder#issues | ||
| 48 | + .file_title | ||
| 49 | + %i.icon-file | ||
| 50 | + Issues | ||
| 51 | + .file_content.wiki | ||
| 52 | + = preserve do | ||
| 53 | + = markdown File.read(Rails.root.join("doc", "api", "issues.md")) |
doc/api/README.md
| @@ -27,3 +27,4 @@ The API uses JSON to serialize data. You don't need to specify `.json` at the en | @@ -27,3 +27,4 @@ The API uses JSON to serialize data. You don't need to specify `.json` at the en | ||
| 27 | 27 | ||
| 28 | + [Users](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/users.md) | 28 | + [Users](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/users.md) |
| 29 | + [Projects](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/projects.md) | 29 | + [Projects](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/projects.md) |
| 30 | ++ [Issues](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/issues.md) |
| @@ -0,0 +1,181 @@ | @@ -0,0 +1,181 @@ | ||
| 1 | +## List issues | ||
| 2 | + | ||
| 3 | +Get all issues created by authenticed user. | ||
| 4 | + | ||
| 5 | +``` | ||
| 6 | +GET /issues | ||
| 7 | +``` | ||
| 8 | + | ||
| 9 | +```json | ||
| 10 | +[ | ||
| 11 | + { | ||
| 12 | + "id": 43, | ||
| 13 | + "title": "4xx/5xx pages", | ||
| 14 | + "description": "", | ||
| 15 | + "labels": [ ], | ||
| 16 | + "milestone": null, | ||
| 17 | + "assignee": null, | ||
| 18 | + "author": { | ||
| 19 | + "id": 1, | ||
| 20 | + "email": "john@example.com", | ||
| 21 | + "name": "John Smith", | ||
| 22 | + "blocked": false, | ||
| 23 | + "created_at": "2012-05-23T08:00:58Z" | ||
| 24 | + }, | ||
| 25 | + "closed": true, | ||
| 26 | + "updated_at": "2012-07-02T17:53:12Z", | ||
| 27 | + "created_at": "2012-07-02T17:53:12Z" | ||
| 28 | + }, | ||
| 29 | + { | ||
| 30 | + "id": 42, | ||
| 31 | + "title": "Add user settings", | ||
| 32 | + "description": "", | ||
| 33 | + "labels": [ | ||
| 34 | + "feature" | ||
| 35 | + ], | ||
| 36 | + "milestone": { | ||
| 37 | + "id": 1, | ||
| 38 | + "title": "v1.0", | ||
| 39 | + "description": "", | ||
| 40 | + "due_date": "2012-07-20", | ||
| 41 | + "closed": false, | ||
| 42 | + "updated_at": "2012-07-04T13:42:48Z", | ||
| 43 | + "created_at": "2012-07-04T13:42:48Z" | ||
| 44 | + }, | ||
| 45 | + "assignee": { | ||
| 46 | + "id": 2, | ||
| 47 | + "email": "jack@example.com", | ||
| 48 | + "name": "Jack Smith", | ||
| 49 | + "blocked": false, | ||
| 50 | + "created_at": "2012-05-23T08:01:01Z" | ||
| 51 | + }, | ||
| 52 | + "author": { | ||
| 53 | + "id": 1, | ||
| 54 | + "email": "john@example.com", | ||
| 55 | + "name": "John Smith", | ||
| 56 | + "blocked": false, | ||
| 57 | + "created_at": "2012-05-23T08:00:58Z" | ||
| 58 | + }, | ||
| 59 | + "closed": false, | ||
| 60 | + "updated_at": "2012-07-12T13:43:19Z", | ||
| 61 | + "created_at": "2012-06-28T12:58:06Z" | ||
| 62 | + } | ||
| 63 | +] | ||
| 64 | +``` | ||
| 65 | + | ||
| 66 | +## List project issues | ||
| 67 | + | ||
| 68 | +Get a list of project issues. | ||
| 69 | + | ||
| 70 | +``` | ||
| 71 | +GET /projects/:id/issues | ||
| 72 | +``` | ||
| 73 | + | ||
| 74 | +Parameters: | ||
| 75 | + | ||
| 76 | ++ `id` (required) - The code name of a project | ||
| 77 | + | ||
| 78 | +## Single issue | ||
| 79 | + | ||
| 80 | +Get a project issue. | ||
| 81 | + | ||
| 82 | +``` | ||
| 83 | +GET /projects/:id/issues/:issue_id | ||
| 84 | +``` | ||
| 85 | + | ||
| 86 | +Parameters: | ||
| 87 | + | ||
| 88 | ++ `id` (required) - The code name of a project | ||
| 89 | ++ `issue_id` (required) - The ID of a project issue | ||
| 90 | + | ||
| 91 | +```json | ||
| 92 | +{ | ||
| 93 | + "id": 42, | ||
| 94 | + "title": "Add user settings", | ||
| 95 | + "description": "", | ||
| 96 | + "labels": [ | ||
| 97 | + "feature" | ||
| 98 | + ], | ||
| 99 | + "milestone": { | ||
| 100 | + "id": 1, | ||
| 101 | + "title": "v1.0", | ||
| 102 | + "description": "", | ||
| 103 | + "due_date": "2012-07-20", | ||
| 104 | + "closed": false, | ||
| 105 | + "updated_at": "2012-07-04T13:42:48Z", | ||
| 106 | + "created_at": "2012-07-04T13:42:48Z" | ||
| 107 | + }, | ||
| 108 | + "assignee": { | ||
| 109 | + "id": 2, | ||
| 110 | + "email": "jack@example.com", | ||
| 111 | + "name": "Jack Smith", | ||
| 112 | + "blocked": false, | ||
| 113 | + "created_at": "2012-05-23T08:01:01Z" | ||
| 114 | + }, | ||
| 115 | + "author": { | ||
| 116 | + "id": 1, | ||
| 117 | + "email": "john@example.com", | ||
| 118 | + "name": "John Smith", | ||
| 119 | + "blocked": false, | ||
| 120 | + "created_at": "2012-05-23T08:00:58Z" | ||
| 121 | + }, | ||
| 122 | + "closed": false, | ||
| 123 | + "updated_at": "2012-07-12T13:43:19Z", | ||
| 124 | + "created_at": "2012-06-28T12:58:06Z" | ||
| 125 | +} | ||
| 126 | +``` | ||
| 127 | + | ||
| 128 | +## New issue | ||
| 129 | + | ||
| 130 | +Create a new project issue. | ||
| 131 | + | ||
| 132 | +``` | ||
| 133 | +POST /projects/:id/issues | ||
| 134 | +``` | ||
| 135 | + | ||
| 136 | +Parameters: | ||
| 137 | + | ||
| 138 | ++ `id` (required) - The code name of a project | ||
| 139 | ++ `title` (required) - The title of an issue | ||
| 140 | ++ `description` (optional) - The description of an issue | ||
| 141 | ++ `assignee_id` (optional) - The ID of a user to assign issue | ||
| 142 | ++ `milestone_id` (optional) - The ID of a milestone to assign issue | ||
| 143 | ++ `labels` (optional) - Comma-separated label names for an issue | ||
| 144 | + | ||
| 145 | +Will return created issue with status `201 Created` on success, or `404 Not found` on fail. | ||
| 146 | + | ||
| 147 | +## Edit issue | ||
| 148 | + | ||
| 149 | +Update an existing project issue. | ||
| 150 | + | ||
| 151 | +``` | ||
| 152 | +PUT /projects/:id/issues/:issue_id | ||
| 153 | +``` | ||
| 154 | + | ||
| 155 | +Parameters: | ||
| 156 | + | ||
| 157 | ++ `id` (required) - The code name of a project | ||
| 158 | ++ `issue_id` (required) - The ID of a project's issue | ||
| 159 | ++ `title` (optional) - The title of an issue | ||
| 160 | ++ `description` (optional) - The description of an issue | ||
| 161 | ++ `assignee_id` (optional) - The ID of a user to assign issue | ||
| 162 | ++ `milestone_id` (optional) - The ID of a milestone to assign issue | ||
| 163 | ++ `labels` (optional) - Comma-separated label names for an issue | ||
| 164 | ++ `closed` (optional) - The state of an issue (0 = false, 1 = true) | ||
| 165 | + | ||
| 166 | +Will return updated issue with status `200 OK` on success, or `404 Not found` on fail. | ||
| 167 | + | ||
| 168 | +## Delete issue | ||
| 169 | + | ||
| 170 | +Delete existing project issue. | ||
| 171 | + | ||
| 172 | +``` | ||
| 173 | +DELETE /projects/:id/issues/:issue_id | ||
| 174 | +``` | ||
| 175 | + | ||
| 176 | +Parameters: | ||
| 177 | + | ||
| 178 | ++ `id` (required) - The code name of a project | ||
| 179 | ++ `issue_id` (required) - The ID of a project's issue | ||
| 180 | + | ||
| 181 | +Status code `200` will be returned on success. |
lib/api.rb
lib/api/entities.rb
| @@ -16,11 +16,7 @@ module Gitlab | @@ -16,11 +16,7 @@ module Gitlab | ||
| 16 | expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :created_at | 16 | expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :created_at |
| 17 | end | 17 | end |
| 18 | 18 | ||
| 19 | - class ProjectRepositoryBranches < Grape::Entity | ||
| 20 | - expose :name, :commit | ||
| 21 | - end | ||
| 22 | - | ||
| 23 | - class ProjectRepositoryTags < Grape::Entity | 19 | + class RepoObject < Grape::Entity |
| 24 | expose :name, :commit | 20 | expose :name, :commit |
| 25 | end | 21 | end |
| 26 | 22 | ||
| @@ -29,5 +25,17 @@ module Gitlab | @@ -29,5 +25,17 @@ module Gitlab | ||
| 29 | expose :author, :using => Entities::UserBasic | 25 | expose :author, :using => Entities::UserBasic |
| 30 | expose :expires_at, :updated_at, :created_at | 26 | expose :expires_at, :updated_at, :created_at |
| 31 | end | 27 | end |
| 28 | + | ||
| 29 | + class Milestone < Grape::Entity | ||
| 30 | + expose :id, :title, :description, :due_date, :closed, :updated_at, :created_at | ||
| 31 | + end | ||
| 32 | + | ||
| 33 | + class Issue < Grape::Entity | ||
| 34 | + expose :id, :title, :description | ||
| 35 | + expose :label_list, :as => :labels | ||
| 36 | + expose :milestone, :using => Entities::Milestone | ||
| 37 | + expose :assignee, :author, :using => Entities::UserBasic | ||
| 38 | + expose :closed, :updated_at, :created_at | ||
| 39 | + end | ||
| 32 | end | 40 | end |
| 33 | end | 41 | end |
lib/api/helpers.rb
| @@ -4,6 +4,10 @@ module Gitlab | @@ -4,6 +4,10 @@ module Gitlab | ||
| 4 | @current_user ||= User.find_by_authentication_token(params[:private_token]) | 4 | @current_user ||= User.find_by_authentication_token(params[:private_token]) |
| 5 | end | 5 | end |
| 6 | 6 | ||
| 7 | + def user_project | ||
| 8 | + @project ||= current_user.projects.find_by_code(params[:id]) | ||
| 9 | + end | ||
| 10 | + | ||
| 7 | def authenticate! | 11 | def authenticate! |
| 8 | error!({'message' => '401 Unauthorized'}, 401) unless current_user | 12 | error!({'message' => '401 Unauthorized'}, 401) unless current_user |
| 9 | end | 13 | end |
| @@ -0,0 +1,111 @@ | @@ -0,0 +1,111 @@ | ||
| 1 | +module Gitlab | ||
| 2 | + # Issues API | ||
| 3 | + class Issues < Grape::API | ||
| 4 | + before { authenticate! } | ||
| 5 | + | ||
| 6 | + resource :issues do | ||
| 7 | + # Get currently authenticated user's issues | ||
| 8 | + # | ||
| 9 | + # Example Request: | ||
| 10 | + # GET /issues | ||
| 11 | + get do | ||
| 12 | + present current_user.issues, :with => Entities::Issue | ||
| 13 | + end | ||
| 14 | + end | ||
| 15 | + | ||
| 16 | + resource :projects do | ||
| 17 | + # Get a list of project issues | ||
| 18 | + # | ||
| 19 | + # Parameters: | ||
| 20 | + # id (required) - The code name of a project | ||
| 21 | + # Example Request: | ||
| 22 | + # GET /projects/:id/issues | ||
| 23 | + get ":id/issues" do | ||
| 24 | + present user_project.issues, :with => Entities::Issue | ||
| 25 | + end | ||
| 26 | + | ||
| 27 | + # Get a single project issue | ||
| 28 | + # | ||
| 29 | + # Parameters: | ||
| 30 | + # id (required) - The code name of a project | ||
| 31 | + # issue_id (required) - The ID of a project issue | ||
| 32 | + # Example Request: | ||
| 33 | + # GET /projects/:id/issues/:issue_id | ||
| 34 | + get ":id/issues/:issue_id" do | ||
| 35 | + @issue = user_project.issues.find(params[:issue_id]) | ||
| 36 | + present @issue, :with => Entities::Issue | ||
| 37 | + end | ||
| 38 | + | ||
| 39 | + # Create a new project issue | ||
| 40 | + # | ||
| 41 | + # Parameters: | ||
| 42 | + # id (required) - The code name of a project | ||
| 43 | + # title (required) - The title of an issue | ||
| 44 | + # description (optional) - The description of an issue | ||
| 45 | + # assignee_id (optional) - The ID of a user to assign issue | ||
| 46 | + # milestone_id (optional) - The ID of a milestone to assign issue | ||
| 47 | + # labels (optional) - The labels of an issue | ||
| 48 | + # Example Request: | ||
| 49 | + # POST /projects/:id/issues | ||
| 50 | + post ":id/issues" do | ||
| 51 | + @issue = user_project.issues.new( | ||
| 52 | + :title => params[:title], | ||
| 53 | + :description => params[:description], | ||
| 54 | + :assignee_id => params[:assignee_id], | ||
| 55 | + :milestone_id => params[:milestone_id], | ||
| 56 | + :label_list => params[:labels] | ||
| 57 | + ) | ||
| 58 | + @issue.author = current_user | ||
| 59 | + | ||
| 60 | + if @issue.save | ||
| 61 | + present @issue, :with => Entities::Issue | ||
| 62 | + else | ||
| 63 | + error!({'message' => '404 Not found'}, 404) | ||
| 64 | + end | ||
| 65 | + end | ||
| 66 | + | ||
| 67 | + # Update an existing issue | ||
| 68 | + # | ||
| 69 | + # Parameters: | ||
| 70 | + # id (required) - The code name of a project | ||
| 71 | + # issue_id (required) - The ID of a project issue | ||
| 72 | + # title (optional) - The title of an issue | ||
| 73 | + # description (optional) - The description of an issue | ||
| 74 | + # assignee_id (optional) - The ID of a user to assign issue | ||
| 75 | + # milestone_id (optional) - The ID of a milestone to assign issue | ||
| 76 | + # labels (optional) - The labels of an issue | ||
| 77 | + # closed (optional) - The state of an issue (0 = false, 1 = true) | ||
| 78 | + # Example Request: | ||
| 79 | + # PUT /projects/:id/issues/:issue_id | ||
| 80 | + put ":id/issues/:issue_id" do | ||
| 81 | + @issue = user_project.issues.find(params[:issue_id]) | ||
| 82 | + parameters = { | ||
| 83 | + :title => (params[:title] || @issue.title), | ||
| 84 | + :description => (params[:description] || @issue.description), | ||
| 85 | + :assignee_id => (params[:assignee_id] || @issue.assignee_id), | ||
| 86 | + :milestone_id => (params[:milestone_id] || @issue.milestone_id), | ||
| 87 | + :label_list => (params[:labels] || @issue.label_list), | ||
| 88 | + :closed => (params[:closed] || @issue.closed) | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + if @issue.update_attributes(parameters) | ||
| 92 | + present @issue, :with => Entities::Issue | ||
| 93 | + else | ||
| 94 | + error!({'message' => '404 Not found'}, 404) | ||
| 95 | + end | ||
| 96 | + end | ||
| 97 | + | ||
| 98 | + # Delete a project issue | ||
| 99 | + # | ||
| 100 | + # Parameters: | ||
| 101 | + # id (required) - The code name of a project | ||
| 102 | + # issue_id (required) - The ID of a project issue | ||
| 103 | + # Example Request: | ||
| 104 | + # DELETE /projects/:id/issues/:issue_id | ||
| 105 | + delete ":id/issues/:issue_id" do | ||
| 106 | + @issue = user_project.issues.find(params[:issue_id]) | ||
| 107 | + @issue.destroy | ||
| 108 | + end | ||
| 109 | + end | ||
| 110 | + end | ||
| 111 | +end |
lib/api/projects.rb
| @@ -20,8 +20,7 @@ module Gitlab | @@ -20,8 +20,7 @@ module Gitlab | ||
| 20 | # Example Request: | 20 | # Example Request: |
| 21 | # GET /projects/:id | 21 | # GET /projects/:id |
| 22 | get ":id" do | 22 | get ":id" do |
| 23 | - @project = current_user.projects.find_by_code(params[:id]) | ||
| 24 | - present @project, :with => Entities::Project | 23 | + present user_project, :with => Entities::Project |
| 25 | end | 24 | end |
| 26 | 25 | ||
| 27 | # Get a project repository branches | 26 | # Get a project repository branches |
| @@ -31,8 +30,7 @@ module Gitlab | @@ -31,8 +30,7 @@ module Gitlab | ||
| 31 | # Example Request: | 30 | # Example Request: |
| 32 | # GET /projects/:id/repository/branches | 31 | # GET /projects/:id/repository/branches |
| 33 | get ":id/repository/branches" do | 32 | get ":id/repository/branches" do |
| 34 | - @project = current_user.projects.find_by_code(params[:id]) | ||
| 35 | - present @project.repo.heads.sort_by(&:name), :with => Entities::ProjectRepositoryBranches | 33 | + present user_project.repo.heads.sort_by(&:name), :with => Entities::RepoObject |
| 36 | end | 34 | end |
| 37 | 35 | ||
| 38 | # Get a project repository tags | 36 | # Get a project repository tags |
| @@ -42,8 +40,7 @@ module Gitlab | @@ -42,8 +40,7 @@ module Gitlab | ||
| 42 | # Example Request: | 40 | # Example Request: |
| 43 | # GET /projects/:id/repository/tags | 41 | # GET /projects/:id/repository/tags |
| 44 | get ":id/repository/tags" do | 42 | get ":id/repository/tags" do |
| 45 | - @project = current_user.projects.find_by_code(params[:id]) | ||
| 46 | - present @project.repo.tags.sort_by(&:name).reverse, :with => Entities::ProjectRepositoryTags | 43 | + present user_project.repo.tags.sort_by(&:name).reverse, :with => Entities::RepoObject |
| 47 | end | 44 | end |
| 48 | 45 | ||
| 49 | # Get a project snippet | 46 | # Get a project snippet |
| @@ -54,8 +51,7 @@ module Gitlab | @@ -54,8 +51,7 @@ module Gitlab | ||
| 54 | # Example Request: | 51 | # Example Request: |
| 55 | # GET /projects/:id/snippets/:snippet_id | 52 | # GET /projects/:id/snippets/:snippet_id |
| 56 | get ":id/snippets/:snippet_id" do | 53 | get ":id/snippets/:snippet_id" do |
| 57 | - @project = current_user.projects.find_by_code(params[:id]) | ||
| 58 | - @snippet = @project.snippets.find(params[:snippet_id]) | 54 | + @snippet = user_project.snippets.find(params[:snippet_id]) |
| 59 | present @snippet, :with => Entities::ProjectSnippet | 55 | present @snippet, :with => Entities::ProjectSnippet |
| 60 | end | 56 | end |
| 61 | 57 | ||
| @@ -70,8 +66,7 @@ module Gitlab | @@ -70,8 +66,7 @@ module Gitlab | ||
| 70 | # Example Request: | 66 | # Example Request: |
| 71 | # POST /projects/:id/snippets | 67 | # POST /projects/:id/snippets |
| 72 | post ":id/snippets" do | 68 | post ":id/snippets" do |
| 73 | - @project = current_user.projects.find_by_code(params[:id]) | ||
| 74 | - @snippet = @project.snippets.new( | 69 | + @snippet = user_project.snippets.new( |
| 75 | :title => params[:title], | 70 | :title => params[:title], |
| 76 | :file_name => params[:file_name], | 71 | :file_name => params[:file_name], |
| 77 | :expires_at => params[:lifetime], | 72 | :expires_at => params[:lifetime], |
| @@ -98,8 +93,7 @@ module Gitlab | @@ -98,8 +93,7 @@ module Gitlab | ||
| 98 | # Example Request: | 93 | # Example Request: |
| 99 | # PUT /projects/:id/snippets/:snippet_id | 94 | # PUT /projects/:id/snippets/:snippet_id |
| 100 | put ":id/snippets/:snippet_id" do | 95 | put ":id/snippets/:snippet_id" do |
| 101 | - @project = current_user.projects.find_by_code(params[:id]) | ||
| 102 | - @snippet = @project.snippets.find(params[:snippet_id]) | 96 | + @snippet = user_project.snippets.find(params[:snippet_id]) |
| 103 | parameters = { | 97 | parameters = { |
| 104 | :title => (params[:title] || @snippet.title), | 98 | :title => (params[:title] || @snippet.title), |
| 105 | :file_name => (params[:file_name] || @snippet.file_name), | 99 | :file_name => (params[:file_name] || @snippet.file_name), |
| @@ -122,8 +116,7 @@ module Gitlab | @@ -122,8 +116,7 @@ module Gitlab | ||
| 122 | # Example Request: | 116 | # Example Request: |
| 123 | # DELETE /projects/:id/snippets/:snippet_id | 117 | # DELETE /projects/:id/snippets/:snippet_id |
| 124 | delete ":id/snippets/:snippet_id" do | 118 | delete ":id/snippets/:snippet_id" do |
| 125 | - @project = current_user.projects.find_by_code(params[:id]) | ||
| 126 | - @snippet = @project.snippets.find(params[:snippet_id]) | 119 | + @snippet = user_project.snippets.find(params[:snippet_id]) |
| 127 | @snippet.destroy | 120 | @snippet.destroy |
| 128 | end | 121 | end |
| 129 | 122 | ||
| @@ -135,8 +128,7 @@ module Gitlab | @@ -135,8 +128,7 @@ module Gitlab | ||
| 135 | # Example Request: | 128 | # Example Request: |
| 136 | # GET /projects/:id/snippets/:snippet_id/raw | 129 | # GET /projects/:id/snippets/:snippet_id/raw |
| 137 | get ":id/snippets/:snippet_id/raw" do | 130 | get ":id/snippets/:snippet_id/raw" do |
| 138 | - @project = current_user.projects.find_by_code(params[:id]) | ||
| 139 | - @snippet = @project.snippets.find(params[:snippet_id]) | 131 | + @snippet = user_project.snippets.find(params[:snippet_id]) |
| 140 | present @snippet.content | 132 | present @snippet.content |
| 141 | end | 133 | end |
| 142 | end | 134 | end |
| @@ -0,0 +1,71 @@ | @@ -0,0 +1,71 @@ | ||
| 1 | +require 'spec_helper' | ||
| 2 | + | ||
| 3 | +describe Gitlab::API do | ||
| 4 | + let(:user) { Factory :user } | ||
| 5 | + let!(:project) { Factory :project, :owner => user } | ||
| 6 | + let!(:issue) { Factory :issue, :author => user, :assignee => user, :project => project } | ||
| 7 | + before { project.add_access(user, :read) } | ||
| 8 | + | ||
| 9 | + describe "GET /issues" do | ||
| 10 | + it "should return authentication error" do | ||
| 11 | + get "#{api_prefix}/issues" | ||
| 12 | + response.status.should == 401 | ||
| 13 | + end | ||
| 14 | + | ||
| 15 | + describe "authenticated GET /issues" do | ||
| 16 | + it "should return an array of issues" do | ||
| 17 | + get "#{api_prefix}/issues?private_token=#{user.private_token}" | ||
| 18 | + response.status.should == 200 | ||
| 19 | + json_response.should be_an Array | ||
| 20 | + json_response.first['title'].should == issue.title | ||
| 21 | + end | ||
| 22 | + end | ||
| 23 | + end | ||
| 24 | + | ||
| 25 | + describe "GET /projects/:id/issues" do | ||
| 26 | + it "should return project issues" do | ||
| 27 | + get "#{api_prefix}/projects/#{project.code}/issues?private_token=#{user.private_token}" | ||
| 28 | + response.status.should == 200 | ||
| 29 | + json_response.should be_an Array | ||
| 30 | + json_response.first['title'].should == issue.title | ||
| 31 | + end | ||
| 32 | + end | ||
| 33 | + | ||
| 34 | + describe "GET /projects/:id/issues/:issue_id" do | ||
| 35 | + it "should return a project issue by id" do | ||
| 36 | + get "#{api_prefix}/projects/#{project.code}/issues/#{issue.id}?private_token=#{user.private_token}" | ||
| 37 | + response.status.should == 200 | ||
| 38 | + json_response['title'].should == issue.title | ||
| 39 | + end | ||
| 40 | + end | ||
| 41 | + | ||
| 42 | + describe "POST /projects/:id/issues" do | ||
| 43 | + it "should create a new project issue" do | ||
| 44 | + post "#{api_prefix}/projects/#{project.code}/issues?private_token=#{user.private_token}", | ||
| 45 | + :title => 'new issue', :labels => 'label, label2' | ||
| 46 | + response.status.should == 201 | ||
| 47 | + json_response['title'].should == 'new issue' | ||
| 48 | + json_response['description'].should be_nil | ||
| 49 | + json_response['labels'].should == ['label', 'label2'] | ||
| 50 | + end | ||
| 51 | + end | ||
| 52 | + | ||
| 53 | + describe "PUT /projects/:id/issues/:issue_id" do | ||
| 54 | + it "should update a project issue" do | ||
| 55 | + put "#{api_prefix}/projects/#{project.code}/issues/#{issue.id}?private_token=#{user.private_token}", | ||
| 56 | + :title => 'updated title', :labels => 'label2', :closed => 1 | ||
| 57 | + response.status.should == 200 | ||
| 58 | + json_response['title'].should == 'updated title' | ||
| 59 | + json_response['labels'].should == ['label2'] | ||
| 60 | + json_response['closed'].should be_true | ||
| 61 | + end | ||
| 62 | + end | ||
| 63 | + | ||
| 64 | + describe "DELETE /projects/:id/issues/:issue_id" do | ||
| 65 | + it "should delete a project issue" do | ||
| 66 | + expect { | ||
| 67 | + delete "#{api_prefix}/projects/#{project.code}/issues/#{issue.id}?private_token=#{user.private_token}" | ||
| 68 | + }.to change { Issue.count }.by(-1) | ||
| 69 | + end | ||
| 70 | + end | ||
| 71 | +end |