diff --git a/app/controllers/apps_controller.rb b/app/controllers/apps_controller.rb index 7aaaa0a..2a1f5b9 100644 --- a/app/controllers/apps_controller.rb +++ b/app/controllers/apps_controller.rb @@ -80,6 +80,11 @@ class AppsController < ApplicationController end end + def regenerate_api_key + app.regenerate_api_key! + redirect_to edit_app_path(app) + end + protected def initialize_subclassed_issue_tracker diff --git a/app/models/app.rb b/app/models/app.rb index 4eb3fa5..043fcff 100644 --- a/app/models/app.rb +++ b/app/models/app.rb @@ -170,6 +170,10 @@ class App Errbit::Config.per_app_email_at_notices ? super : Errbit::Config.email_at_notices end + def regenerate_api_key! + set(:api_key, SecureRandom.hex) + end + protected def store_cached_attributes_on_problems diff --git a/app/views/apps/_fields.html.haml b/app/views/apps/_fields.html.haml index bacf103..46df9a3 100644 --- a/app/views/apps/_fields.html.haml +++ b/app/views/apps/_fields.html.haml @@ -5,6 +5,10 @@ = f.text_field :name %div + %label Api Key + %span= app.api_key + = link_to t('.regenerate_api_key'), regenerate_api_key_app_path(app), :class => 'button', :method => 'post' +%div = f.label :repository_branch = f.text_field :repository_branch, :placeholder => "master" %div diff --git a/config/locales/en.yml b/config/locales/en.yml index 7e6b8f8..7d49c3e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -81,6 +81,8 @@ en: new_app: Add a New App no_apps: 'No apps here.' click_to_create: 'Click here to create your first one' + fields: + regenerate_api_key: "Regenerate API key" show: all_deploys: "All Deploys (%{count})" all_errs: all errs @@ -100,7 +102,6 @@ en: no_error_yet: "No errs have been caught yet, make sure you setup your app" no_watcher: "Sadly, no one is watching this app" repository: Repository - repository: Repository revision: Revision search_placeholder: 'Search for issues' show_hide: "(show/hide)" @@ -110,3 +111,4 @@ en: watchers: Watchers when: When who: Who + diff --git a/config/routes.rb b/config/routes.rb index 8d84f2e..04e671a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -39,6 +39,9 @@ Errbit::Application.routes.draw do end resources :deploys, :only => [:index] resources :watchers, :only => [:destroy] + member do + post :regenerate_api_key + end end namespace :api do diff --git a/spec/acceptance/acceptance_helper.rb b/spec/acceptance/acceptance_helper.rb index bbd8ba3..2255870 100644 --- a/spec/acceptance/acceptance_helper.rb +++ b/spec/acceptance/acceptance_helper.rb @@ -17,3 +17,10 @@ def mock_auth(user = "test_user", token = "abcdef") } ) end + +def log_in(user) + visit '/' + fill_in :user_email, :with => user.email + fill_in :user_password, :with => 'password' + click_on I18n.t('devise.sessions.new.sign_in') +end diff --git a/spec/acceptance/app_regenerate_api_key_spec.rb b/spec/acceptance/app_regenerate_api_key_spec.rb new file mode 100644 index 0000000..a5494e0 --- /dev/null +++ b/spec/acceptance/app_regenerate_api_key_spec.rb @@ -0,0 +1,29 @@ +require 'acceptance/acceptance_helper' + +feature "Regeneration api_Key" do + let!(:app) { Fabricate(:app) } + let!(:admin) { Fabricate(:admin) } + let(:user) { + Fabricate(:user_watcher, :app => app).user + } + + scenario "an admin change api_key" do + visit '/' + log_in admin + click_link app.name + click_link I18n.t('apps.show.edit') + expect { + click_link I18n.t('apps.fields.regenerate_api_key') + }.to change { + app.reload.api_key + } + end + + scenario "a user cannot access to edit page" do + visit '/' + log_in user + click_link app.name if page.current_url != app_url(app) + expect(page).to_not have_button I18n.t('apps.show.edit') + end + +end diff --git a/spec/acceptance/watch_unwatch_app.rb b/spec/acceptance/watch_unwatch_app.rb deleted file mode 100644 index 4087221..0000000 --- a/spec/acceptance/watch_unwatch_app.rb +++ /dev/null @@ -1,23 +0,0 @@ -require 'acceptance/acceptance_helper' - -feature 'A user can watch and unwatch an application' do - - let!(:app) { Fabricate(:app) } - let!(:user) do - user = Fabricate(:user) - app.watchers.create!( - :user_id => user.id - ) - user.reload - end - - scenario 'log in watch a project and unwatch it' do - visit '/' - fill_in :user_email, :with => user.email - fill_in :user_password, :with => 'password' - click_on I18n.t('devise.sessions.new.sign_in') - click_on I18n.t('apps.show.unwatch') - expect(page).to have_content(I18n.t('apps.index.no_apps') - end - -end diff --git a/spec/acceptance/watch_unwatch_app_spec.rb b/spec/acceptance/watch_unwatch_app_spec.rb new file mode 100644 index 0000000..c718cdc --- /dev/null +++ b/spec/acceptance/watch_unwatch_app_spec.rb @@ -0,0 +1,20 @@ +require 'acceptance/acceptance_helper' + +feature 'A user can watch and unwatch an application' do + + let!(:app) { Fabricate(:app) } + let!(:user) do + user = Fabricate(:user) + app.watchers.create!( + :user_id => user.id + ) + user.reload + end + + scenario 'log in watch a project and unwatch it' do + log_in user + click_on I18n.t('apps.show.unwatch') + expect(page).to have_content(I18n.t('apps.index.no_apps')) + end + +end diff --git a/spec/controllers/apps_controller_spec.rb b/spec/controllers/apps_controller_spec.rb index 165067a..b4a29a8 100644 --- a/spec/controllers/apps_controller_spec.rb +++ b/spec/controllers/apps_controller_spec.rb @@ -5,11 +5,37 @@ describe AppsController do it_requires_authentication it_requires_admin_privileges :for => {:new => :get, :edit => :get, :create => :post, :update => :put, :destroy => :delete} + let(:admin) { Fabricate(:admin) } + let(:user) { Fabricate(:user) } + let(:watcher) { Fabricate(:user_watcher, :app => app, :user => user) } + let(:unwatched_app) { Fabricate(:app) } + let(:app) { unwatched_app } + let(:watched_app1) do + a = Fabricate(:app) + Fabricate(:user_watcher, :user => user, :app => a) + a + end + let(:watched_app2) do + a = Fabricate(:app) + Fabricate(:user_watcher, :user => user, :app => a) + a + end + let(:err) do + Fabricate(:err, :problem => problem) + end + let(:notice) do + Fabricate(:notice, :err => err) + end + let(:problem) do + Fabricate(:problem, :app => app) + end + let(:problem_resolved) { Fabricate(:problem_resolved, :app => app) } + describe "GET /apps" do context 'when logged in as an admin' do it 'finds all apps' do - sign_in Fabricate(:admin) - 3.times { Fabricate(:app) } + sign_in admin + unwatched_app && watched_app1 && watched_app2 get :index controller.apps.entries.should == App.all.sort.entries end @@ -17,12 +43,8 @@ describe AppsController do context 'when logged in as a regular user' do it 'finds apps the user is watching' do - sign_in(user = Fabricate(:user)) - unwatched_app = Fabricate(:app) - watched_app1 = Fabricate(:app) - watched_app2 = Fabricate(:app) - Fabricate(:user_watcher, :user => user, :app => watched_app1) - Fabricate(:user_watcher, :user => user, :app => watched_app2) + sign_in(user) + watched_app1 && watched_app2 && unwatched_app get :index controller.apps.should include(watched_app1, watched_app2) controller.apps.should_not include(unwatched_app) @@ -33,61 +55,56 @@ describe AppsController do describe "GET /apps/:id" do context 'logged in as an admin' do before(:each) do - @user = Fabricate(:admin) - sign_in @user - @app = Fabricate(:app) - @problem = Fabricate(:notice, :err => Fabricate(:err, :problem => Fabricate(:problem, :app => @app))).problem + sign_in admin end it 'finds the app' do - get :show, :id => @app.id - controller.app.should == @app + get :show, :id => app.id + controller.app.should == app end it "should not raise errors for app with err without notices" do - Fabricate(:err, :problem => Fabricate(:problem, :app => @app)) - lambda { get :show, :id => @app.id }.should_not raise_error + err + lambda { get :show, :id => app.id }.should_not raise_error end it "should list atom feed successfully" do - get :show, :id => @app.id, :format => "atom" + get :show, :id => app.id, :format => "atom" response.should be_success end context "pagination" do before(:each) do - 35.times { Fabricate(:err, :problem => Fabricate(:problem, :app => @app)) } + 35.times { Fabricate(:err, :problem => Fabricate(:problem, :app => app)) } end it "should have default per_page value for user" do - get :show, :id => @app.id + get :show, :id => app.id controller.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 :show, :id => @app.id + admin.update_attribute :per_page, 10 + get :show, :id => app.id controller.problems.to_a.size.should == 10 end end context 'with resolved errors' do before(:each) do - resolved_problem = Fabricate(:problem, :app => @app) - Fabricate(:notice, :err => Fabricate(:err, :problem => resolved_problem)) - resolved_problem.resolve! + problem_resolved && problem end context 'and no params' do it 'shows only unresolved problems' do - get :show, :id => @app.id + get :show, :id => app.id controller.problems.size.should == 1 end end context 'and all_problems=true params' do it 'shows all errors' do - get :show, :id => @app.id, :all_errs => true + get :show, :id => app.id, :all_errs => true controller.problems.size.should == 2 end end @@ -97,41 +114,41 @@ describe AppsController do before(:each) do environments = ['production', 'test', 'development', 'staging'] 20.times do |i| - Fabricate(:problem, :app => @app, :environment => environments[i % environments.length]) + Fabricate(:problem, :app => app, :environment => environments[i % environments.length]) end end context 'no params' do it 'shows errs for all environments' do - get :show, :id => @app.id - controller.problems.size.should == 21 + get :show, :id => app.id + controller.problems.size.should == 20 end end context 'environment production' do it 'shows errs for just production' do - get :show, :id => @app.id, :environment => 'production' - controller.problems.size.should == 6 + get :show, :id => app.id, :environment => 'production' + controller.problems.size.should == 5 end end context 'environment staging' do it 'shows errs for just staging' do - get :show, :id => @app.id, :environment => 'staging' + get :show, :id => app.id, :environment => 'staging' controller.problems.size.should == 5 end end context 'environment development' do it 'shows errs for just development' do - get :show, :id => @app.id, :environment => 'development' + get :show, :id => app.id, :environment => 'development' controller.problems.size.should == 5 end end context 'environment test' do it 'shows errs for just test' do - get :show, :id => @app.id, :environment => 'test' + get :show, :id => app.id, :environment => 'test' controller.problems.size.should == 5 end end @@ -140,9 +157,7 @@ describe AppsController do context 'logged in as a user' do it 'finds the app if the user is watching it' do - user = Fabricate(:user) - app = Fabricate(:app) - watcher = Fabricate(:user_watcher, :app => app, :user => user) + watcher sign_in user get :show, :id => app.id controller.app.should == app @@ -160,7 +175,7 @@ describe AppsController do context 'logged in as an admin' do before do - sign_in Fabricate(:admin) + sign_in admin end describe "GET /apps/new" do @@ -345,6 +360,34 @@ describe AppsController do end end + describe "POST /apps/:id/regenerate_api_key" do + + context "like watcher" do + before do + sign_in watcher.user + end + + it 'redirect to root with flash error' do + post :regenerate_api_key, :id => 'foo' + expect(request).to redirect_to root_path + end + + end + + context "like admin" do + before do + sign_in admin + end + + it 'redirect_to app view' do + expect do + post :regenerate_api_key, :id => app.id + expect(request).to redirect_to edit_app_path(app) + end.to change { app.api_key } + end + end + + end end diff --git a/spec/fabricators/err_fabricator.rb b/spec/fabricators/err_fabricator.rb index c50e392..14ad9f3 100644 --- a/spec/fabricators/err_fabricator.rb +++ b/spec/fabricators/err_fabricator.rb @@ -21,3 +21,4 @@ Fabricator :backtrace_line do file { "/path/to/file/#{SecureRandom.hex(4)}.rb" } method(:method) { ActiveSupport.methods.shuffle.first } end + diff --git a/spec/fabricators/problem_fabricator.rb b/spec/fabricators/problem_fabricator.rb index 4ef1de0..537c37a 100644 --- a/spec/fabricators/problem_fabricator.rb +++ b/spec/fabricators/problem_fabricator.rb @@ -21,4 +21,10 @@ Fabricator(:problem_with_errs, :from => :problem) do } end - +Fabricator(:problem_resolved, :from => :problem) do + after_create do |pr| + Fabricate(:notice, + :err => Fabricate(:err, :problem => pr)) + pr.resolve! + end +end -- libgit2 0.21.2