diff --git a/Gemfile b/Gemfile
index 1dcda45..9fd2cd4 100644
--- a/Gemfile
+++ b/Gemfile
@@ -27,30 +27,13 @@ gem 'rails_autolink'
gem 'hoptoad_notifier', "~> 2.4"
gem 'draper', :require => false
+gem 'errbit_plugin',
+ :git => 'https://github.com/errbit/errbit_plugin.git'
+ # :path => 'vendor/gems/errbit_plugin'
+gem 'errbit_github_plugin',
+ :git => 'https://github.com/errbit/errbit_github_plugin.git'
+ # :path => 'vendor/gems/errbit_github_plugin'
-# Remove / comment out any of the gems below if you want to disable
-# a given issue tracker, notification service, or authentication.
-
-# Issue Trackers
-# ---------------------------------------
-# Lighthouse
-gem 'lighthouse-api'
-# Redmine
-gem 'oruen_redmine_client', :require => 'redmine_client'
-# Pivotal Tracker
-gem 'pivotal-tracker'
-# Fogbugz
-gem 'ruby-fogbugz', :require => 'fogbugz'
-# Github Issues
-gem 'octokit', '~> 1.18'
-# Gitlab
-gem 'gitlab', '~> 3.0.0'
-
-# Bitbucket Issues
-gem 'bitbucket_rest_api', :require => false
-
-# Jira
-gem 'jira-ruby', :require => 'jira'
# Notification services
# ---------------------------------------
@@ -80,7 +63,6 @@ group :development, :test do
gem 'rspec-rails'
gem 'webmock', :require => false
gem 'airbrake', :require => false
- gem 'ruby-debug', :platform => :mri_18
gem 'debugger', :platform => :mri_19
gem 'pry-rails'
# gem 'rpm_contrib'
@@ -117,7 +99,6 @@ group :heroku, :production do
gem 'unicorn', :require => false
end
-
# Gems used only for assets and not required
# in production environments by default.
group :assets do
diff --git a/Gemfile.lock b/Gemfile.lock
index ac35328..d20f390 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,3 +1,15 @@
+PATH
+ remote: vendor/gems/errbit_github_plugin
+ specs:
+ errbit_github_plugin (0.0.1)
+ errbit_plugin
+ octokit
+
+PATH
+ remote: vendor/gems/errbit_plugin
+ specs:
+ errbit_plugin (0.0.1)
+
GEM
remote: https://rubygems.org/
specs:
@@ -44,13 +56,6 @@ GEM
erubis (>= 2.6.6)
binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1)
- bitbucket_rest_api (0.1.4)
- faraday (~> 0.8.1)
- faraday_middleware (~> 0.9.0)
- hashie (~> 2.0.5)
- multi_json (~> 1.3)
- nokogiri (~> 1.5.2)
- simple_oauth
builder (3.0.4)
callsite (0.0.11)
campy (1.0.0)
@@ -96,8 +101,9 @@ GEM
warden (~> 1.2.3)
diff-lcs (1.2.4)
dotenv (0.9.0)
- draper (1.2.1)
+ draper (1.3.0)
actionpack (>= 3.0)
+ activemodel (>= 3.0)
activesupport (>= 3.0)
request_store (~> 1.0.3)
email_spec (1.5.0)
@@ -105,25 +111,19 @@ GEM
mail (~> 2.2)
erubis (2.7.0)
execjs (2.0.2)
- fabrication (2.8.1)
+ fabrication (2.9.0)
faraday (0.8.8)
multipart-post (~> 1.2.0)
- faraday_middleware (0.9.0)
- faraday (>= 0.7.4, < 0.9)
flowdock (0.3.1)
httparty (~> 0.7)
multi_json
foreman (0.63.0)
dotenv (>= 0.7)
thor (>= 0.13.6)
- gitlab (3.0.0)
- httparty
haml (4.0.3)
tilt
- happymapper (0.4.1)
- libxml-ruby (~> 2.0)
hashie (2.0.5)
- highline (1.6.19)
+ highline (1.6.20)
hike (1.2.3)
hipchat (0.12.0)
httparty
@@ -138,11 +138,7 @@ GEM
json (~> 1.8)
multi_xml (>= 0.5.2)
httpauth (0.2.0)
- i18n (0.6.9)
- jira-ruby (0.1.2)
- activesupport
- oauth
- railties
+ i18n (0.6.5)
journey (1.0.4)
jquery-rails (2.1.4)
railties (>= 3.0, < 5.0)
@@ -157,10 +153,6 @@ GEM
launchy (2.3.0)
addressable (~> 2.3)
libv8 (3.16.14.3)
- libxml-ruby (2.7.0)
- lighthouse-api (2.0)
- activeresource (>= 3.0.0)
- activesupport (>= 3.0.0)
linecache (0.46)
rbx-require-relative (> 0.0.4)
mail (2.5.4)
@@ -197,24 +189,15 @@ GEM
net-ssh (2.7.0)
net-ssh-gateway (1.2.0)
net-ssh (>= 2.6.5)
- netrc (0.7.7)
nokogiri (1.5.10)
- nokogiri-happymapper (0.5.8)
- nokogiri (~> 1.5)
- oauth (0.4.7)
oauth2 (0.8.1)
faraday (~> 0.8)
httpauth (~> 0.1)
jwt (~> 0.1.4)
multi_json (~> 1.0)
rack (~> 1.2)
- octokit (1.25.0)
- addressable (~> 2.2)
- faraday (~> 0.8)
- faraday_middleware (~> 0.9)
- hashie (~> 2.0)
- multi_json (~> 1.3)
- netrc (~> 0.7.7)
+ octokit (2.1.2)
+ sawyer (~> 0.5.0)
omniauth (1.1.4)
hashie (>= 1.2, < 3)
rack
@@ -226,18 +209,6 @@ GEM
omniauth (~> 1.0)
origin (1.1.0)
orm_adapter (0.4.0)
- oruen_redmine_client (0.0.1)
- activeresource (>= 2.3.0)
- pivotal-tracker (0.5.12)
- builder
- builder
- crack
- happymapper (>= 0.3.2)
- nokogiri (>= 1.4.3)
- nokogiri (>= 1.5.5)
- nokogiri-happymapper (>= 0.5.4)
- rest-client (~> 1.6.0)
- rest-client (~> 1.6.0)
pjax_rails (0.3.4)
jquery-rails
poltergeist (1.4.1)
@@ -246,7 +217,7 @@ GEM
multi_json (~> 1.0)
websocket-driver (>= 0.2.0)
polyglot (0.3.3)
- premailer (1.7.3)
+ premailer (1.7.9)
css_parser (>= 1.1.9)
htmlentities (>= 4.0.0)
pry (0.9.12.2)
@@ -276,8 +247,7 @@ GEM
activeresource (= 3.2.16)
activesupport (= 3.2.16)
bundler (~> 1.0)
- railties (= 3.2.16)
- rails_autolink (1.1.4)
+ rails_autolink (1.1.5)
rails (> 3.1)
railties (3.2.16)
actionpack (= 3.2.16)
@@ -316,13 +286,13 @@ GEM
ruby-debug-base (~> 0.10.4.0)
ruby-debug-base (0.10.4)
linecache (>= 0.3)
- ruby-fogbugz (0.1.1)
- crack
rushover (0.3.0)
json
rest-client
safe_yaml (0.9.7)
- simple_oauth (0.2.0)
+ sawyer (0.5.0)
+ addressable (~> 2.3.5)
+ faraday (~> 0.8, < 0.10)
simplecov (0.7.1)
multi_json (~> 1.0)
simplecov-html (~> 0.7.1)
@@ -355,15 +325,15 @@ GEM
railties (> 3.2.8, < 4.0.0)
sprockets (>= 2.0.0)
tzinfo (0.3.38)
- uglifier (2.2.1)
+ uglifier (2.3.0)
execjs (>= 0.3.0)
- multi_json (~> 1.0, >= 1.0.2)
+ json (>= 1.8.0)
underscore-rails (1.5.2)
unicorn (4.6.3)
kgio (~> 2.6)
rack
raindrops (~> 0.7)
- useragent (0.8.3)
+ useragent (0.9.0)
warden (1.2.3)
rack (>= 1.0)
webmock (1.15.0)
@@ -385,7 +355,6 @@ DEPENDENCIES
airbrake
better_errors
binding_of_caller
- bitbucket_rest_api
campy
capistrano (~> 2.0)
capybara
@@ -396,30 +365,26 @@ DEPENDENCIES
devise
draper
email_spec
+ errbit_github_plugin!
+ errbit_plugin!
execjs
fabrication
flowdock
foreman
- gitlab (~> 3.0.0)
haml
hipchat
hoi
hoptoad_notifier (~> 2.4)
htmlentities
httparty
- jira-ruby
jquery-rails (~> 2.1.4)
kaminari (>= 0.14.1)
launchy
- lighthouse-api
meta_request
mongoid
mongoid-rspec
mongoid_rails_migrations
- octokit (~> 1.18)
omniauth-github
- oruen_redmine_client
- pivotal-tracker
pjax_rails
poltergeist
pry-rails
@@ -432,7 +397,6 @@ DEPENDENCIES
ri_cal
rspec-rails
ruby-debug
- ruby-fogbugz
rushover
strong_parameters
therubyracer
diff --git a/app/controllers/apps_controller.rb b/app/controllers/apps_controller.rb
index 7cebb18..bafee25 100644
--- a/app/controllers/apps_controller.rb
+++ b/app/controllers/apps_controller.rb
@@ -99,7 +99,7 @@ class AppsController < ApplicationController
def plug_params app
app.watchers.build if app.watchers.none?
- app.issue_tracker = IssueTracker.new unless app.issue_tracker_configured?
+ app.issue_tracker ||= IssueTracker.new
app.notification_service = NotificationService.new unless app.notification_service_configured?
app.copy_attributes_from(params[:copy_attributes_from]) if params[:copy_attributes_from]
end
diff --git a/app/controllers/problems_controller.rb b/app/controllers/problems_controller.rb
index 08e985f..c21c751 100644
--- a/app/controllers/problems_controller.rb
+++ b/app/controllers/problems_controller.rb
@@ -62,8 +62,7 @@ class ProblemsController < ApplicationController
end
def create_issue
- IssueTracker.update_url_options(request)
- issue_creation = IssueCreation.new(problem, current_user, params[:tracker])
+ issue_creation = IssueCreation.new(problem, current_user, params[:tracker], request)
unless issue_creation.execute
flash[:error] = issue_creation.errors.full_messages.join(', ')
diff --git a/app/decorators/issue_tracker_decorator.rb b/app/decorators/issue_tracker_decorator.rb
index 4abea5c..82774ec 100644
--- a/app/decorators/issue_tracker_decorator.rb
+++ b/app/decorators/issue_tracker_decorator.rb
@@ -1,23 +1,26 @@
class IssueTrackerDecorator < Draper::Decorator
+ def initialize(object, key)
+ @object = object
+ @key = key
+ end
+ attr_reader :key
+
delegate_all
def issue_trackers
- @issue_trackers ||= [
- IssueTracker::None,
- IssueTracker.subclasses.select{|klass| klass != IssueTracker::None }
- ].flatten
- @issue_trackers.each do |it|
- yield IssueTrackerDecorator.new(it)
+ @issue_trackers ||= ErrbitPlugin::Register.issue_trackers
+ @issue_trackers.each do |key, it|
+ yield IssueTrackerDecorator.new(it.new(app, {}), key)
end
end
def note
- object::Note.html_safe
+ object.note.html_safe
end
def fields
- object::Fields.each do |field, field_info|
+ object.fields.each do |field, field_info|
yield IssueTrackerFieldDecorator.new(field, field_info)
end
end
@@ -29,7 +32,7 @@ class IssueTrackerDecorator < Draper::Decorator
private
def choosen?(issue_tracker)
- object.to_s == issue_tracker._type ? 'chosen' : ''
+ key == issue_tracker.type_tracker.to_s ? 'chosen' : ''
end
end
diff --git a/app/decorators/issue_tracker_field_decorator.rb b/app/decorators/issue_tracker_field_decorator.rb
index 46f16ec..bd6d508 100644
--- a/app/decorators/issue_tracker_field_decorator.rb
+++ b/app/decorators/issue_tracker_field_decorator.rb
@@ -13,10 +13,10 @@ class IssueTrackerFieldDecorator < Draper::Decorator
end
- def input(form)
- form.send(input_field, object,
+ def input(form, issue_tracker)
+ form.send(input_field, key.to_s,
:placeholder => field_info[:placeholder],
- :value => form.object.send(object))
+ :value => issue_tracker.options[key.to_s])
end
private
diff --git a/app/interactors/issue_creation.rb b/app/interactors/issue_creation.rb
index ef0e70d..880524d 100644
--- a/app/interactors/issue_creation.rb
+++ b/app/interactors/issue_creation.rb
@@ -5,12 +5,24 @@ class IssueCreation
delegate :app, :to => :problem
- def initialize(problem, user, tracker_name)
+ def initialize(problem, user, tracker_name, request)
@problem = problem
@user = user
@tracker_name = tracker_name
+ IssueTracker.update_url_options(request)
end
+ def execute
+ tracker.create_issue(problem, user) if tracker
+ errors.empty?
+ rescue => ex
+ Rails.logger.error "Error during issue creation: " << ex.message
+ errors.add :base, "There was an error during issue creation: #{ex.message}"
+ false
+ end
+
+ private
+
def tracker
return @tracker if @tracker
@@ -21,10 +33,11 @@ class IssueCreation
elsif !user.github_account?
errors.add :base, "You haven't linked your Github account."
else
- @tracker = GithubIssuesTracker.new(
- :app => app,
- :username => user.github_login,
- :oauth_token => user.github_oauth_token
+ @tracker = ErrbitGithubPlugin::IssueTracker.new(
+ app, {
+ :username => user.github_login,
+ :oauth_token => user.github_oauth_token
+ }
)
end
@@ -39,13 +52,4 @@ class IssueCreation
@tracker
end
-
- def execute
- tracker.create_issue problem, user if tracker
- errors.empty?
- rescue => ex
- Rails.logger.error "Error during issue creation: " << ex.message
- errors.add :base, "There was an error during issue creation: #{ex.message}"
- false
- end
end
diff --git a/app/models/app.rb b/app/models/app.rb
index 043fcff..7617470 100644
--- a/app/models/app.rb
+++ b/app/models/app.rb
@@ -25,7 +25,7 @@ class App
embeds_many :watchers
embeds_many :deploys
- embeds_one :issue_tracker
+ embeds_one :issue_tracker, :class_name => 'IssueTracker'
embeds_one :notification_service
has_many :problems, :inverse_of => :app, :dependent => :destroy
@@ -43,7 +43,7 @@ class App
accepts_nested_attributes_for :watchers, :allow_destroy => true,
:reject_if => proc { |attrs| attrs[:user_id].blank? && attrs[:email].blank? }
accepts_nested_attributes_for :issue_tracker, :allow_destroy => true,
- :reject_if => proc { |attrs| !IssueTracker.subclasses.map(&:to_s).include?(attrs[:type].to_s) }
+ :reject_if => proc { |attrs| !ErrbitPlugin::Register.issue_trackers.keys.map(&:to_s).include?(attrs[:type_tracker].to_s) }
accepts_nested_attributes_for :notification_service, :allow_destroy => true,
:reject_if => proc { |attrs| !NotificationService.subclasses.map(&:to_s).include?(attrs[:type].to_s) }
@@ -119,7 +119,7 @@ class App
def issue_tracker_configured?
- !!(issue_tracker.class < IssueTracker && issue_tracker.configured?)
+ !!issue_tracker && !!(issue_tracker.configured?)
end
def notification_service_configured?
@@ -174,6 +174,13 @@ class App
set(:api_key, SecureRandom.hex)
end
+ ##
+ # Check if comments can be allowed on this application
+ #
+ def comments_allowed?
+ !issue_tracker || issue_tracker.comments_allowed?
+ end
+
protected
def store_cached_attributes_on_problems
@@ -199,5 +206,6 @@ class App
github_repo.sub!(/(git@|https?:\/\/)github\.com(\/|:)/, '')
github_repo.sub!(/\.git$/, '')
end
+
end
diff --git a/app/models/issue_tracker.rb b/app/models/issue_tracker.rb
index 5cf412a..02af2f4 100644
--- a/app/models/issue_tracker.rb
+++ b/app/models/issue_tracker.rb
@@ -1,55 +1,15 @@
class IssueTracker
include Mongoid::Document
include Mongoid::Timestamps
- include HashHelper
- include Rails.application.routes.url_helpers
- Note = ''
+ include Rails.application.routes.url_helpers
default_url_options[:host] = ActionMailer::Base.default_url_options[:host]
embedded_in :app, :inverse_of => :issue_tracker
- field :project_id, :type => String
- field :alt_project_id, :type => String # Specify an alternative project id. e.g. for viewing files
- field :api_token, :type => String
- field :account, :type => String
- field :username, :type => String
- field :password, :type => String
- field :ticket_properties, :type => String
- field :subdomain, :type => String
- field :milestone_id, :type => String
-
- # Is there any better way to enhance the props? Putting them into the subclass leads to
- # an error while rendering the form fields -.-
- field :base_url, :type => String
- field :context_path, :type => String
- field :issue_type, :type => String
- field :issue_component, :type => String
- field :issue_priority, :type => String
-
- validate :check_params
-
- # Subclasses are responsible for overwriting this method.
- def check_params; true; end
-
- def issue_title(problem)
- "[#{ problem.environment }][#{ problem.where }] #{problem.message.to_s.truncate(100)}"
- end
-
- # Allows us to set the issue tracker class from a single form.
- def type; self._type; end
- def type=(t); self._type=t; end
-
- def url; nil; end
-
- # Retrieve tracker label from either class or instance.
- def self.label; self::Label; end
- def label; self.class.label; end
-
- def configured?
- project_id.present?
- end
+ field :type_tracker, :type => String
+ field :options, :type => Hash, :default => {}
##
# Update default_url_option with valid data from the request information
@@ -61,4 +21,14 @@ class IssueTracker
IssueTracker.default_url_options[:port] = request.port
IssueTracker.default_url_options[:protocol] = request.scheme
end
+
+ def tracker
+ @tracker ||= ErrbitPlugin::Register.issue_tracker(self.type_tracker).new(app, self.options)
+ rescue NameError
+ ErrbitPlugin::NoneIssueTracker.new(app, {})
+ end
+ delegate :configured?, :to => :tracker
+ delegate :create_issue, :to => :tracker
+ delegate :label, :to => :tracker
+ delegate :comments_allowed?, :to => :tracker
end
diff --git a/app/models/issue_trackers/bitbucket_issues_tracker.rb b/app/models/issue_trackers/bitbucket_issues_tracker.rb
deleted file mode 100644
index c28d3fe..0000000
--- a/app/models/issue_trackers/bitbucket_issues_tracker.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-begin
- require 'bitbucket_rest_api'
-rescue LoadError
-end
-
-if defined? BitBucket
- class IssueTrackers::BitbucketIssuesTracker < IssueTracker
- Label = "bitbucket"
- Note = 'Please configure your Bitbucket repository in the BITBUCKET REPO field above.'
- Fields = [
- [:api_token, {
- :placeholder => "Your username on Bitbucket account",
- :label => "Username"
- }],
- [:project_id, {
- :placeholder => "Password for your Bitbucket account",
- :label => "Password"
- }]
- ]
-
- def check_params
- if Fields.detect {|f| self[f[0]].blank? }
- errors.add :base, 'You must specify your Bitbucket username and password'
- end
- end
-
- def repo_name
- app.bitbucket_repo
- end
-
- def create_issue(problem, reported_by = nil)
- bitbucket = BitBucket.new :basic_auth => "#{api_token}:#{project_id}"
-
- begin
- r_user = repo_name.split('/')[0]
- r_name = repo_name.split('/')[1]
- issue = bitbucket.issues.create r_user, r_name, :title => issue_title(problem), :content => body_template.result(binding), :priority => 'critical'
- problem.update_attributes(
- :issue_link => "https://bitbucket.org/#{repo_name}/issue/#{issue.local_id}/",
- :issue_type => Label
- )
- rescue BitBucket::Error::Unauthorized
- raise IssueTrackers::AuthenticationError, "Could not authenticate with BitBucket. Please check your username and password."
- end
- end
-
- def body_template
- @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/bitbucket_issues_body.txt.erb"))
- end
-
- def url
- "https://www.bitbucket.org/#{repo_name}/issues"
- end
- end
-end
diff --git a/app/models/issue_trackers/fogbugz_tracker.rb b/app/models/issue_trackers/fogbugz_tracker.rb
deleted file mode 100644
index 3ef9d44..0000000
--- a/app/models/issue_trackers/fogbugz_tracker.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-if defined? Fogbugz
- class IssueTrackers::FogbugzTracker < IssueTracker
- Label = "fogbugz"
- Fields = [
- [:project_id, {
- :label => "Area Name"
- }],
- [:account, {
- :label => "FogBugz URL",
- :placeholder => "abc from http://abc.fogbugz.com/"
- }],
- [:username, {
- :placeholder => "Username/Email for your account"
- }],
- [:password, {
- :placeholder => "Password for your account"
- }]
- ]
-
- def check_params
- if Fields.detect {|f| self[f[0]].blank? }
- errors.add :base, 'You must specify your FogBugz Area Name, FogBugz URL, Username, and Password'
- end
- end
-
- def create_issue(problem, reported_by = nil)
- fogbugz = Fogbugz::Interface.new(:email => username, :password => password, :uri => "https://#{account}.fogbugz.com")
- fogbugz.authenticate
-
- issue = {}
- issue['sTitle'] = issue_title problem
- issue['sArea'] = project_id
- issue['sEvent'] = body_template.result(binding)
- issue['sTags'] = ['errbit'].join(',')
- issue['cols'] = ['ixBug'].join(',')
-
- fb_resp = fogbugz.command(:new, issue)
- problem.update_attributes(
- :issue_link => "https://#{account}.fogbugz.com/default.asp?#{fb_resp['case']['ixBug']}",
- :issue_type => Label
- )
-
- end
-
- def body_template
- @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/fogbugz_body.txt.erb"))
- end
-
- def url
- "http://#{account}.fogbugz.com/"
- end
- end
-end
diff --git a/app/models/issue_trackers/github_issues_tracker.rb b/app/models/issue_trackers/github_issues_tracker.rb
deleted file mode 100644
index c9aa0a5..0000000
--- a/app/models/issue_trackers/github_issues_tracker.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-if defined? Octokit
- class IssueTrackers::GithubIssuesTracker < IssueTracker
- Label = "github"
- Note = 'Please configure your github repository in the GITHUB REPO field above.
' <<
- 'Instead of providing your username & password, you can link your Github account ' <<
- 'to your user profile, and allow Errbit to create issues using your OAuth token.'
-
- Fields = [
- [:username, {
- :placeholder => "Your username on GitHub"
- }],
- [:password, {
- :placeholder => "Password for your account"
- }]
- ]
-
- attr_accessor :oauth_token
-
- def project_id
- app.github_repo
- end
-
- def check_params
- if Fields.detect {|f| self[f[0]].blank? }
- errors.add :base, 'You must specify your GitHub username and password'
- end
- end
-
- def create_issue(problem, reported_by = nil)
- # Login using OAuth token, if given.
- if oauth_token
- client = Octokit::Client.new(:login => username, :oauth_token => oauth_token)
- else
- client = Octokit::Client.new(:login => username, :password => password)
- end
-
- begin
- issue = client.create_issue(
- project_id,
- issue_title(problem),
- body_template.result(binding).unpack('C*').pack('U*')
- )
- problem.update_attributes(
- :issue_link => issue.html_url,
- :issue_type => Label
- )
-
- rescue Octokit::Unauthorized
- raise IssueTrackers::AuthenticationError, "Could not authenticate with GitHub. Please check your username and password."
- end
- end
-
- def body_template
- @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/github_issues_body.txt.erb").gsub(/^\s*/, ''))
- end
-
- def url
- "https://github.com/#{project_id}/issues"
- end
- end
-end
diff --git a/app/models/issue_trackers/gitlab_tracker.rb b/app/models/issue_trackers/gitlab_tracker.rb
deleted file mode 100644
index 64d2a7d..0000000
--- a/app/models/issue_trackers/gitlab_tracker.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-if defined? Gitlab
- class IssueTrackers::GitlabTracker < IssueTracker
- Label = "gitlab"
- Fields = [
- [:account, {
- :label => "Gitlab URL",
- :placeholder => "e.g. https://example.net"
- }],
- [:api_token, {
- :placeholder => "API Token for your account"
- }],
- [:project_id, {
- :label => "Ticket Project ID (use Number)",
- :placeholder => "Gitlab Project where issues will be created"
- }],
- [:alt_project_id, {
- :label => "Project Name (namespace/project)",
- :placeholder => "Gitlab Project where issues will be created"
- }]
- ]
-
- def check_params
- if Fields.detect {|f| self[f[0]].blank?}
- errors.add :base, 'You must specify your Gitlab URL, API token, Project ID and Project Name'
- end
- end
-
- def create_issue(problem, reported_by = nil)
- Gitlab.configure do |config|
- config.endpoint = "#{account}/api/v3"
- config.private_token = api_token
- config.user_agent = 'Errbit User Agent'
- end
- title = issue_title problem
- description_summary = summary_template.result(binding)
- description_body = body_template.result(binding)
- ticket = Gitlab.create_issue(project_id, title, { :description => description_summary, :labels => "errbit" } )
- Gitlab.create_issue_note(project_id, ticket.id, description_body)
- end
-
- def summary_template
- @@summary_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/gitlab_summary.txt.erb").gsub(/^\s*/, ''))
- end
-
- def body_template
- @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/gitlab_body.txt.erb").gsub(/^\s*/, ''))
- end
-
- def url
- "#{account}/#{alt_project_id}/issues"
- end
- end
-end
diff --git a/app/models/issue_trackers/jira_tracker.rb b/app/models/issue_trackers/jira_tracker.rb
deleted file mode 100644
index 2c9f68a..0000000
--- a/app/models/issue_trackers/jira_tracker.rb
+++ /dev/null
@@ -1,110 +0,0 @@
-if defined? JIRA
- class IssueTrackers::JiraTracker < IssueTracker
- Label = 'jira'
-
- Fields = [
- [:base_url, {
- :label => 'Jira URL without trailing slash',
- :placeholder => 'https://jira.example.org/'
- }],
- [:context_path, {
- :optional => true,
- :label => 'Context Path (Just "/" if empty otherwise with leading slash)',
- :placeholder => "/jira"
- }],
- [:username, {
- :optional => true,
- :label => 'HTTP Basic Auth User',
- :placeholder => 'johndoe'
- }],
- [:password, {
- :optional => true,
- :label => 'HTTP Basic Auth Password',
- :placeholder => 'p@assW0rd'
- }],
- [:project_id, {
- :label => 'Project Key',
- :placeholder => 'The project Key where the issue will be created'
- }],
- [:account, {
- :optional => true,
- :label => 'Assign to this user. If empty, Jira takes the project default.',
- :placeholder => "username"
- }],
- [:issue_component, {
- :label => 'Issue category',
- :placeholder => 'Website - Other'
- }],
- [:issue_type, {
- :label => 'Issue type',
- :placeholder => 'Bug'
- }],
- [:issue_priority, {
- :label => 'Priority',
- :placeholder => 'Normal'
- }]
- ]
-
- def check_params
- if Fields.detect { |f| self[f[0]].blank? && !f[1][:optional] }
- errors.add :base, 'You must specify all non optional values!'
- end
- end
-
-
- #
- # @param problem Problem
- def create_issue(problem, reported_by = nil)
- options = {
- :username => username,
- :password => password,
- :site => base_url,
- :context_path => context_path,
- :auth_type => :basic,
- :use_ssl => base_url.match(/^https/) ? true : false
- }
- client = JIRA::Client.new(options)
-
- issue = {
- :fields => {
- :project => {
- :key => project_id
- },
- :summary => issue_title(problem),
- :description => body_template.result(binding),
- :issuetype => {
- :name => issue_type
- },
- :priority => {
- :name => issue_priority,
- },
-
- :components => [{:name => issue_component}]
- }
- }
-
- issue[:fields][:assignee] = {:name => account} if account
-
- issue_build = client.Issue.build
- issue_build.save(issue)
- issue_build.fetch
-
- problem.update_attributes(
- :issue_link => "#{base_url}#{context_path}browse/#{issue_build.key}",
- :issue_type => Label
- )
-
- # Maybe in a later version?
- #remote_link = {
- # :url => app_problem_url(problem.app, problem),
- # :name => "Link to Errbit Issue"
- #}
- #remote_link_build = issue_build.remotelink.build
- #remote_link_build.save(remote_link)
- end
-
- def body_template
- @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/jira_body.txt.erb"))
- end
- end
-end
\ No newline at end of file
diff --git a/app/models/issue_trackers/lighthouse_tracker.rb b/app/models/issue_trackers/lighthouse_tracker.rb
deleted file mode 100644
index 21aaaeb..0000000
--- a/app/models/issue_trackers/lighthouse_tracker.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-if defined? Lighthouse
- class IssueTrackers::LighthouseTracker < IssueTracker
- Label = "lighthouseapp"
- Fields = [
- [:account, {
- :label => "Subdomain",
- :placeholder => "subdomain from http://{{subdomain}}.lighthouseapp.com"
- }],
- [:api_token, {
- :label => "API Token",
- :placeholder => "123456789abcdef123456789abcdef"
- }],
- [:project_id, {
- :label => "Project ID",
- :placeholder => "123456"
- }]
- ]
-
- def check_params
- if Fields.detect {|f| self[f[0]].blank? }
- errors.add :base, 'You must specify your Lighthouseapp Subdomain, API token and Project ID'
- end
- end
-
- def create_issue(problem, reported_by = nil)
- Lighthouse.account = account
- Lighthouse.token = api_token
- # updating lighthouse account
- Lighthouse::Ticket.site
- Lighthouse::Ticket.format = :xml
- ticket = Lighthouse::Ticket.new(:project_id => project_id)
- ticket.title = issue_title problem
-
- ticket.body = body_template.result(binding)
-
- ticket.tags << "errbit"
- ticket.save!
- problem.update_attributes(
- :issue_link => "#{Lighthouse::Ticket.site.to_s.sub(/#{Lighthouse::Ticket.site.path}$/, '')}#{Lighthouse::Ticket.element_path(ticket.id, :project_id => project_id)}".sub(/\.xml$/, ''),
- :issue_type => Label
- )
-
- end
-
- def body_template
- @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/lighthouseapp_body.txt.erb").gsub(/^\s*/, ''))
- end
-
- def url
- "http://#{account}.lighthouseapp.com"
- end
- end
-end
\ No newline at end of file
diff --git a/app/models/issue_trackers/mingle_tracker.rb b/app/models/issue_trackers/mingle_tracker.rb
deleted file mode 100644
index 2105148..0000000
--- a/app/models/issue_trackers/mingle_tracker.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-class IssueTrackers::MingleTracker < IssueTracker
- Label = "mingle"
- Note = "Note: CARD PROPERTIES must be comma separated key = value pairs"
-
- Fields = [
- [:account, {
- :label => "Mingle URL",
- :placeholder => "http://mingle.example.com/"
- }],
- [:project_id, {
- :placeholder => "Mingle project"
- }],
- [:ticket_properties, {
- :label => "Card Properties",
- :placeholder => "card_type = Defect, defect_status = Open, priority = Essential"
- }],
- [:username, {
- :label => "Sign-in name",
- :placeholder => "Sign-in name for your account"
- }],
- [:password, {
- :placeholder => "Password for your account"
- }]
- ]
-
- def check_params
- if Fields.detect {|f| self[f[0]].blank? } or !ticket_properties_hash["card_type"]
- errors.add :base, 'You must specify your Mingle URL, Project ID, Card Type (in default card properties), Sign-in name, and Password'
- end
- end
-
- def create_issue(problem, reported_by = nil)
- properties = ticket_properties_hash
- basic_auth = account.gsub(/https?:\/\//, "https://#{username}:#{password}@")
- Mingle.set_site "#{basic_auth}/api/v1/projects/#{project_id}/"
-
- card = Mingle::Card.new
- card.card_type_name = properties.delete("card_type")
- card.name = issue_title(problem)
- card.description = body_template.result(binding)
- properties.each do |property, value|
- card.send("cp_#{property}=", value)
- end
-
- card.save!
- problem.update_attributes(
- :issue_link => URI.parse("#{account}/projects/#{project_id}/cards/#{card.id}").to_s,
- :issue_type => Label
- )
- end
-
- def body_template
- @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/textile_body.txt.erb"))
- end
-
- def ticket_properties_hash
- # Parses 'key=value, key2=value2' from ticket_properties into a ruby hash.
- self.ticket_properties.to_s.split(",").inject({}) do |hash, pair|
- key, value = pair.split("=").map(&:strip)
- hash[key] = value
- hash
- end
- end
-
- def url
- acc_url = account.start_with?('http') ? account : "http://#{account}"
- URI.parse("#{acc_url}/projects/#{project_id}").to_s
- rescue URI::InvalidURIError
- end
-end
-
diff --git a/app/models/issue_trackers/none.rb b/app/models/issue_trackers/none.rb
deleted file mode 100644
index 43e09d9..0000000
--- a/app/models/issue_trackers/none.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class IssueTrackers::None < IssueTracker
- Fields = []
- Note = 'When no issue tracker has been configured, you will be able to leave comments on errors.'
- Label = 'none'
-end
diff --git a/app/models/issue_trackers/pivotal_labs_tracker.rb b/app/models/issue_trackers/pivotal_labs_tracker.rb
deleted file mode 100644
index cc014f9..0000000
--- a/app/models/issue_trackers/pivotal_labs_tracker.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-if defined? PivotalTracker
- class IssueTrackers::PivotalLabsTracker < IssueTracker
- Label = "pivotal"
- Fields = [
- [:api_token, {
- :placeholder => "API Token for your account"
- }],
- [:project_id, {}]
- ]
-
- def check_params
- if Fields.detect {|f| self[f[0]].blank? }
- errors.add :base, 'You must specify your Pivotal Tracker API token and Project ID'
- end
- end
-
- def create_issue(problem, reported_by = nil)
- PivotalTracker::Client.token = api_token
- PivotalTracker::Client.use_ssl = true
- project = PivotalTracker::Project.find project_id.to_i
- story = project.stories.create :name => issue_title(problem),
- :story_type => 'bug', :description => body_template.result(binding),
- :requested_by => reported_by.name
-
- if story.errors.present?
- raise IssueTrackers::IssueTrackerError, story.errors.first
- else
- problem.update_attributes(
- :issue_link => "https://www.pivotaltracker.com/story/show/#{story.id}",
- :issue_type => Label
- )
- end
- end
-
- def body_template
- @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/pivotal_body.txt.erb"))
- end
-
- def url
- "https://www.pivotaltracker.com/"
- end
- end
-end
\ No newline at end of file
diff --git a/app/models/issue_trackers/redmine_tracker.rb b/app/models/issue_trackers/redmine_tracker.rb
deleted file mode 100644
index fc178e4..0000000
--- a/app/models/issue_trackers/redmine_tracker.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-if defined? RedmineClient
- class IssueTrackers::RedmineTracker < IssueTracker
- Label = "redmine"
- Fields = [
- [:account, {
- :label => "Redmine URL",
- :placeholder => "http://www.redmine.org/"
- }],
- [:api_token, {
- :placeholder => "API Token for your account"
- }],
- [:username, {
- :placeholder => "Your username"
- }],
- [:password, {
- :placeholder => "Your password"
- }],
- [:project_id, {
- :label => "Ticket Project",
- :placeholder => "Redmine Project where tickets will be created"
- }],
- [:alt_project_id, {
- :optional => true,
- :label => "App Project",
- :placeholder => "Where app's files & revisions can be viewed. (Leave blank to use the above project by default)"
- }]
- ]
-
- def check_params
- if Fields.detect {|f| self[f[0]].blank? && !f[1][:optional]}
- errors.add :base, 'You must specify your Redmine URL, API token, Username, Password and Project ID'
- end
- end
-
- def create_issue(problem, reported_by = nil)
- token = api_token
- acc = account
- user = username
- passwd = password
- RedmineClient::Base.configure do
- self.token = token
- self.user = user
- self.password = passwd
- self.site = acc
- self.format = :xml
- end
- issue = RedmineClient::Issue.new(:project_id => project_id)
- issue.subject = issue_title problem
- issue.description = body_template.result(binding)
- issue.save!
- problem.update_attributes(
- :issue_link => "#{RedmineClient::Issue.site.to_s.sub(/#{RedmineClient::Issue.site.path}$/, '')}#{RedmineClient::Issue.element_path(issue.id, :project_id => project_id)}".sub(/\.xml\?project_id=#{project_id}$/, "\?project_id=#{project_id}"),
- :issue_type => Label
- )
- end
-
- def url_to_file(file_path, line_number = nil)
- # alt_project_id let's users specify a different project for tickets / app files.
- project = self.alt_project_id.present? ? self.alt_project_id : self.project_id
- url = "#{self.account.gsub(/\/$/, '')}/projects/#{project}/repository/revisions/#{app.repository_branch}/changes/#{file_path.sub(/\[PROJECT_ROOT\]/, '').sub(/^\//,'')}"
- line_number ? url << "#L#{line_number}" : url
- end
-
- def body_template
- @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/redmine_body.txt.erb"))
- end
-
- def url
- acc_url = account.start_with?('http') ? account : "http://#{account}"
- acc_url = acc_url.gsub(/\/$/, '')
- URI.parse("#{acc_url}/projects/#{project_id}").to_s
- rescue URI::InvalidURIError
- end
- end
-end
diff --git a/app/models/issue_trackers/unfuddle_tracker.rb b/app/models/issue_trackers/unfuddle_tracker.rb
deleted file mode 100644
index 243bc6d..0000000
--- a/app/models/issue_trackers/unfuddle_tracker.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-class IssueTrackers::UnfuddleTracker < IssueTracker
- Label = "unfuddle"
- Fields = [
-
- [:account, {
- :placeholder => "Your domain"
- }],
-
-
- [:username, {
- :placeholder => "Your username"
- }],
-
- [:password, {
- :placeholder => "Your password"
- }],
-
- [:project_id, {
- :label => "Ticket Project",
- :placeholder => "Project where tickets will be created"
- }],
-
- [:milestone_id, {
- :optional => true,
- :label => "Ticket Milestone",
- :placeholder => "Milestone where tickets will be created"
- }]
-
-
- ]
-
- def check_params
- if Fields.detect {|f| self[f[0]].blank? && !f[1][:optional]}
- errors.add :base, 'You must specify your Account, Username, Password and Project ID'
- end
- end
-
- def create_issue(problem, reported_by = nil)
-
- Unfuddle.config(account, username, password)
- begin
- issue_options = {:project_id => project_id,
- :summary => issue_title(problem),
- :priority => '5',
- :status => "new",
- :description => body_template.result(binding),
- 'description-format' => 'textile' }
-
- issue_options[:milestone_id] = milestone_id if milestone_id.present?
-
- issue = Unfuddle::Ticket.create(issue_options)
- problem.update_attributes(
- :issue_link => File.join("#{url}/tickets/#{issue.id}"),
- :issue_type => Label
- )
- rescue ActiveResource::UnauthorizedAccess
- raise ActiveResource::UnauthorizedAccess, "Could not authenticate with Unfuddle. Please check your username and password."
- end
-
- end
-
- def body_template
- @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/textile_body.txt.erb"))
- end
-
- def url
- "https://#{account}.unfuddle.com/projects/#{project_id}"
- end
-end
diff --git a/app/models/problem.rb b/app/models/problem.rb
index 548dbbe..bc7a728 100644
--- a/app/models/problem.rb
+++ b/app/models/problem.rb
@@ -68,7 +68,7 @@ class Problem
end
def comments_allowed?
- Errbit::Config.allow_comments_with_issue_tracker || !app.issue_tracker_configured?
+ Errbit::Config.allow_comments_with_issue_tracker || app.comments_allowed?
end
def resolve!
diff --git a/app/views/apps/_issue_tracker_fields.html.haml b/app/views/apps/_issue_tracker_fields.html.haml
index 0322d2c..36e9228 100644
--- a/app/views/apps/_issue_tracker_fields.html.haml
+++ b/app/views/apps/_issue_tracker_fields.html.haml
@@ -1,22 +1,23 @@
%fieldset
%legend= t('.legend')
- = f.fields_for :issue_tracker do |w|
+ = f.fields_for :issue_tracker do |issue_tracker_form|
%div.issue_tracker.nested
%div.choose
- - w.object.issue_trackers do |tracker|
- = w.label :type, :class => "label_radio #{tracker.label}", :value => tracker.name do
- = w.radio_button :type, tracker.name, 'data-section' => tracker.label
+ - issue_tracker_form.object.issue_trackers do |tracker|
+ = issue_tracker_form.label :type_tracker, :class => "label_radio #{tracker.label}", :value => tracker.key do
+ = issue_tracker_form.radio_button :type_tracker, tracker.key, 'data-section' => tracker.label
= tracker.label
- - w.object.issue_trackers do |tracker|
- %div.tracker_params{:class => tracker.params_class(w.object)}
- %p= tracker.note
- - tracker.fields do |field|
- = w.label field.key, field.label
- = field.input(w)
+ - issue_tracker_form.object.issue_trackers do |tracker|
+ %div.tracker_params{:class => tracker.params_class(issue_tracker_form.object)}
+ = issue_tracker_form.fields_for(:options) do |options_form|
+ %p= tracker.note
+ - tracker.fields do |field|
+ = options_form.label field.key, field.label
+ = field.input(options_form, issue_tracker_form.object)
.image_preloader
- - w.object.issue_trackers do |tracker|
+ - issue_tracker_form.object.issue_trackers do |tracker|
= image_tag "#{tracker.label}_inactive.png"
= image_tag "#{tracker.label}_create.png"
diff --git a/db/migrate/20131011155638_extract_issue_tracker.rb b/db/migrate/20131011155638_extract_issue_tracker.rb
new file mode 100644
index 0000000..7b50551
--- /dev/null
+++ b/db/migrate/20131011155638_extract_issue_tracker.rb
@@ -0,0 +1,19 @@
+class ExtractIssueTracker < Mongoid::Migration
+
+ def self.up
+ App.collection.find.each do |app|
+ if app['issue_tracker'] && !app['issue_tracker'].empty?
+ it = app['issue_tracker']
+ it['type_tracker'] = 'IssueTrackers::BitbucketIssuesTracker'
+ it['options'] = app['issue_tracker'].dup
+ it.delete('_type')
+ App.collection.find(
+ :_id => app['_id']
+ ).update(app)
+ end
+ end
+ end
+
+ def self.down
+ end
+end
diff --git a/spec/acceptance/app_regenerate_api_key_spec.rb b/spec/acceptance/app_regenerate_api_key_spec.rb
index f82bcb1..70f5c40 100644
--- a/spec/acceptance/app_regenerate_api_key_spec.rb
+++ b/spec/acceptance/app_regenerate_api_key_spec.rb
@@ -72,17 +72,17 @@ feature "Create an application" do
log_in admin
click_on I18n.t('apps.index.new_app')
fill_in 'app_name', :with => 'My new app'
- find('.label_radio.bitbucket').click
- within ".bitbucket.tracker_params" do
- fill_in 'app_issue_tracker_attributes_api_token', :with => 'token'
- fill_in 'app_issue_tracker_attributes_project_id', :with => 'pass'
+ find('.label_radio.github').click
+ within ".github.tracker_params" do
+ fill_in 'app_issue_tracker_attributes_options_username', :with => 'token'
+ fill_in 'app_issue_tracker_attributes_options_password', :with => 'pass'
end
click_on I18n.t('apps.new.add_app')
expect(page.has_content?(I18n.t('controllers.apps.flash.create.success'))).to eql true
app = App.where(:name => 'My new app').first
- expect(app.issue_tracker).to be_a IssueTracker::BitbucketIssuesTracker
- expect(app.issue_tracker.api_token).to eql 'token'
- expect(app.issue_tracker.project_id).to eql 'pass'
+ expect(app.issue_tracker.type_tracker).to eql 'IssueTrackers::GithubIssuesTracker'
+ expect(app.issue_tracker.options['username']).to eql 'token'
+ expect(app.issue_tracker.options['password']).to eql 'pass'
click_on I18n.t('shared.navigation.apps')
click_on 'My new app'
@@ -91,6 +91,6 @@ feature "Create an application" do
click_on I18n.t('apps.edit.update')
expect(page.has_content?(I18n.t('controllers.apps.flash.update.success'))).to eql true
app = App.where(:name => 'My new app').first
- expect(app.issue_tracker).to be_a IssueTracker::None
+ expect(app.issue_tracker.tracker).to be_a ErrbitPlugin::NoneIssueTracker
end
end
diff --git a/spec/controllers/apps_controller_spec.rb b/spec/controllers/apps_controller_spec.rb
index b001a29..97fc64b 100644
--- a/spec/controllers/apps_controller_spec.rb
+++ b/spec/controllers/apps_controller_spec.rb
@@ -289,7 +289,7 @@ describe AppsController do
context "unknown tracker type" do
before(:each) do
put :update, :id => @app.id, :app => { :issue_tracker_attributes => {
- :type => 'unknown', :project_id => '1234', :api_token => '123123', :account => 'myapp'
+ :type_tracker => 'unknown', :options => {:project_id => '1234', :api_token => '123123', :account => 'myapp'}
} }
@app.reload
end
@@ -299,24 +299,24 @@ describe AppsController do
end
end
- IssueTracker.subclasses.each do |tracker_klass|
- context tracker_klass do
+ ErrbitPlugin::Register.issue_trackers.each do |key, klass|
+ context key do
it "should save tracker params" do
- params = tracker_klass::Fields.inject({}){|hash,f| hash[f[0]] = "test_value"; hash }
- params[:ticket_properties] = "card_type = defect" if tracker_klass == MingleTracker
- params[:type] = tracker_klass.to_s
+ issue_tracker_klass = klass.new(@app, {})
+ params = {
+ :options => issue_tracker_klass.fields.inject({}){|hash,f| hash[f[0]] = "test_value"; hash },
+ :type_tracker => key.dup.to_s
+ }
put :update, :id => @app.id, :app => {:issue_tracker_attributes => params}
@app.reload
tracker = @app.issue_tracker
- expect(tracker).to be_a(tracker_klass)
- tracker_klass::Fields.each do |field, field_info|
+ expect(tracker.tracker).to be_a(ErrbitPlugin::Register.issue_tracker(key))
+ issue_tracker_klass.fields.each do |field, field_info|
case field
- when :ticket_properties
- expect(tracker.send(field.to_sym)).to eq 'card_type = defect'
- else
- expect(tracker.send(field.to_sym)).to eq 'test_value'
+ when :ticket_properties; tracker.send(field.to_sym).should == 'card_type = defect'
+ else tracker.options[field.to_s].should == 'test_value'
end
end
end
@@ -324,8 +324,11 @@ describe AppsController do
it "should show validation notice when sufficient params are not present" do
# Leave out one required param
# TODO. previous test was not relevant because one params can be enough. So put noone
- params = {:type => tracker_klass.to_s }
- put :update, :id => @app.id, :app => {:issue_tracker_attributes => params}
+ put :update, :id => @app.id, :app => {
+ :issue_tracker_attributes => {
+ :type_tracker => key.dup.to_s
+ }
+ }
@app.reload
expect(@app.issue_tracker_configured?).to eq false
diff --git a/spec/controllers/problems_controller_spec.rb b/spec/controllers/problems_controller_spec.rb
index 0885ae4..3cd4e97 100644
--- a/spec/controllers/problems_controller_spec.rb
+++ b/spec/controllers/problems_controller_spec.rb
@@ -8,15 +8,16 @@ describe ProblemsController do
:params => {:app_id => 'dummyid', :id => 'dummyid'}
let(:app) { Fabricate(:app) }
- let(:err) { Fabricate(:err, :problem => Fabricate(:problem, :app => app, :environment => "production")) }
+ let(:err) { Fabricate(:err, :problem => problem) }
+ let(:admin) { Fabricate(:admin) }
+ let(:problem) { Fabricate(:problem, :app => app, :environment => "production") }
describe "GET /problems" do
#render_views
context 'when logged in as an admin' do
before(:each) do
- @user = Fabricate(:admin)
- sign_in @user
+ sign_in admin
@problem = Fabricate(:notice, :err => Fabricate(:err, :problem => Fabricate(:problem, :app => app, :environment => "production"))).problem
end
@@ -31,7 +32,7 @@ describe ProblemsController do
end
it "should be able to override default per_page value" do
- @user.update_attribute :per_page, 10
+ admin.update_attribute :per_page, 10
get :index
expect(controller.problems.to_a.size).to eq 10
end
@@ -98,7 +99,7 @@ describe ProblemsController do
describe "GET /problems - previously all" do
context 'when logged in as an admin' do
it "gets a paginated list of all problems" do
- sign_in Fabricate(:admin)
+ sign_in admin
problems = Kaminari.paginate_array((1..30).to_a)
3.times { problems << Fabricate(:err).problem }
3.times { problems << Fabricate(:err, :problem => Fabricate(:problem, :resolved => true)).problem }
@@ -128,7 +129,7 @@ describe ProblemsController do
context 'when logged in as an admin' do
before do
- sign_in Fabricate(:admin)
+ sign_in admin
end
it "finds the app" do
@@ -192,7 +193,7 @@ describe ProblemsController do
describe "PUT /apps/:app_id/problems/:id/resolve" do
before do
- sign_in Fabricate(:admin)
+ sign_in admin
@problem = Fabricate(:err)
App.stub(:find).with(@problem.app.id.to_s).and_return(@problem.app)
@@ -231,76 +232,50 @@ describe ProblemsController do
end
describe "POST /apps/:app_id/problems/:id/create_issue" do
- #render_views
before(:each) do
- sign_in Fabricate(:admin)
+ sign_in admin
end
context "successful issue creation" do
context "lighthouseapp tracker" do
let(:notice) { Fabricate :notice }
- let(:tracker) { Fabricate :lighthouse_tracker, :app => notice.app }
let(:problem) { notice.problem }
before(:each) do
- number = 5
- @issue_link = "http://#{tracker.account}.lighthouseapp.com/projects/#{tracker.project_id}/tickets/#{number}.xml"
- body = "#{number}"
- stub_request(:post, "http://#{tracker.account}.lighthouseapp.com/projects/#{tracker.project_id}/tickets.xml").
- to_return(:status => 201, :headers => {'Location' => @issue_link}, :body => body )
-
+ controller.stub(:problem).and_return(problem)
+ controller.stub(:current_user).and_return(admin)
+ IssueCreation.should_receive(:new).with(problem, admin, nil, request).and_return(double(:execute => true))
post :create_issue, :app_id => problem.app.id, :id => problem.id
- problem.reload
end
it "should redirect to problem page" do
expect(response).to redirect_to( app_problem_path(problem.app, problem) )
+ expect(flash[:error]).to be_blank
end
end
end
- context "absent issue tracker" do
- let(:problem) { Fabricate :problem }
-
+ context "error during request to a tracker" do
before(:each) do
+ IssueCreation.should_receive(:new).with(problem, admin, nil, request).and_return(
+ double(:execute => false, :errors => double(:full_messages => ['not create']))
+ )
+ controller.stub(:problem).and_return(problem)
post :create_issue, :app_id => problem.app.id, :id => problem.id
end
it "should redirect to problem page" do
expect(response).to redirect_to( app_problem_path(problem.app, problem) )
- end
-
- it "should set flash error message telling issue tracker of the app doesn't exist" do
- expect(flash[:error]).to eq "This app has no issue tracker setup."
+ expect(flash[:error]).to eql 'not create'
end
end
- context "error during request to a tracker" do
- context "lighthouseapp tracker" do
- let(:tracker) { Fabricate :lighthouse_tracker }
- let(:err) { Fabricate(:err, :problem => Fabricate(:problem, :app => tracker.app)) }
-
- before(:each) do
- stub_request(:post, "http://#{tracker.account}.lighthouseapp.com/projects/#{tracker.project_id}/tickets.xml").to_return(:status => 500)
-
- post :create_issue, :app_id => err.app.id, :id => err.problem.id
- end
-
- it "should redirect to problem page" do
- expect(response).to redirect_to( app_problem_path(err.app, err.problem) )
- end
-
- it "should notify of connection error" do
- expect(flash[:error]).to include("There was an error during issue creation:")
- end
- end
- end
end
describe "DELETE /apps/:app_id/problems/:id/unlink_issue" do
before(:each) do
- sign_in Fabricate(:admin)
+ sign_in admin
end
context "problem with issue" do
@@ -336,7 +311,7 @@ describe ProblemsController do
describe "Bulk Actions" do
before(:each) do
- sign_in Fabricate(:admin)
+ sign_in admin
@problem1 = Fabricate(:err, :problem => Fabricate(:problem, :resolved => true)).problem
@problem2 = Fabricate(:err, :problem => Fabricate(:problem, :resolved => false)).problem
end
diff --git a/spec/decorators/issue_tracker_decorator_spec.rb b/spec/decorators/issue_tracker_decorator_spec.rb
index ff3f50a..2567e3e 100644
--- a/spec/decorators/issue_tracker_decorator_spec.rb
+++ b/spec/decorators/issue_tracker_decorator_spec.rb
@@ -2,37 +2,28 @@ require 'spec_helper'
describe IssueTrackerDecorator do
- class Foo
- Note = 'hello '
- Fields = [
- [:foo, :bar]
- ]
- Label = 'foo'
- def self.label; Label; end
- def _type
- 'Foo'
- end
+ let(:none_tracker) do
+ ErrbitPlugin::NoneIssueTracker.new(Object.new, 'none')
end
- class Bar
- Label = 'bar'
- def self.label; Label; end
- def _type
- 'Bar'
- end
+ let(:tracker) do
+ ErrbitPlugin::FakeIssueTracker.new(Object.new, 'fake')
end
- describe "#note" do
+ let(:decorator) do
+ IssueTrackerDecorator.new(tracker, 'fake')
+ end
+ describe "#note" do
it 'return the html_safe of Note' do
- expect(IssueTrackerDecorator.new(Foo).note).to eql 'hello '.html_safe
+ expect(decorator.note).to eql tracker.note
end
end
describe "#issue_trackers" do
it 'return an array of IssueTrackerDecorator' do
- IssueTrackerDecorator.new(Foo).issue_trackers do |it|
+ decorator.issue_trackers do |it|
expect(it).to be_a(IssueTrackerDecorator)
end
end
@@ -40,20 +31,20 @@ describe IssueTrackerDecorator do
describe "#fields" do
it 'return all Fields define decorate' do
- IssueTrackerDecorator.new(Foo).fields do |itf|
+ decorator.fields do |itf|
expect(itf).to be_a(IssueTrackerFieldDecorator)
- expect(itf.object).to eql :foo
- expect(itf.field_info).to eql :bar
+ expect([:foo, :bar]).to be_include(itf.object)
+ expect([{:label => 'foo'}, {:label => 'bar'}]).to be_include(itf.field_info)
end
end
end
describe "#params_class" do
it 'add the label in class' do
- expect(IssueTrackerDecorator.new(Bar).params_class(Foo.new)).to eql 'bar'
+ expect(decorator.params_class(IssueTracker.new(:type_tracker => 'none'))).to eql 'fake'
end
it 'add chosen class if _type is same' do
- expect(IssueTrackerDecorator.new(Foo).params_class(Foo.new)).to eql 'chosen foo'
+ expect(decorator.params_class(IssueTracker.new(:type_tracker => 'fake'))).to eql 'chosen fake'
end
end
end
diff --git a/spec/fabricators/issue_tracker_fabricator.rb b/spec/fabricators/issue_tracker_fabricator.rb
index b6b10d0..ff75151 100644
--- a/spec/fabricators/issue_tracker_fabricator.rb
+++ b/spec/fabricators/issue_tracker_fabricator.rb
@@ -1,41 +1,3 @@
Fabricator :issue_tracker do
app
- api_token { sequence :word }
- project_id { sequence :word }
- account { sequence :word }
- username { sequence :word }
- password { sequence :word }
-end
-
-%w(lighthouse pivotal_labs fogbugz).each do |t|
- Fabricator "#{t}_tracker".to_sym, :from => :issue_tracker, :class_name => "IssueTrackers::#{t.camelcase}Tracker"
-end
-
-Fabricator :redmine_tracker, :from => :issue_tracker, :class_name => "IssueTrackers::RedmineTracker" do
- account 'http://redmine.example.com'
-end
-
-Fabricator :gitlab_tracker, :from => :issue_tracker, :class_name => "IssueTrackers::GitlabTracker" do
- account 'http://gitlab.example.com'
- alt_project_id 'foo'
-end
-
-Fabricator :mingle_tracker, :from => :issue_tracker, :class_name => "IssueTrackers::MingleTracker" do
- account 'https://mingle.example.com'
- ticket_properties 'card_type = Defect, defect_status = open, priority = essential'
-end
-
-Fabricator :github_issues_tracker, :from => :issue_tracker, :class_name => "IssueTrackers::GithubIssuesTracker" do
- project_id 'test_account/test_project'
- username 'test_username'
-end
-
-Fabricator :bitbucket_issues_tracker, :from => :issue_tracker, :class_name => "IssueTrackers::BitbucketIssuesTracker" do
- project_id 'password'
- api_token 'test_username'
-end
-
-Fabricator :unfuddle_issues_tracker, :from => :issue_tracker, :class_name => "IssueTrackers::UnfuddleTracker" do
- account 'test'
- project_id 15
end
diff --git a/spec/interactors/issue_creation_spec.rb b/spec/interactors/issue_creation_spec.rb
index ab74419..852d8d9 100644
--- a/spec/interactors/issue_creation_spec.rb
+++ b/spec/interactors/issue_creation_spec.rb
@@ -1,8 +1,22 @@
require 'spec_helper'
describe IssueCreation do
- subject(:issue_creation) { IssueCreation.new(problem, user, tracker_name) }
+ class FakeIssueTracker
+ def initialize(app, params); end
+ def configured?; true; end
+ def create_issue(problem,user) ; true; end
+ end
+ subject(:issue_creation) do
+ IssueCreation.new(problem, user, tracker_name, request)
+ end
+ let(:request) do
+ double(:request,
+ :host => 'github.com',
+ :port => '80',
+ :scheme => 'http'
+ )
+ end
let(:problem) { notice.problem }
let(:notice) { Fabricate(:notice) }
let(:user) { Fabricate(:admin) }
@@ -15,8 +29,9 @@ describe IssueCreation do
end
it 'creates an issue if issue tracker is configured' do
- tracker = Fabricate(:lighthouse_tracker, :app => notice.app)
- expect(tracker).to receive(:create_issue)
+ a = problem.app
+ a.build_issue_tracker
+ expect(ErrbitPlugin::Register).to receive(:issue_tracker).and_return(FakeIssueTracker)
issue_creation.execute
expect(errors).to be_empty
end
@@ -44,7 +59,9 @@ describe IssueCreation do
user.github_oauth_token = 'oauthtoken'
user.save!
- GithubIssuesTracker.any_instance.should_receive(:create_issue)
+ ErrbitGithubPlugin::IssueTracker.should_receive(:new).and_return(
+ double(:create_issue => true)
+ )
issue_creation.execute
expect(errors).to be_empty
end
diff --git a/spec/interactors/problem_updater_cache_spec.rb b/spec/interactors/problem_updater_cache_spec.rb
index dca8381..679a95b 100644
--- a/spec/interactors/problem_updater_cache_spec.rb
+++ b/spec/interactors/problem_updater_cache_spec.rb
@@ -74,7 +74,7 @@ describe ProblemUpdaterCache do
end
it 'update last_notice_at' do
- expect(problem.last_notice_at.to_i).to be_within(1).of(notice.created_at.to_i)
+ expect(problem.last_notice_at.to_i).to be_within(2).of(notice.created_at.to_i)
end
it 'update stats messages' do
diff --git a/spec/models/app_spec.rb b/spec/models/app_spec.rb
index 0242175..0d57a51 100644
--- a/spec/models/app_spec.rb
+++ b/spec/models/app_spec.rb
@@ -1,6 +1,7 @@
require 'spec_helper'
describe App do
+
context "Attributes" do
it { should have_field(:_id).of_type(String) }
it { should have_field(:name).of_type(String) }
@@ -220,5 +221,26 @@ describe App do
end
end
+ describe "#comments_allowed?" do
+ context "without issue_tracker" do
+ it 'return true' do
+ expect(App.new.comments_allowed?).to be_true
+ end
+ end
+
+ context "with issue_tracker" do
+ let(:issue_tracker) do
+ ist = IssueTracker.new
+ ist.stub(:comments_allowed?).and_return('foo')
+ ist
+ end
+ it 'delegate to issue_tracker' do
+ expect(App.new(
+ :issue_tracker => issue_tracker
+ ).comments_allowed?).to eql 'foo'
+ end
+ end
+ end
+
end
diff --git a/spec/models/issue_tracker_spec.rb b/spec/models/issue_tracker_spec.rb
new file mode 100644
index 0000000..9c4b7a7
--- /dev/null
+++ b/spec/models/issue_tracker_spec.rb
@@ -0,0 +1,20 @@
+require 'spec_helper'
+
+describe IssueTracker do
+ describe "Association" do
+ it { should be_embedded_in(:app) }
+ end
+
+ describe "Attributes" do
+ it { should have_field(:type_tracker).of_type(String) }
+ it { should have_field(:options).of_type(Hash).with_default_value_of({}) }
+ end
+
+ describe "#tracker" do
+ context "with type_tracker class not exist" do
+ it 'return NullIssueTracker' do
+ expect(IssueTracker.new(:type_tracker => 'Foo').tracker).to be_a ErrbitPlugin::NoneIssueTracker
+ end
+ end
+ end
+end
diff --git a/spec/models/issue_trackers/bitbucket_issues_tracker_spec.rb b/spec/models/issue_trackers/bitbucket_issues_tracker_spec.rb
deleted file mode 100644
index 12640f6..0000000
--- a/spec/models/issue_trackers/bitbucket_issues_tracker_spec.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-require 'spec_helper'
-
-describe IssueTrackers::BitbucketIssuesTracker do
- it "should create an issue on BitBucket Issues with problem params, and set issue link for problem" do
- repo = "test_user/test_repo"
- notice = Fabricate :notice
- notice.app.bitbucket_repo = repo
- tracker = Fabricate :bitbucket_issues_tracker, :app => notice.app
- problem = notice.problem
-
- number = 123
- @issue_link = "https://bitbucket.org/#{repo}/issue/#{number}/"
- body = < 200, :headers => {}, :body => body )
-
- problem.app.issue_tracker.create_issue(problem)
- problem.reload
-
- requested = have_requested(:post, "https://#{tracker.api_token}:#{tracker.project_id}@bitbucket.org/api/1.0/repositories/test_user/test_repo/issues/")
- expect(WebMock).to requested.with(:title => /[production][foo#bar] FooError: Too Much Bar/)
- expect(WebMock).to requested.with(:content => /See this exception on Errbit/)
-
- expect(problem.issue_link).to eq @issue_link
- end
-end
diff --git a/spec/models/issue_trackers/fogbugz_tracker_spec.rb b/spec/models/issue_trackers/fogbugz_tracker_spec.rb
deleted file mode 100644
index cee2603..0000000
--- a/spec/models/issue_trackers/fogbugz_tracker_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-require 'spec_helper'
-
-describe IssueTrackers::FogbugzTracker do
- it "should create an issue on Fogbugz with problem params, and set issue link for problem" do
- notice = Fabricate :notice
- tracker = Fabricate :fogbugz_tracker, :app => notice.app
- problem = notice.problem
-
- number = 123
- @issue_link = "https://#{tracker.account}.fogbugz.com/default.asp?#{number}"
- response = "12345123"
- http_mock = double
- expect(http_mock).to receive(:new).and_return(http_mock)
- expect(http_mock).to receive(:request).twice.and_return(response)
- Fogbugz.adapter[:http] = http_mock
-
- problem.app.issue_tracker.create_issue(problem)
- problem.reload
-
- expect(problem.issue_link).to eq @issue_link
- end
-end
-
diff --git a/spec/models/issue_trackers/github_issues_tracker_spec.rb b/spec/models/issue_trackers/github_issues_tracker_spec.rb
deleted file mode 100644
index 5fc0aec..0000000
--- a/spec/models/issue_trackers/github_issues_tracker_spec.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-require 'spec_helper'
-
-describe IssueTrackers::GithubIssuesTracker do
- it "should create an issue on GitHub Issues with problem params, and set issue link for problem" do
- repo = "test_user/test_repo"
- notice = Fabricate :notice
- notice.app.github_repo = repo
- tracker = Fabricate :github_issues_tracker, :app => notice.app
- problem = notice.problem
-
- number = 5
- @issue_link = "https://github.com/#{repo}/issues/#{number}"
- body = < 201,
- :headers => {
- 'Location' => @issue_link,
- 'Content-Type' => 'application/json',
- },
- :body => body )
-
- problem.app.issue_tracker.create_issue(problem)
- problem.reload
-
- requested = have_requested(:post, "https://#{tracker.username}:#{tracker.password}@api.github.com/repos/#{repo}/issues")
- expect(WebMock).to requested.with(:body => /[production][foo#bar] FooError: Too Much Bar/)
- expect(WebMock).to requested.with(:body => /See this exception on Errbit/)
-
- expect(problem.issue_link).to eq @issue_link
- end
-end
-
diff --git a/spec/models/issue_trackers/gitlab_issues_tracker_spec.rb b/spec/models/issue_trackers/gitlab_issues_tracker_spec.rb
deleted file mode 100644
index 45c5b9e..0000000
--- a/spec/models/issue_trackers/gitlab_issues_tracker_spec.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-require 'spec_helper'
-
-describe IssueTrackers::GitlabTracker do
- it "should create an issue on Gitlab with problem params" do
- notice = Fabricate :notice
- tracker = Fabricate :gitlab_tracker, :app => notice.app
- problem = notice.problem
-
- issue_id = 5
- note_id = 10
- issue_body = {:id => issue_id, :title => "[production][foo#bar] FooError: Too Much Bar", :description => "[See this exception on Errbit]"}.to_json
- note_body = {:id => note_id, :body => "Example note body"}.to_json
-
- stub_request(:post, "#{tracker.account}/api/v3/projects/#{tracker.project_id}/issues?private_token=#{tracker.api_token}").
- with(:body => /.+/, :headers => {'Accept'=>'application/json'}).
- to_return(:status => 200, :body => issue_body, :headers => {'Accept'=>'application/json'})
-
- stub_request(:post, "#{tracker.account}/api/v3/projects/#{tracker.project_id}/issues/#{issue_id}/notes?private_token=#{tracker.api_token}").
- with(:body => /.+/, :headers => {'Accept'=>'application/json'}).
- to_return(:status => 200, :body => note_body, :headers => {'Accept'=>'application/json'})
-
- problem.app.issue_tracker.create_issue(problem)
- problem.reload
-
- requested_issue = have_requested(:post, "#{tracker.account}/api/v3/projects/#{tracker.project_id}/issues?private_token=#{tracker.api_token}").with(:body => /.+/, :headers => {'Accept'=>'application/json'})
- requested_note = have_requested(:post, "#{tracker.account}/api/v3/projects/#{tracker.project_id}/issues/#{issue_id}/notes?private_token=#{tracker.api_token}")
- expect(WebMock).to requested_issue.with(:body => /%5Bproduction%5D%5Bfoo%23bar%5D%20FooError%3A%20Too%20Much%20Bar/)
- expect(WebMock).to requested_issue.with(:body => /See%20this%20exception%20on%20Errbit/)
-
- end
-end
-
diff --git a/spec/models/issue_trackers/lighthouse_tracker_spec.rb b/spec/models/issue_trackers/lighthouse_tracker_spec.rb
deleted file mode 100644
index 1bcbb99..0000000
--- a/spec/models/issue_trackers/lighthouse_tracker_spec.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-require 'spec_helper'
-
-describe IssueTrackers::LighthouseTracker do
- it "should create an issue on Lighthouse with problem params, and set issue link for problem" do
- notice = Fabricate :notice
- tracker = Fabricate :lighthouse_tracker, :app => notice.app
- problem = notice.problem
-
- number = 5
- @issue_link = "http://#{tracker.account}.lighthouseapp.com/projects/#{tracker.project_id}/tickets/#{number}.xml"
- body = "#{number}"
- stub_request(:post, "http://#{tracker.account}.lighthouseapp.com/projects/#{tracker.project_id}/tickets.xml").
- to_return(:status => 201, :headers => {'Location' => @issue_link}, :body => body )
-
- problem.app.issue_tracker.create_issue(problem)
- problem.reload
-
- requested = have_requested(:post, "http://#{tracker.account}.lighthouseapp.com/projects/#{tracker.project_id}/tickets.xml")
- expect(WebMock).to requested.with(:headers => {'X-Lighthousetoken' => tracker.api_token})
- expect(WebMock).to requested.with(:body => /errbit<\/tag>/)
- expect(WebMock).to requested.with(:body => /\[#{ problem.environment }\]\[#{problem.where}\] #{problem.message.to_s.truncate(100)}<\/title>/)
- expect(WebMock).to requested.with(:body => /.+<\/body>/m)
-
- expect(problem.issue_link).to eq @issue_link.sub(/\.xml$/, '')
- end
-end
-
diff --git a/spec/models/issue_trackers/mingle_tracker_spec.rb b/spec/models/issue_trackers/mingle_tracker_spec.rb
deleted file mode 100644
index 7011f26..0000000
--- a/spec/models/issue_trackers/mingle_tracker_spec.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-require 'spec_helper'
-
-describe IssueTrackers::MingleTracker do
- it "should create an issue on Mingle with problem params, and set issue link for problem" do
- notice = Fabricate :notice
- tracker = Fabricate :mingle_tracker, :app => notice.app
- problem = notice.problem
-
- number = 5
- @issue_link = "#{tracker.account}/projects/#{tracker.project_id}/cards/#{number}.xml"
- @basic_auth = tracker.account.gsub("://", "://#{tracker.username}:#{tracker.password}@")
- body = "#{number}"
- stub_request(:post, "#{@basic_auth}/api/v1/projects/#{tracker.project_id}/cards.xml").
- to_return(:status => 201, :headers => {'Location' => @issue_link}, :body => body )
-
- problem.app.issue_tracker.create_issue(problem)
- problem.reload
-
- requested = have_requested(:post, "#{@basic_auth}/api/v1/projects/#{tracker.project_id}/cards.xml")
- expect(WebMock).to requested.with(:headers => {'Content-Type' => 'application/xml'})
- expect(WebMock).to requested.with(:body => /FooError: Too Much Bar/)
- expect(WebMock).to requested.with(:body => /See this exception on Errbit/)
- expect(WebMock).to requested.with(:body => /Defect<\/card-type-name>/)
-
- expect(problem.issue_link).to eq @issue_link.sub(/\.xml$/, '')
- end
-end
-
diff --git a/spec/models/issue_trackers/pivotal_labs_tracker_spec.rb b/spec/models/issue_trackers/pivotal_labs_tracker_spec.rb
deleted file mode 100644
index c27927a..0000000
--- a/spec/models/issue_trackers/pivotal_labs_tracker_spec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-require 'spec_helper'
-
-describe IssueTrackers::PivotalLabsTracker do
-
- let(:user) { Fabricate(:user) }
- let(:notice) { Fabricate(:notice) }
- let(:tracker) { Fabricate :pivotal_labs_tracker, :app => notice.app, :project_id => 10 }
- let(:problem) { notice.problem }
- let(:story_id) { 5 }
- let(:issue_link) { "https://www.pivotaltracker.com/story/show/#{story_id}" }
-
- it "creates an issue on Pivotal Tracker with problem params, and set issue link for problem" do
- project_body = "#{tracker.project_id}TestProject"
- stub_request(:get, "https://www.pivotaltracker.com/services/v3/projects/#{tracker.project_id}").
- to_return(:status => 200, :headers => {'Location' => issue_link}, :body => project_body )
- story_body = "Test Story#{story_id}"
- stub_request(:post, "https://www.pivotaltracker.com/services/v3/projects/#{tracker.project_id}/stories").
- to_return(:status => 201, :headers => {'Location' => issue_link}, :body => story_body )
-
- problem.app.issue_tracker.create_issue(problem, user)
- problem.reload
-
- requested = have_requested(:post, "https://www.pivotaltracker.com/services/v3/projects/#{tracker.project_id}/stories")
- expect(WebMock).to requested.with(:headers => {'X-Trackertoken' => tracker.api_token})
- expect(WebMock).to requested.with(:body => /See this exception on Errbit/)
- expect(WebMock).to requested.with(:body => /\[#{ problem.environment }\]\[#{problem.where}\] #{problem.message.to_s.truncate(100)}<\/name>/)
- expect(WebMock).to requested.with(:body => /.+<\/description>/m)
-
- expect(problem.issue_link).to eq issue_link
- end
-
- it "raises IssueTrackers::IssueTrackerError exception when invalid params and does not set issue link for problem" do
- project_body = "#{tracker.project_id}TestProject"
- stub_request(:get, "https://www.pivotaltracker.com/services/v3/projects/#{tracker.project_id}").
- to_return(:status => 200, :body => project_body )
- story_body = "Requested by can't be blankRequested by can't be blank"
- stub_request(:post, "https://www.pivotaltracker.com/services/v3/projects/#{tracker.project_id}/stories").
- to_return(:status => 422, :body => story_body )
-
- expect{
- problem.app.issue_tracker.create_issue(problem, user)
- }.to raise_exception(IssueTrackers::IssueTrackerError, "Requested by can't be blank")
- expect(problem.issue_link).to be_nil
- end
-end
-
diff --git a/spec/models/issue_trackers/redmine_tracker_spec.rb b/spec/models/issue_trackers/redmine_tracker_spec.rb
deleted file mode 100644
index 399df99..0000000
--- a/spec/models/issue_trackers/redmine_tracker_spec.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-require 'spec_helper'
-
-describe IssueTrackers::RedmineTracker do
- it "should create an issue on Redmine with problem params, and set issue link for problem" do
- notice = Fabricate(:notice)
- tracker = Fabricate(:redmine_tracker, :app => notice.app, :project_id => 10)
- problem = notice.problem
- number = 5
- @issue_link = "#{tracker.account}/issues/#{number}.xml?project_id=#{tracker.project_id}"
- body = "my subject#{number}"
-
- # Build base url with account URL, and username/password basic auth
- base_url = tracker.account.gsub 'http://', "http://#{tracker.username}:#{tracker.password}@"
-
- stub_request(:post, "#{base_url}/issues.xml").
- to_return(:status => 201, :headers => {'Location' => @issue_link}, :body => body )
-
- problem.app.issue_tracker.create_issue(problem)
- problem.reload
-
- requested = have_requested(:post, "#{base_url}/issues.xml")
- expect(WebMock).to requested.with(:headers => {'X-Redmine-API-Key' => tracker.api_token})
- expect(WebMock).to requested.with(:body => /#{tracker.project_id}<\/project-id>/)
- expect(WebMock).to requested.with(:body => /\[#{ problem.environment }\]\[#{problem.where}\] #{problem.message.to_s.truncate(100)}<\/subject>/)
- expect(WebMock).to requested.with(:body => /.+<\/description>/m)
-
- expect(problem.issue_link).to eq @issue_link.sub(/\.xml/, '')
- end
-
- it "should generate a url where a file with line number can be viewed" do
- t = Fabricate(:redmine_tracker, :account => 'http://redmine.example.com', :project_id => "errbit")
- expect(t.url_to_file("/example/file")).
- to eq 'http://redmine.example.com/projects/errbit/repository/revisions/master/changes/example/file'
- expect(t.url_to_file("/example/file", 25)).
- to eq 'http://redmine.example.com/projects/errbit/repository/revisions/master/changes/example/file#L25'
- end
-
- it "should use the alt_project_id to generate a file/linenumber url, if given" do
- t = Fabricate(:redmine_tracker, :account => 'http://redmine.example.com',
- :project_id => "errbit",
- :alt_project_id => "actual_project")
- expect(t.url_to_file("/example/file", 25)).
- to eq 'http://redmine.example.com/projects/actual_project/repository/revisions/master/changes/example/file#L25'
- end
-end
diff --git a/spec/models/issue_trackers/unfuddle_issues_tracker_spec.rb b/spec/models/issue_trackers/unfuddle_issues_tracker_spec.rb
deleted file mode 100644
index c518c97..0000000
--- a/spec/models/issue_trackers/unfuddle_issues_tracker_spec.rb
+++ /dev/null
@@ -1,92 +0,0 @@
-require 'spec_helper'
-
-describe IssueTrackers::UnfuddleTracker do
-
- let(:issue_link) { "https://test.unfuddle.com/projects/15/tickets/2436" }
- let(:notice) { Fabricate :notice }
- let(:tracker) { Fabricate :unfuddle_issues_tracker, :app => notice.app }
- let(:problem) { notice.problem }
-
- it "should create an issue on Unfuddle Issues with problem params, and set issue link for problem" do
-project_xml = <
-
- 1
- false
- reporter
- 0
- false
-
-
- 27932
- true
- #{tracker.project_id}
-
- false
-
- test-project
- blue
- false
- text
- Field 1
- false
- text
- Field 2
- false
- text
- Field 3
- test-project
- 2011-04-25T09:21:43Z
- 2013-03-08T08:03:02Z
-
-EOF
-
- ticket_xml =<
-
- 40
-
-
- markdown
-
-
-
-
- 1268.7
- 0.0
- 2436
- 78
- 119
- 3
- 15
- 40
-
-
- markdown
-
- reopened
- TEST-ticket.
-
- 2012-06-27T17:49:06Z
- 2013-03-07T16:04:05Z
-
-EOF
-
- stub_request(:get, "https://#{tracker.username}:#{tracker.password}@test.unfuddle.com/api/v1/projects/#{tracker.project_id}.xml").
- to_return(:status => 200, :body => project_xml, :headers => {})
-
-
- stub_request(:post, "https://#{tracker.username}:#{tracker.password}@test.unfuddle.com/api/v1/projects/#{tracker.project_id}/tickets.xml").
- to_return(:status => 200, :body => ticket_xml, :headers => {})
-
- problem.app.issue_tracker.create_issue(problem)
- problem.reload
-
- requested = have_requested(:post,"https://#{tracker.username}:#{tracker.password}@test.unfuddle.com/api/v1/projects/#{tracker.project_id}/tickets.xml" )
- expect(WebMock).to requested.with(:title => /[production][foo#bar] FooError: Too Much Bar/)
- expect(WebMock).to requested.with(:content => /See this exception on Errbit/)
-
- expect(problem.issue_link).to eq issue_link
- expect(problem.issue_type).to eq IssueTrackers::UnfuddleTracker::Label
- end
-end
diff --git a/spec/models/problem_spec.rb b/spec/models/problem_spec.rb
index afbf12d..412f02a 100644
--- a/spec/models/problem_spec.rb
+++ b/spec/models/problem_spec.rb
@@ -370,6 +370,56 @@ describe Problem do
end
end
+ describe "#issue_type" do
+ context "without issue_type fill in Problem" do
+ let(:problem) do
+ Problem.new(:app => app)
+ end
+
+ let(:app) do
+ App.new(:issue_tracker => issue_tracker)
+ end
+
+ context "without issue_tracker associate to app" do
+ let(:issue_tracker) do
+ nil
+ end
+ it 'return nil' do
+ expect(problem.issue_type).to be_nil
+ end
+ end
+
+ context "with issue_tracker valid associate to app" do
+ let(:issue_tracker) do
+ it = IssueTracker.new
+ it.stub(:tracker).and_return(double(:configured? => true, :label => 'foo'))
+ it
+ end
+
+ it 'return the issue_tracker label' do
+ expect(problem.issue_type).to eql 'foo'
+ end
+ end
+
+ context "with issue_tracker not valid associate to app" do
+ let(:issue_tracker) do
+ it = IssueTracker.new
+ it.stub(:tracker).and_return(double(:configured? => false))
+ it
+ end
+ it 'return nil' do
+ expect(problem.issue_type).to be_nil
+ end
+ end
+ end
+
+ context "with issue_type fill in Problem" do
+ it 'return the value associate' do
+ expect(Problem.new(:issue_type => 'foo').issue_type).to eql 'foo'
+ end
+ end
+ end
+
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 47080d8..ea72e22 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -24,6 +24,7 @@ require 'webmock/rspec'
require 'xmpp4r'
require 'xmpp4r/muc'
require 'mongoid-rspec'
+require 'errbit_plugin/issue_trackers/fake'
# Requires supporting files with custom matchers and macros, etc,
@@ -54,7 +55,7 @@ RSpec.configure do |config|
init_haml_helpers
end
- config.after(:all) do
+ config.before(:all) do
WebMock.disable_net_connect! :allow => /coveralls\.io|127\.0\.0\.1/
end
end
diff --git a/spec/views/problems/show.html.haml_spec.rb b/spec/views/problems/show.html.haml_spec.rb
index 90d87a1..4d70795 100644
--- a/spec/views/problems/show.html.haml_spec.rb
+++ b/spec/views/problems/show.html.haml_spec.rb
@@ -1,6 +1,20 @@
require 'spec_helper'
describe "problems/show.html.haml" do
+ class PivotalLabsTracker
+ def initialize(app, params); end
+ def label; 'pivotal'; end
+ def configured?; true; end
+ def comments_allowed?; false; end
+ end
+
+ class GithubIssuesTracker
+ def initialize(app, params); end
+ def label; 'github'; end
+ def configured?; true; end
+ def comments_allowed?; false; end
+ end
+
let(:problem) { Fabricate(:problem) }
let(:comment) { Fabricate(:comment) }
@@ -16,7 +30,8 @@ describe "problems/show.html.haml" do
end
def with_issue_tracker(tracker, problem)
- problem.app.issue_tracker = tracker.new :api_token => "token token token", :project_id => "1234"
+ problem.app.issue_tracker = IssueTracker.new :type_tracker => tracker, :options => {:api_token => "token token token", :project_id => "1234"}
+ ErrbitPlugin::Register.stub(:issue_tracker).with(tracker).and_return(tracker.constantize)
view.stub(:problem).and_return(problem)
view.stub(:app).and_return(problem.app)
end
@@ -75,7 +90,7 @@ describe "problems/show.html.haml" do
it 'should allow creating issue for github if application has a github tracker' do
problem = Fabricate(:problem_with_comments, :app => Fabricate(:app, :github_repo => "test_user/test_repo"))
- with_issue_tracker(GithubIssuesTracker, problem)
+ with_issue_tracker("GithubIssuesTracker", problem)
view.stub(:problem).and_return(problem)
view.stub(:app).and_return(problem.app)
render
@@ -96,16 +111,15 @@ describe "problems/show.html.haml" do
end
- context "with lighthouse tracker on app" do
- let(:app) { App.new(:new_record => false, :issue_tracker => tracker ) }
- let(:tracker) {
- IssueTrackers::LighthouseTracker.new(:project_id => 'x')
- }
+ context "with tracker associate on app" do
+ before do
+ with_issue_tracker("PivotalLabsTracker", problem)
+ end
context "with problem without issue link" do
- let(:problem){ Problem.new(:new_record => false, :app => app) }
+ before do
+ problem.issue_link = nil
+ end
it 'not see link if no issue tracker' do
- view.stub(:problem).and_return(problem)
- view.stub(:app).and_return(problem.app)
render
expect(view.content_for(:action_bar)).to match(/create issue/)
end
@@ -113,11 +127,11 @@ describe "problems/show.html.haml" do
end
context "with problem with issue link" do
- let(:problem){ Problem.new(:new_record => false, :app => app, :issue_link => 'http://foo') }
+ before do
+ problem.issue_link = 'http://foo'
+ end
it 'not see link if no issue tracker' do
- view.stub(:problem).and_return(problem)
- view.stub(:app).and_return(problem.app)
render
expect(view.content_for(:action_bar)).to_not match(/create issue/)
end
@@ -147,7 +161,7 @@ describe "problems/show.html.haml" do
context "with issue tracker" do
it 'should not display the comments section' do
problem = Fabricate(:problem)
- with_issue_tracker(PivotalLabsTracker, problem)
+ with_issue_tracker("PivotalLabsTracker", problem)
render
expect(view.view_flow.get(:comments)).to be_blank
end
@@ -155,7 +169,7 @@ describe "problems/show.html.haml" do
it 'should display existing comments' do
problem = Fabricate(:problem_with_comments)
problem.reload
- with_issue_tracker(PivotalLabsTracker, problem)
+ with_issue_tracker("PivotalLabsTracker", problem)
render
expect(view.content_for(:comments)).to include('Test comment')
--
libgit2 0.21.2