feat: add schema validation

This commit is contained in:
Shivam Mishra
2025-10-03 16:29:33 +05:30
parent 8b9b2f75fe
commit 8ceefacfac
2 changed files with 76 additions and 0 deletions
@@ -28,6 +28,21 @@ class Captain::CustomTool < ApplicationRecord
self.table_name = 'captain_custom_tools'
PARAM_SCHEMA_VALIDATION = {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'name': { 'type': 'string' },
'type': { 'type': 'string' },
'description': { 'type': 'string' },
'required': { 'type': 'boolean' }
},
'required': %w[name type description],
'additionalProperties': false
}
}.to_json.freeze
belongs_to :account
enum :http_method, %w[GET POST].index_by(&:itself), validate: true
@@ -38,6 +53,9 @@ class Captain::CustomTool < ApplicationRecord
validates :slug, presence: true, uniqueness: { scope: :account_id }
validates :title, presence: true
validates :endpoint_url, presence: true
validates_with JsonSchemaValidator,
schema: PARAM_SCHEMA_VALIDATION,
attribute_resolver: ->(record) { record.param_schema }
scope :enabled, -> { where(enabled: true) }
@@ -34,6 +34,64 @@ RSpec.describe Captain::CustomTool, type: :model do
expect(different_account_tool).to be_valid
end
end
describe 'param_schema validation' do
let(:account) { create(:account) }
it 'is valid with proper param_schema' do
tool = build(:captain_custom_tool, account: account, param_schema: [
{ 'name' => 'order_id', 'type' => 'string', 'description' => 'Order ID', 'required' => true }
])
expect(tool).to be_valid
end
it 'is valid with empty param_schema' do
tool = build(:captain_custom_tool, account: account, param_schema: [])
expect(tool).to be_valid
end
it 'is invalid when param_schema is missing name' do
tool = build(:captain_custom_tool, account: account, param_schema: [
{ 'type' => 'string', 'description' => 'Order ID' }
])
expect(tool).not_to be_valid
end
it 'is invalid when param_schema is missing type' do
tool = build(:captain_custom_tool, account: account, param_schema: [
{ 'name' => 'order_id', 'description' => 'Order ID' }
])
expect(tool).not_to be_valid
end
it 'is invalid when param_schema is missing description' do
tool = build(:captain_custom_tool, account: account, param_schema: [
{ 'name' => 'order_id', 'type' => 'string' }
])
expect(tool).not_to be_valid
end
it 'is invalid with additional properties in param_schema' do
tool = build(:captain_custom_tool, account: account, param_schema: [
{ 'name' => 'order_id', 'type' => 'string', 'description' => 'Order ID', 'extra_field' => 'value' }
])
expect(tool).not_to be_valid
end
it 'is valid when required field is omitted (defaults to optional param)' do
tool = build(:captain_custom_tool, account: account, param_schema: [
{ 'name' => 'order_id', 'type' => 'string', 'description' => 'Order ID' }
])
expect(tool).to be_valid
end
end
end
describe 'scopes' do