From bf76fd37693e40da564d55f15a6aeec3a4ff6f61 Mon Sep 17 00:00:00 2001 From: aakashb95 Date: Wed, 17 Dec 2025 15:19:31 +0530 Subject: [PATCH] add spec --- .../captain/config_controller_spec.rb | 50 +++++++++++++++++ spec/models/account_spec.rb | 55 +++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 spec/controllers/api/v1/accounts/captain/config_controller_spec.rb diff --git a/spec/controllers/api/v1/accounts/captain/config_controller_spec.rb b/spec/controllers/api/v1/accounts/captain/config_controller_spec.rb new file mode 100644 index 000000000..a851ddb95 --- /dev/null +++ b/spec/controllers/api/v1/accounts/captain/config_controller_spec.rb @@ -0,0 +1,50 @@ +require 'rails_helper' + +RSpec.describe 'Api::V1::Accounts::Captain::Config', type: :request do + let(:account) { create(:account) } + let(:admin) { create(:user, account: account, role: :administrator) } + let(:agent) { create(:user, account: account, role: :agent) } + + def json_response + JSON.parse(response.body, symbolize_names: true) + end + + describe 'GET /api/v1/accounts/{account.id}/captain/config' do + context 'when it is an unauthenticated user' do + it 'returns unauthorized' do + get "/api/v1/accounts/#{account.id}/captain/config", + as: :json + + expect(response).to have_http_status(:unauthorized) + end + end + + context 'when it is an agent' do + it 'returns available AI model options for each feature' do + get "/api/v1/accounts/#{account.id}/captain/config", + headers: agent.create_new_auth_token, + as: :json + + expect(response).to have_http_status(:success) + + %w[editor assistant copilot label_suggestion].each do |feature| + expect(json_response.dig(:features, feature.to_sym, :models)).to be_present + expect(json_response.dig(:features, feature.to_sym, :default)).to be_present + end + end + end + + context 'when it is an admin' do + it 'returns providers, models, and features configuration' do + get "/api/v1/accounts/#{account.id}/captain/config", + headers: admin.create_new_auth_token, + as: :json + + expect(response).to have_http_status(:success) + expect(json_response).to have_key(:providers) + expect(json_response).to have_key(:models) + expect(json_response).to have_key(:features) + end + end + end +end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index 0656870c8..dfe581325 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -218,4 +218,59 @@ RSpec.describe Account do end end end + + describe 'captain_preferences' do + let(:account) { create(:account) } + + describe 'with no saved preferences' do + it 'returns defaults from llm.yml' do + prefs = account.captain_preferences + + expect(prefs[:features].values).to all(be false) + + Llm::ConfigService.feature_keys.each do |feature| + expect(prefs[:models][feature]).to eq(Llm::ConfigService.default_model_for_feature(feature)) + end + end + end + + describe 'with saved model preferences' do + it 'returns saved preferences merged with defaults' do + account.update!(captain_models: { 'editor' => 'gpt-4o', 'assistant' => 'gpt-5' }) + + prefs = account.captain_preferences + + expect(prefs[:models]['editor']).to eq('gpt-4o') + expect(prefs[:models]['assistant']).to eq('gpt-5') + expect(prefs[:models]['copilot']).to eq(Llm::ConfigService.default_model_for_feature('copilot')) + end + end + + describe 'with saved feature preferences' do + it 'returns saved feature states' do + account.update!(captain_features: { 'editor' => true, 'assistant' => true }) + + prefs = account.captain_preferences + + expect(prefs[:features]['editor']).to be true + expect(prefs[:features]['assistant']).to be true + expect(prefs[:features]['copilot']).to be false + end + end + + describe 'validation' do + it 'rejects invalid model for a feature' do + account.captain_models = { 'label_suggestion' => 'gpt-5' } + + expect(account).not_to be_valid + expect(account.errors[:captain_models].first).to include('not a valid model for label_suggestion') + end + + it 'accepts valid model for a feature' do + account.captain_models = { 'editor' => 'gpt-4o', 'label_suggestion' => 'gpt-4.1-nano' } + + expect(account).to be_valid + end + end + end end