Add ability to search for a collection by URL (#38588)
This commit is contained in:
parent
97ba08113d
commit
4ad54b279d
@ -1,5 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Search < ActiveModelSerializers::Model
|
||||
attributes :accounts, :statuses, :hashtags
|
||||
attributes :accounts, :statuses, :hashtags, :collections
|
||||
end
|
||||
|
||||
@ -4,4 +4,5 @@ class REST::SearchSerializer < ActiveModel::Serializer
|
||||
has_many :accounts, serializer: REST::AccountSerializer
|
||||
has_many :statuses, serializer: REST::StatusSerializer
|
||||
has_many :hashtags, serializer: REST::TagSerializer
|
||||
has_many :collections, serializer: REST::CollectionSerializer
|
||||
end
|
||||
|
||||
@ -3,8 +3,12 @@
|
||||
class ActivityPub::FetchRemoteFeaturedCollectionService < BaseService
|
||||
include JsonLdHelper
|
||||
|
||||
def call(uri, request_id: nil, on_behalf_of: nil)
|
||||
json = fetch_resource(uri, true, on_behalf_of)
|
||||
def call(uri, request_id: nil, prefetched_body: nil, on_behalf_of: nil)
|
||||
json = if prefetched_body.nil?
|
||||
fetch_resource(uri, true, on_behalf_of)
|
||||
else
|
||||
body_to_json(prefetched_body, compare_id: uri)
|
||||
end
|
||||
|
||||
return unless supported_context?(json)
|
||||
return unless json['type'] == 'FeaturedCollection'
|
||||
|
||||
@ -63,7 +63,7 @@ class FetchResourceService < BaseService
|
||||
end
|
||||
|
||||
def expected_type?(json)
|
||||
equals_or_includes_any?(json['type'], ActivityPub::Activity::Create::SUPPORTED_TYPES + ActivityPub::Activity::Create::CONVERTED_TYPES)
|
||||
equals_or_includes_any?(json['type'], ActivityPub::Activity::Create::SUPPORTED_TYPES + ActivityPub::Activity::Create::CONVERTED_TYPES + %w(FeaturedCollection))
|
||||
end
|
||||
|
||||
def process_html(response)
|
||||
|
||||
@ -28,6 +28,10 @@ class ResolveURLService < BaseService
|
||||
status = FetchRemoteStatusService.new.call(resource_url, prefetched_body: body)
|
||||
authorize_with @on_behalf_of, status, :show? unless status.nil?
|
||||
status
|
||||
elsif type == 'FeaturedCollection' && Mastodon::Feature.collections_enabled?
|
||||
collection = ActivityPub::FetchRemoteFeaturedCollectionService.new.call(resource_url, prefetched_body: body)
|
||||
authorize_with @on_behalf_of, collection, :show? unless collection.nil?
|
||||
collection
|
||||
end
|
||||
end
|
||||
|
||||
@ -111,9 +115,21 @@ class ResolveURLService < BaseService
|
||||
|
||||
Account.find_remote(username, domain)
|
||||
end
|
||||
when 'collections'
|
||||
return unless recognized_params[:action] == 'show'
|
||||
|
||||
check_collection(Collection.find_by(id: recognized_params[:id]))
|
||||
end
|
||||
end
|
||||
|
||||
def check_collection(collection)
|
||||
return if collection.nil?
|
||||
|
||||
authorize_with @on_behalf_of, collection, :show?
|
||||
rescue Mastodon::NotPermittedError
|
||||
nil
|
||||
end
|
||||
|
||||
def check_local_status(status)
|
||||
return if status.nil?
|
||||
|
||||
|
||||
@ -64,7 +64,7 @@ class SearchService < BaseService
|
||||
end
|
||||
|
||||
def default_results
|
||||
{ accounts: [], hashtags: [], statuses: [] }
|
||||
{ accounts: [], hashtags: [], statuses: [], collections: [] }
|
||||
end
|
||||
|
||||
def url_query?
|
||||
|
||||
@ -30,6 +30,49 @@ RSpec.describe ResolveURLService do
|
||||
expect(subject.call(url)).to eq known_account
|
||||
end
|
||||
|
||||
context 'when searching for a remote collection', feature: :collections do
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:collection_account) { Fabricate(:account, domain: 'example.com', protocol: :activitypub) }
|
||||
|
||||
let(:uri) { 'https://example.com/featured_collections/1' }
|
||||
|
||||
let(:payload) do
|
||||
{
|
||||
'@context' => 'https://www.w3.org/ns/activitystreams',
|
||||
'id' => uri,
|
||||
'type' => 'FeaturedCollection',
|
||||
'name' => 'Incredible people',
|
||||
'summary' => 'These are really amazing',
|
||||
'attributedTo' => collection_account.uri,
|
||||
'sensitive' => false,
|
||||
'discoverable' => true,
|
||||
'totalItems' => 0,
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
stub_request(:get, uri).to_return(status: 200, body: payload.to_json, headers: { 'Content-Type': 'application/activity+json' })
|
||||
end
|
||||
|
||||
it 'returns the collection' do
|
||||
expect(subject.call(uri, on_behalf_of: account))
|
||||
.to be_a(Collection)
|
||||
.and have_attributes(
|
||||
uri: uri
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when searching for a local collection', feature: :collections do
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:collection) { Fabricate(:collection) }
|
||||
|
||||
it 'returns the collection' do
|
||||
expect(subject.call(ActivityPub::TagManager.instance.uri_for(collection), on_behalf_of: account))
|
||||
.to eq(collection)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when searching for a remote private status' do
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:poster) { Fabricate(:account, domain: 'example.com') }
|
||||
|
||||
@ -86,6 +86,6 @@ RSpec.describe SearchService do
|
||||
end
|
||||
|
||||
def empty_results
|
||||
{ accounts: [], hashtags: [], statuses: [] }
|
||||
{ accounts: [], hashtags: [], statuses: [], collections: [] }
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user