require 'rails_helper' RSpec.describe ReportingEventsRollup do describe 'associations' do it { is_expected.to belong_to(:account) } end describe 'enums' do describe 'dimension_type enum' do it 'stores dimension_type as string values' do rollup = build(:reporting_events_rollup, dimension_type: 'account') expect(rollup.dimension_type).to eq('account') end it 'has account dimension type' do rollup = build(:reporting_events_rollup, dimension_type: 'account') expect(rollup.account?).to be true end it 'has agent dimension type' do rollup = build(:reporting_events_rollup, dimension_type: 'agent') expect(rollup.agent?).to be true end it 'has inbox dimension type' do rollup = build(:reporting_events_rollup, dimension_type: 'inbox') expect(rollup.inbox?).to be true end it 'has team dimension type' do rollup = build(:reporting_events_rollup, dimension_type: 'team') expect(rollup.team?).to be true end end describe 'metric enum' do it 'stores metric as string values' do rollup = build(:reporting_events_rollup, metric: 'first_response') expect(rollup.metric).to eq('first_response') end it 'has resolutions_count metric' do rollup = build(:reporting_events_rollup, metric: 'resolutions_count') expect(rollup.resolutions_count?).to be true end it 'has first_response metric' do rollup = build(:reporting_events_rollup, metric: 'first_response') expect(rollup.first_response?).to be true end it 'has resolution_time metric' do rollup = build(:reporting_events_rollup, metric: 'resolution_time') expect(rollup.resolution_time?).to be true end it 'has reply_time metric' do rollup = build(:reporting_events_rollup, metric: 'reply_time') expect(rollup.reply_time?).to be true end it 'has bot_resolutions_count metric' do rollup = build(:reporting_events_rollup, metric: 'bot_resolutions_count') expect(rollup.bot_resolutions_count?).to be true end it 'has bot_handoffs_count metric' do rollup = build(:reporting_events_rollup, metric: 'bot_handoffs_count') expect(rollup.bot_handoffs_count?).to be true end end end describe 'validations' do it { is_expected.to validate_presence_of(:account_id) } it { is_expected.to validate_presence_of(:date) } it { is_expected.to validate_presence_of(:dimension_type) } it { is_expected.to validate_presence_of(:dimension_id) } it { is_expected.to validate_presence_of(:metric) } it { is_expected.to validate_numericality_of(:count).is_greater_than_or_equal_to(0) } end describe 'scopes' do let(:account) { create(:account) } let(:other_account) { create(:account) } describe '.for_date_range' do it 'filters by date range' do create(:reporting_events_rollup, account: account, date: '2026-02-08'.to_date) create(:reporting_events_rollup, account: account, date: '2026-02-10'.to_date) create(:reporting_events_rollup, account: account, date: '2026-02-12'.to_date) results = described_class.for_date_range('2026-02-10'.to_date, '2026-02-11'.to_date) expect(results.count).to eq(1) expect(results.first.date).to eq('2026-02-10'.to_date) end it 'returns empty array when no records match' do create(:reporting_events_rollup, account: account, date: '2026-02-08'.to_date) results = described_class.for_date_range('2026-02-20'.to_date, '2026-02-25'.to_date) expect(results).to be_empty end end describe '.for_dimension' do it 'filters by dimension type and id' do create(:reporting_events_rollup, account: account, dimension_type: 'account', dimension_id: 1) create(:reporting_events_rollup, account: account, dimension_type: 'agent', dimension_id: 1) create(:reporting_events_rollup, account: account, dimension_type: 'agent', dimension_id: 2) results = described_class.for_dimension('agent', 1) expect(results.count).to eq(1) expect(results.first.dimension_type).to eq('agent') expect(results.first.dimension_id).to eq(1) end it 'returns empty array when no records match' do create(:reporting_events_rollup, account: account, dimension_type: 'account', dimension_id: 1) results = described_class.for_dimension('agent', 1) expect(results).to be_empty end end describe '.for_metric' do it 'filters by metric' do create(:reporting_events_rollup, account: account, metric: 'first_response', dimension_id: 1) create(:reporting_events_rollup, account: account, metric: 'resolution_time', dimension_id: 2) create(:reporting_events_rollup, account: account, metric: 'first_response', dimension_id: 3) results = described_class.for_metric('first_response') expect(results.count).to eq(2) expect(results.all? { |r| r.metric == 'first_response' }).to be true end it 'returns empty array when no records match' do create(:reporting_events_rollup, account: account, metric: 'first_response') results = described_class.for_metric('resolution_time') expect(results).to be_empty end end end describe 'database schema' do let(:account) { create(:account) } let(:rollup) do create(:reporting_events_rollup, account: account, date: '2026-02-10'.to_date, dimension_type: 'account', metric: 'first_response') end it 'has all required columns' do expect(rollup).to have_attributes( account_id: account.id, date: '2026-02-10'.to_date, dimension_type: 'account', dimension_id: 1, metric: 'first_response', count: 1, sum_value: 100.0, sum_value_business_hours: 50.0 ) end it 'stores enum values as strings in database' do rollup db_record = described_class.find(rollup.id) expect(db_record.dimension_type).to eq('account') expect(db_record.metric).to eq('first_response') end end end