From ac60fc9c1c587ba1f600c7d17723d2b88f2b6bed Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Sun, 12 Dec 2010 17:00:52 +0000 Subject: [PATCH] Refactor and add tests for News #index API (#7072). git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@4505 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/controllers/news_controller.rb | 25 +++++-- app/models/news.rb | 5 ++ app/views/news/index.api.rsb | 14 ++++ test/fixtures/enabled_modules.yml | 4 ++ test/fixtures/news.yml | 9 +++ test/integration/api_test/news_test.rb | 94 ++++++++++++++++++++++++++ 6 files changed, 144 insertions(+), 7 deletions(-) create mode 100644 app/views/news/index.api.rsb create mode 100644 test/integration/api_test/news_test.rb diff --git a/app/controllers/news_controller.rb b/app/controllers/news_controller.rb index eebc0ba02..e7c643e90 100644 --- a/app/controllers/news_controller.rb +++ b/app/controllers/news_controller.rb @@ -26,15 +26,26 @@ class NewsController < ApplicationController accept_key_auth :index def index - @news_pages, @newss = paginate :news, - :per_page => 10, - :conditions => Project.allowed_to_condition(User.current, :view_news, :project => @project), - :include => [:author, :project], - :order => "#{News.table_name}.created_on DESC" + case params[:format] + when 'xml', 'json' + @offset, @limit = api_offset_and_limit + else + @limit = 10 + end + + scope = @project ? @project.news.visible : News.visible + + @news_count = scope.count + @news_pages = Paginator.new self, @news_count, @limit, params['page'] + @offset ||= @news_pages.current.offset + @newss = scope.all(:include => [:author, :project], + :order => "#{News.table_name}.created_on DESC", + :offset => @offset, + :limit => @limit) + respond_to do |format| format.html { render :layout => false if request.xhr? } - format.xml { render :xml => @newss.to_xml } - format.json { render :json => @newss.to_json } + format.api format.atom { render_feed(@newss, :title => (@project ? @project.name : Setting.app_title) + ": #{l(:label_news_plural)}") } end end diff --git a/app/models/news.rb b/app/models/news.rb index a167cdf38..00729f06c 100644 --- a/app/models/news.rb +++ b/app/models/news.rb @@ -29,6 +29,11 @@ class News < ActiveRecord::Base acts_as_activity_provider :find_options => {:include => [:project, :author]}, :author_key => :author_id + named_scope :visible, lambda {|*args| { + :include => :project, + :conditions => Project.allowed_to_condition(args.first || User.current, :view_news) + }} + def visible?(user=User.current) !user.nil? && user.allowed_to?(:view_news, project) end diff --git a/app/views/news/index.api.rsb b/app/views/news/index.api.rsb new file mode 100644 index 000000000..2cacbc7f8 --- /dev/null +++ b/app/views/news/index.api.rsb @@ -0,0 +1,14 @@ +api.array :news, api_meta(:total_count => @news_count, :offset => @offset, :limit => @limit) do + @newss.each do |news| + api.news do + api.id news.id + api.project(:id => news.project_id, :name => news.project.name) unless news.project.nil? + api.author(:id => news.author_id, :name => news.author.name) unless news.author.nil? + + api.title news.title + api.summary news.summary + api.description news.description + api.created_on news.created_on + end + end +end diff --git a/test/fixtures/enabled_modules.yml b/test/fixtures/enabled_modules.yml index 5f2ba63d1..3b4eb7ace 100644 --- a/test/fixtures/enabled_modules.yml +++ b/test/fixtures/enabled_modules.yml @@ -95,3 +95,7 @@ enabled_modules_024: name: gantt project_id: 5 id: 24 +enabled_modules_025: + name: news + project_id: 2 + id: 25 diff --git a/test/fixtures/news.yml b/test/fixtures/news.yml index 1819095ce..9876065e1 100644 --- a/test/fixtures/news.yml +++ b/test/fixtures/news.yml @@ -20,3 +20,12 @@ news_002: summary: eCookbook 1.0 have downloaded 100,000 times author_id: 2 comments_count: 0 +news_003: + created_on: 2006-07-19 22:42:58 +02:00 + project_id: 2 + title: News on a private project + id: 3 + description: This is a private news + summary: + author_id: 2 + comments_count: 0 diff --git a/test/integration/api_test/news_test.rb b/test/integration/api_test/news_test.rb new file mode 100644 index 000000000..2d09e6d4c --- /dev/null +++ b/test/integration/api_test/news_test.rb @@ -0,0 +1,94 @@ +# Redmine - project management software +# Copyright (C) 2006-2010 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.dirname(__FILE__)}/../../test_helper" +require 'pp' +class ApiTest::NewsTest < ActionController::IntegrationTest + fixtures :all + + def setup + Setting.rest_api_enabled = '1' + end + + context "GET /news" do + context ".xml" do + should "return news" do + get '/news.xml' + + assert_tag :tag => 'news', + :attributes => {:type => 'array'}, + :child => { + :tag => 'news', + :child => { + :tag => 'id', + :content => '2' + } + } + end + end + + context ".json" do + 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 + end + end + + context "GET /projects/:project_id/news" do + context ".xml" do + should_allow_api_authentication(:get, "/projects/onlinestore/news.xml") + + should "return news" do + get '/projects/ecookbook/news.xml' + + assert_tag :tag => 'news', + :attributes => {:type => 'array'}, + :child => { + :tag => 'news', + :child => { + :tag => 'id', + :content => '2' + } + } + end + end + + context ".json" do + should_allow_api_authentication(:get, "/projects/onlinestore/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 + end + end + + def credentials(user, password=nil) + ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user) + end +end