* Fix contexts not being dynamically included Fixes #11649 * Refactor Note context in serializer * Refactor Actor serializermaster^2
@@ -32,22 +32,23 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base | |||||
end | end | ||||
def serializable_hash(options = nil) | def serializable_hash(options = nil) | ||||
named_contexts = {} | |||||
context_extensions = {} | |||||
options = serialization_options(options) | options = serialization_options(options) | ||||
serialized_hash = serializer.serializable_hash(options) | |||||
serialized_hash = serializer.serializable_hash(options.merge(named_contexts: named_contexts, context_extensions: context_extensions)) | |||||
serialized_hash = serialized_hash.select { |k, _| options[:fields].include?(k) } if options[:fields] | serialized_hash = serialized_hash.select { |k, _| options[:fields].include?(k) } if options[:fields] | ||||
serialized_hash = self.class.transform_key_casing!(serialized_hash, instance_options) | serialized_hash = self.class.transform_key_casing!(serialized_hash, instance_options) | ||||
{ '@context' => serialized_context }.merge(serialized_hash) | |||||
{ '@context' => serialized_context(named_contexts, context_extensions) }.merge(serialized_hash) | |||||
end | end | ||||
private | private | ||||
def serialized_context | |||||
def serialized_context(named_contexts_map, context_extensions_map) | |||||
context_array = [] | context_array = [] | ||||
serializer_options = serializer.send(:instance_options) || {} | |||||
named_contexts = [:activitystreams] + serializer._named_contexts.keys + serializer_options.fetch(:named_contexts, {}).keys | |||||
context_extensions = serializer._context_extensions.keys + serializer_options.fetch(:context_extensions, {}).keys | |||||
named_contexts = [:activitystreams] + named_contexts_map.keys | |||||
context_extensions = context_extensions_map.keys | |||||
named_contexts.each do |key| | named_contexts.each do |key| | ||||
context_array << NAMED_CONTEXT_MAP[key] | context_array << NAMED_CONTEXT_MAP[key] | ||||
@@ -27,4 +27,12 @@ class ActivityPub::Serializer < ActiveModel::Serializer | |||||
_context_extensions[extension_name] = true | _context_extensions[extension_name] = true | ||||
end | end | ||||
end | end | ||||
def serializable_hash(adapter_options = nil, options = {}, adapter_instance = self.class.serialization_adapter_instance) | |||||
unless adapter_options&.fetch(:named_contexts, nil).nil? | |||||
adapter_options[:named_contexts].merge!(_named_contexts) | |||||
adapter_options[:context_extensions].merge!(_context_extensions) | |||||
end | |||||
super(adapter_options, options, adapter_instance) | |||||
end | |||||
end | end |
@@ -6,7 +6,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer | |||||
context :security | context :security | ||||
context_extensions :manually_approves_followers, :featured, :also_known_as, | context_extensions :manually_approves_followers, :featured, :also_known_as, | ||||
:moved_to, :property_value, :hashtag, :emoji, :identity_proof, | |||||
:moved_to, :property_value, :identity_proof, | |||||
:discoverable | :discoverable | ||||
attributes :id, :type, :following, :followers, | attributes :id, :type, :following, :followers, | ||||
@@ -138,6 +138,8 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer | |||||
end | end | ||||
class TagSerializer < ActivityPub::Serializer | class TagSerializer < ActivityPub::Serializer | ||||
context_extensions :hashtag | |||||
include RoutingHelper | include RoutingHelper | ||||
attributes :type, :href, :name | attributes :type, :href, :name | ||||
@@ -1,8 +1,7 @@ | |||||
# frozen_string_literal: true | # frozen_string_literal: true | ||||
class ActivityPub::NoteSerializer < ActivityPub::Serializer | class ActivityPub::NoteSerializer < ActivityPub::Serializer | ||||
context_extensions :atom_uri, :conversation, :sensitive, | |||||
:hashtag, :emoji, :focal_point, :blurhash | |||||
context_extensions :atom_uri, :conversation, :sensitive | |||||
attributes :id, :type, :summary, | attributes :id, :type, :summary, | ||||
:in_reply_to, :published, :url, | :in_reply_to, :published, :url, | ||||
@@ -151,6 +150,8 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer | |||||
end | end | ||||
class MediaAttachmentSerializer < ActivityPub::Serializer | class MediaAttachmentSerializer < ActivityPub::Serializer | ||||
context_extensions :blurhash, :focal_point | |||||
include RoutingHelper | include RoutingHelper | ||||
attributes :type, :media_type, :url, :name, :blurhash | attributes :type, :media_type, :url, :name, :blurhash | ||||
@@ -198,6 +199,8 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer | |||||
end | end | ||||
class TagSerializer < ActivityPub::Serializer | class TagSerializer < ActivityPub::Serializer | ||||
context_extensions :hashtag | |||||
include RoutingHelper | include RoutingHelper | ||||
attributes :type, :href, :name | attributes :type, :href, :name | ||||
@@ -3,22 +3,3 @@ ActiveModelSerializers.config.tap do |config| | |||||
end | end | ||||
ActiveSupport::Notifications.unsubscribe(ActiveModelSerializers::Logging::RENDER_EVENT) | ActiveSupport::Notifications.unsubscribe(ActiveModelSerializers::Logging::RENDER_EVENT) | ||||
class ActiveModel::Serializer::Reflection | |||||
# We monkey-patch this method so that when we include associations in a serializer, | |||||
# the nested serializers can send information about used contexts upwards back to | |||||
# the root. We do this via instance_options because the nesting can be dynamic. | |||||
def build_association(parent_serializer, parent_serializer_options, include_slice = {}) | |||||
serializer = options[:serializer] | |||||
parent_serializer_options.merge!(named_contexts: serializer._named_contexts, context_extensions: serializer._context_extensions) if serializer.respond_to?(:_named_contexts) | |||||
association_options = { | |||||
parent_serializer: parent_serializer, | |||||
parent_serializer_options: parent_serializer_options, | |||||
include_slice: include_slice, | |||||
} | |||||
ActiveModel::Serializer::Association.new(self, association_options) | |||||
end | |||||
end |
@@ -19,7 +19,7 @@ RSpec.describe ActivityPub::Activity::Update do | |||||
end | end | ||||
let(:actor_json) do | let(:actor_json) do | ||||
ActiveModelSerializers::SerializableResource.new(modified_sender, serializer: ActivityPub::ActorSerializer, key_transform: :camel_lower).as_json | |||||
ActiveModelSerializers::SerializableResource.new(modified_sender, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter).as_json | |||||
end | end | ||||
let(:json) do | let(:json) do | ||||