Add /api/v1/accounts/familiar_followers to REST API (#17700)
				
					
				
			* Add `/api/v1/accounts/familiar_followers` to REST API * Change hide network preference to be stored consistently for local and remote accounts * Add dummy classes to migration * Apply suggestions from code review Co-authored-by: Claire <claire.github-309c@sitedethib.com> Co-authored-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
		
							parent
							
								
									d99303533e
								
							
						
					
					
						commit
						e3d3b4ae21
					
				
					 22 changed files with 169 additions and 32 deletions
				
			
		|  | @ -0,0 +1,25 @@ | ||||||
|  | # frozen_string_literal: true | ||||||
|  | 
 | ||||||
|  | class Api::V1::Accounts::FamiliarFollowersController < Api::BaseController | ||||||
|  |   before_action -> { doorkeeper_authorize! :read, :'read:follows' } | ||||||
|  |   before_action :require_user! | ||||||
|  |   before_action :set_accounts | ||||||
|  | 
 | ||||||
|  |   def index | ||||||
|  |     render json: familiar_followers.accounts, each_serializer: REST::FamiliarFollowersSerializer | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   private | ||||||
|  | 
 | ||||||
|  |   def set_accounts | ||||||
|  |     @accounts = Account.without_suspended.where(id: account_ids).select('id, hide_collections').index_by(&:id).values_at(*account_ids).compact | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def familiar_followers | ||||||
|  |     FamiliarFollowersPresenter.new(@accounts, current_user.account_id) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def account_ids | ||||||
|  |     Array(params[:id]).map(&:to_i) | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | @ -15,13 +15,13 @@ class FollowerAccountsController < ApplicationController | ||||||
|       format.html do |       format.html do | ||||||
|         expires_in 0, public: true unless user_signed_in? |         expires_in 0, public: true unless user_signed_in? | ||||||
| 
 | 
 | ||||||
|         next if @account.user_hides_network? |         next if @account.hide_collections? | ||||||
| 
 | 
 | ||||||
|         follows |         follows | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       format.json do |       format.json do | ||||||
|         raise Mastodon::NotPermittedError if page_requested? && @account.user_hides_network? |         raise Mastodon::NotPermittedError if page_requested? && @account.hide_collections? | ||||||
| 
 | 
 | ||||||
|         expires_in(page_requested? ? 0 : 3.minutes, public: public_fetch_mode?) |         expires_in(page_requested? ? 0 : 3.minutes, public: public_fetch_mode?) | ||||||
| 
 | 
 | ||||||
|  | @ -82,7 +82,7 @@ class FollowerAccountsController < ApplicationController | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def restrict_fields_to |   def restrict_fields_to | ||||||
|     if page_requested? || !@account.user_hides_network? |     if page_requested? || !@account.hide_collections? | ||||||
|       # Return all fields |       # Return all fields | ||||||
|     else |     else | ||||||
|       %i(id type total_items) |       %i(id type total_items) | ||||||
|  |  | ||||||
|  | @ -15,13 +15,13 @@ class FollowingAccountsController < ApplicationController | ||||||
|       format.html do |       format.html do | ||||||
|         expires_in 0, public: true unless user_signed_in? |         expires_in 0, public: true unless user_signed_in? | ||||||
| 
 | 
 | ||||||
|         next if @account.user_hides_network? |         next if @account.hide_collections? | ||||||
| 
 | 
 | ||||||
|         follows |         follows | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       format.json do |       format.json do | ||||||
|         raise Mastodon::NotPermittedError if page_requested? && @account.user_hides_network? |         raise Mastodon::NotPermittedError if page_requested? && @account.hide_collections? | ||||||
| 
 | 
 | ||||||
|         expires_in(page_requested? ? 0 : 3.minutes, public: public_fetch_mode?) |         expires_in(page_requested? ? 0 : 3.minutes, public: public_fetch_mode?) | ||||||
| 
 | 
 | ||||||
|  | @ -82,7 +82,7 @@ class FollowingAccountsController < ApplicationController | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def restrict_fields_to |   def restrict_fields_to | ||||||
|     if page_requested? || !@account.user_hides_network? |     if page_requested? || !@account.hide_collections? | ||||||
|       # Return all fields |       # Return all fields | ||||||
|     else |     else | ||||||
|       %i(id type total_items) |       %i(id type total_items) | ||||||
|  |  | ||||||
|  | @ -47,7 +47,6 @@ class Settings::PreferencesController < Settings::BaseController | ||||||
|       :setting_system_font_ui, |       :setting_system_font_ui, | ||||||
|       :setting_noindex, |       :setting_noindex, | ||||||
|       :setting_theme, |       :setting_theme, | ||||||
|       :setting_hide_network, |  | ||||||
|       :setting_aggregate_reblogs, |       :setting_aggregate_reblogs, | ||||||
|       :setting_show_application, |       :setting_show_application, | ||||||
|       :setting_advanced_layout, |       :setting_advanced_layout, | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ class Settings::ProfilesController < Settings::BaseController | ||||||
|   private |   private | ||||||
| 
 | 
 | ||||||
|   def account_params |   def account_params | ||||||
|     params.require(:account).permit(:display_name, :note, :avatar, :header, :locked, :bot, :discoverable, fields_attributes: [:name, :value]) |     params.require(:account).permit(:display_name, :note, :avatar, :header, :locked, :bot, :discoverable, :hide_collections, fields_attributes: [:name, :value]) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def set_account |   def set_account | ||||||
|  |  | ||||||
|  | @ -31,7 +31,6 @@ class UserSettingsDecorator | ||||||
|     user.settings['system_font_ui']      = system_font_ui_preference if change?('setting_system_font_ui') |     user.settings['system_font_ui']      = system_font_ui_preference if change?('setting_system_font_ui') | ||||||
|     user.settings['noindex']             = noindex_preference if change?('setting_noindex') |     user.settings['noindex']             = noindex_preference if change?('setting_noindex') | ||||||
|     user.settings['theme']               = theme_preference if change?('setting_theme') |     user.settings['theme']               = theme_preference if change?('setting_theme') | ||||||
|     user.settings['hide_network']        = hide_network_preference if change?('setting_hide_network') |  | ||||||
|     user.settings['aggregate_reblogs']   = aggregate_reblogs_preference if change?('setting_aggregate_reblogs') |     user.settings['aggregate_reblogs']   = aggregate_reblogs_preference if change?('setting_aggregate_reblogs') | ||||||
|     user.settings['show_application']    = show_application_preference if change?('setting_show_application') |     user.settings['show_application']    = show_application_preference if change?('setting_show_application') | ||||||
|     user.settings['advanced_layout']     = advanced_layout_preference if change?('setting_advanced_layout') |     user.settings['advanced_layout']     = advanced_layout_preference if change?('setting_advanced_layout') | ||||||
|  | @ -97,10 +96,6 @@ class UserSettingsDecorator | ||||||
|     boolean_cast_setting 'setting_noindex' |     boolean_cast_setting 'setting_noindex' | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def hide_network_preference |  | ||||||
|     boolean_cast_setting 'setting_hide_network' |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def show_application_preference |   def show_application_preference | ||||||
|     boolean_cast_setting 'setting_show_application' |     boolean_cast_setting 'setting_show_application' | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  | @ -349,11 +349,11 @@ class Account < ApplicationRecord | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def hides_followers? |   def hides_followers? | ||||||
|     hide_collections? || user_hides_network? |     hide_collections? | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def hides_following? |   def hides_following? | ||||||
|     hide_collections? || user_hides_network? |     hide_collections? | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def object_type |   def object_type | ||||||
|  |  | ||||||
|  | @ -126,7 +126,7 @@ class User < ApplicationRecord | ||||||
|   has_many :session_activations, dependent: :destroy |   has_many :session_activations, dependent: :destroy | ||||||
| 
 | 
 | ||||||
|   delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :delete_modal, |   delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :delete_modal, | ||||||
|            :reduce_motion, :system_font_ui, :noindex, :theme, :display_media, :hide_network, |            :reduce_motion, :system_font_ui, :noindex, :theme, :display_media, | ||||||
|            :expand_spoilers, :default_language, :aggregate_reblogs, :show_application, |            :expand_spoilers, :default_language, :aggregate_reblogs, :show_application, | ||||||
|            :advanced_layout, :use_blurhash, :use_pending_items, :trends, :crop_images, |            :advanced_layout, :use_blurhash, :use_pending_items, :trends, :crop_images, | ||||||
|            :disable_swiping, |            :disable_swiping, | ||||||
|  | @ -273,10 +273,6 @@ class User < ApplicationRecord | ||||||
|     settings.notification_emails['trending_tag'] |     settings.notification_emails['trending_tag'] | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def hides_network? |  | ||||||
|     @hides_network ||= settings.hide_network |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def aggregates_reblogs? |   def aggregates_reblogs? | ||||||
|     @aggregates_reblogs ||= settings.aggregate_reblogs |     @aggregates_reblogs ||= settings.aggregate_reblogs | ||||||
|   end |   end | ||||||
|  |  | ||||||
							
								
								
									
										17
									
								
								app/presenters/familiar_followers_presenter.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								app/presenters/familiar_followers_presenter.rb
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | ||||||
|  | # frozen_string_literal: true | ||||||
|  | 
 | ||||||
|  | class FamiliarFollowersPresenter | ||||||
|  |   class Result < ActiveModelSerializers::Model | ||||||
|  |     attributes :id, :accounts | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def initialize(accounts, current_account_id) | ||||||
|  |     @accounts           = accounts | ||||||
|  |     @current_account_id = current_account_id | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def accounts | ||||||
|  |     map = Follow.includes(account: :account_stat).where(target_account_id: @accounts.map(&:id)).where(account_id: Follow.where(account_id: @current_account_id).joins(:target_account).merge(Account.where(hide_collections: [nil, false])).select(:target_account_id)).group_by(&:target_account_id) | ||||||
|  |     @accounts.map { |account| Result.new(id: account.id, accounts: (account.hide_collections? ? [] : (map[account.id] || [])).map(&:account)) } | ||||||
|  |   end | ||||||
|  | end | ||||||
							
								
								
									
										11
									
								
								app/serializers/rest/familiar_followers_serializer.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								app/serializers/rest/familiar_followers_serializer.rb
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | ||||||
|  | # frozen_string_literal: true | ||||||
|  | 
 | ||||||
|  | class REST::FamiliarFollowersSerializer < ActiveModel::Serializer | ||||||
|  |   attribute :id | ||||||
|  | 
 | ||||||
|  |   has_many :accounts, serializer: REST::AccountSerializer | ||||||
|  | 
 | ||||||
|  |   def id | ||||||
|  |     object.id.to_s | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | @ -7,7 +7,7 @@ | ||||||
| 
 | 
 | ||||||
| = render 'accounts/header', account: @account | = render 'accounts/header', account: @account | ||||||
| 
 | 
 | ||||||
| - if @account.user_hides_network? | - if @account.hide_collections? | ||||||
|   .nothing-here= t('accounts.network_hidden') |   .nothing-here= t('accounts.network_hidden') | ||||||
| - elsif user_signed_in? && @account.blocking?(current_account) | - elsif user_signed_in? && @account.blocking?(current_account) | ||||||
|   .nothing-here= t('accounts.unavailable') |   .nothing-here= t('accounts.unavailable') | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ | ||||||
| 
 | 
 | ||||||
| = render 'accounts/header', account: @account | = render 'accounts/header', account: @account | ||||||
| 
 | 
 | ||||||
| - if @account.user_hides_network? | - if @account.hide_collections? | ||||||
|   .nothing-here= t('accounts.network_hidden') |   .nothing-here= t('accounts.network_hidden') | ||||||
| - elsif user_signed_in? && @account.blocking?(current_account) | - elsif user_signed_in? && @account.blocking?(current_account) | ||||||
|   .nothing-here= t('accounts.unavailable') |   .nothing-here= t('accounts.unavailable') | ||||||
|  |  | ||||||
|  | @ -10,9 +10,6 @@ | ||||||
|   .fields-group |   .fields-group | ||||||
|     = f.input :setting_noindex, as: :boolean, wrapper: :with_label |     = f.input :setting_noindex, as: :boolean, wrapper: :with_label | ||||||
| 
 | 
 | ||||||
|   .fields-group |  | ||||||
|     = f.input :setting_hide_network, as: :boolean, wrapper: :with_label |  | ||||||
| 
 |  | ||||||
|   .fields-group |   .fields-group | ||||||
|     = f.input :setting_aggregate_reblogs, as: :boolean, wrapper: :with_label, recommended: true |     = f.input :setting_aggregate_reblogs, as: :boolean, wrapper: :with_label, recommended: true | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -30,7 +30,10 @@ | ||||||
|     = f.input :bot, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.bot') |     = f.input :bot, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.bot') | ||||||
| 
 | 
 | ||||||
|   .fields-group |   .fields-group | ||||||
|     = f.input :discoverable, as: :boolean, wrapper: :with_label, hint: t(Setting.profile_directory ? 'simple_form.hints.defaults.discoverable' : 'simple_form.hints.defaults.discoverable_no_directory'), recommended: true |     = f.input :discoverable, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.discoverable'), recommended: true | ||||||
|  | 
 | ||||||
|  |   .fields-group | ||||||
|  |     = f.input :hide_collections, as: :boolean, wrapper: :with_label, label: t('simple_form.labels.defaults.setting_hide_network'), hint: t('simple_form.hints.defaults.setting_hide_network') | ||||||
| 
 | 
 | ||||||
|   %hr.spacer/ |   %hr.spacer/ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -37,8 +37,7 @@ en: | ||||||
|         current_password: For security purposes please enter the password of the current account |         current_password: For security purposes please enter the password of the current account | ||||||
|         current_username: To confirm, please enter the username of the current account |         current_username: To confirm, please enter the username of the current account | ||||||
|         digest: Only sent after a long period of inactivity and only if you have received any personal messages in your absence |         digest: Only sent after a long period of inactivity and only if you have received any personal messages in your absence | ||||||
|         discoverable: Allow your account to be discovered by strangers through recommendations, profile directory and other features |         discoverable: Allow your account to be discovered by strangers through recommendations, trends and other features | ||||||
|         discoverable_no_directory: Allow your account to be discovered by strangers through recommendations and other features |  | ||||||
|         email: You will be sent a confirmation e-mail |         email: You will be sent a confirmation e-mail | ||||||
|         fields: You can have up to 4 items displayed as a table on your profile |         fields: You can have up to 4 items displayed as a table on your profile | ||||||
|         header: PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px |         header: PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px | ||||||
|  |  | ||||||
|  | @ -493,6 +493,7 @@ Rails.application.routes.draw do | ||||||
|         resource :search, only: :show, controller: :search |         resource :search, only: :show, controller: :search | ||||||
|         resource :lookup, only: :show, controller: :lookup |         resource :lookup, only: :show, controller: :lookup | ||||||
|         resources :relationships, only: :index |         resources :relationships, only: :index | ||||||
|  |         resources :familiar_followers, only: :index | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       resources :accounts, only: [:create, :show] do |       resources :accounts, only: [:create, :show] do | ||||||
|  |  | ||||||
|  | @ -17,7 +17,6 @@ defaults: &defaults | ||||||
|   timeline_preview: true |   timeline_preview: true | ||||||
|   show_staff_badge: true |   show_staff_badge: true | ||||||
|   default_sensitive: false |   default_sensitive: false | ||||||
|   hide_network: false |  | ||||||
|   unfollow_modal: false |   unfollow_modal: false | ||||||
|   boost_modal: false |   boost_modal: false | ||||||
|   delete_modal: true |   delete_modal: true | ||||||
|  |  | ||||||
							
								
								
									
										37
									
								
								db/migrate/20220304195405_migrate_hide_network_preference.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								db/migrate/20220304195405_migrate_hide_network_preference.rb
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | ||||||
|  | class MigrateHideNetworkPreference < ActiveRecord::Migration[6.1] | ||||||
|  |   disable_ddl_transaction! | ||||||
|  | 
 | ||||||
|  |   # Dummy classes, to make migration possible across version changes | ||||||
|  |   class Account < ApplicationRecord | ||||||
|  |     has_one :user, inverse_of: :account | ||||||
|  |     scope :local, -> { where(domain: nil) } | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   class User < ApplicationRecord | ||||||
|  |     belongs_to :account | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def up | ||||||
|  |     Account.reset_column_information | ||||||
|  | 
 | ||||||
|  |     Setting.unscoped.where(thing_type: 'User', var: 'hide_network').find_each do |setting| | ||||||
|  |       account = User.find(setting.thing_id).account | ||||||
|  | 
 | ||||||
|  |       ApplicationRecord.transaction do | ||||||
|  |         account.update(hide_collections: setting.value) | ||||||
|  |         setting.delete | ||||||
|  |       end | ||||||
|  |     rescue ActiveRecord::RecordNotFound | ||||||
|  |       next | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def down | ||||||
|  |     Account.local.where(hide_collections: true).includes(:user).find_each do |account| | ||||||
|  |       ApplicationRecord.transaction do | ||||||
|  |         Setting.create(thing_type: 'User', thing_id: account.user.id, var: 'hide_network', value: account.hide_collections?) | ||||||
|  |         account.update(hide_collections: nil) | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | @ -10,7 +10,7 @@ | ||||||
| # | # | ||||||
| # It's strongly recommended that you check this file into your version control system. | # It's strongly recommended that you check this file into your version control system. | ||||||
| 
 | 
 | ||||||
| ActiveRecord::Schema.define(version: 2022_02_27_041951) do | ActiveRecord::Schema.define(version: 2022_03_04_195405) do | ||||||
| 
 | 
 | ||||||
|   # These are extensions that must be enabled in order to support this database |   # These are extensions that must be enabled in order to support this database | ||||||
|   enable_extension "plpgsql" |   enable_extension "plpgsql" | ||||||
|  |  | ||||||
|  | @ -103,7 +103,7 @@ describe FollowerAccountsController do | ||||||
| 
 | 
 | ||||||
|         context 'when account hides their network' do |         context 'when account hides their network' do | ||||||
|           before do |           before do | ||||||
|             alice.user.settings.hide_network = true |             alice.update(hide_collections: true) | ||||||
|           end |           end | ||||||
| 
 | 
 | ||||||
|           it 'returns followers count' do |           it 'returns followers count' do | ||||||
|  |  | ||||||
|  | @ -103,7 +103,7 @@ describe FollowingAccountsController do | ||||||
| 
 | 
 | ||||||
|         context 'when account hides their network' do |         context 'when account hides their network' do | ||||||
|           before do |           before do | ||||||
|             alice.user.settings.hide_network = true |             alice.update(hide_collections: true) | ||||||
|           end |           end | ||||||
| 
 | 
 | ||||||
|           it 'returns followers count' do |           it 'returns followers count' do | ||||||
|  |  | ||||||
							
								
								
									
										58
									
								
								spec/presenters/familiar_followers_presenter_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								spec/presenters/familiar_followers_presenter_spec.rb
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,58 @@ | ||||||
|  | # frozen_string_literal: true | ||||||
|  | 
 | ||||||
|  | require 'rails_helper' | ||||||
|  | 
 | ||||||
|  | RSpec.describe FamiliarFollowersPresenter do | ||||||
|  |   describe '#accounts' do | ||||||
|  |     let(:account) { Fabricate(:account) } | ||||||
|  |     let(:familiar_follower) { Fabricate(:account) } | ||||||
|  |     let(:requested_accounts) { Fabricate.times(2, :account) } | ||||||
|  | 
 | ||||||
|  |     subject { described_class.new(requested_accounts, account.id) } | ||||||
|  | 
 | ||||||
|  |     before do | ||||||
|  |       familiar_follower.follow!(requested_accounts.first) | ||||||
|  |       account.follow!(familiar_follower) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     it 'returns a result for each requested account' do | ||||||
|  |       expect(subject.accounts.map(&:id)).to eq requested_accounts.map(&:id) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     it 'returns followers you follow' do | ||||||
|  |       result = subject.accounts.first | ||||||
|  | 
 | ||||||
|  |       expect(result).to_not be_nil | ||||||
|  |       expect(result.id).to eq requested_accounts.first.id | ||||||
|  |       expect(result.accounts).to match_array([familiar_follower]) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     context 'when requested account hides followers' do | ||||||
|  |       before do | ||||||
|  |         requested_accounts.first.update(hide_collections: true) | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       it 'does not return followers you follow' do | ||||||
|  |         result = subject.accounts.first | ||||||
|  | 
 | ||||||
|  |         expect(result).to_not be_nil | ||||||
|  |         expect(result.id).to eq requested_accounts.first.id | ||||||
|  |         expect(result.accounts).to be_empty | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     context 'when familiar follower hides follows' do | ||||||
|  |       before do | ||||||
|  |         familiar_follower.update(hide_collections: true) | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       it 'does not return followers you follow' do | ||||||
|  |         result = subject.accounts.first | ||||||
|  | 
 | ||||||
|  |         expect(result).to_not be_nil | ||||||
|  |         expect(result.id).to eq requested_accounts.first.id | ||||||
|  |         expect(result.accounts).to be_empty | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
		Loading…
	
		Reference in a new issue