Revision 1298:4f746d8966dd .svn/pristine/23

View differences:

.svn/pristine/23/2330bc88f1bd2ce1c1b2bfa4d60a6eb823530bd2.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2011  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
require File.expand_path('../../../../../test_helper', __FILE__)
19

  
20
class Redmine::MenuManager::MapperTest < ActiveSupport::TestCase
21
  context "Mapper#initialize" do
22
    should "be tested"
23
  end
24

  
25
  def test_push_onto_root
26
    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
27
    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
28

  
29
    menu_mapper.exists?(:test_overview)
30
  end
31

  
32
  def test_push_onto_parent
33
    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
34
    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
35
    menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent => :test_overview}
36

  
37
    assert menu_mapper.exists?(:test_child)
38
    assert_equal :test_child, menu_mapper.find(:test_child).name
39
  end
40

  
41
  def test_push_onto_grandparent
42
    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
43
    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
44
    menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent => :test_overview}
45
    menu_mapper.push :test_grandchild, { :controller => 'projects', :action => 'show'}, {:parent => :test_child}
46

  
47
    assert menu_mapper.exists?(:test_grandchild)
48
    grandchild = menu_mapper.find(:test_grandchild)
49
    assert_equal :test_grandchild, grandchild.name
50
    assert_equal :test_child, grandchild.parent.name
51
  end
52

  
53
  def test_push_first
54
    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
55
    menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
56
    menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
57
    menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
58
    menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
59
    menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {:first => true}
60

  
61
    root = menu_mapper.find(:root)
62
    assert_equal 5, root.children.size
63
    {0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
64
      assert_not_nil root.children[position]
65
      assert_equal name, root.children[position].name
66
    end
67

  
68
  end
69

  
70
  def test_push_before
71
    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
72
    menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
73
    menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
74
    menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
75
    menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
76
    menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {:before => :test_fourth}
77

  
78
    root = menu_mapper.find(:root)
79
    assert_equal 5, root.children.size
80
    {0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
81
      assert_not_nil root.children[position]
82
      assert_equal name, root.children[position].name
83
    end
84

  
85
  end
86

  
87
  def test_push_after
88
    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
89
    menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
90
    menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
91
    menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
92
    menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
93
    menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {:after => :test_third}
94

  
95
    root = menu_mapper.find(:root)
96
    assert_equal 5, root.children.size
97
    {0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
98
      assert_not_nil root.children[position]
99
      assert_equal name, root.children[position].name
100
    end
101

  
102
  end
103

  
104
  def test_push_last
105
    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
106
    menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
107
    menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
108
    menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
109
    menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {:last => true}
110
    menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
111

  
112
    root = menu_mapper.find(:root)
113
    assert_equal 5, root.children.size
114
    {0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
115
      assert_not_nil root.children[position]
116
      assert_equal name, root.children[position].name
117
    end
118

  
119
  end
120

  
121
  def test_exists_for_child_node
122
    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
123
    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
124
    menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent => :test_overview }
125

  
126
    assert menu_mapper.exists?(:test_child)
127
  end
128

  
129
  def test_exists_for_invalid_node
130
    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
131
    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
132

  
133
    assert !menu_mapper.exists?(:nothing)
134
  end
135

  
136
  def test_find
137
    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
138
    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
139

  
140
    item = menu_mapper.find(:test_overview)
141
    assert_equal :test_overview, item.name
142
    assert_equal({:controller => 'projects', :action => 'show'}, item.url)
143
  end
144

  
145
  def test_find_missing
146
    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
147
    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
148

  
149
    item = menu_mapper.find(:nothing)
150
    assert_equal nil, item
151
  end
152

  
153
  def test_delete
154
    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
155
    menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
156
    assert_not_nil menu_mapper.delete(:test_overview)
157

  
158
    assert_nil menu_mapper.find(:test_overview)
159
  end
160

  
161
  def test_delete_missing
162
    menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
163
    assert_nil menu_mapper.delete(:test_missing)
164
  end
165

  
166
  test 'deleting all items' do
167
    # Exposed by deleting :last items
168
    Redmine::MenuManager.map :test_menu do |menu|
169
      menu.push :not_last, Redmine::Info.help_url
170
      menu.push :administration, { :controller => 'projects', :action => 'show'}, {:last => true}
171
      menu.push :help, Redmine::Info.help_url, :last => true
172
    end
173

  
174
    assert_nothing_raised do
175
      Redmine::MenuManager.map :test_menu do |menu|
176
        menu.delete(:administration)
177
        menu.delete(:help)
178
        menu.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
179
     end
180
    end
181
  end
182
end
.svn/pristine/23/239f83d29fc7b11e5679dea8261085d9a0c7a621.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2011  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
module Redmine #:nodoc:
19
  module CoreExtensions #:nodoc:
20
    module String #:nodoc:
21
      # Custom string conversions
22
      module Conversions
23
        # Parses hours format and returns a float
24
        def to_hours
25
          s = self.dup
26
          s.strip!
27
          if s =~ %r{^(\d+([.,]\d+)?)h?$}
28
            s = $1
29
          else
30
            # 2:30 => 2.5
31
            s.gsub!(%r{^(\d+):(\d+)$}) { $1.to_i + $2.to_i / 60.0 }
32
            # 2h30, 2h, 30m => 2.5, 2, 0.5
33
            s.gsub!(%r{^((\d+)\s*(h|hours?))?\s*((\d+)\s*(m|min)?)?$}) { |m| ($1 || $4) ? ($2.to_i + $5.to_i / 60.0) : m[0] }
34
          end
35
          # 2,5 => 2.5
36
          s.gsub!(',', '.')
37
          begin; Kernel.Float(s); rescue; nil; end
38
        end
39

  
40
        # Object#to_a removed in ruby1.9
41
        if RUBY_VERSION > '1.9'
42
          def to_a
43
            [self.dup]
44
          end
45
        end
46
      end
47
    end
48
  end
49
end
.svn/pristine/23/23b009231ec6aa90fecfe01522aea6ff2ac84fb3.svn-base
1
<h2><%= l(:label_home) %></h2>
2

  
3
<div class="splitcontentleft">
4
  <%= textilizable Setting.welcome_text %>
5
  <% if @news.any? %>
6
  <div class="news box">
7
  <h3><%=l(:label_news_latest)%></h3>
8
    <%= render :partial => 'news/news', :collection => @news %>
9
    <%= link_to l(:label_news_view_all), :controller => 'news' %>
10
  </div>
11
  <% end %>
12
  <%= call_hook(:view_welcome_index_left, :projects => @projects) %>
13
</div>
14

  
15
<div class="splitcontentright">
16
    <% if @projects.any? %>
17
  <div class="projects box">
18
  <h3><%=l(:label_project_latest)%></h3>
19
    <ul>
20
    <% for project in @projects %>
21
      <% @project = project %>
22
      <li>
23
      <%= link_to_project project %> (<%= format_time(project.created_on) %>)
24
      <%= textilizable project.short_description, :project => project %>
25
      </li>
26
    <% end %>
27
    <% @project = nil %>
28
    </ul>
29
  </div>
30
  <% end %>
31
    <%= call_hook(:view_welcome_index_right, :projects => @projects) %>
32
</div>
33

  
34
<% content_for :header_tags do %>
35
<%= stylesheet_link_tag 'scm' %>
36
<%= auto_discovery_link_tag(:atom, {:controller => 'news', :action => 'index', :key => User.current.rss_key, :format => 'atom'},
37
                                   :title => "#{Setting.app_title}: #{l(:label_news_latest)}") %>
38
<%= auto_discovery_link_tag(:atom, {:controller => 'activities', :action => 'index', :key => User.current.rss_key, :format => 'atom'},
39
                                   :title => "#{Setting.app_title}: #{l(:label_activity)}") %>
40
<% end %>
.svn/pristine/23/23ef48c3079c4ad7ff9c6850f3a7bce6b2c94752.svn-base
1
<% form_tag({}) do -%>
2
<%= hidden_field_tag 'back_url', url_for(params) %>
3
<div class="autoscroll">
4
<table class="list time-entries">
5
<thead>
6
<tr>
7
<th class="checkbox hide-when-print">
8
  <%= link_to image_tag('toggle_check.png'),
9
    {},
10
    :onclick => 'toggleIssuesSelection(Element.up(this, "form")); return false;',
11
    :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
12
</th>
13
<%= sort_header_tag('spent_on', :caption => l(:label_date), :default_order => 'desc') %>
14
<%= sort_header_tag('user', :caption => l(:label_member)) %>
15
<%= sort_header_tag('activity', :caption => l(:label_activity)) %>
16
<%= sort_header_tag('project', :caption => l(:label_project)) %>
17
<%= sort_header_tag('issue', :caption => l(:label_issue), :default_order => 'desc') %>
18
<th><%= l(:field_comments) %></th>
19
<%= sort_header_tag('hours', :caption => l(:field_hours)) %>
20
<th></th>
21
</tr>
22
</thead>
23
<tbody>
24
<% entries.each do |entry| -%>
25
<tr class="time-entry <%= cycle("odd", "even") %> hascontextmenu">
26
<td class="checkbox hide-when-print"><%= check_box_tag("ids[]", entry.id, false, :id => nil) %></td>
27
<td class="spent_on"><%= format_date(entry.spent_on) %></td>
28
<td class="user"><%= link_to_user(entry.user) %></td>
29
<td class="activity"><%=h entry.activity %></td>
30
<td class="project"><%= link_to_project(entry.project) %></td>
31
<td class="subject">
32
<% if entry.issue -%>
33
<%= entry.issue.visible? ? link_to_issue(entry.issue, :truncate => 50) : "##{entry.issue.id}" -%>
34
<% end -%>
35
</td>
36
<td class="comments"><%=h entry.comments %></td>
37
<td class="hours"><%= html_hours("%.2f" % entry.hours) %></td>
38
<td align="center">
39
<% if entry.editable_by?(User.current) -%>
40
    <%= link_to image_tag('edit.png'), {:controller => 'timelog', :action => 'edit', :id => entry, :project_id => nil},
41
                                       :title => l(:button_edit) %>
42
    <%= link_to image_tag('delete.png'), {:controller => 'timelog', :action => 'destroy', :id => entry, :project_id => nil},
43
                                         :confirm => l(:text_are_you_sure),
44
                                         :method => :delete,
45
                                         :title => l(:button_delete) %>
46
<% end -%>
47
</td>
48
</tr>
49
<% end -%>
50
</tbody>
51
</table>
52
</div>
53
<% end -%>
54

  
55
<%= context_menu time_entries_context_menu_path %>
.svn/pristine/23/23f046e7217770bca11bfe9989b755a158f48868.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2013  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
class Token < ActiveRecord::Base
19
  belongs_to :user
20
  validates_uniqueness_of :value
21

  
22
  before_create :delete_previous_tokens, :generate_new_token
23

  
24
  @@validity_time = 1.day
25

  
26
  def generate_new_token
27
    self.value = Token.generate_token_value
28
  end
29

  
30
  # Return true if token has expired
31
  def expired?
32
    return Time.now > self.created_on + @@validity_time
33
  end
34

  
35
  # Delete all expired tokens
36
  def self.destroy_expired
37
    Token.delete_all ["action NOT IN (?) AND created_on < ?", ['feeds', 'api'], Time.now - @@validity_time]
38
  end
39

  
40
  # Returns the active user who owns the key for the given action
41
  def self.find_active_user(action, key, validity_days=nil)
42
    user = find_user(action, key, validity_days)
43
    if user && user.active?
44
      user
45
    end
46
  end
47

  
48
  # Returns the user who owns the key for the given action
49
  def self.find_user(action, key, validity_days=nil)
50
    token = find_token(action, key, validity_days)
51
    if token
52
      token.user
53
    end
54
  end
55

  
56
  # Returns the token for action and key with an optional
57
  # validity duration (in number of days)
58
  def self.find_token(action, key, validity_days=nil)
59
    action = action.to_s
60
    key = key.to_s
61
    return nil unless action.present? && key =~ /\A[a-z0-9]+\z/i
62

  
63
    token = Token.where(:action => action, :value => key).first
64
    if token && (token.action == action) && (token.value == key) && token.user
65
      if validity_days.nil? || (token.created_on > validity_days.days.ago)
66
        token
67
      end
68
    end
69
  end
70

  
71
  def self.generate_token_value
72
    Redmine::Utils.random_hex(20)
73
  end
74

  
75
  private
76

  
77
  # Removes obsolete tokens (same user and action)
78
  def delete_previous_tokens
79
    if user
80
      Token.delete_all(['user_id = ? AND action = ?', user.id, action])
81
    end
82
  end
83
end
.svn/pristine/23/23f71ac728c941d3ffe5e3105dc856980b211079.svn-base
1
plugin mail template loaded from application
.svn/pristine/23/23ff873f0bf0f2e45a3709caf12bc84dab7be570.svn-base
1
# encoding: utf-8
2
#
3
# Redmine - project management software
4
# Copyright (C) 2006-2013  Jean-Philippe Lang
5
#
6
# This program is free software; you can redistribute it and/or
7
# modify it under the terms of the GNU General Public License
8
# as published by the Free Software Foundation; either version 2
9
# of the License, or (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19

  
20
module SettingsHelper
21
  def administration_settings_tabs
22
    tabs = [{:name => 'general', :partial => 'settings/general', :label => :label_general},
23
            {:name => 'display', :partial => 'settings/display', :label => :label_display},
24
            {:name => 'authentication', :partial => 'settings/authentication', :label => :label_authentication},
25
            {:name => 'projects', :partial => 'settings/projects', :label => :label_project_plural},
26
            {:name => 'issues', :partial => 'settings/issues', :label => :label_issue_tracking},
27
            {:name => 'notifications', :partial => 'settings/notifications', :label => :field_mail_notification},
28
            {:name => 'mail_handler', :partial => 'settings/mail_handler', :label => :label_incoming_emails},
29
            {:name => 'repositories', :partial => 'settings/repositories', :label => :label_repository_plural}
30
            ]
31
  end
32

  
33
  def setting_select(setting, choices, options={})
34
    if blank_text = options.delete(:blank)
35
      choices = [[blank_text.is_a?(Symbol) ? l(blank_text) : blank_text, '']] + choices
36
    end
37
    setting_label(setting, options).html_safe +
38
      select_tag("settings[#{setting}]",
39
                 options_for_select(choices, Setting.send(setting).to_s),
40
                 options).html_safe
41
  end
42

  
43
  def setting_multiselect(setting, choices, options={})
44
    setting_values = Setting.send(setting)
45
    setting_values = [] unless setting_values.is_a?(Array)
46

  
47
    content_tag("label", l(options[:label] || "setting_#{setting}")) +
48
      hidden_field_tag("settings[#{setting}][]", '').html_safe +
49
      choices.collect do |choice|
50
        text, value = (choice.is_a?(Array) ? choice : [choice, choice])
51
        content_tag(
52
          'label',
53
          check_box_tag(
54
             "settings[#{setting}][]",
55
             value,
56
             setting_values.include?(value),
57
             :id => nil
58
           ) + text.to_s,
59
          :class => (options[:inline] ? 'inline' : 'block')
60
         )
61
      end.join.html_safe
62
  end
63

  
64
  def setting_text_field(setting, options={})
65
    setting_label(setting, options).html_safe +
66
      text_field_tag("settings[#{setting}]", Setting.send(setting), options).html_safe
67
  end
68

  
69
  def setting_text_area(setting, options={})
70
    setting_label(setting, options).html_safe +
71
      text_area_tag("settings[#{setting}]", Setting.send(setting), options).html_safe
72
  end
73

  
74
  def setting_check_box(setting, options={})
75
    setting_label(setting, options).html_safe +
76
      hidden_field_tag("settings[#{setting}]", 0, :id => nil).html_safe +
77
        check_box_tag("settings[#{setting}]", 1, Setting.send("#{setting}?"), options).html_safe
78
  end
79

  
80
  def setting_label(setting, options={})
81
    label = options.delete(:label)
82
    label != false ? label_tag("settings_#{setting}", l(label || "setting_#{setting}")).html_safe : ''
83
  end
84

  
85
  # Renders a notification field for a Redmine::Notifiable option
86
  def notification_field(notifiable)
87
    return content_tag(:label,
88
                       check_box_tag('settings[notified_events][]',
89
                                     notifiable.name,
90
                                     Setting.notified_events.include?(notifiable.name), :id => nil).html_safe +
91
                         l_or_humanize(notifiable.name, :prefix => 'label_').html_safe,
92
                       :class => notifiable.parent.present? ? "parent" : '').html_safe
93
  end
94

  
95
  def cross_project_subtasks_options
96
    options = [
97
      [:label_disabled, ''],
98
      [:label_cross_project_system, 'system'],
99
      [:label_cross_project_tree, 'tree'],
100
      [:label_cross_project_hierarchy, 'hierarchy'],
101
      [:label_cross_project_descendants, 'descendants']
102
    ]
103

  
104
    options.map {|label, value| [l(label), value.to_s]}
105
  end
106
end

Also available in: Unified diff