Files
Reem-Notas/spec/requests/dashboard_spec.rb

221 lines
8.7 KiB
Ruby
Raw 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.
require 'rails_helper'
RSpec.describe 'Dashboard', type: :request do
it 'redireciona usuário não autenticado para o login' do
get dashboard_path
expect(response).to redirect_to(new_user_session_path)
end
it 'redireciona motorista para o painel exclusivo de motorista' do
sign_in create(:motorista)
get dashboard_path
expect(response).to redirect_to(motorista_dashboard_path)
end
end
# Trava a CONTABILIZAÇÃO DAS FALHAS no dashboard principal.
#
# A base financeira do dashboard é `atendidas` (concluídas + falhadas, com
# checkout) — o MESMO conjunto que a consolidação considera elegível e paga.
# Antes usava só `pagas` (concluídas) e o valor da tela ficava menor que o do
# fechamento; e as falhas eram filtradas por `planned_date`, caindo no período
# errado. Os dois casos estão fixados aqui.
#
# ⚠️ Falhada TEM checkout: o motorista foi ao local e fechou a visita com motivo
# de insucesso. É o que torna `checkout` o eixo correto também para elas.
RSpec.describe 'Dashboard — contabilização de falhas', type: :request do
include_context 'espelho de rastreio'
# Preço redondo para os valores esperados serem óbvios na leitura do spec.
let(:preco) { 10.0 }
let(:inicio) { '2026-08-01' }
let(:fim) { '2026-08-14' }
before do
create(:configuracao, chave: 'preco_entrega', valor: preco.to_s)
sign_in create(:gerente)
end
def abrir_dashboard
get dashboard_path, params: { inicio: inicio, fim: fim }
expect(response).to have_http_status(:ok)
response.body
end
it 'soma a falhada ao valor estimado e ao total de atendidas' do
semear([
{ driver: 'JOSE DA SILVA', vehicle: 'GADE_001', status: 'completed',
planned_date: Time.zone.local(2026, 8, 5, 8, 0), checkout: Time.zone.local(2026, 8, 5, 10, 0) },
{ driver: 'JOSE DA SILVA', vehicle: 'GADE_001', status: 'failed',
planned_date: Time.zone.local(2026, 8, 6, 8, 0), checkout: Time.zone.local(2026, 8, 6, 11, 0) }
])
corpo = abrir_dashboard
# 2 atendidas × R$ 10,00 — com a base antiga (`pagas`) seria 1 e R$ 10,00.
expect(corpo).to include('2 entregas atendidas')
expect(corpo).to include('1 concluídas · 1 falhadas')
expect(corpo).to include('R$ 20,00')
end
it 'conta a falhada pela data do CHECKOUT, não pela planejada' do
# Planejada em 31/07 (fora), entregue em 01/08 (dentro) → entra.
semear([
{ driver: 'JOSE DA SILVA', vehicle: 'GADE_002', status: 'failed',
planned_date: Time.zone.local(2026, 7, 31, 8, 0), checkout: Time.zone.local(2026, 8, 1, 9, 0) }
])
corpo = abrir_dashboard
expect(corpo).to include('1 entregas atendidas')
expect(corpo).to include('0 concluídas · 1 falhadas')
end
it 'exclui a falhada planejada dentro do período mas com checkout fora' do
# O espelho do caso acima: planejada em 10/08 (dentro), entregue em 01/09
# (fora) → não entra. Com o eixo antigo (planned_date) entrava.
semear([
{ driver: 'JOSE DA SILVA', vehicle: 'GADE_003', status: 'failed',
planned_date: Time.zone.local(2026, 8, 10, 8, 0), checkout: Time.zone.local(2026, 9, 1, 9, 0) }
])
corpo = abrir_dashboard
expect(corpo).to include('0 entregas atendidas')
expect(corpo).to include('0 concluídas · 0 falhadas')
end
it 'mantém a pendente fora do valor, contando-a só como pendente' do
# Pendente não tem checkout: continua no eixo planned_date e não vira R$.
semear([
{ driver: 'JOSE DA SILVA', vehicle: 'GADE_004', status: 'pending',
planned_date: Time.zone.local(2026, 8, 7, 8, 0), checkout: nil }
])
corpo = abrir_dashboard
expect(corpo).to include('0 entregas atendidas')
expect(corpo).to include('1 pendentes')
end
it 'inclui a falhada no ranking por motorista' do
semear([
# JOSE: 1 concluída + 1 falhada = 2 atendidas → R$ 20,00
{ driver: 'JOSE DA SILVA', vehicle: 'GADE_005', status: 'completed',
planned_date: Time.zone.local(2026, 8, 4, 8, 0), checkout: Time.zone.local(2026, 8, 4, 10, 0) },
{ driver: 'JOSE DA SILVA', vehicle: 'GADE_005', status: 'failed',
planned_date: Time.zone.local(2026, 8, 4, 8, 0), checkout: Time.zone.local(2026, 8, 4, 15, 0) },
# MARIA: 1 concluída = 1 atendida → R$ 10,00
{ driver: 'MARIA SOUZA', vehicle: 'GADE_006', status: 'completed',
planned_date: Time.zone.local(2026, 8, 5, 8, 0), checkout: Time.zone.local(2026, 8, 5, 10, 0) }
])
corpo = abrir_dashboard
expect(corpo).to include('3 entregas atendidas')
expect(corpo).to include('JOSE DA SILVA')
# R$ 20,00 do JOSE só existe se a falhada dele entrou na conta do ranking
# (com a base antiga ele apareceria com R$ 10,00, igual à MARIA).
expect(corpo).to include('R$ 20,00')
expect(corpo).to include('R$ 30,00') # total estimado do período
end
end
# Trava a ABA "CONSOLIDADO" do card de motoristas.
#
# O card tem duas abas sobre o mesmo ranking e elas mostram números diferentes de
# propósito: "Estimado" = atendidas × preço; "Consolidado" = o que realmente foi
# fechado (com bônus/desconto/retirada) + a quantidade de entregas do fechamento.
# Confundir as duas é justamente o que este spec impede.
RSpec.describe 'Dashboard — aba Consolidado do ranking de motoristas', type: :request do
include_context 'espelho de rastreio'
let(:inicio) { '2026-08-01' }
let(:fim) { '2026-08-14' }
before do
create(:configuracao, chave: 'preco_entrega', valor: '10.0')
sign_in create(:gerente)
end
# Só o conteúdo da aba consolidada: a aba estimada renderiza o MESMO markup
# (moeda + "N entregas"), então asserção no body inteiro passaria por acidente.
def painel_consolidado
get dashboard_path, params: { inicio: inicio, fim: fim }
expect(response).to have_http_status(:ok)
Nokogiri::HTML(response.body).at_css('#ranking-painel-consolidado').text
end
# cria as entregas ANTES do motorista: ConsolidacaoMotorista#recalcular_valor
# (before_save) soma as consolidacao_entregas do mesmo nome — sem elas o
# valor_total nasceria zerado.
def consolidar!(nome, linhas, consolidacao)
linhas.each { |l| create(:consolidacao_entrega, { consolidacao: consolidacao, motorista_nome: nome }.merge(l)) }
create(:consolidacao_motorista, consolidacao: consolidacao, motorista_nome: nome)
end
let(:consolidacao) do
create(:consolidacao, status: :finalizada,
data_inicio: Date.new(2026, 8, 1), data_fim: Date.new(2026, 8, 14))
end
it 'mostra o valor fechado e a quantidade exata de entregas de cada motorista' do
# JOSE: 2 entregas (TRK-A e TRK-B). TRK-A tem DOIS pilares (normal + bônus),
# então são 3 linhas para 2 entregas — é o caso que quebra se alguém contar
# linhas em vez de tracking_id distinto.
consolidar!('JOSE DA SILVA', [
{ tracking_id: 'TRK-A', tipo: :entrega_normal, valor_aplicado: 10.0 },
{ tracking_id: 'TRK-A', tipo: :bonus, valor_aplicado: 5.0 },
{ tracking_id: 'TRK-B', tipo: :entrega_normal, valor_aplicado: 10.0 }
], consolidacao)
consolidar!('MARIA SOUZA', [
{ tracking_id: 'TRK-C', tipo: :entrega_normal, valor_aplicado: 10.0 }
], consolidacao)
texto = painel_consolidado
expect(texto).to include('JOSE DA SILVA')
expect(texto).to include('R$ 25,00') # 10 + 5 + 10, valor REAL do fechamento
expect(texto).to include('2 entregas') # e NÃO 3: TRK-A conta uma vez só
expect(texto).to include('MARIA SOUZA')
expect(texto).to include('R$ 10,00')
expect(texto).to include('1 entregas')
end
it 'subtrai o desconto do valor fechado' do
consolidar!('JOSE DA SILVA', [
{ tracking_id: 'TRK-A', tipo: :entrega_normal, valor_aplicado: 10.0 },
{ tracking_id: 'TRK-A', tipo: :desconto, valor_aplicado: 4.0 }
], consolidacao)
expect(painel_consolidado).to include('R$ 6,00')
end
it 'não lista motorista arquivado, que saiu do fechamento' do
consolidar!('JOSE DA SILVA', [
{ tracking_id: 'TRK-A', tipo: :entrega_normal, valor_aplicado: 10.0 }
], consolidacao)
cm = consolidar!('MARIA SOUZA', [
{ tracking_id: 'TRK-C', tipo: :entrega_normal, valor_aplicado: 10.0 }
], consolidacao)
cm.arquivar!(nil)
texto = painel_consolidado
expect(texto).to include('JOSE DA SILVA')
expect(texto).not_to include('MARIA SOUZA')
end
it 'ignora consolidação em rascunho — só entra o que foi finalizado' do
rascunho = create(:consolidacao, status: :rascunho,
data_inicio: Date.new(2026, 8, 1), data_fim: Date.new(2026, 8, 14))
consolidar!('JOSE DA SILVA', [
{ tracking_id: 'TRK-A', tipo: :entrega_normal, valor_aplicado: 10.0 }
], rascunho)
expect(painel_consolidado).to include('Nenhuma consolidação finalizada neste período')
end
end