also validate remote posts
all data is included in the federated status_message, so we can validate on receive. add the photos to the status_message before save.
This commit is contained in:
parent
df9874b73a
commit
2cd831f94e
4 changed files with 37 additions and 27 deletions
|
|
@ -13,7 +13,7 @@ class StatusMessage < Post
|
||||||
validates_length_of :text, :maximum => 65535, :message => proc {|p, v| I18n.t('status_messages.too_long', :count => 65535, :current_length => v[:value].length)}
|
validates_length_of :text, :maximum => 65535, :message => proc {|p, v| I18n.t('status_messages.too_long', :count => 65535, :current_length => v[:value].length)}
|
||||||
|
|
||||||
# don't allow creation of empty status messages
|
# don't allow creation of empty status messages
|
||||||
validate :presence_of_content, on: :create, if: proc {|sm| sm.author && sm.author.local? }
|
validate :presence_of_content, on: :create
|
||||||
|
|
||||||
has_many :photos, :dependent => :destroy, :foreign_key => :status_message_guid, :primary_key => :guid
|
has_many :photos, :dependent => :destroy, :foreign_key => :status_message_guid, :primary_key => :guid
|
||||||
|
|
||||||
|
|
@ -126,9 +126,7 @@ class StatusMessage < Post
|
||||||
|
|
||||||
protected
|
protected
|
||||||
def presence_of_content
|
def presence_of_content
|
||||||
if text_and_photos_blank?
|
errors[:base] << "Cannot create a StatusMessage without content" if text_and_photos_blank?
|
||||||
errors[:base] << "Cannot create a StatusMessage without content"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def absence_of_content
|
def absence_of_content
|
||||||
|
|
|
||||||
|
|
@ -161,9 +161,20 @@ module Diaspora
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.status_message(entity)
|
def self.status_message(entity)
|
||||||
save_status_message(entity).tap do
|
try_load_existing_guid(StatusMessage, entity.guid, author_of(entity)) do
|
||||||
entity.photos.map do |photo|
|
StatusMessage.new(
|
||||||
ignore_existing_guid(Photo, photo.guid, author_of(photo)) { save_photo(photo) }
|
author: author_of(entity),
|
||||||
|
guid: entity.guid,
|
||||||
|
text: entity.text,
|
||||||
|
public: entity.public,
|
||||||
|
created_at: entity.created_at,
|
||||||
|
provider_display_name: entity.provider_display_name
|
||||||
|
).tap do |status_message|
|
||||||
|
status_message.location = build_location(entity.location) if entity.location
|
||||||
|
status_message.poll = build_poll(entity.poll) if entity.poll
|
||||||
|
status_message.photos = save_or_load_photos(entity.photos)
|
||||||
|
|
||||||
|
status_message.save!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -228,6 +239,12 @@ module Diaspora
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private_class_method def self.save_or_load_photos(photos)
|
||||||
|
photos.map do |photo|
|
||||||
|
try_load_existing_guid(Photo, photo.guid, author_of(photo)) { save_photo(photo) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private_class_method def self.receive_relayable(klass, entity)
|
private_class_method def self.receive_relayable(klass, entity)
|
||||||
save_relayable(klass, entity) { yield }.tap {|relayable| relay_relayable(relayable) if relayable }
|
save_relayable(klass, entity) { yield }.tap {|relayable| relay_relayable(relayable) if relayable }
|
||||||
end
|
end
|
||||||
|
|
@ -243,24 +260,6 @@ module Diaspora
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private_class_method def self.save_status_message(entity)
|
|
||||||
try_load_existing_guid(StatusMessage, entity.guid, author_of(entity)) do
|
|
||||||
StatusMessage.new(
|
|
||||||
author: author_of(entity),
|
|
||||||
guid: entity.guid,
|
|
||||||
text: entity.text,
|
|
||||||
public: entity.public,
|
|
||||||
created_at: entity.created_at,
|
|
||||||
provider_display_name: entity.provider_display_name
|
|
||||||
).tap do |status_message|
|
|
||||||
status_message.location = build_location(entity.location) if entity.location
|
|
||||||
status_message.poll = build_poll(entity.poll) if entity.poll
|
|
||||||
|
|
||||||
status_message.save!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private_class_method def self.retract_if_author_ignored(relayable)
|
private_class_method def self.retract_if_author_ignored(relayable)
|
||||||
parent_author = relayable.parent.author.owner
|
parent_author = relayable.parent.author.owner
|
||||||
return unless parent_author && parent_author.ignored_people.include?(relayable.author)
|
return unless parent_author && parent_author.ignored_people.include?(relayable.author)
|
||||||
|
|
|
||||||
|
|
@ -591,6 +591,19 @@ describe Diaspora::Federation::Receive do
|
||||||
expect(status_message.photos.map(&:guid)).to include(photo1.guid, photo2.guid)
|
expect(status_message.photos.map(&:guid)).to include(photo1.guid, photo2.guid)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "receives a status message only with photos and without text" do
|
||||||
|
entity = DiasporaFederation::Entities::StatusMessage.new(status_message_entity.to_h.merge(text: nil))
|
||||||
|
received = Diaspora::Federation::Receive.perform(entity)
|
||||||
|
|
||||||
|
status_message = StatusMessage.find_by!(guid: status_message_entity.guid)
|
||||||
|
|
||||||
|
expect(received).to eq(status_message)
|
||||||
|
expect(status_message.author).to eq(sender)
|
||||||
|
|
||||||
|
expect(status_message.text).to be_nil
|
||||||
|
expect(status_message.photos.map(&:guid)).to include(photo1.guid, photo2.guid)
|
||||||
|
end
|
||||||
|
|
||||||
it "does not overwrite the photos if they already exist" do
|
it "does not overwrite the photos if they already exist" do
|
||||||
received_photo = Diaspora::Federation::Receive.photo(photo1)
|
received_photo = Diaspora::Federation::Receive.photo(photo1)
|
||||||
received_photo.text = "foobar"
|
received_photo.text = "foobar"
|
||||||
|
|
|
||||||
|
|
@ -114,9 +114,9 @@ describe StatusMessage, type: :model do
|
||||||
expect(post.errors.full_messages).to eq([])
|
expect(post.errors.full_messages).to eq([])
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't check for content when author is remote (federation...)" do
|
it "also checks for content when author is remote" do
|
||||||
post = FactoryGirl.build(:status_message, text: nil)
|
post = FactoryGirl.build(:status_message, text: nil)
|
||||||
expect(post).to be_valid
|
expect(post).not_to be_valid
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue