From 387bca94f6e617fe5e910eed032900145de4b11b Mon Sep 17 00:00:00 2001 From: Marcin Ciunelis Date: Sun, 23 Sep 2012 00:20:43 +0200 Subject: [PATCH] rename ErrsController to ProblemsController --- app/controllers/comments_controller.rb | 6 +++--- app/controllers/errs_controller.rb | 157 ------------------------------------------------------------------------------------------------------------------------------------------------------------- app/controllers/notices_controller.rb | 2 +- app/controllers/problems_controller.rb | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ app/helpers/application_helper.rb | 6 +++--- app/helpers/errs_helper.rb | 27 --------------------------- app/helpers/problems_helper.rb | 27 +++++++++++++++++++++++++++ app/views/apps/show.atom.builder | 2 +- app/views/apps/show.html.haml | 2 +- app/views/errs/_issue_tracker_links.html.haml | 15 --------------- app/views/errs/_list.atom.builder | 15 --------------- app/views/errs/_table.html.haml | 56 -------------------------------------------------------- app/views/errs/_tally_table.html.haml | 18 ------------------ app/views/errs/all.html.haml | 4 ---- app/views/errs/index.atom.builder | 4 ---- app/views/errs/index.html.haml | 6 ------ app/views/errs/show.html.haml | 83 ----------------------------------------------------------------------------------- app/views/errs/show.ics.haml | 1 - app/views/issue_trackers/fogbugz_body.txt.erb | 2 +- app/views/issue_trackers/github_issues_body.txt.erb | 2 +- app/views/issue_trackers/lighthouseapp_body.txt.erb | 2 +- app/views/issue_trackers/pivotal_body.txt.erb | 2 +- app/views/issue_trackers/textile_body.txt.erb | 2 +- app/views/mailer/err_notification.html.haml | 2 +- app/views/mailer/err_notification.text.erb | 2 +- app/views/problems/_issue_tracker_links.html.haml | 15 +++++++++++++++ app/views/problems/_list.atom.builder | 15 +++++++++++++++ app/views/problems/_table.html.haml | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ app/views/problems/_tally_table.html.haml | 18 ++++++++++++++++++ app/views/problems/all.html.haml | 4 ++++ app/views/problems/index.atom.builder | 4 ++++ app/views/problems/index.html.haml | 6 ++++++ app/views/problems/show.html.haml | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ app/views/problems/show.ics.haml | 1 + app/views/shared/_navigation.html.haml | 4 ++-- config/routes.rb | 8 ++++---- spec/controllers/comments_controller_spec.rb | 8 ++++---- spec/controllers/errs_controller_spec.rb | 441 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- spec/controllers/notices_controller_spec.rb | 2 +- spec/controllers/problems_controller_spec.rb | 441 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ spec/helpers/errs_helper_spec.rb | 35 ----------------------------------- spec/helpers/problems_helper_spec.rb | 35 +++++++++++++++++++++++++++++++++++ spec/views/errs/show.html.haml_spec.rb | 128 -------------------------------------------------------------------------------------------------------------------------------- spec/views/problems/show.html.haml_spec.rb | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 44 files changed, 1016 insertions(+), 1017 deletions(-) delete mode 100644 app/controllers/errs_controller.rb create mode 100644 app/controllers/problems_controller.rb delete mode 100644 app/helpers/errs_helper.rb create mode 100644 app/helpers/problems_helper.rb delete mode 100644 app/views/errs/_issue_tracker_links.html.haml delete mode 100644 app/views/errs/_list.atom.builder delete mode 100644 app/views/errs/_table.html.haml delete mode 100644 app/views/errs/_tally_table.html.haml delete mode 100644 app/views/errs/all.html.haml delete mode 100644 app/views/errs/index.atom.builder delete mode 100644 app/views/errs/index.html.haml delete mode 100644 app/views/errs/show.html.haml delete mode 100644 app/views/errs/show.ics.haml create mode 100644 app/views/problems/_issue_tracker_links.html.haml create mode 100644 app/views/problems/_list.atom.builder create mode 100644 app/views/problems/_table.html.haml create mode 100644 app/views/problems/_tally_table.html.haml create mode 100644 app/views/problems/all.html.haml create mode 100644 app/views/problems/index.atom.builder create mode 100644 app/views/problems/index.html.haml create mode 100644 app/views/problems/show.html.haml create mode 100644 app/views/problems/show.ics.haml delete mode 100644 spec/controllers/errs_controller_spec.rb create mode 100644 spec/controllers/problems_controller_spec.rb delete mode 100644 spec/helpers/errs_helper_spec.rb create mode 100644 spec/helpers/problems_helper_spec.rb delete mode 100644 spec/views/errs/show.html.haml_spec.rb create mode 100644 spec/views/problems/show.html.haml_spec.rb diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index fbd5447..0d36cf3 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -11,7 +11,7 @@ class CommentsController < ApplicationController else flash[:error] = "I'm sorry, your comment was blank! Try again?" end - redirect_to app_err_path(@app, @problem) + redirect_to app_problem_path(@app, @problem) end def destroy @@ -21,7 +21,7 @@ class CommentsController < ApplicationController else flash[:error] = "Sorry, I couldn't delete your comment for some reason. I hope you don't have any sensitive information in there!" end - redirect_to app_err_path(@app, @problem) + redirect_to app_problem_path(@app, @problem) end protected @@ -34,7 +34,7 @@ class CommentsController < ApplicationController end def find_problem - @problem = @app.problems.find(params[:err_id]) + @problem = @app.problems.find(params[:problem_id]) end end diff --git a/app/controllers/errs_controller.rb b/app/controllers/errs_controller.rb deleted file mode 100644 index 84c6d22..0000000 --- a/app/controllers/errs_controller.rb +++ /dev/null @@ -1,157 +0,0 @@ -class ErrsController < ApplicationController - include ActionView::Helpers::TextHelper - - before_filter :find_app, :except => [:index, :all, :destroy_several, :resolve_several, :unresolve_several, :merge_several, :unmerge_several] - before_filter :find_problem, :except => [:index, :all, :destroy_several, :resolve_several, :unresolve_several, :merge_several, :unmerge_several] - before_filter :find_selected_problems, :only => [:destroy_several, :resolve_several, :unresolve_several, :merge_several, :unmerge_several] - before_filter :set_sorting_params, :only => [:index, :all] - before_filter :set_tracker_params, :only => [:create_issue] - - def index - app_scope = current_user.admin? ? App.all : current_user.apps - - @problems = Problem.for_apps(app_scope).in_env(params[:environment]).unresolved.ordered_by(@sort, @order) - @selected_problems = params[:problems] || [] - respond_to do |format| - format.html do - @problems = @problems.page(params[:page]).per(current_user.per_page) - end - format.atom - end - end - - def all - app_scope = current_user.admin? ? App.all : current_user.apps - @problems = Problem.for_apps(app_scope).ordered_by(@sort, @order).page(params[:page]).per(current_user.per_page) - @selected_problems = params[:problems] || [] - end - - def show - @notices = @problem.notices.reverse_ordered.page(params[:notice]).per(1) - @notice = @notices.first - @comment = Comment.new - if request.headers['X-PJAX'] - params["_pjax"] = nil - render :layout => false - end - end - - def create_issue - # Create an issue on GitHub using user's github token - if params[:tracker] == 'user_github' - if !@app.github_repo? - flash[:error] = "This app doesn't have a GitHub repo set up." - elsif !current_user.github_account? - flash[:error] = "You haven't linked your Github account." - else - @tracker = GithubIssuesTracker.new( - :app => @app, - :username => current_user.github_login, - :oauth_token => current_user.github_oauth_token - ) - end - - # Or, create an issue using the App's issue tracker - elsif @app.issue_tracker_configured? - @tracker = @app.issue_tracker - - # Otherwise, display error about missing tracker configuration. - else - flash[:error] = "This app has no issue tracker setup." - end - - if flash[:error].blank? && @tracker - begin - @tracker.create_issue @problem, current_user - rescue Exception => ex - Rails.logger.error "Error during issue creation: " << ex.message - flash[:error] = "There was an error during issue creation: #{ex.message}" - end - end - - redirect_to app_err_path(@app, @problem) - end - - def unlink_issue - @problem.update_attribute :issue_link, nil - redirect_to app_err_path(@app, @problem) - end - - def resolve - @problem.resolve! - flash[:success] = 'Great news everyone! The err has been resolved.' - redirect_to :back - rescue ActionController::RedirectBackError - redirect_to app_path(@app) - end - - def resolve_several - @selected_problems.each(&:resolve!) - flash[:success] = "Great news everyone! #{pluralize(@selected_problems.count, 'err has', 'errs have')} been resolved." - redirect_to :back - end - - def unresolve_several - @selected_problems.each(&:unresolve!) - flash[:success] = "#{pluralize(@selected_problems.count, 'err has', 'errs have')} been unresolved." - redirect_to :back - end - - def merge_several - if @selected_problems.length < 2 - flash[:notice] = "You must select at least two errors to merge" - else - @merged_problem = Problem.merge!(@selected_problems) - flash[:notice] = "#{@selected_problems.count} errors have been merged." - end - redirect_to :back - end - - def unmerge_several - all = @selected_problems.map(&:unmerge!).flatten - flash[:success] = "#{pluralize(all.length, 'err has', 'errs have')} been unmerged." - redirect_to :back - end - - def destroy_several - nb_problem_destroy = ProblemDestroy.execute(@selected_problems) - flash[:notice] = "#{pluralize(nb_problem_destroy, 'err has', 'errs have')} been deleted." - redirect_to :back - end - - protected - def find_app - @app = App.find(params[:app_id]) - - # Mongoid Bug: could not chain: current_user.apps.find_by_id! - # apparently finding by 'watchers.email' and 'id' is broken - raise(Mongoid::Errors::DocumentNotFound.new(App,@app.id)) unless current_user.admin? || current_user.watching?(@app) - end - - def find_problem - @problem = @app.problems.find(params[:id]) - end - - def set_tracker_params - IssueTracker.default_url_options[:host] = request.host - IssueTracker.default_url_options[:port] = request.port - IssueTracker.default_url_options[:protocol] = request.scheme - end - - def find_selected_problems - err_ids = (params[:problems] || []).compact - if err_ids.empty? - flash[:notice] = "You have not selected any errors" - redirect_to :back - else - @selected_problems = Array(Problem.find(err_ids)) - end - end - - def set_sorting_params - @sort = params[:sort] - @sort = "last_notice_at" unless %w{app message last_notice_at last_deploy_at count}.member?(@sort) - @order = params[:order] || "desc" - end -end - diff --git a/app/controllers/notices_controller.rb b/app/controllers/notices_controller.rb index 40bef96..8b900ad 100644 --- a/app/controllers/notices_controller.rb +++ b/app/controllers/notices_controller.rb @@ -15,6 +15,6 @@ class NoticesController < ApplicationController # Redirects a notice to the problem page. Useful when using User Information at Airbrake gem. def locate problem = Notice.find(params[:id]).problem - redirect_to app_err_path(problem.app, problem) + redirect_to app_problem_path(problem.app, problem) end end diff --git a/app/controllers/problems_controller.rb b/app/controllers/problems_controller.rb new file mode 100644 index 0000000..b88d2f8 --- /dev/null +++ b/app/controllers/problems_controller.rb @@ -0,0 +1,157 @@ +class ProblemsController < ApplicationController + include ActionView::Helpers::TextHelper + + before_filter :find_app, :except => [:index, :all, :destroy_several, :resolve_several, :unresolve_several, :merge_several, :unmerge_several] + before_filter :find_problem, :except => [:index, :all, :destroy_several, :resolve_several, :unresolve_several, :merge_several, :unmerge_several] + before_filter :find_selected_problems, :only => [:destroy_several, :resolve_several, :unresolve_several, :merge_several, :unmerge_several] + before_filter :set_sorting_params, :only => [:index, :all] + before_filter :set_tracker_params, :only => [:create_issue] + + def index + app_scope = current_user.admin? ? App.all : current_user.apps + + @problems = Problem.for_apps(app_scope).in_env(params[:environment]).unresolved.ordered_by(@sort, @order) + @selected_problems = params[:problems] || [] + respond_to do |format| + format.html do + @problems = @problems.page(params[:page]).per(current_user.per_page) + end + format.atom + end + end + + def all + app_scope = current_user.admin? ? App.all : current_user.apps + @problems = Problem.for_apps(app_scope).ordered_by(@sort, @order).page(params[:page]).per(current_user.per_page) + @selected_problems = params[:problems] || [] + end + + def show + @notices = @problem.notices.reverse_ordered.page(params[:notice]).per(1) + @notice = @notices.first + @comment = Comment.new + if request.headers['X-PJAX'] + params["_pjax"] = nil + render :layout => false + end + end + + def create_issue + # Create an issue on GitHub using user's github token + if params[:tracker] == 'user_github' + if !@app.github_repo? + flash[:error] = "This app doesn't have a GitHub repo set up." + elsif !current_user.github_account? + flash[:error] = "You haven't linked your Github account." + else + @tracker = GithubIssuesTracker.new( + :app => @app, + :username => current_user.github_login, + :oauth_token => current_user.github_oauth_token + ) + end + + # Or, create an issue using the App's issue tracker + elsif @app.issue_tracker_configured? + @tracker = @app.issue_tracker + + # Otherwise, display error about missing tracker configuration. + else + flash[:error] = "This app has no issue tracker setup." + end + + if flash[:error].blank? && @tracker + begin + @tracker.create_issue @problem, current_user + rescue Exception => ex + Rails.logger.error "Error during issue creation: " << ex.message + flash[:error] = "There was an error during issue creation: #{ex.message}" + end + end + + redirect_to app_problem_path(@app, @problem) + end + + def unlink_issue + @problem.update_attribute :issue_link, nil + redirect_to app_problem_path(@app, @problem) + end + + def resolve + @problem.resolve! + flash[:success] = 'Great news everyone! The err has been resolved.' + redirect_to :back + rescue ActionController::RedirectBackError + redirect_to app_path(@app) + end + + def resolve_several + @selected_problems.each(&:resolve!) + flash[:success] = "Great news everyone! #{pluralize(@selected_problems.count, 'err has', 'errs have')} been resolved." + redirect_to :back + end + + def unresolve_several + @selected_problems.each(&:unresolve!) + flash[:success] = "#{pluralize(@selected_problems.count, 'err has', 'errs have')} been unresolved." + redirect_to :back + end + + def merge_several + if @selected_problems.length < 2 + flash[:notice] = "You must select at least two errors to merge" + else + @merged_problem = Problem.merge!(@selected_problems) + flash[:notice] = "#{@selected_problems.count} errors have been merged." + end + redirect_to :back + end + + def unmerge_several + all = @selected_problems.map(&:unmerge!).flatten + flash[:success] = "#{pluralize(all.length, 'err has', 'errs have')} been unmerged." + redirect_to :back + end + + def destroy_several + nb_problem_destroy = ProblemDestroy.execute(@selected_problems) + flash[:notice] = "#{pluralize(nb_problem_destroy, 'err has', 'errs have')} been deleted." + redirect_to :back + end + + protected + def find_app + @app = App.find(params[:app_id]) + + # Mongoid Bug: could not chain: current_user.apps.find_by_id! + # apparently finding by 'watchers.email' and 'id' is broken + raise(Mongoid::Errors::DocumentNotFound.new(App,@app.id)) unless current_user.admin? || current_user.watching?(@app) + end + + def find_problem + @problem = @app.problems.find(params[:id]) + end + + def set_tracker_params + IssueTracker.default_url_options[:host] = request.host + IssueTracker.default_url_options[:port] = request.port + IssueTracker.default_url_options[:protocol] = request.scheme + end + + def find_selected_problems + err_ids = (params[:problems] || []).compact + if err_ids.empty? + flash[:notice] = "You have not selected any errors" + redirect_to :back + else + @selected_problems = Array(Problem.find(err_ids)) + end + end + + def set_sorting_params + @sort = params[:sort] + @sort = "last_notice_at" unless %w{app message last_notice_at last_deploy_at count}.member?(@sort) + @order = params[:order] || "desc" + end +end + diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 19b9a5d..966585c 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -13,7 +13,7 @@ module ApplicationHelper event.dtend = notice.created_at.utc + 60.minutes event.organizer = notice.server_environment && notice.server_environment["hostname"] event.location = notice.server_environment && notice.server_environment["project-root"] - event.url = app_err_url(:app_id => notice.problem.app.id, :id => notice.problem) + event.url = app_problem_url(:app_id => notice.problem.app.id, :id => notice.problem) end end end.to_s @@ -58,11 +58,11 @@ module ApplicationHelper percent = 100.0 / total.to_f rows = tallies.map {|value, count| [(count.to_f * percent), value]} \ .sort {|a, b| a[0] <=> b[0]} - render "errs/tally_table", :rows => rows + render "problems/tally_table", :rows => rows end def head(collection) - collection.first(head_size) + collection.first(head_size) end def tail(collection) diff --git a/app/helpers/errs_helper.rb b/app/helpers/errs_helper.rb deleted file mode 100644 index ffdd958..0000000 --- a/app/helpers/errs_helper.rb +++ /dev/null @@ -1,27 +0,0 @@ -module ErrsHelper - def err_confirm - Errbit::Config.confirm_resolve_err === false ? nil : 'Seriously?' - end - - def truncated_err_message(problem) - unless (msg = problem.message).blank? - # Truncate & insert invisible chars so that firefox can emulate 'word-wrap: break-word' CSS rule - truncate(msg, :length => 300).scan(/.{1,5}/).map { |s| h(s) }.join("​").html_safe - end - end - - def gravatar_tag(email, options = {}) - image_tag gravatar_url(email, options), :alt => email, :class => 'gravatar' - end - - def gravatar_url(email, options = {}) - default_options = { - :d => Errbit::Config.gravatar_default, - } - options.reverse_merge! default_options - params = options.extract!(:s, :d).delete_if { |k, v| v.blank? } - email_hash = Digest::MD5.hexdigest(email) - "http://www.gravatar.com/avatar/#{email_hash}?#{params.to_query}" - end -end - diff --git a/app/helpers/problems_helper.rb b/app/helpers/problems_helper.rb new file mode 100644 index 0000000..0e0c807 --- /dev/null +++ b/app/helpers/problems_helper.rb @@ -0,0 +1,27 @@ +module ProblemsHelper + def problem_confirm + Errbit::Config.confirm_resolve_err === false ? nil : 'Seriously?' + end + + def truncated_problem_message(problem) + unless (msg = problem.message).blank? + # Truncate & insert invisible chars so that firefox can emulate 'word-wrap: break-word' CSS rule + truncate(msg, :length => 300).scan(/.{1,5}/).map { |s| h(s) }.join("​").html_safe + end + end + + def gravatar_tag(email, options = {}) + image_tag gravatar_url(email, options), :alt => email, :class => 'gravatar' + end + + def gravatar_url(email, options = {}) + default_options = { + :d => Errbit::Config.gravatar_default, + } + options.reverse_merge! default_options + params = options.extract!(:s, :d).delete_if { |k, v| v.blank? } + email_hash = Digest::MD5.hexdigest(email) + "http://www.gravatar.com/avatar/#{email_hash}?#{params.to_query}" + end +end + diff --git a/app/views/apps/show.atom.builder b/app/views/apps/show.atom.builder index fc416c1..84d3120 100644 --- a/app/views/apps/show.atom.builder +++ b/app/views/apps/show.atom.builder @@ -1,4 +1,4 @@ atom_feed do |feed| feed.title("Errbit notices for #{h @app.name} at #{root_url}") - render "errs/list", :feed => feed + render "problems/list", :feed => feed end diff --git a/app/views/apps/show.html.haml b/app/views/apps/show.html.haml index b7bf7ba..de352a2 100644 --- a/app/views/apps/show.html.haml +++ b/app/views/apps/show.html.haml @@ -83,7 +83,7 @@ - if @app.problems.any? %h3.clear Errors - = render 'errs/table', :errs => @problems + = render 'problems/table', :problems => @problems - else %h3.clear No errs have been caught yet, make sure you setup your app = render 'configuration_instructions', :app => @app diff --git a/app/views/errs/_issue_tracker_links.html.haml b/app/views/errs/_issue_tracker_links.html.haml deleted file mode 100644 index 2e36277..0000000 --- a/app/views/errs/_issue_tracker_links.html.haml +++ /dev/null @@ -1,15 +0,0 @@ -- if @app.issue_tracker_configured? || current_user.github_account? - - if @problem.issue_link.present? - %span= link_to 'go to issue', @problem.issue_link, :class => "#{@problem.issue_type}_goto goto-issue" - = link_to 'unlink issue', unlink_issue_app_err_path(@app, @problem), :method => :delete, :data => { :confirm => "Unlink err issues?" }, :class => "unlink-issue" - - elsif @problem.issue_link == "pending" - %span.disabled= link_to 'creating...', '#', :class => "#{@problem.issue_type}_inactive create-issue" - = link_to 'retry', create_issue_app_err_path(@app, @problem), :method => :post - - else - - if @app.github_repo? - - if current_user.can_create_github_issues? - %span= link_to 'create issue', create_issue_app_err_path(@app, @problem, :tracker => 'user_github'), :method => :post, :class => "github_create create-issue" - - elsif @app.issue_tracker_configured? && @app.issue_tracker.is_a?(GithubIssuesTracker) - %span= link_to 'create issue', create_issue_app_err_path(@app, @problem), :method => :post, :class => "github_create create-issue" - - if @app.issue_tracker_configured? && !@app.issue_tracker.is_a?(GithubIssuesTracker) - %span= link_to 'create issue', create_issue_app_err_path(@app, @problem), :method => :post, :class => "#{@app.issue_tracker.label}_create create-issue" diff --git a/app/views/errs/_list.atom.builder b/app/views/errs/_list.atom.builder deleted file mode 100644 index 36197b7..0000000 --- a/app/views/errs/_list.atom.builder +++ /dev/null @@ -1,15 +0,0 @@ -feed.updated(@problems.first.try(:created_at) || Time.now) - -for problem in @problems - notice = problem.notices.first - - feed.entry(problem, :url => app_err_url(problem.app, problem)) do |entry| - entry.title "[#{ problem.where }] #{problem.message.to_s.truncate(27)}" - entry.author do |author| - author.name "#{ problem.app.name } [#{ problem.environment }]" - end - if notice - entry.summary(notice_atom_summary(notice), :type => "html") - end - end -end diff --git a/app/views/errs/_table.html.haml b/app/views/errs/_table.html.haml deleted file mode 100644 index d2d2c96..0000000 --- a/app/views/errs/_table.html.haml +++ /dev/null @@ -1,56 +0,0 @@ -- any_issue_links = errs.any?{|e| e.issue_link.present? && e.issue_link != 'pending' } -=form_tag do - %table.errs.selectable - %thead - %tr - %th= check_box_tag "toggle_problems_checkboxes" - %th= link_for_sort "App" - %th= link_for_sort "What & Where".html_safe, "message" - %th= link_for_sort "Latest", "last_notice_at" - %th= link_for_sort "Deploy", "last_deploy_at" - %th= link_for_sort "Count" - - if any_issue_links - %th Issue - %th Resolve - %tbody - - errs.each do |problem| - %tr{:class => problem.resolved? ? 'resolved' : 'unresolved'} - %td.select - = check_box_tag "problems[]", problem.id, @selected_problems.member?(problem.id.to_s) - %td.app - = link_to problem.app.name, app_path(problem.app) - - if current_page?(:controller => 'errs') - %span.environment= link_to problem.environment, errs_path(:environment => problem.environment) - - else - %span.environment= link_to problem.environment, app_path(problem.app, :environment => problem.environment) - %td.message - = link_to truncated_err_message(problem), app_err_path(problem.app, problem) - %em= problem.where - - if problem.comments_count > 0 - - comment = problem.comments.last - %br - .inline_comment - - if comment.user - %em.commenter= (Errbit::Config.user_has_username ? comment.user.username : comment.user.email).to_s << ":" - %em= truncate(comment.body, :length => 100, :separator => ' ') - %td.latest #{time_ago_in_words(problem.last_notice_at)} ago - %td.deploy= problem.last_deploy_at ? problem.last_deploy_at.to_s(:micro) : 'n/a' - %td.count= link_to problem.notices_count, app_err_path(problem.app, problem) - - if any_issue_links - %td.issue_link - - if problem.app.issue_tracker_configured? && problem.issue_link.present? && problem.issue_link != 'pending' - = link_to image_tag("#{problem.issue_type}_goto.png"), problem.issue_link, :target => "_blank" - %td.resolve= link_to image_tag("thumbs-up.png"), resolve_app_err_path(problem.app, problem), :title => "Resolve", :method => :put, :data => { :confirm => err_confirm }, :class => 'resolve' if problem.unresolved? - - if errs.none? - %tr - %td{:colspan => (any_issue_links ? 8 : 7)} - %em No errs here - = paginate errs - .tab-bar - %ul - %li= submit_tag 'Merge', :id => 'merge_errs', :class => 'button', 'data-action' => merge_several_errs_path - %li= submit_tag 'Unmerge', :id => 'unmerge_errs', :class => 'button', 'data-action' => unmerge_several_errs_path - %li= submit_tag 'Resolve', :id => 'resolve_errs', :class => 'button', 'data-action' => resolve_several_errs_path - %li= submit_tag 'Unresolve', :id => 'unresolve_errs', :class => 'button', 'data-action' => unresolve_several_errs_path - %li= submit_tag 'Delete', :id => 'delete_errs', :class => 'button', 'data-action' => destroy_several_errs_path - diff --git a/app/views/errs/_tally_table.html.haml b/app/views/errs/_tally_table.html.haml deleted file mode 100644 index bd03ede..0000000 --- a/app/views/errs/_tally_table.html.haml +++ /dev/null @@ -1,18 +0,0 @@ -.head_and_tail - %table.tally.head - %tbody - - head(rows).each do |row| - %tr - %td.percent= number_to_percentage(row[0], :precision => 1) - %th.value= row[1] - - if rows.size > head_size - %tfoot - %tr - %td{:colspan => 2} - = link_to 'Show more...', '#', :class => :show_tail - %table.tally.tail{:style => "display: none"} - %tbody - - tail(rows).each do |row| - %tr - %td.percent= number_to_percentage(row[0], :precision => 1) - %th.value= row[1] diff --git a/app/views/errs/all.html.haml b/app/views/errs/all.html.haml deleted file mode 100644 index de9a42f..0000000 --- a/app/views/errs/all.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -- content_for :title, 'All Errors' -- content_for :action_bar do - = link_to 'hide resolved', errs_path, :class => 'button' -= render 'table', :errs => @problems diff --git a/app/views/errs/index.atom.builder b/app/views/errs/index.atom.builder deleted file mode 100644 index 55df01c..0000000 --- a/app/views/errs/index.atom.builder +++ /dev/null @@ -1,4 +0,0 @@ -atom_feed do |feed| - feed.title("Errbit notices at #{root_url}") - render "errs/list", :feed => feed -end diff --git a/app/views/errs/index.html.haml b/app/views/errs/index.html.haml deleted file mode 100644 index d265f14..0000000 --- a/app/views/errs/index.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -- content_for :title, 'Unresolved Errors' -- content_for :head do - = auto_discovery_link_tag :atom, errs_path(User.token_authentication_key => current_user.authentication_token, :format => "atom"), :title => "Errbit notices at #{request.host}" -- content_for :action_bar do - = link_to 'show resolved', all_errs_path, :class => 'button' -= render 'table', :errs => @problems diff --git a/app/views/errs/show.html.haml b/app/views/errs/show.html.haml deleted file mode 100644 index 511d4e0..0000000 --- a/app/views/errs/show.html.haml +++ /dev/null @@ -1,83 +0,0 @@ -- content_for :page_title, @problem.message -- content_for :title_css_class, 'err_show' -- content_for :title, @problem.error_class || truncate(@problem.message, :length => 32) -- content_for :meta do - %strong App: - = link_to @app.name, app_path(@app) - %strong Where: - = @problem.where - %br - %strong Environment: - = @problem.environment - %strong Last Notice: - = @problem.last_notice_at.to_s(:precise) -- content_for :action_bar do - - if @problem.unresolved? - %span= link_to 'resolve', resolve_app_err_path(@app, @problem), :method => :put, :data => { :confirm => err_confirm }, :class => 'resolve' - - if current_user.authentication_token - %span= link_to 'iCal', app_err_path(:app_id => @app.id, :id => @problem.id, :format => "ics", :auth_token => current_user.authentication_token), :class => "calendar_link" - %span>= link_to 'up', (request.env['HTTP_REFERER'] ? :back : app_errs_path(@app)), :class => 'up' - %br - = render "issue_tracker_links" - -- if Errbit::Config.allow_comments_with_issue_tracker || !@app.issue_tracker_configured? || @problem.comments.any? - - content_for :comments do - %h3 Comments - - @problem.comments.each do |comment| - .window - %table.comment - %tr - %th - - if Errbit::Config.use_gravatar - = gravatar_tag comment.user.email, :s => 24 - %span.comment-info - = time_ago_in_words(comment.created_at, true) << " ago by " - = link_to comment.user.email, user_path(comment.user) - %span.delete= link_to '✘'.html_safe, app_err_comment_path(@app, @problem, comment), :method => :delete, :data => { :confirm => "Are sure you don't need this comment?" }, :class => "destroy-comment" - %tr - %td= comment.body.gsub("\n", "
").html_safe - - if Errbit::Config.allow_comments_with_issue_tracker || !@app.issue_tracker_configured? - = form_for @comment, :url => app_err_comments_path(@app, @problem) do |comment_form| - %p Add a comment - = comment_form.text_area :body, :style => "width: 420px; height: 80px;" - = comment_form.submit "Save Comment" - -%h4= @notice.try(:message) - -= paginate @notices, :param_name => :notice, :theme => :notices - -.tab-bar - %ul - %li= link_to 'Summary', '#summary', :rel => 'summary', :class => 'button' - %li= link_to 'Backtrace', '#backtrace', :rel => 'backtrace', :class => 'button' - - if @notice && @notice.user_attributes.present? - %li= link_to 'User Details', '#user_attributes', :rel => 'user_attributes', :class => 'button' - %li= link_to 'Environment', '#environment', :rel => 'environment', :class => 'button' - %li= link_to 'Parameters', '#params', :rel => 'params', :class => 'button' - %li= link_to 'Session', '#session', :rel => 'session', :class => 'button' - -- if @notice - #summary - %h3 Summary - = render 'notices/summary', :notice => @notice, :problem => @problem - - #backtrace - %h3 Backtrace - = render 'notices/backtrace', :lines => @notice.backtrace - - - if @notice.user_attributes.present? - #user_attributes - %h3 User Details - = render 'notices/user_attributes', :user => @notice.user_attributes - - #environment - %h3 Environment - = render 'notices/environment', :notice => @notice - - #params - %h3 Parameters - = render 'notices/params', :notice => @notice - - #session - %h3 Session - = render 'notices/session', :notice => @notice diff --git a/app/views/errs/show.ics.haml b/app/views/errs/show.ics.haml deleted file mode 100644 index 913dbf4..0000000 --- a/app/views/errs/show.ics.haml +++ /dev/null @@ -1 +0,0 @@ -= generate_problem_ical(@problem.notices.order_by(:created_at.asc)) diff --git a/app/views/issue_trackers/fogbugz_body.txt.erb b/app/views/issue_trackers/fogbugz_body.txt.erb index 85a5364..56195b9 100644 --- a/app/views/issue_trackers/fogbugz_body.txt.erb +++ b/app/views/issue_trackers/fogbugz_body.txt.erb @@ -1,4 +1,4 @@ -"See this exception on Errbit": <%= app_err_url(problem.app, problem) %> +"See this exception on Errbit": <%= app_problem_url(problem.app, problem) %> <% if notice = problem.notices.first %> <%= notice.message %> diff --git a/app/views/issue_trackers/github_issues_body.txt.erb b/app/views/issue_trackers/github_issues_body.txt.erb index 7ac9514..b0edcd5 100644 --- a/app/views/issue_trackers/github_issues_body.txt.erb +++ b/app/views/issue_trackers/github_issues_body.txt.erb @@ -1,4 +1,4 @@ -[See this exception on Errbit](<%= app_err_url problem.app, problem %> "See this exception on Errbit") +[See this exception on Errbit](<%= app_problem_url problem.app, problem %> "See this exception on Errbit") <% if notice = problem.notices.first %> # <%= notice.message %> # ## Summary ## diff --git a/app/views/issue_trackers/lighthouseapp_body.txt.erb b/app/views/issue_trackers/lighthouseapp_body.txt.erb index 713711e..612047c 100644 --- a/app/views/issue_trackers/lighthouseapp_body.txt.erb +++ b/app/views/issue_trackers/lighthouseapp_body.txt.erb @@ -1,4 +1,4 @@ -[See this exception on Errbit](<%= app_err_url problem.app, problem %> "See this exception on Errbit") +[See this exception on Errbit](<%= app_problem_url problem.app, problem %> "See this exception on Errbit") <% if notice = problem.notices.first %> # <%= notice.message %> # ## Summary ## diff --git a/app/views/issue_trackers/pivotal_body.txt.erb b/app/views/issue_trackers/pivotal_body.txt.erb index 5c9e6bd..b2fadc5 100644 --- a/app/views/issue_trackers/pivotal_body.txt.erb +++ b/app/views/issue_trackers/pivotal_body.txt.erb @@ -1,4 +1,4 @@ -See this exception on Errbit: <%= app_err_url problem.app, problem %> +See this exception on Errbit: <%= app_problem_url problem.app, problem %> <% if notice = problem.notices.first %> <% if notice.request['url'].present? %>URL: <%= notice.request['url'] %><% end %> Where: <%= notice.where %> diff --git a/app/views/issue_trackers/textile_body.txt.erb b/app/views/issue_trackers/textile_body.txt.erb index 82bd6fa..c65d886 100644 --- a/app/views/issue_trackers/textile_body.txt.erb +++ b/app/views/issue_trackers/textile_body.txt.erb @@ -1,7 +1,7 @@ <% if notice = problem.notices.first %> h1. <%= notice.message %> -h3. "See this exception on Errbit":<%= app_err_url problem.app, problem %> +h3. "See this exception on Errbit":<%= app_problem_url problem.app, problem %> h2. Summary <% if notice.request['url'].present? %> diff --git a/app/views/mailer/err_notification.html.haml b/app/views/mailer/err_notification.html.haml index ea0103b..9884876 100644 --- a/app/views/mailer/err_notification.html.haml +++ b/app/views/mailer/err_notification.html.haml @@ -14,7 +14,7 @@ %br This err has occurred #{pluralize @notice.problem.notices_count, 'time'}. %p - = link_to("Click here to view the error on Errbit", app_err_url(@app, @notice.problem), :class => "bold") << "." + = link_to("Click here to view the error on Errbit", app_problem_url(@app, @notice.problem), :class => "bold") << "." %tr %td.section %table(cellpadding="0" cellspacing="0" border="0" align="left") diff --git a/app/views/mailer/err_notification.text.erb b/app/views/mailer/err_notification.text.erb index 33add18..22acf3e 100644 --- a/app/views/mailer/err_notification.text.erb +++ b/app/views/mailer/err_notification.text.erb @@ -2,7 +2,7 @@ An err has just occurred in <%= @notice.environment_name %>: <%= raw(@notice.mes This err has occurred <%= pluralize @notice.problem.notices_count, 'time' %>. You should really look into it here: - <%= app_err_url(@app, @notice.problem) %> + <%= app_problem_url(@app, @notice.problem) %> ERROR MESSAGE: diff --git a/app/views/problems/_issue_tracker_links.html.haml b/app/views/problems/_issue_tracker_links.html.haml new file mode 100644 index 0000000..1f85327 --- /dev/null +++ b/app/views/problems/_issue_tracker_links.html.haml @@ -0,0 +1,15 @@ +- if @app.issue_tracker_configured? || current_user.github_account? + - if @problem.issue_link.present? + %span= link_to 'go to issue', @problem.issue_link, :class => "#{@problem.issue_type}_goto goto-issue" + = link_to 'unlink issue', unlink_issue_app_problem_path(@app, @problem), :method => :delete, :data => { :confirm => "Unlink err issues?" }, :class => "unlink-issue" + - elsif @problem.issue_link == "pending" + %span.disabled= link_to 'creating...', '#', :class => "#{@problem.issue_type}_inactive create-issue" + = link_to 'retry', create_issue_app_problem_path(@app, @problem), :method => :post + - else + - if @app.github_repo? + - if current_user.can_create_github_issues? + %span= link_to 'create issue', create_issue_app_problem_path(@app, @problem, :tracker => 'user_github'), :method => :post, :class => "github_create create-issue" + - elsif @app.issue_tracker_configured? && @app.issue_tracker.is_a?(GithubIssuesTracker) + %span= link_to 'create issue', create_issue_app_problem_path(@app, @problem), :method => :post, :class => "github_create create-issue" + - if @app.issue_tracker_configured? && !@app.issue_tracker.is_a?(GithubIssuesTracker) + %span= link_to 'create issue', create_issue_app_problem_path(@app, @problem), :method => :post, :class => "#{@app.issue_tracker.label}_create create-issue" diff --git a/app/views/problems/_list.atom.builder b/app/views/problems/_list.atom.builder new file mode 100644 index 0000000..4201144 --- /dev/null +++ b/app/views/problems/_list.atom.builder @@ -0,0 +1,15 @@ +feed.updated(@problems.first.try(:created_at) || Time.now) + +for problem in @problems + notice = problem.notices.first + + feed.entry(problem, :url => app_problem_url(problem.app, problem)) do |entry| + entry.title "[#{ problem.where }] #{problem.message.to_s.truncate(27)}" + entry.author do |author| + author.name "#{ problem.app.name } [#{ problem.environment }]" + end + if notice + entry.summary(notice_atom_summary(notice), :type => "html") + end + end +end diff --git a/app/views/problems/_table.html.haml b/app/views/problems/_table.html.haml new file mode 100644 index 0000000..2de89bf --- /dev/null +++ b/app/views/problems/_table.html.haml @@ -0,0 +1,56 @@ +- any_issue_links = problems.any?{|e| e.issue_link.present? && e.issue_link != 'pending' } +=form_tag do + %table.errs.selectable + %thead + %tr + %th= check_box_tag "toggle_problems_checkboxes" + %th= link_for_sort "App" + %th= link_for_sort "What & Where".html_safe, "message" + %th= link_for_sort "Latest", "last_notice_at" + %th= link_for_sort "Deploy", "last_deploy_at" + %th= link_for_sort "Count" + - if any_issue_links + %th Issue + %th Resolve + %tbody + - problems.each do |problem| + %tr{:class => problem.resolved? ? 'resolved' : 'unresolved'} + %td.select + = check_box_tag "problems[]", problem.id, @selected_problems.member?(problem.id.to_s) + %td.app + = link_to problem.app.name, app_path(problem.app) + - if current_page?(:controller => 'problems') + %span.environment= link_to problem.environment, problems_path(:environment => problem.environment) + - else + %span.environment= link_to problem.environment, app_path(problem.app, :environment => problem.environment) + %td.message + = link_to truncated_problem_message(problem), app_problem_path(problem.app, problem) + %em= problem.where + - if problem.comments_count > 0 + - comment = problem.comments.last + %br + .inline_comment + - if comment.user + %em.commenter= (Errbit::Config.user_has_username ? comment.user.username : comment.user.email).to_s << ":" + %em= truncate(comment.body, :length => 100, :separator => ' ') + %td.latest #{time_ago_in_words(problem.last_notice_at)} ago + %td.deploy= problem.last_deploy_at ? problem.last_deploy_at.to_s(:micro) : 'n/a' + %td.count= link_to problem.notices_count, app_problem_path(problem.app, problem) + - if any_issue_links + %td.issue_link + - if problem.app.issue_tracker_configured? && problem.issue_link.present? && problem.issue_link != 'pending' + = link_to image_tag("#{problem.issue_type}_goto.png"), problem.issue_link, :target => "_blank" + %td.resolve= link_to image_tag("thumbs-up.png"), resolve_app_problem_path(problem.app, problem), :title => "Resolve", :method => :put, :data => { :confirm => problem_confirm }, :class => 'resolve' if problem.unresolved? + - if problems.none? + %tr + %td{:colspan => (any_issue_links ? 8 : 7)} + %em No errs here + = paginate problems + .tab-bar + %ul + %li= submit_tag 'Merge', :id => 'merge_problems', :class => 'button', 'data-action' => merge_several_problems_path + %li= submit_tag 'Unmerge', :id => 'unmerge_problems', :class => 'button', 'data-action' => unmerge_several_problems_path + %li= submit_tag 'Resolve', :id => 'resolve_problems', :class => 'button', 'data-action' => resolve_several_problems_path + %li= submit_tag 'Unresolve', :id => 'unresolve_problems', :class => 'button', 'data-action' => unresolve_several_problems_path + %li= submit_tag 'Delete', :id => 'delete_problems', :class => 'button', 'data-action' => destroy_several_problems_path + diff --git a/app/views/problems/_tally_table.html.haml b/app/views/problems/_tally_table.html.haml new file mode 100644 index 0000000..bd03ede --- /dev/null +++ b/app/views/problems/_tally_table.html.haml @@ -0,0 +1,18 @@ +.head_and_tail + %table.tally.head + %tbody + - head(rows).each do |row| + %tr + %td.percent= number_to_percentage(row[0], :precision => 1) + %th.value= row[1] + - if rows.size > head_size + %tfoot + %tr + %td{:colspan => 2} + = link_to 'Show more...', '#', :class => :show_tail + %table.tally.tail{:style => "display: none"} + %tbody + - tail(rows).each do |row| + %tr + %td.percent= number_to_percentage(row[0], :precision => 1) + %th.value= row[1] diff --git a/app/views/problems/all.html.haml b/app/views/problems/all.html.haml new file mode 100644 index 0000000..3f6159e --- /dev/null +++ b/app/views/problems/all.html.haml @@ -0,0 +1,4 @@ +- content_for :title, 'All Errors' +- content_for :action_bar do + = link_to 'hide resolved', problems_path, :class => 'button' += render 'table', :problems => @problems diff --git a/app/views/problems/index.atom.builder b/app/views/problems/index.atom.builder new file mode 100644 index 0000000..aa0710b --- /dev/null +++ b/app/views/problems/index.atom.builder @@ -0,0 +1,4 @@ +atom_feed do |feed| + feed.title("Errbit notices at #{root_url}") + render "problems/list", :feed => feed +end diff --git a/app/views/problems/index.html.haml b/app/views/problems/index.html.haml new file mode 100644 index 0000000..74267b8 --- /dev/null +++ b/app/views/problems/index.html.haml @@ -0,0 +1,6 @@ +- content_for :title, 'Unresolved Errors' +- content_for :head do + = auto_discovery_link_tag :atom, problems_path(User.token_authentication_key => current_user.authentication_token, :format => "atom"), :title => "Errbit notices at #{request.host}" +- content_for :action_bar do + = link_to 'show resolved', all_problems_path, :class => 'button' += render 'table', :problems => @problems diff --git a/app/views/problems/show.html.haml b/app/views/problems/show.html.haml new file mode 100644 index 0000000..596964d --- /dev/null +++ b/app/views/problems/show.html.haml @@ -0,0 +1,83 @@ +- content_for :page_title, @problem.message +- content_for :title_css_class, 'err_show' +- content_for :title, @problem.error_class || truncate(@problem.message, :length => 32) +- content_for :meta do + %strong App: + = link_to @app.name, app_path(@app) + %strong Where: + = @problem.where + %br + %strong Environment: + = @problem.environment + %strong Last Notice: + = @problem.last_notice_at.to_s(:precise) +- content_for :action_bar do + - if @problem.unresolved? + %span= link_to 'resolve', resolve_app_problem_path(@app, @problem), :method => :put, :data => { :confirm => problem_confirm }, :class => 'resolve' + - if current_user.authentication_token + %span= link_to 'iCal', app_problem_path(:app_id => @app.id, :id => @problem.id, :format => "ics", :auth_token => current_user.authentication_token), :class => "calendar_link" + %span>= link_to 'up', (request.env['HTTP_REFERER'] ? :back : app_problems_path(@app)), :class => 'up' + %br + = render "issue_tracker_links" + +- if Errbit::Config.allow_comments_with_issue_tracker || !@app.issue_tracker_configured? || @problem.comments.any? + - content_for :comments do + %h3 Comments + - @problem.comments.each do |comment| + .window + %table.comment + %tr + %th + - if Errbit::Config.use_gravatar + = gravatar_tag comment.user.email, :s => 24 + %span.comment-info + = time_ago_in_words(comment.created_at, true) << " ago by " + = link_to comment.user.email, user_path(comment.user) + %span.delete= link_to '✘'.html_safe, app_problem_comment_path(@app, @problem, comment), :method => :delete, :data => { :confirm => "Are sure you don't need this comment?" }, :class => "destroy-comment" + %tr + %td= comment.body.gsub("\n", "
").html_safe + - if Errbit::Config.allow_comments_with_issue_tracker || !@app.issue_tracker_configured? + = form_for @comment, :url => app_problem_comments_path(@app, @problem) do |comment_form| + %p Add a comment + = comment_form.text_area :body, :style => "width: 420px; height: 80px;" + = comment_form.submit "Save Comment" + +%h4= @notice.try(:message) + += paginate @notices, :param_name => :notice, :theme => :notices + +.tab-bar + %ul + %li= link_to 'Summary', '#summary', :rel => 'summary', :class => 'button' + %li= link_to 'Backtrace', '#backtrace', :rel => 'backtrace', :class => 'button' + - if @notice && @notice.user_attributes.present? + %li= link_to 'User Details', '#user_attributes', :rel => 'user_attributes', :class => 'button' + %li= link_to 'Environment', '#environment', :rel => 'environment', :class => 'button' + %li= link_to 'Parameters', '#params', :rel => 'params', :class => 'button' + %li= link_to 'Session', '#session', :rel => 'session', :class => 'button' + +- if @notice + #summary + %h3 Summary + = render 'notices/summary', :notice => @notice, :problem => @problem + + #backtrace + %h3 Backtrace + = render 'notices/backtrace', :lines => @notice.backtrace + + - if @notice.user_attributes.present? + #user_attributes + %h3 User Details + = render 'notices/user_attributes', :user => @notice.user_attributes + + #environment + %h3 Environment + = render 'notices/environment', :notice => @notice + + #params + %h3 Parameters + = render 'notices/params', :notice => @notice + + #session + %h3 Session + = render 'notices/session', :notice => @notice diff --git a/app/views/problems/show.ics.haml b/app/views/problems/show.ics.haml new file mode 100644 index 0000000..913dbf4 --- /dev/null +++ b/app/views/problems/show.ics.haml @@ -0,0 +1 @@ += generate_problem_ical(@problem.notices.order_by(:created_at.asc)) diff --git a/app/views/shared/_navigation.html.haml b/app/views/shared/_navigation.html.haml index 518f412..9e036a5 100644 --- a/app/views/shared/_navigation.html.haml +++ b/app/views/shared/_navigation.html.haml @@ -2,7 +2,7 @@ %ul //%li= link_to 'Dashboard', admin_dashboard_path, :class => active_if_here(:dashboards) %li.apps{:class => active_if_here(:apps)}= link_to 'Apps', apps_path - %li.errs{:class => active_if_here(:errs)}= link_to 'Errors', errs_path + %li.errs{:class => active_if_here(:problems)}= link_to 'Errors', problems_path - if user_signed_in? && current_user.admin? %li.users{:class => active_if_here(:users)}= link_to 'Users', users_path - %div.clear \ No newline at end of file + %div.clear diff --git a/config/routes.rb b/config/routes.rb index fbdc652..5ff11a4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -14,7 +14,7 @@ Errbit::Application.routes.draw do delete :unlink_github end end - resources :errs, :only => [:index] do + resources :problems, :only => [:index] do collection do post :destroy_several post :resolve_several @@ -26,7 +26,7 @@ Errbit::Application.routes.draw do end resources :apps do - resources :errs do + resources :problems do resources :notices resources :comments, :only => [:create, :destroy] @@ -37,7 +37,7 @@ Errbit::Application.routes.draw do delete :unlink_issue end end - + resources :deploys, :only => [:index] end @@ -46,7 +46,7 @@ Errbit::Application.routes.draw do resources :problems, :only => [:index], :defaults => { :format => 'json' } resources :notices, :only => [:index], :defaults => { :format => 'json' } end - end + end root :to => 'apps#index' diff --git a/spec/controllers/comments_controller_spec.rb b/spec/controllers/comments_controller_spec.rb index 12a6cee..b1c74d7 100644 --- a/spec/controllers/comments_controller_spec.rb +++ b/spec/controllers/comments_controller_spec.rb @@ -16,7 +16,7 @@ describe CommentsController do let(:user) { Fabricate(:user) } before(:each) do - post :create, :app_id => problem.app.id, :err_id => problem.id, + post :create, :app_id => problem.app.id, :problem_id => problem.id, :comment => { :body => "One test comment", :user_id => user.id } problem.reload end @@ -26,7 +26,7 @@ describe CommentsController do end it "should redirect to problem page" do - response.should redirect_to( app_err_path(problem.app, problem) ) + response.should redirect_to( app_problem_path(problem.app, problem) ) end end end @@ -43,7 +43,7 @@ describe CommentsController do let(:comment) { problem.reload.comments.first } before(:each) do - delete :destroy, :app_id => problem.app.id, :err_id => problem.id, :id => comment.id.to_s + delete :destroy, :app_id => problem.app.id, :problem_id => problem.id, :id => comment.id.to_s problem.reload end @@ -52,7 +52,7 @@ describe CommentsController do end it "should redirect to problem page" do - response.should redirect_to( app_err_path(problem.app, problem) ) + response.should redirect_to( app_problem_path(problem.app, problem) ) end end end diff --git a/spec/controllers/errs_controller_spec.rb b/spec/controllers/errs_controller_spec.rb deleted file mode 100644 index 33a8136..0000000 --- a/spec/controllers/errs_controller_spec.rb +++ /dev/null @@ -1,441 +0,0 @@ -require 'spec_helper' - -describe ErrsController do - - it_requires_authentication :for => { - :index => :get, :all => :get, :show => :get, :resolve => :put - }, - :params => {:app_id => 'dummyid', :id => 'dummyid'} - - let(:app) { Fabricate(:app) } - let(:err) { Fabricate(:err, :problem => Fabricate(:problem, :app => app, :environment => "production")) } - - - describe "GET /errs" do - render_views - context 'when logged in as an admin' do - before(:each) do - @user = Fabricate(:admin) - sign_in @user - @problem = Fabricate(:notice, :err => Fabricate(:err, :problem => Fabricate(:problem, :app => app, :environment => "production"))).problem - end - - it "should successfully list errs" do - get :index - response.should be_success - response.body.gsub("​", "").should match(@problem.message) - end - - it "should list atom feed successfully" do - get :index, :format => "atom" - response.should be_success - response.body.should match(@problem.message) - end - - context "pagination" do - before(:each) do - 35.times { Fabricate :err } - end - - it "should have default per_page value for user" do - get :index - assigns(:problems).to_a.size.should == User::PER_PAGE - end - - it "should be able to override default per_page value" do - @user.update_attribute :per_page, 10 - get :index - assigns(:problems).to_a.size.should == 10 - end - end - - context 'with environment filters' do - before(:each) do - environments = ['production', 'test', 'development', 'staging'] - 20.times do |i| - Fabricate(:problem, :environment => environments[i % environments.length]) - end - end - - context 'no params' do - it 'shows errs for all environments' do - get :index - assigns(:problems).size.should == 21 - end - end - - context 'environment production' do - it 'shows errs for just production' do - get :index, :environment => 'production' - assigns(:problems).size.should == 6 - end - end - - context 'environment staging' do - it 'shows errs for just staging' do - get :index, :environment => 'staging' - assigns(:problems).size.should == 5 - end - end - - context 'environment development' do - it 'shows errs for just development' do - get :index, :environment => 'development' - assigns(:problems).size.should == 5 - end - end - - context 'environment test' do - it 'shows errs for just test' do - get :index, :environment => 'test' - assigns(:problems).size.should == 5 - end - end - end - end - - context 'when logged in as a user' do - it 'gets a paginated list of unresolved errs for the users apps' do - sign_in(user = Fabricate(:user)) - unwatched_err = Fabricate(:err) - watched_unresolved_err = Fabricate(:err, :problem => Fabricate(:problem, :app => Fabricate(:user_watcher, :user => user).app, :resolved => false)) - watched_resolved_err = Fabricate(:err, :problem => Fabricate(:problem, :app => Fabricate(:user_watcher, :user => user).app, :resolved => true)) - get :index - assigns(:problems).should include(watched_unresolved_err.problem) - assigns(:problems).should_not include(unwatched_err.problem, watched_resolved_err.problem) - end - end - end - - describe "GET /errs/all" do - context 'when logged in as an admin' do - it "gets a paginated list of all errs" do - sign_in Fabricate(:admin) - errs = Kaminari.paginate_array((1..30).to_a) - 3.times { errs << Fabricate(:err).problem } - 3.times { errs << Fabricate(:err, :problem => Fabricate(:problem, :resolved => true)).problem } - Problem.should_receive(:ordered_by).and_return( - mock('proxy', :page => mock('other_proxy', :per => errs)) - ) - get :all - assigns(:problems).should == errs - end - end - - context 'when logged in as a user' do - it 'gets a paginated list of all errs for the users apps' do - sign_in(user = Fabricate(:user)) - unwatched_err = Fabricate(:problem) - watched_unresolved_err = Fabricate(:problem, :app => Fabricate(:user_watcher, :user => user).app, :resolved => false) - watched_resolved_err = Fabricate(:problem, :app => Fabricate(:user_watcher, :user => user).app, :resolved => true) - get :all - assigns(:problems).should include(watched_resolved_err, watched_unresolved_err) - assigns(:problems).should_not include(unwatched_err) - end - end - end - - describe "GET /apps/:app_id/errs/:id" do - render_views - - context 'when logged in as an admin' do - before do - sign_in Fabricate(:admin) - end - - it "finds the app" do - get :show, :app_id => app.id, :id => err.problem.id - assigns(:app).should == app - end - - it "finds the err" do - get :show, :app_id => app.id, :id => err.problem.id - assigns(:problem).should == err.problem - end - - it "successfully render page" do - get :show, :app_id => app.id, :id => err.problem.id - response.should be_success - end - - context 'pagination' do - let!(:notices) do - 3.times.reduce([]) do |coll, i| - coll << Fabricate(:notice, :err => err, :created_at => (Time.now + i)) - end - end - - it "paginates the notices 1 at a time, starting with the most recent" do - get :show, :app_id => app.id, :id => err.problem.id - assigns(:notices).entries.count.should == 1 - assigns(:notices).should include(notices.last) - end - - it "paginates the notices 1 at a time, based on then notice param" do - get :show, :app_id => app.id, :id => err.problem.id, :notice => 3 - assigns(:notices).entries.count.should == 1 - assigns(:notices).should include(notices.first) - end - end - - context "create issue button" do - let(:button_matcher) { match(/create issue/) } - - it "should not exist for err's app without issue tracker" do - err = Fabricate :err - get :show, :app_id => err.app.id, :id => err.problem.id - - response.body.should_not button_matcher - end - - it "should exist for err's app with issue tracker" do - tracker = Fabricate(:lighthouse_tracker) - err = Fabricate(:err, :problem => Fabricate(:problem, :app => tracker.app)) - get :show, :app_id => err.app.id, :id => err.problem.id - - response.body.should button_matcher - end - - it "should not exist for err with issue_link" do - tracker = Fabricate(:lighthouse_tracker) - err = Fabricate(:err, :problem => Fabricate(:problem, :app => tracker.app, :issue_link => "http://some.host")) - get :show, :app_id => err.app.id, :id => err.problem.id - - response.body.should_not button_matcher - end - end - end - - context 'when logged in as a user' do - before do - sign_in(@user = Fabricate(:user)) - @unwatched_err = Fabricate(:err) - @watched_app = Fabricate(:app) - @watcher = Fabricate(:user_watcher, :user => @user, :app => @watched_app) - @watched_err = Fabricate(:err, :problem => Fabricate(:problem, :app => @watched_app)) - end - - it 'finds the err if the user is watching the app' do - get :show, :app_id => @watched_app.to_param, :id => @watched_err.problem.id - assigns(:problem).should == @watched_err.problem - end - - it 'raises a DocumentNotFound error if the user is not watching the app' do - lambda { - get :show, :app_id => @unwatched_err.problem.app_id, :id => @unwatched_err.problem.id - }.should raise_error(Mongoid::Errors::DocumentNotFound) - end - end - end - - describe "PUT /apps/:app_id/errs/:id/resolve" do - before do - sign_in Fabricate(:admin) - - @problem = Fabricate(:err) - App.stub(:find).with(@problem.app.id).and_return(@problem.app) - @problem.app.problems.stub(:find).and_return(@problem.problem) - @problem.problem.stub(:resolve!) - end - - it 'finds the app and the err' do - App.should_receive(:find).with(@problem.app.id).and_return(@problem.app) - @problem.app.problems.should_receive(:find).and_return(@problem.problem) - put :resolve, :app_id => @problem.app.id, :id => @problem.problem.id - assigns(:app).should == @problem.app - assigns(:problem).should == @problem.problem - end - - it "should resolve the issue" do - @problem.problem.should_receive(:resolve!).and_return(true) - put :resolve, :app_id => @problem.app.id, :id => @problem.problem.id - end - - it "should display a message" do - put :resolve, :app_id => @problem.app.id, :id => @problem.problem.id - request.flash[:success].should match(/Great news/) - end - - it "should redirect to the app page" do - put :resolve, :app_id => @problem.app.id, :id => @problem.problem.id - response.should redirect_to(app_path(@problem.app)) - end - - it "should redirect back to errs page" do - request.env["Referer"] = errs_path - put :resolve, :app_id => @problem.app.id, :id => @problem.problem.id - response.should redirect_to(errs_path) - end - end - - describe "POST /apps/:app_id/errs/:id/create_issue" do - render_views - - before(:each) do - sign_in Fabricate(:admin) - end - - context "successful issue creation" do - context "lighthouseapp tracker" do - let(:notice) { Fabricate :notice } - let(:tracker) { Fabricate :lighthouse_tracker, :app => notice.app } - let(:problem) { notice.problem } - - before(:each) do - number = 5 - @issue_link = "http://#{tracker.account}.lighthouseapp.com/projects/#{tracker.project_id}/tickets/#{number}.xml" - body = "#{number}" - stub_request(:post, "http://#{tracker.account}.lighthouseapp.com/projects/#{tracker.project_id}/tickets.xml"). - to_return(:status => 201, :headers => {'Location' => @issue_link}, :body => body ) - - post :create_issue, :app_id => problem.app.id, :id => problem.id - problem.reload - end - - it "should redirect to problem page" do - response.should redirect_to( app_err_path(problem.app, problem) ) - end - end - end - - context "absent issue tracker" do - let(:problem) { Fabricate :problem } - - before(:each) do - post :create_issue, :app_id => problem.app.id, :id => problem.id - end - - it "should redirect to problem page" do - response.should redirect_to( app_err_path(problem.app, problem) ) - end - - it "should set flash error message telling issue tracker of the app doesn't exist" do - flash[:error].should == "This app has no issue tracker setup." - end - end - - context "error during request to a tracker" do - context "lighthouseapp tracker" do - let(:tracker) { Fabricate :lighthouse_tracker } - let(:err) { Fabricate(:err, :problem => Fabricate(:problem, :app => tracker.app)) } - - before(:each) do - stub_request(:post, "http://#{tracker.account}.lighthouseapp.com/projects/#{tracker.project_id}/tickets.xml").to_return(:status => 500) - - post :create_issue, :app_id => err.app.id, :id => err.problem.id - end - - it "should redirect to err page" do - response.should redirect_to( app_err_path(err.app, err.problem) ) - end - - it "should notify of connection error" do - flash[:error].should include("There was an error during issue creation:") - end - end - end - end - - describe "DELETE /apps/:app_id/errs/:id/unlink_issue" do - before(:each) do - sign_in Fabricate(:admin) - end - - context "err with issue" do - let(:err) { Fabricate(:err, :problem => Fabricate(:problem, :issue_link => "http://some.host")) } - - before(:each) do - delete :unlink_issue, :app_id => err.app.id, :id => err.problem.id - err.problem.reload - end - - it "should redirect to err page" do - response.should redirect_to( app_err_path(err.app, err.problem) ) - end - - it "should clear issue link" do - err.problem.issue_link.should be_nil - end - end - - context "err without issue" do - let(:err) { Fabricate :err } - - before(:each) do - delete :unlink_issue, :app_id => err.app.id, :id => err.problem.id - err.problem.reload - end - - it "should redirect to err page" do - response.should redirect_to( app_err_path(err.app, err.problem) ) - end - end - end - - describe "Bulk Actions" do - before(:each) do - sign_in Fabricate(:admin) - @problem1 = Fabricate(:err, :problem => Fabricate(:problem, :resolved => true)).problem - @problem2 = Fabricate(:err, :problem => Fabricate(:problem, :resolved => false)).problem - end - - it "should apply to multiple problems" do - post :resolve_several, :problems => [@problem1.id.to_s, @problem2.id.to_s] - assigns(:selected_problems).should == [@problem1, @problem2] - end - - it "should require at least one problem" do - post :resolve_several, :problems => [] - request.flash[:notice].should match(/You have not selected any/) - end - - context "POST /errs/merge_several" do - it "should require at least two problems" do - post :merge_several, :problems => [@problem1.id.to_s] - request.flash[:notice].should match(/You must select at least two/) - end - - it "should merge the problems" do - lambda { - post :merge_several, :problems => [@problem1.id.to_s, @problem2.id.to_s] - assigns(:merged_problem).reload.errs.length.should == 2 - }.should change(Problem, :count).by(-1) - end - end - - context "POST /errs/unmerge_several" do - it "should unmerge a merged problem" do - merged_problem = Problem.merge!(@problem1, @problem2) - merged_problem.errs.length.should == 2 - lambda { - post :unmerge_several, :problems => [merged_problem.id.to_s] - merged_problem.reload.errs.length.should == 1 - }.should change(Problem, :count).by(1) - end - end - - context "POST /errs/resolve_several" do - it "should resolve the issue" do - post :resolve_several, :problems => [@problem2.id.to_s] - @problem2.reload.resolved?.should == true - end - end - - context "POST /errs/unresolve_several" do - it "should unresolve the issue" do - post :unresolve_several, :problems => [@problem1.id.to_s] - @problem1.reload.resolved?.should == false - end - end - - context "POST /errs/destroy_several" do - it "should delete the errs" do - lambda { - post :destroy_several, :problems => [@problem1.id.to_s] - }.should change(Problem, :count).by(-1) - end - end - end - -end - diff --git a/spec/controllers/notices_controller_spec.rb b/spec/controllers/notices_controller_spec.rb index be32eb1..31820dd 100644 --- a/spec/controllers/notices_controller_spec.rb +++ b/spec/controllers/notices_controller_spec.rb @@ -68,7 +68,7 @@ describe NoticesController do problem = Fabricate(:problem, :app => app, :environment => "production") notice = Fabricate(:notice, :err => Fabricate(:err, :problem => problem)) get :locate, :id => notice.id - response.should redirect_to(app_err_path(problem.app, problem)) + response.should redirect_to(app_problem_path(problem.app, problem)) end end end diff --git a/spec/controllers/problems_controller_spec.rb b/spec/controllers/problems_controller_spec.rb new file mode 100644 index 0000000..f024d29 --- /dev/null +++ b/spec/controllers/problems_controller_spec.rb @@ -0,0 +1,441 @@ +require 'spec_helper' + +describe ProblemsController do + + it_requires_authentication :for => { + :index => :get, :all => :get, :show => :get, :resolve => :put + }, + :params => {:app_id => 'dummyid', :id => 'dummyid'} + + let(:app) { Fabricate(:app) } + let(:err) { Fabricate(:err, :problem => Fabricate(:problem, :app => app, :environment => "production")) } + + + describe "GET /problems" do + render_views + context 'when logged in as an admin' do + before(:each) do + @user = Fabricate(:admin) + sign_in @user + @problem = Fabricate(:notice, :err => Fabricate(:err, :problem => Fabricate(:problem, :app => app, :environment => "production"))).problem + end + + it "should successfully list problems" do + get :index + response.should be_success + response.body.gsub("​", "").should match(@problem.message) + end + + it "should list atom feed successfully" do + get :index, :format => "atom" + response.should be_success + response.body.should match(@problem.message) + end + + context "pagination" do + before(:each) do + 35.times { Fabricate :err } + end + + it "should have default per_page value for user" do + get :index + assigns(:problems).to_a.size.should == User::PER_PAGE + end + + it "should be able to override default per_page value" do + @user.update_attribute :per_page, 10 + get :index + assigns(:problems).to_a.size.should == 10 + end + end + + context 'with environment filters' do + before(:each) do + environments = ['production', 'test', 'development', 'staging'] + 20.times do |i| + Fabricate(:problem, :environment => environments[i % environments.length]) + end + end + + context 'no params' do + it 'shows problems for all environments' do + get :index + assigns(:problems).size.should == 21 + end + end + + context 'environment production' do + it 'shows problems for just production' do + get :index, :environment => 'production' + assigns(:problems).size.should == 6 + end + end + + context 'environment staging' do + it 'shows problems for just staging' do + get :index, :environment => 'staging' + assigns(:problems).size.should == 5 + end + end + + context 'environment development' do + it 'shows problems for just development' do + get :index, :environment => 'development' + assigns(:problems).size.should == 5 + end + end + + context 'environment test' do + it 'shows problems for just test' do + get :index, :environment => 'test' + assigns(:problems).size.should == 5 + end + end + end + end + + context 'when logged in as a user' do + it 'gets a paginated list of unresolved problems for the users apps' do + sign_in(user = Fabricate(:user)) + unwatched_err = Fabricate(:err) + watched_unresolved_err = Fabricate(:err, :problem => Fabricate(:problem, :app => Fabricate(:user_watcher, :user => user).app, :resolved => false)) + watched_resolved_err = Fabricate(:err, :problem => Fabricate(:problem, :app => Fabricate(:user_watcher, :user => user).app, :resolved => true)) + get :index + assigns(:problems).should include(watched_unresolved_err.problem) + assigns(:problems).should_not include(unwatched_err.problem, watched_resolved_err.problem) + end + end + end + + describe "GET /problems/all" do + context 'when logged in as an admin' do + it "gets a paginated list of all problems" do + sign_in Fabricate(:admin) + problems = Kaminari.paginate_array((1..30).to_a) + 3.times { problems << Fabricate(:err).problem } + 3.times { problems << Fabricate(:err, :problem => Fabricate(:problem, :resolved => true)).problem } + Problem.should_receive(:ordered_by).and_return( + mock('proxy', :page => mock('other_proxy', :per => problems)) + ) + get :all + assigns(:problems).should == problems + end + end + + context 'when logged in as a user' do + it 'gets a paginated list of all problems for the users apps' do + sign_in(user = Fabricate(:user)) + unwatched_problem = Fabricate(:problem) + watched_unresolved_problem = Fabricate(:problem, :app => Fabricate(:user_watcher, :user => user).app, :resolved => false) + watched_resolved_problem = Fabricate(:problem, :app => Fabricate(:user_watcher, :user => user).app, :resolved => true) + get :all + assigns(:problems).should include(watched_resolved_problem, watched_unresolved_problem) + assigns(:problems).should_not include(unwatched_problem) + end + end + end + + describe "GET /apps/:app_id/problems/:id" do + render_views + + context 'when logged in as an admin' do + before do + sign_in Fabricate(:admin) + end + + it "finds the app" do + get :show, :app_id => app.id, :id => err.problem.id + assigns(:app).should == app + end + + it "finds the problem" do + get :show, :app_id => app.id, :id => err.problem.id + assigns(:problem).should == err.problem + end + + it "successfully render page" do + get :show, :app_id => app.id, :id => err.problem.id + response.should be_success + end + + context 'pagination' do + let!(:notices) do + 3.times.reduce([]) do |coll, i| + coll << Fabricate(:notice, :err => err, :created_at => (Time.now + i)) + end + end + + it "paginates the notices 1 at a time, starting with the most recent" do + get :show, :app_id => app.id, :id => err.problem.id + assigns(:notices).entries.count.should == 1 + assigns(:notices).should include(notices.last) + end + + it "paginates the notices 1 at a time, based on then notice param" do + get :show, :app_id => app.id, :id => err.problem.id, :notice => 3 + assigns(:notices).entries.count.should == 1 + assigns(:notices).should include(notices.first) + end + end + + context "create issue button" do + let(:button_matcher) { match(/create issue/) } + + it "should not exist for problem's app without issue tracker" do + err = Fabricate :err + get :show, :app_id => err.app.id, :id => err.problem.id + + response.body.should_not button_matcher + end + + it "should exist for problem's app with issue tracker" do + tracker = Fabricate(:lighthouse_tracker) + err = Fabricate(:err, :problem => Fabricate(:problem, :app => tracker.app)) + get :show, :app_id => err.app.id, :id => err.problem.id + + response.body.should button_matcher + end + + it "should not exist for problem with issue_link" do + tracker = Fabricate(:lighthouse_tracker) + err = Fabricate(:err, :problem => Fabricate(:problem, :app => tracker.app, :issue_link => "http://some.host")) + get :show, :app_id => err.app.id, :id => err.problem.id + + response.body.should_not button_matcher + end + end + end + + context 'when logged in as a user' do + before do + sign_in(@user = Fabricate(:user)) + @unwatched_err = Fabricate(:err) + @watched_app = Fabricate(:app) + @watcher = Fabricate(:user_watcher, :user => @user, :app => @watched_app) + @watched_err = Fabricate(:err, :problem => Fabricate(:problem, :app => @watched_app)) + end + + it 'finds the problem if the user is watching the app' do + get :show, :app_id => @watched_app.to_param, :id => @watched_err.problem.id + assigns(:problem).should == @watched_err.problem + end + + it 'raises a DocumentNotFound error if the user is not watching the app' do + lambda { + get :show, :app_id => @unwatched_err.problem.app_id, :id => @unwatched_err.problem.id + }.should raise_error(Mongoid::Errors::DocumentNotFound) + end + end + end + + describe "PUT /apps/:app_id/problems/:id/resolve" do + before do + sign_in Fabricate(:admin) + + @problem = Fabricate(:err) + App.stub(:find).with(@problem.app.id).and_return(@problem.app) + @problem.app.problems.stub(:find).and_return(@problem.problem) + @problem.problem.stub(:resolve!) + end + + it 'finds the app and the problem' do + App.should_receive(:find).with(@problem.app.id).and_return(@problem.app) + @problem.app.problems.should_receive(:find).and_return(@problem.problem) + put :resolve, :app_id => @problem.app.id, :id => @problem.problem.id + assigns(:app).should == @problem.app + assigns(:problem).should == @problem.problem + end + + it "should resolve the issue" do + @problem.problem.should_receive(:resolve!).and_return(true) + put :resolve, :app_id => @problem.app.id, :id => @problem.problem.id + end + + it "should display a message" do + put :resolve, :app_id => @problem.app.id, :id => @problem.problem.id + request.flash[:success].should match(/Great news/) + end + + it "should redirect to the app page" do + put :resolve, :app_id => @problem.app.id, :id => @problem.problem.id + response.should redirect_to(app_path(@problem.app)) + end + + it "should redirect back to problems page" do + request.env["Referer"] = problems_path + put :resolve, :app_id => @problem.app.id, :id => @problem.problem.id + response.should redirect_to(problems_path) + end + end + + describe "POST /apps/:app_id/problems/:id/create_issue" do + render_views + + before(:each) do + sign_in Fabricate(:admin) + end + + context "successful issue creation" do + context "lighthouseapp tracker" do + let(:notice) { Fabricate :notice } + let(:tracker) { Fabricate :lighthouse_tracker, :app => notice.app } + let(:problem) { notice.problem } + + before(:each) do + number = 5 + @issue_link = "http://#{tracker.account}.lighthouseapp.com/projects/#{tracker.project_id}/tickets/#{number}.xml" + body = "#{number}" + stub_request(:post, "http://#{tracker.account}.lighthouseapp.com/projects/#{tracker.project_id}/tickets.xml"). + to_return(:status => 201, :headers => {'Location' => @issue_link}, :body => body ) + + post :create_issue, :app_id => problem.app.id, :id => problem.id + problem.reload + end + + it "should redirect to problem page" do + response.should redirect_to( app_problem_path(problem.app, problem) ) + end + end + end + + context "absent issue tracker" do + let(:problem) { Fabricate :problem } + + before(:each) do + post :create_issue, :app_id => problem.app.id, :id => problem.id + end + + it "should redirect to problem page" do + response.should redirect_to( app_problem_path(problem.app, problem) ) + end + + it "should set flash error message telling issue tracker of the app doesn't exist" do + flash[:error].should == "This app has no issue tracker setup." + end + end + + context "error during request to a tracker" do + context "lighthouseapp tracker" do + let(:tracker) { Fabricate :lighthouse_tracker } + let(:err) { Fabricate(:err, :problem => Fabricate(:problem, :app => tracker.app)) } + + before(:each) do + stub_request(:post, "http://#{tracker.account}.lighthouseapp.com/projects/#{tracker.project_id}/tickets.xml").to_return(:status => 500) + + post :create_issue, :app_id => err.app.id, :id => err.problem.id + end + + it "should redirect to problem page" do + response.should redirect_to( app_problem_path(err.app, err.problem) ) + end + + it "should notify of connection error" do + flash[:error].should include("There was an error during issue creation:") + end + end + end + end + + describe "DELETE /apps/:app_id/problems/:id/unlink_issue" do + before(:each) do + sign_in Fabricate(:admin) + end + + context "problem with issue" do + let(:err) { Fabricate(:err, :problem => Fabricate(:problem, :issue_link => "http://some.host")) } + + before(:each) do + delete :unlink_issue, :app_id => err.app.id, :id => err.problem.id + err.problem.reload + end + + it "should redirect to problem page" do + response.should redirect_to( app_problem_path(err.app, err.problem) ) + end + + it "should clear issue link" do + err.problem.issue_link.should be_nil + end + end + + context "err without issue" do + let(:err) { Fabricate :err } + + before(:each) do + delete :unlink_issue, :app_id => err.app.id, :id => err.problem.id + err.problem.reload + end + + it "should redirect to problem page" do + response.should redirect_to( app_problem_path(err.app, err.problem) ) + end + end + end + + describe "Bulk Actions" do + before(:each) do + sign_in Fabricate(:admin) + @problem1 = Fabricate(:err, :problem => Fabricate(:problem, :resolved => true)).problem + @problem2 = Fabricate(:err, :problem => Fabricate(:problem, :resolved => false)).problem + end + + it "should apply to multiple problems" do + post :resolve_several, :problems => [@problem1.id.to_s, @problem2.id.to_s] + assigns(:selected_problems).should == [@problem1, @problem2] + end + + it "should require at least one problem" do + post :resolve_several, :problems => [] + request.flash[:notice].should match(/You have not selected any/) + end + + context "POST /problems/merge_several" do + it "should require at least two problems" do + post :merge_several, :problems => [@problem1.id.to_s] + request.flash[:notice].should match(/You must select at least two/) + end + + it "should merge the problems" do + lambda { + post :merge_several, :problems => [@problem1.id.to_s, @problem2.id.to_s] + assigns(:merged_problem).reload.errs.length.should == 2 + }.should change(Problem, :count).by(-1) + end + end + + context "POST /problems/unmerge_several" do + it "should unmerge a merged problem" do + merged_problem = Problem.merge!(@problem1, @problem2) + merged_problem.errs.length.should == 2 + lambda { + post :unmerge_several, :problems => [merged_problem.id.to_s] + merged_problem.reload.errs.length.should == 1 + }.should change(Problem, :count).by(1) + end + end + + context "POST /problems/resolve_several" do + it "should resolve the issue" do + post :resolve_several, :problems => [@problem2.id.to_s] + @problem2.reload.resolved?.should == true + end + end + + context "POST /problems/unresolve_several" do + it "should unresolve the issue" do + post :unresolve_several, :problems => [@problem1.id.to_s] + @problem1.reload.resolved?.should == false + end + end + + context "POST /problems/destroy_several" do + it "should delete the problems" do + lambda { + post :destroy_several, :problems => [@problem1.id.to_s] + }.should change(Problem, :count).by(-1) + end + end + end + +end + diff --git a/spec/helpers/errs_helper_spec.rb b/spec/helpers/errs_helper_spec.rb deleted file mode 100644 index c4b8731..0000000 --- a/spec/helpers/errs_helper_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'spec_helper' - -describe ErrsHelper do - describe '#truncated_err_message' do - it 'is html safe' do - problem = double('problem', :message => '#') - truncated = helper.truncated_err_message(problem) - truncated.should be_html_safe - truncated.should_not include('<', '>') - end - end - - describe "#gravatar_tag" do - let(:email) { "gravatar@example.com" } - let(:email_hash) { Digest::MD5.hexdigest email } - let(:base_url) { "http://www.gravatar.com/avatar/#{email_hash}" } - - context "default config" do - before do - Errbit::Config.stub(:use_gravatar).and_return(true) - Errbit::Config.stub(:gravatar_default).and_return('identicon') - end - - it "should render image_tag with correct alt and src" do - expected = "\"#{email}\"" - helper.gravatar_tag(email, :s => 48).should eq(expected) - end - - it "should override :d" do - expected = "\"#{email}\"" - helper.gravatar_tag(email, :d => 'retro', :s => 48).should eq(expected) - end - end - end -end diff --git a/spec/helpers/problems_helper_spec.rb b/spec/helpers/problems_helper_spec.rb new file mode 100644 index 0000000..5c20c6d --- /dev/null +++ b/spec/helpers/problems_helper_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' + +describe ProblemsHelper do + describe '#truncated_problem_message' do + it 'is html safe' do + problem = double('problem', :message => '#') + truncated = helper.truncated_problem_message(problem) + truncated.should be_html_safe + truncated.should_not include('<', '>') + end + end + + describe "#gravatar_tag" do + let(:email) { "gravatar@example.com" } + let(:email_hash) { Digest::MD5.hexdigest email } + let(:base_url) { "http://www.gravatar.com/avatar/#{email_hash}" } + + context "default config" do + before do + Errbit::Config.stub(:use_gravatar).and_return(true) + Errbit::Config.stub(:gravatar_default).and_return('identicon') + end + + it "should render image_tag with correct alt and src" do + expected = "\"#{email}\"" + helper.gravatar_tag(email, :s => 48).should eq(expected) + end + + it "should override :d" do + expected = "\"#{email}\"" + helper.gravatar_tag(email, :d => 'retro', :s => 48).should eq(expected) + end + end + end +end diff --git a/spec/views/errs/show.html.haml_spec.rb b/spec/views/errs/show.html.haml_spec.rb deleted file mode 100644 index 4f00bcc..0000000 --- a/spec/views/errs/show.html.haml_spec.rb +++ /dev/null @@ -1,128 +0,0 @@ -require 'spec_helper' - -describe "errs/show.html.haml" do - before do - err = Fabricate(:err) - problem = err.problem - comment = Fabricate(:comment) - assign :problem, problem - assign :comment, comment - assign :app, problem.app - assign :notices, err.notices.page(1).per(1) - assign :notice, err.notices.first - controller.stub(:current_user) { Fabricate(:user) } - end - - def with_issue_tracker(tracker, problem) - problem.app.issue_tracker = tracker.new :api_token => "token token token", :project_id => "1234" - assign :problem, problem - assign :app, problem.app - end - - describe "content_for :action_bar" do - def action_bar - view.content_for(:action_bar) - end - - it "should confirm the 'resolve' link by default" do - render - - action_bar.should have_selector('a.resolve[data-confirm="Seriously?"]') - end - - it "should confirm the 'resolve' link if configuration is unset" do - Errbit::Config.stub(:confirm_resolve_err).and_return(nil) - render - - action_bar.should have_selector('a.resolve[data-confirm="Seriously?"]') - end - - it "should not confirm the 'resolve' link if configured not to" do - Errbit::Config.stub(:confirm_resolve_err).and_return(false) - render - - action_bar.should have_selector('a.resolve[data-confirm="null"]') - end - - it "should link 'up' to HTTP_REFERER if is set" do - url = 'http://localhost:3000/errs' - controller.request.env['HTTP_REFERER'] = url - render - - action_bar.should have_selector("span a.up[href='#{url}']", :text => 'up') - end - - it "should link 'up' to app_errs_path if HTTP_REFERER isn't set'" do - controller.request.env['HTTP_REFERER'] = nil - problem = Fabricate(:problem_with_comments) - assign :problem, problem - assign :app, problem.app - render - - action_bar.should have_selector("span a.up[href='#{app_errs_path(problem.app)}']", :text => 'up') - end - - context 'create issue links' do - it 'should allow creating issue for github if current user has linked their github account' do - user = Fabricate(:user, :github_login => 'test_user', :github_oauth_token => 'abcdef') - controller.stub(:current_user) { user } - - problem = Fabricate(:problem_with_comments, :app => Fabricate(:app, :github_repo => "test_user/test_repo")) - assign :problem, problem - assign :app, problem.app - render - - action_bar.should have_selector("span a.github_create.create-issue", :text => 'create issue') - end - - it 'should allow creating issue for github if application has a github tracker' do - problem = Fabricate(:problem_with_comments, :app => Fabricate(:app, :github_repo => "test_user/test_repo")) - with_issue_tracker(GithubIssuesTracker, problem) - assign :problem, problem - assign :app, problem.app - render - - action_bar.should have_selector("span a.github_create.create-issue", :text => 'create issue') - end - end - end - - describe "content_for :comments with comments disabled for configured issue tracker" do - before do - Errbit::Config.stub(:allow_comments_with_issue_tracker).and_return(false) - Errbit::Config.stub(:use_gravatar).and_return(true) - end - - it 'should display comments and new comment form when no issue tracker' do - problem = Fabricate(:problem_with_comments) - assign :problem, problem - assign :app, problem.app - render - - view.content_for(:comments).should include('Test comment') - view.content_for(:comments).should have_selector('img[src^="http://www.gravatar.com/avatar"]') - view.content_for(:comments).should include('Add a comment') - end - - context "with issue tracker" do - it 'should not display the comments section' do - problem = Fabricate(:problem) - with_issue_tracker(PivotalLabsTracker, problem) - render - view.view_flow.get(:comments).should be_blank - end - - it 'should display existing comments' do - problem = Fabricate(:problem_with_comments) - problem.reload - with_issue_tracker(PivotalLabsTracker, problem) - render - - view.content_for(:comments).should include('Test comment') - view.content_for(:comments).should have_selector('img[src^="http://www.gravatar.com/avatar"]') - view.content_for(:comments).should_not include('Add a comment') - end - end - end -end - diff --git a/spec/views/problems/show.html.haml_spec.rb b/spec/views/problems/show.html.haml_spec.rb new file mode 100644 index 0000000..6a1e305 --- /dev/null +++ b/spec/views/problems/show.html.haml_spec.rb @@ -0,0 +1,127 @@ +require 'spec_helper' + +describe "problems/show.html.haml" do + before do + problem = Fabricate(:problem) + comment = Fabricate(:comment) + assign :problem, problem + assign :comment, comment + assign :app, problem.app + assign :notices, problem.notices.page(1).per(1) + assign :notice, problem.notices.first + controller.stub(:current_user) { Fabricate(:user) } + end + + def with_issue_tracker(tracker, problem) + problem.app.issue_tracker = tracker.new :api_token => "token token token", :project_id => "1234" + assign :problem, problem + assign :app, problem.app + end + + describe "content_for :action_bar" do + def action_bar + view.content_for(:action_bar) + end + + it "should confirm the 'resolve' link by default" do + render + + action_bar.should have_selector('a.resolve[data-confirm="Seriously?"]') + end + + it "should confirm the 'resolve' link if configuration is unset" do + Errbit::Config.stub(:confirm_resolve_err).and_return(nil) + render + + action_bar.should have_selector('a.resolve[data-confirm="Seriously?"]') + end + + it "should not confirm the 'resolve' link if configured not to" do + Errbit::Config.stub(:confirm_resolve_err).and_return(false) + render + + action_bar.should have_selector('a.resolve[data-confirm="null"]') + end + + it "should link 'up' to HTTP_REFERER if is set" do + url = 'http://localhost:3000/problems' + controller.request.env['HTTP_REFERER'] = url + render + + action_bar.should have_selector("span a.up[href='#{url}']", :text => 'up') + end + + it "should link 'up' to app_problems_path if HTTP_REFERER isn't set'" do + controller.request.env['HTTP_REFERER'] = nil + problem = Fabricate(:problem_with_comments) + assign :problem, problem + assign :app, problem.app + render + + action_bar.should have_selector("span a.up[href='#{app_problems_path(problem.app)}']", :text => 'up') + end + + context 'create issue links' do + it 'should allow creating issue for github if current user has linked their github account' do + user = Fabricate(:user, :github_login => 'test_user', :github_oauth_token => 'abcdef') + controller.stub(:current_user) { user } + + problem = Fabricate(:problem_with_comments, :app => Fabricate(:app, :github_repo => "test_user/test_repo")) + assign :problem, problem + assign :app, problem.app + render + + action_bar.should have_selector("span a.github_create.create-issue", :text => 'create issue') + end + + it 'should allow creating issue for github if application has a github tracker' do + problem = Fabricate(:problem_with_comments, :app => Fabricate(:app, :github_repo => "test_user/test_repo")) + with_issue_tracker(GithubIssuesTracker, problem) + assign :problem, problem + assign :app, problem.app + render + + action_bar.should have_selector("span a.github_create.create-issue", :text => 'create issue') + end + end + end + + describe "content_for :comments with comments disabled for configured issue tracker" do + before do + Errbit::Config.stub(:allow_comments_with_issue_tracker).and_return(false) + Errbit::Config.stub(:use_gravatar).and_return(true) + end + + it 'should display comments and new comment form when no issue tracker' do + problem = Fabricate(:problem_with_comments) + assign :problem, problem + assign :app, problem.app + render + + view.content_for(:comments).should include('Test comment') + view.content_for(:comments).should have_selector('img[src^="http://www.gravatar.com/avatar"]') + view.content_for(:comments).should include('Add a comment') + end + + context "with issue tracker" do + it 'should not display the comments section' do + problem = Fabricate(:problem) + with_issue_tracker(PivotalLabsTracker, problem) + render + view.view_flow.get(:comments).should be_blank + end + + it 'should display existing comments' do + problem = Fabricate(:problem_with_comments) + problem.reload + with_issue_tracker(PivotalLabsTracker, problem) + render + + view.content_for(:comments).should include('Test comment') + view.content_for(:comments).should have_selector('img[src^="http://www.gravatar.com/avatar"]') + view.content_for(:comments).should_not include('Add a comment') + end + end + end +end + -- libgit2 0.21.2