Commit 7763705702f45acb40fcbc846cff81dde6d462b2

Authored by Jared Pace
2 parents 7270ce2c d55d2edf
Exists in master and in 1 other branch production

Merge branch 'master' of https://github.com/Undev/errbit into Undev-master

.gitignore
... ... @@ -4,4 +4,6 @@ log/*.log
4 4 tmp/**/*
5 5 config/config.yml
6 6 config/deploy.rb
7   -config/mongoid.yml
8 7 \ No newline at end of file
  8 +config/mongoid.yml
  9 +.rvmrc
  10 +*~
... ...
Gemfile
1 1 source 'http://rubygems.org'
2 2  
3   -gem 'rails', '3.0.0.rc'
  3 +gem 'rails', '3.0.3'
4 4 gem 'libxml-ruby'
5 5 gem 'bson_ext', :require => nil
6   -gem 'mongoid', '2.0.0.beta.15'
  6 +gem 'mongoid', '~> 2.0.0.beta.20'
7 7 gem 'haml'
8 8 gem 'will_paginate'
9   -gem 'devise', '1.1.1'
  9 +gem 'devise', '~> 1.1.3'
10 10  
11 11 group :development, :test do
12   - gem 'rspec-rails', '>= 2.0.0.beta.19'
  12 + gem 'rspec-rails', '~> 2.1'
13 13 end
14 14  
15 15 group :test do
16   - gem 'rspec', '>= 2.0.0.beta.19'
17   - gem 'database_cleaner', '0.5.2'
  16 + gem 'rspec', '~> 2.1'
  17 + gem 'database_cleaner', '~> 0.6.0'
18 18 gem 'factory_girl_rails'
19 19 end
... ...
Gemfile.lock
... ... @@ -2,40 +2,39 @@ GEM
2 2 remote: http://rubygems.org/
3 3 specs:
4 4 abstract (1.0.0)
5   - actionmailer (3.0.0.rc)
6   - actionpack (= 3.0.0.rc)
7   - mail (~> 2.2.5)
8   - actionpack (3.0.0.rc)
9   - activemodel (= 3.0.0.rc)
10   - activesupport (= 3.0.0.rc)
  5 + actionmailer (3.0.3)
  6 + actionpack (= 3.0.3)
  7 + mail (~> 2.2.9)
  8 + actionpack (3.0.3)
  9 + activemodel (= 3.0.3)
  10 + activesupport (= 3.0.3)
11 11 builder (~> 2.1.2)
12 12 erubis (~> 2.6.6)
13   - i18n (~> 0.4.1)
  13 + i18n (~> 0.4)
14 14 rack (~> 1.2.1)
15   - rack-mount (~> 0.6.9)
16   - rack-test (~> 0.5.4)
17   - tzinfo (~> 0.3.22)
18   - activemodel (3.0.0.rc)
19   - activesupport (= 3.0.0.rc)
  15 + rack-mount (~> 0.6.13)
  16 + rack-test (~> 0.5.6)
  17 + tzinfo (~> 0.3.23)
  18 + activemodel (3.0.3)
  19 + activesupport (= 3.0.3)
20 20 builder (~> 2.1.2)
21   - i18n (~> 0.4.1)
22   - activerecord (3.0.0.rc)
23   - activemodel (= 3.0.0.rc)
24   - activesupport (= 3.0.0.rc)
25   - arel (~> 0.4.0)
26   - tzinfo (~> 0.3.22)
27   - activeresource (3.0.0.rc)
28   - activemodel (= 3.0.0.rc)
29   - activesupport (= 3.0.0.rc)
30   - activesupport (3.0.0.rc)
31   - arel (0.4.0)
32   - activesupport (>= 3.0.0.beta)
  21 + i18n (~> 0.4)
  22 + activerecord (3.0.3)
  23 + activemodel (= 3.0.3)
  24 + activesupport (= 3.0.3)
  25 + arel (~> 2.0.2)
  26 + tzinfo (~> 0.3.23)
  27 + activeresource (3.0.3)
  28 + activemodel (= 3.0.3)
  29 + activesupport (= 3.0.3)
  30 + activesupport (3.0.3)
  31 + arel (2.0.4)
33 32 bcrypt-ruby (2.1.2)
34   - bson (1.0.4)
35   - bson_ext (1.0.4)
  33 + bson (1.1.2)
  34 + bson_ext (1.1.2)
36 35 builder (2.1.2)
37   - database_cleaner (0.5.2)
38   - devise (1.1.1)
  36 + database_cleaner (0.6.0)
  37 + devise (1.1.3)
39 38 bcrypt-ruby (~> 2.1.2)
40 39 warden (~> 0.10.7)
41 40 diff-lcs (1.1.2)
... ... @@ -45,64 +44,58 @@ GEM
45 44 factory_girl_rails (1.0)
46 45 factory_girl (~> 1.3)
47 46 rails (>= 3.0.0.beta4)
48   - haml (3.0.16)
49   - i18n (0.4.1)
  47 + haml (3.0.24)
  48 + i18n (0.4.2)
50 49 libxml-ruby (1.1.4)
51   - mail (2.2.5)
  50 + mail (2.2.10)
52 51 activesupport (>= 2.3.6)
53   - mime-types
54   - treetop (>= 1.4.5)
  52 + i18n (~> 0.4.1)
  53 + mime-types (~> 1.16)
  54 + treetop (~> 1.4.8)
55 55 mime-types (1.16)
56   - mongo (1.0.6)
57   - bson (>= 1.0.4)
58   - mongoid (2.0.0.beta.15)
59   - activemodel (= 3.0.0.rc)
60   - bson (= 1.0.4)
61   - mongo (= 1.0.6)
62   - tzinfo (= 0.3.22)
  56 + mongo (1.1.2)
  57 + bson (>= 1.1.1)
  58 + mongoid (2.0.0.beta.20)
  59 + activemodel (~> 3.0)
  60 + mongo (~> 1.1)
  61 + tzinfo (~> 0.3.22)
63 62 will_paginate (~> 3.0.pre)
64   - nokogiri (1.4.3.1)
65 63 polyglot (0.3.1)
66 64 rack (1.2.1)
67   - rack-mount (0.6.9)
  65 + rack-mount (0.6.13)
68 66 rack (>= 1.0.0)
69   - rack-test (0.5.4)
  67 + rack-test (0.5.6)
70 68 rack (>= 1.0)
71   - rails (3.0.0.rc)
72   - actionmailer (= 3.0.0.rc)
73   - actionpack (= 3.0.0.rc)
74   - activerecord (= 3.0.0.rc)
75   - activeresource (= 3.0.0.rc)
76   - activesupport (= 3.0.0.rc)
77   - bundler (>= 1.0.0.rc.1)
78   - railties (= 3.0.0.rc)
79   - railties (3.0.0.rc)
80   - actionpack (= 3.0.0.rc)
81   - activesupport (= 3.0.0.rc)
82   - rake (>= 0.8.3)
83   - thor (~> 0.14.0)
  69 + rails (3.0.3)
  70 + actionmailer (= 3.0.3)
  71 + actionpack (= 3.0.3)
  72 + activerecord (= 3.0.3)
  73 + activeresource (= 3.0.3)
  74 + activesupport (= 3.0.3)
  75 + bundler (~> 1.0)
  76 + railties (= 3.0.3)
  77 + railties (3.0.3)
  78 + actionpack (= 3.0.3)
  79 + activesupport (= 3.0.3)
  80 + rake (>= 0.8.7)
  81 + thor (~> 0.14.4)
84 82 rake (0.8.7)
85   - rspec (2.0.0.beta.19)
86   - rspec-core (= 2.0.0.beta.19)
87   - rspec-expectations (= 2.0.0.beta.19)
88   - rspec-mocks (= 2.0.0.beta.19)
89   - rspec-core (2.0.0.beta.19)
90   - rspec-expectations (2.0.0.beta.19)
91   - diff-lcs (>= 1.1.2)
92   - rspec-mocks (2.0.0.beta.19)
93   - rspec-rails (2.0.0.beta.19)
94   - rspec (= 2.0.0.beta.19)
95   - webrat (>= 0.7.2.beta.1)
96   - thor (0.14.0)
97   - treetop (1.4.8)
  83 + rspec (2.1.0)
  84 + rspec-core (~> 2.1.0)
  85 + rspec-expectations (~> 2.1.0)
  86 + rspec-mocks (~> 2.1.0)
  87 + rspec-core (2.1.0)
  88 + rspec-expectations (2.1.0)
  89 + diff-lcs (~> 1.1.2)
  90 + rspec-mocks (2.1.0)
  91 + rspec-rails (2.1.0)
  92 + rspec (~> 2.1.0)
  93 + thor (0.14.6)
  94 + treetop (1.4.9)
98 95 polyglot (>= 0.3.1)
99   - tzinfo (0.3.22)
  96 + tzinfo (0.3.23)
100 97 warden (0.10.7)
101 98 rack (>= 1.0.0)
102   - webrat (0.7.2.beta.1)
103   - nokogiri (>= 1.2.0)
104   - rack (>= 1.0)
105   - rack-test (>= 0.5.3)
106 99 will_paginate (3.0.pre2)
107 100  
108 101 PLATFORMS
... ... @@ -110,13 +103,13 @@ PLATFORMS
110 103  
111 104 DEPENDENCIES
112 105 bson_ext
113   - database_cleaner (= 0.5.2)
114   - devise (= 1.1.1)
  106 + database_cleaner (~> 0.6.0)
  107 + devise (~> 1.1.3)
115 108 factory_girl_rails
116 109 haml
117 110 libxml-ruby
118   - mongoid (= 2.0.0.beta.15)
119   - rails (= 3.0.0.rc)
120   - rspec (>= 2.0.0.beta.19)
121   - rspec-rails (>= 2.0.0.beta.19)
  111 + mongoid (~> 2.0.0.beta.20)
  112 + rails (= 3.0.3)
  113 + rspec (~> 2.1)
  114 + rspec-rails (~> 2.1)
122 115 will_paginate
... ...
README.md
... ... @@ -39,7 +39,7 @@ for you. Checkout [Hoptoad](http://hoptoadapp.com) from the guys over at
39 39  
40 40 3. Install Bundler
41 41  
42   - gem install bundler --pre
  42 + gem install bundler
43 43  
44 44 **Running Locally:**
45 45  
... ... @@ -70,7 +70,6 @@ for you. Checkout [Hoptoad](http://hoptoadapp.com) from the guys over at
70 70 TODO
71 71 ----
72 72  
73   -* Add a deployment view
74 73 * Add ability for watchers to be configured for types of notifications they should receive
75 74  
76 75 Special Thanks
... ...
Rakefile
... ... @@ -8,4 +8,18 @@ require 'bundler'
8 8 Errbit::Application.load_tasks
9 9  
10 10 Rake::Task[:default].clear
  11 +
  12 +namespace :spec do
  13 + desc "Preparing test env"
  14 + task :prepare do
  15 + tmp_env = Rails.env
  16 + Rails.env = "test"
  17 + %w( errbit:bootstrap ).each do |task|
  18 + Rake::Task[task].invoke
  19 + end
  20 + Rails.env = tmp_env
  21 + end
  22 +end
  23 +
  24 +Rake::Task["spec"].prerequisites.push("spec:prepare")
11 25 task :default => ['spec']
12 26 \ No newline at end of file
... ...
app/controllers/apps_controller.rb
... ... @@ -8,7 +8,8 @@ class AppsController < ApplicationController
8 8 end
9 9  
10 10 def show
11   - @errs = @app.errs.paginate
  11 + @errs = @app.errs.ordered.paginate(:page => params[:page], :per_page => Err.per_page)
  12 + @deploys = @app.deploys.order_by(:created_at.desc).limit(5)
12 13 end
13 14  
14 15 def new
... ...
app/controllers/deploys_controller.rb
1 1 class DeploysController < ApplicationController
2 2  
  3 + skip_before_filter :verify_authenticity_token, :only => :create
3 4 skip_before_filter :authenticate_user!, :only => :create
4 5  
5 6 def create
... ... @@ -12,5 +13,13 @@ class DeploysController &lt; ApplicationController
12 13 })
13 14 render :xml => @deploy
14 15 end
  16 +
  17 + def index
  18 + # See AppsController#find_app for the reasoning behind this code.
  19 + app = App.find(params[:app_id])
  20 + raise(Mongoid::Errors::DocumentNotFound.new(App,app.id)) unless current_user.admin? || current_user.watching?(app)
  21 +
  22 + @deploys = app.deploys.order_by(:created_at.desc).paginate(:page => params[:page], :per_page => 10)
  23 + end
15 24  
16   -end
17 25 \ No newline at end of file
  26 +end
... ...
app/controllers/errs_controller.rb
... ... @@ -4,12 +4,12 @@ class ErrsController &lt; ApplicationController
4 4  
5 5 def index
6 6 app_scope = current_user.admin? ? App.all : current_user.apps
7   - @errs = Err.for_apps(app_scope).unresolved.ordered.paginate(:page => params[:page])
  7 + @errs = Err.for_apps(app_scope).unresolved.ordered.paginate(:page => params[:page], :per_page => Err.per_page)
8 8 end
9 9  
10 10 def all
11 11 app_scope = current_user.admin? ? App.all : current_user.apps
12   - @errs = Err.for_apps(app_scope).ordered.paginate(:page => params[:page])
  12 + @errs = Err.for_apps(app_scope).ordered.paginate(:page => params[:page], :per_page => Err.per_page)
13 13 end
14 14  
15 15 def show
... ...
app/controllers/users_controller.rb
... ... @@ -6,7 +6,7 @@ class UsersController &lt; ApplicationController
6 6 before_filter :require_user_edit_priviledges, :only => [:edit, :update]
7 7  
8 8 def index
9   - @users = User.paginate(:page => params[:page])
  9 + @users = User.paginate(:page => params[:page], :per_page => User.per_page)
10 10 end
11 11  
12 12 def show
... ... @@ -23,6 +23,9 @@ class UsersController &lt; ApplicationController
23 23 def create
24 24 @user = User.new(params[:user])
25 25  
  26 + # Set protected attributes
  27 + @user.admin = params[:user].try(:[], :admin) if current_user.admin?
  28 +
26 29 if @user.save
27 30 flash[:success] = "#{@user.name} is now part of the team. Be sure to add them as a project watcher."
28 31 redirect_to user_path(@user)
... ...
app/helpers/errs_helper.rb 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +module ErrsHelper
  2 +
  3 + def last_notice_at err
  4 + err.last_notice_at || err.created_at
  5 + end
  6 +
  7 +end
0 8 \ No newline at end of file
... ...
app/models/deploy.rb
... ... @@ -6,6 +6,8 @@ class Deploy
6 6 field :repository
7 7 field :environment
8 8 field :revision
  9 +
  10 + index :created_at, Mongo::DESCENDING
9 11  
10 12 embedded_in :app, :inverse_of => :deploys
11 13  
... ...
app/models/err.rb
1 1 class Err
  2 + cattr_reader :per_page
  3 + @@per_page = 30
2 4 include Mongoid::Document
3 5 include Mongoid::Timestamps
4 6  
... ... @@ -9,7 +11,9 @@ class Err
9 11 field :fingerprint
10 12 field :last_notice_at, :type => DateTime
11 13 field :resolved, :type => Boolean, :default => false
12   -
  14 +
  15 + index :last_notice_at
  16 +
13 17 referenced_in :app
14 18 embeds_many :notices
15 19  
... ... @@ -41,7 +45,7 @@ class Err
41 45 end
42 46  
43 47 def message
44   - notices.first.message || klass
  48 + notices.first.try(:message) || klass
45 49 end
46 50  
47 51 end
48 52 \ No newline at end of file
... ...
app/models/notice.rb
... ... @@ -23,6 +23,7 @@ class Notice
23 23 hoptoad_notice = Hoptoad::V2.parse_xml(hoptoad_xml)
24 24 app = App.find_by_api_key!(hoptoad_notice['api-key'])
25 25  
  26 + hoptoad_notice['request'] ||= {}
26 27 hoptoad_notice['request']['component'] = 'unknown' if hoptoad_notice['request']['component'].blank?
27 28 hoptoad_notice['request']['action'] = nil if hoptoad_notice['request']['action'].blank?
28 29  
... ...
app/models/user.rb
1 1 class User
  2 + cattr_reader :per_page
  3 + @@per_page = 30
2 4 include Mongoid::Document
3 5 include Mongoid::Timestamps
4 6  
... ...
app/views/apps/_configuration_instructions.html.haml
... ... @@ -16,7 +16,7 @@
16 16 HoptoadNotifier.configure do |config|
17 17 config.api_key = '#{app.api_key}'
18 18 config.host = '#{request.host}'
19   - config.port = #{request.port} # Note: Deployment notifications only work on port 80
  19 + config.port = #{request.port}
20 20 end
21 21 #
22 22 # Testing
... ...
app/views/apps/index.html.haml
... ... @@ -12,7 +12,7 @@
12 12 - @apps.each do |app|
13 13 %tr
14 14 %td.name= link_to app.name, app_path(app)
15   - %td.deploy= app.last_deploy_at ? app.last_deploy_at.to_s(:micro) : 'n/a'
  15 + %td.deploy= app.last_deploy_at ? link_to( app.last_deploy_at.to_s(:micro), app_deploys_path(app)) : 'n/a'
16 16 %td.count
17 17 - if app.errs.any?
18 18 = link_to app.errs.unresolved.count, app_errs_path(app)
... ... @@ -23,4 +23,4 @@
23 23 %td{:colspan => 3}
24 24 %em
25 25 No apps here.
26   - = link_to 'Click here to create your first one', new_app_path
27 26 \ No newline at end of file
  27 + = link_to 'Click here to create your first one', new_app_path
... ...
app/views/apps/show.html.haml
... ... @@ -2,6 +2,8 @@
2 2 - content_for :meta do
3 3 %strong Errs Caught:
4 4 = @app.errs.count
  5 + %strong Deploy Count:
  6 + = @app.deploys.count
5 7 %strong API Key:
6 8 = @app.api_key
7 9 - content_for :action_bar do
... ... @@ -23,9 +25,30 @@
23 25 %td
24 26 %em Sadly, no one is watching this app
25 27  
  28 +%h3 Latest Deploys
  29 +- if @deploys.any?
  30 + %table.deploys
  31 + %thead
  32 + %tr
  33 + %th When
  34 + %th Who
  35 + %th Repository
  36 + %th Revision
  37 +
  38 + %tbody
  39 + - @deploys.each do |deploy|
  40 + %tr
  41 + %td.when #{deploy.created_at.to_s(:micro)}
  42 + %td.who #{deploy.username}
  43 + %td.repository #{deploy.repository}
  44 + %td.revision #{deploy.revision}
  45 + = link_to "All Deploys (#{@app.deploys.count})", app_deploys_path(@app), :class => 'button'
  46 +- else
  47 + %h3 No deploys
  48 +
26 49 - if @app.errs.any?
27   - %h3 Errs
  50 + %h3.clear Errs
28 51 = render 'errs/table', :errs => @errs
29 52 - else
30   - %h3 No errs have been caught yet, make sure you setup your app
31   - = render 'configuration_instructions', :app => @app
32 53 \ No newline at end of file
  54 + %h3.clear No errs have been caught yet, make sure you setup your app
  55 + = render 'configuration_instructions', :app => @app
... ...
app/views/deploys/_table.html.haml 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +%table.errs
  2 + %thead
  3 + %tr
  4 + %th App
  5 + %th When
  6 + %th Who
  7 + %th Repository
  8 + %th Revision
  9 + %tbody
  10 + - deploys.each do |deploy|
  11 + %tr
  12 + %td.app
  13 + = deploy.app.name
  14 + %span.environment= deploy.environment
  15 + %td.latest #{time_ago_in_words(deploy.created_at)} ago
  16 + %td.who #{deploy.username}
  17 + %td.repository #{deploy.repository}
  18 + %td.revision #{deploy.revision}
... ...
app/views/deploys/index.html.haml 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +- content_for :title, 'Deploys'
  2 += render 'table', :deploys => @deploys
  3 += will_paginate @deploys, :previous_label => '&laquo; Previous', :next_label => 'Next &raquo;'
... ...
app/views/errs/_table.html.haml
... ... @@ -15,11 +15,11 @@
15 15 %td.message
16 16 = link_to err.message, app_err_path(err.app, err)
17 17 %em= err.where
18   - %td.latest #{time_ago_in_words(err.last_notice_at)} ago
  18 + %td.latest #{time_ago_in_words(last_notice_at err)} ago
19 19 %td.deploy= err.app.last_deploy_at ? err.app.last_deploy_at.to_s(:micro) : 'n/a'
20 20 %td.count= link_to err.notices.count, app_err_path(err.app, err)
21 21 - if errs.none?
22 22 %tr
23 23 %td{:colspan => (@app ? 5 : 6)}
24 24 %em No errs here
25   -= will_paginate @errs, :previous_label => '&laquo; Previous', :next_label => 'Next &raquo;'
26 25 \ No newline at end of file
  26 += will_paginate @errs, :previous_label => '&laquo; Previous', :next_label => 'Next &raquo;'
... ...
app/views/errs/show.html.haml
... ... @@ -6,11 +6,11 @@
6 6 %strong Environment:
7 7 = @err.environment
8 8 %strong Last Notice:
9   - = @err.last_notice_at.to_s(:micro)
  9 + = last_notice_at(@err).to_s(:micro)
10 10 - content_for :action_bar do
11 11 %span= link_to 'resolve', resolve_app_err_path(@app, @err), :method => :put, :confirm => 'Seriously?', :class => 'resolve' if @err.unresolved?
12 12  
13   -%h4= @notice.message
  13 +%h4= @notice.try(:message)
14 14  
15 15 = will_paginate @notices, :param_name => :notice, :page_links => false, :class => 'notice-pagination'
16 16 viewing occurrence #{@notices.current_page} of #{@notices.total_pages}
... ... @@ -23,22 +23,23 @@ viewing occurrence #{@notices.current_page} of #{@notices.total_pages}
23 23 %li= link_to 'Parameters', '#params', :rel => 'params', :class => 'button'
24 24 %li= link_to 'Session', '#session', :rel => 'session', :class => 'button'
25 25  
26   -#summary
27   - %h3 Summary
28   - = render 'notices/summary', :notice => @notice
29   -
30   -#backtrace
31   - %h3 Backtrace
32   - = render 'notices/backtrace', :lines => @notice.backtrace
  26 +- if @notice
  27 + #summary
  28 + %h3 Summary
  29 + = render 'notices/summary', :notice => @notice
33 30  
34   -#environment
35   - %h3 Environment
36   - = render 'notices/environment', :notice => @notice
37   -
38   -#params
39   - %h3 Parameters
40   - = render 'notices/params', :notice => @notice
41   -
42   -#session
43   - %h3 Session
44   - = render 'notices/session', :notice => @notice
45 31 \ No newline at end of file
  32 + #backtrace
  33 + %h3 Backtrace
  34 + = render 'notices/backtrace', :lines => @notice.backtrace
  35 +
  36 + #environment
  37 + %h3 Environment
  38 + = render 'notices/environment', :notice => @notice
  39 +
  40 + #params
  41 + %h3 Parameters
  42 + = render 'notices/params', :notice => @notice
  43 +
  44 + #session
  45 + %h3 Session
  46 + = render 'notices/session', :notice => @notice
... ...
config/routes.rb
... ... @@ -22,6 +22,8 @@ Errbit::Application.routes.draw do
22 22 put :resolve
23 23 end
24 24 end
  25 +
  26 + resources :deploys, :only => [:index]
25 27 end
26 28  
27 29 devise_for :users
... ...
db/seeds.rb
... ... @@ -10,10 +10,12 @@ puts &quot;-- email: #{admin_email}&quot;
10 10 puts "-- password: #{admin_pass}"
11 11 puts ""
12 12 puts "Be sure to change these credentials ASAP!"
13   -User.create!({
  13 +user = User.where(:email => admin_email).first || User.new({
14 14 :name => 'Errbit Admin',
15 15 :email => admin_email,
16 16 :password => admin_pass,
17 17 :password_confirmation => admin_pass,
18   - :admin => true
19   -})
20 18 \ No newline at end of file
  19 +})
  20 +
  21 +user.admin = true
  22 +user.save!
21 23 \ No newline at end of file
... ...
lib/tasks/errbit/bootstrap.rake
... ... @@ -26,6 +26,8 @@ namespace :errbit do
26 26 Rake::Task['errbit:copy_configs'].execute
27 27 puts "\n"
28 28 Rake::Task['db:seed'].invoke
  29 + puts "\n"
  30 + Rake::Task['db:mongoid:create_indexes'].invoke
29 31 end
30 32  
31 33 end
32 34 \ No newline at end of file
... ...
public/stylesheets/application.css
... ... @@ -195,6 +195,12 @@ a.action { float: right; font-size: 0.9em;}
195 195 padding: 20px; border-top: 1px solid #C6C6C6;
196 196 background-color: #FFF;
197 197 }
  198 +
  199 +#content a.button {
  200 + float: right;
  201 + display: block;
  202 + margin-bottom: 10px;
  203 +}
198 204  
199 205 /* Footer */
200 206 #footer {
... ... @@ -607,4 +613,4 @@ table.backtrace li {
607 613 table.backtrace li.in-app {
608 614 color: #2adb2e;
609 615 background-color: #2f2f2f;
610   -}
611 616 \ No newline at end of file
  617 +}
... ...
spec/controllers/apps_controller_spec.rb
... ... @@ -32,18 +32,27 @@ describe AppsController do
32 32 end
33 33  
34 34 describe "GET /apps/:id" do
  35 + render_views
35 36 context 'logged in as an admin' do
36   - it 'finds the app' do
  37 + before(:each) do
37 38 sign_in Factory(:admin)
38   - app = Factory(:app)
39   - get :show, :id => app.id
40   - assigns(:app).should == app
  39 + @app = Factory(:app)
  40 + end
  41 +
  42 + it 'finds the app' do
  43 + get :show, :id => @app.id
  44 + assigns(:app).should == @app
  45 + end
  46 +
  47 + it "should not raise errors for app with err without notices" do
  48 + Factory :err, :app => @app
  49 + lambda { get :show, :id => @app.id }.should_not raise_error
41 50 end
42 51 end
43 52  
44 53 context 'logged in as a user' do
45 54 it 'finds the app if the user is watching it' do
46   -
  55 + pending
47 56 end
48 57  
49 58 it 'does not find the app if the user is not watching it' do
... ...
spec/controllers/deploys_controller_spec.rb
1 1 require 'spec_helper'
2 2  
3 3 describe DeploysController do
  4 + render_views
4 5  
5 6 context 'POST #create' do
6 7 before do
... ... @@ -38,5 +39,22 @@ describe DeploysController do
38 39 end
39 40  
40 41 end
  42 +
  43 + context "GET #index" do
  44 + before(:each) do
  45 + @deploy = Factory :deploy
  46 + sign_in Factory(:admin)
  47 + get :index, :app_id => @deploy.app.id
  48 + end
  49 +
  50 + it "should render successfully" do
  51 + response.should be_success
  52 + end
  53 +
  54 + it "should contain info about existing deploy" do
  55 + response.body.should match(@deploy.revision)
  56 + response.body.should match(@deploy.app.name)
  57 + end
  58 + end
41 59  
42 60 end
43 61 \ No newline at end of file
... ...
spec/controllers/errs_controller_spec.rb
... ... @@ -12,8 +12,11 @@ describe ErrsController do
12 12  
13 13 describe "GET /errs" do
14 14 context 'when logged in as an admin' do
15   - it "gets a paginated list of unresolved errs" do
  15 + before(:each) do
16 16 sign_in Factory(:admin)
  17 + end
  18 +
  19 + it "gets a paginated list of unresolved errs" do
17 20 errs = WillPaginate::Collection.new(1,30)
18 21 3.times { errs << Factory(:err) }
19 22 Err.should_receive(:unresolved).and_return(
... ... @@ -22,6 +25,11 @@ describe ErrsController do
22 25 get :index
23 26 assigns(:errs).should == errs
24 27 end
  28 +
  29 + it "should handle lots of errors" do
  30 + 1000.times { Factory :notice }
  31 + lambda { get :index }.should_not raise_error
  32 + end
25 33 end
26 34  
27 35 context 'when logged in as a user' do
... ... @@ -66,6 +74,8 @@ describe ErrsController do
66 74 end
67 75  
68 76 describe "GET /apps/:app_id/errs/:id" do
  77 + render_views
  78 +
69 79 before do
70 80 3.times { Factory(:notice, :err => err)}
71 81 end
... ... @@ -85,13 +95,9 @@ describe ErrsController do
85 95 assigns(:err).should == err
86 96 end
87 97  
88   - it "paginates the notices, 1 at a time" do
89   - App.stub(:find).with(app.id).and_return(app)
90   - app.errs.stub(:find).with(err.id).and_return(err)
91   - err.notices.should_receive(:ordered).and_return(proxy = stub('proxy'))
92   - proxy.should_receive(:paginate).with(:page => 3, :per_page => 1).
93   - and_return(WillPaginate::Collection.new(1,1) << err.notices.first)
  98 + it "successfully render page" do
94 99 get :show, :app_id => app.id, :id => err.id
  100 + response.should be_success
95 101 end
96 102 end
97 103  
... ...
spec/controllers/users_controller_spec.rb
... ... @@ -48,6 +48,11 @@ describe UsersController do
48 48 put :update, :id => @user.to_param, :user => {:name => 'Kermit'}
49 49 response.should redirect_to(user_path(@user))
50 50 end
  51 +
  52 + it "should not be able to become an admin" do
  53 + put :update, :id => @user.to_param, :user => {:admin => true}
  54 + @user.reload.admin.should be_false
  55 + end
51 56 end
52 57  
53 58 context "when the update is unsuccessful" do
... ... @@ -100,19 +105,24 @@ describe UsersController do
100 105 context "POST /users" do
101 106 context "when the create is successful" do
102 107 before do
103   - @user = Factory(:user)
104   - User.should_receive(:new).and_return(@user)
105   - @user.should_receive(:save).and_return(true)
  108 + @attrs = {:user => Factory.attributes_for(:user)}
106 109 end
107 110  
108 111 it "sets a message to display" do
109   - post :create
  112 + post :create, @attrs
110 113 request.flash[:success].should include('part of the team')
111 114 end
112 115  
113 116 it "redirects to the user's page" do
114   - post :create
115   - response.should redirect_to(user_path(@user))
  117 + post :create, @attrs
  118 + response.should redirect_to(user_path(assigns(:user)))
  119 + end
  120 +
  121 + it "should be able to create admin" do
  122 + @attrs[:user][:admin] = true
  123 + post :create, @attrs
  124 + response.should be_redirect
  125 + User.find(assigns(:user).to_param).admin.should be_true
116 126 end
117 127 end
118 128  
... ... @@ -145,6 +155,12 @@ describe UsersController do
145 155 put :update, :id => @user.to_param, :user => {:name => 'Kermit'}
146 156 response.should redirect_to(user_path(@user))
147 157 end
  158 +
  159 + it "should be able to make user an admin" do
  160 + put :update, :id => @user.to_param, :user => {:admin => true}
  161 + response.should be_redirect
  162 + User.find(assigns(:user).to_param).admin.should be_true
  163 + end
148 164 end
149 165  
150 166 context "when the update is unsuccessful" do
... ...
spec/factories.rb 0 → 100644
... ... @@ -0,0 +1,4 @@
  1 +Factory.sequence(:name) {|n| "John #{n} Doe"}
  2 +Factory.sequence(:app_name) {|n| "App ##{n}"}
  3 +Factory.sequence(:email) {|n| "email#{n}@example.com"}
  4 +Factory.sequence(:user_email) {|n| "user.#{n}@example.com"}
... ...
spec/factories/app_factories.rb
1   -Factory.sequence(:app_name) {|n| "App ##{n}"}
2   -Factory.sequence(:email) {|n| "email#{n}@example.com"}
3   -
4 1 Factory.define(:app) do |p|
5 2 p.name { Factory.next :app_name }
6 3 end
... ... @@ -27,5 +24,5 @@ Factory.define(:deploy) do |d|
27 24 d.username 'clyde.frog'
28 25 d.repository 'git@github.com/jdpace/errbit.git'
29 26 d.environment 'production'
30   - d.revision '2e601cb575ca97f1a1097f12d0edfae241a70263'
  27 + d.revision ActiveSupport::SecureRandom.hex(10)
31 28 end
32 29 \ No newline at end of file
... ...
spec/factories/user_factories.rb
1   -Factory.sequence(:user_email) {|n| "user.#{n}@example.com"}
2   -
3 1 Factory.define :user do |u|
4 2 u.name 'Clyde Frog'
5 3 u.email { Factory.next :user_email }
... ...
spec/fixtures/hoptoad_test_notice_without_request_section.xml 0 → 100644
... ... @@ -0,0 +1,92 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<notice version="2.0">
  3 + <api-key>APIKEY</api-key>
  4 + <notifier>
  5 + <name>Hoptoad Notifier</name>
  6 + <version>2.3.2</version>
  7 + <url>http://hoptoadapp.com</url>
  8 + </notifier>
  9 + <error>
  10 + <class>HoptoadTestingException</class>
  11 + <message>HoptoadTestingException: Testing hoptoad via "rake hoptoad:test". If you can see this, it works.</message>
  12 + <backtrace>
  13 + <line number="425" file="[GEM_ROOT]/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb" method="_run__2115867319__process_action__262109504__callbacks"/>
  14 + <line number="404" file="[GEM_ROOT]/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb" method="send"/>
  15 + <line number="404" file="[GEM_ROOT]/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb" method="_run_process_action_callbacks"/>
  16 + <line number="93" file="[GEM_ROOT]/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb" method="send"/>
  17 + <line number="93" file="[GEM_ROOT]/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb" method="run_callbacks"/>
  18 + <line number="17" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/abstract_controller/callbacks.rb" method="process_action"/>
  19 + <line number="30" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_controller/metal/instrumentation.rb" method="process_action"/>
  20 + <line number="52" file="[GEM_ROOT]/gems/activesupport-3.0.0.rc/lib/active_support/notifications.rb" method="instrument"/>
  21 + <line number="21" file="[GEM_ROOT]/gems/activesupport-3.0.0.rc/lib/active_support/notifications/instrumenter.rb" method="instrument"/>
  22 + <line number="52" file="[GEM_ROOT]/gems/activesupport-3.0.0.rc/lib/active_support/notifications.rb" method="instrument"/>
  23 + <line number="29" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_controller/metal/instrumentation.rb" method="process_action"/>
  24 + <line number="17" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_controller/metal/rescue.rb" method="process_action"/>
  25 + <line number="105" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/abstract_controller/base.rb" method="process"/>
  26 + <line number="40" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/abstract_controller/rendering.rb" method="process"/>
  27 + <line number="133" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_controller/metal.rb" method="dispatch"/>
  28 + <line number="14" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_controller/metal/rack_delegation.rb" method="dispatch"/>
  29 + <line number="173" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_controller/metal.rb" method="action"/>
  30 + <line number="62" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_dispatch/routing/route_set.rb" method="call"/>
  31 + <line number="62" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_dispatch/routing/route_set.rb" method="dispatch"/>
  32 + <line number="27" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_dispatch/routing/route_set.rb" method="call"/>
  33 + <line number="148" file="[GEM_ROOT]/gems/rack-mount-0.6.9/lib/rack/mount/route_set.rb" method="call"/>
  34 + <line number="89" file="[GEM_ROOT]/gems/rack-mount-0.6.9/lib/rack/mount/code_generation.rb" method="recognize"/>
  35 + <line number="66" file="[GEM_ROOT]/gems/rack-mount-0.6.9/lib/rack/mount/code_generation.rb" method="optimized_each"/>
  36 + <line number="88" file="[GEM_ROOT]/gems/rack-mount-0.6.9/lib/rack/mount/code_generation.rb" method="recognize"/>
  37 + <line number="139" file="[GEM_ROOT]/gems/rack-mount-0.6.9/lib/rack/mount/route_set.rb" method="call"/>
  38 + <line number="489" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_dispatch/routing/route_set.rb" method="call"/>
  39 + <line number="41" file="[GEM_ROOT]/gems/haml-3.0.15/lib/sass/plugin/rack.rb" method="call"/>
  40 + <line number="14" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_dispatch/middleware/head.rb" method="call"/>
  41 + <line number="24" file="[GEM_ROOT]/gems/rack-1.2.1/lib/rack/methodoverride.rb" method="call"/>
  42 + <line number="21" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_dispatch/middleware/params_parser.rb" method="call"/>
  43 + <line number="177" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_dispatch/middleware/flash.rb" method="call"/>
  44 + <line number="149" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_dispatch/middleware/session/abstract_store.rb" method="call"/>
  45 + <line number="268" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_dispatch/middleware/cookies.rb" method="call"/>
  46 + <line number="32" file="[GEM_ROOT]/gems/activerecord-3.0.0.rc/lib/active_record/query_cache.rb" method="call"/>
  47 + <line number="28" file="[GEM_ROOT]/gems/activerecord-3.0.0.rc/lib/active_record/connection_adapters/abstract/query_cache.rb" method="cache"/>
  48 + <line number="12" file="[GEM_ROOT]/gems/activerecord-3.0.0.rc/lib/active_record/query_cache.rb" method="cache"/>
  49 + <line number="31" file="[GEM_ROOT]/gems/activerecord-3.0.0.rc/lib/active_record/query_cache.rb" method="call"/>
  50 + <line number="46" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_dispatch/middleware/callbacks.rb" method="call"/>
  51 + <line number="410" file="[GEM_ROOT]/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb" method="_run_call_callbacks"/>
  52 + <line number="44" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_dispatch/middleware/callbacks.rb" method="call"/>
  53 + <line number="107" file="[GEM_ROOT]/gems/rack-1.2.1/lib/rack/sendfile.rb" method="call"/>
  54 + <line number="48" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_dispatch/middleware/remote_ip.rb" method="call"/>
  55 + <line number="48" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_dispatch/middleware/show_exceptions.rb" method="call"/>
  56 + <line number="13" file="[GEM_ROOT]/gems/railties-3.0.0.rc/lib/rails/rack/logger.rb" method="call"/>
  57 + <line number="17" file="[GEM_ROOT]/gems/rack-1.2.1/lib/rack/runtime.rb" method="call"/>
  58 + <line number="72" file="[GEM_ROOT]/gems/activesupport-3.0.0.rc/lib/active_support/cache/strategy/local_cache.rb" method="call"/>
  59 + <line number="11" file="[GEM_ROOT]/gems/rack-1.2.1/lib/rack/lock.rb" method="call"/>
  60 + <line number="11" file="[GEM_ROOT]/gems/rack-1.2.1/lib/rack/lock.rb" method="synchronize"/>
  61 + <line number="11" file="[GEM_ROOT]/gems/rack-1.2.1/lib/rack/lock.rb" method="call"/>
  62 + <line number="30" file="[GEM_ROOT]/gems/actionpack-3.0.0.rc/lib/action_dispatch/middleware/static.rb" method="call"/>
  63 + <line number="168" file="[GEM_ROOT]/gems/railties-3.0.0.rc/lib/rails/application.rb" method="call"/>
  64 + <line number="77" file="[GEM_ROOT]/gems/railties-3.0.0.rc/lib/rails/application.rb" method="send"/>
  65 + <line number="77" file="[GEM_ROOT]/gems/railties-3.0.0.rc/lib/rails/application.rb" method="method_missing"/>
  66 + <line number="636" file="[GEM_ROOT]/gems/rake-0.8.7/lib/rake.rb" method="call"/>
  67 + <line number="636" file="[GEM_ROOT]/gems/rake-0.8.7/lib/rake.rb" method="execute"/>
  68 + <line number="631" file="[GEM_ROOT]/gems/rake-0.8.7/lib/rake.rb" method="each"/>
  69 + <line number="631" file="[GEM_ROOT]/gems/rake-0.8.7/lib/rake.rb" method="execute"/>
  70 + <line number="597" file="[GEM_ROOT]/gems/rake-0.8.7/lib/rake.rb" method="invoke_with_call_chain"/>
  71 + <line number="242" file="/Users/jdpace/.rvm/rubies/ree-1.8.7-2010.02/lib/ruby/1.8/monitor.rb" method="synchronize"/>
  72 + <line number="590" file="[GEM_ROOT]/gems/rake-0.8.7/lib/rake.rb" method="invoke_with_call_chain"/>
  73 + <line number="583" file="[GEM_ROOT]/gems/rake-0.8.7/lib/rake.rb" method="invoke"/>
  74 + <line number="2051" file="[GEM_ROOT]/gems/rake-0.8.7/lib/rake.rb" method="invoke_task"/>
  75 + <line number="2029" file="[GEM_ROOT]/gems/rake-0.8.7/lib/rake.rb" method="top_level"/>
  76 + <line number="2029" file="[GEM_ROOT]/gems/rake-0.8.7/lib/rake.rb" method="each"/>
  77 + <line number="2029" file="[GEM_ROOT]/gems/rake-0.8.7/lib/rake.rb" method="top_level"/>
  78 + <line number="2068" file="[GEM_ROOT]/gems/rake-0.8.7/lib/rake.rb" method="standard_exception_handling"/>
  79 + <line number="2023" file="[GEM_ROOT]/gems/rake-0.8.7/lib/rake.rb" method="top_level"/>
  80 + <line number="2001" file="[GEM_ROOT]/gems/rake-0.8.7/lib/rake.rb" method="run"/>
  81 + <line number="2068" file="[GEM_ROOT]/gems/rake-0.8.7/lib/rake.rb" method="standard_exception_handling"/>
  82 + <line number="1998" file="[GEM_ROOT]/gems/rake-0.8.7/lib/rake.rb" method="run"/>
  83 + <line number="31" file="[GEM_ROOT]/gems/rake-0.8.7/bin/rake" method=""/>
  84 + <line number="19" file="[GEM_ROOT]/bin/rake" method="load"/>
  85 + <line number="19" file="[GEM_ROOT]/bin/rake" method=""/>
  86 + </backtrace>
  87 + </error>
  88 + <server-environment>
  89 + <project-root>/path/to/sample/project</project-root>
  90 + <environment-name>development</environment-name>
  91 + </server-environment>
  92 +</notice>
0 93 \ No newline at end of file
... ...
spec/models/notice_spec.rb
... ... @@ -98,6 +98,11 @@ describe Notice do
98 98 @notice = Notice.from_xml(@xml)
99 99 @notice.notifier['name'].should == 'Hoptoad Notifier'
100 100 end
  101 +
  102 + it "should handle params withour 'request' section" do
  103 + @xml = Rails.root.join('spec','fixtures','hoptoad_test_notice_without_request_section.xml').read
  104 + lambda { Notice.from_xml(@xml) }.should_not raise_error
  105 + end
101 106 end
102 107  
103 108 describe "email notifications" do
... ...
spec/models/user_spec.rb
... ... @@ -38,5 +38,14 @@ describe User do
38 38 end
39 39  
40 40 end
  41 +
  42 + context "First user" do
  43 + it "should be created this admin access via db:seed" do
  44 + require 'rake'
  45 + Errbit::Application.load_tasks
  46 + Rake::Task["db:seed"].execute
  47 + User.first.admin.should be_true
  48 + end
  49 + end
41 50  
42 51 end
... ...
spec/spec_helper.rb
... ... @@ -18,8 +18,7 @@ RSpec.configure do |config|
18 18 config.alias_example_to :fit, :focused => true
19 19  
20 20 config.before(:each) do
21   - DatabaseCleaner.orm = "mongoid"
22   - DatabaseCleaner.strategy = :truncation
  21 + DatabaseCleaner[:mongoid].strategy = :truncation
23 22 DatabaseCleaner.clean
24 23 end
25 24 end
26 25 \ No newline at end of file
... ...