Files
Reem-Notas/spec/support/espelho_rastreio.rb
2026-08-20 15:48:47 -03:00

103 lines
3.4 KiB
Ruby
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Harness da tabela do espelho de rastreio (db_reem_simplerout_2026) para os
# specs.
#
# A tabela é EXTERNA: não tem migration (o model Entrega proíbe explicitamente)
# e não tem factory. Sem este harness, qualquer teste que dependa dela só
# poderia mockar o método sob teste — o que não pega regressão de SQL, que é
# justamente onde moram os bugs de eixo de data (planned_date × checkout).
#
# Uso:
#
# RSpec.describe Entrega do
# include_context 'espelho de rastreio'
#
# it '...' do
# semear([{ driver: 'FULANO', vehicle: 'GADE_001', status: 'completed',
# planned_date: ..., checkout: ... }])
# end
# end
module EspelhoRastreio
TABELA = 'db_reem_simplerout_2026'.freeze
# `Entrega.da_conta_gade` filtra por DB_EXISTING_ACCOUNT_ID (default '95907').
# Gravamos nas linhas o primeiro valor configurado: se estiver 'all' o scope
# não filtra e o valor é indiferente; se estiver '95907' as linhas casam.
# Assim o harness não depende do ENV da máquina nem precisa stubar ENV.
CONTA = ENV.fetch('DB_EXISTING_ACCOUNT_ID', '95907').split(',').first.to_s.strip.presence || '95907'
class << self
def criar!
# ⚠️ GUARDA OBRIGATÓRIA. O model do espelho proíbe DROP porque a tabela
# real é a base de rastreio da operação. Aqui só criamos uma tabela de
# mesmo nome no banco de TESTE; se ela já existir COM DADOS, estamos
# apontados para dados de verdade e o spec tem que abortar em vez de
# destruí-los.
raise "Espelho de teste exige RAILS_ENV=test (está em #{Rails.env})" unless Rails.env.test?
return if @criada
if conexao.table_exists?(TABELA)
linhas = conexao.select_value("SELECT COUNT(*) FROM #{nome_citado}").to_i
if linhas.positive?
raise "#{TABELA} já existe no banco de teste com #{linhas} linha(s) — " \
'o spec NÃO vai derrubá-la. Aponte RAILS_ENV=test para um banco descartável.'
end
conexao.drop_table(TABELA)
end
conexao.create_table(TABELA, id: false) do |t|
t.string :tracking_id, null: false
t.string :account_id
t.bigint :reference_id
t.string :driver
t.string :vehicle
t.string :status
t.datetime :planned_date
t.datetime :checkout
t.string :contact_name
t.string :address
end
conexao.execute("ALTER TABLE #{nome_citado} ADD PRIMARY KEY (tracking_id)")
@criada = true
end
# Só derruba o que este harness criou.
def derrubar!
return unless @criada
conexao.drop_table(TABELA, if_exists: true)
@criada = false
end
def limpar!
conexao.execute("DELETE FROM #{nome_citado}") if @criada
end
private
def conexao
ActiveRecord::Base.connection
end
def nome_citado
conexao.quote_table_name(TABELA)
end
end
end
RSpec.shared_context 'espelho de rastreio' do
before(:all) { EspelhoRastreio.criar! }
after(:all) { EspelhoRastreio.derrubar! }
before { EspelhoRastreio.limpar! }
# O model é readonly? = true, então insert_all (que não instancia registro) é
# a única via de gravação — e vale só para o banco de teste.
def semear(linhas)
Entrega.insert_all(
linhas.map.with_index do |l, i|
{ tracking_id: "TRK-#{i}-#{SecureRandom.hex(3)}", account_id: EspelhoRastreio::CONTA }.merge(l)
end
)
end
end