Files
Reem-Notas/spec/services/pdf/romaneio_pdf_spec.rb

108 lines
4.1 KiB
Ruby

require 'rails_helper'
# A gem entra com `require: false` no Gemfile (é ferramenta de teste, não de runtime).
require 'pdf/inspector'
# As constantes derivadas SÃO o contrato do documento: elas foram conferidas pixel a
# pixel contra Imagens para implantação/Romaneiro_EMAD_SETEMBRO_2026.pdf (render a
# 110 dpi). Se alguém mexer numa margem "só um pouquinho", é aqui que aparece.
RSpec.describe Pdf::RomaneioPdf do
let(:romaneio) { create(:romaneio) }
def semear(veiculo, quantidade)
quantidade.times do |i|
create(:romaneio_linha, romaneio: romaneio, veiculo: veiculo, ordem: i + 1)
end
end
def paginas(pdf)
PDF::Inspector::Page.analyze(pdf).pages.size
end
describe 'geometria' do
subject(:documento) { described_class.new(romaneio: romaneio) }
it 'é A4 paisagem' do
medidas = documento.instance_variable_get(:@pdf).bounds
expect([medidas.width.round(2), medidas.height.round(2)]).to eq([785.2, 487.56])
end
it 'mantém a altura de linha e os corpos de fonte do documento original' do
expect(documento.instance_variable_get(:@linha_h)).to be_within(0.001).of(11.1811)
expect(documento.instance_variable_get(:@fonte_dados)).to eq(7.0)
expect(documento.instance_variable_get(:@fonte_hdr)).to eq(7.5)
end
it 'usa a largura útil inteira nas seis colunas' do
larguras = documento.instance_variable_get(:@larguras)
expect(larguras.size).to eq(6)
expect(larguras.sum).to be_within(0.01).of(785.2)
end
it 'reserva espaço para o rodapé caber na folha cheia' do
# 33 paradas + as 2 linhas em branco estouravam o orçamento e o
# "ASSINATURA DO MOTORISTA" sumia do papel, sem erro nenhum.
expect(documento.instance_variable_get(:@max_linhas_folha))
.to be >= described_class::MAX_LINHAS
end
end
it 'gera uma página por veículo' do
semear('GADE_001', 5)
semear('GADE_002', 3)
expect(paginas(described_class.new(romaneio: romaneio).render)).to eq(2)
end
it 'imprime só o veículo pedido (é o que a prévia do editor usa)' do
semear('GADE_001', 5)
semear('GADE_002', 3)
expect(paginas(described_class.new(romaneio: romaneio, veiculos: ['GADE_002']).render)).to eq(1)
end
it 'quebra em folhas de continuação acima de MAX_LINHAS' do
semear('GADE_008', described_class::MAX_LINHAS + 1)
pdf = described_class.new(romaneio: romaneio).render
expect(paginas(pdf)).to eq(2)
texto = PDF::Inspector::Text.analyze(pdf).strings.join(' ')
expect(texto).to include('FOLHA 1/2').and include('FOLHA 2/2')
end
it 'assina TODAS as folhas — inclusive a de continuação' do
semear('GADE_008', described_class::MAX_LINHAS + 1)
texto = PDF::Inspector::Text.analyze(described_class.new(romaneio: romaneio).render).strings
expect(texto.count { |t| t.include?('ASSINATURA DO MOTORISTA') }).to eq(2)
end
it 'numera as paradas continuando entre folhas (bate com a ordem no celular)' do
semear('GADE_008', described_class::MAX_LINHAS + 1)
texto = PDF::Inspector::Text.analyze(described_class.new(romaneio: romaneio).render).strings
expect(texto).to include((described_class::MAX_LINHAS + 1).to_s)
end
it 'não imprime a parada que saiu do plano' do
semear('GADE_001', 3)
romaneio.romaneio_linhas.first.update!(removido_em: Time.current, nome: 'NAO DEVE SAIR')
texto = PDF::Inspector::Text.analyze(described_class.new(romaneio: romaneio).render).strings.join(' ')
expect(texto).not_to include('NAO DEVE SAIR')
end
it 'escreve o rótulo do plano no cabeçalho' do
semear('GADE_001', 2)
texto = PDF::Inspector::Text.analyze(described_class.new(romaneio: romaneio).render).strings.join(' ')
expect(texto).to include('PLANO:').and include('EMAD 09.2026')
end
it 'aguenta acento nos endereços (a fonte AFM do Prawn estouraria aqui)' do
create(:romaneio_linha, romaneio: romaneio, veiculo: 'GADE_001',
endereco: 'RUA INÁCIO DE OLIVEIRA CAMPOS, 182, SÃO PAULO')
expect { described_class.new(romaneio: romaneio).render }.not_to raise_error
end
end