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
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Search < ActiveModelSerializers::Model
|
class Search < ActiveModelSerializers::Model
|
||||||
attributes :accounts, :statuses, :hashtags
|
attributes :accounts, :statuses, :hashtags, :collections
|
||||||
end
|
end
|
||||||
|
|||||||
@ -4,4 +4,5 @@ class REST::SearchSerializer < ActiveModel::Serializer
|
|||||||
has_many :accounts, serializer: REST::AccountSerializer
|
has_many :accounts, serializer: REST::AccountSerializer
|
||||||
has_many :statuses, serializer: REST::StatusSerializer
|
has_many :statuses, serializer: REST::StatusSerializer
|
||||||
has_many :hashtags, serializer: REST::TagSerializer
|
has_many :hashtags, serializer: REST::TagSerializer
|
||||||
|
has_many :collections, serializer: REST::CollectionSerializer
|
||||||
end
|
end
|
||||||
|
|||||||
@ -3,8 +3,12 @@
|
|||||||
class ActivityPub::FetchRemoteFeaturedCollectionService < BaseService
|
class ActivityPub::FetchRemoteFeaturedCollectionService < BaseService
|
||||||
include JsonLdHelper
|
include JsonLdHelper
|
||||||
|
|
||||||
def call(uri, request_id: nil, on_behalf_of: nil)
|
def call(uri, request_id: nil, prefetched_body: nil, on_behalf_of: nil)
|
||||||
json = fetch_resource(uri, true, on_behalf_of)
|
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 supported_context?(json)
|
||||||
return unless json['type'] == 'FeaturedCollection'
|
return unless json['type'] == 'FeaturedCollection'
|
||||||
|
|||||||
@ -63,7 +63,7 @@ class FetchResourceService < BaseService
|
|||||||
end
|
end
|
||||||
|
|
||||||
def expected_type?(json)
|
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
|
end
|
||||||
|
|
||||||
def process_html(response)
|
def process_html(response)
|
||||||
|
|||||||
@ -28,6 +28,10 @@ class ResolveURLService < BaseService
|
|||||||
status = FetchRemoteStatusService.new.call(resource_url, prefetched_body: body)
|
status = FetchRemoteStatusService.new.call(resource_url, prefetched_body: body)
|
||||||
authorize_with @on_behalf_of, status, :show? unless status.nil?
|
authorize_with @on_behalf_of, status, :show? unless status.nil?
|
||||||
status
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -111,9 +115,21 @@ class ResolveURLService < BaseService
|
|||||||
|
|
||||||
Account.find_remote(username, domain)
|
Account.find_remote(username, domain)
|
||||||
end
|
end
|
||||||
|
when 'collections'
|
||||||
|
return unless recognized_params[:action] == 'show'
|
||||||
|
|
||||||
|
check_collection(Collection.find_by(id: recognized_params[:id]))
|
||||||
end
|
end
|
||||||
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)
|
def check_local_status(status)
|
||||||
return if status.nil?
|
return if status.nil?
|
||||||
|
|
||||||
|
|||||||
@ -64,7 +64,7 @@ class SearchService < BaseService
|
|||||||
end
|
end
|
||||||
|
|
||||||
def default_results
|
def default_results
|
||||||
{ accounts: [], hashtags: [], statuses: [] }
|
{ accounts: [], hashtags: [], statuses: [], collections: [] }
|
||||||
end
|
end
|
||||||
|
|
||||||
def url_query?
|
def url_query?
|
||||||
|
|||||||
@ -30,6 +30,49 @@ RSpec.describe ResolveURLService do
|
|||||||
expect(subject.call(url)).to eq known_account
|
expect(subject.call(url)).to eq known_account
|
||||||
end
|
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
|
context 'when searching for a remote private status' do
|
||||||
let(:account) { Fabricate(:account) }
|
let(:account) { Fabricate(:account) }
|
||||||
let(:poster) { Fabricate(:account, domain: 'example.com') }
|
let(:poster) { Fabricate(:account, domain: 'example.com') }
|
||||||
|
|||||||
@ -86,6 +86,6 @@ RSpec.describe SearchService do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def empty_results
|
def empty_results
|
||||||
{ accounts: [], hashtags: [], statuses: [] }
|
{ accounts: [], hashtags: [], statuses: [], collections: [] }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user