Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
papayalabs committed Nov 18, 2024
1 parent a892e8b commit 2a6c046
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 2 deletions.
2 changes: 1 addition & 1 deletion test/controllers/settings/api_services_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Settings::APIServicesControllerTest < ActionDispatch::IntegrationTest
test "should get index" do
get settings_api_services_url
assert_response :success
assert_select "table#api-services tbody tr", count: 4
assert_select "table#api-services tbody tr", count: 5
assert_select "p a", "Add New"
assert_select "p#no-api-services", false
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Settings::LanguageModelsControllerTest < ActionDispatch::IntegrationTest
test "should get index for user" do
get settings_language_models_url
assert_response :success
assert_select "table#language-models tbody tr", count: 18
assert_select "table#language-models tbody tr", count: 19
assert_select "p a", "Add New"
end

Expand Down
7 changes: 7 additions & 0 deletions test/fixtures/api_services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ rob_openai_service:
token: rob-secret
driver: openai

keith_gemini_service:
name: Gemini
user: keith
url: https://api.gemini.com/v1/
token: keith-secret
driver: gemini

rob_anthropic_service:
name: Anthropic
user: rob
Expand Down
8 changes: 8 additions & 0 deletions test/fixtures/assistants.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,11 @@ pacos_asst:
instructions: Point out flower-related local items, also historical events involving flowers
tools: []
external_id:

keith_gemini:
user: keith
language_model: gemini_flash_1_5
name: Gemini Flash 1.5
description: Gemini Flash 1.5
instructions:
tools: []
6 changes: 6 additions & 0 deletions test/fixtures/conversations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ hello_claude:
title: Meeting Claude
last_assistant_message: claude_age_replying

gemini_conversation:
user: keith
assistant: keith_gemini
title: Meeting Gemini
last_assistant_message: hello_gemini

debugging:
user: rob
assistant: rob_gpt4
Expand Down
11 changes: 11 additions & 0 deletions test/fixtures/language_models.yml
Original file line number Diff line number Diff line change
Expand Up @@ -331,3 +331,14 @@ guanaco:
supports_tools: false
input_token_cost_cents: 0.0001
output_token_cost_cents: 0.0001

gemini_flash_1_5:
position: 23
user: keith
name: Gemini Flash 1.5
api_name: gemini-1.5-flash
api_service: keith_gemini_service
supports_images: true
supports_tools: false
input_token_cost_cents: 0.0001
output_token_cost_cents: 0.0001
11 changes: 11 additions & 0 deletions test/fixtures/messages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,17 @@ hello_claude:
index: 0
version: 1

hello_gemini:
assistant: keith_gemini
conversation: gemini_conversation
role: user
content_text: Hi Gemini, can you hear me?
content_document:
run:
created_at: 2023-12-30 1:00:00
index: 0
version: 1

claude_replying:
assistant: keith_claude3
conversation: hello_claude
Expand Down
56 changes: 56 additions & 0 deletions test/jobs/get_next_ai_message_job_gemini_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
require "test_helper"

class GetNextAIMessageJobGeminiTest < ActiveJob::TestCase
setup do
@conversation = conversations(:gemini_conversation)
@user = @conversation.user
@assistant = @conversation.assistant
@conversation.messages.create! role: :user, content_text: "Still there?", assistant: @assistant
@assistant.language_model.update!(supports_tools: false) # this will change the TestClient response so we want to be selective about this
@message = @conversation.latest_message_for_version(:latest)
@test_client = TestClient::Gemini.new(access_token: "abc")
end

test "populates the latest message from the assistant" do
assert_no_difference "@conversation.messages.reload.length" do
TestClient::Gemini.stub :text, "Hello" do
assert GetNextAIMessageJob.perform_now(@user.id, @message.id, @assistant.id)
end
end

assert_equal "Hello", @conversation.latest_message_for_version(:latest).content_text
end

test "returns early if the message id was invalid" do
refute GetNextAIMessageJob.perform_now(@user.id, 0, @assistant.id)
end

test "returns early if the assistant id was invalid" do
refute GetNextAIMessageJob.perform_now(@user.id, @message.id, 0)
end

test "returns early if the message was already generated" do
@message.update!(content_text: "Hello")
refute GetNextAIMessageJob.perform_now(@user.id, @message.id, @assistant.id)
end

test "returns early if the user has replied after this" do
@conversation.messages.create! role: :user, content_text: "Ignore that, new question:", assistant: @assistant
refute GetNextAIMessageJob.perform_now(@user.id, @message.id, @assistant.id)
end

test "when Gemini key is blank, a nice error message is displayed" do
api_service = @assistant.language_model.api_service
api_service.update!(token: "")

assert GetNextAIMessageJob.perform_now(@user.id, @message.id, @assistant.id)
assert_includes @conversation.latest_message_for_version(:latest).content_text, "need to enter a valid API key for Gemini"
end

test "when API response key is missing, a nice error message is displayed" do
TestClient::Gemini.stub :text, "" do
assert GetNextAIMessageJob.perform_now(@user.id, @message.id, @assistant.id)
assert_includes @conversation.latest_message_for_version(:latest).content_text, "a blank response"
end
end
end
31 changes: 31 additions & 0 deletions test/support/test_client/gemini.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module TestClient
class Gemini
def initialize(args)
end

def self.text
nil
end

# This response is a valid example response from the API.
#
# Stub this method to respond with something more specific if needed.
def stream_generate_content(args)
contents = args.dig(:contents)
system_message = args.dig(:system_instruction)
return [{"candidates"=>
[{"content"=>
{"role"=>"model",
"parts"=>
[{"text"=> self.class.text || "Hello this is a model with instruction #{system_message.to_s.inspect}! How can I assist you today?"}]},
"safetyRatings"=>
[{"category"=>"HARM_CATEGORY_HARASSMENT", "probability"=>"NEGLIGIBLE"},
{"category"=>"HARM_CATEGORY_HATE_SPEECH", "probability"=>"NEGLIGIBLE"},
{"category"=>"HARM_CATEGORY_SEXUALLY_EXPLICIT", "probability"=>"NEGLIGIBLE"},
{"category"=>"HARM_CATEGORY_DANGEROUS_CONTENT", "probability"=>"NEGLIGIBLE"}]}],
"usageMetadata"=>{"promptTokenCount"=>1037, "candidatesTokenCount"=>31, "totalTokenCount"=>1068}
}]

end
end
end

0 comments on commit 2a6c046

Please sign in to comment.