feat: Conversation and contact endpoint (#3198)

This commit is contained in:
Tejaswini Chile
2021-10-20 18:14:56 +05:30
committed by GitHub
parent b0041ccf3f
commit 658a511b88
11 changed files with 200 additions and 24 deletions

View File

@@ -50,6 +50,10 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController
def show; end
def filter
@contacts = Current.account.contacts.limit(10)
end
def contactable_inboxes
@all_contactable_inboxes = Contacts::ContactableInboxesService.new(contact: @contact).get
@contactable_inboxes = @all_contactable_inboxes.select { |contactable_inbox| policy(contactable_inbox[:inbox]).show? }

View File

@@ -2,7 +2,7 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro
include Events::Types
include DateRangeHelper
before_action :conversation, except: [:index, :meta, :search, :create]
before_action :conversation, except: [:index, :meta, :search, :create, :filter]
before_action :contact_inbox, only: [:create]
def index
@@ -31,6 +31,10 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro
def show; end
def filter
@conversations = Current.account.conversations.limit(10)
end
def mute
@conversation.mute!
head :ok

View File

@@ -15,6 +15,10 @@ class ContactPolicy < ApplicationPolicy
true
end
def filter?
true
end
def update?
true
end

View File

@@ -0,0 +1,3 @@
json.array! @contacts do |contact|
json.partial! 'api/v1/models/contact.json.jbuilder', resource: contact
end

View File

@@ -0,0 +1,3 @@
json.array! @conversations do |conversation|
json.partial! 'api/v1/models/conversation.json.jbuilder', conversation: conversation
end

View File

@@ -5,26 +5,6 @@ json.meta do
end
json.payload do
json.array! @conversations do |conversation|
json.id conversation.display_id
json.created_at conversation.created_at.to_i
json.contact do
json.id conversation.contact.id
json.name conversation.contact.name
end
json.inbox do
json.id conversation.inbox.id
json.name conversation.inbox.name
json.channel_type conversation.inbox.channel_type
end
json.messages do
json.array! conversation.messages do |message|
json.content message.content
json.id message.id
json.sender_name message.sender.name if message.sender
json.message_type message.message_type_before_type_cast
json.created_at message.created_at.to_i
end
end
json.account_id conversation.account_id
json.partial! 'api/v1/models/conversation.json.jbuilder', conversation: conversation
end
end

View File

@@ -0,0 +1,21 @@
json.id conversation.display_id
json.created_at conversation.created_at.to_i
json.contact do
json.id conversation.contact.id
json.name conversation.contact.name
end
json.inbox do
json.id conversation.inbox.id
json.name conversation.inbox.name
json.channel_type conversation.inbox.channel_type
end
json.messages do
json.array! conversation.messages do |message|
json.content message.content
json.id message.id
json.sender_name message.sender.name if message.sender
json.message_type message.message_type_before_type_cast
json.created_at message.created_at.to_i
end
end
json.account_id conversation.account_id

View File

@@ -58,8 +58,11 @@ Rails.application.routes.draw do
resource :twilio_channel, only: [:create]
end
resources :conversations, only: [:index, :create, :show] do
get 'meta', on: :collection
get 'search', on: :collection
collection do
get :meta
get :search
get :filter
end
scope module: :conversations do
resources :messages, only: [:index, :create, :destroy]
resources :assignments, only: [:create]
@@ -80,6 +83,7 @@ Rails.application.routes.draw do
collection do
get :active
get :search
get :filter
post :import
end
member do

View File

@@ -0,0 +1,92 @@
{
"conversations": [
{
"attribute_key": "status",
"attribute_name": "Status",
"input_type": "multi_select",
"data_type": "text",
"filter_operators": [ "equal_to", "not_equal_to" ],
"attribute_type": "standard"
},
{
"attribute_key": "assigne",
"attribute_name": "Assignee Name",
"input_type": "search_box with name tags/plain text",
"data_type": "text",
"filter_operators": [ "equal_to", "not_equal_to", "contains", "does_not_contain", "is_present", "is_not_present" ],
"attribute_type": "standard"
},
{
"attribute_key": "contact",
"attribute_name": "Contact Name",
"input_type": "plain_text",
"data_type": "text",
"filter_operators": [ "equal_to", "not_equal_to", "contains", "does_not_contain", "is_present", "is_not_present" ],
"attribute_type": "standard"
},
{
"attribute_key": "inbox",
"attribute_name": "Inbox Name",
"input_type": "search_box",
"data_type": "text",
"filter_operators": [ "equal_to", "not_equal_to", "contains", "does_not_contain", "is_present", "is_not_present" ],
"attribute_type": "standard"
},
{
"attribute_key": "team_id",
"attribute_name": "Team Name",
"input_type": "search_box",
"data_type": "number",
"filter_operators": [ "equal_to", "not_equal_to", "contains", "does_not_contain", "is_present", "is_not_present" ],
"attribute_type": "standard"
},
{
"attribute_key": "id",
"attribute_name": "Conversation Identifier",
"input_type": "textbox",
"data_type": "Number",
"filter_operators": [ "equal_to", "not_equal_to", "contains", "does_not_contain", "is_present", "is_not_present" ],
"attribute_type": "standard"
},
{
"attribute_key": "campaign_id",
"attribute_name": "Campaign Name",
"input_type": "textbox",
"data_type": "Number",
"filter_operators": [ "equal_to", "not_equal_to", "contains", "does_not_contain", "is_present", "is_not_present" ],
"attribute_type": "standard"
},
{
"attribute_key": "labels",
"attribute_name": "Labels",
"input_type": "tags",
"data_type": "text",
"filter_operators": ["exactly_equal_to", "contains", "does_not_contain" ],
"attribute_type": "standard"
},
{
"attribute_key": "browser",
"attribute_name": "browser",
"input_type": "textbox",
"data_type": "text",
"filter_operators": [ "equal_to", "not_equal_to", "contains", "does_not_contain" ],
"attribute_type": "additional_attributes"
},
{
"attribute_key": "country_code",
"attribute_name": "Country Name",
"input_type": "textbox",
"data_type": "text",
"filter_operators": [ "equal_to", "not_equal_to", "contains", "does_not_contain", "present", "is_not_present" ],
"attribute_type": "additional_attributes"
},
{
"attribute_key": "referer",
"attribute_name": "Referer link",
"input_type": "textbox",
"data_type": "link",
"filter_operators": [ "equal_to", "not_equal_to", "contains", "does_not_contain", "present", "is_not_present" ],
"attribute_type": "additional_attributes"
}
]
}

View File

@@ -218,6 +218,33 @@ RSpec.describe 'Contacts API', type: :request do
end
end
describe 'GET /api/v1/accounts/{account.id}/contacts/filter' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/contacts/filter"
expect(response).to have_http_status(:unauthorized)
end
end
context 'when it is an authenticated user' do
let(:admin) { create(:user, account: account, role: :administrator) }
let!(:contact1) { create(:contact, :with_email, account: account) }
let!(:contact2) { create(:contact, :with_email, name: 'testcontact', account: account, email: 'test@test.com') }
it 'returns all contacts when query is empty' do
get "/api/v1/accounts/#{account.id}/contacts/filter",
params: { q: [] },
headers: admin.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(response.body).to include(contact2.email)
expect(response.body).to include(contact1.email)
end
end
end
describe 'GET /api/v1/accounts/{account.id}/contacts/:id' do
let!(:contact) { create(:contact, account: account) }

View File

@@ -109,6 +109,40 @@ RSpec.describe 'Conversations API', type: :request do
end
end
describe 'GET /api/v1/accounts/{account.id}/conversations/filter' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/conversations/filter", params: { q: 'test' }
expect(response).to have_http_status(:unauthorized)
end
end
context 'when it is an authenticated user' do
let(:agent) { create(:user, account: account, role: :agent) }
before do
conversation = create(:conversation, account: account)
create(:message, conversation: conversation, account: account, content: 'test1')
create(:message, conversation: conversation, account: account, content: 'test2')
create(:inbox_member, user: agent, inbox: conversation.inbox)
end
it 'returns all conversations with empty query' do
get "/api/v1/accounts/#{account.id}/conversations/filter",
headers: agent.create_new_auth_token,
params: { q: 'test1' },
as: :json
expect(response).to have_http_status(:success)
response_data = JSON.parse(response.body, symbolize_names: true)
expect(response_data.count).to eq(1)
expect(response_data[0][:messages][0][:content]).to include(Message.first.content)
end
end
end
describe 'GET /api/v1/accounts/{account.id}/conversations/:id' do
let(:conversation) { create(:conversation, account: account) }