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 "goal progress" do goal = sales_goals(:september) assert_equal 0, goal.current_value assert_equal 0, goal.progress_percentage end private def metrics Dashboard::Metrics.new(scope: Opportunity.where(id: @opps.map(&:id)), project: @project) end def add_opp(stage, **attrs) org = 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