@@ -1,110 +1,113 | |||
|
1 | 1 | # Redmine - project management software |
|
2 | 2 | # Copyright (C) 2006-2016 Jean-Philippe Lang |
|
3 | 3 | # |
|
4 | 4 | # This program is free software; you can redistribute it and/or |
|
5 | 5 | # modify it under the terms of the GNU General Public License |
|
6 | 6 | # as published by the Free Software Foundation; either version 2 |
|
7 | 7 | # of the License, or (at your option) any later version. |
|
8 | 8 | # |
|
9 | 9 | # This program is distributed in the hope that it will be useful, |
|
10 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 | 12 | # GNU General Public License for more details. |
|
13 | 13 | # |
|
14 | 14 | # You should have received a copy of the GNU General Public License |
|
15 | 15 | # along with this program; if not, write to the Free Software |
|
16 | 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
17 | 17 | |
|
18 | 18 | class JournalsController < ApplicationController |
|
19 | 19 | before_filter :find_journal, :only => [:edit, :update, :diff] |
|
20 | 20 | before_filter :find_issue, :only => [:new] |
|
21 | 21 | before_filter :find_optional_project, :only => [:index] |
|
22 | 22 | before_filter :authorize, :only => [:new, :edit, :update, :diff] |
|
23 | 23 | accept_rss_auth :index |
|
24 | 24 | menu_item :issues |
|
25 | 25 | |
|
26 | 26 | helper :issues |
|
27 | 27 | helper :custom_fields |
|
28 | 28 | helper :queries |
|
29 | 29 | include QueriesHelper |
|
30 | 30 | helper :sort |
|
31 | 31 | include SortHelper |
|
32 | 32 | |
|
33 | 33 | def index |
|
34 | 34 | retrieve_query |
|
35 | 35 | sort_init 'id', 'desc' |
|
36 | 36 | sort_update(@query.sortable_columns) |
|
37 | 37 | if @query.valid? |
|
38 | 38 | @journals = @query.journals(:order => "#{Journal.table_name}.created_on DESC", |
|
39 | 39 | :limit => 25) |
|
40 | 40 | end |
|
41 | 41 | @title = (@project ? @project.name : Setting.app_title) + ": " + (@query.new_record? ? l(:label_changes_details) : @query.name) |
|
42 | 42 | render :layout => false, :content_type => 'application/atom+xml' |
|
43 | 43 | rescue ActiveRecord::RecordNotFound |
|
44 | 44 | render_404 |
|
45 | 45 | end |
|
46 | 46 | |
|
47 | 47 | def diff |
|
48 | 48 | @issue = @journal.issue |
|
49 | 49 | if params[:detail_id].present? |
|
50 | 50 | @detail = @journal.details.find_by_id(params[:detail_id]) |
|
51 | 51 | else |
|
52 | 52 | @detail = @journal.details.detect {|d| d.property == 'attr' && d.prop_key == 'description'} |
|
53 | 53 | end |
|
54 | 54 | unless @issue && @detail |
|
55 | 55 | render_404 |
|
56 | 56 | return false |
|
57 | 57 | end |
|
58 | 58 | if @detail.property == 'cf' |
|
59 | 59 | unless @detail.custom_field && @detail.custom_field.visible_by?(@issue.project, User.current) |
|
60 | 60 | raise ::Unauthorized |
|
61 | 61 | end |
|
62 | 62 | end |
|
63 | 63 | @diff = Redmine::Helpers::Diff.new(@detail.value, @detail.old_value) |
|
64 | 64 | end |
|
65 | 65 | |
|
66 | 66 | def new |
|
67 | 67 | @journal = Journal.visible.find(params[:journal_id]) if params[:journal_id] |
|
68 | 68 | if @journal |
|
69 | 69 | user = @journal.user |
|
70 | 70 | text = @journal.notes |
|
71 | 71 | else |
|
72 | 72 | user = @issue.author |
|
73 | 73 | text = @issue.description |
|
74 | 74 | end |
|
75 | 75 | # Replaces pre blocks with [...] |
|
76 | 76 | text = text.to_s.strip.gsub(%r{<pre>(.*?)</pre>}m, '[...]') |
|
77 | 77 | @content = "#{ll(Setting.default_language, :text_user_wrote, user)}\n> " |
|
78 | 78 | @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n" |
|
79 | 79 | rescue ActiveRecord::RecordNotFound |
|
80 | 80 | render_404 |
|
81 | 81 | end |
|
82 | 82 | |
|
83 | 83 | def edit |
|
84 | 84 | (render_403; return false) unless @journal.editable_by?(User.current) |
|
85 | 85 | respond_to do |format| |
|
86 | 86 | # TODO: implement non-JS journal update |
|
87 | 87 | format.js |
|
88 | 88 | end |
|
89 | 89 | end |
|
90 | 90 | |
|
91 | 91 | def update |
|
92 | 92 | (render_403; return false) unless @journal.editable_by?(User.current) |
|
93 |
@journal. |
|
|
93 | @journal.notes = params[:notes] if params[:notes] | |
|
94 | @journal.private_notes = params[:private_notes].present? | |
|
95 | (render_403; return false) if @journal.private_notes_changed? && User.current.allowed_to?(:set_notes_private, @journal.issue.project) == false | |
|
96 | @journal.save if @journal.changed? | |
|
94 | 97 | @journal.destroy if @journal.details.empty? && @journal.notes.blank? |
|
95 | 98 | call_hook(:controller_journals_edit_post, { :journal => @journal, :params => params}) |
|
96 | 99 | respond_to do |format| |
|
97 | 100 | format.html { redirect_to issue_path(@journal.journalized) } |
|
98 | 101 | format.js |
|
99 | 102 | end |
|
100 | 103 | end |
|
101 | 104 | |
|
102 | 105 | private |
|
103 | 106 | |
|
104 | 107 | def find_journal |
|
105 | 108 | @journal = Journal.visible.find(params[:id]) |
|
106 | 109 | @project = @journal.journalized.project |
|
107 | 110 | rescue ActiveRecord::RecordNotFound |
|
108 | 111 | render_404 |
|
109 | 112 | end |
|
110 | 113 | end |
@@ -1,61 +1,67 | |||
|
1 | 1 | # encoding: utf-8 |
|
2 | 2 | # |
|
3 | 3 | # Redmine - project management software |
|
4 | 4 | # Copyright (C) 2006-2016 Jean-Philippe Lang |
|
5 | 5 | # |
|
6 | 6 | # This program is free software; you can redistribute it and/or |
|
7 | 7 | # modify it under the terms of the GNU General Public License |
|
8 | 8 | # as published by the Free Software Foundation; either version 2 |
|
9 | 9 | # of the License, or (at your option) any later version. |
|
10 | 10 | # |
|
11 | 11 | # This program is distributed in the hope that it will be useful, |
|
12 | 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 | 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
14 | 14 | # GNU General Public License for more details. |
|
15 | 15 | # |
|
16 | 16 | # You should have received a copy of the GNU General Public License |
|
17 | 17 | # along with this program; if not, write to the Free Software |
|
18 | 18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
19 | 19 | |
|
20 | 20 | module JournalsHelper |
|
21 | 21 | |
|
22 | 22 | # Returns the attachments of a journal that are displayed as thumbnails |
|
23 | 23 | def journal_thumbnail_attachments(journal) |
|
24 | 24 | ids = journal.details.select {|d| d.property == 'attachment' && d.value.present?}.map(&:prop_key) |
|
25 | 25 | ids.any? ? Attachment.where(:id => ids).select(&:thumbnailable?) : [] |
|
26 | 26 | end |
|
27 | 27 | |
|
28 | 28 | def render_notes(issue, journal, options={}) |
|
29 | 29 | content = '' |
|
30 | 30 | editable = User.current.logged? && (User.current.allowed_to?(:edit_issue_notes, issue.project) || (journal.user == User.current && User.current.allowed_to?(:edit_own_issue_notes, issue.project))) |
|
31 | 31 | links = [] |
|
32 | 32 | if !journal.notes.blank? |
|
33 | 33 | links << link_to(l(:button_quote), |
|
34 | 34 | quoted_issue_path(issue, :journal_id => journal), |
|
35 | 35 | :remote => true, |
|
36 | 36 | :method => 'post', |
|
37 | 37 | :title => l(:button_quote), |
|
38 | 38 | :class => 'icon-only icon-comment' |
|
39 | 39 | ) if options[:reply_links] |
|
40 | 40 | links << link_to(l(:button_edit), |
|
41 | 41 | edit_journal_path(journal), |
|
42 | 42 | :remote => true, |
|
43 | 43 | :method => 'get', |
|
44 | 44 | :title => l(:button_edit), |
|
45 | 45 | :class => 'icon-only icon-edit' |
|
46 | 46 | ) if editable |
|
47 | 47 | links << link_to(l(:button_delete), |
|
48 | 48 | journal_path(journal, :notes => ""), |
|
49 | 49 | :remote => true, |
|
50 | 50 | :method => 'put', :data => {:confirm => l(:text_are_you_sure)}, |
|
51 | 51 | :title => l(:button_delete), |
|
52 | 52 | :class => 'icon-only icon-del' |
|
53 | 53 | ) if editable |
|
54 | 54 | end |
|
55 | 55 | content << content_tag('div', links.join(' ').html_safe, :class => 'contextual') unless links.empty? |
|
56 | 56 | content << textilizable(journal, :notes) |
|
57 | 57 | css_classes = "wiki" |
|
58 | 58 | css_classes << " editable" if editable |
|
59 | 59 | content_tag('div', content.html_safe, :id => "journal-#{journal.id}-notes", :class => css_classes) |
|
60 | 60 | end |
|
61 | ||
|
62 | def render_private_notes(journal) | |
|
63 | content = journal.private_notes? ? l(:field_is_private) : '' | |
|
64 | css_classes = journal.private_notes? ? 'private' : '' | |
|
65 | content_tag('span', content.html_safe, :id => "journal-#{journal.id}-private_notes", :class => css_classes) | |
|
66 | end | |
|
61 | 67 | end |
@@ -1,30 +1,30 | |||
|
1 | 1 | <% reply_links = issue.notes_addable? -%> |
|
2 | 2 | <% for journal in journals %> |
|
3 | 3 | <div id="change-<%= journal.id %>" class="<%= journal.css_classes %>"> |
|
4 | 4 | <div id="note-<%= journal.indice %>"> |
|
5 | 5 | <h4><a href="#note-<%= journal.indice %>" class="journal-link">#<%= journal.indice %></a> |
|
6 | 6 | <%= avatar(journal.user, :size => "24") %> |
|
7 | 7 | <%= authoring journal.created_on, journal.user, :label => :label_updated_time_by %> |
|
8 | <%= content_tag('span', l(:field_is_private), :class => 'private') if journal.private_notes? %></h4> | |
|
8 | <%= render_private_notes(journal) %></h4> | |
|
9 | 9 | |
|
10 | 10 | <% if journal.details.any? %> |
|
11 | 11 | <ul class="details"> |
|
12 | 12 | <% details_to_strings(journal.visible_details).each do |string| %> |
|
13 | 13 | <li><%= string %></li> |
|
14 | 14 | <% end %> |
|
15 | 15 | </ul> |
|
16 | 16 | <% if Setting.thumbnails_enabled? && (thumbnail_attachments = journal_thumbnail_attachments(journal)).any? %> |
|
17 | 17 | <div class="thumbnails"> |
|
18 | 18 | <% thumbnail_attachments.each do |attachment| %> |
|
19 | 19 | <div><%= thumbnail_tag(attachment) %></div> |
|
20 | 20 | <% end %> |
|
21 | 21 | </div> |
|
22 | 22 | <% end %> |
|
23 | 23 | <% end %> |
|
24 | 24 | <%= render_notes(issue, journal, :reply_links => reply_links) unless journal.notes.blank? %> |
|
25 | 25 | </div> |
|
26 | 26 | </div> |
|
27 | 27 | <%= call_hook(:view_issues_history_journal_bottom, { :journal => journal }) %> |
|
28 | 28 | <% end %> |
|
29 | 29 | |
|
30 | 30 | <% heads_for_wiki_formatter if User.current.allowed_to?(:edit_issue_notes, issue.project) || User.current.allowed_to?(:edit_own_issue_notes, issue.project) %> |
@@ -1,19 +1,22 | |||
|
1 | 1 | <%= form_tag(journal_path(@journal), |
|
2 | 2 | :remote => true, |
|
3 | 3 | :method => 'put', |
|
4 | 4 | :id => "journal-#{@journal.id}-form") do %> |
|
5 | 5 | <%= label_tag "notes", l(:description_notes), :class => "hidden-for-sighted" %> |
|
6 | 6 | <%= text_area_tag :notes, @journal.notes, |
|
7 | 7 | :id => "journal_#{@journal.id}_notes", |
|
8 | 8 | :class => 'wiki-edit', |
|
9 | 9 | :rows => (@journal.notes.blank? ? 10 : [[10, @journal.notes.length / 50].max, 100].min) %> |
|
10 | <% if @journal.issue.safe_attribute? 'private_notes' %> | |
|
11 | <%= check_box_tag 'private_notes', '1', @journal.private_notes, :id => "journal_#{@journal.id}_private_notes" %> <label for="journal_<%= @journal.id %>_private_notes"><%= l(:field_private_notes) %></label> | |
|
12 | <% end %> | |
|
10 | 13 | <%= call_hook(:view_journals_notes_form_after_notes, { :journal => @journal}) %> |
|
11 | 14 | <p><%= submit_tag l(:button_save) %> |
|
12 | 15 | <%= preview_link preview_edit_issue_path(:project_id => @project, :id => @journal.issue), |
|
13 | 16 | "journal-#{@journal.id}-form", |
|
14 | 17 | "journal_#{@journal.id}_preview" %> | |
|
15 | 18 | <%= link_to l(:button_cancel), '#', :onclick => "$('#journal-#{@journal.id}-form').remove(); $('#journal-#{@journal.id}-notes').show(); return false;" %></p> |
|
16 | 19 | |
|
17 | 20 | <div id="journal_<%= @journal.id %>_preview" class="wiki"></div> |
|
18 | 21 | <% end %> |
|
19 | 22 | <%= wikitoolbar_for "journal_#{@journal.id}_notes" %> |
@@ -1,9 +1,11 | |||
|
1 | 1 | <% if @journal.frozen? %> |
|
2 | 2 | $("#change-<%= @journal.id %>").remove(); |
|
3 | 3 | <% else %> |
|
4 | $("#change-<%= @journal.id %>").attr('class', '<%= @journal.css_classes %>'); | |
|
4 | 5 | $("#journal-<%= @journal.id %>-notes").replaceWith('<%= escape_javascript(render_notes(@journal.issue, @journal, :reply_links => authorize_for('issues', 'edit'))) %>'); |
|
6 | $("#journal-<%= @journal.id %>-private_notes").replaceWith('<%= escape_javascript(render_private_notes(@journal)) %>'); | |
|
5 | 7 | $("#journal-<%= @journal.id %>-notes").show(); |
|
6 | 8 | $("#journal-<%= @journal.id %>-form").remove(); |
|
7 | 9 | <% end %> |
|
8 | 10 | |
|
9 | 11 | <%= call_hook(:view_journals_update_js_bottom, { :journal => @journal }) %> |
@@ -1,221 +1,254 | |||
|
1 | 1 | # Redmine - project management software |
|
2 | 2 | # Copyright (C) 2006-2016 Jean-Philippe Lang |
|
3 | 3 | # |
|
4 | 4 | # This program is free software; you can redistribute it and/or |
|
5 | 5 | # modify it under the terms of the GNU General Public License |
|
6 | 6 | # as published by the Free Software Foundation; either version 2 |
|
7 | 7 | # of the License, or (at your option) any later version. |
|
8 | 8 | # |
|
9 | 9 | # This program is distributed in the hope that it will be useful, |
|
10 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 | 12 | # GNU General Public License for more details. |
|
13 | 13 | # |
|
14 | 14 | # You should have received a copy of the GNU General Public License |
|
15 | 15 | # along with this program; if not, write to the Free Software |
|
16 | 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
17 | 17 | |
|
18 | 18 | require File.expand_path('../../test_helper', __FILE__) |
|
19 | 19 | |
|
20 | 20 | class JournalsControllerTest < ActionController::TestCase |
|
21 | 21 | fixtures :projects, :users, :members, :member_roles, :roles, :issues, :journals, :journal_details, :enabled_modules, |
|
22 | 22 | :trackers, :issue_statuses, :enumerations, :custom_fields, :custom_values, :custom_fields_projects, :projects_trackers |
|
23 | 23 | |
|
24 | 24 | def setup |
|
25 | 25 | User.current = nil |
|
26 | 26 | end |
|
27 | 27 | |
|
28 | 28 | def test_index |
|
29 | 29 | get :index, :project_id => 1 |
|
30 | 30 | assert_response :success |
|
31 | 31 | assert_not_nil assigns(:journals) |
|
32 | 32 | assert_equal 'application/atom+xml', @response.content_type |
|
33 | 33 | end |
|
34 | 34 | |
|
35 | 35 | def test_index_with_invalid_query_id |
|
36 | 36 | get :index, :project_id => 1, :query_id => 999 |
|
37 | 37 | assert_response 404 |
|
38 | 38 | end |
|
39 | 39 | |
|
40 | 40 | def test_index_should_return_privates_notes_with_permission_only |
|
41 | 41 | journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1) |
|
42 | 42 | @request.session[:user_id] = 2 |
|
43 | 43 | |
|
44 | 44 | get :index, :project_id => 1 |
|
45 | 45 | assert_response :success |
|
46 | 46 | assert_include journal, assigns(:journals) |
|
47 | 47 | |
|
48 | 48 | Role.find(1).remove_permission! :view_private_notes |
|
49 | 49 | get :index, :project_id => 1 |
|
50 | 50 | assert_response :success |
|
51 | 51 | assert_not_include journal, assigns(:journals) |
|
52 | 52 | end |
|
53 | 53 | |
|
54 | 54 | def test_index_should_show_visible_custom_fields_only |
|
55 | 55 | Issue.destroy_all |
|
56 | 56 | field_attributes = {:field_format => 'string', :is_for_all => true, :is_filter => true, :trackers => Tracker.all} |
|
57 | 57 | @fields = [] |
|
58 | 58 | @fields << (@field1 = IssueCustomField.create!(field_attributes.merge(:name => 'Field 1', :visible => true))) |
|
59 | 59 | @fields << (@field2 = IssueCustomField.create!(field_attributes.merge(:name => 'Field 2', :visible => false, :role_ids => [1, 2]))) |
|
60 | 60 | @fields << (@field3 = IssueCustomField.create!(field_attributes.merge(:name => 'Field 3', :visible => false, :role_ids => [1, 3]))) |
|
61 | 61 | @issue = Issue.generate!( |
|
62 | 62 | :author_id => 1, |
|
63 | 63 | :project_id => 1, |
|
64 | 64 | :tracker_id => 1, |
|
65 | 65 | :custom_field_values => {@field1.id => 'Value0', @field2.id => 'Value1', @field3.id => 'Value2'} |
|
66 | 66 | ) |
|
67 | 67 | @issue.init_journal(User.find(1)) |
|
68 | 68 | @issue.update_attribute :custom_field_values, {@field1.id => 'NewValue0', @field2.id => 'NewValue1', @field3.id => 'NewValue2'} |
|
69 | 69 | |
|
70 | 70 | |
|
71 | 71 | user_with_role_on_other_project = User.generate! |
|
72 | 72 | User.add_to_project(user_with_role_on_other_project, Project.find(2), Role.find(3)) |
|
73 | 73 | users_to_test = { |
|
74 | 74 | User.find(1) => [@field1, @field2, @field3], |
|
75 | 75 | User.find(3) => [@field1, @field2], |
|
76 | 76 | user_with_role_on_other_project => [@field1], # should see field1 only on Project 1 |
|
77 | 77 | User.generate! => [@field1], |
|
78 | 78 | User.anonymous => [@field1] |
|
79 | 79 | } |
|
80 | 80 | |
|
81 | 81 | users_to_test.each do |user, visible_fields| |
|
82 | 82 | get :index, :format => 'atom', :key => user.rss_key |
|
83 | 83 | @fields.each_with_index do |field, i| |
|
84 | 84 | if visible_fields.include?(field) |
|
85 | 85 | assert_select "content[type=html]", { :text => /NewValue#{i}/, :count => 1 }, "User #{user.id} was not able to view #{field.name} in API" |
|
86 | 86 | else |
|
87 | 87 | assert_select "content[type=html]", { :text => /NewValue#{i}/, :count => 0 }, "User #{user.id} was able to view #{field.name} in API" |
|
88 | 88 | end |
|
89 | 89 | end |
|
90 | 90 | end |
|
91 | 91 | |
|
92 | 92 | end |
|
93 | 93 | |
|
94 | 94 | def test_diff_for_description_change |
|
95 | 95 | get :diff, :id => 3, :detail_id => 4 |
|
96 | 96 | assert_response :success |
|
97 | 97 | assert_template 'diff' |
|
98 | 98 | |
|
99 | 99 | assert_select 'span.diff_out', :text => /removed/ |
|
100 | 100 | assert_select 'span.diff_in', :text => /added/ |
|
101 | 101 | end |
|
102 | 102 | |
|
103 | 103 | def test_diff_for_custom_field |
|
104 | 104 | field = IssueCustomField.create!(:name => "Long field", :field_format => 'text') |
|
105 | 105 | journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Notes', :user_id => 1) |
|
106 | 106 | detail = JournalDetail.create!(:journal => journal, :property => 'cf', :prop_key => field.id, |
|
107 | 107 | :old_value => 'Foo', :value => 'Bar') |
|
108 | 108 | |
|
109 | 109 | get :diff, :id => journal.id, :detail_id => detail.id |
|
110 | 110 | assert_response :success |
|
111 | 111 | assert_template 'diff' |
|
112 | 112 | |
|
113 | 113 | assert_select 'span.diff_out', :text => /Foo/ |
|
114 | 114 | assert_select 'span.diff_in', :text => /Bar/ |
|
115 | 115 | end |
|
116 | 116 | |
|
117 | 117 | def test_diff_for_custom_field_should_be_denied_if_custom_field_is_not_visible |
|
118 | 118 | field = IssueCustomField.create!(:name => "Long field", :field_format => 'text', :visible => false, :role_ids => [1]) |
|
119 | 119 | journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Notes', :user_id => 1) |
|
120 | 120 | detail = JournalDetail.create!(:journal => journal, :property => 'cf', :prop_key => field.id, |
|
121 | 121 | :old_value => 'Foo', :value => 'Bar') |
|
122 | 122 | |
|
123 | 123 | get :diff, :id => journal.id, :detail_id => detail.id |
|
124 | 124 | assert_response 302 |
|
125 | 125 | end |
|
126 | 126 | |
|
127 | 127 | def test_diff_should_default_to_description_diff |
|
128 | 128 | get :diff, :id => 3 |
|
129 | 129 | assert_response :success |
|
130 | 130 | assert_template 'diff' |
|
131 | 131 | |
|
132 | 132 | assert_select 'span.diff_out', :text => /removed/ |
|
133 | 133 | assert_select 'span.diff_in', :text => /added/ |
|
134 | 134 | end |
|
135 | 135 | |
|
136 | 136 | def test_reply_to_issue |
|
137 | 137 | @request.session[:user_id] = 2 |
|
138 | 138 | xhr :get, :new, :id => 6 |
|
139 | 139 | assert_response :success |
|
140 | 140 | assert_template 'new' |
|
141 | 141 | assert_equal 'text/javascript', response.content_type |
|
142 | 142 | assert_include '> This is an issue', response.body |
|
143 | 143 | end |
|
144 | 144 | |
|
145 | 145 | def test_reply_to_issue_without_permission |
|
146 | 146 | @request.session[:user_id] = 7 |
|
147 | 147 | xhr :get, :new, :id => 6 |
|
148 | 148 | assert_response 403 |
|
149 | 149 | end |
|
150 | 150 | |
|
151 | 151 | def test_reply_to_note |
|
152 | 152 | @request.session[:user_id] = 2 |
|
153 | 153 | xhr :get, :new, :id => 6, :journal_id => 4 |
|
154 | 154 | assert_response :success |
|
155 | 155 | assert_template 'new' |
|
156 | 156 | assert_equal 'text/javascript', response.content_type |
|
157 | 157 | assert_include '> A comment with a private version', response.body |
|
158 | 158 | end |
|
159 | 159 | |
|
160 | 160 | def test_reply_to_private_note_should_fail_without_permission |
|
161 | 161 | journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true) |
|
162 | 162 | @request.session[:user_id] = 2 |
|
163 | 163 | |
|
164 | 164 | xhr :get, :new, :id => 2, :journal_id => journal.id |
|
165 | 165 | assert_response :success |
|
166 | 166 | assert_template 'new' |
|
167 | 167 | assert_equal 'text/javascript', response.content_type |
|
168 | 168 | assert_include '> Privates notes', response.body |
|
169 | 169 | |
|
170 | 170 | Role.find(1).remove_permission! :view_private_notes |
|
171 | 171 | xhr :get, :new, :id => 2, :journal_id => journal.id |
|
172 | 172 | assert_response 404 |
|
173 | 173 | end |
|
174 | 174 | |
|
175 | 175 | def test_edit_xhr |
|
176 | 176 | @request.session[:user_id] = 1 |
|
177 | 177 | xhr :get, :edit, :id => 2 |
|
178 | 178 | assert_response :success |
|
179 | 179 | assert_template 'edit' |
|
180 | 180 | assert_equal 'text/javascript', response.content_type |
|
181 | 181 | assert_include 'textarea', response.body |
|
182 | 182 | end |
|
183 | 183 | |
|
184 | 184 | def test_edit_private_note_should_fail_without_permission |
|
185 | 185 | journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true) |
|
186 | 186 | @request.session[:user_id] = 2 |
|
187 | 187 | Role.find(1).add_permission! :edit_issue_notes |
|
188 | 188 | |
|
189 | 189 | xhr :get, :edit, :id => journal.id |
|
190 | 190 | assert_response :success |
|
191 | 191 | assert_template 'edit' |
|
192 | 192 | assert_equal 'text/javascript', response.content_type |
|
193 | 193 | assert_include 'textarea', response.body |
|
194 | 194 | |
|
195 | 195 | Role.find(1).remove_permission! :view_private_notes |
|
196 | 196 | xhr :get, :edit, :id => journal.id |
|
197 | 197 | assert_response 404 |
|
198 | 198 | end |
|
199 | 199 | |
|
200 | 200 | def test_update_xhr |
|
201 | 201 | @request.session[:user_id] = 1 |
|
202 | 202 | xhr :post, :update, :id => 2, :notes => 'Updated notes' |
|
203 | 203 | assert_response :success |
|
204 | 204 | assert_template 'update' |
|
205 | 205 | assert_equal 'text/javascript', response.content_type |
|
206 | 206 | assert_equal 'Updated notes', Journal.find(2).notes |
|
207 | 207 | assert_include 'journal-2-notes', response.body |
|
208 | 208 | end |
|
209 | 209 | |
|
210 | def test_update_xhr_with_private_notes_checked | |
|
211 | @request.session[:user_id] = 1 | |
|
212 | xhr :post, :update, :id => 2, :private_notes => '1' | |
|
213 | assert_response :success | |
|
214 | assert_template 'update' | |
|
215 | assert_equal 'text/javascript', response.content_type | |
|
216 | assert_equal true, Journal.find(2).private_notes | |
|
217 | assert_include 'change-2', response.body | |
|
218 | assert_include 'journal-2-private_notes', response.body | |
|
219 | end | |
|
220 | ||
|
221 | def test_update_xhr_with_private_notes_unchecked | |
|
222 | Journal.find(2).update_attributes(:private_notes => true) | |
|
223 | @request.session[:user_id] = 1 | |
|
224 | xhr :post, :update, :id => 2 | |
|
225 | assert_response :success | |
|
226 | assert_template 'update' | |
|
227 | assert_equal 'text/javascript', response.content_type | |
|
228 | assert_equal false, Journal.find(2).private_notes | |
|
229 | assert_include 'change-2', response.body | |
|
230 | assert_include 'journal-2-private_notes', response.body | |
|
231 | end | |
|
232 | ||
|
233 | def test_update_xhr_with_private_notes_changes_and_without_set_private_notes_permission | |
|
234 | @request.session[:user_id] = 2 | |
|
235 | Role.find(1).add_permission! :edit_issue_notes | |
|
236 | Role.find(1).add_permission! :view_private_notes | |
|
237 | Role.find(1).remove_permission! :set_notes_private | |
|
238 | ||
|
239 | xhr :post, :update, :id => 2, :private_notes => '1' | |
|
240 | assert_response 403 | |
|
241 | end | |
|
242 | ||
|
210 | 243 | def test_update_xhr_with_empty_notes_should_delete_the_journal |
|
211 | 244 | @request.session[:user_id] = 1 |
|
212 | 245 | assert_difference 'Journal.count', -1 do |
|
213 | 246 | xhr :post, :update, :id => 2, :notes => '' |
|
214 | 247 | assert_response :success |
|
215 | 248 | assert_template 'update' |
|
216 | 249 | assert_equal 'text/javascript', response.content_type |
|
217 | 250 | end |
|
218 | 251 | assert_nil Journal.find_by_id(2) |
|
219 | 252 | assert_include 'change-2', response.body |
|
220 | 253 | end |
|
221 | 254 | end |
General Comments 0
You need to be logged in to leave comments.
Login now