disable external connections while testing with mimix
Some checks failed
CI/CD Pipeline / build (push) Failing after 3s

This commit is contained in:
2026-03-13 15:21:06 -06:00
parent 59a8ad9635
commit 0fd243d259
13 changed files with 151 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
defmodule SQLTest do
use ExUnit.Case
use ElixirAi.TestCase
alias ElixirAi.Data.DbHelpers
test "converts simple named parameters" do

View File

@@ -1,5 +1,5 @@
defmodule ElixirAiWeb.ErrorHTMLTest do
use ElixirAiWeb.ConnCase, async: true
use ElixirAiWeb.ConnCase, async: false
# Bring render_to_string/4 for testing custom views
import Phoenix.Template

View File

@@ -1,5 +1,5 @@
defmodule ElixirAiWeb.ErrorJSONTest do
use ElixirAiWeb.ConnCase, async: true
use ElixirAiWeb.ConnCase, async: false
test "renders 404" do
assert ElixirAiWeb.ErrorJSON.render("404.json", %{}) == %{errors: %{detail: "Not Found"}}

View File

@@ -0,0 +1,112 @@
defmodule ElixirAi.MessageStorageTest do
use ElixirAi.TestCase
setup do
# Default run_sql and request_ai_response stubs are set by TestCase.
# Start ConversationManager AFTER stubs are active so its :load_conversations
# handler sees the stub rather than hitting the real (absent) DB.
case Horde.DynamicSupervisor.start_child(
ElixirAi.ChatRunnerSupervisor,
ElixirAi.ConversationManager
) do
{:ok, _pid} -> :ok
{:error, {:already_started, _pid}} -> :ok
{:error, :already_present} -> :ok
end
:ok
end
# Stubs run_sql for all infrastructure calls (conversation lookup, message load,
# conversation insert) and notifies the test pid whenever a message INSERT occurs.
defp setup_conversation do
conv_name = "test_conv_#{System.unique_integer([:positive])}"
conv_id = :crypto.strong_rand_bytes(16)
test_pid = self()
stub(ElixirAi.Data.DbHelpers, :run_sql, fn sql, params, _topic ->
cond do
String.contains?(sql, "SELECT id FROM conversations") ->
[%{"id" => conv_id}]
String.contains?(sql, "INSERT INTO messages") ->
send(test_pid, {:insert_message, params})
[]
true ->
[]
end
end)
# 4-arity version used by Conversation.all_names/0
stub(ElixirAi.Data.DbHelpers, :run_sql, fn _sql, _params, _topic, _schema -> [] end)
provider_id = Ecto.UUID.generate()
{:ok, _pid} = ElixirAi.ConversationManager.create_conversation(conv_name, provider_id)
conv_name
end
test "run_sql is called with user message params" do
conv_name = setup_conversation()
stub(ElixirAi.ChatUtils, :request_ai_response, fn _server, _messages, _tools -> :ok end)
ElixirAi.ChatRunner.new_user_message(conv_name, "hello world")
assert_receive {:insert_message, params}, 2000
assert params["role"] == "user"
assert params["content"] == "hello world"
end
test "run_sql is called with assistant message params" do
conv_name = setup_conversation()
stub(ElixirAi.ChatUtils, :request_ai_response, fn server, _messages, _tools ->
id = make_ref()
send(server, {:start_new_ai_response, id})
send(server, {:ai_text_chunk, id, "Hello from AI"})
send(server, {:ai_text_stream_finish, id})
:ok
end)
ElixirAi.ChatRunner.new_user_message(conv_name, "hi")
assert_receive {:insert_message, %{"role" => "user"}}, 2000
assert_receive {:insert_message, params}, 2000
assert params["role"] == "assistant"
assert params["content"] == "Hello from AI"
end
test "run_sql is called with tool request and tool result message params" do
conv_name = setup_conversation()
# First AI call triggers the tool; subsequent calls (after tool completes) are no-ops.
expect(ElixirAi.ChatUtils, :request_ai_response, fn server, _messages, _tools ->
id = make_ref()
send(server, {:start_new_ai_response, id})
send(
server,
{:ai_tool_call_start, id, {"store_thing", ~s({"name":"k","value":"v"}), 0, "tc_1"}}
)
send(server, {:ai_tool_call_end, id})
:ok
end)
stub(ElixirAi.ChatUtils, :request_ai_response, fn _server, _messages, _tools -> :ok end)
ElixirAi.ChatRunner.new_user_message(conv_name, "store something")
assert_receive {:insert_message, %{"role" => "user"}}, 2000
# Assistant message that carries the tool_calls list
assert_receive {:insert_message, params}, 2000
assert params["role"] == "assistant"
refute is_nil(params["tool_calls"])
# Tool result message
assert_receive {:insert_message, params}, 2000
assert params["role"] == "tool"
assert params["tool_call_id"] == "tc_1"
end
end

View File

@@ -1,5 +1,6 @@
defmodule ElixirAi.AiUtils.StreamLineUtilsTest do
use ExUnit.Case
use ElixirAi.TestCase
@moduletag capture_log: true
import ElixirAi.StreamChunkHelpers
alias ElixirAi.AiUtils.StreamLineUtils

19
test/support/test_case.ex Normal file
View File

@@ -0,0 +1,19 @@
defmodule ElixirAi.TestCase do
use ExUnit.CaseTemplate
use Mimic
using do
quote do
use Mimic
end
end
setup :set_mimic_global
setup do
stub(ElixirAi.Data.DbHelpers, :run_sql, fn _sql, _params, _topic -> [] end)
stub(ElixirAi.Data.DbHelpers, :run_sql, fn _sql, _params, _topic, _schema -> [] end)
stub(ElixirAi.ChatUtils, :request_ai_response, fn _server, _messages, _tools -> :ok end)
:ok
end
end

View File

@@ -1 +1,3 @@
ExUnit.start()
Mimic.copy(ElixirAi.Data.DbHelpers)
Mimic.copy(ElixirAi.ChatUtils)