Convert settings/applications controller spec to system/request specs (#32006)
				
					
				
			This commit is contained in:
		
							parent
							
								
									aaab6b7adc
								
							
						
					
					
						commit
						5dfdec6453
					
				| @ -1,36 +0,0 @@ | ||||
| .fields-group | ||||
|   = f.input :name, | ||||
|             label: t('activerecord.attributes.doorkeeper/application.name'), | ||||
|             wrapper: :with_label | ||||
| 
 | ||||
| .fields-group | ||||
|   = f.input :website, | ||||
|             label: t('activerecord.attributes.doorkeeper/application.website'), | ||||
|             wrapper: :with_label | ||||
| 
 | ||||
| .fields-group | ||||
|   = f.input :redirect_uri, | ||||
|             label: t('activerecord.attributes.doorkeeper/application.redirect_uri'), hint: t('doorkeeper.applications.help.redirect_uri'), | ||||
|             required: true, | ||||
|             wrapper: :with_block_label | ||||
| 
 | ||||
|   %p.hint= t('doorkeeper.applications.help.native_redirect_uri', native_redirect_uri: content_tag(:code, Doorkeeper.configuration.native_redirect_uri)).html_safe | ||||
| 
 | ||||
| .field-group | ||||
|   .input.with_block_label | ||||
|     %label= t('activerecord.attributes.doorkeeper/application.scopes') | ||||
|     %span.hint= t('simple_form.hints.defaults.scopes') | ||||
| 
 | ||||
|   - Doorkeeper.configuration.scopes.group_by { |s| s.split(':').first }.each_value do |value| | ||||
|     = f.input :scopes, | ||||
|               as: :check_boxes, | ||||
|               collection_wrapper_tag: 'ul', | ||||
|               collection: value.sort, | ||||
|               hint: false, | ||||
|               include_blank: false, | ||||
|               item_wrapper_tag: 'li', | ||||
|               label_method: ->(scope) { safe_join([content_tag(:samp, scope, class: class_for_scope(scope)), content_tag(:span, t("doorkeeper.scopes.#{scope}"), class: 'hint')]) }, | ||||
|               label: false, | ||||
|               required: false, | ||||
|               selected: f.object.scopes.all, | ||||
|               wrapper: :with_block_label | ||||
							
								
								
									
										36
									
								
								app/views/settings/applications/_form.html.haml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								app/views/settings/applications/_form.html.haml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | ||||
| .fields-group | ||||
|   = form.input :name, | ||||
|                label: t('activerecord.attributes.doorkeeper/application.name'), | ||||
|                wrapper: :with_label | ||||
| 
 | ||||
| .fields-group | ||||
|   = form.input :website, | ||||
|                label: t('activerecord.attributes.doorkeeper/application.website'), | ||||
|                wrapper: :with_label | ||||
| 
 | ||||
| .fields-group | ||||
|   = form.input :redirect_uri, | ||||
|                label: t('activerecord.attributes.doorkeeper/application.redirect_uri'), hint: t('doorkeeper.applications.help.redirect_uri'), | ||||
|                required: true, | ||||
|                wrapper: :with_block_label | ||||
| 
 | ||||
|   %p.hint= t('doorkeeper.applications.help.native_redirect_uri', native_redirect_uri: content_tag(:code, Doorkeeper.configuration.native_redirect_uri)).html_safe | ||||
| 
 | ||||
| .field-group | ||||
|   .input.with_block_label | ||||
|     %label= t('activerecord.attributes.doorkeeper/application.scopes') | ||||
|     %span.hint= t('simple_form.hints.defaults.scopes') | ||||
| 
 | ||||
|   - Doorkeeper.configuration.scopes.group_by { |s| s.split(':').first }.each_value do |value| | ||||
|     = form.input :scopes, | ||||
|                  as: :check_boxes, | ||||
|                  collection_wrapper_tag: 'ul', | ||||
|                  collection: value.sort, | ||||
|                  hint: false, | ||||
|                  include_blank: false, | ||||
|                  item_wrapper_tag: 'li', | ||||
|                  label_method: ->(scope) { safe_join([content_tag(:samp, scope, class: class_for_scope(scope)), content_tag(:span, t("doorkeeper.scopes.#{scope}"), class: 'hint')]) }, | ||||
|                  label: false, | ||||
|                  required: false, | ||||
|                  selected: form.object.scopes.all, | ||||
|                  wrapper: :with_block_label | ||||
| @ -1,8 +1,8 @@ | ||||
| - content_for :page_title do | ||||
|   = t('doorkeeper.applications.new.title') | ||||
| 
 | ||||
| = simple_form_for @application, url: settings_applications_path do |f| | ||||
|   = render 'fields', f: f | ||||
| = simple_form_for @application, url: settings_applications_path do |form| | ||||
|   = render form | ||||
| 
 | ||||
|   .actions | ||||
|     = f.button :button, t('doorkeeper.applications.buttons.submit'), type: :submit | ||||
|     = form.button :button, t('doorkeeper.applications.buttons.submit'), type: :submit | ||||
|  | ||||
| @ -23,8 +23,8 @@ | ||||
| 
 | ||||
| %hr/ | ||||
| 
 | ||||
| = simple_form_for @application, url: settings_application_path(@application), method: :put do |f| | ||||
|   = render 'fields', f: f | ||||
| = simple_form_for @application, url: settings_application_path(@application), method: :put do |form| | ||||
|   = render form | ||||
| 
 | ||||
|   .actions | ||||
|     = f.button :button, t('generic.save_changes'), type: :submit | ||||
|     = form.button :button, t('generic.save_changes'), type: :submit | ||||
|  | ||||
| @ -1,178 +0,0 @@ | ||||
| # frozen_string_literal: true | ||||
| 
 | ||||
| require 'rails_helper' | ||||
| 
 | ||||
| RSpec.describe Settings::ApplicationsController do | ||||
|   render_views | ||||
| 
 | ||||
|   let!(:user) { Fabricate(:user) } | ||||
|   let!(:app) { Fabricate(:application, owner: user) } | ||||
| 
 | ||||
|   before do | ||||
|     sign_in user, scope: :user | ||||
|   end | ||||
| 
 | ||||
|   describe 'GET #index' do | ||||
|     before do | ||||
|       Fabricate(:application) | ||||
|       get :index | ||||
|     end | ||||
| 
 | ||||
|     it 'returns http success with private cache control headers', :aggregate_failures do | ||||
|       expect(response).to have_http_status(200) | ||||
|       expect(response.headers['Cache-Control']).to include('private, no-store') | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   describe 'GET #show' do | ||||
|     it 'returns http success' do | ||||
|       get :show, params: { id: app.id } | ||||
|       expect(response).to have_http_status(200) | ||||
|       expect(assigns[:application]).to eql(app) | ||||
|     end | ||||
| 
 | ||||
|     it 'returns 404 if you dont own app' do | ||||
|       app.update!(owner: nil) | ||||
| 
 | ||||
|       get :show, params: { id: app.id } | ||||
|       expect(response).to have_http_status 404 | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   describe 'GET #new' do | ||||
|     it 'returns http success' do | ||||
|       get :new | ||||
|       expect(response).to have_http_status(200) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   describe 'POST #create' do | ||||
|     context 'when success (passed scopes as a String)' do | ||||
|       subject do | ||||
|         post :create, params: { | ||||
|           doorkeeper_application: { | ||||
|             name: 'My New App', | ||||
|             redirect_uri: 'urn:ietf:wg:oauth:2.0:oob', | ||||
|             website: 'http://google.com', | ||||
|             scopes: 'read write follow', | ||||
|           }, | ||||
|         } | ||||
|       end | ||||
| 
 | ||||
|       it 'creates an entry in the database', :aggregate_failures do | ||||
|         expect { subject }.to change(Doorkeeper::Application, :count) | ||||
|         expect(response).to redirect_to(settings_applications_path) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     context 'when success (passed scopes as an Array)' do | ||||
|       subject do | ||||
|         post :create, params: { | ||||
|           doorkeeper_application: { | ||||
|             name: 'My New App', | ||||
|             redirect_uri: 'urn:ietf:wg:oauth:2.0:oob', | ||||
|             website: 'http://google.com', | ||||
|             scopes: %w(read write follow), | ||||
|           }, | ||||
|         } | ||||
|       end | ||||
| 
 | ||||
|       it 'creates an entry in the database', :aggregate_failures do | ||||
|         expect { subject }.to change(Doorkeeper::Application, :count) | ||||
|         expect(response).to redirect_to(settings_applications_path) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     context 'with failure request' do | ||||
|       before do | ||||
|         post :create, params: { | ||||
|           doorkeeper_application: { | ||||
|             name: '', | ||||
|             redirect_uri: '', | ||||
|             website: '', | ||||
|             scopes: [], | ||||
|           }, | ||||
|         } | ||||
|       end | ||||
| 
 | ||||
|       it 'returns http success and renders form', :aggregate_failures do | ||||
|         expect(response).to have_http_status(200) | ||||
|         expect(response).to render_template(:new) | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   describe 'PATCH #update' do | ||||
|     context 'when success' do | ||||
|       subject do | ||||
|         patch :update, params: { | ||||
|           id: app.id, | ||||
|           doorkeeper_application: opts, | ||||
|         } | ||||
|         response | ||||
|       end | ||||
| 
 | ||||
|       let(:opts) do | ||||
|         { | ||||
|           website: 'https://foo.bar/', | ||||
|         } | ||||
|       end | ||||
| 
 | ||||
|       it 'updates existing application' do | ||||
|         subject | ||||
| 
 | ||||
|         expect(app.reload.website).to eql(opts[:website]) | ||||
|         expect(response).to redirect_to(settings_application_path(app)) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     context 'with failure request' do | ||||
|       before do | ||||
|         patch :update, params: { | ||||
|           id: app.id, | ||||
|           doorkeeper_application: { | ||||
|             name: '', | ||||
|             redirect_uri: '', | ||||
|             website: '', | ||||
|             scopes: [], | ||||
|           }, | ||||
|         } | ||||
|       end | ||||
| 
 | ||||
|       it 'returns http success and renders form', :aggregate_failures do | ||||
|         expect(response).to have_http_status(200) | ||||
|         expect(response).to render_template(:show) | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   describe 'destroy' do | ||||
|     let(:redis_pipeline_stub) { instance_double(Redis::Namespace, publish: nil) } | ||||
|     let!(:access_token) { Fabricate(:accessible_access_token, application: app) } | ||||
| 
 | ||||
|     before do | ||||
|       allow(redis).to receive(:pipelined).and_yield(redis_pipeline_stub) | ||||
|       post :destroy, params: { id: app.id } | ||||
|     end | ||||
| 
 | ||||
|     it 'redirects back to applications page removes the app' do | ||||
|       expect(response).to redirect_to(settings_applications_path) | ||||
|       expect(Doorkeeper::Application.find_by(id: app.id)).to be_nil | ||||
|     end | ||||
| 
 | ||||
|     it 'sends a session kill payload to the streaming server' do | ||||
|       expect(redis_pipeline_stub).to have_received(:publish).with("timeline:access_token:#{access_token.id}", '{"event":"kill"}') | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   describe 'regenerate' do | ||||
|     let(:token) { user.token_for_app(app) } | ||||
| 
 | ||||
|     it 'creates new token' do | ||||
|       expect(token).to_not be_nil | ||||
|       post :regenerate, params: { id: app.id } | ||||
| 
 | ||||
|       expect(user.token_for_app(app)).to_not eql(token) | ||||
|     end | ||||
|   end | ||||
| end | ||||
							
								
								
									
										44
									
								
								spec/requests/settings/applications_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								spec/requests/settings/applications_spec.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| # frozen_string_literal: true | ||||
| 
 | ||||
| require 'rails_helper' | ||||
| 
 | ||||
| RSpec.describe 'Settings / Exports' do | ||||
|   let(:user) { Fabricate :user } | ||||
| 
 | ||||
|   before { sign_in user } | ||||
| 
 | ||||
|   describe 'GET /settings/application/:id' do | ||||
|     context 'when user does not own application' do | ||||
|       let(:application) { Fabricate :application } | ||||
| 
 | ||||
|       it 'returns http missing' do | ||||
|         get settings_application_path(application) | ||||
| 
 | ||||
|         expect(response) | ||||
|           .to have_http_status(404) | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   describe 'POST /settings/applications' do | ||||
|     subject { post '/settings/applications', params: params } | ||||
| 
 | ||||
|     let(:params) do | ||||
|       { | ||||
|         doorkeeper_application: { | ||||
|           name: 'My New App', | ||||
|           redirect_uri: 'urn:ietf:wg:oauth:2.0:oob', | ||||
|           website: 'http://google.com', | ||||
|           scopes: 'read write follow', | ||||
|         }, | ||||
|       } | ||||
|     end | ||||
| 
 | ||||
|     it 'supports passing scope values as string' do | ||||
|       expect { subject } | ||||
|         .to change(Doorkeeper::Application, :count).by(1) | ||||
|       expect(response) | ||||
|         .to redirect_to(settings_applications_path) | ||||
|     end | ||||
|   end | ||||
| end | ||||
							
								
								
									
										144
									
								
								spec/system/settings/applications_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								spec/system/settings/applications_spec.rb
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,144 @@ | ||||
| # frozen_string_literal: true | ||||
| 
 | ||||
| require 'rails_helper' | ||||
| 
 | ||||
| RSpec.describe 'Settings applications page' do | ||||
|   let!(:application) { Fabricate :application, owner: user } | ||||
|   let(:user) { Fabricate :user } | ||||
| 
 | ||||
|   before { sign_in user } | ||||
| 
 | ||||
|   describe 'Viewing the list of applications' do | ||||
|     it 'sees the applications' do | ||||
|       visit settings_applications_path | ||||
| 
 | ||||
|       expect(page) | ||||
|         .to have_content(application.name) | ||||
|         .and have_private_cache_control | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   describe 'Viewing a single application' do | ||||
|     it 'shows a page with application details' do | ||||
|       visit settings_application_path(application) | ||||
| 
 | ||||
|       expect(page) | ||||
|         .to have_content(application.name) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   describe 'Creating a new application' do | ||||
|     it 'accepts form input to make an application' do | ||||
|       visit new_settings_application_path | ||||
| 
 | ||||
|       fill_in_form | ||||
| 
 | ||||
|       expect { submit_form } | ||||
|         .to change(Doorkeeper::Application, :count).by(1) | ||||
|       expect(page) | ||||
|         .to have_content(I18n.t('doorkeeper.applications.index.title')) | ||||
|         .and have_content('My new app') | ||||
|     end | ||||
| 
 | ||||
|     it 'does not save with invalid form values' do | ||||
|       visit new_settings_application_path | ||||
| 
 | ||||
|       expect { submit_form } | ||||
|         .to not_change(Doorkeeper::Application, :count) | ||||
|       expect(page) | ||||
|         .to have_content("can't be blank") | ||||
|     end | ||||
| 
 | ||||
|     def fill_in_form | ||||
|       fill_in form_app_name_label, | ||||
|               with: 'My new app' | ||||
|       fill_in I18n.t('activerecord.attributes.doorkeeper/application.website'), | ||||
|               with: 'http://google.com' | ||||
|       fill_in I18n.t('activerecord.attributes.doorkeeper/application.redirect_uri'), | ||||
|               with: 'urn:ietf:wg:oauth:2.0:oob' | ||||
| 
 | ||||
|       check 'read', id: :doorkeeper_application_scopes_read | ||||
|       check 'write', id: :doorkeeper_application_scopes_write | ||||
|       check 'follow', id: :doorkeeper_application_scopes_follow | ||||
|     end | ||||
| 
 | ||||
|     def submit_form | ||||
|       click_on I18n.t('doorkeeper.applications.buttons.submit') | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   describe 'Updating an application' do | ||||
|     it 'successfully updates with valid values' do | ||||
|       visit settings_application_path(application) | ||||
| 
 | ||||
|       fill_in form_app_name_label, | ||||
|               with: 'My new app name with a new value' | ||||
|       submit_form | ||||
| 
 | ||||
|       expect(page) | ||||
|         .to have_content('My new app name with a new value') | ||||
|     end | ||||
| 
 | ||||
|     it 'does not update with wrong values' do | ||||
|       visit settings_application_path(application) | ||||
| 
 | ||||
|       fill_in form_app_name_label, | ||||
|               with: '' | ||||
|       submit_form | ||||
| 
 | ||||
|       expect(page) | ||||
|         .to have_content("can't be blank") | ||||
|     end | ||||
| 
 | ||||
|     def submit_form | ||||
|       click_on I18n.t('generic.save_changes') | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   describe 'Destroying an application' do | ||||
|     let(:redis_pipeline_stub) { instance_double(Redis::Namespace, publish: nil) } | ||||
|     let!(:access_token) { Fabricate(:accessible_access_token, application: application) } | ||||
| 
 | ||||
|     before { stub_redis_pipeline } | ||||
| 
 | ||||
|     it 'destroys the record and tells the broader universe about that' do | ||||
|       visit settings_applications_path | ||||
| 
 | ||||
|       expect { destroy_application } | ||||
|         .to change(Doorkeeper::Application, :count).by(-1) | ||||
|       expect(page) | ||||
|         .to have_no_content(application.name) | ||||
|       expect(redis_pipeline_stub) | ||||
|         .to have_received(:publish).with("timeline:access_token:#{access_token.id}", '{"event":"kill"}') | ||||
|     end | ||||
| 
 | ||||
|     def destroy_application | ||||
|       click_on I18n.t('doorkeeper.applications.index.delete') | ||||
|     end | ||||
| 
 | ||||
|     def stub_redis_pipeline | ||||
|       allow(redis) | ||||
|         .to receive(:pipelined) | ||||
|         .and_yield(redis_pipeline_stub) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   describe 'Regenerating an app token' do | ||||
|     it 'updates the app token' do | ||||
|       visit settings_application_path(application) | ||||
| 
 | ||||
|       expect { regenerate_token } | ||||
|         .to(change { user.token_for_app(application) }) | ||||
|       expect(page) | ||||
|         .to have_content(I18n.t('applications.token_regenerated')) | ||||
|     end | ||||
| 
 | ||||
|     def regenerate_token | ||||
|       click_on I18n.t('applications.regenerate_token') | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def form_app_name_label | ||||
|     I18n.t('activerecord.attributes.doorkeeper/application.name') | ||||
|   end | ||||
| end | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user