# frozen_string_literal: true # Redmine - project management software # Copyright (C) 2006-2023 Jean-Philippe Lang # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require File.expand_path('../../../test_helper', __FILE__) class Redmine::ApiTest::NewsTest < Redmine::ApiTest::Base fixtures :projects, :trackers, :issue_statuses, :issues, :enumerations, :users, :issue_categories, :projects_trackers, :roles, :member_roles, :members, :enabled_modules, :news, :comments, :attachments test "GET /news.xml should return news" do get '/news.xml' assert_select 'news[type=array] news id', :text => '2' end test "GET /news.json should return news" do get '/news.json' json = ActiveSupport::JSON.decode(response.body) assert_kind_of Hash, json assert_kind_of Array, json['news'] assert_kind_of Hash, json['news'].first assert_equal 2, json['news'].first['id'] end test "GET /projects/:project_id/news.xml should return news" do get '/projects/ecookbook/news.xml' assert_select 'news[type=array] news id', :text => '2' end test "GET /projects/:project_id/news.json should return news" do get '/projects/ecookbook/news.json' json = ActiveSupport::JSON.decode(response.body) assert_kind_of Hash, json assert_kind_of Array, json['news'] assert_kind_of Hash, json['news'].first assert_equal 2, json['news'].first['id'] end test "GET /news/:id.xml" do get "/news/1.xml" assert_response :success assert_equal 'application/xml', response.media_type assert_select 'news' do assert_select 'id', 1 assert_select "project[id=1][name=\"eCookbook\"]" assert_select "author[id=2][name=\"John Smith\"]" assert_select 'title', 'eCookbook first release !' assert_select 'summary', 'First version was released...' assert_select 'description', "eCookbook 1.0 has been released.\n\nVisit http://ecookbook.somenet.foo/" assert_select 'created_on', News.find(1).created_on.iso8601 end end test "GET /news/:id.json" do get "/news/1.json" assert_response :success assert_equal 'application/json', response.media_type json = ActiveSupport::JSON.decode(response.body) assert_equal 1, json['news']['id'] end test "GET /news/:id.xml with attachments" do news = News.find(1) attachment = Attachment.first attachment.container = news attachment.save! get "/news/1.xml?include=attachments" assert_select 'news attachments[type=array]' do assert_select 'attachment id', :text => '1' do assert_select '~ filename', :text => 'error281.txt' assert_select '~ content_url', :text => 'http://www.example.com/attachments/download/1/error281.txt' end end end test "GET /news/:id.xml with comments" do get "/news/1.xml?include=comments" assert_select 'news comments[type=array]' do assert_select 'comment', 2 assert_select 'comment[id=1]' do assert_select 'author[id=1][name="Redmine Admin"]' assert_select 'content', :text => 'my first comment' end assert_select 'comment[id=2]' do assert_select 'author[id=2][name="John Smith"]' assert_select 'content', :text => 'This is an other comment' end end end test "POST /project/:project_id/news.xml should create a news with the attributes" do payload = <<~XML NewsXmlApiTest News XML-API Test This is the description XML assert_difference('News.count') do post( '/projects/1/news.xml', :params => payload, :headers => {"CONTENT_TYPE" => 'application/xml'}.merge(credentials('jsmith'))) end news = News.find_by(:title => 'NewsXmlApiTest') assert_not_nil news assert_equal 'News XML-API Test', news.summary assert_equal 'This is the description', news.description assert_equal User.find_by_login('jsmith'), news.author assert_equal Project.find(1), news.project assert_response :no_content end test "POST /project/:project_id/news.xml with failure should return errors" do assert_no_difference('News.count') do post( '/projects/1/news.xml', :params => {:news => {:title => ''}}, :headers => credentials('jsmith')) end assert_select 'errors error', :text => "Title cannot be blank" end test "POST /project/:project_id/news.json should create a news with the attributes" do payload = <<~JSON { "news": { "title": "NewsJsonApiTest", "summary": "News JSON-API Test", "description": "This is the description" } } JSON assert_difference('News.count') do post( '/projects/1/news.json', :params => payload, :headers => {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))) end news = News.find_by(:title => 'NewsJsonApiTest') assert_not_nil news assert_equal 'News JSON-API Test', news.summary assert_equal 'This is the description', news.description assert_equal User.find_by_login('jsmith'), news.author assert_equal Project.find(1), news.project assert_response :no_content end test "POST /project/:project_id/news.json with failure should return errors" do assert_no_difference('News.count') do post( '/projects/1/news.json', :params => {:news => {:title => ''}}, :headers => credentials('jsmith')) end json = ActiveSupport::JSON.decode(response.body) assert json['errors'].include?("Title cannot be blank") end test "POST /project/:project_id/news.xml with attachment should create a news with attachment" do token = xml_upload('test_create_with_attachment', credentials('jsmith')) attachment = Attachment.find_by_token(token) assert_difference 'News.count' do post( '/projects/1/news.xml', :params => {:news => {:title => 'News XML-API with Attachment', :description => 'desc'}, :attachments => [{:token => token, :filename => 'test.txt', :content_type => 'text/plain'}]}, :headers => credentials('jsmith')) assert_response :no_content end news = News.find_by(:title => 'News XML-API with Attachment') assert_equal attachment, news.attachments.first attachment.reload assert_equal 'test.txt', attachment.filename assert_equal 'text/plain', attachment.content_type assert_equal 'test_create_with_attachment'.size, attachment.filesize assert_equal 2, attachment.author_id end test "POST /project/:project_id/news.xml with multiple attachment should create a news with attachments" do token1 = xml_upload('File content 1', credentials('jsmith')) token2 = xml_upload('File content 2', credentials('jsmith')) payload = <<~XML News XML-API with attachments News with multiple attachments #{token1} test1.txt #{token2} test2.txt XML assert_difference('News.count') do post( '/projects/1/news.xml', :params => payload, :headers => {"CONTENT_TYPE" => 'application/xml'}.merge(credentials('jsmith'))) assert_response :no_content end news = News.find_by(:title => 'News XML-API with attachments') assert_equal 2, news.attachments.count end test "POST /project/:project_id/news.json with multiple attachment should create a news with attachments" do token1 = json_upload('File content 1', credentials('jsmith')) token2 = json_upload('File content 2', credentials('jsmith')) payload = <<~JSON { "news": { "title": "News JSON-API with attachments", "description": "News with multiple attachments", "uploads": [ {"token": "#{token1}", "filename": "test1.txt"}, {"token": "#{token2}", "filename": "test2.txt"} ] } } JSON assert_difference('News.count') do post( '/projects/1/news.json', :params => payload, :headers => {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))) assert_response :no_content end news = News.find_by(:title => 'News JSON-API with attachments') assert_equal 2, news.attachments.count end test "PUT /news/:id.xml" do payload = <<~XML NewsUpdateXmlApiTest News Update XML-API Test update description via xml api XML put( '/news/1.xml', :params => payload, :headers => {"CONTENT_TYPE" => 'application/xml'}.merge(credentials('jsmith'))) news = News.find(1) assert_equal 'NewsUpdateXmlApiTest', news.title assert_equal 'News Update XML-API Test', news.summary assert_equal 'update description via xml api', news.description end test "PUT /news/:id.json" do payload = <<~JSON { "news": { "title": "NewsUpdateJsonApiTest", "summary": "News Update JSON-API Test", "description": "update description via json api" } } JSON put( '/news/1.json', :params => payload, :headers => {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))) news = News.find(1) assert_equal 'NewsUpdateJsonApiTest', news.title assert_equal 'News Update JSON-API Test', news.summary assert_equal 'update description via json api', news.description end test "PUT /news/:id.xml with failed update" do put( '/news/1.xml', :params => {:news => {:title => ''}}, :headers => credentials('jsmith')) assert_response :unprocessable_entity assert_select 'errors error', :text => "Title cannot be blank" end test "PUT /news/:id.json with failed update" do put( '/news/1.json', :params => {:news => {:title => ''}}, :headers => credentials('jsmith')) assert_response :unprocessable_entity json = ActiveSupport::JSON.decode(response.body) assert json['errors'].include?("Title cannot be blank") end test "PUT /news/:id.xml with multiple attachment should update a news with attachments" do token1 = xml_upload('File content 1', credentials('jsmith')) token2 = xml_upload('File content 2', credentials('jsmith')) payload = <<~XML News Update XML-API with attachments #{token1} test1.txt #{token2} test2.txt XML put( '/news/1.xml', :params => payload, :headers => {"CONTENT_TYPE" => 'application/xml'}.merge(credentials('jsmith'))) assert_response :no_content news = News.find_by(:title => 'News Update XML-API with attachments') assert_equal 2, news.attachments.count end test "PUT /news/:id.json with multiple attachment should update a news with attachments" do token1 = json_upload('File content 1', credentials('jsmith')) token2 = json_upload('File content 2', credentials('jsmith')) payload = <<~JSON { "news": { "title": "News Update JSON-API with attachments", "uploads": [ {"token": "#{token1}", "filename": "test1.txt"}, {"token": "#{token2}", "filename": "test2.txt"} ] } } JSON put( '/news/1.json', :params => payload, :headers => {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))) assert_response :no_content news = News.find_by(:title => 'News Update JSON-API with attachments') assert_equal 2, news.attachments.count end test "DELETE /news/:id.xml" do assert_difference('News.count', -1) do delete '/news/1.xml', :headers => credentials('jsmith') assert_response :no_content assert_equal '', response.body end assert_nil News.find_by_id(1) end test "DELETE /news/:id.json" do assert_difference('News.count', -1) do delete '/news/1.json', :headers => credentials('jsmith') assert_response :no_content assert_equal '', response.body end assert_nil News.find_by_id(6) end end