diff --git a/app/models/reference.rb b/app/models/reference.rb index 87a04ed2a..8312ceb61 100644 --- a/app/models/reference.rb +++ b/app/models/reference.rb @@ -9,8 +9,17 @@ class Reference < ApplicationRecord extend ActiveSupport::Concern included do + after_create :create_references has_many :references, as: :source, dependent: :destroy end + + def create_references + text&.scan(DiasporaFederation::Federation::DiasporaUrlParser::DIASPORA_URL_REGEX)&.each do |author, type, guid| + class_name = DiasporaFederation::Entity.entity_class(type).to_s.rpartition("::").last + entity = Diaspora::Federation::Mappings.model_class_for(class_name).find_by(guid: guid) + references.find_or_create_by(target: entity) if entity.diaspora_handle == author + end + end end module Target diff --git a/spec/shared_behaviors/references.rb b/spec/shared_behaviors/references.rb index d78829baf..61567a652 100644 --- a/spec/shared_behaviors/references.rb +++ b/spec/shared_behaviors/references.rb @@ -14,6 +14,43 @@ shared_examples_for "a reference source" do expect(Reference.where(id: reference.id)).not_to exist end end + + describe "#create_references" do + it "creates a reference for every referenced post after create" do + target1 = FactoryGirl.create(:status_message) + target2 = FactoryGirl.create(:status_message) + text = "Have a look at [this post](diaspora://#{target1.diaspora_handle}/post/#{target1.guid}) and " \ + "this one too diaspora://#{target2.diaspora_handle}/post/#{target2.guid}." + + post = FactoryGirl.build(described_class.to_s.underscore.to_sym, text: text) + post.save + + expect(post.references.map(&:target).map(&:guid)).to match_array([target1, target2].map(&:guid)) + end + + it "only creates one reference, even when it is referenced twice" do + target = FactoryGirl.create(:status_message) + text = "Have a look at [this post](diaspora://#{target.diaspora_handle}/post/#{target.guid}) and " \ + "this one too diaspora://#{target.diaspora_handle}/post/#{target.guid}." + + post = FactoryGirl.build(described_class.to_s.underscore.to_sym, text: text) + post.save + + expect(post.references.map(&:target).map(&:guid)).to match_array([target.guid]) + end + + it "only creates references, when the author of the known entity matches" do + target1 = FactoryGirl.create(:status_message) + target2 = FactoryGirl.create(:status_message) + text = "Have a look at [this post](diaspora://#{target1.diaspora_handle}/post/#{target1.guid}) and " \ + "this one too diaspora://#{target1.diaspora_handle}/post/#{target2.guid}." + + post = FactoryGirl.build(described_class.to_s.underscore.to_sym, text: text) + post.save + + expect(post.references.map(&:target).map(&:guid)).to match_array([target1.guid]) + end + end end shared_examples_for "a reference target" do