Restructure omni services and add Chatwoot research snapshot
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Token Confirmation', type: :request do
|
||||
describe 'POST /auth/confirmation' do
|
||||
let(:response_json) { JSON.parse(response.body, symbolize_names: true) }
|
||||
|
||||
before do
|
||||
create(:user, email: 'john.doe@gmail.com', **user_attributes)
|
||||
|
||||
post user_confirmation_url, params: { confirmation_token: confirmation_token }
|
||||
end
|
||||
|
||||
context 'when token is valid' do
|
||||
let(:user_attributes) { { confirmation_token: '12345', skip_confirmation: false } }
|
||||
let(:confirmation_token) { '12345' }
|
||||
|
||||
it 'has status 200' do
|
||||
expect(response).to have_http_status :ok
|
||||
end
|
||||
|
||||
it 'returns "auth data"' do
|
||||
expect(response.body).to include('john.doe@gmail.com')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when token is invalid' do
|
||||
let(:user_attributes) { { confirmation_token: '12345' } }
|
||||
let(:confirmation_token) { '' }
|
||||
|
||||
it 'has status 422' do
|
||||
expect(response).to have_http_status :unprocessable_entity
|
||||
end
|
||||
|
||||
it 'returns message "Invalid token"' do
|
||||
expect(response_json).to eq({ message: 'Invalid token', redirect_url: '/' })
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user had already been confirmed' do
|
||||
let(:user_attributes) { { confirmation_token: '12345' } }
|
||||
let(:confirmation_token) { '12345' }
|
||||
|
||||
it 'has status 422' do
|
||||
expect(response).to have_http_status :unprocessable_entity
|
||||
end
|
||||
|
||||
it 'returns message "Already confirmed"' do
|
||||
expect(response_json).to eq({ message: 'Already confirmed', redirect_url: '/' })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,148 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'DeviseOverrides::OmniauthCallbacksController', type: :request do
|
||||
let(:account_builder) { double }
|
||||
let(:user_double) { object_double(:user) }
|
||||
let(:email_validation_service) { instance_double(Account::SignUpEmailValidationService) }
|
||||
|
||||
def set_omniauth_config(for_email = 'test@example.com')
|
||||
OmniAuth.config.test_mode = true
|
||||
OmniAuth.config.mock_auth[:google_oauth2] = OmniAuth::AuthHash.new(
|
||||
provider: 'google',
|
||||
uid: '123545',
|
||||
info: {
|
||||
name: 'test',
|
||||
email: for_email,
|
||||
image: 'https://example.com/image.jpg'
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
before do
|
||||
allow(Account::SignUpEmailValidationService).to receive(:new).and_return(email_validation_service)
|
||||
end
|
||||
|
||||
describe '#omniauth_sucess' do
|
||||
before do
|
||||
GlobalConfig.clear_cache
|
||||
end
|
||||
|
||||
it 'allows signup' do
|
||||
with_modified_env ENABLE_ACCOUNT_SIGNUP: 'true', FRONTEND_URL: 'http://www.example.com' do
|
||||
set_omniauth_config('test_not_preset@example.com')
|
||||
allow(AccountBuilder).to receive(:new).and_return(account_builder)
|
||||
allow(account_builder).to receive(:perform).and_return(user_double)
|
||||
allow(Avatar::AvatarFromUrlJob).to receive(:perform_later).and_return(true)
|
||||
allow(email_validation_service).to receive(:perform).and_return(true)
|
||||
|
||||
get '/omniauth/google_oauth2/callback'
|
||||
|
||||
# expect a 302 redirect to auth/google_oauth2/callback
|
||||
expect(response).to redirect_to('http://www.example.com/auth/google_oauth2/callback')
|
||||
follow_redirect!
|
||||
|
||||
expect(AccountBuilder).to have_received(:new).with({
|
||||
account_name: 'example',
|
||||
user_full_name: 'test',
|
||||
email: 'test_not_preset@example.com',
|
||||
locale: I18n.locale,
|
||||
confirmed: nil
|
||||
})
|
||||
expect(account_builder).to have_received(:perform)
|
||||
end
|
||||
end
|
||||
|
||||
it 'blocks personal accounts signup' do
|
||||
with_modified_env ENABLE_ACCOUNT_SIGNUP: 'true', FRONTEND_URL: 'http://www.example.com' do
|
||||
set_omniauth_config('personal@gmail.com')
|
||||
allow(email_validation_service).to receive(:perform).and_raise(CustomExceptions::Account::InvalidEmail.new({ valid: false, disposable: nil }))
|
||||
|
||||
get '/omniauth/google_oauth2/callback'
|
||||
|
||||
# expect a 302 redirect to auth/google_oauth2/callback
|
||||
expect(response).to redirect_to('http://www.example.com/auth/google_oauth2/callback')
|
||||
follow_redirect!
|
||||
|
||||
# expect a 302 redirect to app/login with error disallowing personal accounts
|
||||
expect(response).to redirect_to(%r{/app/login\?error=business-account-only$})
|
||||
end
|
||||
end
|
||||
|
||||
it 'blocks personal accounts signup with different Gmail case variations' do
|
||||
with_modified_env ENABLE_ACCOUNT_SIGNUP: 'true', FRONTEND_URL: 'http://www.example.com' do
|
||||
# Test different case variations of Gmail
|
||||
['personal@Gmail.com', 'personal@GMAIL.com', 'personal@Gmail.COM'].each do |email|
|
||||
set_omniauth_config(email)
|
||||
allow(email_validation_service).to receive(:perform).and_raise(CustomExceptions::Account::InvalidEmail.new({ valid: false,
|
||||
disposable: nil }))
|
||||
|
||||
get '/omniauth/google_oauth2/callback'
|
||||
|
||||
# expect a 302 redirect to auth/google_oauth2/callback
|
||||
expect(response).to redirect_to('http://www.example.com/auth/google_oauth2/callback')
|
||||
follow_redirect!
|
||||
|
||||
# expect a 302 redirect to app/login with error disallowing personal accounts
|
||||
expect(response).to redirect_to(%r{/app/login\?error=business-account-only$})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# This test does not affect line coverage, but it is important to ensure that the logic
|
||||
# does not allow any signup if the ENV explicitly disables it
|
||||
it 'blocks signup if ENV disabled' do
|
||||
with_modified_env ENABLE_ACCOUNT_SIGNUP: 'false', FRONTEND_URL: 'http://www.example.com' do
|
||||
set_omniauth_config('does-not-exist-for-sure@example.com')
|
||||
allow(email_validation_service).to receive(:perform).and_return(true)
|
||||
|
||||
get '/omniauth/google_oauth2/callback'
|
||||
|
||||
# expect a 302 redirect to auth/google_oauth2/callback
|
||||
expect(response).to redirect_to('http://www.example.com/auth/google_oauth2/callback')
|
||||
follow_redirect!
|
||||
|
||||
# expect a 302 redirect to app/login with error disallowing signup
|
||||
expect(response).to redirect_to(%r{/app/login\?error=no-account-found$})
|
||||
end
|
||||
end
|
||||
|
||||
it 'allows login' do
|
||||
with_modified_env FRONTEND_URL: 'http://www.example.com' do
|
||||
create(:user, email: 'test@example.com')
|
||||
set_omniauth_config('test@example.com')
|
||||
|
||||
get '/omniauth/google_oauth2/callback'
|
||||
# expect a 302 redirect to auth/google_oauth2/callback
|
||||
expect(response).to redirect_to('http://www.example.com/auth/google_oauth2/callback')
|
||||
|
||||
follow_redirect!
|
||||
expect(response).to redirect_to(%r{/app/login\?email=.+&sso_auth_token=.+$})
|
||||
|
||||
# expect app/login page to respond with 200 and render
|
||||
follow_redirect!
|
||||
expect(response).to have_http_status(:ok)
|
||||
end
|
||||
end
|
||||
|
||||
# from a line coverage point of view this may seem redundant
|
||||
# but to ensure that the logic allows for existing users even if they have a gmail account
|
||||
# we need to test this explicitly
|
||||
it 'allows personal account login' do
|
||||
with_modified_env FRONTEND_URL: 'http://www.example.com' do
|
||||
create(:user, email: 'personal-existing@gmail.com')
|
||||
set_omniauth_config('personal-existing@gmail.com')
|
||||
|
||||
get '/omniauth/google_oauth2/callback'
|
||||
# expect a 302 redirect to auth/google_oauth2/callback
|
||||
expect(response).to redirect_to('http://www.example.com/auth/google_oauth2/callback')
|
||||
|
||||
follow_redirect!
|
||||
expect(response).to redirect_to(%r{/app/login\?email=.+&sso_auth_token=.+$})
|
||||
|
||||
# expect app/login page to respond with 200 and render
|
||||
follow_redirect!
|
||||
expect(response).to have_http_status(:ok)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,96 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Session', type: :request do
|
||||
describe 'GET /sign_in' do
|
||||
let!(:account) { create(:account) }
|
||||
|
||||
context 'when it is invalid credentials' do
|
||||
it 'returns unauthorized' do
|
||||
params = { email: 'invalid@invalid.com', password: 'invalid' }
|
||||
|
||||
post new_user_session_url,
|
||||
params: params,
|
||||
as: :json
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
expect(response.body).to include('Invalid login credentials')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it is valid credentials' do
|
||||
let!(:user) { create(:user, password: 'Password1!', account: account) }
|
||||
let!(:user_with_new_pwd) { create(:user, password: 'Password1!.><?', account: account) }
|
||||
|
||||
it 'returns successful auth response' do
|
||||
params = { email: user.email, password: 'Password1!' }
|
||||
|
||||
post new_user_session_url,
|
||||
params: params,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response.body).to include(user.email)
|
||||
end
|
||||
|
||||
it 'returns successful auth response with new password special characters' do
|
||||
params = { email: user_with_new_pwd.email, password: 'Password1!.><?' }
|
||||
|
||||
post new_user_session_url,
|
||||
params: params,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response.body).to include(user_with_new_pwd.email)
|
||||
end
|
||||
|
||||
it 'returns the permission of the user' do
|
||||
params = { email: user.email, password: 'Password1!' }
|
||||
|
||||
post new_user_session_url,
|
||||
params: params,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response.parsed_body['data']['accounts'].first['permissions']).to eq(['agent'])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it is invalid sso auth token' do
|
||||
let!(:user) { create(:user, password: 'Password1!', account: account) }
|
||||
|
||||
it 'returns unauthorized' do
|
||||
params = { email: user.email, sso_auth_token: SecureRandom.hex(32) }
|
||||
|
||||
post new_user_session_url,
|
||||
params: params,
|
||||
as: :json
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
expect(response.body).to include('Invalid login credentials')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when with valid sso auth token' do
|
||||
let!(:user) { create(:user, password: 'Password1!', account: account) }
|
||||
|
||||
it 'returns successful auth response' do
|
||||
params = { email: user.email, sso_auth_token: user.generate_sso_auth_token }
|
||||
|
||||
post new_user_session_url, params: params, as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response.body).to include(user.email)
|
||||
|
||||
# token won't work on a subsequent request
|
||||
post new_user_session_url, params: params, as: :json
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /auth/sign_in' do
|
||||
it 'redirects to the frontend login page with error' do
|
||||
get new_user_session_url
|
||||
|
||||
expect(response).to redirect_to(%r{/app/login\?error=access-denied$})
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Token Validation API', type: :request do
|
||||
describe 'GET /validate_token' do
|
||||
let(:account) { create(:account) }
|
||||
|
||||
context 'when it is an invalid token' do
|
||||
it 'returns unauthorized' do
|
||||
get '/auth/validate_token'
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it is a valid token' do
|
||||
let(:agent) { create(:user, account: account, role: :agent) }
|
||||
|
||||
it 'returns all the labels for the conversation' do
|
||||
get '/auth/validate_token',
|
||||
headers: agent.create_new_auth_token
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response.body).to include('payload')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user