mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-19 05:09:38 +02:00
Fix rubocop linting issues in API chat endpoints
- Fix trailing whitespace - Add missing final newlines - Fix array bracket spacing - Auto-corrected all layout issues 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
94202b2a6b
commit
404066eaa1
7 changed files with 56 additions and 56 deletions
|
@ -4,4 +4,4 @@ json.id chat.id
|
||||||
json.title chat.title
|
json.title chat.title
|
||||||
json.error chat.error.present? ? chat.error : nil
|
json.error chat.error.present? ? chat.error : nil
|
||||||
json.created_at chat.created_at.iso8601
|
json.created_at chat.created_at.iso8601
|
||||||
json.updated_at chat.updated_at.iso8601
|
json.updated_at chat.updated_at.iso8601
|
||||||
|
|
|
@ -15,4 +15,4 @@ json.pagination do
|
||||||
json.per_page @pagy.vars[:items]
|
json.per_page @pagy.vars[:items]
|
||||||
json.total_count @pagy.count
|
json.total_count @pagy.count
|
||||||
json.total_pages @pagy.pages
|
json.total_pages @pagy.pages
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,7 +10,7 @@ json.messages @messages do |message|
|
||||||
json.model message.ai_model if message.type == "AssistantMessage"
|
json.model message.ai_model if message.type == "AssistantMessage"
|
||||||
json.created_at message.created_at.iso8601
|
json.created_at message.created_at.iso8601
|
||||||
json.updated_at message.updated_at.iso8601
|
json.updated_at message.updated_at.iso8601
|
||||||
|
|
||||||
# Include tool calls for assistant messages
|
# Include tool calls for assistant messages
|
||||||
if message.type == "AssistantMessage" && message.tool_calls.any?
|
if message.type == "AssistantMessage" && message.tool_calls.any?
|
||||||
json.tool_calls message.tool_calls do |tool_call|
|
json.tool_calls message.tool_calls do |tool_call|
|
||||||
|
@ -30,4 +30,4 @@ if @pagy
|
||||||
json.total_count @pagy.count
|
json.total_count @pagy.count
|
||||||
json.total_pages @pagy.pages
|
json.total_pages @pagy.pages
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,4 +13,4 @@ json.updated_at @message.updated_at.iso8601
|
||||||
if @message.type == "UserMessage"
|
if @message.type == "UserMessage"
|
||||||
json.ai_response_status "pending"
|
json.ai_response_status "pending"
|
||||||
json.ai_response_message "AI response is being generated"
|
json.ai_response_message "AI response is being generated"
|
||||||
end
|
end
|
||||||
|
|
|
@ -189,7 +189,7 @@ Rails.application.routes.draw do
|
||||||
resources :accounts, only: [ :index ]
|
resources :accounts, only: [ :index ]
|
||||||
resources :transactions, only: [ :index, :show, :create, :update, :destroy ]
|
resources :transactions, only: [ :index, :show, :create, :update, :destroy ]
|
||||||
resource :usage, only: [ :show ], controller: "usage"
|
resource :usage, only: [ :show ], controller: "usage"
|
||||||
|
|
||||||
resources :chats, only: [ :index, :show, :create, :update, :destroy ] do
|
resources :chats, only: [ :index, :show, :create, :update, :destroy ] do
|
||||||
resources :messages, only: [ :create ] do
|
resources :messages, only: [ :create ] do
|
||||||
post :retry, on: :collection
|
post :retry, on: :collection
|
||||||
|
|
|
@ -6,25 +6,25 @@ class Api::V1::ChatsControllerTest < ActionDispatch::IntegrationTest
|
||||||
setup do
|
setup do
|
||||||
@user = users(:family_admin)
|
@user = users(:family_admin)
|
||||||
@user.update!(ai_enabled: true)
|
@user.update!(ai_enabled: true)
|
||||||
|
|
||||||
@oauth_app = Doorkeeper::Application.create!(
|
@oauth_app = Doorkeeper::Application.create!(
|
||||||
name: "Test API App",
|
name: "Test API App",
|
||||||
redirect_uri: "https://example.com/callback",
|
redirect_uri: "https://example.com/callback",
|
||||||
scopes: "read write read_write"
|
scopes: "read write read_write"
|
||||||
)
|
)
|
||||||
|
|
||||||
@read_token = Doorkeeper::AccessToken.create!(
|
@read_token = Doorkeeper::AccessToken.create!(
|
||||||
application: @oauth_app,
|
application: @oauth_app,
|
||||||
resource_owner_id: @user.id,
|
resource_owner_id: @user.id,
|
||||||
scopes: "read"
|
scopes: "read"
|
||||||
)
|
)
|
||||||
|
|
||||||
@write_token = Doorkeeper::AccessToken.create!(
|
@write_token = Doorkeeper::AccessToken.create!(
|
||||||
application: @oauth_app,
|
application: @oauth_app,
|
||||||
resource_owner_id: @user.id,
|
resource_owner_id: @user.id,
|
||||||
scopes: "read_write"
|
scopes: "read_write"
|
||||||
)
|
)
|
||||||
|
|
||||||
@chat = chats(:one)
|
@chat = chats(:one)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -32,13 +32,13 @@ class Api::V1::ChatsControllerTest < ActionDispatch::IntegrationTest
|
||||||
get "/api/v1/chats"
|
get "/api/v1/chats"
|
||||||
assert_response :unauthorized
|
assert_response :unauthorized
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should require AI to be enabled" do
|
test "should require AI to be enabled" do
|
||||||
@user.update!(ai_enabled: false)
|
@user.update!(ai_enabled: false)
|
||||||
|
|
||||||
get "/api/v1/chats", headers: bearer_auth_header(@read_token)
|
get "/api/v1/chats", headers: bearer_auth_header(@read_token)
|
||||||
assert_response :forbidden
|
assert_response :forbidden
|
||||||
|
|
||||||
response_body = JSON.parse(response.body)
|
response_body = JSON.parse(response.body)
|
||||||
assert_equal "feature_disabled", response_body["error"]
|
assert_equal "feature_disabled", response_body["error"]
|
||||||
end
|
end
|
||||||
|
@ -46,88 +46,88 @@ class Api::V1::ChatsControllerTest < ActionDispatch::IntegrationTest
|
||||||
test "should list chats with read scope" do
|
test "should list chats with read scope" do
|
||||||
get "/api/v1/chats", headers: bearer_auth_header(@read_token)
|
get "/api/v1/chats", headers: bearer_auth_header(@read_token)
|
||||||
assert_response :success
|
assert_response :success
|
||||||
|
|
||||||
response_body = JSON.parse(response.body)
|
response_body = JSON.parse(response.body)
|
||||||
assert response_body["chats"].is_a?(Array)
|
assert response_body["chats"].is_a?(Array)
|
||||||
assert response_body["pagination"].present?
|
assert response_body["pagination"].present?
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should show chat with messages" do
|
test "should show chat with messages" do
|
||||||
get "/api/v1/chats/#{@chat.id}", headers: bearer_auth_header(@read_token)
|
get "/api/v1/chats/#{@chat.id}", headers: bearer_auth_header(@read_token)
|
||||||
assert_response :success
|
assert_response :success
|
||||||
|
|
||||||
response_body = JSON.parse(response.body)
|
response_body = JSON.parse(response.body)
|
||||||
assert_equal @chat.id, response_body["id"]
|
assert_equal @chat.id, response_body["id"]
|
||||||
assert response_body["messages"].is_a?(Array)
|
assert response_body["messages"].is_a?(Array)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should create chat with write scope" do
|
test "should create chat with write scope" do
|
||||||
assert_difference "Chat.count" do
|
assert_difference "Chat.count" do
|
||||||
post "/api/v1/chats",
|
post "/api/v1/chats",
|
||||||
params: { title: "New chat", message: "Hello AI" },
|
params: { title: "New chat", message: "Hello AI" },
|
||||||
headers: bearer_auth_header(@write_token)
|
headers: bearer_auth_header(@write_token)
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_response :created
|
assert_response :created
|
||||||
response_body = JSON.parse(response.body)
|
response_body = JSON.parse(response.body)
|
||||||
assert_equal "New chat", response_body["title"]
|
assert_equal "New chat", response_body["title"]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should not create chat with read scope" do
|
test "should not create chat with read scope" do
|
||||||
post "/api/v1/chats",
|
post "/api/v1/chats",
|
||||||
params: { title: "New chat" },
|
params: { title: "New chat" },
|
||||||
headers: bearer_auth_header(@read_token)
|
headers: bearer_auth_header(@read_token)
|
||||||
|
|
||||||
assert_response :forbidden
|
assert_response :forbidden
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should update chat" do
|
test "should update chat" do
|
||||||
patch "/api/v1/chats/#{@chat.id}",
|
patch "/api/v1/chats/#{@chat.id}",
|
||||||
params: { title: "Updated title" },
|
params: { title: "Updated title" },
|
||||||
headers: bearer_auth_header(@write_token)
|
headers: bearer_auth_header(@write_token)
|
||||||
|
|
||||||
assert_response :success
|
assert_response :success
|
||||||
response_body = JSON.parse(response.body)
|
response_body = JSON.parse(response.body)
|
||||||
assert_equal "Updated title", response_body["title"]
|
assert_equal "Updated title", response_body["title"]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should delete chat" do
|
test "should delete chat" do
|
||||||
assert_difference "Chat.count", -1 do
|
assert_difference "Chat.count", -1 do
|
||||||
delete "/api/v1/chats/#{@chat.id}", headers: bearer_auth_header(@write_token)
|
delete "/api/v1/chats/#{@chat.id}", headers: bearer_auth_header(@write_token)
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_response :no_content
|
assert_response :no_content
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should not access other user's chat" do
|
test "should not access other user's chat" do
|
||||||
other_user = users(:family_member)
|
other_user = users(:family_member)
|
||||||
other_user.update!(family: families(:empty))
|
other_user.update!(family: families(:empty))
|
||||||
other_chat = chats(:two)
|
other_chat = chats(:two)
|
||||||
other_chat.update!(user: other_user)
|
other_chat.update!(user: other_user)
|
||||||
|
|
||||||
get "/api/v1/chats/#{other_chat.id}", headers: bearer_auth_header(@read_token)
|
get "/api/v1/chats/#{other_chat.id}", headers: bearer_auth_header(@read_token)
|
||||||
assert_response :not_found
|
assert_response :not_found
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should support API key authentication" do
|
test "should support API key authentication" do
|
||||||
# Remove any existing API keys for this user
|
# Remove any existing API keys for this user
|
||||||
@user.api_keys.destroy_all
|
@user.api_keys.destroy_all
|
||||||
|
|
||||||
plain_key = ApiKey.generate_secure_key
|
plain_key = ApiKey.generate_secure_key
|
||||||
api_key = @user.api_keys.build(
|
api_key = @user.api_keys.build(
|
||||||
name: "Test API Key",
|
name: "Test API Key",
|
||||||
scopes: ["read_write"]
|
scopes: [ "read_write" ]
|
||||||
)
|
)
|
||||||
api_key.key = plain_key
|
api_key.key = plain_key
|
||||||
api_key.save!
|
api_key.save!
|
||||||
|
|
||||||
get "/api/v1/chats", headers: { "X-Api-Key" => plain_key }
|
get "/api/v1/chats", headers: { "X-Api-Key" => plain_key }
|
||||||
assert_response :success
|
assert_response :success
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def bearer_auth_header(token)
|
def bearer_auth_header(token)
|
||||||
{ "Authorization" => "Bearer #{token.token}" }
|
{ "Authorization" => "Bearer #{token.token}" }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,19 +6,19 @@ class Api::V1::MessagesControllerTest < ActionDispatch::IntegrationTest
|
||||||
setup do
|
setup do
|
||||||
@user = users(:family_admin)
|
@user = users(:family_admin)
|
||||||
@user.update!(ai_enabled: true)
|
@user.update!(ai_enabled: true)
|
||||||
|
|
||||||
@oauth_app = Doorkeeper::Application.create!(
|
@oauth_app = Doorkeeper::Application.create!(
|
||||||
name: "Test API App",
|
name: "Test API App",
|
||||||
redirect_uri: "https://example.com/callback",
|
redirect_uri: "https://example.com/callback",
|
||||||
scopes: "read write read_write"
|
scopes: "read write read_write"
|
||||||
)
|
)
|
||||||
|
|
||||||
@write_token = Doorkeeper::AccessToken.create!(
|
@write_token = Doorkeeper::AccessToken.create!(
|
||||||
application: @oauth_app,
|
application: @oauth_app,
|
||||||
resource_owner_id: @user.id,
|
resource_owner_id: @user.id,
|
||||||
scopes: "read_write"
|
scopes: "read_write"
|
||||||
)
|
)
|
||||||
|
|
||||||
@chat = chats(:one)
|
@chat = chats(:one)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -26,30 +26,30 @@ class Api::V1::MessagesControllerTest < ActionDispatch::IntegrationTest
|
||||||
post "/api/v1/chats/#{@chat.id}/messages"
|
post "/api/v1/chats/#{@chat.id}/messages"
|
||||||
assert_response :unauthorized
|
assert_response :unauthorized
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should require AI to be enabled" do
|
test "should require AI to be enabled" do
|
||||||
@user.update!(ai_enabled: false)
|
@user.update!(ai_enabled: false)
|
||||||
|
|
||||||
post "/api/v1/chats/#{@chat.id}/messages",
|
post "/api/v1/chats/#{@chat.id}/messages",
|
||||||
params: { content: "Hello" },
|
params: { content: "Hello" },
|
||||||
headers: bearer_auth_header(@write_token)
|
headers: bearer_auth_header(@write_token)
|
||||||
assert_response :forbidden
|
assert_response :forbidden
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should create message with write scope" do
|
test "should create message with write scope" do
|
||||||
assert_difference "Message.count" do
|
assert_difference "Message.count" do
|
||||||
post "/api/v1/chats/#{@chat.id}/messages",
|
post "/api/v1/chats/#{@chat.id}/messages",
|
||||||
params: { content: "Test message", model: "gpt-4" },
|
params: { content: "Test message", model: "gpt-4" },
|
||||||
headers: bearer_auth_header(@write_token)
|
headers: bearer_auth_header(@write_token)
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_response :created
|
assert_response :created
|
||||||
response_body = JSON.parse(response.body)
|
response_body = JSON.parse(response.body)
|
||||||
assert_equal "Test message", response_body["content"]
|
assert_equal "Test message", response_body["content"]
|
||||||
assert_equal "user_message", response_body["type"]
|
assert_equal "user_message", response_body["type"]
|
||||||
assert_equal "pending", response_body["ai_response_status"]
|
assert_equal "pending", response_body["ai_response_status"]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should enqueue assistant response job" do
|
test "should enqueue assistant response job" do
|
||||||
assert_enqueued_with(job: AssistantResponseJob) do
|
assert_enqueued_with(job: AssistantResponseJob) do
|
||||||
post "/api/v1/chats/#{@chat.id}/messages",
|
post "/api/v1/chats/#{@chat.id}/messages",
|
||||||
|
@ -57,55 +57,55 @@ class Api::V1::MessagesControllerTest < ActionDispatch::IntegrationTest
|
||||||
headers: bearer_auth_header(@write_token)
|
headers: bearer_auth_header(@write_token)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should retry last assistant message" do
|
test "should retry last assistant message" do
|
||||||
skip "Retry functionality needs debugging"
|
skip "Retry functionality needs debugging"
|
||||||
|
|
||||||
# Create an assistant message to retry
|
# Create an assistant message to retry
|
||||||
assistant_message = @chat.messages.create!(
|
assistant_message = @chat.messages.create!(
|
||||||
type: "AssistantMessage",
|
type: "AssistantMessage",
|
||||||
content: "Previous response",
|
content: "Previous response",
|
||||||
ai_model: "gpt-4"
|
ai_model: "gpt-4"
|
||||||
)
|
)
|
||||||
|
|
||||||
assert_enqueued_with(job: AssistantResponseJob) do
|
assert_enqueued_with(job: AssistantResponseJob) do
|
||||||
post "/api/v1/chats/#{@chat.id}/messages/retry",
|
post "/api/v1/chats/#{@chat.id}/messages/retry",
|
||||||
headers: bearer_auth_header(@write_token)
|
headers: bearer_auth_header(@write_token)
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_response :accepted
|
assert_response :accepted
|
||||||
response_body = JSON.parse(response.body)
|
response_body = JSON.parse(response.body)
|
||||||
assert response_body["message_id"].present?
|
assert response_body["message_id"].present?
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should not retry if no assistant message exists" do
|
test "should not retry if no assistant message exists" do
|
||||||
# Remove all assistant messages
|
# Remove all assistant messages
|
||||||
@chat.messages.where(type: "AssistantMessage").destroy_all
|
@chat.messages.where(type: "AssistantMessage").destroy_all
|
||||||
|
|
||||||
post "/api/v1/chats/#{@chat.id}/messages/retry.json",
|
post "/api/v1/chats/#{@chat.id}/messages/retry.json",
|
||||||
headers: bearer_auth_header(@write_token)
|
headers: bearer_auth_header(@write_token)
|
||||||
|
|
||||||
assert_response :unprocessable_entity
|
assert_response :unprocessable_entity
|
||||||
response_body = JSON.parse(response.body)
|
response_body = JSON.parse(response.body)
|
||||||
assert_equal "No assistant message to retry", response_body["error"]
|
assert_equal "No assistant message to retry", response_body["error"]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should not access messages in other user's chat" do
|
test "should not access messages in other user's chat" do
|
||||||
other_user = users(:family_member)
|
other_user = users(:family_member)
|
||||||
other_user.update!(family: families(:empty))
|
other_user.update!(family: families(:empty))
|
||||||
other_chat = chats(:two)
|
other_chat = chats(:two)
|
||||||
other_chat.update!(user: other_user)
|
other_chat.update!(user: other_user)
|
||||||
|
|
||||||
post "/api/v1/chats/#{other_chat.id}/messages",
|
post "/api/v1/chats/#{other_chat.id}/messages",
|
||||||
params: { content: "Test" },
|
params: { content: "Test" },
|
||||||
headers: bearer_auth_header(@write_token)
|
headers: bearer_auth_header(@write_token)
|
||||||
|
|
||||||
assert_response :not_found
|
assert_response :not_found
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def bearer_auth_header(token)
|
def bearer_auth_header(token)
|
||||||
{ "Authorization" => "Bearer #{token.token}" }
|
{ "Authorization" => "Bearer #{token.token}" }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue