Status messages now process mentions and output links
This commit is contained in:
parent
99f84de368
commit
0000185875
2 changed files with 53 additions and 10 deletions
|
|
@ -10,7 +10,7 @@ class StatusMessage < Post
|
||||||
|
|
||||||
validates_length_of :message, :maximum => 1000, :message => "please make your status messages less than 1000 characters"
|
validates_length_of :message, :maximum => 1000, :message => "please make your status messages less than 1000 characters"
|
||||||
xml_name :status_message
|
xml_name :status_message
|
||||||
xml_attr :message
|
xml_attr :raw_message
|
||||||
|
|
||||||
has_many :photos, :dependent => :destroy
|
has_many :photos, :dependent => :destroy
|
||||||
validate :message_or_photos_present?
|
validate :message_or_photos_present?
|
||||||
|
|
@ -22,19 +22,34 @@ class StatusMessage < Post
|
||||||
get_youtube_title message
|
get_youtube_title message
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def message
|
||||||
|
self.formatted_message
|
||||||
|
end
|
||||||
|
|
||||||
|
def raw_message
|
||||||
|
read_attribute(:message)
|
||||||
|
end
|
||||||
|
def raw_message=(text)
|
||||||
|
write_attribute(:message, text)
|
||||||
|
end
|
||||||
|
|
||||||
def formatted_message
|
def formatted_message
|
||||||
|
return self.raw_message unless self.raw_message
|
||||||
people = self.mentioned_people
|
people = self.mentioned_people
|
||||||
regex = /@\{([^;]+); ([^\}]+)\}/
|
regex = /@\{([^;]+); ([^\}]+)\}/
|
||||||
message.gsub(regex) do |matched_string|
|
escaped_message = ERB::Util.h(raw_message)
|
||||||
people.detect{ |p|
|
form_message = escaped_message.gsub(regex) do |matched_string|
|
||||||
|
person = people.detect{ |p|
|
||||||
p.diaspora_handle == matched_string.match(regex).captures.last
|
p.diaspora_handle == matched_string.match(regex).captures.last
|
||||||
}.name
|
}
|
||||||
|
"<a href=\"/people/#{person.id}\">#{ERB::Util.h(person.name)}</a>"
|
||||||
end
|
end
|
||||||
|
form_message
|
||||||
end
|
end
|
||||||
|
|
||||||
def mentioned_people
|
def mentioned_people
|
||||||
regex = /@\{([^;]+); ([^\}]+)\}/
|
regex = /@\{([^;]+); ([^\}]+)\}/
|
||||||
identifiers = self.message.scan(regex).map do |match|
|
identifiers = self.raw_message.scan(regex).map do |match|
|
||||||
match.last
|
match.last
|
||||||
end
|
end
|
||||||
self.person.owner.contact_people.where(:diaspora_handle => identifiers)
|
self.person.owner.contact_people.where(:diaspora_handle => identifiers)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
|
|
||||||
describe StatusMessage do
|
describe StatusMessage do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
|
@ -54,6 +55,12 @@ describe StatusMessage do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'mentions' do
|
describe 'mentions' do
|
||||||
|
def controller
|
||||||
|
mock()
|
||||||
|
end
|
||||||
|
|
||||||
|
include ActionView::Helpers::UrlHelper
|
||||||
|
include Rails.application.routes.url_helpers
|
||||||
before do
|
before do
|
||||||
@people = [alice, bob, eve].map{|u| u.person}
|
@people = [alice, bob, eve].map{|u| u.person}
|
||||||
@test_string = <<-STR
|
@test_string = <<-STR
|
||||||
|
|
@ -63,12 +70,29 @@ STR
|
||||||
@sm = Factory.create(:status_message, :message => @test_string )
|
@sm = Factory.create(:status_message, :message => @test_string )
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'adds the links in the formated message text' do
|
describe '#formatted_message' do
|
||||||
@sm.formatted_message.should == <<-STR
|
it 'adds the links in the formated message text' do
|
||||||
#{@people[0].name} can mention people like Raphael #{@people[1].name}
|
@sm.formatted_message.should == <<-STR
|
||||||
can mention people like Raphaellike Raphael #{@people[2].name} can mention people like Raph
|
#{link_to(@people[0].name, person_path(@people[0]))} can mention people like Raphael #{link_to(@people[1].name, person_path(@people[1]))}
|
||||||
|
can mention people like Raphaellike Raphael #{link_to(@people[2].name, person_path(@people[2]))} can mention people like Raph
|
||||||
STR
|
STR
|
||||||
|
end
|
||||||
|
it 'escapes the link title' do
|
||||||
|
p = @people[0].profile
|
||||||
|
p.first_name="</a><script>alert('h')</script>"
|
||||||
|
p.save!
|
||||||
|
|
||||||
|
@sm.formatted_message.should_not include(@people[0].profile.first_name)
|
||||||
|
end
|
||||||
|
it 'escapes the message' do
|
||||||
|
xss = "</a> <script> alert('hey'); </script>"
|
||||||
|
@sm.message << xss
|
||||||
|
|
||||||
|
@sm.formatted_message.should_not include xss
|
||||||
|
end
|
||||||
|
it 'is html_safe' do
|
||||||
|
@sm.formatted_message.html_safe?.should be_true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'extracts the mentioned people from the message' do
|
it 'extracts the mentioned people from the message' do
|
||||||
|
|
@ -80,8 +104,12 @@ STR
|
||||||
@message = Factory.create(:status_message, :message => "I hate WALRUSES!", :person => @user.person)
|
@message = Factory.create(:status_message, :message => "I hate WALRUSES!", :person => @user.person)
|
||||||
@xml = @message.to_xml.to_s
|
@xml = @message.to_xml.to_s
|
||||||
end
|
end
|
||||||
|
it 'serializes the unescaped, unprocessed message' do
|
||||||
|
@message.message = "<script> alert('xss should be federated');</script>"
|
||||||
|
@message.to_xml.to_s.should include @message.message
|
||||||
|
end
|
||||||
it 'serializes the message' do
|
it 'serializes the message' do
|
||||||
@xml.should include "<message>I hate WALRUSES!</message>"
|
@xml.should include "<raw_message>I hate WALRUSES!</raw_message>"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'serializes the author address' do
|
it 'serializes the author address' do
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue