Commit e5e6ce94b24155d18551e3299e6808eafa50841f
Exists in
master
and in
1 other branch
Merge branch 'fogbugz_integration' of https://github.com/narshlob/errbit into pull-request-43
Conflicts: app/models/app.rb
Showing
26 changed files
with
409 additions
and
92 deletions
Show diff stats
Gemfile
| @@ -2,7 +2,7 @@ source 'http://rubygems.org' | @@ -2,7 +2,7 @@ source 'http://rubygems.org' | ||
| 2 | 2 | ||
| 3 | gem 'rails', '3.0.5' | 3 | gem 'rails', '3.0.5' |
| 4 | gem 'nokogiri' | 4 | gem 'nokogiri' |
| 5 | -gem 'mongoid', '2.0.0.rc.8' | 5 | +gem 'mongoid', '2.0.2' |
| 6 | gem 'haml' | 6 | gem 'haml' |
| 7 | gem 'will_paginate' | 7 | gem 'will_paginate' |
| 8 | gem 'devise', '~> 1.1.8' | 8 | gem 'devise', '~> 1.1.8' |
| @@ -11,14 +11,16 @@ gem 'redmine_client', :git => "git://github.com/oruen/redmine_client.git" | @@ -11,14 +11,16 @@ gem 'redmine_client', :git => "git://github.com/oruen/redmine_client.git" | ||
| 11 | gem 'mongoid_rails_migrations' | 11 | gem 'mongoid_rails_migrations' |
| 12 | gem 'useragent', '~> 0.3.1' | 12 | gem 'useragent', '~> 0.3.1' |
| 13 | gem 'pivotal-tracker' | 13 | gem 'pivotal-tracker' |
| 14 | +gem 'ruby-fogbugz', :require => 'fogbugz' | ||
| 14 | 15 | ||
| 15 | platform :ruby do | 16 | platform :ruby do |
| 16 | - gem 'bson_ext', '~> 1.2' | 17 | + gem 'bson_ext', '~> 1.3.1' |
| 17 | end | 18 | end |
| 18 | 19 | ||
| 19 | group :development, :test do | 20 | group :development, :test do |
| 20 | gem 'rspec-rails', '~> 2.5' | 21 | gem 'rspec-rails', '~> 2.5' |
| 21 | gem 'webmock', :require => false | 22 | gem 'webmock', :require => false |
| 23 | + gem 'ruby-debug19', :require => 'ruby-debug' | ||
| 22 | end | 24 | end |
| 23 | 25 | ||
| 24 | group :test do | 26 | group :test do |
Gemfile.lock
| @@ -36,11 +36,13 @@ GEM | @@ -36,11 +36,13 @@ GEM | ||
| 36 | activesupport (= 3.0.5) | 36 | activesupport (= 3.0.5) |
| 37 | activesupport (3.0.5) | 37 | activesupport (3.0.5) |
| 38 | addressable (2.2.5) | 38 | addressable (2.2.5) |
| 39 | + archive-tar-minitar (0.5.2) | ||
| 39 | arel (2.0.9) | 40 | arel (2.0.9) |
| 40 | bcrypt-ruby (2.1.4) | 41 | bcrypt-ruby (2.1.4) |
| 41 | - bson (1.3.0) | ||
| 42 | - bson_ext (1.3.0) | 42 | + bson (1.3.1) |
| 43 | + bson_ext (1.3.1) | ||
| 43 | builder (2.1.2) | 44 | builder (2.1.2) |
| 45 | + columnize (0.3.4) | ||
| 44 | crack (0.1.8) | 46 | crack (0.1.8) |
| 45 | daemons (1.1.4) | 47 | daemons (1.1.4) |
| 46 | database_cleaner (0.6.7) | 48 | database_cleaner (0.6.7) |
| @@ -65,19 +67,20 @@ GEM | @@ -65,19 +67,20 @@ GEM | ||
| 65 | lighthouse-api (2.0) | 67 | lighthouse-api (2.0) |
| 66 | activeresource (>= 3.0.0) | 68 | activeresource (>= 3.0.0) |
| 67 | activesupport (>= 3.0.0) | 69 | activesupport (>= 3.0.0) |
| 70 | + linecache19 (0.5.12) | ||
| 71 | + ruby_core_source (>= 0.1.4) | ||
| 68 | mail (2.2.17) | 72 | mail (2.2.17) |
| 69 | activesupport (>= 2.3.6) | 73 | activesupport (>= 2.3.6) |
| 70 | i18n (>= 0.4.0) | 74 | i18n (>= 0.4.0) |
| 71 | mime-types (~> 1.16) | 75 | mime-types (~> 1.16) |
| 72 | treetop (~> 1.4.8) | 76 | treetop (~> 1.4.8) |
| 73 | mime-types (1.16) | 77 | mime-types (1.16) |
| 74 | - mongo (1.3.0) | ||
| 75 | - bson (>= 1.3.0) | ||
| 76 | - mongoid (2.0.0.rc.8) | 78 | + mongo (1.3.1) |
| 79 | + bson (>= 1.3.1) | ||
| 80 | + mongoid (2.0.2) | ||
| 77 | activemodel (~> 3.0) | 81 | activemodel (~> 3.0) |
| 78 | - mongo (~> 1.2) | 82 | + mongo (~> 1.3) |
| 79 | tzinfo (~> 0.3.22) | 83 | tzinfo (~> 0.3.22) |
| 80 | - will_paginate (~> 3.0.pre) | ||
| 81 | mongoid_rails_migrations (0.0.10) | 84 | mongoid_rails_migrations (0.0.10) |
| 82 | activesupport (~> 3.0.0) | 85 | activesupport (~> 3.0.0) |
| 83 | bundler (>= 0.9.19) | 86 | bundler (>= 0.9.19) |
| @@ -124,6 +127,19 @@ GEM | @@ -124,6 +127,19 @@ GEM | ||
| 124 | activesupport (~> 3.0) | 127 | activesupport (~> 3.0) |
| 125 | railties (~> 3.0) | 128 | railties (~> 3.0) |
| 126 | rspec (~> 2.5.0) | 129 | rspec (~> 2.5.0) |
| 130 | + ruby-debug-base19 (0.11.25) | ||
| 131 | + columnize (>= 0.3.1) | ||
| 132 | + linecache19 (>= 0.5.11) | ||
| 133 | + ruby_core_source (>= 0.1.4) | ||
| 134 | + ruby-debug19 (0.11.6) | ||
| 135 | + columnize (>= 0.3.1) | ||
| 136 | + linecache19 (>= 0.5.11) | ||
| 137 | + ruby-debug-base19 (>= 0.11.19) | ||
| 138 | + ruby-fogbugz (0.0.4) | ||
| 139 | + crack | ||
| 140 | + typhoeus | ||
| 141 | + ruby_core_source (0.1.5) | ||
| 142 | + archive-tar-minitar (>= 0.5.2) | ||
| 127 | thin (1.2.11) | 143 | thin (1.2.11) |
| 128 | daemons (>= 1.0.9) | 144 | daemons (>= 1.0.9) |
| 129 | eventmachine (>= 0.12.6) | 145 | eventmachine (>= 0.12.6) |
| @@ -131,6 +147,9 @@ GEM | @@ -131,6 +147,9 @@ GEM | ||
| 131 | thor (0.14.6) | 147 | thor (0.14.6) |
| 132 | treetop (1.4.9) | 148 | treetop (1.4.9) |
| 133 | polyglot (>= 0.3.1) | 149 | polyglot (>= 0.3.1) |
| 150 | + typhoeus (0.2.4) | ||
| 151 | + mime-types | ||
| 152 | + mime-types | ||
| 134 | tzinfo (0.3.26) | 153 | tzinfo (0.3.26) |
| 135 | useragent (0.3.1) | 154 | useragent (0.3.1) |
| 136 | warden (1.0.3) | 155 | warden (1.0.3) |
| @@ -144,14 +163,14 @@ PLATFORMS | @@ -144,14 +163,14 @@ PLATFORMS | ||
| 144 | ruby | 163 | ruby |
| 145 | 164 | ||
| 146 | DEPENDENCIES | 165 | DEPENDENCIES |
| 147 | - bson_ext (~> 1.2) | 166 | + bson_ext (~> 1.3.1) |
| 148 | database_cleaner (~> 0.6.0) | 167 | database_cleaner (~> 0.6.0) |
| 149 | devise (~> 1.1.8) | 168 | devise (~> 1.1.8) |
| 150 | email_spec | 169 | email_spec |
| 151 | factory_girl_rails | 170 | factory_girl_rails |
| 152 | haml | 171 | haml |
| 153 | lighthouse-api | 172 | lighthouse-api |
| 154 | - mongoid (= 2.0.0.rc.8) | 173 | + mongoid (= 2.0.2) |
| 155 | mongoid_rails_migrations | 174 | mongoid_rails_migrations |
| 156 | nokogiri | 175 | nokogiri |
| 157 | pivotal-tracker | 176 | pivotal-tracker |
| @@ -159,6 +178,8 @@ DEPENDENCIES | @@ -159,6 +178,8 @@ DEPENDENCIES | ||
| 159 | redmine_client! | 178 | redmine_client! |
| 160 | rspec (~> 2.5) | 179 | rspec (~> 2.5) |
| 161 | rspec-rails (~> 2.5) | 180 | rspec-rails (~> 2.5) |
| 181 | + ruby-debug19 | ||
| 182 | + ruby-fogbugz | ||
| 162 | thin | 183 | thin |
| 163 | useragent (~> 0.3.1) | 184 | useragent (~> 0.3.1) |
| 164 | webmock | 185 | webmock |
app/controllers/apps_controller.rb
| @@ -8,9 +8,17 @@ class AppsController < ApplicationController | @@ -8,9 +8,17 @@ class AppsController < ApplicationController | ||
| 8 | end | 8 | end |
| 9 | 9 | ||
| 10 | def show | 10 | def show |
| 11 | + where_clause = {} | ||
| 11 | respond_to do |format| | 12 | respond_to do |format| |
| 12 | format.html do | 13 | format.html do |
| 13 | - @errs = @app.errs.ordered.paginate(:page => params[:page], :per_page => current_user.per_page) | 14 | + where_clause[:environment] = params[:environment] if(params[:environment].present?) |
| 15 | + if(params[:all_errs]) | ||
| 16 | + @errs = @app.errs.where(where_clause).ordered.paginate(:page => params[:page], :per_page => current_user.per_page) | ||
| 17 | + @all_errs = true | ||
| 18 | + else | ||
| 19 | + @errs = @app.errs.unresolved.where(where_clause).ordered.paginate(:page => params[:page], :per_page => current_user.per_page) | ||
| 20 | + @all_errs = false | ||
| 21 | + end | ||
| 14 | @deploys = @app.deploys.order_by(:created_at.desc).limit(5) | 22 | @deploys = @app.deploys.order_by(:created_at.desc).limit(5) |
| 15 | end | 23 | end |
| 16 | format.atom do | 24 | format.atom do |
app/controllers/errs_controller.rb
| @@ -5,12 +5,14 @@ class ErrsController < ApplicationController | @@ -5,12 +5,14 @@ class ErrsController < ApplicationController | ||
| 5 | 5 | ||
| 6 | def index | 6 | def index |
| 7 | app_scope = current_user.admin? ? App.all : current_user.apps | 7 | app_scope = current_user.admin? ? App.all : current_user.apps |
| 8 | + where_clause = {} | ||
| 9 | + where_clause[:environment] = params[:environment] if(params[:environment].present?) | ||
| 8 | respond_to do |format| | 10 | respond_to do |format| |
| 9 | format.html do | 11 | format.html do |
| 10 | - @errs = Err.for_apps(app_scope).unresolved.ordered.paginate(:page => params[:page], :per_page => current_user.per_page) | 12 | + @errs = Err.for_apps(app_scope).where(where_clause).unresolved.ordered.paginate(:page => params[:page], :per_page => current_user.per_page) |
| 11 | end | 13 | end |
| 12 | format.atom do | 14 | format.atom do |
| 13 | - @errs = Err.for_apps(app_scope).unresolved.ordered | 15 | + @errs = Err.for_apps(app_scope).where(where_clause).unresolved.ordered |
| 14 | end | 16 | end |
| 15 | end | 17 | end |
| 16 | end | 18 | end |
| @@ -42,7 +44,7 @@ class ErrsController < ApplicationController | @@ -42,7 +44,7 @@ class ErrsController < ApplicationController | ||
| 42 | redirect_to app_err_path(@app, @err) | 44 | redirect_to app_err_path(@app, @err) |
| 43 | end | 45 | end |
| 44 | 46 | ||
| 45 | - def clear_issue | 47 | + def unlink_issue |
| 46 | @err.update_attribute :issue_link, nil | 48 | @err.update_attribute :issue_link, nil |
| 47 | redirect_to app_err_path(@app, @err) | 49 | redirect_to app_err_path(@app, @err) |
| 48 | end | 50 | end |
app/controllers/users_controller.rb
| @@ -6,7 +6,7 @@ class UsersController < ApplicationController | @@ -6,7 +6,7 @@ class UsersController < ApplicationController | ||
| 6 | before_filter :require_user_edit_priviledges, :only => [:edit, :update] | 6 | before_filter :require_user_edit_priviledges, :only => [:edit, :update] |
| 7 | 7 | ||
| 8 | def index | 8 | def index |
| 9 | - @users = User.paginate(:page => params[:page], :per_page => current_user.per_page) | 9 | + @users = User.all.paginate(:page => params[:page], :per_page => current_user.per_page) |
| 10 | end | 10 | end |
| 11 | 11 | ||
| 12 | def show | 12 | def show |
app/helpers/application_helper.rb
| @@ -42,4 +42,8 @@ module ApplicationHelper | @@ -42,4 +42,8 @@ module ApplicationHelper | ||
| 42 | def pivotal_tracker? object | 42 | def pivotal_tracker? object |
| 43 | object.issue_tracker_type == "pivotal" | 43 | object.issue_tracker_type == "pivotal" |
| 44 | end | 44 | end |
| 45 | + | ||
| 46 | + def fogbugz_tracker? object | ||
| 47 | + object.issue_tracker_type == 'fogbugz' | ||
| 48 | + end | ||
| 45 | end | 49 | end |
app/models/app.rb
| @@ -21,11 +21,11 @@ class App | @@ -21,11 +21,11 @@ class App | ||
| 21 | embeds_many :watchers | 21 | embeds_many :watchers |
| 22 | embeds_many :deploys | 22 | embeds_many :deploys |
| 23 | embeds_one :issue_tracker | 23 | embeds_one :issue_tracker |
| 24 | - references_many :errs, :dependent => :destroy | 24 | + has_many :errs, :inverse_of => :app, :dependent => :destroy |
| 25 | 25 | ||
| 26 | before_validation :generate_api_key, :on => :create | 26 | before_validation :generate_api_key, :on => :create |
| 27 | before_save :normalize_github_url | 27 | before_save :normalize_github_url |
| 28 | - | 28 | + |
| 29 | validates_presence_of :name, :api_key | 29 | validates_presence_of :name, :api_key |
| 30 | validates_uniqueness_of :name, :allow_blank => true | 30 | validates_uniqueness_of :name, :allow_blank => true |
| 31 | validates_uniqueness_of :api_key, :allow_blank => true | 31 | validates_uniqueness_of :api_key, :allow_blank => true |
| @@ -35,7 +35,7 @@ class App | @@ -35,7 +35,7 @@ class App | ||
| 35 | accepts_nested_attributes_for :watchers, :allow_destroy => true, | 35 | accepts_nested_attributes_for :watchers, :allow_destroy => true, |
| 36 | :reject_if => proc { |attrs| attrs[:user_id].blank? && attrs[:email].blank? } | 36 | :reject_if => proc { |attrs| attrs[:user_id].blank? && attrs[:email].blank? } |
| 37 | accepts_nested_attributes_for :issue_tracker, :allow_destroy => true, | 37 | accepts_nested_attributes_for :issue_tracker, :allow_destroy => true, |
| 38 | - :reject_if => proc { |attrs| !%w(lighthouseapp redmine pivotal).include?(attrs[:issue_tracker_type]) } | 38 | + :reject_if => proc { |attrs| !%w(lighthouseapp redmine pivotal fogbugz).include?(attrs[:issue_tracker_type]) } |
| 39 | 39 | ||
| 40 | # Mongoid Bug: find(id) on association proxies returns an Enumerator | 40 | # Mongoid Bug: find(id) on association proxies returns an Enumerator |
| 41 | def self.find_by_id!(app_id) | 41 | def self.find_by_id!(app_id) |
| @@ -60,18 +60,19 @@ class App | @@ -60,18 +60,19 @@ class App | ||
| 60 | !(self[:notify_on_deploys] == false) | 60 | !(self[:notify_on_deploys] == false) |
| 61 | end | 61 | end |
| 62 | alias :notify_on_deploys? :notify_on_deploys | 62 | alias :notify_on_deploys? :notify_on_deploys |
| 63 | - | 63 | + |
| 64 | def github_url? | 64 | def github_url? |
| 65 | self.github_url.present? | 65 | self.github_url.present? |
| 66 | end | 66 | end |
| 67 | - | 67 | + |
| 68 | def github_url_to_file(file) | 68 | def github_url_to_file(file) |
| 69 | "#{self.github_url}/blob/master#{file}" | 69 | "#{self.github_url}/blob/master#{file}" |
| 70 | end | 70 | end |
| 71 | - | 71 | + |
| 72 | def issue_tracker_configured? | 72 | def issue_tracker_configured? |
| 73 | issue_tracker && !issue_tracker.project_id.blank? | 73 | issue_tracker && !issue_tracker.project_id.blank? |
| 74 | end | 74 | end |
| 75 | + | ||
| 75 | protected | 76 | protected |
| 76 | 77 | ||
| 77 | def generate_api_key | 78 | def generate_api_key |
| @@ -86,12 +87,12 @@ class App | @@ -86,12 +87,12 @@ class App | ||
| 86 | end if issue_tracker.errors | 87 | end if issue_tracker.errors |
| 87 | end | 88 | end |
| 88 | end | 89 | end |
| 89 | - | 90 | + |
| 90 | def normalize_github_url | 91 | def normalize_github_url |
| 91 | return if self.github_url.blank? | 92 | return if self.github_url.blank? |
| 92 | self.github_url.gsub!(%r{^http://|git@}, 'https://') | 93 | self.github_url.gsub!(%r{^http://|git@}, 'https://') |
| 93 | self.github_url.gsub!(/github\.com:/, 'github.com/') | 94 | self.github_url.gsub!(/github\.com:/, 'github.com/') |
| 94 | self.github_url.gsub!(/\.git$/, '') | 95 | self.github_url.gsub!(/\.git$/, '') |
| 95 | end | 96 | end |
| 96 | - | 97 | + |
| 97 | end | 98 | end |
app/models/err.rb
| @@ -16,8 +16,8 @@ class Err | @@ -16,8 +16,8 @@ class Err | ||
| 16 | index :last_notice_at | 16 | index :last_notice_at |
| 17 | index :app_id | 17 | index :app_id |
| 18 | 18 | ||
| 19 | - referenced_in :app | ||
| 20 | - references_many :notices | 19 | + belongs_to :app |
| 20 | + has_many :notices | ||
| 21 | 21 | ||
| 22 | validates_presence_of :klass, :environment | 22 | validates_presence_of :klass, :environment |
| 23 | 23 |
app/models/issue_tracker.rb
| @@ -12,6 +12,8 @@ class IssueTracker | @@ -12,6 +12,8 @@ class IssueTracker | ||
| 12 | field :account, :type => String | 12 | field :account, :type => String |
| 13 | field :api_token, :type => String | 13 | field :api_token, :type => String |
| 14 | field :project_id, :type => String | 14 | field :project_id, :type => String |
| 15 | + field :username, :type => String | ||
| 16 | + field :password, :type => String | ||
| 15 | field :issue_tracker_type, :type => String, :default => 'lighthouseapp' | 17 | field :issue_tracker_type, :type => String, :default => 'lighthouseapp' |
| 16 | 18 | ||
| 17 | def create_issue err | 19 | def create_issue err |
| @@ -22,6 +24,8 @@ class IssueTracker | @@ -22,6 +24,8 @@ class IssueTracker | ||
| 22 | create_redmine_issue err | 24 | create_redmine_issue err |
| 23 | when 'pivotal' | 25 | when 'pivotal' |
| 24 | create_pivotal_issue err | 26 | create_pivotal_issue err |
| 27 | + when 'fogbugz' | ||
| 28 | + create_fogbugz_issue err | ||
| 25 | end | 29 | end |
| 26 | end | 30 | end |
| 27 | 31 | ||
| @@ -65,22 +69,44 @@ class IssueTracker | @@ -65,22 +69,44 @@ class IssueTracker | ||
| 65 | err.update_attribute :issue_link, "#{Lighthouse::Ticket.site.to_s.sub(/#{Lighthouse::Ticket.site.path}$/, '')}#{Lighthouse::Ticket.element_path(ticket.id, :project_id => project_id)}".sub(/\.xml$/, '') | 69 | err.update_attribute :issue_link, "#{Lighthouse::Ticket.site.to_s.sub(/#{Lighthouse::Ticket.site.path}$/, '')}#{Lighthouse::Ticket.element_path(ticket.id, :project_id => project_id)}".sub(/\.xml$/, '') |
| 66 | end | 70 | end |
| 67 | 71 | ||
| 72 | + def create_fogbugz_issue err | ||
| 73 | + fogbugz = Fogbugz::Interface.new(:email => username, :password => password, :uri => "https://#{account}.fogbugz.com") | ||
| 74 | + fogbugz.authenticate | ||
| 75 | + | ||
| 76 | + issue = {} | ||
| 77 | + issue['sTitle'] = issue_title err | ||
| 78 | + issue['sArea'] = project_id | ||
| 79 | + issue['sEvent'] = self.class.fogbugz_body_template.result(binding) | ||
| 80 | + issue['sTags'] = ['errbit'].join(',') | ||
| 81 | + issue['cols'] = ['ixBug'].join(',') | ||
| 82 | + | ||
| 83 | + fb_resp = fogbugz.command(:new, issue) | ||
| 84 | + err.update_attribute :issue_link, "https://#{account}.fogbugz.com/default.asp?#{fb_resp['case']['ixBug']}" | ||
| 85 | + end | ||
| 86 | + | ||
| 68 | def issue_title err | 87 | def issue_title err |
| 69 | "[#{ err.environment }][#{ err.where }] #{err.message.to_s.truncate(100)}" | 88 | "[#{ err.environment }][#{ err.where }] #{err.message.to_s.truncate(100)}" |
| 70 | end | 89 | end |
| 71 | 90 | ||
| 72 | def check_params | 91 | def check_params |
| 73 | - blank_flag_fields = %w(api_token project_id) | ||
| 74 | - blank_flag_fields << 'account' if %w(lighthouseapp redmine).include? issue_tracker_type | 92 | + blank_flag_fields = %w(project_id) |
| 93 | + if(%w(fogbugz).include?(issue_tracker_type)) | ||
| 94 | + blank_flag_fields += %w(username password) | ||
| 95 | + else | ||
| 96 | + blank_flag_fields << 'api_token' | ||
| 97 | + end | ||
| 98 | + blank_flag_fields << 'account' if(%w(fogbugz lighthouseapp redmine).include?(issue_tracker_type)) | ||
| 75 | blank_flags = blank_flag_fields.map {|m| self[m].blank? } | 99 | blank_flags = blank_flag_fields.map {|m| self[m].blank? } |
| 76 | if blank_flags.any? && !blank_flags.all? | 100 | if blank_flags.any? && !blank_flags.all? |
| 77 | message = case issue_tracker_type | 101 | message = case issue_tracker_type |
| 78 | when 'lighthouseapp' | 102 | when 'lighthouseapp' |
| 79 | - "You must specify your Lighthouseapp account, api token and project id" | 103 | + 'You must specify your Lighthouseapp account, api token and project id' |
| 80 | when 'redmine' | 104 | when 'redmine' |
| 81 | - "You must specify your Redmine url, api token and project id" | 105 | + 'You must specify your Redmine url, api token and project id' |
| 82 | when 'pivotal' | 106 | when 'pivotal' |
| 83 | - "You must specify your Pivotal Tracker api token and project id" | 107 | + 'You must specify your Pivotal Tracker api token and project id' |
| 108 | + when 'fogbugz' | ||
| 109 | + 'You must specify your FogBugz Area Name, Username, and Password' | ||
| 84 | end | 110 | end |
| 85 | errors.add(:base, message) | 111 | errors.add(:base, message) |
| 86 | end | 112 | end |
| @@ -98,5 +124,9 @@ class IssueTracker | @@ -98,5 +124,9 @@ class IssueTracker | ||
| 98 | def pivotal_body_template | 124 | def pivotal_body_template |
| 99 | @@pivotal_body_template ||= ERB.new(File.read(Rails.root + "app/views/errs/pivotal_body.txt.erb")) | 125 | @@pivotal_body_template ||= ERB.new(File.read(Rails.root + "app/views/errs/pivotal_body.txt.erb")) |
| 100 | end | 126 | end |
| 127 | + | ||
| 128 | + def fogbugz_body_template | ||
| 129 | + @@fogbugz_body_template ||= ERB.new(File.read(Rails.root + "app/views/errs/fogbugz_body.txt.erb")) | ||
| 130 | + end | ||
| 101 | end | 131 | end |
| 102 | end | 132 | end |
app/models/notice.rb
| @@ -11,7 +11,7 @@ class Notice | @@ -11,7 +11,7 @@ class Notice | ||
| 11 | field :request, :type => Hash | 11 | field :request, :type => Hash |
| 12 | field :notifier, :type => Hash | 12 | field :notifier, :type => Hash |
| 13 | 13 | ||
| 14 | - referenced_in :err | 14 | + belongs_to :err |
| 15 | index :err_id | 15 | index :err_id |
| 16 | 16 | ||
| 17 | after_create :cache_last_notice_at | 17 | after_create :cache_last_notice_at |
app/views/apps/_fields.html.haml
| @@ -45,13 +45,15 @@ | @@ -45,13 +45,15 @@ | ||
| 45 | = label_tag :issue_tracker_type_redmine, 'Redmine', :for => label_for_attr(w, 'issue_tracker_type_redmine') | 45 | = label_tag :issue_tracker_type_redmine, 'Redmine', :for => label_for_attr(w, 'issue_tracker_type_redmine') |
| 46 | = w.radio_button :issue_tracker_type, :pivotal | 46 | = w.radio_button :issue_tracker_type, :pivotal |
| 47 | = label_tag :issue_tracker_type_pivotal, 'Pivotal Tracker', :for => label_for_attr(w, 'issue_tracker_type_pivotal') | 47 | = label_tag :issue_tracker_type_pivotal, 'Pivotal Tracker', :for => label_for_attr(w, 'issue_tracker_type_pivotal') |
| 48 | + = w.radio_button :issue_tracker_type, :fogbugz | ||
| 49 | + = label_tag :issue_tracker_type_fogbugz, 'FogBugz', :for => label_for_attr(w, 'issue_tracker_type_fogbugz') | ||
| 48 | %div.tracker_params.lighthouseapp{:class => lighthouse_tracker?(w.object) ? 'chosen' : nil} | 50 | %div.tracker_params.lighthouseapp{:class => lighthouse_tracker?(w.object) ? 'chosen' : nil} |
| 49 | = w.label :account, "Account" | 51 | = w.label :account, "Account" |
| 50 | = w.text_field :account, :placeholder => "abc from abc.lighthouseapp.com" | 52 | = w.text_field :account, :placeholder => "abc from abc.lighthouseapp.com" |
| 51 | = w.label :api_token, "API token" | 53 | = w.label :api_token, "API token" |
| 52 | = w.text_field :api_token, :placeholder => "API Token for your account" | 54 | = w.text_field :api_token, :placeholder => "API Token for your account" |
| 53 | = w.label :project_id, "Project ID" | 55 | = w.label :project_id, "Project ID" |
| 54 | - = w.text_field :project_id, :placeholder => "123 from abc from abc.lighthouseapp.com/projects/123" | 56 | + = w.text_field :project_id, :placeholder => "123 from abc.lighthouseapp.com/projects/123" |
| 55 | %div.tracker_params.redmine{:class => redmine_tracker?(w.object) ? 'chosen' : nil} | 57 | %div.tracker_params.redmine{:class => redmine_tracker?(w.object) ? 'chosen' : nil} |
| 56 | = w.label :account, "Redmine URL" | 58 | = w.label :account, "Redmine URL" |
| 57 | = w.text_field :account, :placeholder => "like http://www.redmine.org/" | 59 | = w.text_field :account, :placeholder => "like http://www.redmine.org/" |
| @@ -64,3 +66,12 @@ | @@ -64,3 +66,12 @@ | ||
| 64 | = w.text_field :project_id | 66 | = w.text_field :project_id |
| 65 | = w.label :api_token, "API token" | 67 | = w.label :api_token, "API token" |
| 66 | = w.text_field :api_token, :placeholder => "API Token for your account" | 68 | = w.text_field :api_token, :placeholder => "API Token for your account" |
| 69 | + %div.tracker_params.fogbugz{:class => fogbugz_tracker?(w.object) ? 'chosen' : nil} | ||
| 70 | + = w.label :project_id, "Area Name" | ||
| 71 | + = w.text_field :project_id | ||
| 72 | + = w.label :account, "FogBugz URL" | ||
| 73 | + = w.text_field :account, :placeholder => "abc from http://abc.fogbugz.com/" | ||
| 74 | + = w.label :username, 'account username' | ||
| 75 | + = w.text_field :username, :placeholder => 'Username/Email for your account' | ||
| 76 | + = w.label :password, 'account password' | ||
| 77 | + = w.password_field :password, :placeholder => 'Password for your account' |
app/views/apps/show.html.haml
| 1 | - content_for :title, @app.name | 1 | - content_for :title, @app.name |
| 2 | - content_for :head do | 2 | - content_for :head do |
| 3 | = auto_discovery_link_tag :atom, app_url(@app, User.token_authentication_key => current_user.authentication_token, :format => "atom"), :title => "Errbit notices for #{@app.name} at #{root_url}" | 3 | = auto_discovery_link_tag :atom, app_url(@app, User.token_authentication_key => current_user.authentication_token, :format => "atom"), :title => "Errbit notices for #{@app.name} at #{root_url}" |
| 4 | + = javascript_include_tag 'apps.show' | ||
| 4 | - content_for :meta do | 5 | - content_for :meta do |
| 5 | %strong Errs Caught: | 6 | %strong Errs Caught: |
| 6 | = @app.errs.count | 7 | = @app.errs.count |
| @@ -12,53 +13,66 @@ | @@ -12,53 +13,66 @@ | ||
| 12 | - if current_user.admin? | 13 | - if current_user.admin? |
| 13 | = link_to 'edit', edit_app_path(@app), :class => 'button' | 14 | = link_to 'edit', edit_app_path(@app), :class => 'button' |
| 14 | = link_to 'destroy', app_path(@app), :method => :delete, :confirm => 'Seriously?', :class => 'button' | 15 | = link_to 'destroy', app_path(@app), :method => :delete, :confirm => 'Seriously?', :class => 'button' |
| 16 | + - if @all_errs == true | ||
| 17 | + = link_to 'unresolved errs', app_path(@app), :class => 'button' | ||
| 18 | + - else | ||
| 19 | + = link_to 'all errs', app_path(@app, {all_errs: true}), :class => 'button' | ||
| 15 | 20 | ||
| 16 | -%h3 Watchers | ||
| 17 | -%table.watchers | ||
| 18 | - %thead | ||
| 19 | - %tr | ||
| 20 | - %th User or Email | ||
| 21 | - %tbody | ||
| 22 | - - @app.watchers.each do |watcher| | ||
| 23 | - %tr | ||
| 24 | - %td= watcher.label | ||
| 25 | - - if @app.watchers.none? | ||
| 26 | - %tr | ||
| 27 | - %td | ||
| 28 | - %em Sadly, no one is watching this app | ||
| 29 | - | ||
| 30 | -- if @app.github_url? | ||
| 31 | - %h3 Repository | ||
| 32 | - %table.repository | 21 | +%h3{:id => 'watchers_toggle'} |
| 22 | + Watchers | ||
| 23 | + %span{:class => 'click_span'} (show/hide) | ||
| 24 | +#watchers_div | ||
| 25 | + %table.watchers | ||
| 33 | %thead | 26 | %thead |
| 34 | %tr | 27 | %tr |
| 35 | - %th GitHub | 28 | + %th User or Email |
| 36 | %tbody | 29 | %tbody |
| 37 | - %tr | ||
| 38 | - %td= link_to(@app.github_url, @app.github_url, :target => '_blank') | 30 | + - @app.watchers.each do |watcher| |
| 31 | + %tr | ||
| 32 | + %td= watcher.label | ||
| 33 | + - if @app.watchers.none? | ||
| 34 | + %tr | ||
| 35 | + %td | ||
| 36 | + %em Sadly, no one is watching this app | ||
| 39 | 37 | ||
| 40 | -%h3 Latest Deploys | ||
| 41 | -- if @deploys.any? | ||
| 42 | - %table.deploys | ||
| 43 | - %thead | ||
| 44 | - %tr | ||
| 45 | - %th When | ||
| 46 | - %th Who | ||
| 47 | - %th Message | ||
| 48 | - %th Repository | ||
| 49 | - %th Revision | 38 | +- if @app.github_url? |
| 39 | + %h3{:id => 'repository_toggle'} | ||
| 40 | + Repository | ||
| 41 | + %span{:class => 'click_span'} (show/hide) | ||
| 42 | + #repository_div | ||
| 43 | + %table.repository | ||
| 44 | + %thead | ||
| 45 | + %tr | ||
| 46 | + %th GitHub | ||
| 47 | + %tbody | ||
| 48 | + %tr | ||
| 49 | + %td= link_to(@app.github_url, @app.github_url, :target => '_blank') | ||
| 50 | 50 | ||
| 51 | - %tbody | ||
| 52 | - - @deploys.each do |deploy| | 51 | +%h3{:id => 'deploys_toggle'} |
| 52 | + Latest Deploys | ||
| 53 | + %span{:class => 'click_span'} (show/hide) | ||
| 54 | +#deploys_div | ||
| 55 | + - if @deploys.any? | ||
| 56 | + %table.deploys | ||
| 57 | + %thead | ||
| 53 | %tr | 58 | %tr |
| 54 | - %td.when #{deploy.created_at.to_s(:micro)} | ||
| 55 | - %td.who #{deploy.username} | ||
| 56 | - %td.message #{deploy.message} | ||
| 57 | - %td.repository #{deploy.repository} | ||
| 58 | - %td.revision #{deploy.revision} | ||
| 59 | - = link_to "All Deploys (#{@app.deploys.count})", app_deploys_path(@app), :class => 'button' | ||
| 60 | -- else | ||
| 61 | - %h3 No deploys | 59 | + %th When |
| 60 | + %th Who | ||
| 61 | + %th Message | ||
| 62 | + %th Repository | ||
| 63 | + %th Revision | ||
| 64 | + | ||
| 65 | + %tbody | ||
| 66 | + - @deploys.each do |deploy| | ||
| 67 | + %tr | ||
| 68 | + %td.when #{deploy.created_at.to_s(:micro)} | ||
| 69 | + %td.who #{deploy.username} | ||
| 70 | + %td.message #{deploy.message} | ||
| 71 | + %td.repository #{deploy.repository} | ||
| 72 | + %td.revision #{deploy.revision} | ||
| 73 | + = link_to "All Deploys (#{@app.deploys.count})", app_deploys_path(@app), :class => 'button' | ||
| 74 | + - else | ||
| 75 | + %h3 No deploys | ||
| 62 | 76 | ||
| 63 | - if @app.errs.count > 0 | 77 | - if @app.errs.count > 0 |
| 64 | %h3.clear Errs | 78 | %h3.clear Errs |
app/views/errs/_table.html.haml
| @@ -12,7 +12,10 @@ | @@ -12,7 +12,10 @@ | ||
| 12 | %tr{:class => err.resolved? ? 'resolved' : 'unresolved'} | 12 | %tr{:class => err.resolved? ? 'resolved' : 'unresolved'} |
| 13 | %td.app | 13 | %td.app |
| 14 | = link_to err.app.name, app_path(err.app) | 14 | = link_to err.app.name, app_path(err.app) |
| 15 | - %span.environment= err.environment | 15 | + - if(current_page?(:controller => 'errs')) |
| 16 | + %span.environment= link_to err.environment, errs_path(environment: err.environment) | ||
| 17 | + - else | ||
| 18 | + %span.environment= link_to err.environment, app_path(environment: err.environment) | ||
| 16 | %td.message | 19 | %td.message |
| 17 | = link_to err.message, app_err_path(err.app, err) | 20 | = link_to err.message, app_err_path(err.app, err) |
| 18 | %em= err.where | 21 | %em= err.where |
| @@ -0,0 +1,31 @@ | @@ -0,0 +1,31 @@ | ||
| 1 | +"See this exception on Errbit": <%= app_err_url(err.app, err) %> | ||
| 2 | +<% if notice = err.notices.first %> | ||
| 3 | + <%= notice.message %> | ||
| 4 | + | ||
| 5 | + Summary | ||
| 6 | + - Where | ||
| 7 | + <%= notice.err.where %> | ||
| 8 | + | ||
| 9 | + - Occured | ||
| 10 | + <%= notice.created_at.to_s(:micro) %> | ||
| 11 | + | ||
| 12 | + - Similar | ||
| 13 | + <%= (notice.err.notices_count - 1).to_s %> | ||
| 14 | + | ||
| 15 | + Params | ||
| 16 | + <%= pretty_hash(notice.params) %> | ||
| 17 | + | ||
| 18 | + Session | ||
| 19 | + <%= pretty_hash(notice.session) %> | ||
| 20 | + | ||
| 21 | + Backtrace | ||
| 22 | + <% for line in notice.backtrace %> | ||
| 23 | + <%= line['number'] %>: <%= line['file'].sub(/^\[PROJECT_ROOT\]/, '') %> | ||
| 24 | + <% end %> | ||
| 25 | + | ||
| 26 | + Environment | ||
| 27 | + <% for key, val in notice.env_vars %> | ||
| 28 | + <%= key %>: <%= val %> | ||
| 29 | + <% end %> | ||
| 30 | +<% end %> | ||
| 31 | + |
app/views/errs/show.html.haml
| @@ -5,6 +5,7 @@ | @@ -5,6 +5,7 @@ | ||
| 5 | = @app.name | 5 | = @app.name |
| 6 | %strong Where: | 6 | %strong Where: |
| 7 | = @err.where | 7 | = @err.where |
| 8 | + %br | ||
| 8 | %strong Environment: | 9 | %strong Environment: |
| 9 | = @err.environment | 10 | = @err.environment |
| 10 | %strong Last Notice: | 11 | %strong Last Notice: |
| @@ -15,7 +16,7 @@ | @@ -15,7 +16,7 @@ | ||
| 15 | %span= link_to 'create issue', create_issue_app_err_path(@app, @err), :method => :post, :class => "#{@app.issue_tracker.issue_tracker_type}_create create-issue" | 16 | %span= link_to 'create issue', create_issue_app_err_path(@app, @err), :method => :post, :class => "#{@app.issue_tracker.issue_tracker_type}_create create-issue" |
| 16 | - else | 17 | - else |
| 17 | %span= link_to 'go to issue', @err.issue_link, :class => "#{@app.issue_tracker.issue_tracker_type}_goto goto-issue" | 18 | %span= link_to 'go to issue', @err.issue_link, :class => "#{@app.issue_tracker.issue_tracker_type}_goto goto-issue" |
| 18 | - = link_to 'clear issue', clear_issue_app_err_path(@app, @err), :method => :delete, :confirm => "Clear err issues?", :class => "clear-issue" | 19 | + = link_to 'unlink issue', unlink_issue_app_err_path(@app, @err), :method => :delete, :confirm => "Unlink err issues?", :class => "unlink-issue" |
| 19 | - if @err.unresolved? | 20 | - if @err.unresolved? |
| 20 | %span= link_to 'resolve', resolve_app_err_path(@app, @err), :method => :put, :confirm => err_confirm, :class => 'resolve' | 21 | %span= link_to 'resolve', resolve_app_err_path(@app, @err), :method => :put, :confirm => err_confirm, :class => 'resolve' |
| 21 | 22 |
app/views/notices/_params.html.haml
app/views/notices/_session.html.haml
| @@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
| 1 | +require Rails.root.join('lib/overrides/mongoid/relations/builder.rb') |
config/routes.rb
| 1 | Errbit::Application.routes.draw do | 1 | Errbit::Application.routes.draw do |
| 2 | - | 2 | + |
| 3 | devise_for :users | 3 | devise_for :users |
| 4 | 4 | ||
| 5 | # Hoptoad Notifier Routes | 5 | # Hoptoad Notifier Routes |
| 6 | match '/notifier_api/v2/notices' => 'notices#create' | 6 | match '/notifier_api/v2/notices' => 'notices#create' |
| 7 | match '/deploys.txt' => 'deploys#create' | 7 | match '/deploys.txt' => 'deploys#create' |
| 8 | - | 8 | + |
| 9 | resources :notices, :only => [:show] | 9 | resources :notices, :only => [:show] |
| 10 | resources :deploys, :only => [:show] | 10 | resources :deploys, :only => [:show] |
| 11 | resources :users | 11 | resources :users |
| @@ -14,22 +14,22 @@ Errbit::Application.routes.draw do | @@ -14,22 +14,22 @@ Errbit::Application.routes.draw do | ||
| 14 | get :all | 14 | get :all |
| 15 | end | 15 | end |
| 16 | end | 16 | end |
| 17 | - | 17 | + |
| 18 | resources :apps do | 18 | resources :apps do |
| 19 | resources :errs do | 19 | resources :errs do |
| 20 | resources :notices | 20 | resources :notices |
| 21 | member do | 21 | member do |
| 22 | put :resolve | 22 | put :resolve |
| 23 | post :create_issue | 23 | post :create_issue |
| 24 | - delete :clear_issue | 24 | + delete :unlink_issue |
| 25 | end | 25 | end |
| 26 | end | 26 | end |
| 27 | 27 | ||
| 28 | resources :deploys, :only => [:index] | 28 | resources :deploys, :only => [:index] |
| 29 | end | 29 | end |
| 30 | - | 30 | + |
| 31 | devise_for :users | 31 | devise_for :users |
| 32 | - | 32 | + |
| 33 | root :to => 'apps#index' | 33 | root :to => 'apps#index' |
| 34 | - | 34 | + |
| 35 | end | 35 | end |
| @@ -0,0 +1,15 @@ | @@ -0,0 +1,15 @@ | ||
| 1 | +# ruby-fogbugz requires crack. crack adds the attributes method to strings, | ||
| 2 | +# thus breaking the relations of Mongoid. | ||
| 3 | +# Tests reside in a separate fork of mongoid: | ||
| 4 | +# https://github.com/mhs/mongoid/commit/e5b2b1346c73a2935c606317314b6ded07260429#diff-1 | ||
| 5 | +module Mongoid | ||
| 6 | + module Relations | ||
| 7 | + class Builder | ||
| 8 | + def query? | ||
| 9 | + return true unless object.respond_to?(:to_a) | ||
| 10 | + obj = object.to_a.first | ||
| 11 | + !obj.is_a?(Mongoid::Document) && !obj.nil? | ||
| 12 | + end | ||
| 13 | + end | ||
| 14 | + end | ||
| 15 | +end |
4.78 KB
4.78 KB
| @@ -0,0 +1,11 @@ | @@ -0,0 +1,11 @@ | ||
| 1 | +$(function() { | ||
| 2 | + $("#watchers_toggle").click(function() { | ||
| 3 | + $("#watchers_div").slideToggle("slow"); | ||
| 4 | + }); | ||
| 5 | + $("#repository_toggle").click(function() { | ||
| 6 | + $("#repository_div").slideToggle("slow"); | ||
| 7 | + }); | ||
| 8 | + $("#deploys_toggle").click(function() { | ||
| 9 | + $("#deploys_div").slideToggle("slow"); | ||
| 10 | + }); | ||
| 11 | +}); |
public/stylesheets/application.css
| @@ -376,13 +376,18 @@ table .main { width: 100%; } | @@ -376,13 +376,18 @@ table .main { width: 100%; } | ||
| 376 | table.single_user { | 376 | table.single_user { |
| 377 | border-top: none; | 377 | border-top: none; |
| 378 | } | 378 | } |
| 379 | + | ||
| 380 | +.raw_data { | ||
| 381 | + width: 100%; | ||
| 382 | + color: #f0f0f0; | ||
| 383 | + background-color: #222; | ||
| 384 | + overflow: auto; | ||
| 385 | +} | ||
| 386 | + | ||
| 379 | /* Code */ | 387 | /* Code */ |
| 380 | pre { | 388 | pre { |
| 381 | padding: 0.8em; | 389 | padding: 0.8em; |
| 382 | margin-bottom: 1em; | 390 | margin-bottom: 1em; |
| 383 | - color: #f0f0f0; | ||
| 384 | - background-color: #222; | ||
| 385 | - border: 1px solid #444; | ||
| 386 | font-family: monaco, courier, monospace; | 391 | font-family: monaco, courier, monospace; |
| 387 | font-size: 1.1em; | 392 | font-size: 1.1em; |
| 388 | } | 393 | } |
| @@ -502,7 +507,7 @@ a.button.active { | @@ -502,7 +507,7 @@ a.button.active { | ||
| 502 | } | 507 | } |
| 503 | 508 | ||
| 504 | /* Watchers and Issue Tracker Forms */ | 509 | /* Watchers and Issue Tracker Forms */ |
| 505 | -div.nested.watcher .user, div.nested.watcher .email, div.issue_tracker.nested .lighthouseapp, div.issue_tracker.nested .redmine, div.issue_tracker.nested .pivotal { | 510 | +div.nested.watcher .user, div.nested.watcher .email, div.issue_tracker.nested .lighthouseapp, div.issue_tracker.nested .redmine, div.issue_tracker.nested .pivotal, div.issue_tracker.nested .fogbugz { |
| 506 | display: none; | 511 | display: none; |
| 507 | } | 512 | } |
| 508 | div.nested.watcher .choosen, div.nested.issue_tracker .chosen { | 513 | div.nested.watcher .choosen, div.nested.issue_tracker .chosen { |
| @@ -612,6 +617,10 @@ table.tally th.value { | @@ -612,6 +617,10 @@ table.tally th.value { | ||
| 612 | background: transparent url(/images/pivotal_create.png) 6px 5px no-repeat; | 617 | background: transparent url(/images/pivotal_create.png) 6px 5px no-repeat; |
| 613 | } | 618 | } |
| 614 | 619 | ||
| 620 | +#action-bar a.fogbugz_create { | ||
| 621 | + background: transparent url(/images/fogbugz_create.png) 6px 5px no-repeat; | ||
| 622 | +} | ||
| 623 | + | ||
| 615 | #action-bar a.lighthouseapp_goto { | 624 | #action-bar a.lighthouseapp_goto { |
| 616 | background: transparent url(/images/lighthouseapp_goto.png) 6px 5px no-repeat; | 625 | background: transparent url(/images/lighthouseapp_goto.png) 6px 5px no-repeat; |
| 617 | } | 626 | } |
| @@ -624,6 +633,10 @@ table.tally th.value { | @@ -624,6 +633,10 @@ table.tally th.value { | ||
| 624 | background: transparent url(/images/pivotal_goto.png) 6px 5px no-repeat; | 633 | background: transparent url(/images/pivotal_goto.png) 6px 5px no-repeat; |
| 625 | } | 634 | } |
| 626 | 635 | ||
| 636 | +#action-bar a.fogbugz_goto { | ||
| 637 | + background: transparent url(/images/fogbugz_goto.png) 6px 5px no-repeat; | ||
| 638 | +} | ||
| 639 | + | ||
| 627 | /* Notices Pagination */ | 640 | /* Notices Pagination */ |
| 628 | .notice-pagination { | 641 | .notice-pagination { |
| 629 | float: left; | 642 | float: left; |
| @@ -636,9 +649,11 @@ table.tally th.value { | @@ -636,9 +649,11 @@ table.tally th.value { | ||
| 636 | margin-bottom: 1em; | 649 | margin-bottom: 1em; |
| 637 | overflow: auto; | 650 | overflow: auto; |
| 638 | } | 651 | } |
| 652 | + | ||
| 639 | .window table { | 653 | .window table { |
| 640 | margin: 0; | 654 | margin: 0; |
| 641 | } | 655 | } |
| 656 | + | ||
| 642 | table.backtrace td { | 657 | table.backtrace td { |
| 643 | width: 100%; | 658 | width: 100%; |
| 644 | padding: 0; | 659 | padding: 0; |
| @@ -660,3 +675,11 @@ table.backtrace li.in-app { | @@ -660,3 +675,11 @@ table.backtrace li.in-app { | ||
| 660 | color: #2adb2e; | 675 | color: #2adb2e; |
| 661 | background-color: #2f2f2f; | 676 | background-color: #2f2f2f; |
| 662 | } | 677 | } |
| 678 | + | ||
| 679 | +span.click_span { | ||
| 680 | + font-size: 0.7em; | ||
| 681 | +} | ||
| 682 | + | ||
| 683 | +#deploys_div, #repository_div, #watchers_div { | ||
| 684 | + display: none; | ||
| 685 | +} |
spec/controllers/apps_controller_spec.rb
| @@ -74,6 +74,71 @@ describe AppsController do | @@ -74,6 +74,71 @@ describe AppsController do | ||
| 74 | assigns(:errs).size.should == 10 | 74 | assigns(:errs).size.should == 10 |
| 75 | end | 75 | end |
| 76 | end | 76 | end |
| 77 | + | ||
| 78 | + context 'with resolved errors' do | ||
| 79 | + before(:each) do | ||
| 80 | + resolved_err = Factory.create(:err, app: @app, resolved: true) | ||
| 81 | + Factory.create(:notice, err: resolved_err) | ||
| 82 | + end | ||
| 83 | + | ||
| 84 | + context 'and no params' do | ||
| 85 | + it 'shows only unresolved errs' do | ||
| 86 | + get :show, id: @app.id | ||
| 87 | + assigns(:errs).size.should == 1 | ||
| 88 | + end | ||
| 89 | + end | ||
| 90 | + | ||
| 91 | + context 'and all_errs=true params' do | ||
| 92 | + it 'shows all errors' do | ||
| 93 | + get :show, id: @app.id, all_errs: true | ||
| 94 | + assigns(:errs).size.should == 2 | ||
| 95 | + end | ||
| 96 | + end | ||
| 97 | + end | ||
| 98 | + | ||
| 99 | + context 'with environment filters' do | ||
| 100 | + before(:each) do | ||
| 101 | + environments = ['production', 'test', 'development', 'staging'] | ||
| 102 | + 20.times do |i| | ||
| 103 | + Factory.create(:err, app: @app, environment: environments[i % environments.length]) | ||
| 104 | + end | ||
| 105 | + end | ||
| 106 | + | ||
| 107 | + context 'no params' do | ||
| 108 | + it 'shows errs for all environments' do | ||
| 109 | + get :show, id: @app.id | ||
| 110 | + assigns(:errs).size.should == 21 | ||
| 111 | + end | ||
| 112 | + end | ||
| 113 | + | ||
| 114 | + context 'environment production' do | ||
| 115 | + it 'shows errs for just production' do | ||
| 116 | + get :show, id: @app.id, environment: :production | ||
| 117 | + assigns(:errs).size.should == 6 | ||
| 118 | + end | ||
| 119 | + end | ||
| 120 | + | ||
| 121 | + context 'environment staging' do | ||
| 122 | + it 'shows errs for just staging' do | ||
| 123 | + get :show, id: @app.id, environment: :staging | ||
| 124 | + assigns(:errs).size.should == 5 | ||
| 125 | + end | ||
| 126 | + end | ||
| 127 | + | ||
| 128 | + context 'environment development' do | ||
| 129 | + it 'shows errs for just development' do | ||
| 130 | + get :show, id: @app.id, environment: :development | ||
| 131 | + assigns(:errs).size.should == 5 | ||
| 132 | + end | ||
| 133 | + end | ||
| 134 | + | ||
| 135 | + context 'environment test' do | ||
| 136 | + it 'shows errs for just test' do | ||
| 137 | + get :show, id: @app.id, environment: :test | ||
| 138 | + assigns(:errs).size.should == 5 | ||
| 139 | + end | ||
| 140 | + end | ||
| 141 | + end | ||
| 77 | end | 142 | end |
| 78 | 143 | ||
| 79 | context 'logged in as a user' do | 144 | context 'logged in as a user' do |
| @@ -261,6 +326,34 @@ describe AppsController do | @@ -261,6 +326,34 @@ describe AppsController do | ||
| 261 | response.body.should match(/You must specify your Pivotal Tracker api token and project id/) | 326 | response.body.should match(/You must specify your Pivotal Tracker api token and project id/) |
| 262 | end | 327 | end |
| 263 | end | 328 | end |
| 329 | + | ||
| 330 | + context "fogbugz" do | ||
| 331 | + context 'with correct params' do | ||
| 332 | + before do | ||
| 333 | + put :update, :id => @app.id, :app => { :issue_tracker_attributes => { | ||
| 334 | + :issue_tracker_type => 'fogbugz', :account => 'abc', :project_id => 'Service - Peon', :username => '1234', :password => '123123' } } | ||
| 335 | + @app.reload | ||
| 336 | + end | ||
| 337 | + | ||
| 338 | + subject {@app.issue_tracker} | ||
| 339 | + its(:issue_tracker_type) {should == 'fogbugz'} | ||
| 340 | + its(:account) {should == 'abc'} | ||
| 341 | + its(:project_id) {should == 'Service - Peon'} | ||
| 342 | + its(:username) {should == '1234'} | ||
| 343 | + its(:password) {should == '123123'} | ||
| 344 | + end | ||
| 345 | + | ||
| 346 | + context 'insufficient params' do | ||
| 347 | + it 'shows validation notice' do | ||
| 348 | + put :update, :id => @app.id, :app => { :issue_tracker_attributes => { | ||
| 349 | + :issue_tracker_type => 'fogbugz', :project_id => '1234' } } | ||
| 350 | + @app.reload | ||
| 351 | + | ||
| 352 | + @app.issue_tracker.should be_nil | ||
| 353 | + response.body.should match(/You must specify your FogBugz Area Name, Username, and Password/) | ||
| 354 | + end | ||
| 355 | + end | ||
| 356 | + end | ||
| 264 | end | 357 | end |
| 265 | end | 358 | end |
| 266 | 359 |
spec/controllers/errs_controller_spec.rb
| @@ -54,6 +54,50 @@ describe ErrsController do | @@ -54,6 +54,50 @@ describe ErrsController do | ||
| 54 | assigns(:errs).size.should == 10 | 54 | assigns(:errs).size.should == 10 |
| 55 | end | 55 | end |
| 56 | end | 56 | end |
| 57 | + | ||
| 58 | + context 'with environment filters' do | ||
| 59 | + before(:each) do | ||
| 60 | + environments = ['production', 'test', 'development', 'staging'] | ||
| 61 | + 20.times do |i| | ||
| 62 | + Factory.create(:err, environment: environments[i % environments.length]) | ||
| 63 | + end | ||
| 64 | + end | ||
| 65 | + | ||
| 66 | + context 'no params' do | ||
| 67 | + it 'shows errs for all environments' do | ||
| 68 | + get :index | ||
| 69 | + assigns(:errs).size.should == 21 | ||
| 70 | + end | ||
| 71 | + end | ||
| 72 | + | ||
| 73 | + context 'environment production' do | ||
| 74 | + it 'shows errs for just production' do | ||
| 75 | + get :index, environment: :production | ||
| 76 | + assigns(:errs).size.should == 6 | ||
| 77 | + end | ||
| 78 | + end | ||
| 79 | + | ||
| 80 | + context 'environment staging' do | ||
| 81 | + it 'shows errs for just staging' do | ||
| 82 | + get :index, environment: :staging | ||
| 83 | + assigns(:errs).size.should == 5 | ||
| 84 | + end | ||
| 85 | + end | ||
| 86 | + | ||
| 87 | + context 'environment development' do | ||
| 88 | + it 'shows errs for just development' do | ||
| 89 | + get :index, environment: :development | ||
| 90 | + assigns(:errs).size.should == 5 | ||
| 91 | + end | ||
| 92 | + end | ||
| 93 | + | ||
| 94 | + context 'environment test' do | ||
| 95 | + it 'shows errs for just test' do | ||
| 96 | + get :index, environment: :test | ||
| 97 | + assigns(:errs).size.should == 5 | ||
| 98 | + end | ||
| 99 | + end | ||
| 100 | + end | ||
| 57 | end | 101 | end |
| 58 | 102 | ||
| 59 | context 'when logged in as a user' do | 103 | context 'when logged in as a user' do |
| @@ -358,7 +402,7 @@ describe ErrsController do | @@ -358,7 +402,7 @@ describe ErrsController do | ||
| 358 | end | 402 | end |
| 359 | end | 403 | end |
| 360 | 404 | ||
| 361 | - describe "DELETE /apps/:app_id/errs/:id/clear_issue" do | 405 | + describe "DELETE /apps/:app_id/errs/:id/unlink_issue" do |
| 362 | before(:each) do | 406 | before(:each) do |
| 363 | sign_in Factory(:admin) | 407 | sign_in Factory(:admin) |
| 364 | end | 408 | end |
| @@ -367,7 +411,7 @@ describe ErrsController do | @@ -367,7 +411,7 @@ describe ErrsController do | ||
| 367 | let(:err) { Factory :err, :issue_link => "http://some.host" } | 411 | let(:err) { Factory :err, :issue_link => "http://some.host" } |
| 368 | 412 | ||
| 369 | before(:each) do | 413 | before(:each) do |
| 370 | - delete :clear_issue, :app_id => err.app.id, :id => err.id | 414 | + delete :unlink_issue, :app_id => err.app.id, :id => err.id |
| 371 | err.reload | 415 | err.reload |
| 372 | end | 416 | end |
| 373 | 417 | ||
| @@ -384,7 +428,7 @@ describe ErrsController do | @@ -384,7 +428,7 @@ describe ErrsController do | ||
| 384 | let(:err) { Factory :err } | 428 | let(:err) { Factory :err } |
| 385 | 429 | ||
| 386 | before(:each) do | 430 | before(:each) do |
| 387 | - delete :clear_issue, :app_id => err.app.id, :id => err.id | 431 | + delete :unlink_issue, :app_id => err.app.id, :id => err.id |
| 388 | err.reload | 432 | err.reload |
| 389 | end | 433 | end |
| 390 | 434 |