diff --git a/plugins/redmine_questions/.drone.jsonnet b/plugins/redmine_questions/.drone.jsonnet new file mode 100644 index 0000000..55d8ab7 --- /dev/null +++ b/plugins/redmine_questions/.drone.jsonnet @@ -0,0 +1,34 @@ +local Pipeline(rubyVer, db, license, redmine, dependents) = { + kind: "pipeline", + name: rubyVer + "-" + db + "-" + redmine + "-" + license + "-" + dependents, + steps: [ + { + name: "tests", + image: "redmineup/redmineup_ci", + commands: [ + "service postgresql start && service mysql start && sleep 5", + "export PATH=~/.rbenv/shims:$PATH", + "export CODEPATH=`pwd`", + "/root/run_for.sh redmine_questions+" + license + " ruby-" + rubyVer + " " + db + " redmine-" + redmine + " " + dependents + ] + } + ] +}; + +[ + Pipeline("2.4.1", "mysql", "pro", "trunk", ""), + Pipeline("2.4.1", "mysql", "light", "trunk", ""), + Pipeline("2.4.1", "pg", "pro", "trunk", ""), + Pipeline("2.4.1", "mysql", "pro", "4.1", ""), + Pipeline("2.4.1", "mysql", "light", "4.1", ""), + Pipeline("2.4.1", "pg", "pro", "4.1", ""), + Pipeline("2.4.1", "mysql", "pro", "4.0", ""), + Pipeline("2.4.1", "mysql", "light", "4.0", ""), + Pipeline("2.4.1", "pg", "pro", "4.0", ""), + Pipeline("2.4.1", "pg", "light", "4.0", ""), + Pipeline("2.2.6", "mysql", "pro", "3.4", ""), + Pipeline("2.2.6", "pg", "pro", "3.4", ""), + Pipeline("2.2.6", "mysql", "pro", "3.0", ""), + Pipeline("2.2.6", "mysql", "light", "3.0", ""), + Pipeline("1.9.3", "pg", "pro", "2.6", ""), +] diff --git a/plugins/redmine_questions/app/controllers/questions_answers_controller.rb b/plugins/redmine_questions/app/controllers/questions_answers_controller.rb index 7ebf11d..f28d247 100644 --- a/plugins/redmine_questions/app/controllers/questions_answers_controller.rb +++ b/plugins/redmine_questions/app/controllers/questions_answers_controller.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify @@ -34,9 +34,11 @@ class QuestionsAnswersController < ApplicationController end def edit + (render_403; return false) unless @answer.editable_by?(User.current) end def update + (render_403; return false) unless @answer.editable_by?(User.current) || User.current.allowed_to?(:accept_answers, @project) @answer.safe_attributes = params[:answer] @answer.save_attachments(params[:attachments]) if @answer.save @@ -87,7 +89,7 @@ class QuestionsAnswersController < ApplicationController private def redirect_to_question - redirect_to question_path(@answer.question, :anchor => "question_item_#{@answer.id}") + redirect_to question_path(@answer.question, :anchor => "questions_answer_#{@answer.id}") end def find_answer diff --git a/plugins/redmine_questions/app/controllers/questions_comments_controller.rb b/plugins/redmine_questions/app/controllers/questions_comments_controller.rb index 7c4512e..0887b64 100644 --- a/plugins/redmine_questions/app/controllers/questions_comments_controller.rb +++ b/plugins/redmine_questions/app/controllers/questions_comments_controller.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/app/controllers/questions_controller.rb b/plugins/redmine_questions/app/controllers/questions_controller.rb index 224844c..bc67eac 100644 --- a/plugins/redmine_questions/app/controllers/questions_controller.rb +++ b/plugins/redmine_questions/app/controllers/questions_controller.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify @@ -54,6 +54,7 @@ class QuestionsController < ApplicationController end def update + (render_403; return false) unless @question_item.editable_by?(User.current) @question_item.safe_attributes = params[:question] @question_item.save_attachments(params[:attachments]) if @question_item.save @@ -133,6 +134,7 @@ class QuestionsController < ApplicationController @text = (params[:question] ? params[:question][:content] : nil) render :partial => 'common/preview' end + private def find_questions @@ -142,10 +144,10 @@ class QuestionsController < ApplicationController scope = Question.visible scope = scope.where(:section_id => @section) if @section - columns = ["subject", "content"] - tokens = seach.to_s.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect{|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')}.uniq.select {|w| w.length > 1 } + columns = ['subject', 'content'] + tokens = seach.to_s.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect { |m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '') }.uniq.select { |w| w.length > 1 } tokens = [] << tokens unless tokens.is_a?(Array) - token_clauses = columns.collect {|column| "(LOWER(#{column}) LIKE ?)"} + token_clauses = columns.collect { |column| "(LOWER(#{column}) LIKE ?)" } sql = (['(' + token_clauses.join(' OR ') + ')'] * tokens.size).join(' AND ') find_options = [sql, * (tokens.collect {|w| "%#{w.downcase}%"} * token_clauses.size).sort] @@ -166,9 +168,9 @@ class QuestionsController < ApplicationController end @limit = per_page_option - @offset = params[:page].to_i*@limit + @offset = params[:page].to_i * @limit scope = scope.limit(@limit).offset(@offset) - scope = scope.tagged_with(params[:tag]) unless params[:tag].blank? + scope = scope.tagged_with(params[:tag]) if params[:tag].present? @topic_count = scope.count @topic_pages = Paginator.new @topic_count, @limit, params[:page] @@ -178,7 +180,7 @@ class QuestionsController < ApplicationController def find_section @section = QuestionsSection.find_by_id(params[:section_id] || (params[:question] && params[:question][:section_id])) - @section ||= @project.questions_sections.first + @section ||= @project.questions_sections.first if @project rescue ActiveRecord::RecordNotFound render_404 end diff --git a/plugins/redmine_questions/app/controllers/questions_sections_controller.rb b/plugins/redmine_questions/app/controllers/questions_sections_controller.rb index b33376d..a9bb37b 100644 --- a/plugins/redmine_questions/app/controllers/questions_sections_controller.rb +++ b/plugins/redmine_questions/app/controllers/questions_sections_controller.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify @@ -58,6 +58,7 @@ class QuestionsSectionsController < ApplicationController def update @section.safe_attributes = params[:questions_section] + @section.insert_at(@section.position) if @section.position_changed? if @section.save respond_to do |format| format.html do diff --git a/plugins/redmine_questions/app/controllers/questions_statuses_controller.rb b/plugins/redmine_questions/app/controllers/questions_statuses_controller.rb index 35db2e2..1acbc7c 100644 --- a/plugins/redmine_questions/app/controllers/questions_statuses_controller.rb +++ b/plugins/redmine_questions/app/controllers/questions_statuses_controller.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify @@ -39,12 +39,13 @@ class QuestionsStatusesController < ApplicationController end def create - @questions_status = QuestionsStatus.new(params[:questions_status]) + @questions_status = QuestionsStatus.new + @questions_status.safe_attributes = params[:questions_status] if request.post? && @questions_status.save flash[:notice] = l(:notice_successful_create) - redirect_to :action => "plugin", :id => "redmine_questions", :controller => "settings", :tab => 'questions_statuses' + redirect_to action: 'plugin', id: 'redmine_questions', controller: 'settings', tab: 'questions_statuses' else - render :action => 'new' + render action: 'new' end end @@ -54,17 +55,18 @@ class QuestionsStatusesController < ApplicationController def update @questions_status = QuestionsStatus.find(params[:id]) - if @questions_status.update_attributes(params[:questions_status]) + @questions_status.safe_attributes = params[:questions_status] + if @questions_status.save respond_to do |format| format.html { flash[:notice] = l(:notice_successful_update) - redirect_to :action => 'plugin', :id => 'redmine_questions', :controller => 'settings', :tab => 'questions_statuses' + redirect_to action: 'plugin', id: 'redmine_questions', controller: 'settings', tab: 'questions_statuses' } format.js { head 200 } end else respond_to do |format| - format.html { render :action => 'edit' } + format.html { render action: 'edit' } format.js { head 422 } end end @@ -72,11 +74,9 @@ class QuestionsStatusesController < ApplicationController def destroy QuestionsStatus.find(params[:id]).destroy - redirect_to :action =>"plugin", :id => "redmine_questions", :controller => "settings", :tab => 'questions_statuses' + redirect_to action: 'plugin', id: 'redmine_questions', controller: 'settings', tab: 'questions_statuses' rescue flash[:error] = l(:error_products_unable_delete_questions_status) - redirect_to :action =>"plugin", :id => "redmine_questions", :controller => "settings", :tab => 'questions_statuses' + redirect_to action: 'plugin', id: 'redmine_questions', controller: 'settings', tab: 'questions_statuses' end - - end diff --git a/plugins/redmine_questions/app/helpers/questions_helper.rb b/plugins/redmine_questions/app/helpers/questions_helper.rb index a9e353c..c16eb61 100644 --- a/plugins/redmine_questions/app/helpers/questions_helper.rb +++ b/plugins/redmine_questions/app/helpers/questions_helper.rb @@ -3,7 +3,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/app/models/question.rb b/plugins/redmine_questions/app/models/question.rb index 99efbcd..c21af9b 100644 --- a/plugins/redmine_questions/app/models/question.rb +++ b/plugins/redmine_questions/app/models/question.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify @@ -54,22 +54,22 @@ class Question < ActiveRecord::Base :author_key => :author_id, :timestamp => "#{table_name}.created_on", :scope => joins({:section => :project}, :author) - acts_as_searchable :columns => ["#{table_name}.subject", - "#{table_name}.content", + acts_as_searchable :columns => ["#{table_name}.subject", + "#{table_name}.content", "#{QuestionsAnswer.table_name}.content"], - :scope => joins({:section => :project}, :answers), - :project_key => "#{QuestionsSection.table_name}.project_id" + :scope => joins({:section => :project}, :answers), + :project_key => "#{QuestionsSection.table_name}.project_id" else acts_as_activity_provider :type => 'questions', :permission => :view_questions, :author_key => :author_id, :timestamp => "#{table_name}.created_on", :find_options => { :include => [{:section => :project}, :author] } - acts_as_searchable :columns => ["#{table_name}.subject", - "#{table_name}.content", + acts_as_searchable :columns => ["#{table_name}.subject", + "#{table_name}.content", "#{QuestionsAnswer.table_name}.content"], :include => [{:section => :project}, :answers], - :project_key => "#{QuestionsSection.table_name}.project_id" + :project_key => "#{QuestionsSection.table_name}.project_id" end scope :solutions, lambda { joins(:section).where(:questions_sections => {:section_type => QuestionsSection::SECTION_TYPE_SOLUTIONS}) } @@ -114,7 +114,7 @@ class Question < ActiveRecord::Base allowed_to_view_condition += projects_allowed_to_view_questions.empty? ? ' OR (0=1) ' : " OR (#{table_name}.project_id IN (#{projects_allowed_to_view_questions.join(',')}))" user.admin? ? '(1=1)' : allowed_to_view_condition - end + end def self.related(question, limit) tokens = question.subject.strip.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}). @@ -127,7 +127,7 @@ class Question < ActiveRecord::Base end def commentable?(user = User.current) - return false if locked? + return false if locked? user.allowed_to?(:comment_question, project) end @@ -285,6 +285,6 @@ class Question < ActiveRecord::Base end def send_notification - Mailer.question_question_added(self).deliver if Setting.notified_events.include?('question_added') + Mailer.question_question_added(User.current, self).deliver if Setting.notified_events.include?('question_added') end end diff --git a/plugins/redmine_questions/app/models/questions_answer.rb b/plugins/redmine_questions/app/models/questions_answer.rb index b1e9f0f..39c46a7 100644 --- a/plugins/redmine_questions/app/models/questions_answer.rb +++ b/plugins/redmine_questions/app/models/questions_answer.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify @@ -97,6 +97,7 @@ class QuestionsAnswer < ActiveRecord::Base end def editable_by?(user) + (author == user && user.allowed_to?(:edit_own_answers, project)) || user.allowed_to?(:edit_questions, project) end @@ -107,7 +108,7 @@ class QuestionsAnswer < ActiveRecord::Base def votable_by?(user) user.allowed_to?(:vote_questions, project) end - + private def check_accepted question.answers.update_all(:accepted => false) if question && @@ -121,6 +122,6 @@ class QuestionsAnswer < ActiveRecord::Base end def send_notification - Mailer.question_answer_added(self).deliver if Setting.notified_events.include?('question_answer_added') + Mailer.question_answer_added(User.current, self).deliver if Setting.notified_events.include?('question_answer_added') end end diff --git a/plugins/redmine_questions/app/models/questions_section.rb b/plugins/redmine_questions/app/models/questions_section.rb index 1263bbf..44418c4 100644 --- a/plugins/redmine_questions/app/models/questions_section.rb +++ b/plugins/redmine_questions/app/models/questions_section.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify @@ -27,7 +27,12 @@ class QuestionsSection < ActiveRecord::Base attr_protected :id if ActiveRecord::VERSION::MAJOR <= 4 safe_attributes 'name', 'project', 'position', 'description', 'section_type' - scope :with_questions_count, lambda { select("#{QuestionsSection.table_name}.*, count(#{QuestionsSection.table_name}.id) as questions_count").joins(:questions).order("project_id ASC").group("#{QuestionsSection.table_name}.id, #{QuestionsSection.table_name}.name, #{QuestionsSection.table_name}.project_id, #{QuestionsSection.table_name}.section_type") } + scope :with_questions_count, lambda { + select("#{QuestionsSection.table_name}.*, count(#{QuestionsSection.table_name}.id) as questions_count"). + joins(:questions). + order("project_id ASC"). + group(QuestionsSection.column_names.map { |column| "#{QuestionsSection.table_name}.#{column}" }.join(', ')) + } scope :for_project, lambda { |project| where(:project_id => project) unless project.blank? } scope :visible, lambda {|*args| joins(:project). diff --git a/plugins/redmine_questions/app/models/questions_settings.rb b/plugins/redmine_questions/app/models/questions_settings.rb index bd81f48..04168f6 100644 --- a/plugins/redmine_questions/app/models/questions_settings.rb +++ b/plugins/redmine_questions/app/models/questions_settings.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/app/models/questions_status.rb b/plugins/redmine_questions/app/models/questions_status.rb index 1014152..4400653 100644 --- a/plugins/redmine_questions/app/models/questions_status.rb +++ b/plugins/redmine_questions/app/models/questions_status.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify @@ -26,7 +26,7 @@ class QuestionsStatus < ActiveRecord::Base attr_protected :id if ActiveRecord::VERSION::MAJOR <= 4 safe_attributes 'name', 'is_closed', 'position', 'color' - validates :name, :presence => true, :uniqueness => true + validates :name, presence: true, uniqueness: true scope :sorted, lambda { order(:position) } diff --git a/plugins/redmine_questions/app/views/projects/_questions_settings.html.erb b/plugins/redmine_questions/app/views/projects/_questions_settings.html.erb index 9e38735..83b372e 100644 --- a/plugins/redmine_questions/app/views/projects/_questions_settings.html.erb +++ b/plugins/redmine_questions/app/views/projects/_questions_settings.html.erb @@ -1,36 +1,41 @@ +<% @project_sections = QuestionsSection.for_project(@project).sorted %>

<%= l(:label_questions_sections_plural) %>

- - - - - - - - - - <% QuestionsSection.for_project(@project).sorted.each do |section| %> - - - - +<% if @project_sections.any? %> +
<%= l(:field_name) %><%=l(:field_type)%>
- <%= h(section.name) %> - - <%= section.l_type %> - - <% if User.current.allowed_to?(:manage_sections, @project) %> - <%= reorder_handle(section, :url => project_questions_section_path(@project, section), :param => 'questions_section') if respond_to?(:reorder_handle) %> - <%= link_to l(:button_edit), {:controller => 'questions_sections', :action => 'edit', :project_id => @project, :id => section}, :class => 'icon icon-edit' %> - <%= delete_link :controller => 'questions_sections', :action => 'destroy', :project_id => @project, :id => section %> - <% end %> -
+ + + + + - <% end %> - -
<%= l(:field_name) %><%=l(:field_type)%>
+ + + <% @project_sections.each do |section| %> + + + <%= h(section.name) %> + + + <%= section.l_type %> + + + <% if User.current.allowed_to?(:manage_sections, @project) %> + <%= reorder_handle(section, url: project_questions_section_path(@project, section), param: 'questions_section') if respond_to?(:reorder_handle) %> + <%= link_to l(:button_edit), edit_questions_section_path(section, project_id: @project), class: 'icon icon-edit' %> + <%= delete_link questions_section_path(section, project_id: @project) %> + <% end %> + + + <% end %> + + +<% else %> +

<%= l(:label_no_data) %>

+<% end %> <% if User.current.allowed_to?(:manage_sections, @project) %> - <%= link_to image_tag('add.png', :style => 'vertical-align: middle;')+l(:label_questions_section_new), :controller => 'questions_sections', :action => 'new', :project_id => @project %> + <%= link_to image_tag('add.png', style: 'vertical-align: middle;') + l(:label_questions_section_new), new_questions_section_path(project_id: @project) %> <% end %> <%= javascript_tag do %> diff --git a/plugins/redmine_questions/app/views/questions/_form.html.erb b/plugins/redmine_questions/app/views/questions/_form.html.erb index 2f22e64..25c5411 100644 --- a/plugins/redmine_questions/app/views/questions/_form.html.erb +++ b/plugins/redmine_questions/app/views/questions/_form.html.erb @@ -6,7 +6,7 @@ <%= f.text_field :subject, :id => "question_subject", :size => 120%>


- <%= f.select :section_id, options_from_collection_for_select(QuestionsSection.where(:project_id => @project),:id, :name, f.object.section_id), :style => "width: 80%;", :required => true %> + <%= f.select :section_id, options_from_collection_for_select(QuestionsSection.where(:project_id => @project).sorted, :id, :name, f.object.section_id), :style => "width: 80%;", :required => true %> <%= javascript_tag do %> $('#question_section_id').change(function() { $.ajax({ diff --git a/plugins/redmine_questions/app/views/questions/_question_item.html.erb b/plugins/redmine_questions/app/views/questions/_question_item.html.erb index 738298b..986641e 100644 --- a/plugins/redmine_questions/app/views/questions/_question_item.html.erb +++ b/plugins/redmine_questions/app/views/questions/_question_item.html.erb @@ -1,6 +1,6 @@

div-table" id="question_<%= question_item.id %>"> - <% if question_item.allow_voting? && User.current.allowed_to?(:vote_questions, @project) %> + <% if question_item.allow_voting? %>
<%= render :partial => 'questions_votes/question_item_vote', :locals => {:question_item => question_item} %>
diff --git a/plugins/redmine_questions/app/views/questions/edit.html.erb b/plugins/redmine_questions/app/views/questions/edit.html.erb index 055f9a7..c3eab94 100644 --- a/plugins/redmine_questions/app/views/questions/edit.html.erb +++ b/plugins/redmine_questions/app/views/questions/edit.html.erb @@ -8,7 +8,8 @@ <%= render :partial => 'form', :locals => {:f => f} %>
<%= submit_tag l(:button_save) %> - <%= preview_link({:controller => 'questions', :action => 'preview', :question_id => @question_item}, 'question_form') %> + <%= preview_link({:controller => 'questions', :action => 'preview', :question_id => @question_item}, 'question_form') if Redmine::VERSION.to_s <= '3.4.5' %> + | <%= link_to l(:button_cancel), question_path(@question_item) %> <% end %>
diff --git a/plugins/redmine_questions/app/views/questions/index.html.erb b/plugins/redmine_questions/app/views/questions/index.html.erb index a364d69..00d33bf 100644 --- a/plugins/redmine_questions/app/views/questions/index.html.erb +++ b/plugins/redmine_questions/app/views/questions/index.html.erb @@ -19,7 +19,7 @@
<%= form_tag({:controller => "questions", :action => "index"}, :method => :get, :id => "query_form") do %> <%= text_field_tag(:topic_search, params[:topic_search], :autocomplete => "off", :class => "questions-search", :placeholder => l(:label_questions_search) ) %> - <%= javascript_tag "observeSearchfield('topic_search', 'topics_list', '#{ escape_javascript(autocomplete_for_subject_questions_path(:project_id => @project, :section_id => @section)) }')" %> + <%= javascript_tag "observeSearchfield('topic_search', 'topics_list', '#{ escape_javascript(autocomplete_for_subject_questions_path(:project_id => @project, :section_id => @section, :sort_order => @sort_order)) }')" %> <% end %>
diff --git a/plugins/redmine_questions/app/views/questions/new.html.erb b/plugins/redmine_questions/app/views/questions/new.html.erb index 48eae58..6dd25ca 100644 --- a/plugins/redmine_questions/app/views/questions/new.html.erb +++ b/plugins/redmine_questions/app/views/questions/new.html.erb @@ -1,12 +1,12 @@

<%= l(:label_message_new) %>

-<%= form_for @question_item, { :url => questions_path, :html => {:multipart => true, +<%= form_for @question_item, { :url => project_questions_path(@project, {}), :html => {:multipart => true, :id => 'question_form'}} do |f| %>
- <%= render :partial => 'form', :locals => {:f => f} %> + <%= render partial: 'form', locals: { f: f } %>
<%= submit_tag l(:button_create) %> - <% preview_link({:controller => 'questions', :action => 'preview', :id => @question_item}, 'question_form') %> + <% preview_link({ controller: 'questions', action: 'preview', id: @question_item }, 'question_form') if Redmine::VERSION.to_s <= '3.4.5' %> <% end %>
diff --git a/plugins/redmine_questions/app/views/questions_answers/_actions.html.erb b/plugins/redmine_questions/app/views/questions_answers/_actions.html.erb index bb3d84a..afecfa7 100644 --- a/plugins/redmine_questions/app/views/questions_answers/_actions.html.erb +++ b/plugins/redmine_questions/app/views/questions_answers/_actions.html.erb @@ -1,5 +1,11 @@
- <%= link_to(l(:button_edit), edit_questions_answer_path(question_item), :class => 'icon icon-edit') if question_item.editable_by?(User.current) %> - <%= link_to(l(:button_delete), questions_answer_path(question_item), :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'icon icon-del') if question_item.destroyable_by?(User.current) + <% if question_item.editable_by?(User.current) %> + <%= link_to(l(:button_edit), edit_questions_answer_path(question_item), :class => 'icon icon-edit') %> + <% elsif User.current.allowed_to?(:accept_answers, @project) && !question_item.accepted? %> + <%= link_to(l(:label_questions_accept), questions_answer_path(question_item, answer: {accepted: true}), method: :put, :class => 'icon icon-accept') %> + <% elsif User.current.allowed_to?(:accept_answers, @project) && question_item.accepted? %> + <%= link_to(l(:label_questions_discard), questions_answer_path(question_item, answer: {accepted: false}), method: :put, :class => 'icon icon-discard') %> + <% end %> + <%= link_to(l(:button_delete), questions_answer_path(question_item), :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'icon icon-del') if question_item.destroyable_by?(User.current) %>
diff --git a/plugins/redmine_questions/app/views/questions_answers/_answer_item.html.erb b/plugins/redmine_questions/app/views/questions_answers/_answer_item.html.erb index 01a39ca..c7e8a1b 100644 --- a/plugins/redmine_questions/app/views/questions_answers/_answer_item.html.erb +++ b/plugins/redmine_questions/app/views/questions_answers/_answer_item.html.erb @@ -1,6 +1,6 @@
- <% if question_item.allow_voting? && User.current.allowed_to?(:vote_questions, @project) %> + <% if question_item.allow_voting? %>
<%= render :partial => 'questions_votes/question_item_vote', :locals => {:question_item => question_item } %>
diff --git a/plugins/redmine_questions/app/views/questions_answers/edit.html.erb b/plugins/redmine_questions/app/views/questions_answers/edit.html.erb index ea448b8..bb93a46 100644 --- a/plugins/redmine_questions/app/views/questions_answers/edit.html.erb +++ b/plugins/redmine_questions/app/views/questions_answers/edit.html.erb @@ -5,8 +5,8 @@ <%= back_url_hidden_field_tag %> <%= render :partial => 'form', :locals => {:f => f} %> <%= submit_tag l(:button_save) %> - <%= preview_link(preview_questions_answers_path(@answer), 'answer-form') %> - + <%= preview_link(preview_questions_answers_path(@answer), 'answer-form') if Redmine::VERSION.to_s <= '3.4.5' %> + | <%= link_to l(:button_cancel), question_path(@answer.question, :anchor => "question_item_#{@answer.id}") %> <% end %>
diff --git a/plugins/redmine_questions/app/views/questions_sections/_tiles.html.erb b/plugins/redmine_questions/app/views/questions_sections/_tiles.html.erb index 44420f3..c94109f 100644 --- a/plugins/redmine_questions/app/views/questions_sections/_tiles.html.erb +++ b/plugins/redmine_questions/app/views/questions_sections/_tiles.html.erb @@ -1,29 +1,25 @@ -<% previous_group = false %> -
-<% @sections.each do |section| %> - <% if @project.blank? && (group = section.project) != previous_group %> - <% reset_cycle %> +<% @sections.group_by(&:project).each do |project, sections| %> + <% if @project.blank? %> +
+

+ <%= project.name %> + <%= link_to " \xc2\xbb", project_questions_sections_path(project_id: project.identifier) %> +

- <% if group %> -
-

- <%= group.name %> - <%= link_to " \xc2\xbb", project_questions_sections_path(:project_id => group.identifier) %> -

-
- <% end %> -
- <% previous_group = group %> <% end %> - - 'index', :section_id => section, :project_id => section.project}) %>" id="section_<%= section.id %>" class="section-tile"> -

- <%= section.name %> - <%= "(#{section.questions_count})" %> -

-
- <%= section.description %> -
-
+ + <% end %> - diff --git a/plugins/redmine_questions/app/views/questions_sections/index.html.erb b/plugins/redmine_questions/app/views/questions_sections/index.html.erb index d8aec00..43ff5b8 100644 --- a/plugins/redmine_questions/app/views/questions_sections/index.html.erb +++ b/plugins/redmine_questions/app/views/questions_sections/index.html.erb @@ -26,4 +26,3 @@ <% content_for :header_tags do %> <%= javascript_include_tag :questions, :plugin => 'redmine_questions' %> <% end %> - diff --git a/plugins/redmine_questions/assets/images/accept.png b/plugins/redmine_questions/assets/images/accept.png new file mode 100644 index 0000000..89c8129 Binary files /dev/null and b/plugins/redmine_questions/assets/images/accept.png differ diff --git a/plugins/redmine_questions/assets/images/discard.png b/plugins/redmine_questions/assets/images/discard.png new file mode 100644 index 0000000..d793b74 Binary files /dev/null and b/plugins/redmine_questions/assets/images/discard.png differ diff --git a/plugins/redmine_questions/assets/stylesheets/redmine_questions.css b/plugins/redmine_questions/assets/stylesheets/redmine_questions.css index 7843900..203ed45 100644 --- a/plugins/redmine_questions/assets/stylesheets/redmine_questions.css +++ b/plugins/redmine_questions/assets/stylesheets/redmine_questions.css @@ -400,3 +400,5 @@ div.question.votable .question-container .contextual {margin-top: 0px;} .icon-tag { background-image: url(../images/tag_blue.png); } .icon-question { background-image: url(../../../images/help.png); } .icon-solution { background-image: url(../images/book_open.png); } +.icon-accept { background-image: url(../images/accept.png); } +.icon-discard { background-image: url(../images/discard.png); } \ No newline at end of file diff --git a/plugins/redmine_questions/config/locales/en.yml b/plugins/redmine_questions/config/locales/en.yml index 1c06d6c..467868c 100644 --- a/plugins/redmine_questions/config/locales/en.yml +++ b/plugins/redmine_questions/config/locales/en.yml @@ -169,4 +169,6 @@ en: permission_vote_questions: Vote questions permission_accept_answers: Accept answers permission_manage_sections: Manage sections - permission_create_tags: Create new tags \ No newline at end of file + permission_create_tags: Create new tags + label_questions_discard: Discard + permission_edit_own_answers: Edit own answers \ No newline at end of file diff --git a/plugins/redmine_questions/config/locales/es.yml b/plugins/redmine_questions/config/locales/es.yml index 82e27bb..b052764 100644 --- a/plugins/redmine_questions/config/locales/es.yml +++ b/plugins/redmine_questions/config/locales/es.yml @@ -22,8 +22,6 @@ es: field_questions_tags: Etiquetas - label_questions_most_popular: Más populares - permission_view_questions: Ver Ayuda y Soporte permission_edit_messages_tags: Editar etiquetas permission_edit_vote_messages: Votar mensajes \ No newline at end of file diff --git a/plugins/redmine_questions/config/locales/ru.yml b/plugins/redmine_questions/config/locales/ru.yml index a8c198d..bacd237 100644 --- a/plugins/redmine_questions/config/locales/ru.yml +++ b/plugins/redmine_questions/config/locales/ru.yml @@ -94,4 +94,6 @@ ru: permission_vote_questions: Голосовать за вопросы permission_accept_answers: Принимать ответы permission_manage_sections: Управлять секциями - permission_create_tags: Создавать новые тэги \ No newline at end of file + permission_create_tags: Создавать новые тэги + label_questions_discard: Не принимать + permission_edit_own_answers: Редактировать свои ответы diff --git a/plugins/redmine_questions/config/routes.rb b/plugins/redmine_questions/config/routes.rb index 9135b49..37d1162 100644 --- a/plugins/redmine_questions/config/routes.rb +++ b/plugins/redmine_questions/config/routes.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/db/migrate/001_acts_as_votable_migration.rb b/plugins/redmine_questions/db/migrate/001_acts_as_votable_migration.rb index 7f4787d..a172ce2 100644 --- a/plugins/redmine_questions/db/migrate/001_acts_as_votable_migration.rb +++ b/plugins/redmine_questions/db/migrate/001_acts_as_votable_migration.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/db/migrate/002_add_viewing_migration.rb b/plugins/redmine_questions/db/migrate/002_add_viewing_migration.rb index 63f04c0..71557c1 100644 --- a/plugins/redmine_questions/db/migrate/002_add_viewing_migration.rb +++ b/plugins/redmine_questions/db/migrate/002_add_viewing_migration.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/db/migrate/003_add_tagging_migration.rb b/plugins/redmine_questions/db/migrate/003_add_tagging_migration.rb index a54614e..e8b1fcc 100644 --- a/plugins/redmine_questions/db/migrate/003_add_tagging_migration.rb +++ b/plugins/redmine_questions/db/migrate/003_add_tagging_migration.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/db/migrate/004_create_questions.rb b/plugins/redmine_questions/db/migrate/004_create_questions.rb index 8165cf0..ed0665b 100644 --- a/plugins/redmine_questions/db/migrate/004_create_questions.rb +++ b/plugins/redmine_questions/db/migrate/004_create_questions.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/db/migrate/005_create_questions_sections.rb b/plugins/redmine_questions/db/migrate/005_create_questions_sections.rb index f53d117..d3db0a5 100644 --- a/plugins/redmine_questions/db/migrate/005_create_questions_sections.rb +++ b/plugins/redmine_questions/db/migrate/005_create_questions_sections.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/db/migrate/006_create_questions_answers.rb b/plugins/redmine_questions/db/migrate/006_create_questions_answers.rb index 2c984b2..8a14b85 100644 --- a/plugins/redmine_questions/db/migrate/006_create_questions_answers.rb +++ b/plugins/redmine_questions/db/migrate/006_create_questions_answers.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/db/migrate/007_create_questions_statuses.rb b/plugins/redmine_questions/db/migrate/007_create_questions_statuses.rb index 9fb72d0..a892ced 100644 --- a/plugins/redmine_questions/db/migrate/007_create_questions_statuses.rb +++ b/plugins/redmine_questions/db/migrate/007_create_questions_statuses.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/doc/CHANGELOG b/plugins/redmine_questions/doc/CHANGELOG index aee16f7..f371240 100755 --- a/plugins/redmine_questions/doc/CHANGELOG +++ b/plugins/redmine_questions/doc/CHANGELOG @@ -1,9 +1,27 @@ == Redmine Q&A plugin changelog Redmine Q&A plugin -Copyright (C) 2011-2018 RedmineUP +Copyright (C) 2011-2020 RedmineUP https://www.redmineup.com/ +== 2020-03-03 v1.0.2 + +* Redmine 4.1 support +* Fixed section position bug +* Fixed MSSQL group by bug +* Fixed "Help & Support" page layout + +== 2019-08-23 v1.0.1 + +* Accept answer links +* Edit own answers permission +* Redmine 4 support +* Fixed sorting by unanswered question not working +* Fixed project variable dismissed +* Fixed status creating bug +* Fixed preview link, empty project bug +* Fixed boards migration bug + == 2018-08-31 v1.0.0 * Separate models for questions, answers and comments diff --git a/plugins/redmine_questions/init.rb b/plugins/redmine_questions/init.rb index 0e373b3..caf83d0 100644 --- a/plugins/redmine_questions/init.rb +++ b/plugins/redmine_questions/init.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify @@ -17,11 +17,11 @@ # You should have received a copy of the GNU General Public License # along with redmine_questions. If not, see . -requires_redmine_crm version_or_higher: '0.0.38' +requires_redmine_crm version_or_higher: '0.0.41' require 'redmine_questions' -QA_VERSION_NUMBER = '1.0.0' +QA_VERSION_NUMBER = '1.0.2' QA_VERSION_TYPE = "Light version" Redmine::Plugin.register :redmine_questions do @@ -47,6 +47,7 @@ Redmine::Plugin.register :redmine_questions do permission :add_questions, { questions: [:create, :new, :preview, :update_form] } permission :edit_questions, { questions: [:edit, :update, :preview, :update_form], questions_answers: [:edit, :update, :preview] }, require: :loggedin permission :edit_own_questions, {questions: [:edit, :update, :preview, :update_form]}, require: :loggedin + permission :edit_own_answers, {questions_answers: [:edit, :update, :preview]}, require: :loggedin permission :add_answers, { questions_answers: [:create, :show, :new, :edit, :update, :preview] } permission :view_questions, { questions: [:index, :show, :autocomplete_for_subject], questions_sections: [:index] }, read: true permission :delete_questions, { questions: [:destroy] }, require: :loggedin diff --git a/plugins/redmine_questions/lib/acts_as_attachable_questions/init.rb b/plugins/redmine_questions/lib/acts_as_attachable_questions/init.rb index 92731f3..810d2d9 100755 --- a/plugins/redmine_questions/lib/acts_as_attachable_questions/init.rb +++ b/plugins/redmine_questions/lib/acts_as_attachable_questions/init.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/lib/acts_as_attachable_questions/lib/acts_as_attachable_questions.rb b/plugins/redmine_questions/lib/acts_as_attachable_questions/lib/acts_as_attachable_questions.rb index 61edb90..6c80c7f 100755 --- a/plugins/redmine_questions/lib/acts_as_attachable_questions/lib/acts_as_attachable_questions.rb +++ b/plugins/redmine_questions/lib/acts_as_attachable_questions/lib/acts_as_attachable_questions.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify @@ -70,6 +70,7 @@ module Redmine end def save_attachments(attachments, author = User.current) + attachments = attachments.to_unsafe_hash if attachments.respond_to?(:to_unsafe_hash) attachments = attachments.values if attachments.is_a?(Hash) if attachments.is_a?(Array) attachments.each do |attachment| diff --git a/plugins/redmine_questions/lib/redmine_questions.rb b/plugins/redmine_questions/lib/redmine_questions.rb index f74816b..36bd531 100644 --- a/plugins/redmine_questions/lib/redmine_questions.rb +++ b/plugins/redmine_questions/lib/redmine_questions.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify @@ -28,5 +28,3 @@ require_dependency 'redmine_questions/patches/auto_completes_controller_patch' require_dependency 'redmine_questions/patches/comment_patch' require_dependency 'acts_as_attachable_questions/init' - -require 'redmine_questions/patches/compatibility/application_controller_patch' if Rails::VERSION::MAJOR < 4 diff --git a/plugins/redmine_questions/lib/redmine_questions/hooks/views_layouts_hook.rb b/plugins/redmine_questions/lib/redmine_questions/hooks/views_layouts_hook.rb index 2405ae1..dc81601 100644 --- a/plugins/redmine_questions/lib/redmine_questions/hooks/views_layouts_hook.rb +++ b/plugins/redmine_questions/lib/redmine_questions/hooks/views_layouts_hook.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/lib/redmine_questions/patches/auto_completes_controller_patch.rb b/plugins/redmine_questions/lib/redmine_questions/patches/auto_completes_controller_patch.rb index 7449d84..9b9e451 100644 --- a/plugins/redmine_questions/lib/redmine_questions/patches/auto_completes_controller_patch.rb +++ b/plugins/redmine_questions/lib/redmine_questions/patches/auto_completes_controller_patch.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/lib/redmine_questions/patches/comment_patch.rb b/plugins/redmine_questions/lib/redmine_questions/patches/comment_patch.rb index 94146b7..8396721 100644 --- a/plugins/redmine_questions/lib/redmine_questions/patches/comment_patch.rb +++ b/plugins/redmine_questions/lib/redmine_questions/patches/comment_patch.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/lib/redmine_questions/patches/compatibility/application_controller_patch.rb b/plugins/redmine_questions/lib/redmine_questions/patches/compatibility/application_controller_patch.rb deleted file mode 100644 index 723eb8c..0000000 --- a/plugins/redmine_questions/lib/redmine_questions/patches/compatibility/application_controller_patch.rb +++ /dev/null @@ -1,37 +0,0 @@ -# This file is a part of Redmine Q&A (redmine_questions) plugin, -# Q&A plugin for Redmine -# -# Copyright (C) 2011-2018 RedmineUP -# http://www.redmineup.com/ -# -# redmine_questions 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 3 of the License, or -# (at your option) any later version. -# -# redmine_questions 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 redmine_questions. If not, see . - -module RedmineQuestions - module Patches - module ApplicationControllerPatch - def self.included(base) # :nodoc: - base.class_eval do - unloadable # Send unloadable so it will not be unloaded in development - class << self - alias_method :before_action, :before_filter - end - end - end - end - end -end - -unless ApplicationController.included_modules.include?(RedmineQuestions::Patches::ApplicationControllerPatch) - ApplicationController.send(:include, RedmineQuestions::Patches::ApplicationControllerPatch) -end diff --git a/plugins/redmine_questions/lib/redmine_questions/patches/mailer_patch.rb b/plugins/redmine_questions/lib/redmine_questions/patches/mailer_patch.rb index b0022af..f895146 100644 --- a/plugins/redmine_questions/lib/redmine_questions/patches/mailer_patch.rb +++ b/plugins/redmine_questions/lib/redmine_questions/patches/mailer_patch.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify @@ -20,8 +20,15 @@ module RedmineQuestions module Patches module MailerPatch + + module ClassMethods + def deliver_question_comment_added(comment) + question_comment_added(User.current, comment).deliver_later + end + end + module InstanceMethods - def question_comment_added(comment) + def question_comment_added(_user = User.current, comment) question = comment.commented.is_a?(Question) ? comment.commented : comment.commented.question @question_url = url_for(:controller => 'questions', :action => 'show', :id => question.id) project_identifier = question.project.try(:identifier) @@ -36,7 +43,7 @@ module RedmineQuestions :subject => "[#{project_prefix}] RE: #{question.subject}" end - def question_question_added(question) + def question_question_added(_user = Current.user, question) @question_url = url_for(:controller => 'questions', :action => 'show', :id => question.id) project_identifier = question.project.try(:identifier) redmine_headers 'Project' => project_identifier, 'Question-Id' => question.id @@ -51,9 +58,9 @@ module RedmineQuestions :subject => "[#{project_prefix}] #{question.subject}" end - def question_answer_added(answer) + def question_answer_added(_user = Current.user, answer) question = answer.question - @question_url = url_for(:controller => 'questions', :action => 'show', :id => question.id) + @question_url = url_for(controller: 'questions', action: 'show', id: question.id) project_identifier = question.project.try(:identifier) redmine_headers 'Project' => project_identifier, 'Question-Id' => question.id message_id question @@ -66,13 +73,14 @@ module RedmineQuestions @answer = answer @question = question project_prefix = [project_identifier, question.section_name, "q&a#{question.id}"].compact.join(' - ') - mail :to => recipients, - :cc => cc, - :subject => "[#{project_prefix}] - answ##{answer.id} - RE: #{question.subject}" + mail to: recipients, + cc: cc, + subject: "[#{project_prefix}] - answ##{answer.id} - RE: #{question.subject}" end end def self.included(receiver) + receiver.send :extend, ClassMethods receiver.send :include, InstanceMethods receiver.class_eval do unloadable diff --git a/plugins/redmine_questions/lib/redmine_questions/patches/notifiable_patch.rb b/plugins/redmine_questions/lib/redmine_questions/patches/notifiable_patch.rb index 578d435..87c79ca 100644 --- a/plugins/redmine_questions/lib/redmine_questions/patches/notifiable_patch.rb +++ b/plugins/redmine_questions/lib/redmine_questions/patches/notifiable_patch.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/lib/redmine_questions/patches/project_patch.rb b/plugins/redmine_questions/lib/redmine_questions/patches/project_patch.rb index cb9ef94..8390cc0 100644 --- a/plugins/redmine_questions/lib/redmine_questions/patches/project_patch.rb +++ b/plugins/redmine_questions/lib/redmine_questions/patches/project_patch.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/lib/redmine_questions/patches/projects_helper_patch.rb b/plugins/redmine_questions/lib/redmine_questions/patches/projects_helper_patch.rb index 96ba21a..2482f0d 100644 --- a/plugins/redmine_questions/lib/redmine_questions/patches/projects_helper_patch.rb +++ b/plugins/redmine_questions/lib/redmine_questions/patches/projects_helper_patch.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/lib/redmine_questions/patches/user_patch.rb b/plugins/redmine_questions/lib/redmine_questions/patches/user_patch.rb index e2467ad..b18d28d 100644 --- a/plugins/redmine_questions/lib/redmine_questions/patches/user_patch.rb +++ b/plugins/redmine_questions/lib/redmine_questions/patches/user_patch.rb @@ -1,7 +1,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/lib/tasks/migrate_from_boards.rake b/plugins/redmine_questions/lib/tasks/migrate_from_boards.rake index c13175b..9e2245e 100644 --- a/plugins/redmine_questions/lib/tasks/migrate_from_boards.rake +++ b/plugins/redmine_questions/lib/tasks/migrate_from_boards.rake @@ -38,13 +38,13 @@ END_DESC next end - question_attrs = topic.attributes.slice('subject', 'content', 'author_id', 'locked').merge('project_id' => project.try(:id)) + question_attrs = topic.attributes.slice('subject', 'content', 'author_id', 'locked') migrated_question = section.questions.create(question_attrs) migrated_question.attachments = topic.attachments.map { |attachment| attachment.copy } topic.children.each do |reply| if section.section_type == 'questions' - answer_attrs = reply.slice('subject', 'content', 'author_id', 'locked').merge('project_id' => project.try(:id)) + answer_attrs = reply.slice('subject', 'content', 'author_id', 'locked') migrated_answer = migrated_question.answers.create(answer_attrs) migrated_answer.attachments = reply.attachments.map { |attachment| attachment.copy } else diff --git a/plugins/redmine_questions/test/fixtures/questions_answers.yml b/plugins/redmine_questions/test/fixtures/questions_answers.yml index 1b9ff76..ec45b66 100644 --- a/plugins/redmine_questions/test/fixtures/questions_answers.yml +++ b/plugins/redmine_questions/test/fixtures/questions_answers.yml @@ -9,4 +9,10 @@ answer_002: content: This is answer for question_002 question_id: 2 author_id: 1 - accepted: false \ No newline at end of file + accepted: false +answer_003: + id: 3 + content: This is a second answer for question_001 + question_id: 1 + author_id: 3 + accepted: false \ No newline at end of file diff --git a/plugins/redmine_questions/test/fixtures/questions_statuses.yml b/plugins/redmine_questions/test/fixtures/questions_statuses.yml new file mode 100644 index 0000000..96f89bb --- /dev/null +++ b/plugins/redmine_questions/test/fixtures/questions_statuses.yml @@ -0,0 +1,10 @@ +section_001: + id: 1 + name: Open + color: green + is_closed: false +section_002: + id: 2 + name: Closed + color: red + is_closed: true diff --git a/plugins/redmine_questions/test/functional/questions_answers_controller_test.rb b/plugins/redmine_questions/test/functional/questions_answers_controller_test.rb index db5c126..41452ae 100644 --- a/plugins/redmine_questions/test/functional/questions_answers_controller_test.rb +++ b/plugins/redmine_questions/test/functional/questions_answers_controller_test.rb @@ -3,7 +3,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify @@ -79,7 +79,7 @@ class QuestionsAnswersControllerTest < ActionController::TestCase assert_redirected_to :controller => 'questions', :action => 'show', :id => question, - :anchor => "question_item_#{QuestionsAnswer.order(:id).last.id}" + :anchor => "questions_answer_#{QuestionsAnswer.order(:id).last.id}" assert_equal old_answer_count + 1, question.answers.count assert_equal 'Answer for the first question', question.answers.last.content end @@ -92,11 +92,7 @@ class QuestionsAnswersControllerTest < ActionController::TestCase :content => "Previewed answer", } assert_response :success - assert_select 'fieldset' do - assert_select 'legend', :text => 'Preview' - assert_select 'p', :text => 'Previewed answer' - end - + assert_select 'p', :text => 'Previewed answer' end def test_preview_edited_answer @@ -107,11 +103,7 @@ class QuestionsAnswersControllerTest < ActionController::TestCase :content => "Previewed answer 1", } assert_response :success - assert_select 'fieldset' do - assert_select 'legend', :text => 'Preview' - assert_select 'p', :text => 'Previewed answer 1' - end - + assert_select 'p', :text => 'Previewed answer 1' end def test_destroy @@ -121,7 +113,7 @@ class QuestionsAnswersControllerTest < ActionController::TestCase assert_difference 'QuestionsAnswer.count', -1 do compatible_request :post, :destroy, :id => answer.id end - assert_redirected_to question_path(answer.question, :anchor => "question_item_#{answer.id}") + assert_redirected_to question_path(answer.question, :anchor => "questions_answer_#{answer.id}") assert_nil QuestionsAnswer.find_by_id(answer.id) end @@ -144,6 +136,6 @@ class QuestionsAnswersControllerTest < ActionController::TestCase } # assert_response :success answer.reload - assert !answer.accepted, "Mark as officail answer did set for answer after update for user without permission" + assert !answer.accepted, "Mark as official answer did set for answer after update for user without permission" end end diff --git a/plugins/redmine_questions/test/functional/questions_comments_controller_test.rb b/plugins/redmine_questions/test/functional/questions_comments_controller_test.rb index 5b54656..637495b 100644 --- a/plugins/redmine_questions/test/functional/questions_comments_controller_test.rb +++ b/plugins/redmine_questions/test/functional/questions_comments_controller_test.rb @@ -3,7 +3,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify @@ -22,8 +22,8 @@ require File.expand_path('../../test_helper', __FILE__) class QuestionsCommentsControllerTest < ActionController::TestCase - fixtures :users, - :projects, + fixtures :users, + :projects, :roles, :members, :member_roles, @@ -38,7 +38,7 @@ class QuestionsCommentsControllerTest < ActionController::TestCase :issue_categories, :enabled_modules, :workflows, - :questions, + :questions, :questions_answers, :questions_sections diff --git a/plugins/redmine_questions/test/functional/questions_controller_test.rb b/plugins/redmine_questions/test/functional/questions_controller_test.rb index 955fea7..c5a5d94 100644 --- a/plugins/redmine_questions/test/functional/questions_controller_test.rb +++ b/plugins/redmine_questions/test/functional/questions_controller_test.rb @@ -3,7 +3,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify @@ -22,8 +22,8 @@ require File.expand_path('../../test_helper', __FILE__) class QuestionsControllerTest < ActionController::TestCase - fixtures :users, - :projects, + fixtures :users, + :projects, :roles, :members, :member_roles, @@ -40,14 +40,13 @@ class QuestionsControllerTest < ActionController::TestCase :attachments, :workflows, :time_entries, - :questions, - :questions_answers, + :questions, + :questions_answers, :questions_sections fixtures :email_addresses if ActiveRecord::VERSION::MAJOR >= 4 - RedmineQuestions::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_questions).directory + '/test/fixtures/', - [:tags, :taggings, :comments]) + RedmineQuestions::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_questions).directory + '/test/fixtures/', [:tags, :taggings, :comments]) def setup RedmineQuestions::TestCase.prepare @@ -77,6 +76,34 @@ class QuestionsControllerTest < ActionController::TestCase assert_select 'p.breadcrumb' end + def test_get_new + @request.session[:user_id] = 1 + compatible_request :get, :new, project_id: @project + + assert_select 'input#question_subject' + assert_select 'select#question_section_id' + assert_select 'input[type=?]', 'submit' + end + + def test_get_edit + @request.session[:user_id] = 1 + compatible_request :get, :edit, id: 1 + + assert_select 'input#question_subject' + assert_select 'select#question_section_id' + assert_select 'input[type=?]', 'submit' + end + + def test_post_create_failed + @request.session[:user_id] = 1 + compatible_request :post, :create, :project_id => @project, + :question => { + + :content => "Body of text" + } + assert_response :success + end + def test_post_create @request.session[:user_id] = 1 ActionMailer::Base.deliveries.clear @@ -118,7 +145,7 @@ class QuestionsControllerTest < ActionController::TestCase assert_select 'div#reply' assert_select 'a.icon-del' assert_select 'a.add-comment-link' - assert_select 'span.items', {:text => "(1-1/1)"} + assert_select 'span.items', {:text => "(1-2/2)"} @dev_role.permissions << :add_answers @dev_role.save @request.session[:user_id] = 3 @@ -164,20 +191,17 @@ class QuestionsControllerTest < ActionController::TestCase end assert_redirected_to questions_path(:section_id => question.section) assert_nil Question.find_by_id(question.id) - end + end def test_preview_new_question @request.session[:user_id] = 1 question = questions(:question_001) - compatible_xhr_request :post, :preview, + compatible_xhr_request :post, :preview, :question => { :content => "Previewed question", } assert_response :success - assert_select 'fieldset' do - assert_select 'legend', :text => 'Preview' - assert_select 'p', :text => 'Previewed question' - end + assert_select 'p', :text => 'Previewed question' end def test_update_question diff --git a/plugins/redmine_questions/test/functional/questions_sections_controller_test.rb b/plugins/redmine_questions/test/functional/questions_sections_controller_test.rb index 09cfca7..ca72b0a 100644 --- a/plugins/redmine_questions/test/functional/questions_sections_controller_test.rb +++ b/plugins/redmine_questions/test/functional/questions_sections_controller_test.rb @@ -3,7 +3,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/test/functional/questions_statuses_controller_test.rb b/plugins/redmine_questions/test/functional/questions_statuses_controller_test.rb new file mode 100644 index 0000000..d1bb7cc --- /dev/null +++ b/plugins/redmine_questions/test/functional/questions_statuses_controller_test.rb @@ -0,0 +1,93 @@ +# encoding: utf-8 +# +# This file is a part of Redmine Q&A (redmine_questions) plugin, +# Q&A plugin for Redmine +# +# Copyright (C) 2011-2020 RedmineUP +# http://www.redmineup.com/ +# +# redmine_questions 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 3 of the License, or +# (at your option) any later version. +# +# redmine_questions 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 redmine_questions. If not, see . + +require File.expand_path('../../test_helper', __FILE__) + +class QuestionsStatusesControllerTest < ActionController::TestCase + fixtures :users, + :projects, + :roles, + :members, + :member_roles, + :trackers, + :enumerations, + :projects_trackers, + :issues, + :issue_statuses, + :versions, + :trackers, + :projects_trackers, + :issue_categories, + :enabled_modules, + :workflows, + :questions, + :questions_answers, + :questions_sections + + fixtures :email_addresses if ActiveRecord::VERSION::MAJOR >= 4 + + RedmineQuestions::TestCase.create_fixtures(Redmine::Plugin.find(:redmine_questions).directory + '/test/fixtures/', [:questions, + :questions_answers, + :questions_sections, + :questions_statuses]) + + def setup + RedmineQuestions::TestCase.prepare + @project = Project.find(1) + User.current = nil + end + + def test_new + @request.session[:user_id] = 1 + compatible_request :get, :new + assert_response :success + + assert_select 'input#questions_status_name' + assert_select 'input[type=?]', 'submit' + end + + def test_create + @request.session[:user_id] = 1 + assert_difference 'QuestionsStatus.count' do + compatible_request :post, :create, questions_status: { name: 'Test status', color: 'green', is_closed: '0' } + end + assert_equal 'Test status', QuestionsStatus.last.name + end + + def test_delete + @request.session[:user_id] = 1 + + status = QuestionsStatus.find(1) + assert_difference 'QuestionsStatus.count', -1 do + compatible_request :delete, :destroy, id: status + end + assert_nil QuestionsStatus.where(id: status.id).first + end + + def test_update + @request.session[:user_id] = 1 + + status = QuestionsStatus.find(1) + compatible_request :put, :update, id: status, questions_status: { name: 'New name', color: 'green', is_closed: '0' } + status.reload + assert_equal status.name, 'New name' + end +end diff --git a/plugins/redmine_questions/test/integration/common_views_test.rb b/plugins/redmine_questions/test/integration/common_views_test.rb index 4c32eef..0d89b47 100644 --- a/plugins/redmine_questions/test/integration/common_views_test.rb +++ b/plugins/redmine_questions/test/integration/common_views_test.rb @@ -3,7 +3,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/test/test_helper.rb b/plugins/redmine_questions/test/test_helper.rb index e082a08..4080085 100644 --- a/plugins/redmine_questions/test/test_helper.rb +++ b/plugins/redmine_questions/test/test_helper.rb @@ -3,7 +3,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify @@ -74,7 +74,7 @@ class RedmineQuestions::TestCase end def self.prepare - Role.where(:id => [1, 3]).each do |r| + Role.where(:id => 1).each do |r| # user_2 r.permissions << :view_questions r.permissions << :global_view_questions @@ -103,11 +103,6 @@ class RedmineQuestions::TestCase r.save end - Role.where(:id => 1).each do |r| - r.permissions << :accept_answers - r.save - end - Project.where(:id => [1, 2, 3, 4, 5]).each do |project| EnabledModule.create(:project => project, :name => 'questions') end diff --git a/plugins/redmine_questions/test/unit/question_test.rb b/plugins/redmine_questions/test/unit/question_test.rb index c0ea0ef..0d1355a 100644 --- a/plugins/redmine_questions/test/unit/question_test.rb +++ b/plugins/redmine_questions/test/unit/question_test.rb @@ -3,7 +3,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/test/unit/questions_section_test.rb b/plugins/redmine_questions/test/unit/questions_section_test.rb index fed2eb9..2331c75 100644 --- a/plugins/redmine_questions/test/unit/questions_section_test.rb +++ b/plugins/redmine_questions/test/unit/questions_section_test.rb @@ -3,7 +3,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify diff --git a/plugins/redmine_questions/test/unit/user_test.rb b/plugins/redmine_questions/test/unit/user_test.rb index e93fc74..9f1dfd3 100644 --- a/plugins/redmine_questions/test/unit/user_test.rb +++ b/plugins/redmine_questions/test/unit/user_test.rb @@ -3,7 +3,7 @@ # This file is a part of Redmine Q&A (redmine_questions) plugin, # Q&A plugin for Redmine # -# Copyright (C) 2011-2018 RedmineUP +# Copyright (C) 2011-2020 RedmineUP # http://www.redmineup.com/ # # redmine_questions is free software: you can redistribute it and/or modify