Commit 9ce0dc764fd5347f985bb36017e4468d93d3f9b8

Authored by Cyril Mougel
2 parents cd44ad81 88aea500
Exists in master and in 1 other branch production

Merge pull request #289

app/assets/javascripts/apps.show.js
1 1 $(function() {
  2 +
2 3 $("#watchers_toggle").click(function() {
3 4 $("#watchers_div").slideToggle("slow");
4 5 });
  6 +
5 7 $("#repository_toggle").click(function() {
6 8 $("#repository_div").slideToggle("slow");
7 9 });
  10 +
8 11 $("#deploys_toggle").click(function() {
9 12 $("#deploys_div").slideToggle("slow");
10 13 });
... ...
app/controllers/watchers_controller.rb 0 → 100644
... ... @@ -0,0 +1,27 @@
  1 +class WatchersController < ApplicationController
  2 + respond_to :html
  3 +
  4 + expose(:app) do
  5 + App.find(params[:app_id])
  6 + end
  7 +
  8 + expose(:watcher) do
  9 + app.watchers.where(:user_id => params[:id]).first
  10 + end
  11 +
  12 + before_filter :require_watcher_edit_priviledges, :only => [:destroy]
  13 +
  14 + def destroy
  15 + app.watchers.delete(watcher)
  16 + flash[:success] = "That's sad. #{watcher.label} is no longer watcher."
  17 + redirect_to root_path
  18 + end
  19 +
  20 + private
  21 +
  22 + def require_watcher_edit_priviledges
  23 + redirect_to(root_path) unless current_user == watcher.user || current_user.admin?
  24 + end
  25 +
  26 +end
  27 +
... ...
app/views/apps/show.html.haml
1 1 - content_for :title, app.name
2 2 - content_for :head do
3   - = auto_discovery_link_tag :atom, app_path(app, User.token_authentication_key => current_user.authentication_token, :format => "atom"), :title => "Errbit notices for #{app.name} at #{request.host}"
  3 + = auto_discovery_link_tag :atom, app_path(app, User.token_authentication_key => current_user.authentication_token, :format => "atom"), :title => t('.atom_title', :name => app.name, :host => request.host)
4 4 - content_for :meta do
5   - %strong Errors Caught:
  5 + %strong=t('.errors_caught')
6 6 = app.problems.count
7   - %strong Deploy Count:
  7 + %strong=t('.deploy_count')
8 8 = app.deploys.count
9   - %strong API Key:
  9 + %strong=t('.api_key')
10 10 = app.api_key
11 11 - content_for :action_bar do
12 12 - if current_user.admin?
13   - = link_to 'edit', edit_app_path(app), :class => 'button'
  13 + = link_to t('.edit'), edit_app_path(app), :class => 'button'
14 14 - if all_errs
15   - = link_to 'unresolved errs', app_path(app), :class => 'button'
  15 + = link_to t('.unresolved_errs'), app_path(app), :class => 'button'
16 16 - else
17   - = link_to 'all errs', app_path(app, :all_errs => true), :class => 'button'
  17 + = link_to t('.all_errs'), app_path(app, :all_errs => true), :class => 'button'
18 18  
  19 + - if current_user.watching?(app)
  20 + = link_to t('.unwatch'), app_watcher_path({:app_id => app, :id => current_user.id}), :method => :delete, :class => 'button', :confirm => t('.are_you_sure')
19 21 %h3#watchers_toggle
20   - Watchers
21   - %span.click_span (show/hide)
  22 + =t('.watchers')
  23 + %span.click_span=t('.show_hide')
22 24 #watchers_div
23 25 - if app.notify_all_users
24 26 %table.watchers
25 27 %thead
26 28 %tr
27   - %th All users will be notified when something happens.
  29 + %th=t('.all_users_notified')
28 30 - else
29 31 %table.watchers
30 32 %thead
31 33 %tr
32   - %th User or Email
  34 + %th=t('.user_or_email')
33 35 %tbody
34 36 - app.watchers.each do |watcher|
35 37 %tr
... ... @@ -37,35 +39,35 @@
37 39 - if app.watchers.none?
38 40 %tr
39 41 %td
40   - %em Sadly, no one is watching this app
  42 + %em= t('.no_watcher')
41 43  
42 44 - if app.github_repo?
43 45 %h3#repository_toggle
44   - Repository
45   - %span.click_span (show/hide)
  46 + =t('.repository')
  47 + %span.click_span=t('.show_hide')
46 48 #repository_div
47 49 %table.repository
48 50 %thead
49 51 %tr
50   - %th GitHub Repo
  52 + %th=t('.github_repo')
51 53 %tbody
52 54 %tr
53 55 %td= link_to(app.github_repo, app.github_url, :target => '_blank')
54 56  
55 57 %h3#deploys_toggle
56   - Latest Deploys
57   - %span.click_span (show/hide)
  58 + =t('.latest_deploys')
  59 + %span.click_span=t('.show_hide')
58 60 #deploys_div
59 61 - if deploys.any?
60 62 %table.deploys
61 63 %thead
62 64 %tr
63   - %th When
64   - %th Environment
65   - %th Who
66   - %th Message
67   - %th Repository
68   - %th Revision
  65 + %th=t('.when')
  66 + %th=t('.environment')
  67 + %th=t('.who')
  68 + %th=t('.message')
  69 + %th=t('.repository')
  70 + %th=t('.revision')
69 71  
70 72 %tbody
71 73 - deploys.each do |deploy|
... ... @@ -76,20 +78,20 @@
76 78 %td.message #{deploy.message}
77 79 %td.repository #{deploy.repository}
78 80 %td.revision #{deploy.short_revision}
79   - = link_to "All Deploys (#{app.deploys.count})", app_deploys_path(app), :class => 'button'
  81 + = link_to t('.all_deploys', :count => app.deploys.count), app_deploys_path(app), :class => 'button'
80 82 - else
81   - %h3 No deploys
  83 + %h3=t('.no_deploys')
82 84  
83 85 - if app.problems.any?
84   - %h3.clear Errors
  86 + %h3.clear=t('.errors')
85 87 %section
86 88 = form_tag search_problems_path(:all_errs => all_errs, :app_id => app.id), :method => :get, :remote => true do
87   - = text_field_tag :search, params[:search], :placeholder => 'Search for issues'
  89 + = text_field_tag :search, params[:search], :placeholder => t('.search_placeholder')
88 90 %br
89 91 %section
90 92 .problem_table{:id => 'problem_table'}
91 93 = render 'problems/table', :problems => problems
92 94 - else
93   - %h3.clear No errs have been caught yet, make sure you setup your app
  95 + %h3.clear=t('.no_error_yet')
94 96 = render 'configuration_instructions', :app => app
95 97  
... ...
app/views/devise/sessions/new.html.haml
... ... @@ -22,7 +22,7 @@
22 22 = f.label :remember_me
23 23  
24 24 %div.buttons
25   - %button{:type => 'submit', :class => 'sign_in'}= "Sign in"
  25 + %button{:type => 'submit', :class => 'sign_in'}=t('.sign_in')
26 26  
27 27 :javascript
28 28 $('a#forgot_password').click(function(){
... ...
config/locales/en.yml
... ... @@ -65,6 +65,9 @@ en:
65 65 omniauth_callbacks:
66 66 failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
67 67 success: "Successfully authenticated from %{kind} account."
  68 + sessions:
  69 + new:
  70 + sign_in: "Sign in"
68 71  
69 72 apps:
70 73 index:
... ... @@ -78,3 +81,32 @@ en:
78 81 new_app: Add a New App
79 82 no_apps: 'No apps here.'
80 83 click_to_create: 'Click here to create your first one'
  84 + show:
  85 + all_deploys: "All Deploys (%{count})"
  86 + all_errs: all errs
  87 + all_users_notified: "All users will be notified when something happens."
  88 + api_key: "API Key:"
  89 + are_you_sure: 'Are you sure?'
  90 + atom_title: "Errbit notices for %{name} at %{host}"
  91 + deploy_count: "Deploy Count:"
  92 + edit: edit
  93 + environment: Environment
  94 + errors: Errors
  95 + errors_caught: "Errors Caught:"
  96 + github_repo: GitHub Repo
  97 + latest_deploys: Latest Deploys
  98 + message: Message
  99 + no_deploys: No deploys
  100 + no_error_yet: "No errs have been caught yet, make sure you setup your app"
  101 + no_watcher: "Sadly, no one is watching this app"
  102 + repository: Repository
  103 + repository: Repository
  104 + revision: Revision
  105 + search_placeholder: 'Search for issues'
  106 + show_hide: "(show/hide)"
  107 + unresolved_errs: unresolved errs
  108 + unwatch: unwatch
  109 + user_or_email: User or Email
  110 + watchers: Watchers
  111 + when: When
  112 + who: Who
... ...
config/routes.rb
... ... @@ -37,8 +37,8 @@ Errbit::Application.routes.draw do
37 37 delete :unlink_issue
38 38 end
39 39 end
40   -
41 40 resources :deploys, :only => [:index]
  41 + resources :watchers, :only => [:destroy]
42 42 end
43 43  
44 44 namespace :api do
... ...
spec/acceptance/sign_in_with_github_spec.rb
1 1 require 'acceptance/acceptance_helper'
2 2  
3 3 feature 'Sign in with GitHub' do
  4 +
4 5 background do
5 6 Errbit::Config.stub(:github_authentication) { true }
6 7 Fabricate(:user, :github_login => 'nashby')
... ...
spec/acceptance/watch_unwatch_app.rb 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +require 'acceptance/acceptance_helper'
  2 +
  3 +feature 'A user can watch and unwatch an application' do
  4 +
  5 + let!(:app) { Fabricate(:app) }
  6 + let!(:user) do
  7 + user = Fabricate(:user)
  8 + app.watchers.create!(
  9 + :user_id => user.id
  10 + )
  11 + user.reload
  12 + end
  13 +
  14 + scenario 'log in watch a project and unwatch it' do
  15 + visit '/'
  16 + fill_in :user_email, :with => user.email
  17 + fill_in :user_password, :with => 'password'
  18 + click_on I18n.t('devise.sessions.new.sign_in')
  19 + click_on I18n.t('apps.show.unwatch')
  20 + expect(page).to have_content(I18n.t('apps.index.no_apps')
  21 + end
  22 +
  23 +end
... ...
spec/controllers/watchers_controller_spec.rb 0 → 100644
... ... @@ -0,0 +1,36 @@
  1 +require 'spec_helper'
  2 +
  3 +describe WatchersController do
  4 + let(:app) do
  5 + a = Fabricate(:app)
  6 + Fabricate(:user_watcher, :app => a)
  7 + a
  8 + end
  9 +
  10 + describe "DELETE /apps/:app_id/watchers/:id/destroy" do
  11 +
  12 + context "with admin user" do
  13 + before(:each) do
  14 + sign_in Fabricate(:admin)
  15 + end
  16 +
  17 + context "successful watcher deletion" do
  18 + let(:problem) { Fabricate(:problem_with_comments) }
  19 + let(:watcher) { app.watchers.first }
  20 +
  21 + before(:each) do
  22 + delete :destroy, :app_id => app.id, :id => watcher.user.id.to_s
  23 + problem.reload
  24 + end
  25 +
  26 + it "should delete the watcher" do
  27 + app.watchers.detect{|w| w.id.to_s == watcher.id }.should == nil
  28 + end
  29 +
  30 + it "should redirect to index page" do
  31 + response.should redirect_to(root_path)
  32 + end
  33 + end
  34 + end
  35 + end
  36 +end
... ...
spec/views/apps/show.html.haml_spec.rb
... ... @@ -2,17 +2,20 @@ require &#39;spec_helper&#39;
2 2  
3 3 describe "apps/show.html.haml" do
4 4 let(:app) { stub_model(App) }
  5 + let(:user) { stub_model(User) }
  6 +
  7 + let(:action_bar) do
  8 + view.content_for(:action_bar)
  9 + end
  10 +
5 11 before do
6 12 view.stub(:app).and_return(app)
7 13 view.stub(:all_errs).and_return(false)
8 14 view.stub(:deploys).and_return([])
9   - controller.stub(:current_user) { stub_model(User) }
  15 + controller.stub(:current_user) { user }
10 16 end
11 17  
12 18 describe "content_for :action_bar" do
13   - def action_bar
14   - view.content_for(:action_bar)
15   - end
16 19  
17 20 it "should confirm the 'cancel' link" do
18 21 render
... ... @@ -28,5 +31,26 @@ describe &quot;apps/show.html.haml&quot; do
28 31 rendered.should match(/No errs have been/)
29 32 end
30 33 end
  34 +
  35 + context "with user watch application" do
  36 + before do
  37 + user.stub(:watching?).with(app).and_return(true)
  38 + end
  39 + it 'see the unwatch button' do
  40 + render
  41 + expect(action_bar).to include(I18n.t('apps.show.unwatch'))
  42 + end
  43 + end
  44 +
  45 + context "with user not watch application" do
  46 + before do
  47 + user.stub(:watching?).with(app).and_return(false)
  48 + end
  49 + it 'not see the unwatch button' do
  50 + render
  51 + expect(action_bar).to_not include(I18n.t('apps.show.unwatch'))
  52 + end
  53 + end
  54 +
31 55 end
32 56  
... ...