feat: Add inbox-label matrix report endpoint (#13394)
This PR added new API endpoint GET /api/v2/accounts/:account_id/reports/inbox_label_matrix that returns conversation counts grouped by inbox and label in a matrix format. Supports optional filtering by date range, inbox_ids, and label_ids. --------- Co-authored-by: Pranav <pranav@chatwoot.com>
This commit is contained in:
135
spec/builders/v2/reports/inbox_label_matrix_builder_spec.rb
Normal file
135
spec/builders/v2/reports/inbox_label_matrix_builder_spec.rb
Normal file
@@ -0,0 +1,135 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe V2::Reports::InboxLabelMatrixBuilder do
|
||||
let!(:account) { create(:account) }
|
||||
let!(:inbox_one) { create(:inbox, account: account, name: 'Email Support') }
|
||||
let!(:inbox_two) { create(:inbox, account: account, name: 'Web Chat') }
|
||||
let!(:label_one) { create(:label, account: account, title: 'bug') }
|
||||
let!(:label_two) { create(:label, account: account, title: 'feature') }
|
||||
let(:params) do
|
||||
{
|
||||
since: 1.week.ago.beginning_of_day.to_i.to_s,
|
||||
until: Time.current.end_of_day.to_i.to_s
|
||||
}
|
||||
end
|
||||
let(:builder) { described_class.new(account: account, params: params) }
|
||||
|
||||
describe '#build' do
|
||||
subject(:report) { builder.build }
|
||||
|
||||
context 'when there are conversations with labels across inboxes' do
|
||||
before do
|
||||
c1 = create(:conversation, account: account, inbox: inbox_one, created_at: 2.days.ago)
|
||||
c1.update(label_list: [label_one.title])
|
||||
|
||||
c2 = create(:conversation, account: account, inbox: inbox_one, created_at: 3.days.ago)
|
||||
c2.update(label_list: [label_one.title, label_two.title])
|
||||
|
||||
c3 = create(:conversation, account: account, inbox: inbox_two, created_at: 1.day.ago)
|
||||
c3.update(label_list: [label_two.title])
|
||||
end
|
||||
|
||||
it 'returns inboxes ordered by name' do
|
||||
expect(report[:inboxes]).to eq([
|
||||
{ id: inbox_one.id, name: 'Email Support' },
|
||||
{ id: inbox_two.id, name: 'Web Chat' }
|
||||
])
|
||||
end
|
||||
|
||||
it 'returns labels ordered by title' do
|
||||
expect(report[:labels]).to eq([
|
||||
{ id: label_one.id, title: 'bug' },
|
||||
{ id: label_two.id, title: 'feature' }
|
||||
])
|
||||
end
|
||||
|
||||
it 'returns correct conversation counts in the matrix' do
|
||||
# Email Support: bug=2, feature=1
|
||||
# Web Chat: bug=0, feature=1
|
||||
expect(report[:matrix]).to eq([[2, 1], [0, 1]])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when filtering by inbox_ids' do
|
||||
let(:params) do
|
||||
{
|
||||
since: 1.week.ago.beginning_of_day.to_i.to_s,
|
||||
until: Time.current.end_of_day.to_i.to_s,
|
||||
inbox_ids: [inbox_one.id]
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
c1 = create(:conversation, account: account, inbox: inbox_one, created_at: 2.days.ago)
|
||||
c1.update(label_list: [label_one.title])
|
||||
|
||||
c2 = create(:conversation, account: account, inbox: inbox_two, created_at: 1.day.ago)
|
||||
c2.update(label_list: [label_one.title])
|
||||
end
|
||||
|
||||
it 'only includes the specified inboxes and their counts' do
|
||||
expect(report[:inboxes]).to eq([{ id: inbox_one.id, name: 'Email Support' }])
|
||||
expect(report[:matrix]).to eq([[1, 0]])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when filtering by label_ids' do
|
||||
let(:params) do
|
||||
{
|
||||
since: 1.week.ago.beginning_of_day.to_i.to_s,
|
||||
until: Time.current.end_of_day.to_i.to_s,
|
||||
label_ids: [label_one.id]
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
c1 = create(:conversation, account: account, inbox: inbox_one, created_at: 2.days.ago)
|
||||
c1.update(label_list: [label_one.title, label_two.title])
|
||||
end
|
||||
|
||||
it 'only includes the specified labels and their counts' do
|
||||
expect(report[:labels]).to eq([{ id: label_one.id, title: 'bug' }])
|
||||
expect(report[:matrix]).to eq([[1], [0]])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when conversations are outside the date range' do
|
||||
before do
|
||||
c1 = create(:conversation, account: account, inbox: inbox_one, created_at: 2.days.ago)
|
||||
c1.update(label_list: [label_one.title])
|
||||
|
||||
c2 = create(:conversation, account: account, inbox: inbox_one, created_at: 2.weeks.ago)
|
||||
c2.update(label_list: [label_one.title])
|
||||
end
|
||||
|
||||
it 'only counts conversations within the date range' do
|
||||
expect(report[:matrix]).to eq([[1, 0], [0, 0]])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are no conversations with labels' do
|
||||
before do
|
||||
create(:conversation, account: account, inbox: inbox_one, created_at: 2.days.ago)
|
||||
end
|
||||
|
||||
it 'returns a matrix of zeros' do
|
||||
expect(report[:matrix]).to eq([[0, 0], [0, 0]])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when conversations belong to another account' do
|
||||
let(:other_account) { create(:account) }
|
||||
let(:other_inbox) { create(:inbox, account: other_account) }
|
||||
|
||||
before do
|
||||
c1 = create(:conversation, account: other_account, inbox: other_inbox, created_at: 2.days.ago)
|
||||
other_label = create(:label, account: other_account, title: 'bug')
|
||||
c1.update(label_list: [other_label.title])
|
||||
end
|
||||
|
||||
it 'does not include conversations from other accounts' do
|
||||
expect(report[:matrix]).to eq([[0, 0], [0, 0]])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user