Skip to content

Commit

Permalink
change Comment to use new data entity concern
Browse files Browse the repository at this point in the history
  • Loading branch information
Floppy committed Jan 14, 2025
1 parent 80e8d04 commit 0a8050b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 61 deletions.
84 changes: 35 additions & 49 deletions app/models/comment.rb
Original file line number Diff line number Diff line change
@@ -1,69 +1,55 @@
require "federails/data_transformer/note"

class Comment < ApplicationRecord
include PublicIDable

belongs_to :commenter, polymorphic: true
belongs_to :commenter, polymorphic: true, optional: true
belongs_to :commentable, polymorphic: true

after_create :post_create_activity
after_update :post_update_activity

def federated_url
return nil unless public?
Rails.application.routes.url_helpers.url_for([commentable, self, {only_path: false}])
end
include Federails::DataEntity
acts_as_federails_data handles: "Note", actor_entity_method: :commenter

def to_activitypub_object
# Build tag structure
tags = commentable.respond_to?(:tags) ?
commentable.tags.pluck(:name).map do |tag|
{
type: "Hashtag",
name: "##{tag.tr(" ", "_").camelize}",
href: Rails.application.routes.url_helpers.url_for([commentable.class, tag: tag])
}
end
: nil
tag_html = tags&.map { |t| %(<a href="#{t[:href]}" class="mention hashtag" rel="tag">#{t[:name]}</a>) }&.join(" ")
# Comments become Notes in ActvityPub world
{
id: federated_url,
type: "Note",
content: [
Kramdown::Document.new(comment).to_html,
tag_html
].compact.join("\n\n"),
context: Rails.application.routes.url_helpers.url_for([commentable, only_path: false]),
published: created_at&.iso8601,
attributedTo: (commenter&.federails_actor&.respond_to?(:federated_url) ? commenter.federails_actor.federated_url : nil),
sensitive: sensitive,
to: ["https://www.w3.org/ns/activitystreams#Public"],
cc: [commenter.federails_actor.followers_url],
tag: tags
}.compact
# Comments become Notes in ActvityPub
Federails::DataTransformer::Note.to_federation self, content: to_html,
custom: {
"context" => Rails.application.routes.url_helpers.url_for([commentable, only_path: false]),
"sensitive" => sensitive,
"tag" => activitypub_tags
}.merge(address_options)
end

private

def public?
Pundit::PolicyFinder.new(commenter.class).policy.new(nil, commenter).show? &&
Pundit::PolicyFinder.new(commentable.class).policy.new(nil, commentable).show?
end

private

def post_create_activity
post_activity "Create"
def activitypub_tags
return nil unless commentable.respond_to?(:tags)
commentable.tags.pluck(:name).map do |tag|
{
type: "Hashtag",
name: "##{tag.tr(" ", "_").camelize}",
href: Rails.application.routes.url_helpers.url_for([commentable.class, tag: tag])
}
end
end

def post_update_activity
post_activity "Update"
def to_html
[
Kramdown::Document.new(comment).to_html,
activitypub_tags&.map { |t| %(<a href="#{t[:href]}" class="mention hashtag" rel="tag">#{t[:name]}</a>) }&.join(" ")
].compact.join("\n\n")
end

def post_activity(action)
if public?
Federails::Activity.create!(
actor: commenter.federails_actor,
action: action,
entity: self
)
end
def address_options
public? ?
{
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"cc" => [commenter.federails_actor.followers_url]
}
: {}
end
end
24 changes: 12 additions & 12 deletions spec/models/comment_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,57 +25,57 @@
end

it "has a federated_url method" do
expect(comment.federated_url).to eq "http://localhost:3214/models/#{commentable.public_id}/comments/#{comment.public_id}"
expect(comment.federated_url).to eq "http://localhost:3214/federation/objects/comments/#{comment.public_id}"
end

context "when serializing to an ActivityPub Note" do
let(:ap_object) { comment.to_activitypub_object }

it "creates a Note" do
expect(ap_object[:type]).to eq "Note"
expect(ap_object["type"]).to eq "Note"
end

it "includes content" do
expect(ap_object[:content]).to be_present
expect(ap_object["content"]).to be_present
end

it "includes id" do
expect(ap_object[:id]).to eq comment.federated_url
expect(ap_object["id"]).to eq comment.federated_url
end

it "includes commentable ID in context" do
expect(ap_object[:context]).to eq "http://localhost:3214/models/#{commentable.public_id}"
expect(ap_object["context"]).to eq "http://localhost:3214/models/#{commentable.public_id}"
end

it "includes publication time" do
expect(ap_object[:published]).to be_present
expect(ap_object["published"]).to be_present
end

it "includes sensitive flag" do
expect(ap_object[:sensitive]).to be true
expect(ap_object["sensitive"]).to be true
end

it "includes attribution" do
expect(ap_object[:attributedTo]).to eq commenter.federails_actor.federated_url
expect(ap_object["attributedTo"]).to eq commenter.federails_actor.federated_url
end

it "includes to field" do
expect(ap_object[:to]).to include "https://www.w3.org/ns/activitystreams#Public"
expect(ap_object["to"]).to include "https://www.w3.org/ns/activitystreams#Public"
end

it "includes cc field" do
expect(ap_object[:cc]).to include commenter.federails_actor.followers_url
expect(ap_object["cc"]).to include commenter.federails_actor.followers_url
end

it "includes tags appended to content" do
{"tag+one": "#TagOne", tag2: "#Tag2"}.each_pair do |link, hashtag|
expect(ap_object[:content]).to include %(<a href="http://localhost:3214/models?tag=#{link}" class="mention hashtag" rel="tag">#{hashtag}</a>)
expect(ap_object["content"]).to include %(<a href="http://localhost:3214/models?tag=#{link}" class="mention hashtag" rel="tag">#{hashtag}</a>)
end
end

it "includes tags as mentions" do # rubocop:disable RSpec/ExampleLength
{"tag+one": "#TagOne", tag2: "#Tag2"}.each_pair do |link, hashtag|
expect(ap_object[:tag]).to include(
expect(ap_object["tag"]).to include(
type: "Hashtag",
href: "http://localhost:3214/models?tag=#{link}",
name: hashtag
Expand Down

0 comments on commit 0a8050b

Please sign in to comment.