Chris@0: # Redmine - project management software Chris@0: # Copyright (C) 2006-2010 Jean-Philippe Lang Chris@0: # Chris@0: # This program is free software; you can redistribute it and/or Chris@0: # modify it under the terms of the GNU General Public License Chris@0: # as published by the Free Software Foundation; either version 2 Chris@0: # of the License, or (at your option) any later version. Chris@0: # Chris@0: # This program is distributed in the hope that it will be useful, Chris@0: # but WITHOUT ANY WARRANTY; without even the implied warranty of Chris@0: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Chris@0: # GNU General Public License for more details. Chris@0: # Chris@0: # You should have received a copy of the GNU General Public License Chris@0: # along with this program; if not, write to the Free Software Chris@0: # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Chris@0: Chris@0: require "#{File.dirname(__FILE__)}/../test_helper" Chris@0: Chris@0: class IssuesApiTest < ActionController::IntegrationTest Chris@0: fixtures :projects, Chris@0: :users, Chris@0: :roles, Chris@0: :members, Chris@0: :member_roles, Chris@0: :issues, Chris@0: :issue_statuses, Chris@0: :versions, Chris@0: :trackers, Chris@0: :projects_trackers, Chris@0: :issue_categories, Chris@0: :enabled_modules, Chris@0: :enumerations, Chris@0: :attachments, Chris@0: :workflows, Chris@0: :custom_fields, Chris@0: :custom_values, Chris@0: :custom_fields_projects, Chris@0: :custom_fields_trackers, Chris@0: :time_entries, Chris@0: :journals, Chris@0: :journal_details, Chris@0: :queries Chris@0: Chris@0: def setup Chris@0: Setting.rest_api_enabled = '1' Chris@0: end Chris@0: Chris@0: context "/index.xml" do Chris@0: setup do Chris@0: get '/issues.xml' Chris@0: end Chris@0: Chris@0: should_respond_with :success Chris@0: should_respond_with_content_type 'application/xml' Chris@0: end Chris@0: Chris@0: context "/index.json" do Chris@0: setup do Chris@0: get '/issues.json' Chris@0: end Chris@0: Chris@0: should_respond_with :success Chris@0: should_respond_with_content_type 'application/json' Chris@0: Chris@0: should 'return a valid JSON string' do Chris@0: assert ActiveSupport::JSON.decode(response.body) Chris@0: end Chris@0: end Chris@0: Chris@0: context "/index.xml with filter" do Chris@0: setup do Chris@0: get '/issues.xml?status_id=5' Chris@0: end Chris@0: Chris@0: should_respond_with :success Chris@0: should_respond_with_content_type 'application/xml' Chris@0: should "show only issues with the status_id" do Chris@0: assert_tag :tag => 'issues', Chris@0: :children => { :count => Issue.visible.count(:conditions => {:status_id => 5}), Chris@0: :only => { :tag => 'issue' } } Chris@0: end Chris@0: end Chris@0: Chris@0: context "/index.json with filter" do Chris@0: setup do Chris@0: get '/issues.json?status_id=5' Chris@0: end Chris@0: Chris@0: should_respond_with :success Chris@0: should_respond_with_content_type 'application/json' Chris@0: Chris@0: should 'return a valid JSON string' do Chris@0: assert ActiveSupport::JSON.decode(response.body) Chris@0: end Chris@0: Chris@0: should "show only issues with the status_id" do Chris@0: json = ActiveSupport::JSON.decode(response.body) Chris@0: status_ids_used = json.collect {|j| j['status_id'] } Chris@0: assert_equal 3, status_ids_used.length Chris@0: assert status_ids_used.all? {|id| id == 5 } Chris@0: end Chris@0: Chris@0: end Chris@0: Chris@0: context "/issues/1.xml" do Chris@0: setup do Chris@0: get '/issues/1.xml' Chris@0: end Chris@0: Chris@0: should_respond_with :success Chris@0: should_respond_with_content_type 'application/xml' Chris@0: end Chris@0: Chris@0: context "/issues/1.json" do Chris@0: setup do Chris@0: get '/issues/1.json' Chris@0: end Chris@0: Chris@0: should_respond_with :success Chris@0: should_respond_with_content_type 'application/json' Chris@0: Chris@0: should 'return a valid JSON string' do Chris@0: assert ActiveSupport::JSON.decode(response.body) Chris@0: end Chris@0: end Chris@0: Chris@0: context "POST /issues.xml" do Chris@0: setup do Chris@0: @issue_count = Issue.count Chris@0: @attributes = {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3} Chris@0: post '/issues.xml', {:issue => @attributes}, :authorization => credentials('jsmith') Chris@0: end Chris@0: Chris@0: should_respond_with :created Chris@0: should_respond_with_content_type 'application/xml' Chris@0: Chris@0: should "create an issue with the attributes" do Chris@0: assert_equal Issue.count, @issue_count + 1 Chris@0: Chris@0: issue = Issue.first(:order => 'id DESC') Chris@0: @attributes.each do |attribute, value| Chris@0: assert_equal value, issue.send(attribute) Chris@0: end Chris@0: end Chris@0: end Chris@0: Chris@0: context "POST /issues.xml with failure" do Chris@0: setup do Chris@0: @attributes = {:project_id => 1} Chris@0: post '/issues.xml', {:issue => @attributes}, :authorization => credentials('jsmith') Chris@0: end Chris@0: Chris@0: should_respond_with :unprocessable_entity Chris@0: should_respond_with_content_type 'application/xml' Chris@0: Chris@0: should "have an errors tag" do Chris@0: assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"} Chris@0: end Chris@0: end Chris@0: Chris@0: context "POST /issues.json" do Chris@0: setup do Chris@0: @issue_count = Issue.count Chris@0: @attributes = {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3} Chris@0: post '/issues.json', {:issue => @attributes}, :authorization => credentials('jsmith') Chris@0: end Chris@0: Chris@0: should_respond_with :created Chris@0: should_respond_with_content_type 'application/json' Chris@0: Chris@0: should "create an issue with the attributes" do Chris@0: assert_equal Issue.count, @issue_count + 1 Chris@0: Chris@0: issue = Issue.first(:order => 'id DESC') Chris@0: @attributes.each do |attribute, value| Chris@0: assert_equal value, issue.send(attribute) Chris@0: end Chris@0: end Chris@0: end Chris@0: Chris@0: context "POST /issues.json with failure" do Chris@0: setup do Chris@0: @attributes = {:project_id => 1} Chris@0: post '/issues.json', {:issue => @attributes}, :authorization => credentials('jsmith') Chris@0: end Chris@0: Chris@0: should_respond_with :unprocessable_entity Chris@0: should_respond_with_content_type 'application/json' Chris@0: Chris@0: should "have an errors element" do Chris@0: json = ActiveSupport::JSON.decode(response.body) Chris@0: assert_equal "can't be blank", json.first['subject'] Chris@0: end Chris@0: end Chris@0: Chris@0: context "PUT /issues/1.xml" do Chris@0: setup do Chris@0: @issue_count = Issue.count Chris@0: @journal_count = Journal.count chris@22: @attributes = {:subject => 'API update', :notes => 'A new note'} Chris@0: Chris@0: put '/issues/1.xml', {:issue => @attributes}, :authorization => credentials('jsmith') Chris@0: end Chris@0: Chris@0: should_respond_with :ok Chris@0: should_respond_with_content_type 'application/xml' Chris@0: Chris@0: should "not create a new issue" do Chris@0: assert_equal Issue.count, @issue_count Chris@0: end Chris@0: Chris@0: should "create a new journal" do Chris@0: assert_equal Journal.count, @journal_count + 1 Chris@0: end Chris@0: chris@22: should "add the note to the journal" do chris@22: journal = Journal.last chris@22: assert_equal "A new note", journal.notes chris@22: end chris@22: Chris@0: should "update the issue" do Chris@0: issue = Issue.find(1) Chris@0: @attributes.each do |attribute, value| chris@22: assert_equal value, issue.send(attribute) unless attribute == :notes Chris@0: end Chris@0: end Chris@0: Chris@0: end Chris@0: Chris@0: context "PUT /issues/1.xml with failed update" do Chris@0: setup do Chris@0: @attributes = {:subject => ''} Chris@0: @issue_count = Issue.count Chris@0: @journal_count = Journal.count Chris@0: Chris@0: put '/issues/1.xml', {:issue => @attributes}, :authorization => credentials('jsmith') Chris@0: end Chris@0: Chris@0: should_respond_with :unprocessable_entity Chris@0: should_respond_with_content_type 'application/xml' Chris@0: Chris@0: should "not create a new issue" do Chris@0: assert_equal Issue.count, @issue_count Chris@0: end Chris@0: Chris@0: should "not create a new journal" do Chris@0: assert_equal Journal.count, @journal_count Chris@0: end Chris@0: Chris@0: should "have an errors tag" do Chris@0: assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"} Chris@0: end Chris@0: end Chris@0: Chris@0: context "PUT /issues/1.json" do Chris@0: setup do Chris@0: @issue_count = Issue.count Chris@0: @journal_count = Journal.count chris@22: @attributes = {:subject => 'API update', :notes => 'A new note'} Chris@0: Chris@0: put '/issues/1.json', {:issue => @attributes}, :authorization => credentials('jsmith') Chris@0: end Chris@0: Chris@0: should_respond_with :ok Chris@0: should_respond_with_content_type 'application/json' Chris@0: Chris@0: should "not create a new issue" do Chris@0: assert_equal Issue.count, @issue_count Chris@0: end Chris@0: Chris@0: should "create a new journal" do Chris@0: assert_equal Journal.count, @journal_count + 1 Chris@0: end Chris@0: chris@22: should "add the note to the journal" do chris@22: journal = Journal.last chris@22: assert_equal "A new note", journal.notes chris@22: end chris@22: Chris@0: should "update the issue" do Chris@0: issue = Issue.find(1) Chris@0: @attributes.each do |attribute, value| chris@22: assert_equal value, issue.send(attribute) unless attribute == :notes Chris@0: end Chris@0: end chris@22: Chris@0: end Chris@0: Chris@0: context "PUT /issues/1.json with failed update" do Chris@0: setup do Chris@0: @attributes = {:subject => ''} Chris@0: @issue_count = Issue.count Chris@0: @journal_count = Journal.count Chris@0: Chris@0: put '/issues/1.json', {:issue => @attributes}, :authorization => credentials('jsmith') Chris@0: end Chris@0: Chris@0: should_respond_with :unprocessable_entity Chris@0: should_respond_with_content_type 'application/json' Chris@0: Chris@0: should "not create a new issue" do Chris@0: assert_equal Issue.count, @issue_count Chris@0: end Chris@0: Chris@0: should "not create a new journal" do Chris@0: assert_equal Journal.count, @journal_count Chris@0: end Chris@0: Chris@0: should "have an errors attribute" do Chris@0: json = ActiveSupport::JSON.decode(response.body) Chris@0: assert_equal "can't be blank", json.first['subject'] Chris@0: end Chris@0: end Chris@0: Chris@0: context "DELETE /issues/1.xml" do Chris@0: setup do Chris@0: @issue_count = Issue.count Chris@0: delete '/issues/1.xml', {}, :authorization => credentials('jsmith') Chris@0: end Chris@0: Chris@0: should_respond_with :ok Chris@0: should_respond_with_content_type 'application/xml' Chris@0: Chris@0: should "delete the issue" do Chris@0: assert_equal Issue.count, @issue_count -1 Chris@0: assert_nil Issue.find_by_id(1) Chris@0: end Chris@0: end Chris@0: Chris@0: context "DELETE /issues/1.json" do Chris@0: setup do Chris@0: @issue_count = Issue.count Chris@0: delete '/issues/1.json', {}, :authorization => credentials('jsmith') Chris@0: end Chris@0: Chris@0: should_respond_with :ok Chris@0: should_respond_with_content_type 'application/json' Chris@0: Chris@0: should "delete the issue" do Chris@0: assert_equal Issue.count, @issue_count -1 Chris@0: assert_nil Issue.find_by_id(1) Chris@0: end Chris@0: end Chris@0: Chris@0: def credentials(user, password=nil) Chris@0: ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user) Chris@0: end Chris@0: end