Commit e1f77b9be071fac9f57e85b2f3853d2f333aeaab
Exists in
master
and in
4 other branches
Merge branch 'link-to-issue-tracker' of https://github.com/Undev/gitlabhq into U…
…ndev-link-to-issue-tracker Conflicts: Gemfile.lock
Showing
20 changed files
with
299 additions
and
14 deletions
Show diff stats
Gemfile
... | ... | @@ -46,6 +46,9 @@ gem "grape-entity", "~> 0.2.0" |
46 | 46 | # based on human-friendly examples |
47 | 47 | gem "stamp" |
48 | 48 | |
49 | +# Enumeration fields | |
50 | +gem 'enumerize' | |
51 | + | |
49 | 52 | # Pagination |
50 | 53 | gem "kaminari", "~> 0.14.1" |
51 | 54 | |
... | ... | @@ -113,6 +116,7 @@ group :assets do |
113 | 116 | gem 'bootstrap-sass', "2.2.1.1" |
114 | 117 | gem "font-awesome-sass-rails", "~> 3.0.0" |
115 | 118 | gem "gemoji", "~> 1.2.1", require: 'emoji/railtie' |
119 | + gem "gon" | |
116 | 120 | end |
117 | 121 | |
118 | 122 | group :development do | ... | ... |
Gemfile.lock
... | ... | @@ -146,6 +146,8 @@ GEM |
146 | 146 | email_spec (1.4.0) |
147 | 147 | launchy (~> 2.1) |
148 | 148 | mail (~> 2.2) |
149 | + enumerize (0.5.1) | |
150 | + activesupport (>= 3.2) | |
149 | 151 | erubis (2.7.0) |
150 | 152 | escape_utils (0.2.4) |
151 | 153 | eventmachine (1.0.0) |
... | ... | @@ -184,10 +186,13 @@ GEM |
184 | 186 | pyu-ruby-sasl (~> 0.0.3.1) |
185 | 187 | rubyntlm (~> 0.1.1) |
186 | 188 | gitlab_yaml_db (1.0.0) |
189 | + gon (4.0.2) | |
187 | 190 | grape (0.3.1) |
191 | + actionpack (>= 2.3.0) | |
188 | 192 | activesupport |
189 | 193 | grape-entity (~> 0.2.0) |
190 | 194 | hashie (~> 1.2) |
195 | + json | |
191 | 196 | multi_json (>= 1.3.2) |
192 | 197 | multi_xml |
193 | 198 | rack |
... | ... | @@ -473,6 +478,7 @@ DEPENDENCIES |
473 | 478 | devise (~> 2.1.0) |
474 | 479 | draper (~> 0.18.0) |
475 | 480 | email_spec |
481 | + enumerize | |
476 | 482 | factory_girl_rails |
477 | 483 | ffaker |
478 | 484 | font-awesome-sass-rails (~> 3.0.0) |
... | ... | @@ -484,6 +490,7 @@ DEPENDENCIES |
484 | 490 | gitlab_meta (= 5.0) |
485 | 491 | gitlab_omniauth-ldap (= 1.0.2) |
486 | 492 | gitlab_yaml_db (= 1.0.0) |
493 | + gon | |
487 | 494 | grack! |
488 | 495 | grape (~> 0.3.1) |
489 | 496 | grape-entity (~> 0.2.0) | ... | ... |
app/assets/javascripts/projects.js.coffee
... | ... | @@ -18,3 +18,18 @@ $ -> |
18 | 18 | # Ref switcher |
19 | 19 | $('.project-refs-select').on 'change', -> |
20 | 20 | $(@).parents('form').submit() |
21 | + | |
22 | + $('#project_issues_enabled').change -> | |
23 | + if ($(this).is(':checked') == true) | |
24 | + $('#project_issues_tracker').removeAttr('disabled') | |
25 | + else | |
26 | + $('#project_issues_tracker').attr('disabled', 'disabled') | |
27 | + | |
28 | + $('#project_issues_tracker').change() | |
29 | + | |
30 | + $('#project_issues_tracker').change -> | |
31 | + if ($(this).val() == gon.default_issues_tracker || $(this).is(':disabled')) | |
32 | + $('#project_issues_tracker_id').attr('disabled', 'disabled') | |
33 | + else | |
34 | + $('#project_issues_tracker_id').removeAttr('disabled') | |
35 | + | ... | ... |
app/controllers/application_controller.rb
... | ... | @@ -5,6 +5,7 @@ class ApplicationController < ActionController::Base |
5 | 5 | before_filter :add_abilities |
6 | 6 | before_filter :dev_tools if Rails.env == 'development' |
7 | 7 | before_filter :default_headers |
8 | + before_filter :add_gon_variables | |
8 | 9 | |
9 | 10 | protect_from_forgery |
10 | 11 | |
... | ... | @@ -148,4 +149,8 @@ class ApplicationController < ActionController::Base |
148 | 149 | headers['X-Frame-Options'] = 'DENY' |
149 | 150 | headers['X-XSS-Protection'] = '1; mode=block' |
150 | 151 | end |
152 | + | |
153 | + def add_gon_variables | |
154 | + gon.default_issues_tracker = Project.issues_tracker.default_value | |
155 | + end | |
151 | 156 | end | ... | ... |
app/helpers/issues_helper.rb
... | ... | @@ -40,4 +40,39 @@ module IssuesHelper |
40 | 40 | def issues_active_milestones |
41 | 41 | @project.milestones.active.order("id desc").all |
42 | 42 | end |
43 | + | |
44 | + def url_for_project_issues | |
45 | + return "" if @project.nil? | |
46 | + | |
47 | + if @project.used_default_issues_tracker? | |
48 | + project_issues_filter_path(@project) | |
49 | + else | |
50 | + url = Settings[:issues_tracker][@project.issues_tracker]["project_url"] | |
51 | + url.gsub(':project_id', @project.id.to_s) | |
52 | + .gsub(':issues_tracker_id', @project.issues_tracker_id.to_s) | |
53 | + end | |
54 | + end | |
55 | + | |
56 | + def url_for_issue(issue_id) | |
57 | + return "" if @project.nil? | |
58 | + | |
59 | + if @project.used_default_issues_tracker? | |
60 | + url = project_issue_url project_id: @project, id: issue_id | |
61 | + else | |
62 | + url = Settings[:issues_tracker][@project.issues_tracker]["issues_url"] | |
63 | + url.gsub(':id', issue_id.to_s) | |
64 | + .gsub(':project_id', @project.id.to_s) | |
65 | + .gsub(':issues_tracker_id', @project.issues_tracker_id.to_s) | |
66 | + end | |
67 | + end | |
68 | + | |
69 | + def title_for_issue(issue_id) | |
70 | + return "" if @project.nil? | |
71 | + | |
72 | + if @project.used_default_issues_tracker? && issue = @project.issues.where(id: issue_id).first | |
73 | + issue.title | |
74 | + else | |
75 | + "" | |
76 | + end | |
77 | + end | |
43 | 78 | end | ... | ... |
app/models/project.rb
... | ... | @@ -11,6 +11,7 @@ |
11 | 11 | # creator_id :integer |
12 | 12 | # default_branch :string(255) |
13 | 13 | # issues_enabled :boolean default(TRUE), not null |
14 | +# issues_tracker :string not null | |
14 | 15 | # wall_enabled :boolean default(TRUE), not null |
15 | 16 | # merge_requests_enabled :boolean default(TRUE), not null |
16 | 17 | # wiki_enabled :boolean default(TRUE), not null |
... | ... | @@ -22,11 +23,12 @@ require "grit" |
22 | 23 | |
23 | 24 | class Project < ActiveRecord::Base |
24 | 25 | include Gitolited |
26 | + extend Enumerize | |
25 | 27 | |
26 | 28 | class TransferError < StandardError; end |
27 | 29 | |
28 | - attr_accessible :name, :path, :description, :default_branch, | |
29 | - :issues_enabled, :wall_enabled, :merge_requests_enabled, | |
30 | + attr_accessible :name, :path, :description, :default_branch, :issues_tracker, | |
31 | + :issues_enabled, :wall_enabled, :merge_requests_enabled, :issues_tracker_id, | |
30 | 32 | :wiki_enabled, :public, :import_url, as: [:default, :admin] |
31 | 33 | |
32 | 34 | attr_accessible :namespace_id, :creator_id, as: :admin |
... | ... | @@ -72,6 +74,7 @@ class Project < ActiveRecord::Base |
72 | 74 | message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" } |
73 | 75 | validates :issues_enabled, :wall_enabled, :merge_requests_enabled, |
74 | 76 | :wiki_enabled, inclusion: { in: [true, false] } |
77 | + validates :issues_tracker_id, length: { within: 0..255 } | |
75 | 78 | |
76 | 79 | validates_uniqueness_of :name, scope: :namespace_id |
77 | 80 | validates_uniqueness_of :path, scope: :namespace_id |
... | ... | @@ -93,6 +96,8 @@ class Project < ActiveRecord::Base |
93 | 96 | scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) } |
94 | 97 | scope :public_only, -> { where(public: true) } |
95 | 98 | |
99 | + enumerize :issues_tracker, :in => (Gitlab.config.issues_tracker.keys).append(:gitlab), :default => :gitlab | |
100 | + | |
96 | 101 | class << self |
97 | 102 | def abandoned |
98 | 103 | project_ids = Event.select('max(created_at) as latest_date, project_id'). |
... | ... | @@ -201,6 +206,22 @@ class Project < ActiveRecord::Base |
201 | 206 | issues.tag_counts_on(:labels) |
202 | 207 | end |
203 | 208 | |
209 | + def issue_exists?(issue_id) | |
210 | + if used_default_issues_tracker? | |
211 | + self.issues.where(id: issue_id).first.present? | |
212 | + else | |
213 | + true | |
214 | + end | |
215 | + end | |
216 | + | |
217 | + def used_default_issues_tracker? | |
218 | + self.issues_tracker == Project.issues_tracker.default_value | |
219 | + end | |
220 | + | |
221 | + def can_have_issues_tracker_id? | |
222 | + self.issues_enabled && !self.used_default_issues_tracker? | |
223 | + end | |
224 | + | |
204 | 225 | def services |
205 | 226 | [gitlab_ci_service].compact |
206 | 227 | end | ... | ... |
app/views/admin/projects/_form.html.haml
... | ... | @@ -31,6 +31,15 @@ |
31 | 31 | = f.label :issues_enabled, "Issues" |
32 | 32 | .input= f.check_box :issues_enabled |
33 | 33 | |
34 | + - if Project.issues_tracker.values.count > 1 | |
35 | + .clearfix | |
36 | + = f.label :issues_tracker, "Issues tracker", class: 'control-label' | |
37 | + .input= f.select(:issues_tracker, Project.issues_tracker.values, {}, { disabled: !@project.issues_enabled }) | |
38 | + | |
39 | + .clearfix | |
40 | + = f.label :issues_tracker_id, "Project name or id in issues tracker", class: 'control-label' | |
41 | + .input= f.text_field :issues_tracker_id, class: "xxlarge", disabled: !@project.can_have_issues_tracker_id? | |
42 | + | |
34 | 43 | .clearfix |
35 | 44 | = f.label :merge_requests_enabled, "Merge Requests" |
36 | 45 | .input= f.check_box :merge_requests_enabled | ... | ... |
app/views/layouts/_head.html.haml
app/views/layouts/project_resource.html.haml
... | ... | @@ -22,11 +22,12 @@ |
22 | 22 | = nav_link(controller: %w(graph)) do |
23 | 23 | = link_to "Network", project_graph_path(@project, @ref || @repository.root_ref) |
24 | 24 | |
25 | - - if @project.issues_enabled | |
25 | + - if @project.issues_enabled | |
26 | 26 | = nav_link(controller: %w(issues milestones labels)) do |
27 | - = link_to project_issues_filter_path(@project) do | |
27 | + = link_to url_for_project_issues do | |
28 | 28 | Issues |
29 | - %span.count.issue_counter= @project.issues.opened.count | |
29 | + - if @project.used_default_issues_tracker? | |
30 | + %span.count.issue_counter= @project.issues.opened.count | |
30 | 31 | |
31 | 32 | - if @project.repo_exists? && @project.merge_requests_enabled |
32 | 33 | = nav_link(controller: :merge_requests) do | ... | ... |
app/views/projects/_form.html.haml
... | ... | @@ -24,6 +24,15 @@ |
24 | 24 | = f.check_box :issues_enabled |
25 | 25 | %span.descr Lightweight issue tracking system for this project |
26 | 26 | |
27 | + - if Project.issues_tracker.values.count > 1 | |
28 | + .control-group | |
29 | + = f.label :issues_tracker, "Issues tracker", class: 'control-label' | |
30 | + .input= f.select(:issues_tracker, Project.issues_tracker.values, {}, { disabled: !@project.issues_enabled }) | |
31 | + | |
32 | + .clearfix | |
33 | + = f.label :issues_tracker_id, "Project name or id in issues tracker", class: 'control-label' | |
34 | + .input= f.text_field :issues_tracker_id, class: "xxlarge", disabled: !@project.can_have_issues_tracker_id? | |
35 | + | |
27 | 36 | .control-group |
28 | 37 | = f.label :merge_requests_enabled, "Merge Requests", class: 'control-label' |
29 | 38 | .controls | ... | ... |
config/gitlab.yml.example
... | ... | @@ -37,6 +37,22 @@ production: &base |
37 | 37 | # signup_enabled: true # default: false - Account passwords are not sent via the email if signup is enabled. |
38 | 38 | # username_changing_enabled: false # default: true - User can change her username/namespace |
39 | 39 | |
40 | + | |
41 | + ## External issues trackers | |
42 | + issues_tracker: | |
43 | + redmine: | |
44 | + ## If not nil, link 'Issues' on project page will be replaced tp this | |
45 | + ## Use placeholders: | |
46 | + ## :project_id - Gitlab project identifier | |
47 | + ## :issues_tracker_id - Project Name or Id in external issue tracker | |
48 | + project_url: "http://redmine.sample/projects/:issues_tracker_id" | |
49 | + ## If not nil, links from /#\d/ entities from commit messages will replaced to this | |
50 | + ## Use placeholders: | |
51 | + ## :project_id - Gitlab project identifier | |
52 | + ## :issues_tracker_id - Project Name or Id in external issue tracker | |
53 | + ## :id - Issue id (from commit messages) | |
54 | + issues_url: "http://redmine.sample/issues/:id" | |
55 | + | |
40 | 56 | ## Gravatar |
41 | 57 | gravatar: |
42 | 58 | enabled: true # Use user avatar images from Gravatar.com (default: true) |
... | ... | @@ -133,6 +149,10 @@ development: |
133 | 149 | |
134 | 150 | test: |
135 | 151 | <<: *base |
152 | + issues_tracker: | |
153 | + redmine: | |
154 | + project_url: "http://redmine/projects/:issues_tracker_id" | |
155 | + issues_url: "http://redmine/:project_id/:issues_tracker_id/:id" | |
136 | 156 | |
137 | 157 | staging: |
138 | 158 | <<: *base | ... | ... |
config/initializers/1_settings.rb
db/migrate/20130123114545_add_issues_tracker_to_project.rb
0 → 100644
db/migrate/20130211085435_add_issues_tracker_id_to_project.rb
0 → 100644
db/schema.rb
... | ... | @@ -106,11 +106,11 @@ ActiveRecord::Schema.define(:version => 20130220133245) do |
106 | 106 | add_index "milestones", ["project_id"], :name => "index_milestones_on_project_id" |
107 | 107 | |
108 | 108 | create_table "namespaces", :force => true do |t| |
109 | - t.string "name", :null => false | |
110 | - t.string "path", :null => false | |
111 | - t.integer "owner_id", :null => false | |
112 | - t.datetime "created_at", :null => false | |
113 | - t.datetime "updated_at", :null => false | |
109 | + t.string "name", :null => false | |
110 | + t.string "path", :null => false | |
111 | + t.integer "owner_id", :null => false | |
112 | + t.datetime "created_at", :null => false | |
113 | + t.datetime "updated_at", :null => false | |
114 | 114 | t.string "type" |
115 | 115 | end |
116 | 116 | |
... | ... | @@ -152,6 +152,8 @@ ActiveRecord::Schema.define(:version => 20130220133245) do |
152 | 152 | t.boolean "wiki_enabled", :default => true, :null => false |
153 | 153 | t.integer "namespace_id" |
154 | 154 | t.boolean "public", :default => false, :null => false |
155 | + t.string "issues_tracker", :default => "gitlab", :null => false | |
156 | + t.string "issues_tracker_id" | |
155 | 157 | end |
156 | 158 | |
157 | 159 | add_index "projects", ["creator_id"], :name => "index_projects_on_owner_id" |
... | ... | @@ -230,8 +232,8 @@ ActiveRecord::Schema.define(:version => 20130220133245) do |
230 | 232 | t.string "name" |
231 | 233 | t.string "path" |
232 | 234 | t.integer "owner_id" |
233 | - t.datetime "created_at", :null => false | |
234 | - t.datetime "updated_at", :null => false | |
235 | + t.datetime "created_at", :null => false | |
236 | + t.datetime "updated_at", :null => false | |
235 | 237 | end |
236 | 238 | |
237 | 239 | create_table "users", :force => true do |t| | ... | ... |
lib/gitlab/markdown.rb
... | ... | @@ -25,6 +25,8 @@ module Gitlab |
25 | 25 | # >> gfm(":trollface:") |
26 | 26 | # => "<img alt=\":trollface:\" class=\"emoji\" src=\"/images/trollface.png" title=\":trollface:\" /> |
27 | 27 | module Markdown |
28 | + include IssuesHelper | |
29 | + | |
28 | 30 | attr_reader :html_options |
29 | 31 | |
30 | 32 | # Public: Parse the provided text with GitLab-Flavored Markdown |
... | ... | @@ -163,8 +165,11 @@ module Gitlab |
163 | 165 | end |
164 | 166 | |
165 | 167 | def reference_issue(identifier) |
166 | - if issue = @project.issues.where(id: identifier).first | |
167 | - link_to("##{identifier}", project_issue_url(@project, issue), html_options.merge(title: "Issue: #{issue.title}", class: "gfm gfm-issue #{html_options[:class]}")) | |
168 | + if @project.issue_exists? identifier | |
169 | + url = url_for_issue(identifier) | |
170 | + title = title_for_issue(identifier) | |
171 | + | |
172 | + link_to("##{identifier}", url, html_options.merge(title: "Issue: #{title}", class: "gfm gfm-issue #{html_options[:class]}")) | |
168 | 173 | end |
169 | 174 | end |
170 | 175 | ... | ... |
spec/factories.rb
... | ... | @@ -29,6 +29,11 @@ FactoryGirl.define do |
29 | 29 | creator |
30 | 30 | end |
31 | 31 | |
32 | + factory :redmine_project, parent: :project do | |
33 | + issues_tracker { "redmine" } | |
34 | + issues_tracker_id { "project_name_in_redmine" } | |
35 | + end | |
36 | + | |
32 | 37 | factory :group do |
33 | 38 | sequence(:name) { |n| "group#{n}" } |
34 | 39 | path { name.downcase.gsub(/\s/, '_') } | ... | ... |
spec/helpers/gitlab_markdown_helper_spec.rb
... | ... | @@ -0,0 +1,79 @@ |
1 | +require "spec_helper" | |
2 | + | |
3 | +describe IssuesHelper do | |
4 | + let(:project) { create :project } | |
5 | + let(:issue) { create :issue, project: project } | |
6 | + let(:ext_project) { create :redmine_project } | |
7 | + | |
8 | + describe :title_for_issue do | |
9 | + it "should return issue title if used internal tracker" do | |
10 | + @project = project | |
11 | + title_for_issue(issue.id).should eq issue.title | |
12 | + end | |
13 | + | |
14 | + it "should always return empty string if used external tracker" do | |
15 | + @project = ext_project | |
16 | + title_for_issue(rand(100)).should eq "" | |
17 | + end | |
18 | + | |
19 | + it "should always return empty string if project nil" do | |
20 | + @project = nil | |
21 | + | |
22 | + title_for_issue(rand(100)).should eq "" | |
23 | + end | |
24 | + end | |
25 | + | |
26 | + describe :url_for_project_issues do | |
27 | + let(:project_url) { Gitlab.config.issues_tracker.redmine.project_url} | |
28 | + let(:ext_expected) do | |
29 | + project_url.gsub(':project_id', ext_project.id.to_s) | |
30 | + .gsub(':issues_tracker_id', ext_project.issues_tracker_id.to_s) | |
31 | + end | |
32 | + let(:int_expected) { polymorphic_path([project]) } | |
33 | + | |
34 | + it "should return internal path if used internal tracker" do | |
35 | + @project = project | |
36 | + url_for_project_issues.should match(int_expected) | |
37 | + end | |
38 | + | |
39 | + it "should return path to external tracker" do | |
40 | + @project = ext_project | |
41 | + | |
42 | + url_for_project_issues.should match(ext_expected) | |
43 | + end | |
44 | + | |
45 | + it "should return empty string if project nil" do | |
46 | + @project = nil | |
47 | + | |
48 | + url_for_project_issues.should eq "" | |
49 | + end | |
50 | + end | |
51 | + | |
52 | + describe :url_for_issue do | |
53 | + let(:issue_id) { 3 } | |
54 | + let(:issues_url) { Gitlab.config.issues_tracker.redmine.issues_url} | |
55 | + let(:ext_expected) do | |
56 | + issues_url.gsub(':id', issue_id.to_s) | |
57 | + .gsub(':project_id', ext_project.id.to_s) | |
58 | + .gsub(':issues_tracker_id', ext_project.issues_tracker_id.to_s) | |
59 | + end | |
60 | + let(:int_expected) { polymorphic_path([project, issue]) } | |
61 | + | |
62 | + it "should return internal path if used internal tracker" do | |
63 | + @project = project | |
64 | + url_for_issue(issue.id).should match(int_expected) | |
65 | + end | |
66 | + | |
67 | + it "should return path to external tracker" do | |
68 | + @project = ext_project | |
69 | + | |
70 | + url_for_issue(issue_id).should match(ext_expected) | |
71 | + end | |
72 | + | |
73 | + it "should return empty string if project nil" do | |
74 | + @project = nil | |
75 | + | |
76 | + url_for_issue(issue.id).should eq "" | |
77 | + end | |
78 | + end | |
79 | +end | ... | ... |
spec/models/project_spec.rb
... | ... | @@ -60,6 +60,7 @@ describe Project do |
60 | 60 | it { should ensure_inclusion_of(:wall_enabled).in_array([true, false]) } |
61 | 61 | it { should ensure_inclusion_of(:merge_requests_enabled).in_array([true, false]) } |
62 | 62 | it { should ensure_inclusion_of(:wiki_enabled).in_array([true, false]) } |
63 | + it { should ensure_length_of(:issues_tracker_id).is_within(0..255) } | |
63 | 64 | |
64 | 65 | it "should not allow new projects beyond user limits" do |
65 | 66 | project.stub(:creator).and_return(double(can_create_project?: false, projects_limit: 1)) |
... | ... | @@ -190,4 +191,57 @@ describe Project do |
190 | 191 | Project.new(path: "empty").repository.should be_nil |
191 | 192 | end |
192 | 193 | end |
194 | + | |
195 | + describe :issue_exists? do | |
196 | + let(:project) { create(:project) } | |
197 | + let(:existed_issue) { create(:issue, project: project) } | |
198 | + let(:not_existed_issue) { create(:issue) } | |
199 | + let(:ext_project) { create(:redmine_project) } | |
200 | + | |
201 | + it "should be true or if used internal tracker and issue exists" do | |
202 | + project.issue_exists?(existed_issue.id).should be_true | |
203 | + end | |
204 | + | |
205 | + it "should be false or if used internal tracker and issue not exists" do | |
206 | + project.issue_exists?(not_existed_issue.id).should be_false | |
207 | + end | |
208 | + | |
209 | + it "should always be true if used other tracker" do | |
210 | + ext_project.issue_exists?(rand(100)).should be_true | |
211 | + end | |
212 | + end | |
213 | + | |
214 | + describe :used_default_issues_tracker? do | |
215 | + let(:project) { create(:project) } | |
216 | + let(:ext_project) { create(:redmine_project) } | |
217 | + | |
218 | + it "should be true if used internal tracker" do | |
219 | + project.used_default_issues_tracker?.should be_true | |
220 | + end | |
221 | + | |
222 | + it "should be false if used other tracker" do | |
223 | + ext_project.used_default_issues_tracker?.should be_false | |
224 | + end | |
225 | + end | |
226 | + | |
227 | + describe :can_have_issues_tracker_id? do | |
228 | + let(:project) { create(:project) } | |
229 | + let(:ext_project) { create(:redmine_project) } | |
230 | + | |
231 | + it "should be true for projects with external issues tracker if issues enabled" do | |
232 | + ext_project.can_have_issues_tracker_id?.should be_true | |
233 | + end | |
234 | + | |
235 | + it "should be false for projects with internal issue tracker if issues enabled" do | |
236 | + project.can_have_issues_tracker_id?.should be_false | |
237 | + end | |
238 | + | |
239 | + it "should be always false if issues disbled" do | |
240 | + project.issues_enabled = false | |
241 | + ext_project.issues_enabled = false | |
242 | + | |
243 | + project.can_have_issues_tracker_id?.should be_false | |
244 | + ext_project.can_have_issues_tracker_id?.should be_false | |
245 | + end | |
246 | + end | |
193 | 247 | end | ... | ... |