Revision 912:5e80956cc792 .svn/pristine/03

View differences:

.svn/pristine/03/03110323c21c0fa4339bdcd80aed971c5c6bd9d4.svn-base
1
api.issue_category do
2
  api.id @category.id
3
  api.project(:id => @category.project_id, :name => @category.project.name) unless @category.project.nil?
4
  api.name @category.name
5
  api.assigned_to(:id => @category.assigned_to_id, :name => @category.assigned_to.name) unless @category.assigned_to.nil?
6
end
.svn/pristine/03/032e9aa73399010aaf3eb408ecd8fb8f296696b1.svn-base
1
<div class="contextual">
2
  <% if User.current.allowed_to?(:add_subprojects, @project) %>
3
    <%= link_to l(:label_subproject_new), {:controller => 'projects', :action => 'new', :parent_id => @project}, :class => 'icon icon-add' %>
4
  <% end %>
5
</div>
6

  
7
<h2><%=l(:label_overview)%></h2>
8

  
9
<div class="splitcontentleft">
10
  <div class="wiki">
11
    <%= textilizable @project.description %>
12
  </div>
13
  <ul>
14
  <% unless @project.homepage.blank? %><li><%=l(:field_homepage)%>: <%= auto_link(h(@project.homepage)) %></li><% end %>
15
  <% if @subprojects.any? %>
16
   <li><%=l(:label_subproject_plural)%>:
17
      <%= @subprojects.collect{|p| link_to(h(p), :action => 'show', :id => p)}.join(", ").html_safe %></li>
18
  <% end %>
19
  <% @project.visible_custom_field_values.each do |custom_value| %>
20
  <% if !custom_value.value.blank? %>
21
     <li><%=h custom_value.custom_field.name %>: <%=h show_value(custom_value) %></li>
22
  <% end %>
23
  <% end %>
24
  </ul>
25

  
26
  <% if User.current.allowed_to?(:view_issues, @project) %>
27
  <div class="issues box">
28
    <h3><%=l(:label_issue_tracking)%></h3>
29
    <ul>
30
    <% for tracker in @trackers %>
31
      <li><%= link_to h(tracker.name), :controller => 'issues', :action => 'index', :project_id => @project,
32
                                                :set_filter => 1,
33
                                                "tracker_id" => tracker.id %>:
34
          <%= l(:label_x_open_issues_abbr_on_total, :count => @open_issues_by_tracker[tracker].to_i,
35
                                                    :total => @total_issues_by_tracker[tracker].to_i) %>
36
      </li>
37
    <% end %>
38
    </ul>
39
    <p>
40
      <%= link_to l(:label_issue_view_all), :controller => 'issues', :action => 'index', :project_id => @project, :set_filter => 1 %>
41
      <% if User.current.allowed_to?(:view_calendar, @project, :global => true) %>
42
        | <%= link_to(l(:label_calendar), :controller => 'calendars', :action => 'show', :project_id => @project) %>
43
      <% end %>
44
      <% if User.current.allowed_to?(:view_gantt, @project, :global => true) %>
45
        | <%= link_to(l(:label_gantt), :controller => 'gantts', :action => 'show', :project_id => @project) %>
46
      <% end %>
47
    </p>
48
  </div>
49
  <% end %>
50
  <%= call_hook(:view_projects_show_left, :project => @project) %>
51
</div>
52

  
53
<div class="splitcontentright">
54
  <%= render :partial => 'members_box' %>
55

  
56
  <% if @news.any? && authorize_for('news', 'index') %>
57
  <div class="news box">
58
    <h3><%=l(:label_news_latest)%></h3>
59
    <%= render :partial => 'news/news', :collection => @news %>
60
    <p><%= link_to l(:label_news_view_all), :controller => 'news', :action => 'index', :project_id => @project %></p>
61
  </div>
62
  <% end %>
63
  <%= call_hook(:view_projects_show_right, :project => @project) %>
64
</div>
65

  
66
<% content_for :sidebar do %>
67
    <% if @total_hours.present? %>
68
    <h3><%= l(:label_spent_time) %></h3>
69
    <p><span class="icon icon-time"><%= l_hours(@total_hours) %></span></p>
70
    <p><%= link_to(l(:label_details), {:controller => 'timelog', :action => 'index', :project_id => @project}) %> |
71
    <%= link_to(l(:label_report), {:controller => 'time_entry_reports', :action => 'report', :project_id => @project}) %></p>
72
    <% end %>
73
    <%= call_hook(:view_projects_show_sidebar_bottom, :project => @project) %>
74
<% end %>
75

  
76
<% content_for :header_tags do %>
77
<%= auto_discovery_link_tag(:atom, {:controller => 'activities', :action => 'index', :id => @project, :format => 'atom', :key => User.current.rss_key}) %>
78
<% end %>
79

  
80
<% html_title(l(:label_overview)) -%>
.svn/pristine/03/033178c724d843125ead35eb43e31dacdb4a5511.svn-base
1
# Patch the data from a boolean change.
2
class UpdateMailNotificationValues < ActiveRecord::Migration
3
  def self.up
4
    # No-op
5
    # See 20100129193402_change_users_mail_notification_to_string.rb
6
  end
7

  
8
  def self.down
9
    # No-op
10
  end
11
end
.svn/pristine/03/03389ce7c25a023f73b895dc03af8c3f1ee755e9.svn-base
1
<h2><%=l(:label_document)%></h2>
2

  
3
<% form_tag({:action => 'edit', :id => @document}, :class => "tabular") do %>
4
  <%= render :partial => 'form' %>
5
  <%= submit_tag l(:button_save) %>
6
<% end %>
7

  
8

  
.svn/pristine/03/033d037b8655e755ff07ebfb8102a3786ab52ea0.svn-base
1
<p><%= l(:mail_body_account_activation_request, h(@user.login)) %></p>
2
<p><%= link_to h(@url), @url %></p>
.svn/pristine/03/033e041df5add14807dd8e40c1a8ef8894cdf897.svn-base
1
Return-Path: <john.doe@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 Doe" <john.doe@somenet.foo>
7
To: <redmine@somenet.foo>
8
Subject: Ticket by unknown user
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

  
17
This is a ticket submitted by an unknown user.
18

  
.svn/pristine/03/0341468b2bb841c8c330355c1e3aa94ad3cce987.svn-base
1
*SVN* (version numbers are overrated)
2

  
3
* (5 Oct 2006) Allow customization of #versions association options [Dan Peterson]
4

  
5
*0.5.1*
6

  
7
* (8 Aug 2006) Versioned models now belong to the unversioned model.  @article_version.article.class => Article [Aslak Hellesoy]
8

  
9
*0.5* # do versions even matter for plugins?
10

  
11
* (21 Apr 2006) Added without_locking and without_revision methods.
12

  
13
  Foo.without_revision do
14
    @foo.update_attributes ...
15
  end
16

  
17
*0.4*
18

  
19
* (28 March 2006) Rename non_versioned_fields to non_versioned_columns (old one is kept for compatibility).
20
* (28 March 2006) Made explicit documentation note that string column names are required for non_versioned_columns.
21

  
22
*0.3.1*
23

  
24
* (7 Jan 2006) explicitly set :foreign_key option for the versioned model's belongs_to assocation for STI [Caged]
25
* (7 Jan 2006) added tests to prove has_many :through joins work
26

  
27
*0.3*
28

  
29
* (2 Jan 2006) added ability to share a mixin with versioned class
30
* (2 Jan 2006) changed the dynamic version model to MyModel::Version
31

  
32
*0.2.4*
33

  
34
* (27 Nov 2005) added note about possible destructive behavior of if_changed? [Michael Schuerig]
35

  
36
*0.2.3*
37

  
38
* (12 Nov 2005) fixed bug with old behavior of #blank? [Michael Schuerig]
39
* (12 Nov 2005) updated tests to use ActiveRecord Schema
40

  
41
*0.2.2*
42

  
43
* (3 Nov 2005) added documentation note to #acts_as_versioned [Martin Jul]
44

  
45
*0.2.1*
46

  
47
* (6 Oct 2005) renamed dirty? to changed? to keep it uniform.  it was aliased to keep it backwards compatible.
48

  
49
*0.2* 
50

  
51
* (6 Oct 2005)  added find_versions and find_version class methods.
52

  
53
* (6 Oct 2005)  removed transaction from create_versioned_table().  
54
  this way you can specify your own transaction around a group of operations.
55

  
56
* (30 Sep 2005) fixed bug where find_versions() would order by 'version' twice. (found by Joe Clark)
57

  
58
* (26 Sep 2005) added :sequence_name option to acts_as_versioned to set the sequence name on the versioned model
59

  
60
*0.1.3* (18 Sep 2005)
61

  
62
* First RubyForge release
63

  
64
*0.1.2*
65

  
66
* check if module is already included when acts_as_versioned is called
67

  
68
*0.1.1*
69

  
70
* Adding tests and rdocs
71

  
72
*0.1* 
73

  
74
* Initial transfer from Rails ticket: http://dev.rubyonrails.com/ticket/1974
.svn/pristine/03/0367c769a1dec5c6ffea095893b82d493a02e68a.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 'redmine/scm/adapters/subversion_adapter'
19

  
20
class Repository::Subversion < Repository
21
  attr_protected :root_url
22
  validates_presence_of :url
23
  validates_format_of :url, :with => /^(http|https|svn(\+[^\s:\/\\]+)?|file):\/\/.+/i
24

  
25
  def self.scm_adapter_class
26
    Redmine::Scm::Adapters::SubversionAdapter
27
  end
28

  
29
  def self.scm_name
30
    'Subversion'
31
  end
32

  
33
  def supports_directory_revisions?
34
    true
35
  end
36

  
37
  def repo_log_encoding
38
    'UTF-8'
39
  end
40

  
41
  def latest_changesets(path, rev, limit=10)
42
    revisions = scm.revisions(path, rev, nil, :limit => limit)
43
    revisions ? changesets.find_all_by_revision(revisions.collect(&:identifier), :order => "committed_on DESC", :include => :user) : []
44
  end
45

  
46
  # Returns a path relative to the url of the repository
47
  def relative_path(path)
48
    path.gsub(Regexp.new("^\/?#{Regexp.escape(relative_url)}"), '')
49
  end
50

  
51
  def fetch_changesets
52
    scm_info = scm.info
53
    if scm_info
54
      # latest revision found in database
55
      db_revision = latest_changeset ? latest_changeset.revision.to_i : 0
56
      # latest revision in the repository
57
      scm_revision = scm_info.lastrev.identifier.to_i
58
      if db_revision < scm_revision
59
        logger.debug "Fetching changesets for repository #{url}" if logger && logger.debug?
60
        identifier_from = db_revision + 1
61
        while (identifier_from <= scm_revision)
62
          # loads changesets by batches of 200
63
          identifier_to = [identifier_from + 199, scm_revision].min
64
          revisions = scm.revisions('', identifier_to, identifier_from, :with_paths => true)
65
          revisions.reverse_each do |revision|
66
            transaction do
67
              changeset = Changeset.create(:repository   => self,
68
                                           :revision     => revision.identifier,
69
                                           :committer    => revision.author,
70
                                           :committed_on => revision.time,
71
                                           :comments     => revision.message)
72

  
73
              revision.paths.each do |change|
74
                changeset.create_change(change)
75
              end unless changeset.new_record?
76
            end
77
          end unless revisions.nil?
78
          identifier_from = identifier_to + 1
79
        end
80
      end
81
    end
82
  end
83

  
84
  private
85

  
86
  # Returns the relative url of the repository
87
  # Eg: root_url = file:///var/svn/foo
88
  #     url      = file:///var/svn/foo/bar
89
  #     => returns /bar
90
  def relative_url
91
    @relative_url ||= url.gsub(Regexp.new("^#{Regexp.escape(root_url || scm.root_url)}", Regexp::IGNORECASE), '')
92
  end
93
end
.svn/pristine/03/03803ec02697cfe8f89b59eb47e58dc9312a0502.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::UnifiedDiffTest < ActiveSupport::TestCase
21

  
22
  def setup
23
  end
24

  
25
  def test_subversion_diff
26
    diff = Redmine::UnifiedDiff.new(read_diff_fixture('subversion.diff'))
27
    # number of files
28
    assert_equal 4, diff.size
29
    assert diff.detect {|file| file.file_name =~ %r{^config/settings.yml}}
30
  end
31

  
32
  def test_truncate_diff
33
    diff = Redmine::UnifiedDiff.new(read_diff_fixture('subversion.diff'), :max_lines => 20)
34
    assert_equal 2, diff.size
35
  end
36

  
37
  def test_inline_partials
38
    diff = Redmine::UnifiedDiff.new(read_diff_fixture('partials.diff'))
39
    assert_equal 1, diff.size
40
    diff = diff.first
41
    assert_equal 43, diff.size
42

  
43
    assert_equal [51, -1], diff[0].offsets
44
    assert_equal [51, -1], diff[1].offsets
45
    assert_equal 'Lorem ipsum dolor sit amet, consectetur adipiscing <span>elit</span>', diff[0].html_line
46
    assert_equal 'Lorem ipsum dolor sit amet, consectetur adipiscing <span>xx</span>', diff[1].html_line
47

  
48
    assert_nil diff[2].offsets
49
    assert_equal 'Praesent et sagittis dui. Vivamus ac diam diam', diff[2].html_line
50

  
51
    assert_equal [0, -14], diff[3].offsets
52
    assert_equal [0, -14], diff[4].offsets
53
    assert_equal '<span>Ut sed</span> auctor justo', diff[3].html_line
54
    assert_equal '<span>xxx</span> auctor justo', diff[4].html_line
55

  
56
    assert_equal [13, -19], diff[6].offsets
57
    assert_equal [13, -19], diff[7].offsets
58

  
59
    assert_equal [24, -8], diff[9].offsets
60
    assert_equal [24, -8], diff[10].offsets
61

  
62
    assert_equal [37, -1], diff[12].offsets
63
    assert_equal [37, -1], diff[13].offsets
64

  
65
    assert_equal [0, -38], diff[15].offsets
66
    assert_equal [0, -38], diff[16].offsets
67
  end
68

  
69
  def test_side_by_side_partials
70
    diff = Redmine::UnifiedDiff.new(read_diff_fixture('partials.diff'), :type => 'sbs')
71
    assert_equal 1, diff.size
72
    diff = diff.first
73
    assert_equal 32, diff.size
74

  
75
    assert_equal [51, -1], diff[0].offsets
76
    assert_equal 'Lorem ipsum dolor sit amet, consectetur adipiscing <span>elit</span>', diff[0].html_line_left
77
    assert_equal 'Lorem ipsum dolor sit amet, consectetur adipiscing <span>xx</span>', diff[0].html_line_right
78

  
79
    assert_nil diff[1].offsets
80
    assert_equal 'Praesent et sagittis dui. Vivamus ac diam diam', diff[1].html_line_left
81
    assert_equal 'Praesent et sagittis dui. Vivamus ac diam diam', diff[1].html_line_right
82

  
83
    assert_equal [0, -14], diff[2].offsets
84
    assert_equal '<span>Ut sed</span> auctor justo', diff[2].html_line_left
85
    assert_equal '<span>xxx</span> auctor justo', diff[2].html_line_right
86

  
87
    assert_equal [13, -19], diff[4].offsets
88
    assert_equal [24, -8], diff[6].offsets
89
    assert_equal [37, -1], diff[8].offsets
90
    assert_equal [0, -38], diff[10].offsets
91

  
92
  end
93

  
94
  def test_line_starting_with_dashes
95
    diff = Redmine::UnifiedDiff.new(<<-DIFF
96
--- old.txt Wed Nov 11 14:24:58 2009
97
+++ new.txt Wed Nov 11 14:25:02 2009
98
@@ -1,8 +1,4 @@
99
-Lines that starts with dashes:
100
-
101
-------------------------
102
--- file.c
103
-------------------------
104
+A line that starts with dashes:
105
 
106
 and removed.
107
 
108
@@ -23,4 +19,4 @@
109
 
110
 
111
 
112
-Another chunk of change
113
+Another chunk of changes
114

  
115
DIFF
116
    )
117
    assert_equal 1, diff.size
118
  end
119

  
120
  def test_one_line_new_files
121
    diff = Redmine::UnifiedDiff.new(<<-DIFF
122
diff -r 000000000000 -r ea98b14f75f0 README1
123
--- /dev/null
124
+++ b/README1
125
@@ -0,0 +1,1 @@
126
+test1
127
diff -r 000000000000 -r ea98b14f75f0 README2
128
--- /dev/null
129
+++ b/README2
130
@@ -0,0 +1,1 @@
131
+test2
132
diff -r 000000000000 -r ea98b14f75f0 README3
133
--- /dev/null
134
+++ b/README3
135
@@ -0,0 +1,3 @@
136
+test4
137
+test5
138
+test6
139
diff -r 000000000000 -r ea98b14f75f0 README4
140
--- /dev/null
141
+++ b/README4
142
@@ -0,0 +1,3 @@
143
+test4
144
+test5
145
+test6
146
DIFF
147
    )
148
    assert_equal 4, diff.size
149
  end
150

  
151
  private
152

  
153
  def read_diff_fixture(filename)
154
    File.new(File.join(File.dirname(__FILE__), '/../../../fixtures/diffs', filename)).read
155
  end
156
end
.svn/pristine/03/038dcd875902d442a622bf1915b8e83469f95936.svn-base
1
require File.dirname(__FILE__) + '/helper'
2
require File.dirname(__FILE__) + '/../init'
3

  
4
class PaginationTest < ActiveRecordTestCase
5
  fixtures :topics, :replies, :developers, :projects, :developers_projects
6
  
7
  class PaginationController < ActionController::Base
8
    if respond_to? :view_paths=
9
      self.view_paths = [ "#{File.dirname(__FILE__)}/../fixtures/" ]
10
    else
11
      self.template_root = [ "#{File.dirname(__FILE__)}/../fixtures/" ]
12
    end
13
    
14
    def simple_paginate
15
      @topic_pages, @topics = paginate(:topics)
16
      render :nothing => true
17
    end
18
    
19
    def paginate_with_per_page
20
      @topic_pages, @topics = paginate(:topics, :per_page => 1)
21
      render :nothing => true
22
    end
23
    
24
    def paginate_with_order
25
      @topic_pages, @topics = paginate(:topics, :order => 'created_at asc')
26
      render :nothing => true
27
    end
28
    
29
    def paginate_with_order_by
30
      @topic_pages, @topics = paginate(:topics, :order_by => 'created_at asc')
31
      render :nothing => true
32
    end
33
    
34
    def paginate_with_include_and_order
35
      @topic_pages, @topics = paginate(:topics, :include => :replies, :order => 'replies.created_at asc, topics.created_at asc')
36
      render :nothing => true
37
    end
38
    
39
    def paginate_with_conditions
40
      @topic_pages, @topics = paginate(:topics, :conditions => ["created_at > ?", 30.minutes.ago])
41
      render :nothing => true
42
    end
43
    
44
    def paginate_with_class_name
45
      @developer_pages, @developers = paginate(:developers, :class_name => "DeVeLoPeR")
46
      render :nothing => true
47
    end
48
    
49
    def paginate_with_singular_name
50
      @developer_pages, @developers = paginate()
51
      render :nothing => true
52
    end
53
    
54
    def paginate_with_joins
55
      @developer_pages, @developers = paginate(:developers, 
56
                                             :joins => 'LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id',
57
                                             :conditions => 'project_id=1')        
58
      render :nothing => true
59
    end
60
    
61
    def paginate_with_join
62
      @developer_pages, @developers = paginate(:developers, 
63
                                             :join => 'LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id',
64
                                             :conditions => 'project_id=1')        
65
      render :nothing => true
66
    end
67
     
68
    def paginate_with_join_and_count
69
      @developer_pages, @developers = paginate(:developers, 
70
                                             :join => 'd LEFT JOIN developers_projects ON d.id = developers_projects.developer_id',
71
                                             :conditions => 'project_id=1',
72
                                             :count => "d.id")        
73
      render :nothing => true
74
    end
75

  
76
    def paginate_with_join_and_group
77
      @developer_pages, @developers = paginate(:developers, 
78
                                             :join => 'INNER JOIN developers_projects ON developers.id = developers_projects.developer_id',
79
                                             :group => 'developers.id')
80
      render :nothing => true
81
    end
82
    
83
    def rescue_errors(e) raise e end
84

  
85
    def rescue_action(e) raise end
86
    
87
  end
88
  
89
  def setup
90
    @controller = PaginationController.new
91
    @request    = ActionController::TestRequest.new
92
    @response   = ActionController::TestResponse.new
93
    super
94
  end
95

  
96
  # Single Action Pagination Tests
97

  
98
  def test_simple_paginate
99
    get :simple_paginate
100
    assert_equal 1, assigns(:topic_pages).page_count
101
    assert_equal 3, assigns(:topics).size
102
  end
103
  
104
  def test_paginate_with_per_page
105
    get :paginate_with_per_page
106
    assert_equal 1, assigns(:topics).size
107
    assert_equal 3, assigns(:topic_pages).page_count
108
  end
109
  
110
  def test_paginate_with_order
111
    get :paginate_with_order
112
    expected = [topics(:futurama),
113
               topics(:harvey_birdman),
114
               topics(:rails)]
115
    assert_equal expected, assigns(:topics)
116
    assert_equal 1, assigns(:topic_pages).page_count
117
  end
118
  
119
  def test_paginate_with_order_by
120
    get :paginate_with_order
121
    expected = assigns(:topics)
122
    get :paginate_with_order_by
123
    assert_equal expected, assigns(:topics)  
124
    assert_equal 1, assigns(:topic_pages).page_count    
125
  end
126
  
127
  def test_paginate_with_conditions
128
    get :paginate_with_conditions
129
    expected = [topics(:rails)]
130
    assert_equal expected, assigns(:topics)
131
    assert_equal 1, assigns(:topic_pages).page_count
132
  end
133
  
134
  def test_paginate_with_class_name
135
    get :paginate_with_class_name
136
    
137
    assert assigns(:developers).size > 0
138
    assert_equal DeVeLoPeR, assigns(:developers).first.class
139
  end
140
      
141
  def test_paginate_with_joins
142
    get :paginate_with_joins
143
    assert_equal 2, assigns(:developers).size
144
    developer_names = assigns(:developers).map { |d| d.name }
145
    assert developer_names.include?('David')
146
    assert developer_names.include?('Jamis')
147
  end
148
  
149
  def test_paginate_with_join_and_conditions
150
    get :paginate_with_joins
151
    expected = assigns(:developers)
152
    get :paginate_with_join
153
    assert_equal expected, assigns(:developers)
154
  end
155
  
156
  def test_paginate_with_join_and_count
157
    get :paginate_with_joins
158
    expected = assigns(:developers)
159
    get :paginate_with_join_and_count
160
    assert_equal expected, assigns(:developers)
161
  end
162
  
163
  def test_paginate_with_include_and_order
164
    get :paginate_with_include_and_order
165
    expected = Topic.find(:all, :include => 'replies', :order => 'replies.created_at asc, topics.created_at asc', :limit => 10)
166
    assert_equal expected, assigns(:topics)
167
  end
168

  
169
  def test_paginate_with_join_and_group
170
    get :paginate_with_join_and_group
171
    assert_equal 2, assigns(:developers).size
172
    assert_equal 2, assigns(:developer_pages).item_count
173
    developer_names = assigns(:developers).map { |d| d.name }
174
    assert developer_names.include?('David')
175
    assert developer_names.include?('Jamis')
176
  end
177
end
.svn/pristine/03/03b7cab2c78e7db2be70be489d305cf0f31baf79.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
class Tracker < ActiveRecord::Base
19
  before_destroy :check_integrity
20
  has_many :issues
21
  has_many :workflows, :dependent => :delete_all do
22
    def copy(source_tracker)
23
      Workflow.copy(source_tracker, nil, proxy_owner, nil)
24
    end
25
  end
26

  
27
  has_and_belongs_to_many :projects
28
  has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => "#{table_name_prefix}custom_fields_trackers#{table_name_suffix}", :association_foreign_key => 'custom_field_id'
29
  acts_as_list
30

  
31
  validates_presence_of :name
32
  validates_uniqueness_of :name
33
  validates_length_of :name, :maximum => 30
34

  
35
  named_scope :named, lambda {|arg| { :conditions => ["LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip]}}
36

  
37
  def to_s; name end
38

  
39
  def <=>(tracker)
40
    name <=> tracker.name
41
  end
42

  
43
  def self.all
44
    find(:all, :order => 'position')
45
  end
46

  
47
  # Returns an array of IssueStatus that are used
48
  # in the tracker's workflows
49
  def issue_statuses
50
    if @issue_statuses
51
      return @issue_statuses
52
    elsif new_record?
53
      return []
54
    end
55

  
56
    ids = Workflow.
57
            connection.select_rows("SELECT DISTINCT old_status_id, new_status_id FROM #{Workflow.table_name} WHERE tracker_id = #{id}").
58
            flatten.
59
            uniq
60

  
61
    @issue_statuses = IssueStatus.find_all_by_id(ids).sort
62
  end
63

  
64
private
65
  def check_integrity
66
    raise "Can't delete tracker" if Issue.find(:first, :conditions => ["tracker_id=?", self.id])
67
  end
68
end

Also available in: Unified diff