require 'rails_helper' require 'base64' RSpec.describe PostCreator do let(:actor) { create(:user, :member) } def real_thumbnail_upload gif = Base64.decode64('R0lGODdhAQABAIABAP///wAAACwAAAAAAQABAAACAkQBADs=') Rack::Test::UploadedFile.new( StringIO.new(gif), 'image/gif', original_filename: 'thumbnail.gif') end before do allow(TagVersioning).to receive(:record_tag_snapshots!) allow(Tag).to receive(:expand_parent_tags).and_return([]) allow(PostVersionRecorder).to receive(:record!) end it 'prefers thumbnail_base over an explicit upload' do expect(Post).not_to receive(:resized_thumbnail_attachment) allow(Post).to receive(:remote_thumbnail_attachment).and_return( io: StringIO.new('remote'), filename: 'resized_thumbnail.jpg', content_type: 'image/jpeg') post = described_class.new( actor:, attributes: { title: 'title', url: 'https://example.com/post', thumbnail: real_thumbnail_upload, thumbnail_base: 'https://example.com/thumb.jpg', tags: '' }).create!(Locale.nipponese) expect(post.thumbnail).to be_attached expect(post.thumbnail_base).to eq('https://example.com/thumb.jpg') end it 'uses the common remote thumbnail attach path when thumbnail_base is given' do expect(Post).to receive(:remote_thumbnail_attachment) .with('https://example.com/thumb.jpg') .and_return( io: StringIO.new('thumbnail'), filename: 'thumbnail.jpg', content_type: 'image/jpeg') post = described_class.new( actor:, attributes: { title: 'title', url: 'https://example.com/post', thumbnail_base: 'https://example.com/thumb.jpg', tags: '' }).create!(Locale.nipponese) expect(post.thumbnail_base).to eq('https://example.com/thumb.jpg') expect(post.thumbnail).to be_attached end it 'does not create a post when remote thumbnail fetch fails' do allow(Post).to receive(:remote_thumbnail_attachment) .and_raise(Post::RemoteThumbnailFetchFailed, 'サムネール画像を取得できませんでした.') creator = described_class.new( actor:, attributes: { title: 'title', url: 'https://example.com/post', thumbnail_base: 'https://example.com/thumb.jpg', tags: '' }) post_count = Post.count expect { creator.create!(Locale.nipponese) } .to raise_error(Post::RemoteThumbnailFetchFailed) expect(Post.count).to eq(post_count) end context 'with an explicit locale' do include_context 'English locale' [false, true].each do |planned| it "passes locale to tag creation with planned attributes: #{ planned }" do attributes = { title: 'Locale propagation', url: 'https://example.com/locale-post', tags: 'character:locale_character' } if planned specs = [{ name: 'locale_character', category: :character }] attributes.merge!(snapshot_tag_specs: specs, post_tag_specs: specs) end allow(Tag).to receive(:find_or_create_by_tag_name!).and_call_original post = described_class.new(actor:, attributes:).create!(locale) expect(Tag).to have_received(:find_or_create_by_tag_name!) .with(locale, 'locale_character', category: :character).at_least(:once) tag_name = TagName.find_by!(language_code: 'en', name: 'locale_character') expect(tag_name).to have_attributes(script_code: 'Latn', primary_flg: true) expect(post.tags).to include(tag_name.tag) end end end end