Files
chatwoot/spec/controllers/api/v1/accounts/integrations/apps_controller_spec.rb
T
3253e863ed fix: validate OpenAI hook credentials (#14068)
# Pull Request Template

## Description

- Validates openai key while configuring hooks
- added backfill logic

Fixes # (issue)

## Type of change

- [x] New feature (non-breaking change which adds functionality)


## How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide
instructions so we can reproduce. Please also list any relevant details
for your test configuration.
locally

<img width="1710" height="1234" alt="CleanShot 2026-04-15 at 16 15
02@2x"
src="https://github.com/user-attachments/assets/3d319fe0-19f9-4fd0-9308-74987daac2e1"
/>

<img width="2884" height="1136" alt="CleanShot 2026-05-11 at 19 22
53@2x"
src="https://github.com/user-attachments/assets/5eae8650-985b-4c4a-af42-35f7175ff52d"
/>



## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [x] Any dependent changes have been merged and published in downstream
modules

---------

Co-authored-by: Vishnu Narayanan <iamwishnu@gmail.com>
2026-05-18 14:08:57 +05:30

134 lines
5.1 KiB
Ruby

require 'rails_helper'
RSpec.describe 'Integration Apps API', type: :request do
let(:account) { create(:account) }
before { allow(Integrations::Openai::KeyValidator).to receive(:valid?).and_return(true) }
describe 'GET /api/v1/integrations/apps' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get api_v1_account_integrations_apps_url(account)
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) }
it 'returns all active apps without sensitive information if the user is an agent' do
first_app = Integrations::App.all.find { |app| app.active?(account) }
get api_v1_account_integrations_apps_url(account),
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
apps = response.parsed_body['payload'].first
expect(apps['id']).to eql(first_app.id)
expect(apps['name']).to eql(first_app.name)
expect(apps['action']).to be_nil
end
it 'will not return sensitive information for openai app for agents' do
openai = create(:integrations_hook, :openai, account: account)
get api_v1_account_integrations_apps_url(account),
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
app = response.parsed_body['payload'].find { |int_app| int_app['id'] == openai.app.id }
expect(app['hooks'].first['settings']).to be_nil
end
it 'returns all active apps with sensitive information if user is an admin' do
first_app = Integrations::App.all.find { |app| app.active?(account) }
get api_v1_account_integrations_apps_url(account),
headers: admin.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
apps = response.parsed_body['payload'].first
expect(apps['id']).to eql(first_app.id)
expect(apps['name']).to eql(first_app.name)
expect(apps['action']).to eql(first_app.action)
end
it 'returns slack app with appropriate redirect url when configured' do
with_modified_env SLACK_CLIENT_ID: 'client_id', SLACK_CLIENT_SECRET: 'client_secret' do
get api_v1_account_integrations_apps_url(account),
headers: admin.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
apps = response.parsed_body['payload']
slack_app = apps.find { |app| app['id'] == 'slack' }
expect(slack_app['action']).to include('client_id=client_id')
end
end
it 'will return sensitive information for openai app for admins' do
openai = create(:integrations_hook, :openai, account: account)
get api_v1_account_integrations_apps_url(account),
headers: admin.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
app = response.parsed_body['payload'].find { |int_app| int_app['id'] == openai.app.id }
expect(app['hooks'].first['settings']).not_to be_nil
end
end
end
describe 'GET /api/v1/integrations/apps/:id' do
context 'when it is an unauthenticated user' do
it 'returns unauthorized' do
get api_v1_account_integrations_app_url(account_id: account.id, id: 'slack')
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) }
it 'returns details of the app' do
get api_v1_account_integrations_app_url(account_id: account.id, id: 'slack'),
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
app = response.parsed_body
expect(app['id']).to eql('slack')
expect(app['name']).to eql('Slack')
end
it 'will not return sensitive information for openai app for agents' do
openai = create(:integrations_hook, :openai, account: account)
get api_v1_account_integrations_app_url(account_id: account.id, id: openai.app.id),
headers: agent.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
app = response.parsed_body
expect(app['hooks'].first['settings']).to be_nil
end
it 'will return sensitive information for openai app for admins' do
openai = create(:integrations_hook, :openai, account: account)
get api_v1_account_integrations_app_url(account_id: account.id, id: openai.app.id),
headers: admin.create_new_auth_token,
as: :json
expect(response).to have_http_status(:success)
app = response.parsed_body
expect(app['hooks'].first['settings']).not_to be_nil
end
end
end
end