# frozen_string_literal: true require 'rails_helper' RSpec.describe TranslateStatusService do subject(:service) { described_class.new } let(:status) { Fabricate(:status, text: text, spoiler_text: spoiler_text, language: 'en', preloadable_poll: poll, media_attachments: media_attachments) } let(:text) { 'Hello' } let(:spoiler_text) { '' } let(:poll) { nil } let(:media_attachments) { [] } before do Fabricate(:custom_emoji, shortcode: 'highfive') end describe '#call' do before do translation_service = TranslationService.new allow(translation_service).to receive(:languages).and_return({ 'en' => ['es'] }) allow(translation_service).to receive(:translate) do |texts| texts.map do |text| TranslationService::Translation.new( text: text.gsub('Hello', 'Hola').gsub('higfive', 'cincoaltos'), detected_source_language: 'en', provider: 'Dummy' ) end end allow(TranslationService).to receive_messages(configured?: true, configured: translation_service) end it 'returns translated status content' do expect(service.call(status, nil, 'es').content).to eq '

Hola

' end it 'returns source language' do expect(service.call(status, nil, 'es').detected_source_language).to eq 'en' end it 'returns translation provider' do expect(service.call(status, nil, 'es').provider).to eq 'Dummy' end it 'returns original status' do expect(service.call(status, nil, 'es').status).to eq status end describe 'status has content with custom emoji' do let(:text) { 'Hello & :highfive:' } it 'does not translate shortcode' do expect(service.call(status, nil, 'es').content).to eq '

Hola & :highfive:

' end end describe 'status has no spoiler_text' do it 'returns an empty string' do expect(service.call(status, nil, 'es').spoiler_text).to eq '' end end describe 'status has spoiler_text' do let(:spoiler_text) { 'Hello & Hello!' } it 'translates the spoiler text' do expect(service.call(status, nil, 'es').spoiler_text).to eq 'Hola & Hola!' end end describe 'status has spoiler_text with custom emoji' do let(:spoiler_text) { 'Hello :highfive:' } it 'does not translate shortcode' do expect(service.call(status, nil, 'es').spoiler_text).to eq 'Hola :highfive:' end end describe 'status has spoiler_text with unmatched custom emoji' do let(:spoiler_text) { 'Hello :Hello:' } it 'translates the invalid shortcode' do expect(service.call(status, nil, 'es').spoiler_text).to eq 'Hola :Hola:' end end describe 'status has poll' do let(:poll) { Fabricate(:poll, options: ['Hello 1', 'Hello 2']) } it 'translates the poll option title' do status_translation = service.call(status, nil, 'es') expect(status_translation.poll_options.size).to eq 2 expect(status_translation.poll_options.first.title).to eq 'Hola 1' end end describe 'status has media attachment' do let(:media_attachments) { [Fabricate(:media_attachment, description: 'Hello & :highfive:')] } it 'translates the media attachment description' do status_translation = service.call(status, nil, 'es') media_attachment = status_translation.media_attachments.first expect(media_attachment.id).to eq media_attachments.first.id expect(media_attachment.description).to eq 'Hola & :highfive:' end end end describe '#source_texts' do before do service.instance_variable_set(:@status, status) end describe 'status only has content' do it 'returns formatted content' do expect(service.send(:source_texts)).to eq({ content: '

Hello

' }) end end describe 'status content contains custom emoji' do let(:status) { Fabricate(:status, text: 'Hello :highfive:') } it 'returns formatted content' do source_texts = service.send(:source_texts) expect(source_texts[:content]).to eq '

Hello :highfive:

' end end describe 'status content contains tags' do let(:status) { Fabricate(:status, text: 'Hello #hola') } it 'returns formatted content' do source_texts = service.send(:source_texts) expect(source_texts[:content]).to include '

Hello :highfive:' end end describe 'status has poll' do let(:poll) { Fabricate(:poll, options: %w(Blue Green)) } context 'with source texts from the service' do let!(:source_texts) { service.send(:source_texts) } it 'returns formatted poll options' do expect(source_texts.size).to eq 3 expect(source_texts.values).to eq %w(

Hello

Blue Green) end it 'has a first key with content' do expect(source_texts.keys.first).to eq :content end it 'has the first option in the second key with correct options' do option1 = source_texts.keys.second expect(option1).to be_a Poll::Option expect(option1.id).to eq '0' expect(option1.title).to eq 'Blue' end it 'has the second option in the third key with correct options' do option2 = source_texts.keys.third expect(option2).to be_a Poll::Option expect(option2.id).to eq '1' expect(option2.title).to eq 'Green' end end end describe 'status has poll with custom emoji' do let(:poll) { Fabricate(:poll, options: ['Blue', 'Green :highfive:']) } it 'returns formatted poll options' do html = service.send(:source_texts).values.last expect(html).to eq 'Green :highfive:' end end describe 'status has media attachments' do let(:text) { '' } let(:media_attachments) { [Fabricate(:media_attachment, description: 'Hello :highfive:')] } it 'returns media attachments without custom emoji rendering' do source_texts = service.send(:source_texts) expect(source_texts.size).to eq 1 key, text = source_texts.first expect(key).to eq media_attachments.first expect(text).to eq 'Hello :highfive:' end end end describe '#wrap_emoji_shortcodes' do before do service.instance_variable_set(:@status, status) end describe 'string contains custom emoji' do let(:text) { ':highfive:' } it 'renders the emoji' do html = service.send(:wrap_emoji_shortcodes, 'Hello :highfive:'.html_safe) expect(html).to eq 'Hello :highfive:' end end end describe '#unwrap_emoji_shortcodes' do describe 'string contains custom emoji' do it 'inserts the shortcode' do fragment = service.send(:unwrap_emoji_shortcodes, '

Hello :highfive:!

') expect(fragment.to_html).to eq '

Hello :highfive:!

' end it 'preserves other attributes than translate=no' do fragment = service.send(:unwrap_emoji_shortcodes, '

Hello :highfive:!

') expect(fragment.to_html).to eq '

Hello :highfive:!

' end end end end