mirror of https://github.com/Siphonay/mastodon
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
|
|
|
@ -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
|
- content_for :page_title do
|
||||||
= t('doorkeeper.applications.new.title')
|
= t('doorkeeper.applications.new.title')
|
||||||
|
|
||||||
= simple_form_for @application, url: settings_applications_path do |f|
|
= simple_form_for @application, url: settings_applications_path do |form|
|
||||||
= render 'fields', f: f
|
= render form
|
||||||
|
|
||||||
.actions
|
.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/
|
%hr/
|
||||||
|
|
||||||
= simple_form_for @application, url: settings_application_path(@application), method: :put do |f|
|
= simple_form_for @application, url: settings_application_path(@application), method: :put do |form|
|
||||||
= render 'fields', f: f
|
= render form
|
||||||
|
|
||||||
.actions
|
.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
|
|
|
@ -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
|
|
@ -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…
Reference in New Issue