Change user settings to be stored in a more optimal way (#23630)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
parent
e7c3e55874
commit
a9b5598c97
36 changed files with 817 additions and 525 deletions
|
@ -46,6 +46,7 @@ describe Api::V1::Accounts::CredentialsController do
|
|||
end
|
||||
|
||||
it 'updates account info' do
|
||||
user.reload
|
||||
user.account.reload
|
||||
|
||||
expect(user.account.display_name).to eq("Alice Isn't Dead")
|
||||
|
|
|
@ -88,21 +88,19 @@ describe ApplicationController, type: :controller do
|
|||
|
||||
it 'returns instances\'s default theme when user didn\'t set theme' do
|
||||
current_user = Fabricate(:user)
|
||||
current_user.settings.update(theme: 'contrast', noindex: false)
|
||||
current_user.save
|
||||
sign_in current_user
|
||||
|
||||
allow(Setting).to receive(:[]).with('theme').and_return 'contrast'
|
||||
allow(Setting).to receive(:[]).with('noindex').and_return false
|
||||
|
||||
expect(controller.view_context.current_theme).to eq 'contrast'
|
||||
end
|
||||
|
||||
it 'returns user\'s theme when it is set' do
|
||||
current_user = Fabricate(:user)
|
||||
current_user.settings['theme'] = 'mastodon-light'
|
||||
current_user.settings.update(theme: 'mastodon-light')
|
||||
current_user.save
|
||||
sign_in current_user
|
||||
|
||||
allow(Setting).to receive(:[]).with('theme').and_return 'contrast'
|
||||
|
||||
expect(controller.view_context.current_theme).to eq 'mastodon-light'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,20 +20,22 @@ describe Settings::Preferences::NotificationsController do
|
|||
|
||||
describe 'PUT #update' do
|
||||
it 'updates notifications settings' do
|
||||
user.settings['notification_emails'] = user.settings['notification_emails'].merge('follow' => false)
|
||||
user.settings['interactions'] = user.settings['interactions'].merge('must_be_follower' => true)
|
||||
user.settings.update('notification_emails.follow': false, 'interactions.must_be_follower': true)
|
||||
user.save
|
||||
|
||||
put :update, params: {
|
||||
user: {
|
||||
notification_emails: { follow: '1' },
|
||||
interactions: { must_be_follower: '0' },
|
||||
settings_attributes: {
|
||||
'notification_emails.follow': '1',
|
||||
'interactions.must_be_follower': '0',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
expect(response).to redirect_to(settings_preferences_notifications_path)
|
||||
user.reload
|
||||
expect(user.settings['notification_emails']['follow']).to be true
|
||||
expect(user.settings['interactions']['must_be_follower']).to be false
|
||||
expect(user.settings['notification_emails.follow']).to be true
|
||||
expect(user.settings['interactions.must_be_follower']).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,20 +29,22 @@ describe Settings::Preferences::OtherController do
|
|||
end
|
||||
|
||||
it 'updates user settings' do
|
||||
user.settings['boost_modal'] = false
|
||||
user.settings['delete_modal'] = true
|
||||
user.settings.update('web.reblog_modal': false, 'web.delete_modal': true)
|
||||
user.save
|
||||
|
||||
put :update, params: {
|
||||
user: {
|
||||
setting_boost_modal: '1',
|
||||
setting_delete_modal: '0',
|
||||
settings_attributes: {
|
||||
'web.reblog_modal': '1',
|
||||
'web.delete_modal': '0',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
expect(response).to redirect_to(settings_preferences_other_path)
|
||||
user.reload
|
||||
expect(user.settings['boost_modal']).to be true
|
||||
expect(user.settings['delete_modal']).to be false
|
||||
expect(user.settings['web.reblog_modal']).to be true
|
||||
expect(user.settings['web.delete_modal']).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Settings::Extend do
|
||||
class User
|
||||
include Settings::Extend
|
||||
end
|
||||
|
||||
describe '#settings' do
|
||||
it 'sets @settings as an instance of Settings::ScopedSettings' do
|
||||
user = Fabricate(:user)
|
||||
expect(user.settings).to be_a Settings::ScopedSettings
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Settings::ScopedSettings do
|
||||
let(:object) { Fabricate(:user) }
|
||||
let(:scoped_setting) { described_class.new(object) }
|
||||
let(:val) { 'whatever' }
|
||||
let(:methods) { %i(auto_play_gif default_sensitive unfollow_modal boost_modal delete_modal reduce_motion system_font_ui noindex theme) }
|
||||
|
||||
describe '.initialize' do
|
||||
it 'sets @object' do
|
||||
scoped_setting = described_class.new(object)
|
||||
expect(scoped_setting.instance_variable_get(:@object)).to be object
|
||||
end
|
||||
end
|
||||
|
||||
describe '#method_missing' do
|
||||
it 'sets scoped_setting.method_name = val' do
|
||||
methods.each do |key|
|
||||
scoped_setting.send("#{key}=", val)
|
||||
expect(scoped_setting.send(key)).to eq val
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#[]= and #[]' do
|
||||
it 'sets [key] = val' do
|
||||
methods.each do |key|
|
||||
scoped_setting[key] = val
|
||||
expect(scoped_setting[key]).to eq val
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,84 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe UserSettingsDecorator do
|
||||
describe 'update' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:settings) { described_class.new(user) }
|
||||
|
||||
it 'updates the user settings value for email notifications' do
|
||||
values = { 'notification_emails' => { 'follow' => '1' } }
|
||||
|
||||
settings.update(values)
|
||||
expect(user.settings['notification_emails']['follow']).to be true
|
||||
end
|
||||
|
||||
it 'updates the user settings value for interactions' do
|
||||
values = { 'interactions' => { 'must_be_follower' => '0' } }
|
||||
|
||||
settings.update(values)
|
||||
expect(user.settings['interactions']['must_be_follower']).to be false
|
||||
end
|
||||
|
||||
it 'updates the user settings value for privacy' do
|
||||
values = { 'setting_default_privacy' => 'public' }
|
||||
|
||||
settings.update(values)
|
||||
expect(user.settings['default_privacy']).to eq 'public'
|
||||
end
|
||||
|
||||
it 'updates the user settings value for sensitive' do
|
||||
values = { 'setting_default_sensitive' => '1' }
|
||||
|
||||
settings.update(values)
|
||||
expect(user.settings['default_sensitive']).to be true
|
||||
end
|
||||
|
||||
it 'updates the user settings value for unfollow modal' do
|
||||
values = { 'setting_unfollow_modal' => '0' }
|
||||
|
||||
settings.update(values)
|
||||
expect(user.settings['unfollow_modal']).to be false
|
||||
end
|
||||
|
||||
it 'updates the user settings value for boost modal' do
|
||||
values = { 'setting_boost_modal' => '1' }
|
||||
|
||||
settings.update(values)
|
||||
expect(user.settings['boost_modal']).to be true
|
||||
end
|
||||
|
||||
it 'updates the user settings value for delete toot modal' do
|
||||
values = { 'setting_delete_modal' => '0' }
|
||||
|
||||
settings.update(values)
|
||||
expect(user.settings['delete_modal']).to be false
|
||||
end
|
||||
|
||||
it 'updates the user settings value for gif auto play' do
|
||||
values = { 'setting_auto_play_gif' => '0' }
|
||||
|
||||
settings.update(values)
|
||||
expect(user.settings['auto_play_gif']).to be false
|
||||
end
|
||||
|
||||
it 'updates the user settings value for system font in UI' do
|
||||
values = { 'setting_system_font_ui' => '0' }
|
||||
|
||||
settings.update(values)
|
||||
expect(user.settings['system_font_ui']).to be false
|
||||
end
|
||||
|
||||
it 'decoerces setting values before applying' do
|
||||
values = {
|
||||
'setting_delete_modal' => 'false',
|
||||
'setting_boost_modal' => 'true',
|
||||
}
|
||||
|
||||
settings.update(values)
|
||||
expect(user.settings['delete_modal']).to be false
|
||||
expect(user.settings['boost_modal']).to be true
|
||||
end
|
||||
end
|
||||
end
|
25
spec/models/user_settings/namespace_spec.rb
Normal file
25
spec/models/user_settings/namespace_spec.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe UserSettings::Namespace do
|
||||
subject { described_class.new(name) }
|
||||
|
||||
let(:name) { :foo }
|
||||
|
||||
describe '#setting' do
|
||||
before do
|
||||
subject.setting :bar, default: 'baz'
|
||||
end
|
||||
|
||||
it 'adds setting to definitions' do
|
||||
expect(subject.definitions[:'foo.bar']).to have_attributes(name: :bar, namespace: :foo, default_value: 'baz')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#definitions' do
|
||||
it 'returns a hash' do
|
||||
expect(subject.definitions).to be_a Hash
|
||||
end
|
||||
end
|
||||
end
|
74
spec/models/user_settings/setting_spec.rb
Normal file
74
spec/models/user_settings/setting_spec.rb
Normal file
|
@ -0,0 +1,74 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe UserSettings::Setting do
|
||||
subject { described_class.new(name, options) }
|
||||
|
||||
let(:name) { :foo }
|
||||
let(:options) { { default: default, namespace: namespace } }
|
||||
let(:default) { false }
|
||||
let(:namespace) { nil }
|
||||
|
||||
describe '#default_value' do
|
||||
context 'when default value is a primitive value' do
|
||||
it 'returns default value' do
|
||||
expect(subject.default_value).to eq default
|
||||
end
|
||||
end
|
||||
|
||||
context 'when default value is a proc' do
|
||||
let(:default) { -> { 'bar' } }
|
||||
|
||||
it 'returns value from proc' do
|
||||
expect(subject.default_value).to eq 'bar'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#type' do
|
||||
it 'returns a type' do
|
||||
expect(subject.type).to be_a ActiveModel::Type::Value
|
||||
end
|
||||
end
|
||||
|
||||
describe '#type_cast' do
|
||||
context 'when default value is a boolean' do
|
||||
let(:default) { false }
|
||||
|
||||
it 'returns boolean' do
|
||||
expect(subject.type_cast('1')).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when default value is a string' do
|
||||
let(:default) { '' }
|
||||
|
||||
it 'returns string' do
|
||||
expect(subject.type_cast(1)).to eq '1'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_a' do
|
||||
it 'returns an array' do
|
||||
expect(subject.to_a).to eq [name, default]
|
||||
end
|
||||
end
|
||||
|
||||
describe '#key' do
|
||||
context 'when there is no namespace' do
|
||||
it 'returnsn a symbol' do
|
||||
expect(subject.key).to eq :foo
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is a namespace' do
|
||||
let(:namespace) { :bar }
|
||||
|
||||
it 'returns a symbol' do
|
||||
expect(subject.key).to eq :'bar.foo'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
110
spec/models/user_settings_spec.rb
Normal file
110
spec/models/user_settings_spec.rb
Normal file
|
@ -0,0 +1,110 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe UserSettings do
|
||||
subject { described_class.new(json) }
|
||||
|
||||
let(:json) { {} }
|
||||
|
||||
describe '#[]' do
|
||||
context 'when setting is not set' do
|
||||
it 'returns default value' do
|
||||
expect(subject[:always_send_emails]).to be false
|
||||
end
|
||||
end
|
||||
|
||||
context 'when setting is set' do
|
||||
let(:json) { { default_language: 'fr' } }
|
||||
|
||||
it 'returns value' do
|
||||
expect(subject[:default_language]).to eq 'fr'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when setting was not defined' do
|
||||
it 'raises error' do
|
||||
expect { subject[:foo] }.to raise_error UserSettings::KeyError
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#[]=' do
|
||||
context 'when value matches type' do
|
||||
before do
|
||||
subject[:always_send_emails] = true
|
||||
end
|
||||
|
||||
it 'updates value' do
|
||||
expect(subject[:always_send_emails]).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when value needs to be type-cast' do
|
||||
before do
|
||||
subject[:always_send_emails] = '1'
|
||||
end
|
||||
|
||||
it 'updates value with a type-cast' do
|
||||
expect(subject[:always_send_emails]).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#update' do
|
||||
before do
|
||||
subject.update(always_send_emails: true, default_language: 'fr', default_privacy: nil)
|
||||
end
|
||||
|
||||
it 'updates values' do
|
||||
expect(subject[:always_send_emails]).to be true
|
||||
expect(subject[:default_language]).to eq 'fr'
|
||||
end
|
||||
|
||||
it 'does not set values that are nil' do
|
||||
expect(subject.as_json).to_not include(default_privacy: nil)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#as_json' do
|
||||
let(:json) { { default_language: 'fr' } }
|
||||
|
||||
it 'returns hash' do
|
||||
expect(subject.as_json).to eq json
|
||||
end
|
||||
end
|
||||
|
||||
describe '.keys' do
|
||||
it 'returns an array' do
|
||||
expect(described_class.keys).to be_a Array
|
||||
end
|
||||
end
|
||||
|
||||
describe '.definition_for' do
|
||||
context 'when key is defined' do
|
||||
it 'returns a setting' do
|
||||
expect(described_class.definition_for(:always_send_emails)).to be_a UserSettings::Setting
|
||||
end
|
||||
end
|
||||
|
||||
context 'when key is not defined' do
|
||||
it 'returns nil' do
|
||||
expect(described_class.definition_for(:foo)).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.definition_for?' do
|
||||
context 'when key is defined' do
|
||||
it 'returns true' do
|
||||
expect(described_class.definition_for?(:always_send_emails)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when key is not defined' do
|
||||
it 'returns false' do
|
||||
expect(described_class.definition_for?(:foo)).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -313,9 +313,9 @@ RSpec.describe User, type: :model do
|
|||
end
|
||||
|
||||
describe 'settings' do
|
||||
it 'is instance of Settings::ScopedSettings' do
|
||||
it 'is instance of UserSettings' do
|
||||
user = Fabricate(:user)
|
||||
expect(user.settings).to be_a Settings::ScopedSettings
|
||||
expect(user.settings).to be_a UserSettings
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -379,16 +379,6 @@ RSpec.describe User, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'Settings-extended' do
|
||||
def create!
|
||||
User.create!(account: Fabricate(:account, user: nil), email: 'foo@mastodon.space', password: 'abcd1234', agreement: true)
|
||||
end
|
||||
|
||||
def fabricate
|
||||
Fabricate(:user)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'token_for_app' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:app) { Fabricate(:application, owner: user) }
|
||||
|
|
|
@ -54,7 +54,8 @@ RSpec.describe NotifyService, type: :service do
|
|||
let(:type) { :mention }
|
||||
|
||||
before do
|
||||
user.settings.interactions = user.settings.interactions.merge('must_be_following_dm' => enabled)
|
||||
user.settings.update('interactions.must_be_following_dm': enabled)
|
||||
user.save
|
||||
end
|
||||
|
||||
context 'if recipient is supposed to be following sender' do
|
||||
|
@ -155,8 +156,8 @@ RSpec.describe NotifyService, type: :service do
|
|||
before do
|
||||
ActionMailer::Base.deliveries.clear
|
||||
|
||||
notification_emails = user.settings.notification_emails
|
||||
user.settings.notification_emails = notification_emails.merge('follow' => enabled)
|
||||
user.settings.update('notification_emails.follow': enabled)
|
||||
user.save
|
||||
end
|
||||
|
||||
context 'when email notification is enabled' do
|
||||
|
|
|
@ -96,7 +96,8 @@ RSpec.describe ReportService, type: :service do
|
|||
|
||||
before do
|
||||
ActionMailer::Base.deliveries.clear
|
||||
source_account.user.settings.notification_emails['report'] = true
|
||||
source_account.user.settings['notification_emails.report'] = true
|
||||
source_account.user.save
|
||||
end
|
||||
|
||||
it 'does not send an e-mail' do
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue