Depends on: https://github.com/chatwoot/chatwoot/pull/14370 This PR creates a new onboarding controller, this allows more control that the default account update API. Allowing us to spin tasks and update details required specifically during the onboarding flow
354 lines
13 KiB
Ruby
354 lines
13 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe 'Accounts API', type: :request do
|
|
describe 'POST /api/v1/accounts' do
|
|
let(:email) { Faker::Internet.email }
|
|
let(:user_full_name) { Faker::Name.name_with_middle }
|
|
|
|
context 'when posting to accounts with correct parameters' do
|
|
let(:account_builder) { double }
|
|
let(:account) { create(:account) }
|
|
let(:user) { create(:user, email: email, account: account, name: user_full_name) }
|
|
|
|
before do
|
|
allow(AccountBuilder).to receive(:new).and_return(account_builder)
|
|
end
|
|
|
|
it 'calls account builder' do
|
|
with_modified_env ENABLE_ACCOUNT_SIGNUP: 'true' do
|
|
allow(account_builder).to receive(:perform).and_return([user, account])
|
|
|
|
params = { account_name: 'test', email: email, user: nil, locale: nil, user_full_name: user_full_name, password: 'Password1!' }
|
|
|
|
post api_v1_accounts_url,
|
|
params: params,
|
|
as: :json
|
|
|
|
expect(AccountBuilder).to have_received(:new).with(params.except(:password).merge(user_password: params[:password]))
|
|
expect(account_builder).to have_received(:perform)
|
|
expect(response.headers.keys).not_to include('access-token', 'token-type', 'client', 'expiry', 'uid')
|
|
expect(response.parsed_body['email']).to eq(email)
|
|
end
|
|
end
|
|
|
|
it 'calls ChatwootCaptcha' do
|
|
with_modified_env ENABLE_ACCOUNT_SIGNUP: 'true' do
|
|
captcha = double
|
|
allow(account_builder).to receive(:perform).and_return([user, account])
|
|
allow(ChatwootCaptcha).to receive(:new).and_return(captcha)
|
|
allow(captcha).to receive(:valid?).and_return(true)
|
|
|
|
params = { account_name: 'test', email: email, user: nil, locale: nil, user_full_name: user_full_name, password: 'Password1!',
|
|
h_captcha_client_response: '123' }
|
|
|
|
post api_v1_accounts_url,
|
|
params: params,
|
|
as: :json
|
|
|
|
expect(ChatwootCaptcha).to have_received(:new).with('123')
|
|
expect(response.headers.keys).not_to include('access-token', 'token-type', 'client', 'expiry', 'uid')
|
|
expect(response.parsed_body['email']).to eq(email)
|
|
end
|
|
end
|
|
|
|
it 'renders error response on invalid params' do
|
|
with_modified_env ENABLE_ACCOUNT_SIGNUP: 'true' do
|
|
allow(account_builder).to receive(:perform).and_return(nil)
|
|
|
|
params = { account_name: nil, email: nil, user: nil, locale: 'en', user_full_name: nil }
|
|
|
|
post api_v1_accounts_url,
|
|
params: params,
|
|
as: :json
|
|
|
|
expect(AccountBuilder).not_to have_received(:new)
|
|
expect(response).to have_http_status(:forbidden)
|
|
expect(response.body).to eq({ message: I18n.t('errors.signup.invalid_params') }.to_json)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when an authenticated user creates a second account' do
|
|
let(:existing_user) { create(:user, password: 'Password1!') }
|
|
|
|
it 'returns the full response with account_id' do
|
|
with_modified_env ENABLE_ACCOUNT_SIGNUP: 'true' do
|
|
post api_v1_accounts_url,
|
|
params: { account_name: 'Second Account', email: existing_user.email,
|
|
user_full_name: existing_user.name, password: 'Password1!' },
|
|
headers: existing_user.create_new_auth_token,
|
|
as: :json
|
|
|
|
expect(response).to have_http_status(:success)
|
|
expect(response.parsed_body.dig('data', 'account_id')).to be_present
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when ENABLE_ACCOUNT_SIGNUP env variable is set to false' do
|
|
it 'responds 404 on requests' do
|
|
params = { account_name: 'test', email: email, user_full_name: user_full_name }
|
|
with_modified_env ENABLE_ACCOUNT_SIGNUP: 'false' do
|
|
post api_v1_accounts_url,
|
|
params: params,
|
|
as: :json
|
|
|
|
expect(response).to have_http_status(:not_found)
|
|
end
|
|
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
|
|
before do
|
|
GlobalConfig.clear_cache
|
|
InstallationConfig.where(name: 'ENABLE_ACCOUNT_SIGNUP').delete_all
|
|
end
|
|
|
|
after do
|
|
InstallationConfig.where(name: 'ENABLE_ACCOUNT_SIGNUP').delete_all
|
|
GlobalConfig.clear_cache
|
|
end
|
|
|
|
it 'returns auth headers and full response for api_only signup' do
|
|
params = { account_name: 'test', email: email, user_full_name: user_full_name, password: 'Password1!' }
|
|
with_modified_env ENABLE_ACCOUNT_SIGNUP: 'api_only' do
|
|
post api_v1_accounts_url,
|
|
params: params,
|
|
as: :json
|
|
|
|
expect(response).to have_http_status(:success)
|
|
expect(response.headers.keys).to include('access-token', 'token-type', 'client', 'expiry', 'uid')
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when CW_API_ONLY_SERVER is true' do
|
|
it 'returns auth headers and full response' do
|
|
params = { account_name: 'test', email: email, user_full_name: user_full_name, password: 'Password1!' }
|
|
with_modified_env ENABLE_ACCOUNT_SIGNUP: 'true', CW_API_ONLY_SERVER: 'true' do
|
|
post api_v1_accounts_url,
|
|
params: params,
|
|
as: :json
|
|
|
|
expect(response).to have_http_status(:success)
|
|
expect(response.headers.keys).to include('access-token', 'token-type', 'client', 'expiry', 'uid')
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'GET /api/v1/accounts/{account.id}' do
|
|
let(:account) { create(:account) }
|
|
let(:agent) { create(:user, account: account, role: :agent) }
|
|
let(:user_without_access) { create(:user) }
|
|
let(:admin) { create(:user, account: account, role: :administrator) }
|
|
|
|
context 'when it is an unauthenticated user' do
|
|
it 'returns unauthorized' do
|
|
get "/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
|
|
get "/api/v1/accounts/#{account.id}",
|
|
headers: user_without_access.create_new_auth_token
|
|
|
|
expect(response).to have_http_status(:not_found)
|
|
end
|
|
end
|
|
|
|
context 'when it is an authenticated user' do
|
|
it 'shows an account' do
|
|
account.update(name: 'new name')
|
|
|
|
get "/api/v1/accounts/#{account.id}",
|
|
headers: admin.create_new_auth_token,
|
|
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)
|
|
expect(response.body).to include(account.support_email)
|
|
expect(response.body).to include(account.locale)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'GET /api/v1/accounts/{account.id}/cache_keys' do
|
|
let(:account) { create(:account) }
|
|
let(:admin) { create(:user, account: account, role: :administrator) }
|
|
|
|
it 'returns cache_keys as expected' do
|
|
account.update(auto_resolve_duration: 30)
|
|
|
|
get "/api/v1/accounts/#{account.id}/cache_keys",
|
|
headers: admin.create_new_auth_token,
|
|
as: :json
|
|
|
|
expect(response).to have_http_status(:success)
|
|
expect(response.parsed_body['cache_keys'].keys).to match_array(%w[label inbox team])
|
|
end
|
|
|
|
it 'sets the appropriate cache headers' do
|
|
get "/api/v1/accounts/#{account.id}/cache_keys",
|
|
headers: admin.create_new_auth_token,
|
|
as: :json
|
|
|
|
expect(response.headers['Cache-Control']).to include('max-age=10')
|
|
expect(response.headers['Cache-Control']).to include('private')
|
|
expect(response.headers['Cache-Control']).to include('stale-while-revalidate=300')
|
|
end
|
|
end
|
|
|
|
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
|
|
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
|
|
patch "/api/v1/accounts/#{account.id}",
|
|
headers: agent.create_new_auth_token
|
|
|
|
expect(response).to have_http_status(:unauthorized)
|
|
end
|
|
end
|
|
|
|
context 'when it is an authenticated user' do
|
|
params = {
|
|
name: 'New Name',
|
|
locale: 'en',
|
|
domain: 'example.com',
|
|
support_email: 'care@example.com',
|
|
auto_resolve_after: 40,
|
|
auto_resolve_message: 'Auto resolved',
|
|
auto_resolve_ignore_waiting: false,
|
|
timezone: 'Asia/Kolkata',
|
|
industry: 'Technology',
|
|
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
|
|
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])
|
|
expect(account.reload.locale).to eq(params[:locale])
|
|
expect(account.reload.domain).to eq(params[:domain])
|
|
expect(account.reload.support_email).to eq(params[:support_email])
|
|
|
|
%w[auto_resolve_after auto_resolve_message auto_resolve_ignore_waiting].each do |attribute|
|
|
expect(account.reload.settings[attribute]).to eq(params[attribute.to_sym])
|
|
end
|
|
|
|
%w[timezone industry company_size].each do |attribute|
|
|
expect(account.reload.custom_attributes[attribute]).to eq(params[attribute.to_sym])
|
|
end
|
|
end
|
|
|
|
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' })
|
|
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
|
|
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
|
|
|
|
it 'Throws error 422' do
|
|
params[:name] = 'test' * 999
|
|
|
|
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
|
|
expect(json_response['message']).to eq('Name is too long (maximum is 255 characters)')
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'POST /api/v1/accounts/{account.id}/update_active_at' do
|
|
let(:account) { create(:account) }
|
|
let(: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}/update_active_at"
|
|
expect(response).to have_http_status(:unauthorized)
|
|
end
|
|
end
|
|
|
|
context 'when it is an authenticated user' do
|
|
it 'modifies an account' do
|
|
expect(agent.account_users.first.active_at).to be_nil
|
|
post "/api/v1/accounts/#{account.id}/update_active_at",
|
|
params: {},
|
|
headers: agent.create_new_auth_token,
|
|
as: :json
|
|
|
|
expect(response).to have_http_status(:success)
|
|
expect(agent.account_users.first.active_at).not_to be_nil
|
|
end
|
|
end
|
|
end
|
|
end
|