[3187] Filter spec updates

This commit is contained in:
Tejaswini 2021-10-18 12:11:45 +05:30
parent f2de6f1435
commit e2cb2c34fa
8 changed files with 133 additions and 70 deletions

View file

@ -51,7 +51,7 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController
def show; end
def filter
@contacts = ::FilterService.new('contact', params[:q], current_user).perform
@contacts = ::Contacts::FilterService.new(params[:body], current_user).perform
end
def contactable_inboxes

View file

@ -32,7 +32,7 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro
def show; end
def filter
@conversations = ::FilterService.new('conversation', params[:q], current_user).perform
@conversations = ::Conversations::FilterService.new(JSON.parse(params[:body]), current_user).perform
end
def mute

View file

@ -0,0 +1,29 @@
class Contacts::FilterService < FilterService
def perform
contact_query_builder
end
def contact_query_builder
conversation_filters = @filters['contacts']
@params.each_with_index do |query_hash, current_index|
query_hash = query_hash.with_indifferent_access
current_filter = conversation_filters[query_hash['attribute_key']]
@query_string += contact_query_string(current_filter, query_hash, current_index)
end
Contact.where(@query_string, @filter_values.with_indifferent_access)
end
def contact_query_string(current_filter, query_hash, current_index)
attribute_key = query_hash[:attribute_key]
query_operator = query_hash[:query_operator]
filter_operator_value = filter_operation(query_hash, current_index)
case current_filter['attribute_type']
when 'additional_attributes'
" contacts.additional_attributes ->> '#{attribute_key}' #{filter_operator_value} #{query_operator} "
when 'standard'
" contacts.#{attribute_key} #{filter_operator_value} #{query_operator} "
end
end
end

View file

@ -0,0 +1,37 @@
class Conversations::FilterService < FilterService
def perform
conversation_query_builder
end
def conversation_query_builder
conversation_filters = @filters['conversations']
@params.each_with_index do |query_hash, current_index|
query_hash = query_hash.with_indifferent_access
current_filter = conversation_filters[query_hash['attribute_key']]
@query_string += conversation_query_string(current_filter, query_hash, current_index)
end
base_relation.where(@query_string, @filter_values.with_indifferent_access)
end
def conversation_query_string(current_filter, query_hash, current_index)
attribute_key = query_hash[:attribute_key]
query_operator = query_hash[:query_operator]
filter_operator_value = filter_operation(query_hash, current_index)
case current_filter['attribute_type']
when 'additional_attributes'
" conversations.additional_attributes ->> '#{attribute_key}' #{filter_operator_value} #{query_operator} "
when 'standard'
if attribute_key == 'labels'
" tags.name #{filter_operator_value} #{query_operator} "
else
" conversations.#{attribute_key} #{filter_operator_value} #{query_operator} "
end
end
end
def base_relation
Conversation.left_outer_joins(:labels)
end
end

View file

@ -1,9 +1,7 @@
require 'json'
class FilterService
def initialize(type, params, user)
@type = type
def initialize(params, user)
@params = params
@user = user
file = File.read('./lib/filters/filter_keys.json')
@ -12,71 +10,35 @@ class FilterService
@filter_values = {}
end
def perform
case @type
when 'conversation'
conversation_query_builder
Conversation.limit(10)
when 'contact'
Contact.limit(10)
end
end
## Might move this conversation query builder
def conversation_query_builder
conversation_filters = @filters['conversations']
@params.each_with_index do |query_hash, current_index|
current_filter = conversation_filters[query_hash[:attribute_key]]
@query_string = @query_string + conversation_query_string(current_filter, query_hash, current_index)
end
Conversation.where(@query_string, @filter_values.with_indifferent_access)
end
def conversation_query_string(current_filter, query_hash, current_index)
attribute_key = query_hash[:attribute_key]
query_operator = query_hash[:query_operator]
# attribute_type =
filter_operator_value = filter_operation(query_hash, current_index)
# @filter_values << filter_value(query_hash)
case current_filter['attribute_type']
when 'additional_attributes'
" conversations.additional_attributes ->> '#{attribute_key}' #{filter_operator_value} #{query_operator} "
when 'standard'
" conversations.#{attribute_key} #{filter_operator_value} #{query_operator} "
end
end
def perform; end
def filter_operation(query_hash, current_index)
case query_hash[:filter_operator]
when 'equal_to'
@filter_values["value_#{current_index}"] = query_hash[:values]
"= :value_#{current_index}"
@filter_values["value_#{current_index}"] = filter_values(query_hash)
"IN (:value_#{current_index})"
when 'not_equal_to'
@filter_values["value_#{current_index}"] = query_hash[:values]
"!= :value_#{current_index}"
@filter_values["value_#{current_index}"] = filter_values(query_hash)
"NOT IN (:value_#{current_index})"
when 'contains'
@filter_values["value_#{current_index}"] = "%#{query_hash[:values]}%"
@filter_values["value_#{current_index}"] = "%#{filter_values(query_hash)}%"
"LIKE :value_#{current_index}"
when 'does_not_contain'
@filter_values["value_#{current_index}"] = "%#{query_hash[:values]}%"
@filter_values["value_#{current_index}"] = "%#{filter_values(query_hash)}%"
"NOT LIKE :value_#{current_index}"
else
@filter_values["value_#{current_index}"] = "#{query_hash[:values]}"
@filter_values["value_#{current_index}"] = filter_values(query_hash).to_s
"= :value_#{current_index}"
end
end
def filter_value(query_hash)
case query_hash[:filter_operator]
when 'equal_to', "not_equal_to"
@filter_values["value_#{index}"] = "#{query_hash[:values]}"
when 'contains', 'does_not_contain'
@filter_values["value_#{index}"] = "%#{query_hash[:values]}%"
def filter_values(query_hash)
values = query_hash['values'].map { |x| x['name'].downcase }
if query_hash['attribute_key'] == 'status'
values.collect { |v| Conversation.statuses[v] }
else
@filter_values["value_#{index}"] = "#{query_hash[:values]}"
values
end
end
end

View file

@ -61,7 +61,7 @@ Rails.application.routes.draw do
collection do
get :meta
get :search
get :filter
post :filter
end
scope module: :conversations do
resources :messages, only: [:index, :create, :destroy]
@ -83,7 +83,7 @@ Rails.application.routes.draw do
collection do
get :active
get :search
get :filter
post :filter
post :import
end
member do

View file

@ -8,7 +8,7 @@
"filter_operators": [ "equal_to", "not_equal_to" ],
"attribute_type": "standard"
},
"assigne": {
"assignee_id": {
"attribute_name": "Assignee Name",
"input_type": "search_box with name tags/plain text",
"data_type": "text",
@ -78,5 +78,22 @@
"filter_operators": [ "equal_to", "not_equal_to", "contains", "does_not_contain", "present", "is_not_present" ],
"attribute_type": "additional_attributes"
}
},
"contacts":
{
"company_name": {
"attribute_name": "Company Name",
"input_type": "multi_select",
"data_type": "text",
"filter_operators": [ "equal_to", "not_equal_to" ],
"attribute_type": "additional_attributes"
},
"browser_language": {
"attribute_name": "Browser Language",
"input_type": "textbox",
"data_type": "text",
"filter_operators": [ "equal_to", "not_equal_to", "contains", "does_not_contain" ],
"attribute_type": "additional_attributes"
},
}
}

View file

@ -1,6 +1,6 @@
require 'rails_helper'
describe ::FilterService do
describe ::Conversations::FilterService do
subject(:filter_service) { described_class }
let!(:account) { create(:account) }
@ -12,8 +12,10 @@ describe ::FilterService do
create(:inbox_member, user: user_1, inbox: inbox)
create(:inbox_member, user: user_2, inbox: inbox)
create(:conversation, account: account, inbox: inbox, assignee: user_1)
create(:conversation, account: account, inbox: inbox, assignee: user_1)
create(:conversation, account: account, inbox: inbox, assignee: user_1, status: 'resolved')
create(:conversation, account: account, inbox: inbox, assignee: user_1,
status: 'pending', additional_attributes: { 'browser_language': 'en' })
create(:conversation, account: account, inbox: inbox, assignee: user_1,
status: 'pending', additional_attributes: { 'browser_language': 'en' })
create(:conversation, account: account, inbox: inbox, assignee: user_2)
# unassigned conversation
create(:conversation, account: account, inbox: inbox)
@ -26,26 +28,42 @@ describe ::FilterService do
[
{
attribute_key: 'browser_language',
filter_operator: 'not_equal_to',
filter_operator: 'equal_to',
values: ['en'],
query_operator: 'AND',
query_operator: 'AND'
},
{
attribute_key: 'status',
filter_operator: 'equal_to',
values: ['pending'],
query_operator: nil,
},
values: [1, 2],
query_operator: nil
}
]
end
it 'filter conversations by custom_attributes and status' do
result = filter_service.new('conversation', params, user_1).perform
expect(result.length).to be 5
result = filter_service.new(params, user_1).perform
conversations = Conversation.where("additional_attributes ->> 'browser_language' IN (?) AND status IN (?)", ['en'], [1, 2])
expect(result.length).to be conversations.count
end
it 'filter contacts by custom_attributes and status' do
result = filter_service.new('contact', params, user_1).perform
it 'filter conversations by tags' do
conversations.last.labels << 'support'
params = [
{
attribute_key: 'assignee_id',
filter_operator: 'equal_to',
values: [user_1.id, user_2.id],
query_operator: 'AND'
},
{
attribute_key: 'labels',
filter_operator: 'equal_to',
values: ['support'],
query_operator: nil
}
]
result = filter_service.new(params, user_1).perform
expect(result.length).to be 5
end
end