Chore: Scope URLs with account_id (#601)

* Chore: Enable Users to create multiple accounts

Addresses: #402
- migrations to split roles and other attributes from users table
- make changes in code to accommodate this change

Co-authored-by: Pranav Raj Sreepuram <pranavrajs@gmail.com>
This commit is contained in:
Sojan Jose
2020-03-09 23:27:10 +05:30
committed by GitHub
parent 2a6670f0da
commit 19ab0fe108
105 changed files with 480 additions and 402 deletions

View File

@@ -0,0 +1,41 @@
require 'rails_helper'
RSpec.describe 'Contact Merge Action API', type: :request do
let(:account) { create(:account) }
let!(:base_contact) { create(:contact, account: account) }
let!(:mergee_contact) { create(:contact, account: account) }
describe 'POST /api/v1/accounts/{account.id}/actions/contact_merge' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
post "/api/v1/accounts/#{account.id}/actions/contact_merge"
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) }
let(:merge_action) { double }
before do
allow(ContactMergeAction).to receive(:new).and_return(merge_action)
allow(merge_action).to receive(:perform)
end
it 'merges two contacts by calling contact merge action' do
post "/api/v1/accounts/#{account.id}/actions/contact_merge",
params: { base_contact_id: base_contact.id, mergee_contact_id: mergee_contact.id },
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
json_response = JSON.parse(response.body)
expect(json_response['id']).to eq(base_contact.id)
expected_params = { account: account, base_contact: base_contact, mergee_contact: mergee_contact }
expect(ContactMergeAction).to have_received(:new).with(expected_params)
expect(merge_action).to have_received(:perform)
end
end
end
end

View File

@@ -0,0 +1,109 @@
require 'rails_helper'
RSpec.describe 'Agents API', type: :request do
let(:account) { create(:account) }
describe 'GET /api/v1/accounts/{account.id}/agents' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/agents"
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) }
it 'returns all agents of account' do
get "/api/v1/accounts/#{account.id}/agents",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(JSON.parse(response.body).size).to eq(account.users.count)
end
end
end
describe 'DELETE /api/v1/accounts/{account.id}/agents/:id' do
let(:other_agent) { create(:user, account: account, role: :agent) }
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
delete "/api/v1/accounts/#{account.id}/agents/#{other_agent.id}"
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) }
it 'deletes an agent' do
delete "/api/v1/accounts/#{account.id}/agents/#{other_agent.id}",
headers: admin.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(account.users.size).to eq(1)
end
end
end
describe 'PUT /api/v1/accounts/{account.id}/agents/:id' do
let(:other_agent) { create(:user, account: account, role: :agent) }
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
put "/api/v1/accounts/#{account.id}/agents/#{other_agent.id}"
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) }
params = { name: 'TestUser' }
it 'modifies an agent' do
put "/api/v1/accounts/#{account.id}/agents/#{other_agent.id}",
params: params,
headers: admin.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(other_agent.reload.name).to eq(params[:name])
end
end
end
describe 'POST /api/v1/accounts/{account.id}/agents' do
let(:other_agent) { create(:user, account: account, role: :agent) }
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
post "/api/v1/accounts/#{account.id}/agents"
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) }
params = { name: 'NewUser', email: Faker::Internet.email, role: :agent }
it 'creates a new agent' do
post "/api/v1/accounts/#{account.id}/agents",
params: params,
headers: admin.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(account.users.last.name).to eq('NewUser')
end
end
end
end

View File

@@ -0,0 +1,132 @@
require 'rails_helper'
RSpec.describe 'Callbacks API', type: :request do
let(:account) { create(:account) }
let(:valid_params) { attributes_for(:channel_facebook_page).merge(page_name: 'Test', inbox_name: 'Test Inbox') }
let(:inbox) { create(:inbox, account: account) }
let!(:facebook_page) { create(:channel_facebook_page, inbox: inbox, account: account) }
# Doubles
let(:koala_api) { instance_double(Koala::Facebook::API) }
let(:koala_oauth) { instance_double(Koala::Facebook::OAuth) }
before do
# Mock new and return instance doubles defined above
allow(Koala::Facebook::OAuth).to receive(:new).and_return(koala_oauth)
allow(Koala::Facebook::API).to receive(:new).and_return(koala_api)
allow(Facebook::Messenger::Subscriptions).to receive(:subscribe).and_return(true)
allow(koala_api).to receive(:get_connections).and_return(
[{ 'id' => facebook_page.page_id, 'access_token' => SecureRandom.hex(10) }]
)
allow(koala_oauth).to receive(:exchange_access_token_info).and_return('access_token' => SecureRandom.hex(10))
end
describe 'POST /api/v1/accounts/{account.id}/callbacks/register_facebook_page' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
post "/api/v1/accounts/#{account.id}/callbacks/register_facebook_page"
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) }
it 'registers a new facebook page with no avatar' do
post "/api/v1/accounts/#{account.id}/callbacks/register_facebook_page",
headers: admin.create_new_auth_token,
params: valid_params,
as: :json
expect(response).to have_http_status(:success)
end
it 'registers a new facebook page with avatar' do
buf = OpenURI::Buffer.new
io = buf.io
io.base_uri = URI.parse('https://example.org')
allow_any_instance_of(URI::HTTP).to receive(:open).and_return(io) # rubocop:disable RSpec/AnyInstance
post "/api/v1/accounts/#{account.id}/callbacks/register_facebook_page",
headers: admin.create_new_auth_token,
params: valid_params,
as: :json
expect(response).to have_http_status(:success)
end
it 'registers a new facebook page with avatar on redirect' do
allow_any_instance_of(URI::HTTP).to receive(:open).and_raise(OpenURI::HTTPRedirect.new(nil, nil, URI.parse('https://example.org'))) # rubocop:disable RSpec/AnyInstance
post "/api/v1/accounts/#{account.id}/callbacks/register_facebook_page",
headers: admin.create_new_auth_token,
params: valid_params,
as: :json
expect(response).to have_http_status(:success)
end
end
end
describe 'POST /api/v1/accounts/{account.id}/callbacks/facebook_pages' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
post "/api/v1/accounts/#{account.id}/callbacks/facebook_pages"
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) }
it 'returns facebook pages of account' do
post "/api/v1/accounts/#{account.id}/callbacks/facebook_pages",
headers: admin.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(response.body).to include(facebook_page.page_id.to_s)
end
end
end
describe 'POST /api/v1/accounts/{account.id}/callbacks/reauthorize_page' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
post "/api/v1/accounts/#{account.id}/callbacks/reauthorize_page"
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) }
it 'reauthorizes the page' do
params = { inbox_id: inbox.id }
post "/api/v1/accounts/#{account.id}/callbacks/reauthorize_page",
headers: admin.create_new_auth_token,
params: params,
as: :json
expect(response).to have_http_status(:success)
end
it 'returns unprocessable_entity if no page found' do
allow(koala_api).to receive(:get_connections).and_return([])
params = { inbox_id: inbox.id }
post "/api/v1/accounts/#{account.id}/callbacks/reauthorize_page",
headers: admin.create_new_auth_token,
params: params,
as: :json
expect(response).to have_http_status(:unprocessable_entity)
end
end
end
end

View File

@@ -0,0 +1,125 @@
require 'rails_helper'
RSpec.describe 'Canned Responses API', type: :request do
let(:account) { create(:account) }
before do
create(:canned_response, account: account)
end
describe 'GET /api/v1/accounts/{account.id}/canned_responses' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/canned_responses"
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) }
it 'returns all the canned responses' do
get "/api/v1/accounts/#{account.id}/canned_responses",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(JSON.parse(response.body)).to eq(account.canned_responses.as_json)
end
it 'returns all the canned responses the user searched for' do
create(:canned_response, account: account)
params = { search: CannedResponse.last.short_code }
get "/api/v1/accounts/#{account.id}/canned_responses",
params: params,
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(JSON.parse(response.body)).to eq([CannedResponse.last].as_json)
end
end
end
describe 'POST /api/v1/accounts/{account.id}/canned_responses' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
post "/api/v1/accounts/#{account.id}/canned_responses"
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) }
it 'creates a new canned response' do
params = { short_code: 'short', content: 'content' }
post "/api/v1/accounts/#{account.id}/canned_responses",
params: params,
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(CannedResponse.count).to eq(2)
end
end
end
describe 'PUT /api/v1/accounts/{account.id}/canned_responses/:id' do
let(:canned_response) { CannedResponse.last }
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
put "/api/v1/accounts/#{account.id}/canned_responses/#{canned_response.id}"
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) }
it 'updates an existing canned response' do
params = { short_code: 'B' }
put "/api/v1/accounts/#{account.id}/canned_responses/#{canned_response.id}",
params: params,
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(canned_response.reload.short_code).to eq('B')
end
end
end
describe 'DELETE /api/v1/accounts/{account.id}/canned_responses/:id' do
let(:canned_response) { CannedResponse.last }
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
delete "/api/v1/accounts/#{account.id}/canned_responses/#{canned_response.id}"
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) }
it 'destroys the canned response' do
delete "/api/v1/accounts/#{account.id}/canned_responses/#{canned_response.id}",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(CannedResponse.count).to eq(0)
end
end
end
end

View File

@@ -0,0 +1,63 @@
require 'rails_helper'
RSpec.describe '/api/v1/accounts/{account.id}/contacts/:id/conversations', type: :request do
let(:account) { create(:account) }
let(:contact) { create(:contact, account: account) }
let(:inbox_1) { create(:inbox, account: account) }
let(:inbox_2) { create(:inbox, account: account) }
let(:contact_inbox_1) { create(:contact_inbox, contact: contact, inbox: inbox_1) }
let(:contact_inbox_2) { create(:contact_inbox, contact: contact, inbox: inbox_2) }
let(:admin) { create(:user, account: account, role: :administrator) }
let(:agent) { create(:user, account: account, role: :agent) }
let(:unknown) { create(:user, account: account, role: nil) }
before do
create(:inbox_member, user: agent, inbox: inbox_1)
2.times.each { create(:conversation, account: account, inbox: inbox_1, contact: contact, contact_inbox: contact_inbox_1) }
2.times.each { create(:conversation, account: account, inbox: inbox_2, contact: contact, contact_inbox: contact_inbox_2) }
end
describe 'GET /api/v1/accounts/{account.id}/contacts/:id/conversations' do
context 'when unauthenticated user' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/contacts/#{contact.id}/conversations"
expect(response).to have_http_status(:unauthorized)
end
end
context 'when user is logged in' do
context 'with user as administrator' do
it 'returns conversations from all inboxes' do
get "/api/v1/accounts/#{account.id}/contacts/#{contact.id}/conversations", headers: admin.create_new_auth_token
expect(response).to have_http_status(:success)
json_response = JSON.parse(response.body)
expect(json_response['payload'].length).to eq 4
end
end
context 'with user as agent' do
it 'returns conversations from the inboxes which agent has access to' do
get "/api/v1/accounts/#{account.id}/contacts/#{contact.id}/conversations", headers: agent.create_new_auth_token
expect(response).to have_http_status(:success)
json_response = JSON.parse(response.body)
expect(json_response['payload'].length).to eq 2
end
end
context 'with user as unknown role' do
it 'returns conversations from no inboxes' do
get "/api/v1/accounts/#{account.id}/contacts/#{contact.id}/conversations", headers: unknown.create_new_auth_token
expect(response).to have_http_status(:success)
json_response = JSON.parse(response.body)
expect(json_response['payload'].length).to eq 0
end
end
end
end
end

View File

@@ -0,0 +1,119 @@
require 'rails_helper'
RSpec.describe 'Contacts API', type: :request do
let(:account) { create(:account) }
describe 'GET /api/v1/accounts/{account.id}/contacts' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/contacts"
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!(:contact) { create(:contact, account: account) }
it 'returns all contacts' do
get "/api/v1/accounts/#{account.id}/contacts",
headers: admin.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(response.body).to include(contact.email)
end
end
end
describe 'GET /api/v1/accounts/{account.id}/contacts/:id' do
let!(:contact) { create(:contact, account: account) }
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/contacts/#{contact.id}"
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) }
it 'shows the contact' do
get "/api/v1/accounts/#{account.id}/contacts/#{contact.id}",
headers: admin.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(response.body).to include(contact.email)
end
end
end
describe 'POST /api/v1/accounts/{account.id}/contacts' do
let(:valid_params) { { contact: { account_id: account.id } } }
context 'when it is an unauthenticated user' do
it 'creates the contact' do
expect { post "/api/v1/accounts/#{account.id}/contacts", params: valid_params }.to change(Contact, :count).by(1)
expect(response).to have_http_status(:success)
end
end
context 'when it is an authenticated user' do
let(:admin) { create(:user, account: account, role: :administrator) }
it 'creates the contact' do
expect do
post "/api/v1/accounts/#{account.id}/contacts", headers: admin.create_new_auth_token,
params: valid_params
end .to change(Contact, :count).by(1)
expect(response).to have_http_status(:success)
end
end
end
describe 'PATCH /api/v1/accounts/{account.id}/contacts/:id' do
let!(:contact) { create(:contact, account: account) }
let(:valid_params) { { contact: { name: 'Test Blub' } } }
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
put "/api/v1/accounts/#{account.id}/contacts/#{contact.id}",
params: valid_params
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) }
it 'updates the contact' do
patch "/api/v1/accounts/#{account.id}/contacts/#{contact.id}",
headers: admin.create_new_auth_token,
params: valid_params,
as: :json
expect(response).to have_http_status(:success)
expect(Contact.last.name).to eq('Test Blub')
end
it 'prevents the update of contact of another account' do
other_account = create(:account)
other_contact = create(:contact, account: other_account)
patch "/api/v1/accounts/#{account.id}/contacts/#{other_contact.id}",
headers: admin.create_new_auth_token,
params: valid_params,
as: :json
expect(response).to have_http_status(:not_found)
end
end
end
end

View File

@@ -0,0 +1,33 @@
require 'rails_helper'
RSpec.describe 'Conversation Assignment API', type: :request do
let(:account) { create(:account) }
describe 'POST /api/v1/accounts/{account.id}/conversations/<id>/assignments' do
let(:conversation) { create(:conversation, account: account) }
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
post api_v1_account_conversation_assignments_url(account_id: account.id, conversation_id: conversation.display_id)
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) }
it 'assigns a user to the conversation' do
params = { assignee_id: agent.id }
post api_v1_account_conversation_assignments_url(account_id: account.id, conversation_id: conversation.display_id),
params: params,
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(conversation.reload.assignee).to eq(agent)
end
end
end
end

View File

@@ -0,0 +1,67 @@
require 'rails_helper'
RSpec.describe 'Conversation Label API', type: :request do
let(:account) { create(:account) }
describe 'GET /api/v1/accounts/{account.id}/conversations/<id>/labels' do
let(:conversation) { create(:conversation, account: account) }
before do
conversation.update_labels('label1, label2')
end
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get api_v1_account_conversation_labels_url(account_id: account.id, conversation_id: conversation.display_id)
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) }
it 'returns all the labels for the conversation' do
get api_v1_account_conversation_labels_url(account_id: account.id, conversation_id: conversation.display_id),
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(response.body).to include('label1')
expect(response.body).to include('label2')
end
end
end
describe 'POST /api/v1/accounts/{account.id}/conversations/<id>/labels' do
let(:conversation) { create(:conversation, account: account) }
before do
conversation.update_labels('label1, label2')
end
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
post api_v1_account_conversation_labels_url(account_id: account.id, conversation_id: conversation.display_id),
params: { labels: 'label3,label4' },
as: :json
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) }
it 'creates labels for the conversation' do
post api_v1_account_conversation_labels_url(account_id: account.id, conversation_id: conversation.display_id),
params: { labels: 'label3,label4' },
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(response.body).to include('label3')
expect(response.body).to include('label4')
end
end
end
end

View File

@@ -0,0 +1,59 @@
require 'rails_helper'
RSpec.describe 'Conversation Messages API', type: :request do
let(:account) { create(:account) }
describe 'POST /api/v1/accounts/{account.id}/conversations/<id>/messages' do
let(:conversation) { create(:conversation, account: account) }
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
post api_v1_account_conversation_messages_url(account_id: account.id, conversation_id: conversation.display_id)
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) }
it 'creates a new outgoing message' do
params = { message: 'test-message', private: true }
post api_v1_account_conversation_messages_url(account_id: account.id, conversation_id: conversation.display_id),
params: params,
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(conversation.messages.count).to eq(1)
expect(conversation.messages.first.content).to eq(params[:message])
end
end
end
describe 'GET /api/v1/accounts/{account.id}/conversations/:id/messages' do
let(:conversation) { create(:conversation, account: account) }
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/messages"
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) }
it 'shows the conversation' do
get "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/messages",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(JSON.parse(response.body, symbolize_names: true)[:meta][:contact_id]).to eq(conversation.contact_id)
end
end
end
end

View File

@@ -0,0 +1,113 @@
require 'rails_helper'
RSpec.describe 'Conversations API', type: :request do
let(:account) { create(:account) }
describe 'GET /api/v1/accounts/{account.id}/conversations' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/conversations"
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(:inbox_member, user: agent, inbox: conversation.inbox)
end
it 'returns all conversations' do
get "/api/v1/accounts/#{account.id}/conversations",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(JSON.parse(response.body, symbolize_names: true)[:data][:meta][:all_count]).to eq(1)
end
end
end
describe 'GET /api/v1/accounts/{account.id}/conversations/:id' do
let(:conversation) { create(:conversation, account: account) }
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}"
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) }
it 'shows the conversation' do
get "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(JSON.parse(response.body, symbolize_names: true)[:id]).to eq(conversation.display_id)
end
end
end
describe 'POST /api/v1/accounts/{account.id}/conversations/:id/toggle_status' do
let(:conversation) { create(:conversation, account: account) }
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/toggle_status"
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) }
it 'toggles the conversation status' do
expect(conversation.status).to eq('open')
post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/toggle_status",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(conversation.reload.status).to eq('resolved')
end
end
end
describe 'POST /api/v1/accounts/{account.id}/conversations/:id/update_last_seen' do
let(:conversation) { create(:conversation, account: account) }
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/update_last_seen"
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) }
it 'updates last seen' do
params = { agent_last_seen_at: '-1' }
post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/update_last_seen",
headers: agent.create_new_auth_token,
params: params,
as: :json
expect(response).to have_http_status(:success)
expect(conversation.reload.agent_last_seen_at).to eq(DateTime.strptime(params[:agent_last_seen_at].to_s, '%s'))
end
end
end
end

View File

@@ -0,0 +1,143 @@
require 'rails_helper'
RSpec.describe 'Facebook Indicators API', type: :request do
let(:account) { create(:account) }
let(:facebook_channel) { create(:channel_facebook_page, account: account) }
let(:inbox) { create(:inbox, account: account, channel: facebook_channel) }
let(:contact) { create(:contact, account: account) }
let(:valid_params) { { contact_id: contact.id, inbox_id: inbox.id } }
before do
allow(Facebook::Messenger::Bot).to receive(:deliver).and_return(true)
allow(Facebook::Messenger::Subscriptions).to receive(:subscribe).and_return(true)
end
describe 'POST /api/v1/accounts/{account.id}/facebook_indicators/mark_seen' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
post "/api/v1/accounts/#{account.id}/facebook_indicators/mark_seen"
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) }
it 'marks a payload as seen' do
contact_inbox = create(:contact_inbox, contact: contact, inbox: inbox)
expect(Facebook::Messenger::Bot).to receive(:deliver).with(
{ recipient: { id: contact_inbox.source_id }, sender_action: 'mark_seen' },
access_token: inbox.channel.page_access_token
)
post "/api/v1/accounts/#{account.id}/facebook_indicators/mark_seen",
headers: agent.create_new_auth_token,
params: valid_params,
as: :json
expect(response).to have_http_status(:success)
end
it 'rescues an error' do
create(:contact_inbox, contact: contact, inbox: inbox)
allow(Facebook::Messenger::Bot).to receive(:deliver).and_raise(Facebook::Messenger::Error)
post "/api/v1/accounts/#{account.id}/facebook_indicators/mark_seen",
headers: agent.create_new_auth_token,
params: valid_params,
as: :json
expect(response).to have_http_status(:success)
end
end
end
describe 'POST /api/v1/accounts/{account.id}/facebook_indicators/typing_on' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
post "/api/v1/accounts/#{account.id}/facebook_indicators/typing_on"
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) }
it 'marks a payload as typing_on' do
contact_inbox = create(:contact_inbox, contact: contact, inbox: inbox)
expect(Facebook::Messenger::Bot).to receive(:deliver).with(
{ recipient: { id: contact_inbox.source_id }, sender_action: 'typing_on' },
access_token: inbox.channel.page_access_token
)
post "/api/v1/accounts/#{account.id}/facebook_indicators/typing_on",
headers: agent.create_new_auth_token,
params: valid_params,
as: :json
expect(response).to have_http_status(:success)
end
it 'rescues an error' do
create(:contact_inbox, contact: contact, inbox: inbox)
allow(Facebook::Messenger::Bot).to receive(:deliver).and_raise(Facebook::Messenger::Error)
post "/api/v1/accounts/#{account.id}/facebook_indicators/typing_on",
headers: agent.create_new_auth_token,
params: valid_params,
as: :json
expect(response).to have_http_status(:success)
end
end
end
describe 'POST /api/v1/accounts/{account.id}/facebook_indicators/typing_off' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
post "/api/v1/accounts/#{account.id}/facebook_indicators/typing_off"
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) }
it 'marks a payload as typing_off' do
contact_inbox = create(:contact_inbox, contact: contact, inbox: inbox)
expect(Facebook::Messenger::Bot).to receive(:deliver).with(
{ recipient: { id: contact_inbox.source_id }, sender_action: 'typing_off' },
access_token: inbox.channel.page_access_token
)
post "/api/v1/accounts/#{account.id}/facebook_indicators/typing_off",
headers: agent.create_new_auth_token,
params: valid_params,
as: :json
expect(response).to have_http_status(:success)
end
it 'rescues an error' do
create(:contact_inbox, contact: contact, inbox: inbox)
allow(Facebook::Messenger::Bot).to receive(:deliver).and_raise(Facebook::Messenger::Error)
post "/api/v1/accounts/#{account.id}/facebook_indicators/typing_off",
headers: agent.create_new_auth_token,
params: valid_params,
as: :json
expect(response).to have_http_status(:success)
end
end
end
end

View File

@@ -0,0 +1,81 @@
require 'rails_helper'
RSpec.describe 'Inbox Member API', type: :request do
let(:account) { create(:account) }
let(:inbox) { create(:inbox, account: account) }
describe 'POST /api/v1/accounts/{account.id}/inbox_members' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
post "/api/v1/accounts/#{account.id}/inbox_members"
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) }
it 'modifies inbox members' do
params = { inbox_id: inbox.id, user_ids: [agent.id] }
post "/api/v1/accounts/#{account.id}/inbox_members",
headers: agent.create_new_auth_token,
params: params,
as: :json
expect(response).to have_http_status(:success)
expect(inbox.inbox_members&.count).to eq(1)
expect(inbox.inbox_members&.first&.user).to eq(agent)
end
it 'renders not found when inbox not found' do
params = { inbox_id: nil, user_ids: [agent.id] }
post "/api/v1/accounts/#{account.id}/inbox_members",
headers: agent.create_new_auth_token,
params: params,
as: :json
expect(response).to have_http_status(:not_found)
end
it 'renders error on invalid params' do
params = { inbox_id: inbox.id, user_ids: ['invalid'] }
post "/api/v1/accounts/#{account.id}/inbox_members",
headers: agent.create_new_auth_token,
params: params,
as: :json
expect(response).to have_http_status(:unprocessable_entity)
expect(response.body).to include('Could not add agents to inbox')
end
end
end
describe 'GET /api/v1/accounts/{account.id}/inbox_members/:id' do
let(:inbox_member) { create(:inbox_member, inbox: inbox) }
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/inbox_members/#{inbox_member.id}"
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) }
it 'returns inbox member' do
get "/api/v1/accounts/#{account.id}/inbox_members/#{inbox.id}",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(JSON.parse(response.body)).to eq({ payload: inbox.inbox_members }.as_json)
end
end
end
end

View File

@@ -0,0 +1,128 @@
require 'rails_helper'
RSpec.describe 'Inboxes API', type: :request do
let(:account) { create(:account) }
describe 'GET /api/v1/accounts/{account.id}/inboxes' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/inboxes"
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) }
let(:admin) { create(:user, account: account, role: :administrator) }
before do
create(:inbox, account: account)
second_inbox = create(:inbox, account: account)
create(:inbox_member, user: agent, inbox: second_inbox)
end
it 'returns all inboxes of current_account as administrator' do
get "/api/v1/accounts/#{account.id}/inboxes",
headers: admin.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(JSON.parse(response.body, symbolize_names: true)[:payload].size).to eq(2)
end
it 'returns only assigned inboxes of current_account as agent' do
get "/api/v1/accounts/#{account.id}/inboxes",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(JSON.parse(response.body, symbolize_names: true)[:payload].size).to eq(1)
end
end
end
describe 'DELETE /api/v1/accounts/{account.id}/inboxes/:id' do
let(:inbox) { create(:inbox, account: account) }
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
delete "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}"
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) }
it 'deletes inbox' do
delete "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}",
headers: admin.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect { inbox.reload }.to raise_exception(ActiveRecord::RecordNotFound)
end
it 'is unable to delete inbox of another account' do
other_account = create(:account)
other_inbox = create(:inbox, account: other_account)
delete "/api/v1/accounts/#{account.id}/inboxes/#{other_inbox.id}",
headers: admin.create_new_auth_token,
as: :json
expect(response).to have_http_status(:not_found)
end
it 'is unable to delete inbox as agent' do
agent = create(:user, account: account, role: :agent)
delete "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:unauthorized)
end
end
end
describe 'PATCH /api/v1/accounts/{account.id}/inboxes/:id' do
let(:inbox) { create(:inbox, account: account) }
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
patch "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}"
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(:valid_params) { { inbox: { enable_auto_assignment: false } } }
it 'updates inbox' do
patch "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}",
headers: admin.create_new_auth_token,
params: valid_params,
as: :json
expect(response).to have_http_status(:success)
expect(inbox.reload.enable_auto_assignment).to be_falsey
end
it 'will not update inbox for agent' do
agent = create(:user, account: account, role: :agent)
patch "/api/v1/accounts/#{account.id}/inboxes/#{inbox.id}",
headers: agent.create_new_auth_token,
params: valid_params,
as: :json
expect(response).to have_http_status(:unauthorized)
end
end
end
end

View File

@@ -0,0 +1,59 @@
require 'rails_helper'
RSpec.describe 'Label API', type: :request do
let(:account) { create(:account) }
let(:conversation) { create(:conversation, account: account) }
before do
conversation.update_labels('label1, label2')
end
describe 'GET /api/v1/accounts/{account.id}/labels' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/labels"
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) }
it 'returns all the labels in account' do
get "/api/v1/accounts/#{account.id}/labels",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(response.body).to include('label1')
expect(response.body).to include('label2')
end
end
end
describe 'GET /api/v1/accounts/{account.id}/labels/most_used' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/labels"
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) }
it 'returns most used labels' do
get "/api/v1/accounts/#{account.id}/labels/most_used",
headers: agent.create_new_auth_token,
params: { count: 1 },
as: :json
expect(response).to have_http_status(:success)
expect(response.body).to include('label1')
expect(response.body).not_to include('label2')
end
end
end
end

View File

@@ -0,0 +1,58 @@
require 'rails_helper'
RSpec.describe 'Notification Settings API', type: :request do
let(:account) { create(:account) }
describe 'GET /api/v1/accounts/{account.id}/notification_settings' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/notification_settings"
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) }
it 'returns current user notification settings' do
get "/api/v1/accounts/#{account.id}/notification_settings",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
json_response = JSON.parse(response.body)
expect(json_response['user_id']).to eq(agent.id)
expect(json_response['account_id']).to eq(account.id)
end
end
end
describe 'PUT /api/v1/accounts/{account.id}/notification_settings' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
put "/api/v1/accounts/#{account.id}/notification_settings"
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) }
it 'updates the email related notification flags' do
put "/api/v1/accounts/#{account.id}/notification_settings",
params: { notification_settings: { selected_email_flags: ['conversation_assignment'] } },
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
json_response = JSON.parse(response.body)
agent.reload
expect(json_response['user_id']).to eq(agent.id)
expect(json_response['account_id']).to eq(account.id)
expect(json_response['selected_email_flags']).to eq(['conversation_assignment'])
end
end
end
end

View File

@@ -0,0 +1,46 @@
require 'rails_helper'
RSpec.describe 'Subscriptions API', type: :request do
let(:account) { create(:account) }
describe 'GET /api/v1/accounts/{account.id}/subscriptions' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
ENV['BILLING_ENABLED'] = 'true'
get "/api/v1/accounts/#{account.id}/subscriptions"
expect(response).to have_http_status(:unauthorized)
ENV['BILLING_ENABLED'] = nil
end
end
context 'when it is an authenticated user' do
let(:agent) { create(:user, account: account, role: :agent) }
it 'returns all subscriptions' do
ENV['BILLING_ENABLED'] = 'true'
get "/api/v1/accounts/#{account.id}/subscriptions",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(JSON.parse(response.body)).to eq(account.subscription_data.as_json)
ENV['BILLING_ENABLED'] = nil
end
it 'throws 404 error if env variable is not set' do
ENV['BILLING_ENABLED'] = nil
get "/api/v1/accounts/#{account.id}/subscriptions",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:not_found)
end
end
end
end

View File

@@ -0,0 +1,96 @@
require 'rails_helper'
RSpec.describe 'Webhooks API', type: :request do
let(:account) { create(:account) }
let(:inbox) { create(:inbox, account: account) }
let(:webhook) { create(:webhook, account: account, inbox: inbox, url: 'https://hello.com') }
let(:administrator) { create(:user, account: account, role: :administrator) }
let(:agent) { create(:user, account: account, role: :agent) }
describe 'GET /api/v1/accounts/<account_id>/webhooks' do
context 'when it is an authenticated agent' do
it 'returns unauthorized' do
get "/api/v1/accounts/#{account.id}/webhooks",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:unauthorized)
end
end
context 'when it is an authenticated admin user' do
it 'gets all webhook' do
get "/api/v1/accounts/#{account.id}/webhooks",
headers: administrator.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(JSON.parse(response.body)['payload']['webhooks'].count).to eql account.webhooks.count
end
end
end
describe 'POST /api/v1/accounts/<account_id>/webhooks' do
context 'when it is an authenticated agent' do
it 'returns unauthorized' do
post "/api/v1/accounts/#{account.id}/webhooks",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:unauthorized)
end
end
context 'when it is an authenticated admin user' do
it 'creates webhook' do
post "/api/v1/accounts/#{account.id}/webhooks",
params: { account_id: account.id, inbox_id: inbox.id, url: 'https://hello.com' },
headers: administrator.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(JSON.parse(response.body)['payload']['webhook']['url']).to eql 'https://hello.com'
end
end
end
describe 'PUT /api/v1/accounts/<account_id>/webhooks/:id' do
context 'when it is an authenticated agent' do
it 'returns unauthorized' do
put "/api/v1/accounts/#{account.id}/webhooks/#{webhook.id}",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:unauthorized)
end
end
context 'when it is an authenticated admin user' do
it 'updates webhook' do
put "/api/v1/accounts/#{account.id}/webhooks/#{webhook.id}",
params: { url: 'https://hello.com' },
headers: administrator.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(JSON.parse(response.body)['payload']['webhook']['url']).to eql 'https://hello.com'
end
end
end
describe 'DELETE /api/v1/accounts/<account_id>/webhooks/:id' do
context 'when it is an authenticated agent' do
it 'returns unauthorized' do
delete "/api/v1/accounts/#{account.id}/webhooks/#{webhook.id}",
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:unauthorized)
end
end
context 'when it is an authenticated admin user' do
it 'deletes webhook' do
delete "/api/v1/accounts/#{account.id}/webhooks/#{webhook.id}",
headers: administrator.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
expect(account.webhooks.count).to be 0
end
end
end
end