Some imagemagick-versions (I tested Ubuntu 22.04 and debian bullseye) always loose exif data when converting from jpg to webp. So this made our CI fail now, but even if it wasn't failing before, some pods always had and have versions which might loose the information anyway. So having a setting to keep exif information is kinda pointless, if we can't guarantee that the information isn't lost. Also, diaspora isn't a photo sharing platform and we don't display exif information anywhere, so I think we should just always strip exif data (which was already the default before), as we don't need them.
356 lines
12 KiB
Ruby
356 lines
12 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
|
# licensed under the Affero General Public License version 3 or later. See
|
|
# the COPYRIGHT file.
|
|
|
|
describe Diaspora::Exporter do
|
|
let(:user) { FactoryBot.create(:user_with_aspect) }
|
|
|
|
context "output json" do
|
|
let(:json) { Diaspora::Exporter.new(user).execute }
|
|
|
|
it "matches archive schema" do
|
|
DataGenerator.create(
|
|
user,
|
|
%i[generic_user_data activity status_messages_flavours work_aspect]
|
|
)
|
|
|
|
errors = JSON::Validator.fully_validate(ArchiveValidator::SchemaValidator::JSON_SCHEMA, JSON.parse(json))
|
|
expect(errors).to be_empty
|
|
end
|
|
|
|
it "contains basic user data" do
|
|
user_properties = build_property_hash(
|
|
user,
|
|
%i[email username language disable_mail show_community_spotlight_in_stream auto_follow_back
|
|
auto_follow_back_aspect],
|
|
private_key: :serialized_private_key
|
|
)
|
|
|
|
user_properties[:profile] = {
|
|
entity_type: "profile",
|
|
entity_data: build_property_hash(
|
|
user.profile,
|
|
%i[first_name last_name gender bio location image_url birthday searchable nsfw tag_string],
|
|
author: :diaspora_handle
|
|
)
|
|
}
|
|
|
|
expect(json).to include_json(user: user_properties)
|
|
end
|
|
|
|
it "contains aspects" do
|
|
DataGenerator.create(user, :work_aspect)
|
|
|
|
expect(json).to include_json(
|
|
user: {
|
|
"contact_groups": [
|
|
{
|
|
"name": "generic"
|
|
},
|
|
{
|
|
"name": "Work"
|
|
}
|
|
]
|
|
}
|
|
)
|
|
end
|
|
|
|
it "contains contacts" do
|
|
friends = DataGenerator.create(user, Array.new(2, :mutual_friend))
|
|
serialized_contacts = friends.map {|friend|
|
|
contact = Contact.find_by(person_id: friend.person_id)
|
|
hash = build_property_hash(
|
|
contact,
|
|
%i[sharing receiving person_guid person_name],
|
|
following: :sharing, followed: :receiving, account_id: :person_diaspora_handle
|
|
)
|
|
hash[:public_key] = contact.person.serialized_public_key
|
|
hash[:contact_groups_membership] = contact.aspects.map(&:name)
|
|
hash
|
|
}
|
|
|
|
expect(json).to include_json(user: {contacts: serialized_contacts})
|
|
end
|
|
|
|
it "contains a public status message" do
|
|
status_message = FactoryBot.create(:status_message, author: user.person, public: true)
|
|
serialized = {
|
|
"subscribed_pods_uris": [AppConfig.pod_uri.to_s],
|
|
"entity_type": "status_message",
|
|
"entity_data": {
|
|
"author": user.diaspora_handle,
|
|
"guid": status_message.guid,
|
|
"created_at": status_message.created_at.iso8601,
|
|
"text": status_message.text,
|
|
"public": true
|
|
}
|
|
}
|
|
|
|
expect(json).to include_json(user: {posts: [serialized]})
|
|
end
|
|
|
|
it "contains a status message with subscribers" do
|
|
subscriber, status_message = DataGenerator.create(user, :status_message_with_subscriber)
|
|
serialized = {
|
|
"subscribed_users_ids": [subscriber.diaspora_handle],
|
|
"entity_type": "status_message",
|
|
"entity_data": {
|
|
"author": user.diaspora_handle,
|
|
"guid": status_message.guid,
|
|
"created_at": status_message.created_at.iso8601,
|
|
"text": status_message.text,
|
|
"public": false
|
|
}
|
|
}
|
|
|
|
expect(json).to include_json(user: {posts: [serialized]})
|
|
end
|
|
|
|
it "contains a status message with a poll" do
|
|
status_message = FactoryBot.create(:status_message_with_poll, author: user.person)
|
|
serialized = {
|
|
"entity_type": "status_message",
|
|
"entity_data": {
|
|
"author": user.diaspora_handle,
|
|
"guid": status_message.guid,
|
|
"created_at": status_message.created_at.iso8601,
|
|
"text": status_message.text,
|
|
"poll": {
|
|
"entity_type": "poll",
|
|
"entity_data": {
|
|
"guid": status_message.poll.guid,
|
|
"question": status_message.poll.question,
|
|
"poll_answers": status_message.poll.poll_answers.map {|answer|
|
|
{
|
|
"entity_type": "poll_answer",
|
|
"entity_data": {
|
|
"guid": answer.guid,
|
|
"answer": answer.answer
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"public": false
|
|
}
|
|
}
|
|
|
|
expect(json).to include_json(user: {posts: [serialized]})
|
|
end
|
|
|
|
it "contains a status message with a photo" do
|
|
status_message = FactoryBot.create(:status_message_with_photo, author: user.person)
|
|
|
|
serialized = {
|
|
"entity_type": "status_message",
|
|
"entity_data": {
|
|
"author": user.diaspora_handle,
|
|
"guid": status_message.guid,
|
|
"created_at": status_message.created_at.iso8601,
|
|
"text": status_message.text,
|
|
"photos": [
|
|
{
|
|
"entity_type": "photo",
|
|
"entity_data": {
|
|
"guid": status_message.photos.first.guid,
|
|
"author": user.diaspora_handle,
|
|
"public": false,
|
|
"created_at": status_message.photos.first.created_at.iso8601,
|
|
"remote_photo_path": "#{AppConfig.pod_uri}uploads\/images\/",
|
|
"remote_photo_name": status_message.photos.first.remote_photo_name,
|
|
"status_message_guid": status_message.guid,
|
|
"height": 42,
|
|
"width": 23
|
|
}
|
|
}
|
|
],
|
|
"public": false
|
|
}
|
|
}
|
|
|
|
expect(json).to include_json(user: {posts: [serialized]})
|
|
end
|
|
|
|
it "contains a status message with a location" do
|
|
status_message = FactoryBot.create(:status_message_with_location, author: user.person)
|
|
|
|
serialized = {
|
|
"entity_type": "status_message",
|
|
"entity_data": {
|
|
"author": user.diaspora_handle,
|
|
"guid": status_message.guid,
|
|
"created_at": status_message.created_at.iso8601,
|
|
"text": status_message.text,
|
|
"location": {
|
|
"entity_type": "location",
|
|
"entity_data": {
|
|
"address": status_message.location.address,
|
|
"lat": status_message.location.lat,
|
|
"lng": status_message.location.lng
|
|
}
|
|
},
|
|
"public": false
|
|
}
|
|
}
|
|
|
|
expect(json).to include_json(user: {posts: [serialized]})
|
|
end
|
|
|
|
it "contains a reshare" do
|
|
reshare = FactoryBot.create(:reshare, author: user.person)
|
|
serialized_reshare = {
|
|
"subscribed_pods_uris": [reshare.root.author.pod.url_to(""), AppConfig.pod_uri.to_s],
|
|
"entity_type": "reshare",
|
|
"entity_data": {
|
|
"author": user.diaspora_handle,
|
|
"guid": reshare.guid,
|
|
"created_at": reshare.created_at.iso8601,
|
|
"root_author": reshare.root_author.diaspora_handle,
|
|
"root_guid": reshare.root_guid
|
|
}
|
|
}
|
|
|
|
expect(json).to include_json(
|
|
user: {posts: [serialized_reshare]}
|
|
)
|
|
end
|
|
|
|
it "contains followed tags" do
|
|
tag_following = DataGenerator.create(user, :tag_following)
|
|
expect(json).to include_json(user: {followed_tags: [tag_following.tag.name]})
|
|
end
|
|
|
|
it "contains post subscriptions" do
|
|
subscription = DataGenerator.create(user, :subscription)
|
|
expect(json).to include_json(user: {post_subscriptions: [subscription.target.guid]})
|
|
end
|
|
|
|
it "contains a comment" do
|
|
comment = FactoryBot.create(:comment, author: user.person)
|
|
serialized_comment = {
|
|
"entity_type": "comment",
|
|
"entity_data": {
|
|
"author": user.diaspora_handle,
|
|
"guid": comment.guid,
|
|
"parent_guid": comment.parent.guid,
|
|
"text": comment.text,
|
|
"created_at": comment.created_at.iso8601
|
|
},
|
|
"property_order": %w[author guid parent_guid text created_at]
|
|
}
|
|
|
|
expect(json).to include_json(
|
|
user: {relayables: [serialized_comment]}
|
|
)
|
|
end
|
|
|
|
it "contains a like" do
|
|
like = FactoryBot.create(:like, author: user.person)
|
|
serialized_like = {
|
|
"entity_type": "like",
|
|
"entity_data": {
|
|
"author": user.diaspora_handle,
|
|
"guid": like.guid,
|
|
"parent_guid": like.parent.guid,
|
|
"parent_type": like.target_type,
|
|
"positive": like.positive
|
|
},
|
|
"property_order": %w[author guid parent_guid parent_type positive]
|
|
}
|
|
|
|
expect(json).to include_json(
|
|
user: {relayables: [serialized_like]}
|
|
)
|
|
end
|
|
|
|
it "contains a poll participation" do
|
|
poll_participation = FactoryBot.create(:poll_participation, author: user.person)
|
|
serialized_participation = {
|
|
"entity_type": "poll_participation",
|
|
"entity_data": {
|
|
"author": user.diaspora_handle,
|
|
"guid": poll_participation.guid,
|
|
"parent_guid": poll_participation.parent.guid,
|
|
"poll_answer_guid": poll_participation.poll_answer.guid
|
|
},
|
|
"property_order": %w[author guid parent_guid poll_answer_guid]
|
|
}
|
|
|
|
expect(json).to include_json(
|
|
user: {relayables: [serialized_participation]}
|
|
)
|
|
end
|
|
|
|
it "contains a comment for the user's post" do
|
|
status_message, comment = DataGenerator.create(user, :status_message_with_comment)
|
|
serialized = {
|
|
"entity_type": "comment",
|
|
"entity_data": {
|
|
"author": comment.diaspora_handle,
|
|
"guid": comment.guid,
|
|
"parent_guid": status_message.guid,
|
|
"text": comment.text,
|
|
"created_at": comment.created_at.iso8601,
|
|
"author_signature": Diaspora::Federation::Entities.build(comment).to_h[:author_signature]
|
|
},
|
|
"property_order": %w[author guid parent_guid text created_at]
|
|
}
|
|
|
|
expect(json).to include_json(others_data: {relayables: [serialized]})
|
|
end
|
|
|
|
it "contains a like for the user's post" do
|
|
status_message, like = DataGenerator.create(user, :status_message_with_like)
|
|
serialized = {
|
|
"entity_type": "like",
|
|
"entity_data": {
|
|
"author": like.diaspora_handle,
|
|
"guid": like.guid,
|
|
"parent_guid": status_message.guid,
|
|
"parent_type": like.target_type,
|
|
"positive": like.positive,
|
|
"author_signature": Diaspora::Federation::Entities.build(like).to_h[:author_signature]
|
|
},
|
|
"property_order": %w[author guid parent_guid parent_type positive]
|
|
}
|
|
|
|
expect(json).to include_json(others_data: {relayables: [serialized]})
|
|
end
|
|
|
|
it "contains a poll participation for the user's post" do
|
|
_, poll_participation = DataGenerator.create(user, :status_message_with_poll_participation)
|
|
serialized = {
|
|
"entity_type": "poll_participation",
|
|
"entity_data": {
|
|
"author": poll_participation.diaspora_handle,
|
|
"guid": poll_participation.guid,
|
|
"parent_guid": poll_participation.parent.guid,
|
|
"poll_answer_guid": poll_participation.poll_answer.guid,
|
|
"author_signature": Diaspora::Federation::Entities.build(poll_participation).to_h[:author_signature]
|
|
},
|
|
"property_order": %w[author guid parent_guid poll_answer_guid]
|
|
}
|
|
|
|
expect(json).to include_json(others_data: {relayables: [serialized]})
|
|
end
|
|
|
|
def transform_value(value)
|
|
return value.iso8601 if value.is_a? Date
|
|
value
|
|
end
|
|
|
|
def build_property_hash(object, direct_properties, aliased_properties={})
|
|
props = direct_properties.map {|key|
|
|
[key, transform_value(object.send(key))]
|
|
}.to_h
|
|
|
|
aliased = aliased_properties.map {|key, key_alias|
|
|
[key, object.send(key_alias)]
|
|
}.to_h
|
|
|
|
props.merge(aliased)
|
|
end
|
|
end
|
|
end
|