Merge branch 'develop' into codex/fix-inbox-finish-setup-guidance
This commit is contained in:
@@ -25,6 +25,7 @@ RSpec.describe 'Agents API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(response.parsed_body.size).to eq(account.users.count)
|
||||
end
|
||||
|
||||
@@ -122,6 +123,7 @@ RSpec.describe 'Agents API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(other_agent.reload.name).to eq(params[:name])
|
||||
end
|
||||
|
||||
@@ -171,6 +173,7 @@ RSpec.describe 'Agents API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(response.parsed_body['email']).to eq(params[:email])
|
||||
expect(account.users.last.name).to eq('NewUser')
|
||||
end
|
||||
|
||||
@@ -192,6 +192,38 @@ RSpec.describe 'Api::V1::Accounts::Articles', type: :request do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/accounts/{account.id}/portals/{portal.slug}/articles/reorder' do
|
||||
let!(:article_2) do
|
||||
create(:article, category: category, portal: portal, account_id: account.id, author_id: agent.id, position: 20)
|
||||
end
|
||||
let(:positions_hash) do
|
||||
{
|
||||
article.id => 20,
|
||||
article_2.id => 10
|
||||
}
|
||||
end
|
||||
|
||||
context 'when it is an unauthenticated user' do
|
||||
it 'returns unauthorized' do
|
||||
post "/api/v1/accounts/#{account.id}/portals/#{portal.slug}/articles/reorder",
|
||||
params: { positions_hash: positions_hash }
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it is an authenticated user' do
|
||||
it 'reorders articles' do
|
||||
post "/api/v1/accounts/#{account.id}/portals/#{portal.slug}/articles/reorder",
|
||||
params: { positions_hash: positions_hash },
|
||||
headers: admin.create_new_auth_token
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(article.reload.position).to eq(20)
|
||||
expect(article_2.reload.position).to eq(10)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /api/v1/accounts/{account.id}/portals/{portal.slug}/articles' do
|
||||
context 'when it is an unauthenticated user' do
|
||||
it 'returns unauthorized' do
|
||||
|
||||
@@ -237,6 +237,47 @@ RSpec.describe 'Api::V1::Accounts::Categories', type: :request do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/accounts/{account.id}/portals/{portal.slug}/categories/reorder' do
|
||||
let(:positions_hash) do
|
||||
{
|
||||
category.id => 40,
|
||||
category_to_associate.id => 10,
|
||||
related_category_1.id => 30,
|
||||
related_category_2.id => 20
|
||||
}
|
||||
end
|
||||
|
||||
context 'when it is an unauthenticated user' do
|
||||
it 'returns unauthorized' do
|
||||
post "/api/v1/accounts/#{account.id}/portals/#{portal.slug}/categories/reorder",
|
||||
params: { positions_hash: positions_hash }
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it is an authenticated user' do
|
||||
it 'reorders categories' do
|
||||
post "/api/v1/accounts/#{account.id}/portals/#{portal.slug}/categories/reorder",
|
||||
params: { positions_hash: positions_hash },
|
||||
headers: admin.create_new_auth_token
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(category.reload.position).to eq(40)
|
||||
expect(category_to_associate.reload.position).to eq(10)
|
||||
expect(related_category_1.reload.position).to eq(30)
|
||||
expect(related_category_2.reload.position).to eq(20)
|
||||
end
|
||||
|
||||
it 'returns not found when portal does not exist' do
|
||||
post "/api/v1/accounts/#{account.id}/portals/invalid-portal-slug/categories/reorder",
|
||||
params: { positions_hash: positions_hash },
|
||||
headers: admin.create_new_auth_token
|
||||
|
||||
expect(response).to have_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /api/v1/accounts/{account.id}/portals/{portal.slug}/categories' do
|
||||
context 'when it is an unauthenticated user' do
|
||||
it 'returns unauthorized' do
|
||||
|
||||
@@ -45,6 +45,7 @@ RSpec.describe 'Contacts API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
response_body = response.parsed_body
|
||||
contact_emails = response_body['payload'].pluck('email')
|
||||
contact_inboxes_source_ids = response_body['payload'].flat_map { |c| c['contact_inboxes'].pluck('source_id') }
|
||||
@@ -331,6 +332,7 @@ RSpec.describe 'Contacts API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(response.body).to include(contact2.email)
|
||||
expect(response.body).not_to include(contact1.email)
|
||||
end
|
||||
@@ -443,6 +445,7 @@ RSpec.describe 'Contacts API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(response.body).to include(contact2.email)
|
||||
expect(response.body).to include(contact1.email)
|
||||
end
|
||||
@@ -497,6 +500,7 @@ RSpec.describe 'Contacts API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(response.body).to include(contact.name)
|
||||
end
|
||||
end
|
||||
@@ -620,6 +624,7 @@ RSpec.describe 'Contacts API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(contact.reload.name).to eq('Test Blub')
|
||||
# custom attributes are merged properly without overwriting existing ones
|
||||
expect(contact.custom_attributes).to eq({ 'test' => 'new test', 'test1' => 'test1', 'test2' => 'test2' })
|
||||
|
||||
@@ -31,6 +31,7 @@ RSpec.describe 'Conversation Messages API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(conversation.messages.count).to eq(1)
|
||||
expect(conversation.messages.first.content).to eq(params[:content])
|
||||
end
|
||||
@@ -182,6 +183,7 @@ RSpec.describe 'Conversation Messages API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(JSON.parse(response.body, symbolize_names: true)[:meta][:contact][:id]).to eq(conversation.contact_id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -27,6 +27,7 @@ RSpec.describe 'Conversations API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
body = JSON.parse(response.body, symbolize_names: true)
|
||||
expect(body[:data][:meta][:all_count]).to eq(1)
|
||||
expect(body[:data][:meta].keys).to include(:all_count, :mine_count, :assigned_count, :unassigned_count)
|
||||
@@ -165,6 +166,7 @@ RSpec.describe 'Conversations API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
response_data = JSON.parse(response.body, symbolize_names: true)
|
||||
expect(response_data.count).to eq(2)
|
||||
end
|
||||
@@ -234,6 +236,7 @@ RSpec.describe 'Conversations API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(JSON.parse(response.body, symbolize_names: true)[:id]).to eq(conversation.display_id)
|
||||
end
|
||||
|
||||
@@ -282,6 +285,7 @@ RSpec.describe 'Conversations API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(JSON.parse(response.body, symbolize_names: true)[:priority]).to eq('high')
|
||||
end
|
||||
|
||||
@@ -330,6 +334,7 @@ RSpec.describe 'Conversations API', type: :request do
|
||||
context 'when it is an authenticated user who has access to the inbox' do
|
||||
before do
|
||||
create(:inbox_member, user: agent, inbox: inbox)
|
||||
create(:team_member, user: agent, team: team)
|
||||
end
|
||||
|
||||
it 'creates a new conversation' do
|
||||
@@ -341,6 +346,7 @@ RSpec.describe 'Conversations API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
response_data = JSON.parse(response.body, symbolize_names: true)
|
||||
expect(response_data[:additional_attributes]).to eq(additional_attributes)
|
||||
end
|
||||
@@ -448,9 +454,11 @@ RSpec.describe 'Conversations API', type: :request do
|
||||
|
||||
post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/toggle_status",
|
||||
headers: agent.create_new_auth_token,
|
||||
params: { status: 'open' },
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(conversation.reload.status).to eq('open')
|
||||
end
|
||||
|
||||
@@ -646,6 +654,37 @@ RSpec.describe 'Conversations API', type: :request do
|
||||
.with(Conversation::CONVERSATION_TYPING_ON, kind_of(Time), { conversation: conversation, user: agent, is_private: true })
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it is an authenticated bot' do
|
||||
let(:agent_bot) { create(:agent_bot, account: account) }
|
||||
|
||||
it 'toggles the conversation typing status' do
|
||||
create(:agent_bot_inbox, inbox: conversation.inbox, agent_bot: agent_bot)
|
||||
allow(Rails.configuration.dispatcher).to receive(:dispatch)
|
||||
|
||||
post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/toggle_typing_status",
|
||||
headers: { api_access_token: agent_bot.access_token.token },
|
||||
params: { typing_status: 'on', is_private: false },
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(Rails.configuration.dispatcher).to have_received(:dispatch)
|
||||
.with(Conversation::CONVERSATION_TYPING_ON, kind_of(Time), { conversation: conversation, user: agent_bot, is_private: false })
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it is an authenticated platform app token' do
|
||||
let(:platform_app) { create(:platform_app) }
|
||||
|
||||
it 'returns unauthorized' do
|
||||
post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/toggle_typing_status",
|
||||
headers: { api_access_token: platform_app.access_token.token },
|
||||
params: { typing_status: 'on', is_private: false },
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/accounts/{account.id}/conversations/:id/update_last_seen' do
|
||||
|
||||
@@ -10,10 +10,12 @@ RSpec.describe Api::V1::Accounts::InboxCsatTemplatesController, type: :request d
|
||||
let(:whatsapp_inbox) { create(:inbox, channel: whatsapp_channel, account: account) }
|
||||
let(:web_widget_inbox) { create(:inbox, account: account) }
|
||||
let(:mock_service) { instance_double(Whatsapp::CsatTemplateService) }
|
||||
let(:analysis_service) { instance_double(CsatTemplateUtilityAnalysisService) }
|
||||
|
||||
before do
|
||||
create(:inbox_member, user: agent, inbox: whatsapp_inbox)
|
||||
allow(Whatsapp::CsatTemplateService).to receive(:new).and_return(mock_service)
|
||||
allow(CsatTemplateUtilityAnalysisService).to receive(:new).and_return(analysis_service)
|
||||
end
|
||||
|
||||
describe 'GET /api/v1/accounts/{account.id}/inboxes/{inbox.id}/csat_template' do
|
||||
@@ -380,4 +382,93 @@ RSpec.describe Api::V1::Accounts::InboxCsatTemplatesController, type: :request d
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/accounts/{account.id}/inboxes/{inbox.id}/csat_template/analyze' do
|
||||
let(:valid_template_params) do
|
||||
{
|
||||
template: {
|
||||
message: 'How would you rate your experience?',
|
||||
button_text: 'Rate Us',
|
||||
language: 'en'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
context 'when captain_integration feature is disabled' do
|
||||
before do
|
||||
account.disable_features!('captain_integration')
|
||||
end
|
||||
|
||||
it 'returns forbidden' do
|
||||
post "/api/v1/accounts/#{account.id}/inboxes/#{whatsapp_inbox.id}/csat_template/analyze",
|
||||
headers: admin.create_new_auth_token,
|
||||
params: valid_template_params,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:forbidden)
|
||||
expect(response.parsed_body['error']).to eq('Captain is required for template analysis')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when captain_integration feature is enabled' do
|
||||
before do
|
||||
account.enable_features!('captain_integration')
|
||||
account.reload
|
||||
end
|
||||
|
||||
it 'returns analysis response' do
|
||||
allow(analysis_service).to receive(:perform).and_return({
|
||||
classification: 'LIKELY_UTILITY',
|
||||
optimized_message: 'Your support request has been closed.'
|
||||
})
|
||||
|
||||
post "/api/v1/accounts/#{account.id}/inboxes/#{whatsapp_inbox.id}/csat_template/analyze",
|
||||
headers: admin.create_new_auth_token,
|
||||
params: valid_template_params,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
response_data = response.parsed_body
|
||||
expect(response_data['classification']).to eq('LIKELY_UTILITY')
|
||||
expect(response_data['optimized_message']).to eq('Your support request has been closed.')
|
||||
end
|
||||
|
||||
it 'returns error when message is missing' do
|
||||
invalid_params = { template: { button_text: 'Rate Us', language: 'en' } }
|
||||
|
||||
post "/api/v1/accounts/#{account.id}/inboxes/#{whatsapp_inbox.id}/csat_template/analyze",
|
||||
headers: admin.create_new_auth_token,
|
||||
params: invalid_params,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:unprocessable_entity)
|
||||
expect(response.parsed_body['error']).to eq('Message is required')
|
||||
end
|
||||
|
||||
it 'returns unauthorized when agent is not assigned to inbox' do
|
||||
other_agent = create(:user, account: account, role: :agent)
|
||||
|
||||
post "/api/v1/accounts/#{account.id}/inboxes/#{whatsapp_inbox.id}/csat_template/analyze",
|
||||
headers: other_agent.create_new_auth_token,
|
||||
params: valid_template_params,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
|
||||
it 'allows access when agent is assigned to inbox' do
|
||||
allow(analysis_service).to receive(:perform).and_return({
|
||||
classification: 'LIKELY_UTILITY',
|
||||
optimized_message: 'Your support request has been closed.'
|
||||
})
|
||||
|
||||
post "/api/v1/accounts/#{account.id}/inboxes/#{whatsapp_inbox.id}/csat_template/analyze",
|
||||
headers: agent.create_new_auth_token,
|
||||
params: valid_template_params,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -32,6 +32,7 @@ RSpec.describe 'Inboxes API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(JSON.parse(response.body, symbolize_names: true)[:payload].size).to eq(2)
|
||||
end
|
||||
|
||||
@@ -95,6 +96,7 @@ RSpec.describe 'Inboxes API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(JSON.parse(response.body, symbolize_names: true)[:id]).to eq(inbox.id)
|
||||
end
|
||||
|
||||
@@ -383,6 +385,7 @@ RSpec.describe 'Inboxes API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(response.body).to include('test.com')
|
||||
end
|
||||
|
||||
@@ -478,6 +481,7 @@ RSpec.describe 'Inboxes API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(inbox.reload.enable_auto_assignment).to be_falsey
|
||||
expect(inbox.reload.portal_id).to eq(portal.id)
|
||||
expect(response.parsed_body['name']).to eq 'new test inbox'
|
||||
@@ -631,6 +635,7 @@ RSpec.describe 'Inboxes API', type: :request do
|
||||
|
||||
it 'updates smtp configuration with starttls encryption' do
|
||||
smtp_connection = double
|
||||
allow(smtp_connection).to receive(:open_timeout=).and_return(10)
|
||||
allow(smtp_connection).to receive(:start).and_return(true)
|
||||
allow(smtp_connection).to receive(:finish).and_return(true)
|
||||
allow(smtp_connection).to receive(:respond_to?).and_return(true)
|
||||
@@ -661,6 +666,7 @@ RSpec.describe 'Inboxes API', type: :request do
|
||||
|
||||
it 'updates smtp configuration with ssl/tls encryption' do
|
||||
smtp_connection = double
|
||||
allow(smtp_connection).to receive(:open_timeout=).and_return(10)
|
||||
allow(smtp_connection).to receive(:start).and_return(true)
|
||||
allow(smtp_connection).to receive(:finish).and_return(true)
|
||||
allow(smtp_connection).to receive(:respond_to?).and_return(true)
|
||||
@@ -691,6 +697,7 @@ RSpec.describe 'Inboxes API', type: :request do
|
||||
|
||||
it 'updates smtp configuration with authentication mechanism' do
|
||||
smtp_connection = double
|
||||
allow(smtp_connection).to receive(:open_timeout=).and_return(10)
|
||||
allow(smtp_connection).to receive(:start).and_return(true)
|
||||
allow(smtp_connection).to receive(:finish).and_return(true)
|
||||
allow(smtp_connection).to receive(:respond_to?).and_return(true)
|
||||
|
||||
@@ -117,7 +117,7 @@ RSpec.describe 'Api::V1::Accounts::Portals', type: :request do
|
||||
portal_params = {
|
||||
portal: {
|
||||
name: 'updated_test_portal',
|
||||
config: { 'allowed_locales' => %w[en es] }
|
||||
config: { 'allowed_locales' => %w[en es], 'draft_locales' => ['es'], 'default_locale' => 'en' }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,8 +130,33 @@ RSpec.describe 'Api::V1::Accounts::Portals', type: :request do
|
||||
expect(response).to have_http_status(:success)
|
||||
json_response = response.parsed_body
|
||||
expect(json_response['name']).to eql(portal_params[:portal][:name])
|
||||
expect(json_response['config']).to eql({ 'allowed_locales' => [{ 'articles_count' => 0, 'categories_count' => 0, 'code' => 'en' },
|
||||
{ 'articles_count' => 0, 'categories_count' => 0, 'code' => 'es' }] })
|
||||
expect(json_response['config']).to eql(
|
||||
{
|
||||
'allowed_locales' => [
|
||||
{ 'articles_count' => 0, 'categories_count' => 0, 'code' => 'en', 'draft' => false },
|
||||
{ 'articles_count' => 0, 'categories_count' => 0, 'code' => 'es', 'draft' => true }
|
||||
]
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
it 'preserves drafted locales when draft_locales is omitted' do
|
||||
portal.update!(config: { allowed_locales: %w[en es fr], draft_locales: ['es'], default_locale: 'en' })
|
||||
|
||||
put "/api/v1/accounts/#{account.id}/portals/#{portal.slug}",
|
||||
params: {
|
||||
portal: {
|
||||
config: { allowed_locales: %w[en es fr], default_locale: 'en' }
|
||||
}
|
||||
},
|
||||
headers: admin.create_new_auth_token
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
portal.reload
|
||||
expect(portal.draft_locale_codes).to eq(['es'])
|
||||
expect(response.parsed_body.dig('config', 'allowed_locales')).to include(
|
||||
a_hash_including('code' => 'es', 'draft' => true)
|
||||
)
|
||||
end
|
||||
|
||||
it 'archive portal' do
|
||||
|
||||
@@ -22,6 +22,7 @@ RSpec.describe 'Teams API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(response.parsed_body.first['id']).to eq(account.teams.first.id)
|
||||
end
|
||||
end
|
||||
@@ -45,6 +46,7 @@ RSpec.describe 'Teams API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(response.parsed_body['id']).to eq(team.id)
|
||||
end
|
||||
end
|
||||
@@ -83,6 +85,7 @@ RSpec.describe 'Teams API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(Team.count).to eq(2)
|
||||
end
|
||||
end
|
||||
@@ -121,6 +124,7 @@ RSpec.describe 'Teams API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(team.reload.name).to eq('new-team')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -32,23 +32,25 @@ RSpec.describe 'TikTok Authorization API', type: :request do
|
||||
end
|
||||
|
||||
it 'creates a new authorization and returns the redirect url' do
|
||||
with_modified_env TIKTOK_APP_ID: 'tiktok-app-id', TIKTOK_APP_SECRET: 'tiktok-app-secret' do
|
||||
post "/api/v1/accounts/#{account.id}/tiktok/authorization",
|
||||
headers: administrator.create_new_auth_token,
|
||||
as: :json
|
||||
travel_to Time.zone.parse('2025-01-01 00:00:00 UTC') do
|
||||
with_modified_env TIKTOK_APP_ID: 'tiktok-app-id', TIKTOK_APP_SECRET: 'tiktok-app-secret' do
|
||||
post "/api/v1/accounts/#{account.id}/tiktok/authorization",
|
||||
headers: administrator.create_new_auth_token,
|
||||
as: :json
|
||||
end
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response.parsed_body['success']).to be true
|
||||
|
||||
helper = Class.new do
|
||||
include Tiktok::IntegrationHelper
|
||||
end.new
|
||||
|
||||
expected_state = helper.generate_tiktok_token(account.id)
|
||||
expected_url = Tiktok::AuthClient.authorize_url(state: expected_state)
|
||||
|
||||
expect(response.parsed_body['url']).to eq(expected_url)
|
||||
end
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response.parsed_body['success']).to be true
|
||||
|
||||
helper = Class.new do
|
||||
include Tiktok::IntegrationHelper
|
||||
end.new
|
||||
|
||||
expected_state = helper.generate_tiktok_token(account.id)
|
||||
expected_url = Tiktok::AuthClient.authorize_url(state: expected_state)
|
||||
|
||||
expect(response.parsed_body['url']).to eq(expected_url)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -81,6 +81,29 @@ RSpec.describe 'Accounts API', type: :request do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when ENABLE_ACCOUNT_SIGNUP is stored as boolean false' do
|
||||
before do
|
||||
GlobalConfig.clear_cache
|
||||
InstallationConfig.where(name: 'ENABLE_ACCOUNT_SIGNUP').delete_all
|
||||
InstallationConfig.create!(name: 'ENABLE_ACCOUNT_SIGNUP', value: false, locked: false)
|
||||
end
|
||||
|
||||
after do
|
||||
InstallationConfig.where(name: 'ENABLE_ACCOUNT_SIGNUP').delete_all
|
||||
GlobalConfig.clear_cache
|
||||
end
|
||||
|
||||
it 'responds 404 on requests' do
|
||||
params = { account_name: 'test', email: email, user_full_name: user_full_name, password: 'Password1!' }
|
||||
|
||||
post api_v1_accounts_url,
|
||||
params: params,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when ENABLE_ACCOUNT_SIGNUP env variable is set to api_only' do
|
||||
it 'does not respond 404 on requests' do
|
||||
params = { account_name: 'test', email: email, user_full_name: user_full_name, password: 'Password1!' }
|
||||
@@ -126,6 +149,7 @@ RSpec.describe 'Accounts API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(response.body).to include(account.name)
|
||||
expect(response.body).to include(account.locale)
|
||||
expect(response.body).to include(account.domain)
|
||||
@@ -161,22 +185,22 @@ RSpec.describe 'Accounts API', type: :request do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT /api/v1/accounts/{account.id}' do
|
||||
describe 'PATCH /api/v1/accounts/{account.id}' do
|
||||
let(:account) { create(:account) }
|
||||
let(:agent) { create(:user, account: account, role: :agent) }
|
||||
let(:admin) { create(:user, account: account, role: :administrator) }
|
||||
|
||||
context 'when it is an unauthenticated user' do
|
||||
it 'returns unauthorized' do
|
||||
put "/api/v1/accounts/#{account.id}"
|
||||
patch "/api/v1/accounts/#{account.id}"
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it is an unauthorized user' do
|
||||
it 'returns unauthorized' do
|
||||
put "/api/v1/accounts/#{account.id}",
|
||||
headers: agent.create_new_auth_token
|
||||
patch "/api/v1/accounts/#{account.id}",
|
||||
headers: agent.create_new_auth_token
|
||||
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
@@ -196,11 +220,20 @@ RSpec.describe 'Accounts API', type: :request do
|
||||
company_size: '1-10'
|
||||
}
|
||||
|
||||
it 'returns a valid schema' do
|
||||
patch "/api/v1/accounts/#{account.id}",
|
||||
params: params,
|
||||
headers: admin.create_new_auth_token,
|
||||
as: :json
|
||||
|
||||
expect(response).to conform_schema(200)
|
||||
end
|
||||
|
||||
it 'modifies an account' do
|
||||
put "/api/v1/accounts/#{account.id}",
|
||||
params: params,
|
||||
headers: admin.create_new_auth_token,
|
||||
as: :json
|
||||
patch "/api/v1/accounts/#{account.id}",
|
||||
params: params,
|
||||
headers: admin.create_new_auth_token,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(account.reload.name).to eq(params[:name])
|
||||
@@ -219,19 +252,19 @@ RSpec.describe 'Accounts API', type: :request do
|
||||
|
||||
it 'updates onboarding step to invite_team if onboarding step is present in account custom attributes' do
|
||||
account.update(custom_attributes: { onboarding_step: 'account_update' })
|
||||
put "/api/v1/accounts/#{account.id}",
|
||||
params: params,
|
||||
headers: admin.create_new_auth_token,
|
||||
as: :json
|
||||
patch "/api/v1/accounts/#{account.id}",
|
||||
params: params,
|
||||
headers: admin.create_new_auth_token,
|
||||
as: :json
|
||||
|
||||
expect(account.reload.custom_attributes['onboarding_step']).to eq('invite_team')
|
||||
end
|
||||
|
||||
it 'will not update onboarding step if onboarding step is not present in account custom attributes' do
|
||||
put "/api/v1/accounts/#{account.id}",
|
||||
params: params,
|
||||
headers: admin.create_new_auth_token,
|
||||
as: :json
|
||||
patch "/api/v1/accounts/#{account.id}",
|
||||
params: params,
|
||||
headers: admin.create_new_auth_token,
|
||||
as: :json
|
||||
|
||||
expect(account.reload.custom_attributes['onboarding_step']).to be_nil
|
||||
end
|
||||
@@ -239,10 +272,10 @@ RSpec.describe 'Accounts API', type: :request do
|
||||
it 'Throws error 422' do
|
||||
params[:name] = 'test' * 999
|
||||
|
||||
put "/api/v1/accounts/#{account.id}",
|
||||
params: params,
|
||||
headers: admin.create_new_auth_token,
|
||||
as: :json
|
||||
patch "/api/v1/accounts/#{account.id}",
|
||||
params: params,
|
||||
headers: admin.create_new_auth_token,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:unprocessable_entity)
|
||||
json_response = response.parsed_body
|
||||
|
||||
@@ -21,6 +21,7 @@ RSpec.describe 'Profile API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
json_response = response.parsed_body
|
||||
expect(json_response['id']).to eq(agent.id)
|
||||
expect(json_response['email']).to eq(agent.email)
|
||||
@@ -50,6 +51,7 @@ RSpec.describe 'Profile API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
json_response = response.parsed_body
|
||||
agent.reload
|
||||
expect(json_response['id']).to eq(agent.id)
|
||||
@@ -64,6 +66,7 @@ RSpec.describe 'Profile API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
agent.reload
|
||||
|
||||
expect(agent.custom_attributes['phone_number']).to eq('+123456789')
|
||||
@@ -91,6 +94,7 @@ RSpec.describe 'Profile API', type: :request do
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to conform_schema(200)
|
||||
expect(agent.reload.valid_password?('Test1234!')).to be true
|
||||
end
|
||||
|
||||
|
||||
@@ -94,6 +94,29 @@ RSpec.describe 'Accounts API', type: :request do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when ENABLE_ACCOUNT_SIGNUP is stored as boolean false' do
|
||||
before do
|
||||
GlobalConfig.clear_cache
|
||||
InstallationConfig.where(name: 'ENABLE_ACCOUNT_SIGNUP').delete_all
|
||||
InstallationConfig.create!(name: 'ENABLE_ACCOUNT_SIGNUP', value: false, locked: false)
|
||||
end
|
||||
|
||||
after do
|
||||
InstallationConfig.where(name: 'ENABLE_ACCOUNT_SIGNUP').delete_all
|
||||
GlobalConfig.clear_cache
|
||||
end
|
||||
|
||||
it 'responds 404 on requests' do
|
||||
params = { email: email, password: 'Password1!' }
|
||||
|
||||
post api_v2_accounts_url,
|
||||
params: params,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when ENABLE_ACCOUNT_SIGNUP env variable is set to api_only' do
|
||||
let(:account_builder) { double }
|
||||
let(:account) { create(:account) }
|
||||
|
||||
Reference in New Issue
Block a user