mirror of
https://github.com/glitch-soc/mastodon.git
synced 2026-03-29 11:11:11 +02:00
AP/AS serialization of Collections (#37434)
This commit is contained in:
@@ -62,6 +62,8 @@ class ActivityPub::TagManager
|
||||
emoji_url(target)
|
||||
when :flag
|
||||
target.uri
|
||||
when :featured_collection
|
||||
ap_account_featured_collection_url(target.account.id, target)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -60,6 +60,10 @@ class Collection < ApplicationRecord
|
||||
self.tag = Tag.find_or_create_by_names(new_name).first
|
||||
end
|
||||
|
||||
def object_type
|
||||
:featured_collection
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def tag_is_usable
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::FeaturedCollectionSerializer < ActivityPub::Serializer
|
||||
class FeaturedItemSerializer < ActivityPub::Serializer
|
||||
attributes :type, :featured_object, :featured_object_type
|
||||
|
||||
def type
|
||||
'FeaturedItem'
|
||||
end
|
||||
|
||||
def featured_object
|
||||
ActivityPub::TagManager.instance.uri_for(object.account)
|
||||
end
|
||||
|
||||
def featured_object_type
|
||||
object.account.actor_type || 'Person'
|
||||
end
|
||||
end
|
||||
|
||||
attributes :id, :type, :total_items, :name, :summary, :attributed_to,
|
||||
:sensitive, :discoverable, :published, :updated
|
||||
|
||||
has_one :tag, key: :topic, serializer: ActivityPub::NoteSerializer::TagSerializer
|
||||
|
||||
has_many :collection_items, key: :ordered_items, serializer: FeaturedItemSerializer
|
||||
|
||||
def id
|
||||
ActivityPub::TagManager.instance.uri_for(object)
|
||||
end
|
||||
|
||||
def type
|
||||
'FeaturedCollection'
|
||||
end
|
||||
|
||||
def summary
|
||||
object.description
|
||||
end
|
||||
|
||||
def attributed_to
|
||||
ActivityPub::TagManager.instance.uri_for(object.account)
|
||||
end
|
||||
|
||||
def total_items
|
||||
object.collection_items.size
|
||||
end
|
||||
|
||||
def published
|
||||
object.created_at.iso8601
|
||||
end
|
||||
|
||||
def updated
|
||||
object.updated_at.iso8601
|
||||
end
|
||||
end
|
||||
@@ -96,6 +96,7 @@ Rails.application.routes.draw do
|
||||
get '/authorize_follow', to: redirect { |_, request| "/authorize_interaction?#{request.params.to_query}" }
|
||||
|
||||
concern :account_resources do
|
||||
resources :featured_collections, only: [:show]
|
||||
resources :followers, only: [:index], controller: :follower_accounts
|
||||
resources :following, only: [:index], controller: :following_accounts
|
||||
|
||||
|
||||
@@ -8,3 +8,10 @@ Fabricator(:collection) do
|
||||
sensitive false
|
||||
discoverable true
|
||||
end
|
||||
|
||||
Fabricator(:remote_collection, from: :collection) do
|
||||
account { Fabricate.build(:remote_account) }
|
||||
local false
|
||||
uri { sequence(:uri) { |i| "https://example.com/collections/#{i}" } }
|
||||
original_number_of_items 0
|
||||
end
|
||||
|
||||
@@ -192,6 +192,23 @@ RSpec.describe ActivityPub::TagManager do
|
||||
expect(subject.uri_for(status.conversation)).to eq status.conversation.uri
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a local collection' do
|
||||
let(:collection) { Fabricate(:collection) }
|
||||
|
||||
it 'returns a string starting with web domain and with the expected path' do
|
||||
expect(subject.uri_for(collection))
|
||||
.to eq("#{host_prefix}/ap/users/#{collection.account.id}/featured_collections/#{collection.id}")
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a remote collection' do
|
||||
let(:collection) { Fabricate(:remote_collection) }
|
||||
|
||||
it 'returns the expected URL' do
|
||||
expect(subject.uri_for(collection)).to eq collection.uri
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#key_uri_for' do
|
||||
|
||||
@@ -126,4 +126,10 @@ RSpec.describe Collection do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#object_type' do
|
||||
it 'returns `:featured_collection`' do
|
||||
expect(subject.object_type).to eq :featured_collection
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ActivityPub::FeaturedCollectionSerializer do
|
||||
subject { serialized_record_json(collection, described_class, adapter: ActivityPub::Adapter) }
|
||||
|
||||
let(:collection) do
|
||||
Fabricate(:collection,
|
||||
name: 'Incredible people',
|
||||
description: 'These are really amazing',
|
||||
tag_name: '#people',
|
||||
discoverable: false)
|
||||
end
|
||||
let!(:collection_items) { Fabricate.times(2, :collection_item, collection:) }
|
||||
|
||||
it 'serializes to the expected structure' do
|
||||
expect(subject).to include({
|
||||
'type' => 'FeaturedCollection',
|
||||
'id' => ActivityPub::TagManager.instance.uri_for(collection),
|
||||
'name' => 'Incredible people',
|
||||
'summary' => 'These are really amazing',
|
||||
'attributedTo' => ActivityPub::TagManager.instance.uri_for(collection.account),
|
||||
'sensitive' => false,
|
||||
'discoverable' => false,
|
||||
'topic' => {
|
||||
'href' => match(%r{/tags/people$}),
|
||||
'type' => 'Hashtag',
|
||||
'name' => '#people',
|
||||
},
|
||||
'totalItems' => 2,
|
||||
'orderedItems' => [
|
||||
{
|
||||
'type' => 'FeaturedItem',
|
||||
'featuredObject' => ActivityPub::TagManager.instance.uri_for(collection_items.first.account),
|
||||
'featuredObjectType' => 'Person',
|
||||
},
|
||||
{
|
||||
'type' => 'FeaturedItem',
|
||||
'featuredObject' => ActivityPub::TagManager.instance.uri_for(collection_items.last.account),
|
||||
'featuredObjectType' => 'Person',
|
||||
},
|
||||
],
|
||||
'published' => match_api_datetime_format,
|
||||
'updated' => match_api_datetime_format,
|
||||
})
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user