Files
eminuxCRM/test/models/dashboard_metrics_test.rb
T
eminuxandCursor 47c4308815
CI / scan_ruby (push) Failing after 14m57s
CI / scan_js (push) Successful in 11m7s
CI / lint (push) Failing after 12m34s
Allinea il conteggio clienti della dashboard alle società, non ai deal vinti.
Neumarkt aveva due opportunità WON e gonfiava banner e card a 3, mentre la lista Solo clienti mostra 2 società.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 07:52:03 +02:00

140 lines
4.1 KiB
Ruby

require "test_helper"
class DashboardMetricsTest < ActiveSupport::TestCase
setup do
@project = projects(:matchlivetv)
Current.user = users(:marco)
Current.project = @project
@opps = []
end
teardown do
Current.user = nil
Current.project = nil
end
test "computes stage counts and pipeline value" do
metrics = Dashboard::Metrics.new
assert metrics.stage_counts.key?("interested")
assert metrics.stage_counts.key?("to_contact")
assert_kind_of Numeric, metrics.open_pipeline_value
assert_kind_of Array, metrics.funnel_steps
end
test "funnel shows current snapshot and reached-or-beyond without skipping stages" do
add_opp("to_contact")
2.times { add_opp("contacted") }
add_opp("replied")
add_opp("interested")
2.times { add_opp("proposal", estimated_value: 100) }
add_opp("lost", lost_reason: "price")
steps = metrics.funnel_steps.index_by { |step| step[:stage] }
assert_equal Dashboard::Metrics::FUNNEL_STAGES, metrics.funnel_steps.map { |step| step[:stage] }
assert_equal 2, steps["contacted"][:current]
assert_equal 6, steps["contacted"][:reached]
assert_equal 0, steps["first_use"][:current]
assert_equal 2, steps["first_use"][:reached]
assert_equal 2, steps["proposal"][:current]
assert_equal 2, steps["proposal"][:reached]
assert_equal 0, steps["won"][:current]
refute steps.key?("lost")
contacted_step = steps["replied"]
assert_equal "4 su 6 hanno superato Contattato", contacted_step[:conversion_label]
assert_equal 67, contacted_step[:rate]
end
test "next action KPI excludes da contattare and attention remainder uses real total" do
2.times { add_opp("to_contact", send_status: "to_send") }
10.times { add_opp("contacted") }
interested = add_opp("interested")
Task.create!(
title: "Richiama",
organization: interested.organization,
opportunity: interested,
assigned_user: users(:marco),
due_at: 1.day.from_now,
priority: "normal",
task_type: "call",
status: "pending"
)
assert_equal 10, metrics.opportunities_without_next_action
preview = metrics.attention_items[:opportunities_without_next_action]
assert_equal 10, preview[:total]
assert_equal 8, preview[:items].size
end
test "demo and first use conversions are blank when those stages were never used" do
add_opp("proposal")
assert_nil metrics.demo_to_won_conversion
assert_nil metrics.first_use_to_won_conversion
end
test "demo conversion is zero when someone is in demo and nobody won" do
add_opp("demo_trial")
assert_equal 0, metrics.demo_to_won_conversion
end
test "customers acquired counts unique organizations not duplicate won deals" do
org = Organization.create!(
name: "Cliente doppio #{SecureRandom.hex(3)}",
status: "prospect",
organization_type: "societa_sportiva"
)
2.times { |i| add_opp("won", organization: org, name: "Deal #{i}") }
add_opp("won")
assert_equal 3, metrics.stage_counts["won"]
assert_equal 2, metrics.customers_count
end
test "goal progress" do
goal = sales_goals(:september)
assert_equal 0, goal.current_value
assert_equal 0, goal.progress_percentage
end
test "customers_acquired goal counts distinct organizations in the period" do
org = Organization.create!(
name: "Cliente goal #{SecureRandom.hex(3)}",
status: "prospect",
organization_type: "societa_sportiva"
)
2.times { |i| add_opp("won", organization: org, name: "Goal deal #{i}") }
add_opp("won")
assert_equal 2, sales_goals(:september).current_value
end
private
def metrics
Dashboard::Metrics.new(scope: Opportunity.where(id: @opps.map(&:id)), project: @project)
end
def add_opp(stage, **attrs)
org = attrs.delete(:organization) || Organization.create!(
name: "Soc #{stage} #{SecureRandom.hex(3)}",
status: "prospect",
organization_type: "societa_sportiva"
)
opp = Opportunity.create!(
{
organization: org,
project: @project,
name: "Deal #{stage}",
pipeline_stage: stage
}.merge(attrs)
)
@opps << opp
opp
end
end