Commit eedfabc05407c181350302b4e9f68f5c5c473b61

Authored by Stephen Crosby
2 parents 3b534e9c a409ed56
Exists in master and in 1 other branch production

Merge pull request #859 from stevecrozz/new_icon_interface

new image icon interface
1 GIT 1 GIT
2 remote: git://github.com/errbit/errbit_github_plugin.git 2 remote: git://github.com/errbit/errbit_github_plugin.git
3 - revision: 7eb48d540b94d2fa4b8f9805ec0148322ae2bffe 3 + revision: 3597f2d2c6aa75e014251747a30eeb5d19f641dd
4 specs: 4 specs:
5 errbit_github_plugin (0.1.0) 5 errbit_github_plugin (0.1.0)
6 errbit_plugin 6 errbit_plugin
@@ -8,7 +8,7 @@ GIT @@ -8,7 +8,7 @@ GIT
8 8
9 GIT 9 GIT
10 remote: git://github.com/errbit/errbit_plugin.git 10 remote: git://github.com/errbit/errbit_plugin.git
11 - revision: 6a0b93d71a6b4545198f0c68b99b8e8f9281c17e 11 + revision: 9cfe43119be46bfa36cbf4b940b80d39229595ef
12 specs: 12 specs:
13 errbit_plugin (0.4.0) 13 errbit_plugin (0.4.0)
14 14
app/assets/javascripts/form.js
@@ -82,11 +82,17 @@ function activateTypeSelector(field_class, section_class) { @@ -82,11 +82,17 @@ function activateTypeSelector(field_class, section_class) {
82 .attr('disabled','disabled').val(''); 82 .attr('disabled','disabled').val('');
83 83
84 $('div.'+field_class).find('.choose input[name*=type]').on('click', function(){ 84 $('div.'+field_class).find('.choose input[name*=type]').on('click', function(){
  85 + var input = $(this);
85 // Look for section in 'data-section', and fall back to 'value' 86 // Look for section in 'data-section', and fall back to 'value'
86 - var chosen = $(this).data("section") || $(this).val();  
87 - var wrapper = $(this).closest('.nested'); 87 + var chosen = input.data("section") || input.val();
  88 + var wrapper = input.closest('.nested');
  89 + var allLabels = wrapper.find('.label_radio');
  90 +
88 wrapper.find('div.chosen.'+section_class).removeClass('chosen').find('input').attr('disabled','disabled'); 91 wrapper.find('div.chosen.'+section_class).removeClass('chosen').find('input').attr('disabled','disabled');
89 wrapper.find('div.'+section_class+'.'+chosen).addClass('chosen').find('input').removeAttr('disabled'); 92 wrapper.find('div.'+section_class+'.'+chosen).addClass('chosen').find('input').removeAttr('disabled');
  93 +
  94 + wrapper.find('.icon').each(function(){ $(this).attr('src', $(this).data('iconInactive')) });
  95 + input.siblings('.icon').each(function(){ $(this).attr('src', $(this).data('iconCreate')) });
90 }); 96 });
91 } 97 }
92 98
app/assets/stylesheets/application.css.erb
@@ -2,12 +2,6 @@ @@ -2,12 +2,6 @@
2 *= require reset 2 *= require reset
3 *= require jquery.alerts 3 *= require jquery.alerts
4 *= require errbit 4 *= require errbit
5 - *= require issue_tracker_icons  
6 *= require notification_service_icons 5 *= require notification_service_icons
7 *= require_self 6 *= require_self
8 */ 7 */
9 -  
10 -// Allow any gems named 'errbit_*' to require their own assets  
11 -<% Gem.loaded_specs.keys.grep(/^errbit_/).each do |plugin|  
12 - require_asset(plugin) rescue Sprockets::FileNotFound  
13 -end %>  
app/assets/stylesheets/errbit.css.erb
@@ -552,34 +552,63 @@ div.nested .choose { @@ -552,34 +552,63 @@ div.nested .choose {
552 margin-bottom: 0.5em; 552 margin-bottom: 0.5em;
553 } 553 }
554 554
555 -div.issue_tracker.nested .choose, div.notification_service.nested .choose { 555 +div.issue_tracker.nested .choose {
556 background-color: #ebebeb; 556 background-color: #ebebeb;
557 border: 1px solid #dddddd; 557 border: 1px solid #dddddd;
558 margin: 0 0 15px; 558 margin: 0 0 15px;
559 padding: 12px; 559 padding: 12px;
560 } 560 }
561 -div.issue_tracker.nested img, div.notification_service.nested img { 561 +
  562 +div.notification_service.nested .choose {
  563 + background-color: #ebebeb;
  564 + border: 1px solid #dddddd;
  565 + margin: 0 0 15px;
  566 + padding: 12px;
  567 +
  568 +}
  569 +div.issue_tracker.nested img {
  570 + vertical-align: middle;
  571 +}
  572 +
  573 +div.notification_service.nested img {
562 vertical-align: middle; 574 vertical-align: middle;
563 } 575 }
564 576
565 /* Icons for Issue Tracker Radio Buttons */ 577 /* Icons for Issue Tracker Radio Buttons */
566 -div.issue_tracker.nested label.label_radio, div.notification_service.nested label.label_radio { 578 +div.issue_tracker.nested label.label_radio {
  579 + color: #929292;
  580 + margin-right: 8px;
  581 +}
  582 +
  583 +div.notification_service.nested label.label_radio {
567 color: #929292; 584 color: #929292;
568 padding-left: 33px; 585 padding-left: 33px;
569 margin-bottom: 6px; 586 margin-bottom: 6px;
570 margin-right: 8px; 587 margin-right: 8px;
571 line-height: 30px; 588 line-height: 30px;
572 } 589 }
573 -div.issue_tracker.nested .choose, div.notification_service.nested .choose { 590 +
  591 +div.notification_service.nested .choose {
574 padding-bottom: 6px; 592 padding-bottom: 6px;
575 } 593 }
  594 +
576 div.issue_tracker.nested label.label_radio:hover, div.notification_service.nested label.label_radio:hover { 595 div.issue_tracker.nested label.label_radio:hover, div.notification_service.nested label.label_radio:hover {
577 color: #696969; 596 color: #696969;
578 } 597 }
579 -div.issue_tracker.nested .label_radio input, div.notification_service.nested .label_radio input { 598 +
  599 +div.issue_tracker.nested .label_radio input {
  600 + display: none;
  601 +}
  602 +
  603 +div.notification_service.nested .label_radio input {
580 position: absolute; left: -9999px; 604 position: absolute; left: -9999px;
581 } 605 }
582 606
  607 +.button-icon {
  608 + float: left;
  609 + margin: 5px 0 0 6px;
  610 +}
  611 +
583 div.issue_tracker.nested label.r_on, div.issue_tracker.nested label.r_on:hover, div.notification_service.nested label.r_on, div.notification_service.nested label.r_on:hover { 612 div.issue_tracker.nested label.r_on, div.issue_tracker.nested label.r_on:hover, div.notification_service.nested label.r_on, div.notification_service.nested label.r_on:hover {
584 color: #191919; 613 color: #191919;
585 } 614 }
app/assets/stylesheets/issue_tracker_icons.css.erb
@@ -1,9 +0,0 @@ @@ -1,9 +0,0 @@
1 -/* Issue Tracker inactive, select, create and goto icons */  
2 -  
3 -<% ErrbitPlugin::Registry.issue_trackers.keys.each do |label| %>  
4 -div.issue_tracker.nested label.<%= label %> { background: url(<%= asset_path "#{ label }_inactive.png" %>) no-repeat; }  
5 -div.issue_tracker.nested label.r_on.<%= label %> { background: url(<%= asset_path "#{ label }_create.png" %>) no-repeat; }  
6 -#action-bar a.<%= label %>_create { background: transparent url(<%= asset_path "#{ label }_create.png" %>) 6px 5px no-repeat; }  
7 -#action-bar a.<%= label %>_goto { background: transparent url(<%= asset_path "#{ label }_goto.png" %>) 6px 5px no-repeat; }  
8 -<% end %>  
9 -  
app/controllers/apps_controller.rb
@@ -12,7 +12,7 @@ class AppsController &lt; ApplicationController @@ -12,7 +12,7 @@ class AppsController &lt; ApplicationController
12 } 12 }
13 13
14 expose(:apps) { 14 expose(:apps) {
15 - app_scope.all.sort.to_a 15 + app_scope.all.sort.map { |app| AppDecorator.new(app) }
16 } 16 }
17 17
18 expose(:app, ancestor: :app_scope, attributes: :app_params) 18 expose(:app, ancestor: :app_scope, attributes: :app_params)
app/controllers/problems_controller.rb
@@ -12,28 +12,23 @@ class ProblemsController &lt; ApplicationController @@ -12,28 +12,23 @@ class ProblemsController &lt; ApplicationController
12 :resolve_several, :unresolve_several, :unmerge_several 12 :resolve_several, :unresolve_several, :unmerge_several
13 ] 13 ]
14 14
  15 + expose(:app_scope) {
  16 + apps = current_user.admin? ? App.all : current_user.apps
  17 + params[:app_id] ? apps.where(:_id => params[:app_id]) : apps
  18 + }
  19 +
15 expose(:app) { 20 expose(:app) {
16 - if current_user.admin?  
17 - App.find(params[:app_id])  
18 - else  
19 - current_user.apps.find(params[:app_id])  
20 - end 21 + AppDecorator.new app_scope.find(params[:app_id])
21 } 22 }
22 23
23 expose(:problem) { 24 expose(:problem) {
24 app.problems.find(params[:id]) 25 app.problems.find(params[:id])
25 } 26 }
26 27
27 -  
28 expose(:all_errs) { 28 expose(:all_errs) {
29 params[:all_errs] 29 params[:all_errs]
30 } 30 }
31 31
32 - expose(:app_scope) {  
33 - apps = current_user.admin? ? App.all : current_user.apps  
34 - params[:app_id] ? apps.where(:_id => params[:app_id]) : apps  
35 - }  
36 -  
37 expose(:params_environement) { 32 expose(:params_environement) {
38 params[:environment] 33 params[:environment]
39 } 34 }
app/decorators/issue_tracker_decorator.rb
  1 +# Decorates an instance of IssueTracker
1 class IssueTrackerDecorator < Draper::Decorator 2 class IssueTrackerDecorator < Draper::Decorator
2 -  
3 - def initialize(object, key)  
4 - @object = object  
5 - @key = key  
6 - end  
7 - attr_reader :key  
8 -  
9 delegate_all 3 delegate_all
10 4
11 - def issue_trackers  
12 - ErrbitPlugin::Registry.issue_trackers.each do |key, object|  
13 - yield IssueTrackerDecorator.new(object, key)  
14 - end  
15 - end  
16 -  
17 - def note  
18 - object.note.html_safe  
19 - end  
20 -  
21 - def fields  
22 - object.fields.each do |field, field_info|  
23 - yield IssueTrackerFieldDecorator.new(field, field_info)  
24 - end 5 + def type
  6 + @type ||= IssueTrackerTypeDecorator.new(object.tracker.class)
25 end 7 end
26 -  
27 - def params_class(tracker)  
28 - [chosen?(tracker), label].join(" ").strip  
29 - end  
30 -  
31 - private  
32 -  
33 - def chosen?(issue_tracker)  
34 - key == issue_tracker.type_tracker.to_s ? 'chosen' : ''  
35 - end  
36 -  
37 end 8 end
app/decorators/issue_tracker_type_decorator.rb 0 → 100644
@@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
  1 +# Decorates an IssueTracker class
  2 +class IssueTrackerTypeDecorator < Draper::Decorator
  3 + delegate_all
  4 +
  5 + # return hash of icons as data URIs
  6 + def icons
  7 + return unless object.icons
  8 +
  9 + object.icons.reduce({}) do |c, (k,v)|
  10 + c[k] = "data:#{v[0]};base64,#{Base64.encode64(v[1])}"; c
  11 + end
  12 + end
  13 +
  14 + # class name for tracker type form fields
  15 + #
  16 + # 'chosen github' or 'bitbucket' for example
  17 + def params_class(tracker)
  18 + [object.label == tracker.type_tracker ? 'chosen' : '', label].join(" ").strip
  19 + end
  20 +
  21 + def note
  22 + object.note.html_safe
  23 + end
  24 +
  25 + def fields
  26 + object.fields.each do |field, field_info|
  27 + yield IssueTrackerFieldDecorator.new(field, field_info)
  28 + end
  29 + end
  30 +end
app/helpers/application_helper.rb
@@ -69,6 +69,12 @@ module ApplicationHelper @@ -69,6 +69,12 @@ module ApplicationHelper
69 collection.to_a[head_size..-1].to_a 69 collection.to_a[head_size..-1].to_a
70 end 70 end
71 71
  72 + def issue_tracker_types
  73 + ErrbitPlugin::Registry.issue_trackers.map do |_, object|
  74 + IssueTrackerTypeDecorator.new(object)
  75 + end
  76 + end
  77 +
72 private 78 private
73 def total_from_tallies(tallies) 79 def total_from_tallies(tallies)
74 tallies.values.inject(0) {|sum, n| sum + n} 80 tallies.values.inject(0) {|sum, n| sum + n}
@@ -79,4 +85,3 @@ module ApplicationHelper @@ -79,4 +85,3 @@ module ApplicationHelper
79 end 85 end
80 86
81 end 87 end
82 -  
app/models/issue_tracker.rb
@@ -14,10 +14,17 @@ class IssueTracker @@ -14,10 +14,17 @@ class IssueTracker
14 begin 14 begin
15 klass = ErrbitPlugin::Registry.issue_trackers[self.type_tracker] || ErrbitPlugin::NoneIssueTracker 15 klass = ErrbitPlugin::Registry.issue_trackers[self.type_tracker] || ErrbitPlugin::NoneIssueTracker
16 # TODO: we need to find out a better way to pass those config to the issue tracker 16 # TODO: we need to find out a better way to pass those config to the issue tracker
17 - klass.new(options.merge(github_repo: app.github_repo, bitbucket_repo: app.bitbucket_repo)) 17 + klass.new(options.merge(
  18 + github_repo: app.try(:github_repo),
  19 + bitbucket_repo: app.try(:bitbucket_repo)
  20 + ))
18 end 21 end
19 end 22 end
20 23
  24 + def type_tracker
  25 + self.attributes['type_tracker'] ? self.attributes['type_tracker'] : 'none'
  26 + end
  27 +
21 # Allow the tracker to validate its own params 28 # Allow the tracker to validate its own params
22 def validate_tracker 29 def validate_tracker
23 (tracker.errors || {}).each do |k,v| 30 (tracker.errors || {}).each do |k,v|
app/views/apps/_issue_tracker_fields.html.haml
@@ -3,21 +3,17 @@ @@ -3,21 +3,17 @@
3 = f.fields_for :issue_tracker do |issue_tracker_form| 3 = f.fields_for :issue_tracker do |issue_tracker_form|
4 %div.issue_tracker.nested 4 %div.issue_tracker.nested
5 %div.choose 5 %div.choose
6 - - issue_tracker_form.object.issue_trackers do |tracker|  
7 - = issue_tracker_form.label :type_tracker, :class => "label_radio #{tracker.label}", :value => tracker.key do  
8 - = issue_tracker_form.radio_button :type_tracker, tracker.key, 'data-section' => tracker.label  
9 - = tracker.label 6 + - issue_tracker_types.each do |tracker_type|
  7 + = issue_tracker_form.label :type_tracker, :class => "label_radio #{tracker_type.label}", :value => tracker_type.label do
  8 + - icon = tracker_type == issue_tracker_form.object.type ? :create : :inactive
  9 + %img.icon{"src" => tracker_type.icons[icon], "data-icon" => tracker_type.icons}
  10 + = issue_tracker_form.radio_button :type_tracker, tracker_type.label, 'data-section' => tracker_type.label
  11 + = tracker_type.label
10 12
11 - - issue_tracker_form.object.issue_trackers do |tracker|  
12 - %div.tracker_params{:class => tracker.params_class(issue_tracker_form.object)} 13 + - issue_tracker_types.each do |tracker_type|
  14 + %div.tracker_params{:class => tracker_type.params_class(issue_tracker_form.object)}
13 = issue_tracker_form.fields_for(:options) do |options_form| 15 = issue_tracker_form.fields_for(:options) do |options_form|
14 - %p= tracker.note  
15 - - tracker.fields do |field| 16 + %p= tracker_type.note
  17 + - tracker_type.fields do |field|
16 = options_form.label field.key, field.label 18 = options_form.label field.key, field.label
17 = field.input(options_form, issue_tracker_form.object) 19 = field.input(options_form, issue_tracker_form.object)
18 -  
19 - .image_preloader  
20 - - issue_tracker_form.object.issue_trackers do |tracker|  
21 - = image_tag "#{tracker.label}_inactive.png"  
22 - = image_tag "#{tracker.label}_create.png"  
23 -  
app/views/apps/index.html.haml
@@ -36,7 +36,7 @@ @@ -36,7 +36,7 @@
36 - if any_issue_trackers? 36 - if any_issue_trackers?
37 %td.issue_tracker 37 %td.issue_tracker
38 - if app.issue_tracker_configured? 38 - if app.issue_tracker_configured?
39 - - tracker_img = image_tag("#{app.issue_tracker.type_tracker}_goto.png") 39 + - tracker_img = image_tag(app.issue_tracker.type.icons[:goto])
40 - if app.issue_tracker.url 40 - if app.issue_tracker.url
41 = link_to( tracker_img, app.issue_tracker.url ) 41 = link_to( tracker_img, app.issue_tracker.url )
42 - else 42 - else
app/views/problems/_issue_tracker_links.html.haml
1 - if app.issue_tracker_configured? 1 - if app.issue_tracker_configured?
  2 + - tracker = app.issue_tracker
  3 + - tracker_type = tracker.type
2 - if problem.issue_link.present? 4 - if problem.issue_link.present?
3 - %span= link_to 'go to issue', problem.issue_link, :class => "#{problem.issue_type}_goto goto-issue" 5 + %span
  6 + %img.button-icon{"src" => tracker_type.icons[:create]}
  7 + = link_to 'go to issue', problem.issue_link, :class => "goto-issue"
4 = link_to 'unlink issue', unlink_issue_app_problem_path(app, problem), :method => :delete, :data => { :confirm => "Unlink err issues?" }, :class => "unlink-issue" 8 = link_to 'unlink issue', unlink_issue_app_problem_path(app, problem), :method => :delete, :data => { :confirm => "Unlink err issues?" }, :class => "unlink-issue"
5 - elsif problem.issue_link == "pending" 9 - elsif problem.issue_link == "pending"
6 - %span.disabled= link_to 'creating...', '#', :class => "#{problem.issue_type}_inactive create-issue" 10 + %span.disabled
  11 + %img.button-icon{"src" => tracker_type.icons[:inactive]}
  12 + = link_to 'creating...', '#', :class => "create-issue"
7 = link_to 'retry', create_issue_app_problem_path(app, problem), :method => :post 13 = link_to 'retry', create_issue_app_problem_path(app, problem), :method => :post
8 - else 14 - else
9 - %span= link_to 'create issue', create_issue_app_problem_path(app, problem), method: :post, class: "#{app.issue_tracker.type_tracker}_create create-issue" 15 + %span
  16 + %img.button-icon{"src" => tracker_type.icons[:goto]}
  17 + = link_to 'create issue', create_issue_app_problem_path(app, problem), method: :post, :class => "create-issue"
config/initializers/assets.rb
@@ -6,6 +6,3 @@ Rails.application.config.assets.version = &#39;1.0&#39; @@ -6,6 +6,3 @@ Rails.application.config.assets.version = &#39;1.0&#39;
6 # Precompile additional assets. 6 # Precompile additional assets.
7 # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 7 # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
8 # Rails.application.config.assets.precompile += %w( search.js ) 8 # Rails.application.config.assets.precompile += %w( search.js )
9 -  
10 -# Need to initialize Rails environment for issue_tracker_icons.css.erb  
11 -Rails.application.config.assets.initialize_on_precompile = true  
lib/tasks/errbit/demo.rake
1 namespace :errbit do 1 namespace :errbit do
2 -  
3 desc "Add a demo app & errors to your database (for testing)" 2 desc "Add a demo app & errors to your database (for testing)"
4 task :demo => :environment do 3 task :demo => :environment do
  4 + require 'fabrication'
5 5
6 app = Fabricate(:app, :name => "Demo App #{Time.now.strftime("%N")}") 6 app = Fabricate(:app, :name => "Demo App #{Time.now.strftime("%N")}")
7 7
@@ -68,5 +68,4 @@ namespace :errbit do @@ -68,5 +68,4 @@ namespace :errbit do
68 Fabricate(:notice, :err => Fabricate(:err, :problem => Fabricate(:problem, :app => app))) 68 Fabricate(:notice, :err => Fabricate(:err, :problem => Fabricate(:problem, :app => app)))
69 puts "=== Created demo app: '#{app.name}', with example errors." 69 puts "=== Created demo app: '#{app.name}', with example errors."
70 end 70 end
71 -  
72 end 71 end
spec/controllers/problems_controller_spec.rb
@@ -218,9 +218,7 @@ describe ProblemsController, type: &#39;controller&#39; do @@ -218,9 +218,7 @@ describe ProblemsController, type: &#39;controller&#39; do
218 @err = Fabricate(:err) 218 @err = Fabricate(:err)
219 end 219 end
220 220
221 - it 'finds the app and the err' do  
222 - expect(App).to receive(:find).with(@err.app.id.to_s).and_return(@err.app)  
223 - expect(@err.app.problems).to receive(:find).and_return(@err.problem) 221 + it 'finds the app and the problem' do
224 put :resolve, :app_id => @err.app.id, :id => @err.problem.id 222 put :resolve, :app_id => @err.app.id, :id => @err.problem.id
225 expect(controller.app).to eq @err.app 223 expect(controller.app).to eq @err.app
226 expect(controller.problem).to eq @err.problem 224 expect(controller.problem).to eq @err.problem
spec/decorators/issue_tracker_decorator_spec.rb
1 describe IssueTrackerDecorator do 1 describe IssueTrackerDecorator do
2 let(:fake_tracker) do 2 let(:fake_tracker) do
3 - Class.new(ErrbitPlugin::IssueTracker) do 3 + klass = Class.new(ErrbitPlugin::IssueTracker) {
4 def self.label; 'fake'; end 4 def self.label; 'fake'; end
5 def self.note; 'a note'; end 5 def self.note; 'a note'; end
6 def self.fields 6 def self.fields
@@ -11,43 +11,23 @@ describe IssueTrackerDecorator do @@ -11,43 +11,23 @@ describe IssueTrackerDecorator do
11 end 11 end
12 12
13 def configured?; true; end 13 def configured?; true; end
14 - end 14 + }
  15 + klass.new 'nothing special'
15 end 16 end
16 17
17 - let(:decorator) do  
18 - IssueTrackerDecorator.new(fake_tracker, 'fake') 18 + let(:issue_tracker) do
  19 + it = IssueTracker.new
  20 + allow(it).to receive(:tracker).and_return(fake_tracker)
  21 + it
19 end 22 end
20 23
21 - describe "#note" do  
22 - it 'return the html_safe of Note' do  
23 - expect(decorator.note).to eql fake_tracker.note  
24 - end  
25 - end  
26 -  
27 - describe "#issue_trackers" do  
28 - it 'return an array of IssueTrackerDecorator' do  
29 - decorator.issue_trackers do |it|  
30 - expect(it).to be_a(IssueTrackerDecorator)  
31 - end  
32 - end  
33 - end  
34 -  
35 - describe "#fields" do  
36 - it 'return all Fields define decorate' do  
37 - decorator.fields do |itf|  
38 - expect(itf).to be_a(IssueTrackerFieldDecorator)  
39 - expect([:foo, :bar]).to be_include(itf.object)  
40 - expect([{:label => 'foo'}, {:label => 'bar'}]).to be_include(itf.field_info)  
41 - end  
42 - end 24 + let(:decorator) do
  25 + IssueTrackerDecorator.new(issue_tracker)
43 end 26 end
44 27
45 - describe "#params_class" do  
46 - it 'add the label in class' do  
47 - expect(decorator.params_class(IssueTracker.new(:type_tracker => 'none'))).to eql 'fake'  
48 - end  
49 - it 'add chosen class if _type is same' do  
50 - expect(decorator.params_class(IssueTracker.new(:type_tracker => 'fake'))).to eql 'chosen fake' 28 + describe "#type" do
  29 + it 'returns decorator for the issue tracker class' do
  30 + expect(decorator.type.class).to eq(IssueTrackerTypeDecorator)
51 end 31 end
52 end 32 end
53 end 33 end
spec/decorators/issue_tracker_type_decorator_spec.rb 0 → 100644
@@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
  1 +describe IssueTrackerDecorator do
  2 + let(:fake_tracker_class) do
  3 + klass = Class.new(ErrbitPlugin::IssueTracker) do
  4 + def self.label; 'fake'; end
  5 + def self.note; 'a note'; end
  6 + def self.fields
  7 + {
  8 + :foo => {:label => 'foo'},
  9 + :bar => {:label => 'bar'}
  10 + }
  11 + end
  12 + def self.icons
  13 + {
  14 + one: ['text/plain', 'all your base are belong to us'],
  15 + two: ['application/xml', '<root></root>'],
  16 + }
  17 + end
  18 + end
  19 +
  20 + allow(ErrbitPlugin::Registry).to receive(:issue_trackers).and_return({
  21 + fake: klass
  22 + })
  23 +
  24 + klass
  25 + end
  26 +
  27 + let(:fake_tracker) { IssueTrackerDecorator.new(fake_tracker_class.new) }
  28 + let(:decorator) { IssueTrackerTypeDecorator.new(fake_tracker_class) }
  29 +
  30 + describe "::note" do
  31 + it 'return the html_safe of Note' do
  32 + expect(decorator.note).to eql fake_tracker_class.note
  33 + end
  34 + end
  35 +
  36 + describe "#fields" do
  37 + it 'return all Fields define decorate' do
  38 + decorator.fields do |itf|
  39 + expect(itf).to be_a(IssueTrackerFieldDecorator)
  40 + expect([:foo, :bar]).to be_include(itf.object)
  41 + expect([{:label => 'foo'}, {:label => 'bar'}]).to be_include(itf.field_info)
  42 + end
  43 + end
  44 + end
  45 +
  46 + describe "#params_class" do
  47 + it 'adds the label in class' do
  48 + tracker = IssueTrackerDecorator.new(IssueTracker.new(
  49 + type_tracker: 'none'))
  50 + expect(decorator.params_class(tracker)).to eql 'fake'
  51 + end
  52 +
  53 + it 'adds chosen class if type is same' do
  54 + expect(decorator.params_class(
  55 + IssueTracker.new(type_tracker: 'fake').decorate
  56 + )).to eql 'chosen fake'
  57 + end
  58 + end
  59 +end
spec/views/problems/show.html.haml_spec.rb
@@ -4,12 +4,14 @@ describe &quot;problems/show.html.haml&quot;, type: &#39;view&#39; do @@ -4,12 +4,14 @@ describe &quot;problems/show.html.haml&quot;, type: &#39;view&#39; do
4 let(:pivotal_tracker) { 4 let(:pivotal_tracker) {
5 Class.new(ErrbitPlugin::MockIssueTracker) do 5 Class.new(ErrbitPlugin::MockIssueTracker) do
6 def self.label; 'pivotal'; end 6 def self.label; 'pivotal'; end
  7 + def self.icons; {}; end
7 def configured?; true; end 8 def configured?; true; end
8 end 9 end
9 } 10 }
10 let(:github_tracker) { 11 let(:github_tracker) {
11 Class.new(ErrbitPlugin::MockIssueTracker) do 12 Class.new(ErrbitPlugin::MockIssueTracker) do
12 - def label; 'github'; end 13 + def self.label; 'github'; end
  14 + def self.icons; {}; end
13 def configured?; true; end 15 def configured?; true; end
14 end 16 end
15 } 17 }
@@ -19,9 +21,10 @@ describe &quot;problems/show.html.haml&quot;, type: &#39;view&#39; do @@ -19,9 +21,10 @@ describe &quot;problems/show.html.haml&quot;, type: &#39;view&#39; do
19 'pivotal' => pivotal_tracker 21 'pivotal' => pivotal_tracker
20 } 22 }
21 } 23 }
  24 + let(:app) { AppDecorator.new(problem.app) }
22 25
23 before do 26 before do
24 - allow(view).to receive(:app).and_return(problem.app) 27 + allow(view).to receive(:app).and_return(app)
25 allow(view).to receive(:problem).and_return(problem) 28 allow(view).to receive(:problem).and_return(problem)
26 29
27 assign :comment, comment 30 assign :comment, comment
@@ -33,7 +36,11 @@ describe &quot;problems/show.html.haml&quot;, type: &#39;view&#39; do @@ -33,7 +36,11 @@ describe &quot;problems/show.html.haml&quot;, type: &#39;view&#39; do
33 36
34 def with_issue_tracker(tracker, problem) 37 def with_issue_tracker(tracker, problem)
35 allow(ErrbitPlugin::Registry).to receive(:issue_trackers).and_return(trackers) 38 allow(ErrbitPlugin::Registry).to receive(:issue_trackers).and_return(trackers)
36 - problem.app.issue_tracker = IssueTracker.new :type_tracker => tracker, :options => {:api_token => "token token token", :project_id => "1234"} 39 + app.issue_tracker = IssueTrackerDecorator.new(
  40 + IssueTracker.new :type_tracker => tracker, :options => {
  41 + :api_token => "token token token",
  42 + :project_id => "1234"
  43 + })
37 end 44 end
38 45
39 describe "content_for :action_bar" do 46 describe "content_for :action_bar" do
@@ -86,7 +93,7 @@ describe &quot;problems/show.html.haml&quot;, type: &#39;view&#39; do @@ -86,7 +93,7 @@ describe &quot;problems/show.html.haml&quot;, type: &#39;view&#39; do
86 allow(view).to receive(:app).and_return(problem.app) 93 allow(view).to receive(:app).and_return(problem.app)
87 render 94 render
88 95
89 - expect(action_bar).to have_selector("span a.github_create.create-issue", text: 'create issue') 96 + expect(action_bar).to have_selector("span a.create-issue", text: 'create issue')
90 end 97 end
91 98
92 context "without issue tracker associate on app" do 99 context "without issue tracker associate on app" do
@@ -118,12 +125,7 @@ describe &quot;problems/show.html.haml&quot;, type: &#39;view&#39; do @@ -118,12 +125,7 @@ describe &quot;problems/show.html.haml&quot;, type: &#39;view&#39; do
118 125
119 it 'links to the associated tracker' do 126 it 'links to the associated tracker' do
120 render 127 render
121 - expect(view.content_for(:action_bar)).to match(".pivotal_create.create-issue")  
122 - end  
123 -  
124 - it 'does not link to github' do  
125 - render  
126 - expect(view.content_for(:action_bar)).to_not match(".github_create.create-issue") 128 + expect(view.content_for(:action_bar)).to match(".create-issue")
127 end 129 end
128 end 130 end
129 131
@@ -179,4 +181,3 @@ describe &quot;problems/show.html.haml&quot;, type: &#39;view&#39; do @@ -179,4 +181,3 @@ describe &quot;problems/show.html.haml&quot;, type: &#39;view&#39; do
179 end 181 end
180 end 182 end
181 end 183 end
182 -