Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix: #442 カスタム絵文字のaliasesにnullが入る場合がある #443

Merged
merged 4 commits into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions app/helpers/jsonld_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ def as_array(value)
end
end

def as_array_ex(value)
if value.is_a?(Hash)
[]
else
as_array(value)
end
end

def value_or_id(value)
value.is_a?(String) || value.nil? ? value : value['id']
end
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/mastodon/features/emoji/emoji_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const buildSearch = (data) => {
}

(Array.isArray(strings) ? strings : [strings]).forEach((string) => {
(split ? string.split(/[-|_|\s]+/) : [string]).forEach((s) => {
(split ? string.split(/[-|_|\s]+/) : [string]).filter((s) => s).forEach((s) => {
s = s.toLowerCase();

if (search.indexOf(s) === -1) {
Expand Down
2 changes: 1 addition & 1 deletion app/lib/activitypub/parser/custom_emoji_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def shortcode
end

def aliases
as_array(@json['keywords'])
as_array_ex(@json['keywords'])
end

def image_remote_url
Expand Down
10 changes: 5 additions & 5 deletions app/models/custom_emoji.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ def object_type
def copy!
copy = self.class.find_or_initialize_by(
domain: nil,
shortcode: shortcode,
license: license,
aliases: aliases,
is_sensitive: is_sensitive
shortcode: shortcode
)
copy.aliases = (aliases || []).compact_blank
copy.license = license
copy.is_sensitive = is_sensitive
copy.image = image
copy.tap(&:save!)
end
Expand All @@ -96,7 +96,7 @@ def aliases_raw
end

def aliases_raw=(raw)
aliases = raw.split(',').filter(&:present?).uniq
aliases = raw.split(',').compact_blank.uniq
self[:aliases] = aliases
end

Expand Down
10 changes: 7 additions & 3 deletions app/serializers/rest/custom_emoji_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ class REST::CustomEmojiSerializer < REST::CustomEmojiSlimSerializer

# Please update `app/javascript/mastodon/api_types/custom_emoji.ts` when making changes to the attributes

attribute :aliases, if: :aliases?
attribute :aliases

def aliases?
object.respond_to?(:aliases) && object.aliases.present?
def aliases
if object.respond_to?(:aliases) && object.aliases.present?
object.aliases.compact_blank
else
[]
end
end
end
46 changes: 46 additions & 0 deletions spec/models/custom_emoji_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,52 @@
end
end

describe '#copy!' do
subject do
custom_emoji.copy!
described_class.where.not(id: custom_emoji.id).find_by(domain: nil, shortcode: custom_emoji.shortcode)
end

context 'when a simple case' do
let(:custom_emoji) { Fabricate(:custom_emoji, license: 'Ohagi', aliases: %w(aaa bbb), domain: 'example.com', uri: 'https://example.com/emoji') }

it 'makes a copy ot the emoji' do
emoji = subject
expect(emoji).to_not be_nil
expect(emoji.license).to eq 'Ohagi'
expect(emoji.aliases).to eq %w(aaa bbb)
end
end

context 'when local has already same emoji' do
let(:custom_emoji) { Fabricate(:custom_emoji, domain: nil) }

it 'does not make a copy of the emoji' do
expect(subject).to be_nil
end
end

context 'when aliases is null' do
let(:custom_emoji) { Fabricate(:custom_emoji, aliases: nil, domain: 'example.com', uri: 'https://example.com/emoji') }

it 'makes a copy of the emoji but aliases property is normalized' do
emoji = subject
expect(emoji).to_not be_nil
expect(emoji.aliases).to eq []
end
end

context 'when aliases contains null' do
let(:custom_emoji) { Fabricate(:custom_emoji, aliases: [nil], domain: 'example.com', uri: 'https://example.com/emoji') }

it 'makes a copy of the emoji but aliases property is normalized' do
emoji = subject
expect(emoji).to_not be_nil
expect(emoji.aliases).to eq []
end
end
end

describe '#object_type' do
it 'returns :emoji' do
custom_emoji = Fabricate(:custom_emoji)
Expand Down
4 changes: 2 additions & 2 deletions spec/models/form/custom_emoji_batch_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,12 @@
end

describe 'the copy action' do
let(:custom_emoji) { Fabricate(:custom_emoji) }
let(:custom_emoji) { Fabricate(:custom_emoji, domain: 'example.com', uri: 'https://example.com/emoji') }
let(:options) { { action: 'copy', custom_emoji_ids: [custom_emoji.id] } }

it 'makes a copy of the emoji' do
expect { subject.save }
.to change(CustomEmoji, :count).by(1)
.to change(CustomEmoji, :count).by(2)
end
end

Expand Down
41 changes: 41 additions & 0 deletions spec/serializers/rest/custom_emoji_serializer_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# frozen_string_literal: true

require 'rails_helper'

describe REST::CustomEmojiSerializer do
let(:serialization) { serialized_record_json(record, described_class) }
let(:record) do
Fabricate(:custom_emoji, shortcode: 'ohagi', aliases: aliases)
end
let(:aliases) { [] }

context 'when empty aliases' do
it 'returns normalized aliases' do
expect(serialization['aliases']).to eq []
end
end

context 'when null aliases' do
let(:aliases) { nil }

it 'returns normalized aliases' do
expect(serialization['aliases']).to eq []
end
end

context 'when aliases contains null' do
let(:aliases) { [nil] }

it 'returns normalized aliases' do
expect(serialization['aliases']).to eq []
end
end

context 'when aliases contains normal text' do
let(:aliases) { ['neko'] }

it 'returns normalized aliases' do
expect(serialization['aliases']).to eq ['neko']
end
end
end