diff options
| -rw-r--r-- | CHANGELOG | 4 | ||||
| -rw-r--r-- | VERSION | 2 | ||||
| -rw-r--r-- | app/assets/stylesheets/header.scss | 3 | ||||
| -rw-r--r-- | app/assets/stylesheets/themes/ui_mars.scss | 3 | ||||
| -rw-r--r-- | app/controllers/dashboard_controller.rb | 3 | ||||
| -rw-r--r-- | app/views/admin/hooks/_data_ex.html.erb | 93 | ||||
| -rw-r--r-- | app/views/admin/users/_form.html.haml | 6 | ||||
| -rw-r--r-- | app/views/dashboard/index.html.haml | 7 | ||||
| -rw-r--r-- | app/views/dashboard/index.js.haml | 2 | ||||
| -rw-r--r-- | app/views/help/api.html.haml | 20 | ||||
| -rw-r--r-- | app/views/help/index.html.haml | 3 | ||||
| -rw-r--r-- | app/views/layouts/profile.html.haml | 9 | ||||
| -rw-r--r-- | doc/api/README.md | 1 | ||||
| -rw-r--r-- | doc/api/issues.md | 181 | ||||
| -rw-r--r-- | lib/api.rb | 1 | ||||
| -rw-r--r-- | lib/api/entities.rb | 18 | ||||
| -rw-r--r-- | lib/api/helpers.rb | 4 | ||||
| -rw-r--r-- | lib/api/issues.rb | 111 | ||||
| -rw-r--r-- | lib/api/projects.rb | 24 | ||||
| -rw-r--r-- | lib/gitlab/logger.rb | 1 | ||||
| -rw-r--r-- | spec/api/issues_spec.rb | 71 |
21 files changed, 490 insertions, 77 deletions
diff --git a/CHANGELOG b/CHANGELOG index fe243d65e4b..ec5d2f220d3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,10 @@ v 2.7.0 - Git HTTP - API - UI improved + - System hooks + - UI improved + - Dashboard events endless scroll + - Source perfomance increased v 2.6.0 - UI polished @@ -1 +1 @@ -2.7.0pre +2.7.0 diff --git a/app/assets/stylesheets/header.scss b/app/assets/stylesheets/header.scss index c3a570036bb..07eba39b275 100644 --- a/app/assets/stylesheets/header.scss +++ b/app/assets/stylesheets/header.scss @@ -125,9 +125,6 @@ header { display: block; cursor: pointer; img { - -moz-box-shadow: 0 0 5px #ccc; - -webkit-box-shadow: 0 0 5px #ccc; - box-shadow: 0 0 5px #ccc; border-radius: 4px; right: 5px; position: absolute; diff --git a/app/assets/stylesheets/themes/ui_mars.scss b/app/assets/stylesheets/themes/ui_mars.scss index 0fea6144431..39dcab1d085 100644 --- a/app/assets/stylesheets/themes/ui_mars.scss +++ b/app/assets/stylesheets/themes/ui_mars.scss @@ -70,8 +70,7 @@ } } .separator { - border-color:#444; - background:#31363E; + display:none; } } diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 14f6ab1c31a..8508e2454d2 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -3,11 +3,12 @@ class DashboardController < ApplicationController def index @projects = current_user.projects_with_events.page(params[:page]).per(40) - @events = Event.recent_for_user(current_user).limit(20) + @events = Event.recent_for_user(current_user).limit(20).offset(params[:offset] || 0) @last_push = current_user.recent_push respond_to do |format| format.html + format.js format.atom { render :layout => false } end end diff --git a/app/views/admin/hooks/_data_ex.html.erb b/app/views/admin/hooks/_data_ex.html.erb index 8d3de3f0bf2..652ee5aa56f 100644 --- a/app/views/admin/hooks/_data_ex.html.erb +++ b/app/views/admin/hooks/_data_ex.html.erb @@ -1,44 +1,65 @@ <% data_ex_str = <<eos +1. Project created: { - :before => "95790bf891e76fee5e1747ab589903a6a1f80f22", - :after => "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", - :ref => "refs/heads/master", - :user_id => 4, - :user_name => "John Smith", - :repository => { - :name => "Diaspora", - :url => "localhost/diaspora", - :description => "", - :homepage => "localhost/diaspora", - :private => true - }, - :commits => [ - [0] { - :id => "450d0de7532f8b663b9c5cce183b...", - :message => "Update Catalan translation to e38cb41.", - :timestamp => "2011-12-12T14:27:31+02:00", - :url => "http://localhost/diaspora/commits/450d0de7532f...", - :author => { - :name => "Jordi Mallach", - :email => "jordi@softcatala.org" - } - }, + "created_at": "2012-07-21T07:30:54Z", + "event_name": "project_create", + "name": "StoreCloud", + "owner_email": "johnsmith@gmail.com", + "owner_name": "John Smith", + "path": "storecloud", + "project_id": 74 +} + +2. Project destroyed: +{ + "event_name": "project_destroy", + "name": "Underscore", + "owner_email": "johnsmith@gmail.com", + "owner_name": "John Smith", + "path": "underscore", + "project_id": 73 +} + +3. New Team Member: +{ + "created_at": "2012-07-21T07:30:56Z", + "event_name": "user_add_to_team", + "project_access": "Master", + "project_id": 74, + "project_name": "StoreCloud", + "project_path": "storecloud", + "owner_email": "johnsmith@gmail.com", + "owner_name": "John Smith", +} + +4. Team Member Removed: +{ + "created_at": "2012-07-21T07:30:56Z", + "event_name": "user_remove_from_team", + "project_access": "Master", + "project_id": 74, + "project_name": "StoreCloud", + "project_path": "storecloud", + "owner_email": "johnsmith@gmail.com", + "owner_name": "John Smith", +} - .... +5. User created: +{ + "created_at": "2012-07-21T07:44:07Z", + "email": "js@gitlabhq.com", + "event_name": "user_create", + "name": "John Smith" +} - [3] { - :id => "da1560886d4f094c3e6c9ef40349...", - :message => "fixed readme", - :timestamp => "2012-01-03T23:36:29+02:00", - :url => "http://localhost/diaspora/commits/da1560886d...", - :author => { - :name => "gitlab dev user", - :email => "gitlabdev@dv6700.(none)" - } - } - ], - total_commits_count => 3 +6. User removed: +{ + "created_at": "2012-07-21T07:44:07Z", + "email": "js@gitlabhq.com", + "event_name": "user_destroy", + "name": "John Smith" } + eos %> <% js_lexer = Pygments::Lexer[:js] %> diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index bd2e136247a..c1955b321d5 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -50,7 +50,7 @@ .alert .clearfix - %p Give user ability to manage application. + %p Make the user a GitLab administrator. = f.label :admin, :class => "checkbox" do = f.check_box :admin %span Administrator @@ -59,11 +59,11 @@ - if @admin_user.blocked %span = link_to 'Unblock', unblock_admin_user_path(@admin_user), :method => :put, :class => "btn small" - This user is blocked and is not able to login GitLab + This user is blocked and is not able to login to GitLab - else %span = link_to 'Block', block_admin_user_path(@admin_user), :confirm => 'USER WILL BE BLOCKED! Are you sure?', :method => :put, :class => "btn small danger" - Blocked user will removed from all projects & will not be able to login to GitLab. + Blocked users will be removed from all projects & will not be able to login to GitLab. .actions = f.submit 'Save', :class => "btn primary" - if @admin_user.new_record? diff --git a/app/views/dashboard/index.html.haml b/app/views/dashboard/index.html.haml index b38544509b2..e1d7781927a 100644 --- a/app/views/dashboard/index.html.haml +++ b/app/views/dashboard/index.html.haml @@ -10,9 +10,10 @@ add new key to your profile - if @events.any? - = render @events + .content_list= render @events - else %h4.nothing_here_message Projects activity will be displayed here + .loading.hide .side = render "events/event_last_push", :event => @last_push .projects_box @@ -54,3 +55,7 @@ New Project ยป - else If you will be added to project - it will be displayed here + + +:javascript + $(function(){ Pager.init(20); }); diff --git a/app/views/dashboard/index.js.haml b/app/views/dashboard/index.js.haml index aa038e75928..7e5a148e5ef 100644 --- a/app/views/dashboard/index.js.haml +++ b/app/views/dashboard/index.js.haml @@ -1,2 +1,2 @@ :plain - $(".projects .activities").append("#{escape_javascript(render(@events))}"); + Pager.append(#{@events.count}, "#{escape_javascript(render(@events))}"); diff --git a/app/views/help/api.html.haml b/app/views/help/api.html.haml index 4964c1bbd87..e184df549de 100644 --- a/app/views/help/api.html.haml +++ b/app/views/help/api.html.haml @@ -1,16 +1,18 @@ %h3 API .back_link - = link_to help_path do + = link_to help_path do ← to index %hr %ol - %li + %li %a{:href => "#README"} README - %li + %li %a{:href => "#projects"} Projects - %li + %li %a{:href => "#users"} Users + %li + %a{:href => "#issues"} Issues .file_holder#README .file_title @@ -39,3 +41,13 @@ .file_content.wiki = preserve do = markdown File.read(Rails.root.join("doc", "api", "users.md")) + +%br + +.file_holder#issues + .file_title + %i.icon-file + Issues + .file_content.wiki + = preserve do + = markdown File.read(Rails.root.join("doc", "api", "issues.md")) diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml index b6c52712c4d..e9602e33037 100644 --- a/app/views/help/index.html.haml +++ b/app/views/help/index.html.haml @@ -24,4 +24,7 @@ %h5= link_to "Web Hooks", help_web_hooks_path %li + %h5= link_to "System Hooks", help_system_hooks_path + + %li %h5= link_to "API", help_api_path diff --git a/app/views/layouts/profile.html.haml b/app/views/layouts/profile.html.haml index dfe48d68240..957a68bf482 100644 --- a/app/views/layouts/profile.html.haml +++ b/app/views/layouts/profile.html.haml @@ -12,16 +12,17 @@ %li{:class => tab_class(:password)} = link_to "Password", profile_password_path + %li{:class => tab_class(:ssh_keys)} + = link_to keys_path do + SSH Keys + %span.count= current_user.keys.count + %li{:class => tab_class(:token)} = link_to "Token", profile_token_path %li{:class => tab_class(:design)} = link_to "Design", profile_design_path - %li{:class => tab_class(:ssh_keys)} - = link_to keys_path do - SSH Keys - %span.count= current_user.keys.count .content = yield diff --git a/doc/api/README.md b/doc/api/README.md index dcf75afda1f..e01119661f0 100644 --- a/doc/api/README.md +++ b/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 + [Users](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/users.md) + [Projects](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/projects.md) ++ [Issues](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/issues.md) diff --git a/doc/api/issues.md b/doc/api/issues.md new file mode 100644 index 00000000000..bad2d474020 --- /dev/null +++ b/doc/api/issues.md @@ -0,0 +1,181 @@ +## List issues + +Get all issues created by authenticed user. + +``` +GET /issues +``` + +```json +[ + { + "id": 43, + "title": "4xx/5xx pages", + "description": "", + "labels": [ ], + "milestone": null, + "assignee": null, + "author": { + "id": 1, + "email": "john@example.com", + "name": "John Smith", + "blocked": false, + "created_at": "2012-05-23T08:00:58Z" + }, + "closed": true, + "updated_at": "2012-07-02T17:53:12Z", + "created_at": "2012-07-02T17:53:12Z" + }, + { + "id": 42, + "title": "Add user settings", + "description": "", + "labels": [ + "feature" + ], + "milestone": { + "id": 1, + "title": "v1.0", + "description": "", + "due_date": "2012-07-20", + "closed": false, + "updated_at": "2012-07-04T13:42:48Z", + "created_at": "2012-07-04T13:42:48Z" + }, + "assignee": { + "id": 2, + "email": "jack@example.com", + "name": "Jack Smith", + "blocked": false, + "created_at": "2012-05-23T08:01:01Z" + }, + "author": { + "id": 1, + "email": "john@example.com", + "name": "John Smith", + "blocked": false, + "created_at": "2012-05-23T08:00:58Z" + }, + "closed": false, + "updated_at": "2012-07-12T13:43:19Z", + "created_at": "2012-06-28T12:58:06Z" + } +] +``` + +## List project issues + +Get a list of project issues. + +``` +GET /projects/:id/issues +``` + +Parameters: + ++ `id` (required) - The code name of a project + +## Single issue + +Get a project issue. + +``` +GET /projects/:id/issues/:issue_id +``` + +Parameters: + ++ `id` (required) - The code name of a project ++ `issue_id` (required) - The ID of a project issue + +```json +{ + "id": 42, + "title": "Add user settings", + "description": "", + "labels": [ + "feature" + ], + "milestone": { + "id": 1, + "title": "v1.0", + "description": "", + "due_date": "2012-07-20", + "closed": false, + "updated_at": "2012-07-04T13:42:48Z", + "created_at": "2012-07-04T13:42:48Z" + }, + "assignee": { + "id": 2, + "email": "jack@example.com", + "name": "Jack Smith", + "blocked": false, + "created_at": "2012-05-23T08:01:01Z" + }, + "author": { + "id": 1, + "email": "john@example.com", + "name": "John Smith", + "blocked": false, + "created_at": "2012-05-23T08:00:58Z" + }, + "closed": false, + "updated_at": "2012-07-12T13:43:19Z", + "created_at": "2012-06-28T12:58:06Z" +} +``` + +## New issue + +Create a new project issue. + +``` +POST /projects/:id/issues +``` + +Parameters: + ++ `id` (required) - The code name of a project ++ `title` (required) - The title of an issue ++ `description` (optional) - The description of an issue ++ `assignee_id` (optional) - The ID of a user to assign issue ++ `milestone_id` (optional) - The ID of a milestone to assign issue ++ `labels` (optional) - Comma-separated label names for an issue + +Will return created issue with status `201 Created` on success, or `404 Not found` on fail. + +## Edit issue + +Update an existing project issue. + +``` +PUT /projects/:id/issues/:issue_id +``` + +Parameters: + ++ `id` (required) - The code name of a project ++ `issue_id` (required) - The ID of a project's issue ++ `title` (optional) - The title of an issue ++ `description` (optional) - The description of an issue ++ `assignee_id` (optional) - The ID of a user to assign issue ++ `milestone_id` (optional) - The ID of a milestone to assign issue ++ `labels` (optional) - Comma-separated label names for an issue ++ `closed` (optional) - The state of an issue (0 = false, 1 = true) + +Will return updated issue with status `200 OK` on success, or `404 Not found` on fail. + +## Delete issue + +Delete existing project issue. + +``` +DELETE /projects/:id/issues/:issue_id +``` + +Parameters: + ++ `id` (required) - The code name of a project ++ `issue_id` (required) - The ID of a project's issue + +Status code `200` will be returned on success. diff --git a/lib/api.rb b/lib/api.rb index e24e0a78f71..6a8a3d651c0 100644 --- a/lib/api.rb +++ b/lib/api.rb @@ -15,5 +15,6 @@ module Gitlab mount Users mount Projects + mount Issues end end diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 35ad4d430ad..e5095f7189e 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -16,11 +16,7 @@ module Gitlab expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :created_at end - class ProjectRepositoryBranches < Grape::Entity - expose :name, :commit - end - - class ProjectRepositoryTags < Grape::Entity + class RepoObject < Grape::Entity expose :name, :commit end @@ -29,5 +25,17 @@ module Gitlab expose :author, :using => Entities::UserBasic expose :expires_at, :updated_at, :created_at end + + class Milestone < Grape::Entity + expose :id, :title, :description, :due_date, :closed, :updated_at, :created_at + end + + class Issue < Grape::Entity + expose :id, :title, :description + expose :label_list, :as => :labels + expose :milestone, :using => Entities::Milestone + expose :assignee, :author, :using => Entities::UserBasic + expose :closed, :updated_at, :created_at + end end end diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 424a17b283c..e7b9a417b08 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -4,6 +4,10 @@ module Gitlab @current_user ||= User.find_by_authentication_token(params[:private_token]) end + def user_project + @project ||= current_user.projects.find_by_code(params[:id]) + end + def authenticate! error!({'message' => '401 Unauthorized'}, 401) unless current_user end diff --git a/lib/api/issues.rb b/lib/api/issues.rb new file mode 100644 index 00000000000..2b6a1ac269d --- /dev/null +++ b/lib/api/issues.rb @@ -0,0 +1,111 @@ +module Gitlab + # Issues API + class Issues < Grape::API + before { authenticate! } + + resource :issues do + # Get currently authenticated user's issues + # + # Example Request: + # GET /issues + get do + present current_user.issues, :with => Entities::Issue + end + end + + resource :projects do + # Get a list of project issues + # + # Parameters: + # id (required) - The code name of a project + # Example Request: + # GET /projects/:id/issues + get ":id/issues" do + present user_project.issues, :with => Entities::Issue + end + + # Get a single project issue + # + # Parameters: + # id (required) - The code name of a project + # issue_id (required) - The ID of a project issue + # Example Request: + # GET /projects/:id/issues/:issue_id + get ":id/issues/:issue_id" do + @issue = user_project.issues.find(params[:issue_id]) + present @issue, :with => Entities::Issue + end + + # Create a new project issue + # + # Parameters: + # id (required) - The code name of a project + # title (required) - The title of an issue + # description (optional) - The description of an issue + # assignee_id (optional) - The ID of a user to assign issue + # milestone_id (optional) - The ID of a milestone to assign issue + # labels (optional) - The labels of an issue + # Example Request: + # POST /projects/:id/issues + post ":id/issues" do + @issue = user_project.issues.new( + :title => params[:title], + :description => params[:description], + :assignee_id => params[:assignee_id], + :milestone_id => params[:milestone_id], + :label_list => params[:labels] + ) + @issue.author = current_user + + if @issue.save + present @issue, :with => Entities::Issue + else + error!({'message' => '404 Not found'}, 404) + end + end + + # Update an existing issue + # + # Parameters: + # id (required) - The code name of a project + # issue_id (required) - The ID of a project issue + # title (optional) - The title of an issue + # description (optional) - The description of an issue + # assignee_id (optional) - The ID of a user to assign issue + # milestone_id (optional) - The ID of a milestone to assign issue + # labels (optional) - The labels of an issue + # closed (optional) - The state of an issue (0 = false, 1 = true) + # Example Request: + # PUT /projects/:id/issues/:issue_id + put ":id/issues/:issue_id" do + @issue = user_project.issues.find(params[:issue_id]) + parameters = { + :title => (params[:title] || @issue.title), + :description => (params[:description] || @issue.description), + :assignee_id => (params[:assignee_id] || @issue.assignee_id), + :milestone_id => (params[:milestone_id] || @issue.milestone_id), + :label_list => (params[:labels] || @issue.label_list), + :closed => (params[:closed] || @issue.closed) + } + + if @issue.update_attributes(parameters) + present @issue, :with => Entities::Issue + else + error!({'message' => '404 Not found'}, 404) + end + end + + # Delete a project issue + # + # Parameters: + # id (required) - The code name of a project + # issue_id (required) - The ID of a project issue + # Example Request: + # DELETE /projects/:id/issues/:issue_id + delete ":id/issues/:issue_id" do + @issue = user_project.issues.find(params[:issue_id]) + @issue.destroy + end + end + end +end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 70f8fa2aa62..34d1c23676e 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -20,8 +20,7 @@ module Gitlab # Example Request: # GET /projects/:id get ":id" do - @project = current_user.projects.find_by_code(params[:id]) - present @project, :with => Entities::Project + present user_project, :with => Entities::Project end # Get a project repository branches @@ -31,8 +30,7 @@ module Gitlab # Example Request: # GET /projects/:id/repository/branches get ":id/repository/branches" do - @project = current_user.projects.find_by_code(params[:id]) - present @project.repo.heads.sort_by(&:name), :with => Entities::ProjectRepositoryBranches + present user_project.repo.heads.sort_by(&:name), :with => Entities::RepoObject end # Get a project repository tags @@ -42,8 +40,7 @@ module Gitlab # Example Request: # GET /projects/:id/repository/tags get ":id/repository/tags" do - @project = current_user.projects.find_by_code(params[:id]) - present @project.repo.tags.sort_by(&:name).reverse, :with => Entities::ProjectRepositoryTags + present user_project.repo.tags.sort_by(&:name).reverse, :with => Entities::RepoObject end # Get a project snippet @@ -54,8 +51,7 @@ module Gitlab # Example Request: # GET /projects/:id/snippets/:snippet_id get ":id/snippets/:snippet_id" do - @project = current_user.projects.find_by_code(params[:id]) - @snippet = @project.snippets.find(params[:snippet_id]) + @snippet = user_project.snippets.find(params[:snippet_id]) present @snippet, :with => Entities::ProjectSnippet end @@ -70,8 +66,7 @@ module Gitlab # Example Request: # POST /projects/:id/snippets post ":id/snippets" do - @project = current_user.projects.find_by_code(params[:id]) - @snippet = @project.snippets.new( + @snippet = user_project.snippets.new( :title => params[:title], :file_name => params[:file_name], :expires_at => params[:lifetime], @@ -98,8 +93,7 @@ module Gitlab # Example Request: # PUT /projects/:id/snippets/:snippet_id put ":id/snippets/:snippet_id" do - @project = current_user.projects.find_by_code(params[:id]) - @snippet = @project.snippets.find(params[:snippet_id]) + @snippet = user_project.snippets.find(params[:snippet_id]) parameters = { :title => (params[:title] || @snippet.title), :file_name => (params[:file_name] || @snippet.file_name), @@ -122,8 +116,7 @@ module Gitlab # Example Request: # DELETE /projects/:id/snippets/:snippet_id delete ":id/snippets/:snippet_id" do - @project = current_user.projects.find_by_code(params[:id]) - @snippet = @project.snippets.find(params[:snippet_id]) + @snippet = user_project.snippets.find(params[:snippet_id]) @snippet.destroy end @@ -135,8 +128,7 @@ module Gitlab # Example Request: # GET /projects/:id/snippets/:snippet_id/raw get ":id/snippets/:snippet_id/raw" do - @project = current_user.projects.find_by_code(params[:id]) - @snippet = @project.snippets.find(params[:snippet_id]) + @snippet = user_project.snippets.find(params[:snippet_id]) present @snippet.content end end diff --git a/lib/gitlab/logger.rb b/lib/gitlab/logger.rb index aff13baf67b..c3a19e71c10 100644 --- a/lib/gitlab/logger.rb +++ b/lib/gitlab/logger.rb @@ -10,6 +10,7 @@ module Gitlab def self.read_latest path = Rails.root.join("log/githost.log") + self.build unless File.exist?(path) logs = File.read(path).split("\n") end diff --git a/spec/api/issues_spec.rb b/spec/api/issues_spec.rb new file mode 100644 index 00000000000..d81a07e214b --- /dev/null +++ b/spec/api/issues_spec.rb @@ -0,0 +1,71 @@ +require 'spec_helper' + +describe Gitlab::API do + let(:user) { Factory :user } + let!(:project) { Factory :project, :owner => user } + let!(:issue) { Factory :issue, :author => user, :assignee => user, :project => project } + before { project.add_access(user, :read) } + + describe "GET /issues" do + it "should return authentication error" do + get "#{api_prefix}/issues" + response.status.should == 401 + end + + describe "authenticated GET /issues" do + it "should return an array of issues" do + get "#{api_prefix}/issues?private_token=#{user.private_token}" + response.status.should == 200 + json_response.should be_an Array + json_response.first['title'].should == issue.title + end + end + end + + describe "GET /projects/:id/issues" do + it "should return project issues" do + get "#{api_prefix}/projects/#{project.code}/issues?private_token=#{user.private_token}" + response.status.should == 200 + json_response.should be_an Array + json_response.first['title'].should == issue.title + end + end + + describe "GET /projects/:id/issues/:issue_id" do + it "should return a project issue by id" do + get "#{api_prefix}/projects/#{project.code}/issues/#{issue.id}?private_token=#{user.private_token}" + response.status.should == 200 + json_response['title'].should == issue.title + end + end + + describe "POST /projects/:id/issues" do + it "should create a new project issue" do + post "#{api_prefix}/projects/#{project.code}/issues?private_token=#{user.private_token}", + :title => 'new issue', :labels => 'label, label2' + response.status.should == 201 + json_response['title'].should == 'new issue' + json_response['description'].should be_nil + json_response['labels'].should == ['label', 'label2'] + end + end + + describe "PUT /projects/:id/issues/:issue_id" do + it "should update a project issue" do + put "#{api_prefix}/projects/#{project.code}/issues/#{issue.id}?private_token=#{user.private_token}", + :title => 'updated title', :labels => 'label2', :closed => 1 + response.status.should == 200 + json_response['title'].should == 'updated title' + json_response['labels'].should == ['label2'] + json_response['closed'].should be_true + end + end + + describe "DELETE /projects/:id/issues/:issue_id" do + it "should delete a project issue" do + expect { + delete "#{api_prefix}/projects/#{project.code}/issues/#{issue.id}?private_token=#{user.private_token}" + }.to change { Issue.count }.by(-1) + end + end +end |
