@@ -0,0 +1,41 | |||||
|
1 | Return-Path: <jsmith@somenet.foo> | |||
|
2 | Received: from osiris ([127.0.0.1]) | |||
|
3 | by OSIRIS | |||
|
4 | with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200 | |||
|
5 | Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris> | |||
|
6 | From: "John Smith" <jsmith@somenet.foo> | |||
|
7 | To: <redmine@somenet.foo> | |||
|
8 | Subject: New ticket with custom field values | |||
|
9 | Date: Sun, 22 Jun 2008 12:28:07 +0200 | |||
|
10 | MIME-Version: 1.0 | |||
|
11 | Content-Type: text/plain; | |||
|
12 | format=flowed; | |||
|
13 | charset="iso-8859-1"; | |||
|
14 | reply-type=original | |||
|
15 | Content-Transfer-Encoding: 7bit | |||
|
16 | X-Priority: 3 | |||
|
17 | X-MSMail-Priority: Normal | |||
|
18 | X-Mailer: Microsoft Outlook Express 6.00.2900.2869 | |||
|
19 | X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869 | |||
|
20 | ||||
|
21 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet | |||
|
22 | turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus | |||
|
23 | blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti | |||
|
24 | sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In | |||
|
25 | in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras | |||
|
26 | sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum | |||
|
27 | id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus | |||
|
28 | eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique | |||
|
29 | sed, mauris. Pellentesque habitant morbi tristique senectus et netus et | |||
|
30 | malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse | |||
|
31 | platea dictumst. | |||
|
32 | ||||
|
33 | Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque | |||
|
34 | sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem. | |||
|
35 | Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et, | |||
|
36 | dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed, | |||
|
37 | massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo | |||
|
38 | pulvinar dui, a gravida orci mi eget odio. Nunc a lacus. | |||
|
39 | ||||
|
40 | category: Stock management | |||
|
41 | searchable field: Value for a custom field |
@@ -35,7 +35,9 class AttachmentsController < ApplicationController | |||||
35 | end |
|
35 | end | |
36 |
|
36 | |||
37 | def download |
|
37 | def download | |
38 | @attachment.increment_download if @attachment.container.is_a?(Version) |
|
38 | if @attachment.container.is_a?(Version) || @attachment.container.is_a?(Project) | |
|
39 | @attachment.increment_download | |||
|
40 | end | |||
39 |
|
41 | |||
40 | # images are sent inline |
|
42 | # images are sent inline | |
41 | send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename), |
|
43 | send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename), |
@@ -84,6 +84,11 class ProjectsController < ApplicationController | |||||
84 |
|
84 | |||
85 | # Show @project |
|
85 | # Show @project | |
86 | def show |
|
86 | def show | |
|
87 | if params[:jump] | |||
|
88 | # try to redirect to the requested menu item | |||
|
89 | redirect_to_project_menu_item(@project, params[:jump]) && return | |||
|
90 | end | |||
|
91 | ||||
87 | @members_by_role = @project.members.find(:all, :include => [:user, :role], :order => 'position').group_by {|m| m.role} |
|
92 | @members_by_role = @project.members.find(:all, :include => [:user, :role], :order => 'position').group_by {|m| m.role} | |
88 | @subprojects = @project.children.find(:all, :conditions => Project.visible_by(User.current)) |
|
93 | @subprojects = @project.children.find(:all, :conditions => Project.visible_by(User.current)) | |
89 | @news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC") |
|
94 | @news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC") |
@@ -90,6 +90,13 class MailHandler < ActionMailer::Base | |||||
90 | end |
|
90 | end | |
91 | issue.subject = email.subject.chomp.toutf8 |
|
91 | issue.subject = email.subject.chomp.toutf8 | |
92 | issue.description = plain_text_body |
|
92 | issue.description = plain_text_body | |
|
93 | # custom fields | |||
|
94 | issue.custom_field_values = issue.available_custom_fields.inject({}) do |h, c| | |||
|
95 | if value = get_keyword(c.name, :override => true) | |||
|
96 | h[c.id] = value | |||
|
97 | end | |||
|
98 | h | |||
|
99 | end | |||
93 | issue.save! |
|
100 | issue.save! | |
94 | add_attachments(issue) |
|
101 | add_attachments(issue) | |
95 | logger.info "MailHandler: issue ##{issue.id} created by #{user}" if logger && logger.info |
|
102 | logger.info "MailHandler: issue ##{issue.id} created by #{user}" if logger && logger.info | |
@@ -155,8 +162,8 class MailHandler < ActionMailer::Base | |||||
155 | end |
|
162 | end | |
156 | end |
|
163 | end | |
157 |
|
164 | |||
158 | def get_keyword(attr) |
|
165 | def get_keyword(attr, options={}) | |
159 | if @@handler_options[:allow_override].include?(attr.to_s) && plain_text_body =~ /^#{attr}:[ \t]*(.+)$/i |
|
166 | if (options[:override] || @@handler_options[:allow_override].include?(attr.to_s)) && plain_text_body =~ /^#{attr}:[ \t]*(.+)$/i | |
160 | $1.strip |
|
167 | $1.strip | |
161 | elsif !@@handler_options[:issue][attr].blank? |
|
168 | elsif !@@handler_options[:issue][attr].blank? | |
162 | @@handler_options[:issue][attr] |
|
169 | @@handler_options[:issue][attr] |
@@ -3,10 +3,10 | |||||
3 | <option selected="selected"><%= l(:label_jump_to_a_project) %></option> |
|
3 | <option selected="selected"><%= l(:label_jump_to_a_project) %></option> | |
4 | <option disabled="disabled">---</option> |
|
4 | <option disabled="disabled">---</option> | |
5 | <% user_projects_by_root.keys.sort.each do |root| %> |
|
5 | <% user_projects_by_root.keys.sort.each do |root| %> | |
6 | <%= content_tag('option', h(root.name), :value => url_for(:controller => 'projects', :action => 'show', :id => root)) %> |
|
6 | <%= content_tag('option', h(root.name), :value => url_for(:controller => 'projects', :action => 'show', :id => root, :jump => current_menu_item)) %> | |
7 | <% user_projects_by_root[root].sort.each do |project| %> |
|
7 | <% user_projects_by_root[root].sort.each do |project| %> | |
8 | <% next if project == root %> |
|
8 | <% next if project == root %> | |
9 | <%= content_tag('option', ('» ' + h(project.name)), :value => url_for(:controller => 'projects', :action => 'show', :id => project)) %> |
|
9 | <%= content_tag('option', ('» ' + h(project.name)), :value => url_for(:controller => 'projects', :action => 'show', :id => project, :jump => current_menu_item)) %> | |
10 | <% end %> |
|
10 | <% end %> | |
11 | <% end %> |
|
11 | <% end %> | |
12 | </select> |
|
12 | </select> |
@@ -52,8 +52,19 module Redmine | |||||
52 |
|
52 | |||
53 | # Returns the menu item name according to the current action |
|
53 | # Returns the menu item name according to the current action | |
54 | def current_menu_item |
|
54 | def current_menu_item | |
55 | menu_items[controller_name.to_sym][:actions][action_name.to_sym] || |
|
55 | @current_menu_item ||= menu_items[controller_name.to_sym][:actions][action_name.to_sym] || | |
56 | menu_items[controller_name.to_sym][:default] |
|
56 | menu_items[controller_name.to_sym][:default] | |
|
57 | end | |||
|
58 | ||||
|
59 | # Redirects user to the menu item of the given project | |||
|
60 | # Returns false if user is not authorized | |||
|
61 | def redirect_to_project_menu_item(project, name) | |||
|
62 | item = Redmine::MenuManager.items(:project_menu).detect {|i| i.name.to_s == name.to_s} | |||
|
63 | if item && User.current.allowed_to?(item.url, project) && (item.condition.nil? || item.condition.call(project)) | |||
|
64 | redirect_to({item.param => project}.merge(item.url)) | |||
|
65 | return true | |||
|
66 | end | |||
|
67 | false | |||
57 | end |
|
68 | end | |
58 | end |
|
69 | end | |
59 |
|
70 |
@@ -287,6 +287,23 class ProjectsControllerTest < Test::Unit::TestCase | |||||
287 | assert Project.find(1).active? |
|
287 | assert Project.find(1).active? | |
288 | end |
|
288 | end | |
289 |
|
289 | |||
|
290 | def test_jump_should_redirect_to_active_tab | |||
|
291 | get :show, :id => 1, :jump => 'issues' | |||
|
292 | assert_redirected_to 'projects/ecookbook/issues' | |||
|
293 | end | |||
|
294 | ||||
|
295 | def test_jump_should_not_redirect_to_inactive_tab | |||
|
296 | get :show, :id => 3, :jump => 'documents' | |||
|
297 | assert_response :success | |||
|
298 | assert_template 'show' | |||
|
299 | end | |||
|
300 | ||||
|
301 | def test_jump_should_not_redirect_to_unknown_tab | |||
|
302 | get :show, :id => 3, :jump => 'foobar' | |||
|
303 | assert_response :success | |||
|
304 | assert_template 'show' | |||
|
305 | end | |||
|
306 | ||||
290 | def test_project_menu |
|
307 | def test_project_menu | |
291 | assert_no_difference 'Redmine::MenuManager.items(:project_menu).size' do |
|
308 | assert_no_difference 'Redmine::MenuManager.items(:project_menu).size' do | |
292 | Redmine::MenuManager.map :project_menu do |menu| |
|
309 | Redmine::MenuManager.map :project_menu do |menu| |
@@ -28,7 +28,9 class MailHandlerTest < Test::Unit::TestCase | |||||
28 | :trackers, |
|
28 | :trackers, | |
29 | :projects_trackers, |
|
29 | :projects_trackers, | |
30 | :enumerations, |
|
30 | :enumerations, | |
31 | :issue_categories |
|
31 | :issue_categories, | |
|
32 | :custom_fields, | |||
|
33 | :custom_fields_trackers | |||
32 |
|
34 | |||
33 | FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler' |
|
35 | FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler' | |
34 |
|
36 | |||
@@ -102,6 +104,15 class MailHandlerTest < Test::Unit::TestCase | |||||
102 | assert_equal 10790, issue.attachments.first.filesize |
|
104 | assert_equal 10790, issue.attachments.first.filesize | |
103 | end |
|
105 | end | |
104 |
|
106 | |||
|
107 | def test_add_issue_with_custom_fields | |||
|
108 | issue = submit_email('ticket_with_custom_fields.eml', :issue => {:project => 'onlinestore'}) | |||
|
109 | assert issue.is_a?(Issue) | |||
|
110 | assert !issue.new_record? | |||
|
111 | issue.reload | |||
|
112 | assert_equal 'New ticket with custom field values', issue.subject | |||
|
113 | assert_equal 'Value for a custom field', issue.custom_value_for(CustomField.find_by_name('Searchable field')).value | |||
|
114 | end | |||
|
115 | ||||
105 | def test_add_issue_with_cc |
|
116 | def test_add_issue_with_cc | |
106 | issue = submit_email('ticket_with_cc.eml', :issue => {:project => 'ecookbook'}) |
|
117 | issue = submit_email('ticket_with_cc.eml', :issue => {:project => 'ecookbook'}) | |
107 | assert issue.is_a?(Issue) |
|
118 | assert issue.is_a?(Issue) |
General Comments 0
You need to be logged in to leave comments.
Login now