From 7ee93b74317c0b51516146fbe32e72cd9bbb151c Mon Sep 17 00:00:00 2001 From: Claire <claire.github-309c@sitedethib.com> Date: Tue, 6 Feb 2024 18:10:17 +0100 Subject: [PATCH] Change `source` attribute of `Suggestion` entity in `/api/v2/suggestions` back to a string (#29108) --- .../components/inline_follow_suggestions.jsx | 8 ++++---- app/models/account_suggestions.rb | 4 ++-- app/models/account_suggestions/suggestion.rb | 2 +- app/serializers/rest/suggestion_serializer.rb | 15 +++++++++++++- spec/requests/api/v2/suggestions_spec.rb | 20 ++++++++++++++++++- .../rest/suggestion_serializer_spec.rb | 2 +- 6 files changed, 41 insertions(+), 10 deletions(-) diff --git a/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.jsx b/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.jsx index ac414d04d6..f76526e045 100644 --- a/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.jsx +++ b/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.jsx @@ -59,7 +59,7 @@ Source.propTypes = { id: PropTypes.oneOf(['friends_of_friends', 'similar_to_recently_followed', 'featured', 'most_followed', 'most_interactions']), }; -const Card = ({ id, source }) => { +const Card = ({ id, sources }) => { const intl = useIntl(); const account = useSelector(state => state.getIn(['accounts', id])); const relationship = useSelector(state => state.getIn(['relationships', id])); @@ -89,7 +89,7 @@ const Card = ({ id, source }) => { <div className='inline-follow-suggestions__body__scrollable__card__text-stack'> <Link to={`/@${account.get('acct')}`}><DisplayName account={account} /></Link> - {firstVerifiedField ? <VerifiedBadge link={firstVerifiedField.get('value')} /> : <Source id={source.get(0)} />} + {firstVerifiedField ? <VerifiedBadge link={firstVerifiedField.get('value')} /> : <Source id={sources.get(0)} />} </div> <Button text={intl.formatMessage(following ? messages.unfollow : messages.follow)} onClick={handleFollow} /> @@ -99,7 +99,7 @@ const Card = ({ id, source }) => { Card.propTypes = { id: PropTypes.string.isRequired, - source: ImmutablePropTypes.list, + sources: ImmutablePropTypes.list, }; const DISMISSIBLE_ID = 'home/follow-suggestions'; @@ -175,7 +175,7 @@ export const InlineFollowSuggestions = ({ hidden }) => { <Card key={suggestion.get('account')} id={suggestion.get('account')} - source={suggestion.get('source')} + sources={suggestion.get('sources')} /> ))} </div> diff --git a/app/models/account_suggestions.rb b/app/models/account_suggestions.rb index 25c8b04d50..98ccf4ad4f 100644 --- a/app/models/account_suggestions.rb +++ b/app/models/account_suggestions.rb @@ -31,12 +31,12 @@ class AccountSuggestions account_ids = account_ids_with_sources[offset, limit] accounts_map = Account.where(id: account_ids.map(&:first)).includes(:account_stat, :user).index_by(&:id) - account_ids.filter_map do |(account_id, source)| + account_ids.filter_map do |(account_id, sources)| next unless accounts_map.key?(account_id) AccountSuggestions::Suggestion.new( account: accounts_map[account_id], - source: source + sources: sources ) end end diff --git a/app/models/account_suggestions/suggestion.rb b/app/models/account_suggestions/suggestion.rb index 2c6f4d27f5..8a5888069a 100644 --- a/app/models/account_suggestions/suggestion.rb +++ b/app/models/account_suggestions/suggestion.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class AccountSuggestions::Suggestion < ActiveModelSerializers::Model - attributes :account, :source + attributes :account, :sources delegate :id, to: :account, prefix: true end diff --git a/app/serializers/rest/suggestion_serializer.rb b/app/serializers/rest/suggestion_serializer.rb index 3d697fd9f1..c60f343ba4 100644 --- a/app/serializers/rest/suggestion_serializer.rb +++ b/app/serializers/rest/suggestion_serializer.rb @@ -1,7 +1,20 @@ # frozen_string_literal: true class REST::SuggestionSerializer < ActiveModel::Serializer - attributes :source + attributes :source, :sources has_one :account, serializer: REST::AccountSerializer + + LEGACY_SOURCE_TYPE_MAP = { + featured: 'staff', + most_followed: 'global', + most_interactions: 'global', + # NOTE: Those are not completely accurate, but those are personalized interactions + similar_to_recently_followed: 'past_interactions', + friends_of_friends: 'past_interactions', + }.freeze + + def source + LEGACY_SOURCE_TYPE_MAP[object.sources.first] + end end diff --git a/spec/requests/api/v2/suggestions_spec.rb b/spec/requests/api/v2/suggestions_spec.rb index 5f1c97b8ae..a7d6a0864f 100644 --- a/spec/requests/api/v2/suggestions_spec.rb +++ b/spec/requests/api/v2/suggestions_spec.rb @@ -9,10 +9,28 @@ describe 'Suggestions API' do let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } describe 'GET /api/v2/suggestions' do - it 'returns http success' do + let(:bob) { Fabricate(:account) } + let(:jeff) { Fabricate(:account) } + let(:params) { {} } + + before do + Setting.bootstrap_timeline_accounts = [bob, jeff].map(&:acct).join(',') + end + + it 'returns the expected suggestions' do get '/api/v2/suggestions', headers: headers expect(response).to have_http_status(200) + + expect(body_as_json).to match_array( + [bob, jeff].map do |account| + hash_including({ + source: 'staff', + sources: ['featured'], + account: hash_including({ id: account.id.to_s }), + }) + end + ) end end end diff --git a/spec/serializers/rest/suggestion_serializer_spec.rb b/spec/serializers/rest/suggestion_serializer_spec.rb index 60420d8023..b5efba082d 100644 --- a/spec/serializers/rest/suggestion_serializer_spec.rb +++ b/spec/serializers/rest/suggestion_serializer_spec.rb @@ -7,7 +7,7 @@ describe REST::SuggestionSerializer do let(:record) do AccountSuggestions::Suggestion.new( account: account, - source: 'SuggestionSource' + sources: ['SuggestionSource'] ) end let(:account) { Fabricate(:account) }