diaspora/spec/models/status_message_spec.rb
Jonne Haß 09908a45fb
StatusMessage#raw_message returns empty string for NULL values
Previously the federation layer has written the empty string to the
database, now it writes nil/no value to it while our code still expects
the empty string in some cases. Restore the old assumption by returning
the empty string, the real raw value by now is available again in
StatusMessage#text for those that need it, such as validations or tests.
2016-06-27 12:07:11 +02:00

331 lines
11 KiB
Ruby

# 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, type: :model do
include PeopleHelper
let!(:user) { alice }
let!(:aspect) { user.aspects.first }
let(:status) { build(:status_message) }
describe "scopes" do
describe ".where_person_is_mentioned" do
it "returns status messages where the given person is mentioned" do
@bob = bob.person
@test_string = "@{Daniel; #{@bob.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)
expect(StatusMessage.where_person_is_mentioned(bob).count).to eq(2)
end
end
context "tag_streams" do
before do
@status_message_1 = FactoryGirl.create(:status_message, text: "#hashtag", public: true)
@status_message_2 = FactoryGirl.create(:status_message, text: "#hashtag")
@status_message_3 = FactoryGirl.create(:status_message, text: "hashtags are #awesome", public: true)
@status_message_4 = 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])
expect(tag_stream).to include @status_message_1
expect(tag_stream).to include @status_message_2
end
end
describe ".public_tag_stream" do
it "returns public status messages tagged with the tag" do
expect(StatusMessage.public_tag_stream([@tag_id])).to eq([@status_message_1])
end
end
describe ".user_tag_stream" do
it "returns tag stream thats owned or visible by" do
relation = double
expect(StatusMessage).to receive(:owned_or_visible_by_user).with(bob).and_return(relation)
expect(relation).to 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
status_message_1 = FactoryGirl.create(:status_message, author: alice.person)
FactoryGirl.create(:status_message, author: bob.person)
guids = StatusMessage.guids_for_author(alice.person)
expect(guids).to eq([status_message_1.guid])
end
end
describe ".before_validation" do
it "calls build_tags" do
expect(status).to receive(:build_tags)
status.save
end
end
describe ".before_create" do
it "calls build_tags" do
expect(status).to receive(:build_tags)
status.save
end
it "calls filter_mentions" do
expect(status).to 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}}")
expect(status).to receive(:create_mentions).and_call_original
status.save
end
end
context "emptyness" do
it "needs either a message or at least one photo" do
post = user.build_post(:status_message, text: nil)
expect(post).not_to be_valid
post.text = ""
expect(post).not_to be_valid
post.text = "wales"
expect(post).to be_valid
post.text = nil
photo = user.build_post(:photo, user_file: uploaded_photo, to: aspect.id)
photo.save!
post.photos << photo
expect(post).to be_valid
expect(post.message.to_s).to be_empty
expect(post.raw_message).to eq ""
expect(post.nsfw).to be_falsy
expect(post.errors.full_messages).to eq([])
end
it "doesn't check for content when author is remote (federation...)" do
post = FactoryGirl.build(:status_message, text: nil)
expect(post).to be_valid
end
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)
expect(db_status.text).to eq(message)
end
it "should require status messages not be more than 65535 characters long" do
message = "a" * (65_535 + 1)
status_message = FactoryGirl.build(:status_message, text: message)
expect(status_message).not_to be_valid
end
describe "mentions" do
let(:people) { [alice, bob, eve].map(&:person) }
let(:test_string) {
"@{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"
}
let(:status_message) { create(:status_message, text: test_string) }
describe "#create_mentions" do
it "creates a mention for everyone mentioned in the message" do
status_message
expect(Diaspora::Mentionable).to receive(:people_from_string).and_return(people)
status_message.mentions.delete_all
status_message.create_mentions
expect(status_message.mentions(true).map(&:person).to_set).to eq(people.to_set)
end
it "does not barf if it gets called twice" do
status_message.create_mentions
expect {
status_message.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
status_message.mentions.delete_all
expect(status_message).to receive(:create_mentions)
status_message.mentioned_people
end
it "returns the mentioned people" do
status_message.mentions.delete_all
expect(status_message.mentioned_people.to_set).to eq(people.to_set)
end
it "does not call create_mentions if there are mentions in the db" do
expect(status_message).not_to receive(:create_mentions)
status_message.mentioned_people
end
end
describe "#mentions?" do
it "returns true if the person was mentioned" do
expect(status_message.mentions?(people[0])).to be true
end
it "returns false if the person was not mentioned" do
expect(status_message.mentions?(FactoryGirl.build(:person))).to be false
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
expect(Diaspora::Mentionable).to 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)
expect(Diaspora::Mentionable).not_to 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")
expect(status.nsfw).to be_truthy
end
it "returns nil (false) if the post does not contain #nsfw" do
status = FactoryGirl.build(:status_message, text: "This message is #sFW")
expect(status.nsfw).to 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
expect(msg_uc.tags).to match_array(tag_array)
expect(msg_cp.tags).to match_array(tag_array)
end
it "should require tag name not be more than 255 characters long" do
message = "##{'a' * (255 + 1)}"
status_message = FactoryGirl.build(:status_message, text: message)
expect(status_message).not_to be_valid
end
end
describe "oembed" do
let(:youtube_url) { "https://www.youtube.com/watch?v=3PtFwlKfvHI" }
let(:message_text) { "#{youtube_url} is so cool. so is this link -> https://joindiaspora.com" }
let(:status_message) { FactoryGirl.build(:status_message, text: message_text) }
it "should queue a GatherOembedData if it includes a link" do
status_message
expect(Workers::GatherOEmbedData).to receive(:perform_async).with(instance_of(Fixnum), instance_of(String))
status_message.save
end
describe "#contains_oembed_url_in_text?" do
it "returns the oembed urls found in the raw message" do
expect(status_message.contains_oembed_url_in_text?).not_to be_nil
expect(status_message.oembed_url).to eq(youtube_url)
end
end
end
describe "opengraph" do
let(:ninegag_url) { "http://9gag.com/gag/a1AMW16" }
let(:youtube_url) { "https://www.youtube.com/watch?v=3PtFwlKfvHI" }
let(:message_text) { "#{ninegag_url} is so cool. so is this link -> https://joindiaspora.com" }
let(:oemessage_text) { "#{youtube_url} is so cool. so is this link -> https://joindiaspora.com" }
let(:status_message) { build(:status_message, text: message_text) }
it "should queue a GatherOpenGraphData if it includes a link" do
status_message
expect(Workers::GatherOpenGraphData).to receive(:perform_async).with(instance_of(Fixnum), instance_of(String))
status_message.save
end
describe "#contains_open_graph_url_in_text?" do
it "returns the opengraph urls found in the raw message" do
expect(status_message.contains_open_graph_url_in_text?).not_to be_nil
expect(status_message.open_graph_url).to eq(ninegag_url)
end
it "returns nil if the link is from trusted oembed provider" do
status_message = FactoryGirl.build(:status_message, text: oemessage_text)
expect(status_message.contains_open_graph_url_in_text?).to be_nil
expect(status_message.open_graph_url).to be_nil
end
end
end
describe "validation" do
let(:status_message) { build(:status_message, text: @message_text) }
it "should not be valid if the author is missing" do
status_message.author = nil
expect(status_message).not_to be_valid
end
end
describe "#coordinates" do
let(:status_message) { build(:status_message, text: @message_text) }
context "with location" do
let(:location) { build(:location) }
it "should deliver address and coordinates" do
status_message.location = location
expect(status_message.post_location).to include(address: location.address, lat: location.lat, lng: location.lng)
end
end
context "without location" do
it "should deliver empty address and coordinates" do
expect(status_message.post_location[:address]).to be_nil
expect(status_message.post_location[:lat]).to be_nil
expect(status_message.post_location[:lng]).to be_nil
end
end
end
end