diaspora/spec/lib/diaspora/mentionable_spec.rb
2022-07-16 04:44:59 +02:00

212 lines
7.6 KiB
Ruby

# frozen_string_literal: true
describe Diaspora::Mentionable do
let(:people) { [alice, bob, eve].map(&:person) }
let(:names) { %w(Alice\ A Bob\ B "Eve>\ E) }
let(:test_text_with_names) { <<-STR }
This post contains a lot of mentions
one @{#{names[0]}; #{people[0].diaspora_handle}},
two @{#{names[1]}; #{people[1].diaspora_handle}} and finally
three @{#{names[2]}; #{people[2].diaspora_handle}}.
STR
let(:test_text_without_names) { <<-STR }
This post contains a lot of mentions
one @{#{people[0].diaspora_handle}},
two @{#{people[1].diaspora_handle}} and finally
three @{#{people[2].diaspora_handle}}.
STR
describe ".mention_attrs" do
it "returns name and diaspora ID" do
name, diaspora_id = Diaspora::Mentionable.mention_attrs("@{#{names[0]}; #{people[0].diaspora_handle}}")
expect(name).to eq(names[0])
expect(diaspora_id).to eq(people[0].diaspora_handle)
end
it "returns only diaspora-ID when no name is included" do
name, diaspora_id = Diaspora::Mentionable.mention_attrs("@{#{people[0].diaspora_handle}}")
expect(diaspora_id).to eq(people[0].diaspora_handle)
expect(name).to be_nil
end
it "trims the name if available" do
name, diaspora_id = Diaspora::Mentionable.mention_attrs("@{#{names[0]} ; #{people[0].diaspora_handle}}")
expect(name).to eq(names[0])
expect(diaspora_id).to eq(people[0].diaspora_handle)
end
end
describe ".format" do
context "html output", type: :helper do
include PeopleHelper
it "adds the links to the formatted message" do
fmt_msg = Diaspora::Mentionable.format(test_text_with_names, people)
[people, names].transpose.each do |person, name|
link = person_link(person, class: "mention hovercardable", display_name: name)
expect(fmt_msg).to include "@#{link}"
end
end
it "adds the links to the formatted message and uses the names from the people" do
fmt_msg = Diaspora::Mentionable.format(test_text_without_names, people)
people.each do |person|
link = person_link(person, class: "mention hovercardable", display_name: person.name)
expect(fmt_msg).to include "@#{link}"
end
end
it "should work correct when message is escaped html" do
fmt_msg = Diaspora::Mentionable.format(CGI.escapeHTML(test_text_with_names), people)
[people, names].transpose.each do |person, name|
expect(fmt_msg).to include person_link(person, class: "mention hovercardable", display_name: name)
end
end
it "escapes the link title (name)" do
name = "</a><script>alert('h')</script>"
test_txt = "two @{#{name}; #{people[0].diaspora_handle}} and finally"
fmt_msg = Diaspora::Mentionable.format(test_txt, people)
expect(fmt_msg).not_to include(name)
expect(fmt_msg).to include("&lt;/a&gt;&lt;script&gt;alert(&#39;h&#39;)&lt;/script&gt;")
end
end
context "plain text output" do
it "removes mention markup and displays unformatted name" do
fmt_msg = Diaspora::Mentionable.format(test_text_with_names, people, plain_text: true)
names.each do |name|
expect(fmt_msg).to include "@#{CGI.escapeHTML(name)}"
end
expect(fmt_msg).not_to include "<a", "</a>", "hovercardable"
end
end
it "leaves the names of people that cannot be found" do
test_txt_plain = <<-STR
This post contains a lot of mentions
one @Alice A,
two @Bob B and finally
three @&quot;Eve&gt; E.
STR
fmt_msg = Diaspora::Mentionable.format(test_text_with_names, [])
expect(fmt_msg).to eql test_txt_plain
end
it "uses the diaspora ID when the person cannot be found" do
test_txt_plain = <<-STR
This post contains a lot of mentions
one @#{people[0].diaspora_handle},
two @#{people[1].diaspora_handle} and finally
three @#{people[2].diaspora_handle}.
STR
fmt_msg = Diaspora::Mentionable.format(test_text_without_names, [])
expect(fmt_msg).to eql test_txt_plain
end
end
describe ".people_from_string" do
it "extracts the mentioned people from the text" do
ppl = Diaspora::Mentionable.people_from_string(test_text_with_names)
expect(ppl).to match_array(people)
end
it "extracts the mentioned people from the text without name" do
text = "test @{#{people[0].diaspora_handle}} test"
ppl = Diaspora::Mentionable.people_from_string(text)
expect(ppl).to match_array([people[0]])
end
it "extracts the mentioned people from the text mixed mentions (with and without name)" do
text = "@{#{people[0].diaspora_handle}} and @{#{names[1]}; #{people[1].diaspora_handle}}"
ppl = Diaspora::Mentionable.people_from_string(text)
expect(ppl).to match_array([people[0], people[1]])
end
describe "returns an empty array if nobody was found" do
it "gets a post without mentions" do
ppl = Diaspora::Mentionable.people_from_string("post w/o mentions")
expect(ppl).to be_empty
end
it "gets a post with invalid handles" do
ppl = Diaspora::Mentionable.people_from_string("@{...} @{bla; blubb}")
expect(ppl).to be_empty
end
it "filters duplicate handles" do
ppl = Diaspora::Mentionable.people_from_string("@{a; #{alice.diaspora_handle}} @{a; #{alice.diaspora_handle}}")
expect(ppl).to eq([alice.person])
end
it "fetches unknown handles" do
person = FactoryBot.build(:person)
expect(Person).to receive(:find_or_fetch_by_identifier).with("xxx@xxx.xx").and_return(person)
ppl = Diaspora::Mentionable.people_from_string("@{a; xxx@xxx.xx}")
expect(ppl).to eq([person])
end
it "handles DiscoveryError" do
expect(Person).to receive(:find_or_fetch_by_identifier).with("yyy@yyy.yy")
.and_raise(DiasporaFederation::Discovery::DiscoveryError)
ppl = Diaspora::Mentionable.people_from_string("@{b; yyy@yyy.yy}")
expect(ppl).to be_empty
end
end
end
describe ".filter_people" do
let(:user_a) { FactoryBot.create(:user_with_aspect, username: "user_a") }
let(:user_b) { FactoryBot.create(:user, username: "user_b") }
let(:user_c) { FactoryBot.create(:user, username: "user_c") }
before do
user_a.aspects.create!(name: "second")
user_a.share_with(user_b.person, user_a.aspects.where(name: "generic"))
user_a.share_with(user_c.person, user_a.aspects.where(name: "second"))
end
it "filters mention, if contact is not in a given aspect" do
mention = "@{user C; #{user_c.diaspora_handle}}"
txt = Diaspora::Mentionable.filter_people(
"mentioning #{mention}",
user_a.aspects.where(name: "generic").first.contacts.map(&:person_id)
)
expect(txt).to include("@[user C](#{Rails.application.routes.url_helpers.person_path(user_c.person)}")
expect(txt).not_to include("href")
expect(txt).not_to include(mention)
end
it "leaves mention, if contact is in a given aspect" do
mention = "@{user B; #{user_b.diaspora_handle}}"
txt = Diaspora::Mentionable.filter_people(
"mentioning #{mention}",
user_a.aspects.where(name: "generic").first.contacts.map(&:person_id)
)
expect(txt).to include("user B")
expect(txt).to include(mention)
end
it "works if the person cannot be found" do
expect(Person).to receive(:find_or_fetch_by_identifier).with("non_existing_user@example.org").and_return(nil)
mention = "@{non_existing_user@example.org}"
txt = Diaspora::Mentionable.filter_people("mentioning #{mention}", [])
expect(txt).to eq "mentioning @non_existing_user@example.org"
end
end
end