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 |