# Copyright (c) 2010-2011, Diaspora Inc. This file is # licensed under the Affero General Public License version 3 or later. See # the COPYRIGHT file. require 'spec_helper' describe StatusMessage do include PeopleHelper before do @user = alice @aspect = @user.aspects.first end describe 'scopes' do describe '.where_person_is_mentioned' do it 'returns status messages where the given person is mentioned' do @bo = bob.person @test_string = "@{Daniel; #{@bo.diaspora_handle}} can mention people like Raph" FactoryGirl.create(:status_message, :text => @test_string ) FactoryGirl.create(:status_message, :text => @test_string ) FactoryGirl.create(:status_message) StatusMessage.where_person_is_mentioned(@bo).count.should == 2 end end context "tag_streams" do before do @sm1 = FactoryGirl.create(:status_message, :text => "#hashtag" , :public => true) @sm2 = FactoryGirl.create(:status_message, :text => "#hashtag" ) @sm3 = FactoryGirl.create(:status_message, :text => "hashtags are #awesome", :public => true ) @sm4 = FactoryGirl.create(:status_message, :text => "hashtags are #awesome" ) @tag_id = ActsAsTaggableOn::Tag.where(:name => "hashtag").first.id end describe '.tag_steam' do it 'returns status messages tagged with the tag' do tag_stream = StatusMessage.send(:tag_stream, [@tag_id]) tag_stream.should include @sm1 tag_stream.should include @sm2 end end describe '.public_tag_stream' do it 'returns public status messages tagged with the tag' do StatusMessage.public_tag_stream([@tag_id]).should == [@sm1] end end describe '.user_tag_stream' do it 'returns tag stream thats owned or visibile by' do StatusMessage.should_receive(:owned_or_visible_by_user).with(bob).and_return(StatusMessage) StatusMessage.should_receive(:tag_stream).with([@tag_id]) StatusMessage.user_tag_stream(bob, [@tag_id]) end end end end describe ".guids_for_author" do it 'returns an array of the status_message guids' do sm1 = FactoryGirl.create(:status_message, :author => alice.person) sm2 = FactoryGirl.create(:status_message, :author => bob.person) guids = StatusMessage.guids_for_author(alice.person) guids.should == [sm1.guid] end end describe '.before_create' do it 'calls build_tags' do status = FactoryGirl.build(:status_message) status.should_receive(:build_tags) status.save end it 'calls filter_mentions' do status = FactoryGirl.build(:status_message) status.should_receive(:filter_mentions) status.save end end describe '.after_create' do it 'calls create_mentions' do status = FactoryGirl.build(:status_message, text: "text @{Test; #{alice.diaspora_handle}}") status.should_receive(:create_mentions).and_call_original status.save end end describe '#diaspora_handle=' do it 'sets #author' do person = FactoryGirl.create(:person) post = FactoryGirl.build(:status_message, :author => @user.person) post.diaspora_handle = person.diaspora_handle post.author.should == person end end it "should have either a message or at least one photo" do n = FactoryGirl.build(:status_message, :text => nil) # n.valid?.should be_false # n.text = "" # n.valid?.should be_false n.text = "wales" n.valid?.should be_true n.text = nil photo = @user.build_post(:photo, :user_file => uploaded_photo, :to => @aspect.id) photo.save! n.photos << photo n.valid?.should be_true n.errors.full_messages.should == [] end it 'should be postable through the user' do message = "Users do things" status = @user.post(:status_message, :text => message, :to => @aspect.id) db_status = StatusMessage.find(status.id) db_status.text.should == message end it 'should require status messages not be more than 65535 characters long' do message = 'a' * (65535+1) status_message = FactoryGirl.build(:status_message, :text => message) status_message.should_not be_valid end describe 'mentions' do before do @people = [alice, bob, eve].map{|u| u.person} @test_string = <<-STR @{Raphael; #{@people[0].diaspora_handle}} can mention people like Raphael @{Ilya; #{@people[1].diaspora_handle}} can mention people like Raphaellike Raphael @{Daniel; #{@people[2].diaspora_handle}} can mention people like Raph STR @sm = FactoryGirl.create(:status_message, :text => @test_string ) end describe '#formatted_message' do it 'escapes the message' do xss = " " @sm.text << xss @sm.formatted_message.should_not include xss end it 'is html_safe' do @sm.formatted_message.html_safe?.should be_true end end describe '#create_mentions' do it 'creates a mention for everyone mentioned in the message' do Diaspora::Mentionable.should_receive(:people_from_string).and_return(@people) @sm.mentions.delete_all @sm.create_mentions @sm.mentions(true).map{|m| m.person}.to_set.should == @people.to_set end it 'does not barf if it gets called twice' do @sm.create_mentions expect{ @sm.create_mentions }.to_not raise_error end end describe '#mentioned_people' do it 'calls create_mentions if there are no mentions in the db' do @sm.mentions.delete_all @sm.should_receive(:create_mentions) @sm.mentioned_people end it 'returns the mentioned people' do @sm.mentions.delete_all @sm.mentioned_people.to_set.should == @people.to_set end it 'does not call create_mentions if there are mentions in the db' do @sm.should_not_receive(:create_mentions) @sm.mentioned_people end end describe "#mentions?" do it 'returns true if the person was mentioned' do @sm.mentions?(@people[0]).should be_true end it 'returns false if the person was not mentioned' do @sm.mentions?(FactoryGirl.build(:person)).should be_false end end describe "#notify_person" do it 'notifies the person mentioned' do Notification.should_receive(:notify).with(alice, anything, anything) @sm.notify_person(alice.person) end end describe "#filter_mentions" do it 'calls Diaspora::Mentionable#filter_for_aspects' do msg = FactoryGirl.build(:status_message_in_aspect) msg_txt = msg.raw_message author_usr = msg.author.owner aspect_id = author_usr.aspects.first.id Diaspora::Mentionable.should_receive(:filter_for_aspects) .with(msg_txt, author_usr, aspect_id) msg.send(:filter_mentions) end it "doesn't do anything when public" do msg = FactoryGirl.build(:status_message, public: true) Diaspora::Mentionable.should_not_receive(:filter_for_aspects) msg.send(:filter_mentions) end end end describe "#nsfw" do it 'returns MatchObject (true) if the post contains #nsfw (however capitalised)' do status = FactoryGirl.build(:status_message, :text => "This message is #nSFw") status.nsfw.should be_true end it 'returns nil (false) if the post does not contain #nsfw' do status = FactoryGirl.build(:status_message, :text => "This message is #sFW") status.nsfw.should be_false end end describe 'tags' do before do @object = FactoryGirl.build(:status_message) end it_should_behave_like 'it is taggable' it 'associates different-case tags to the same tag entry' do assert_equal ActsAsTaggableOn.force_lowercase, true msg_lc = FactoryGirl.build(:status_message, :text => '#newhere') msg_uc = FactoryGirl.build(:status_message, :text => '#NewHere') msg_cp = FactoryGirl.build(:status_message, :text => '#NEWHERE') msg_lc.save; msg_uc.save; msg_cp.save tag_array = msg_lc.tags msg_uc.tags.should =~ tag_array msg_cp.tags.should =~ tag_array end end describe "XML" do before do @message = FactoryGirl.build(:status_message, :text => "I hate WALRUSES!", :author => @user.person) @xml = @message.to_xml.to_s end it 'serializes the escaped, unprocessed message' do text = "[url](http://example.org)" @message.text = text @message.to_xml.to_s.should include Builder::XChar.encode(text) end it 'serializes the message' do @xml.should include "I hate WALRUSES!" end it 'serializes the author address' do @xml.should include(@user.person.diaspora_handle) end describe '.from_xml' do before do @marshalled = StatusMessage.from_xml(@xml) end it 'marshals the message' do @marshalled.text.should == "I hate WALRUSES!" end it 'marshals the guid' do @marshalled.guid.should == @message.guid end it 'marshals the author' do @marshalled.author.should == @message.author end it 'marshals the diaspora_handle' do @marshalled.diaspora_handle.should == @message.diaspora_handle end end context 'with some photos' do before do @message.photos << FactoryGirl.build(:photo) @message.photos << FactoryGirl.build(:photo) @xml = @message.to_xml.to_s end it 'serializes the photos' do @xml.should include "photo" @xml.should include @message.photos.first.remote_photo_path end describe '.from_xml' do before do @marshalled = StatusMessage.from_xml(@xml) end it 'marshals the photos' do @marshalled.photos.size.should == 2 end end end context 'with a location' do before do @message.location = Location.new(coordinates: "1, 2").tap(&:save) @xml = @message.to_xml.to_s end it 'serializes the location' do @xml.should include "location" @xml.should include "lat" @xml.should include "lng" end describe ".from_xml" do before do @marshalled = StatusMessage.from_xml(@xml) end it 'marshals the location' do @marshalled.location.should be_present end end end end describe '#after_dispatch' do before do @photos = [alice.build_post(:photo, :pending => true, :user_file=> File.open(photo_fixture_name)), alice.build_post(:photo, :pending => true, :user_file=> File.open(photo_fixture_name))] @photos.each(&:save!) @status_message = alice.build_post(:status_message, :text => "the best pebble.") @status_message.photos << @photos @status_message.save! alice.add_to_streams(@status_message, alice.aspects) end it 'sets pending to false on any attached photos' do @status_message.after_dispatch(alice) @photos.all?{|p| p.reload.pending}.should be_false end it 'dispatches any attached photos' do alice.should_receive(:dispatch_post).twice @status_message.after_dispatch(alice) end end describe 'oembed' do before do @youtube_url = "https://www.youtube.com/watch?v=3PtFwlKfvHI" @message_text = "#{@youtube_url} is so cool. so is this link -> https://joindiaspora.com" end it 'should queue a GatherOembedData if it includes a link' do sm = FactoryGirl.build(:status_message, :text => @message_text) Workers::GatherOEmbedData.should_receive(:perform_async).with(instance_of(Fixnum), instance_of(String)) sm.save end describe '#contains_oembed_url_in_text?' do it 'returns the oembed urls found in the raw message' do sm = FactoryGirl.build(:status_message, :text => @message_text) sm.contains_oembed_url_in_text?.should_not be_nil sm.oembed_url.should == @youtube_url end end end end