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(Tag).to receive(:normalise_tags!).and_return({ tags: [], sections: {} })
    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!

    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!

    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! }.to raise_error(Post::RemoteThumbnailFetchFailed)
    expect(Post.count).to eq(post_count)
  end
end
