]> source.dussan.org Git - redmine.git/commitdiff
"Add news" button in cross-project News tab (#33167).
authorGo MAEDA <maeda@farend.jp>
Thu, 25 Mar 2021 05:16:54 +0000 (05:16 +0000)
committerGo MAEDA <maeda@farend.jp>
Thu, 25 Mar 2021 05:16:54 +0000 (05:16 +0000)
Patch by Mizuki ISHIKAWA.

git-svn-id: http://svn.redmine.org/redmine/trunk@20845 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/controllers/news_controller.rb
app/views/news/_form.html.erb
app/views/news/index.html.erb
app/views/news/new.html.erb
config/routes.rb
test/functional/news_controller_test.rb
test/integration/routing/news_test.rb

index fa6a62244539e4124686da057a19c7c04392bfc7..7f752fbc22764809e477fafd0c1da3294ebeff4b 100644 (file)
@@ -22,9 +22,9 @@ class NewsController < ApplicationController
   model_object News
   before_action :find_model_object, :except => [:new, :create, :index]
   before_action :find_project_from_association, :except => [:new, :create, :index]
-  before_action :find_project_by_project_id, :only => [:new, :create]
-  before_action :authorize, :except => [:index]
-  before_action :find_optional_project, :only => :index
+  before_action :find_project_by_project_id, :only => :create
+  before_action :authorize, :except => [:index, :new]
+  before_action :find_optional_project, :only => [:index, :new]
   accept_rss_auth :index
   accept_api_auth :index, :show, :create, :update, :destroy
 
@@ -72,6 +72,8 @@ class NewsController < ApplicationController
   end
 
   def new
+    raise ::Unauthorized unless User.current.allowed_to?(:manage_news, @project, :global => true)
+
     @news = News.new(:project => @project, :author => User.current)
   end
 
@@ -84,7 +86,7 @@ class NewsController < ApplicationController
         format.html do
           render_attachment_warning_if_needed(@news)
           flash[:notice] = l(:notice_successful_create)
-          redirect_to project_news_index_path(@project)
+          redirect_to params[:cross_project] ? news_index_path : project_news_index_path(@project)
         end
         format.api  {render_api_ok}
       end
index a441b671dc074cad77202ca5e8f428fbacbe4dbc..8ce430732d9d64ae758189e8087ad523357cf3d5 100644 (file)
@@ -1,6 +1,13 @@
 <%= error_messages_for @news %>
 
 <div class="box tabular">
+<% if @project.nil? %>
+  <p>
+    <label><%= l(:field_project) %> <span class="required">*</span></label>
+    <%= select_tag :project_id, options_for_select(project_tree_options_for_select(Project.allowed_to(:manage_news).to_a), Project.allowed_to(:manage_news).first), {:required => true} %>
+    <%= hidden_field_tag :cross_project, 1, id: nil %>
+  </p>
+<% end %>
 <p><%= f.text_field :title, :required => true, :size => 60 %></p>
 <p><%= f.text_area :summary, :cols => 60, :rows => 2 %></p>
 <p><%= f.text_area :description, :required => true, :cols => 60, :rows => 15, :class => 'wiki-edit',
index 073099f5630cdddaf663226b0d84f5082c598e93..3a8f1ccb2d3689b43903ff33342e86689e25153c 100644 (file)
@@ -1,19 +1,19 @@
 <div class="contextual">
 <%= link_to(l(:label_news_new),
-            new_project_news_path(@project),
+            (@project ? project_news_index_path(@project) : news_index_path),
             :class => 'icon icon-add',
-            :onclick => 'showAndScrollTo("add-news", "news_title"); return false;') if @project && User.current.allowed_to?(:manage_news, @project) %>
+            :onclick => 'showAndScrollTo("add-news", "news_title"); return false;') if (@project.nil? || (@project && User.current.allowed_to?(:manage_news, @project))) %>
 <%= watcher_link(@project.enabled_module('news'), User.current) if @project && User.current.logged? %>
 </div>
 
 <div id="add-news" style="display:none;">
 <h2><%=l(:label_news_new)%></h2>
-<%= labelled_form_for @news, :url => project_news_index_path(@project),
+<%= labelled_form_for @news, :url => (@project ? project_news_index_path(@project) : news_index_path),
                                            :html => { :id => 'news-form', :multipart => true } do |f| %>
 <%= render :partial => 'news/form', :locals => { :f => f } %>
 <%= submit_tag l(:button_create) %>
 <%= link_to l(:button_cancel), "#", :onclick => '$("#add-news").hide()' %>
-<% end if @project %>
+<% end %>
 </div>
 
 <h2><%=l(:label_news_plural)%></h2>
index cf57140b8c32baf097912445c8d68a176ae586ff..6ac32008d0ff8e6e8024712b3c77eb9a7805db93 100644 (file)
@@ -1,6 +1,6 @@
 <h2><%=l(:label_news_new)%></h2>
 
-<%= labelled_form_for @news, :url => project_news_index_path(@project),
+<%= labelled_form_for @news, :url => (@project ? project_news_index_path(@project) : news_index_path),
                                            :html => { :id => 'news-form', :multipart => true } do |f| %>
   <%= render :partial => 'news/form', :locals => { :f => f } %>
   <%= submit_tag l(:button_create) %>
index 40c1d5f50593df40f99551ece95087844fe8574c..93ca77b5c3a956ff7b624561da266c24ac07dc71 100644 (file)
@@ -229,7 +229,7 @@ Rails.application.routes.draw do
   resources :queries, :except => [:show]
   get '/queries/filter', :to => 'queries#filter', :as => 'queries_filter'
 
-  resources :news, :only => [:index, :show, :edit, :update, :destroy]
+  resources :news, :only => [:index, :show, :edit, :update, :destroy, :create, :new]
   match '/news/:id/comments', :to => 'comments#create', :via => :post
   match '/news/:id/comments/:comment_id', :to => 'comments#destroy', :via => :delete
 
index 76517e1a1dd29775073831605d93b65e8e4ababc..c6545fa15dabe150701e9bd9b1a9a33c898c2ea1 100644 (file)
@@ -87,13 +87,32 @@ class NewsControllerTest < Redmine::ControllerTest
     assert_response 404
   end
 
-  def test_get_new
+  def test_get_new_with_project_id
     @request.session[:user_id] = 2
     get(:new, :params => {:project_id => 1})
     assert_response :success
+    assert_select 'select[name=project_id]', false
     assert_select 'input[name=?]', 'news[title]'
   end
 
+  def test_get_new_without_project_id
+    @request.session[:user_id] = 2
+    get(:new)
+    assert_response :success
+    assert_select 'select[name=project_id]'
+    assert_select 'input[name=?]', 'news[title]'
+  end
+
+  def test_get_new_if_user_does_not_have_permission
+    @request.session[:user_id] = 2
+    User.find(2).roles.each{|u| u.remove_permission! :manage_news }
+
+    get(:new)
+    assert_response :forbidden
+    assert_select 'select[name=project_id]', false
+    assert_select 'input[name=?]', 'news[title]', count: 0
+  end
+
   def test_post_create
     ActionMailer::Base.deliveries.clear
     @request.session[:user_id] = 2
@@ -121,6 +140,34 @@ class NewsControllerTest < Redmine::ControllerTest
     assert_equal 2, ActionMailer::Base.deliveries.size
   end
 
+  def test_post_create_with_cross_project_param
+    ActionMailer::Base.deliveries.clear
+    @request.session[:user_id] = 2
+
+    with_settings :notified_events => %w(news_added) do
+      post(
+        :create,
+        :params => {
+          :project_id => 1,
+          :cross_project => '1',
+          :news => {
+            :title => 'NewsControllerTest',
+            :description => 'This is the description',
+            :summary => ''
+          }
+        }
+      )
+    end
+    assert_redirected_to '/news'
+
+    news = News.find_by(title: 'NewsControllerTest')
+    assert_not_nil news
+    assert_equal 'This is the description', news.description
+    assert_equal User.find(2), news.author
+    assert_equal Project.find(1), news.project
+    assert_equal 2, ActionMailer::Base.deliveries.size
+  end
+
   def test_post_create_with_attachment
     set_tmp_attachments_directory
     ActionMailer::Base.deliveries.clear
index 8e62da7742e0e99ac56a89a29088dabb3b78b1a5..7863fad5fee9e3348097a80c0d79ba1eef93512a 100644 (file)
@@ -29,6 +29,8 @@ class RoutingNewsTest < Redmine::RoutingTest
 
   def test_news
     should_route 'GET /news' => 'news#index'
+    should_route 'GET /news/new' => 'news#new'
+    should_route 'POST /news' => 'news#create'
     should_route 'GET /news.atom' => 'news#index', :format => 'atom'
     should_route 'GET /news/2' => 'news#show', :id => '2'
     should_route 'GET /news/2/edit' => 'news#edit', :id => '2'