# 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