Current section
Files
Jump to
Current section
Files
src/telega@testing@conversation.erl
-module(telega@testing@conversation).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/telega/testing/conversation.gleam").
-export([conversation_test/0, send/2, send_callback/2, send_photo/1, send_photo_with/2, send_video/1, send_video_with/2, send_audio/1, send_audio_with/2, send_voice/1, send_voice_with/2, send_message/2, expect_reply/2, expect_reply_containing/2, expect_keyboard/2, expect_reply_with_keyboard/3, expect_api_call/3, run_with_client_with_dependencies/6, run_with_client/5, run_with/3, run/3, run_with_mock_with_dependencies/6, run_with_mock/5, run_with_dependencies/4]).
-export_type([conversation_test/0, step/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Declarative conversation testing DSL for integration testing bot flows.\n"
"\n"
" ```gleam\n"
" import telega/testing/conversation\n"
"\n"
" conversation.conversation_test()\n"
" |> conversation.send(\"/start\")\n"
" |> conversation.expect_reply_containing(\"Hello\")\n"
" |> conversation.send(\"/set_name\")\n"
" |> conversation.expect_reply(\"What's your name?\")\n"
" |> conversation.send(\"Alice\")\n"
" |> conversation.expect_reply_containing(\"Alice\")\n"
" |> conversation.run(router, fn() { Nil })\n"
" ```\n"
).
-opaque conversation_test() :: {conversation_test, list(step())}.
-type step() :: {send_text, binary()} |
{send_command, binary(), gleam@option:option(binary())} |
{send_callback, binary()} |
{send_photo, list(telega@model@types:photo_size())} |
{send_video, telega@model@types:video()} |
{send_audio, telega@model@types:audio()} |
{send_voice, telega@model@types:voice()} |
{send_message_update, telega@model@types:message()} |
{expect_reply, binary()} |
{expect_reply_containing, binary()} |
{expect_keyboard, list(binary())} |
{expect_reply_with_keyboard, binary(), list(binary())} |
{expect_api_call, binary(), binary()}.
-file("src/telega/testing/conversation.gleam", 57).
?DOC(" Creates a new empty conversation test.\n").
-spec conversation_test() -> conversation_test().
conversation_test() ->
{conversation_test, []}.
-file("src/telega/testing/conversation.gleam", 63).
?DOC(
" Sends a message. Text starting with `/` is auto-detected as a command.\n"
" Command payloads are supported: `/cmd payload here`.\n"
).
-spec send(conversation_test(), binary()) -> conversation_test().
send(Ct, Text) ->
Step = case gleam_stdlib:string_starts_with(Text, <<"/"/utf8>>) of
true ->
Without_slash = gleam@string:drop_start(Text, 1),
case gleam@string:split_once(Without_slash, <<" "/utf8>>) of
{ok, {Cmd, Payload}} ->
{send_command, Cmd, {some, Payload}};
{error, _} ->
{send_command, Without_slash, none}
end;
false ->
{send_text, Text}
end,
{conversation_test, lists:append(erlang:element(2, Ct), [Step])}.
-file("src/telega/testing/conversation.gleam", 78).
?DOC(" Sends a callback query with the given data.\n").
-spec send_callback(conversation_test(), binary()) -> conversation_test().
send_callback(Ct, Data) ->
{conversation_test,
lists:append(erlang:element(2, Ct), [{send_callback, Data}])}.
-file("src/telega/testing/conversation.gleam", 83).
?DOC(" Sends a photo message with a single default photo.\n").
-spec send_photo(conversation_test()) -> conversation_test().
send_photo(Ct) ->
{conversation_test,
lists:append(
erlang:element(2, Ct),
[{send_photo, [telega@testing@factory:photo_size()]}]
)}.
-file("src/telega/testing/conversation.gleam", 90).
?DOC(" Sends a photo message with custom photos.\n").
-spec send_photo_with(
conversation_test(),
list(telega@model@types:photo_size())
) -> conversation_test().
send_photo_with(Ct, Photos) ->
{conversation_test,
lists:append(erlang:element(2, Ct), [{send_photo, Photos}])}.
-file("src/telega/testing/conversation.gleam", 98).
?DOC(" Sends a video message with a default video.\n").
-spec send_video(conversation_test()) -> conversation_test().
send_video(Ct) ->
{conversation_test,
lists:append(
erlang:element(2, Ct),
[{send_video, telega@testing@factory:video()}]
)}.
-file("src/telega/testing/conversation.gleam", 105).
?DOC(" Sends a video message with a custom video.\n").
-spec send_video_with(conversation_test(), telega@model@types:video()) -> conversation_test().
send_video_with(Ct, Video) ->
{conversation_test,
lists:append(erlang:element(2, Ct), [{send_video, Video}])}.
-file("src/telega/testing/conversation.gleam", 113).
?DOC(" Sends an audio message with a default audio.\n").
-spec send_audio(conversation_test()) -> conversation_test().
send_audio(Ct) ->
{conversation_test,
lists:append(
erlang:element(2, Ct),
[{send_audio, telega@testing@factory:audio()}]
)}.
-file("src/telega/testing/conversation.gleam", 120).
?DOC(" Sends an audio message with custom audio.\n").
-spec send_audio_with(conversation_test(), telega@model@types:audio()) -> conversation_test().
send_audio_with(Ct, Audio) ->
{conversation_test,
lists:append(erlang:element(2, Ct), [{send_audio, Audio}])}.
-file("src/telega/testing/conversation.gleam", 128).
?DOC(" Sends a voice message with a default voice.\n").
-spec send_voice(conversation_test()) -> conversation_test().
send_voice(Ct) ->
{conversation_test,
lists:append(
erlang:element(2, Ct),
[{send_voice, telega@testing@factory:voice()}]
)}.
-file("src/telega/testing/conversation.gleam", 135).
?DOC(" Sends a voice message with custom voice.\n").
-spec send_voice_with(conversation_test(), telega@model@types:voice()) -> conversation_test().
send_voice_with(Ct, Voice) ->
{conversation_test,
lists:append(erlang:element(2, Ct), [{send_voice, Voice}])}.
-file("src/telega/testing/conversation.gleam", 143).
?DOC(" Sends a raw message update with a user-provided message.\n").
-spec send_message(conversation_test(), telega@model@types:message()) -> conversation_test().
send_message(Ct, Message) ->
{conversation_test,
lists:append(erlang:element(2, Ct), [{send_message_update, Message}])}.
-file("src/telega/testing/conversation.gleam", 151).
?DOC(" Expects the next reply to exactly match the given text.\n").
-spec expect_reply(conversation_test(), binary()) -> conversation_test().
expect_reply(Ct, Text) ->
{conversation_test,
lists:append(erlang:element(2, Ct), [{expect_reply, Text}])}.
-file("src/telega/testing/conversation.gleam", 156).
?DOC(" Expects the next reply to contain the given substring.\n").
-spec expect_reply_containing(conversation_test(), binary()) -> conversation_test().
expect_reply_containing(Ct, Substring) ->
{conversation_test,
lists:append(
erlang:element(2, Ct),
[{expect_reply_containing, Substring}]
)}.
-file("src/telega/testing/conversation.gleam", 166).
?DOC(" Expects the next reply to include an inline keyboard containing all specified button texts.\n").
-spec expect_keyboard(conversation_test(), list(binary())) -> conversation_test().
expect_keyboard(Ct, Buttons) ->
{conversation_test,
lists:append(erlang:element(2, Ct), [{expect_keyboard, Buttons}])}.
-file("src/telega/testing/conversation.gleam", 174).
?DOC(" Expects the next reply to contain the given substring AND include a keyboard with specified buttons.\n").
-spec expect_reply_with_keyboard(conversation_test(), binary(), list(binary())) -> conversation_test().
expect_reply_with_keyboard(Ct, Substring, Buttons) ->
{conversation_test,
lists:append(
erlang:element(2, Ct),
[{expect_reply_with_keyboard, Substring, Buttons}]
)}.
-file("src/telega/testing/conversation.gleam", 188).
?DOC(
" Expects the next API call to have a path containing `path_contains`\n"
" and a body containing `body_contains`.\n"
).
-spec expect_api_call(conversation_test(), binary(), binary()) -> conversation_test().
expect_api_call(Ct, Path_contains, Body_contains) ->
{conversation_test,
lists:append(
erlang:element(2, Ct),
[{expect_api_call, Path_contains, Body_contains}]
)}.
-file("src/telega/testing/conversation.gleam", 576).
-spec receive_next_call_matching(
gleam@erlang@process:subject(telega@testing@mock:api_call()),
binary(),
integer()
) -> telega@testing@mock:api_call().
receive_next_call_matching(Calls, Path_contains, Attempts) ->
case Attempts > 20 of
true ->
erlang:error(#{gleam_error => panic,
message => (<<<<"No API call with path containing '"/utf8,
Path_contains/binary>>/binary,
"' received after waiting"/utf8>>),
file => <<?FILEPATH/utf8>>,
module => <<"telega/testing/conversation"/utf8>>,
function => <<"receive_next_call_matching"/utf8>>,
line => 583});
false ->
case gleam@erlang@process:'receive'(Calls, 100) of
{ok, Call} ->
case gleam_stdlib:contains_string(
erlang:element(8, erlang:element(2, Call)),
Path_contains
) of
true ->
Call;
false ->
receive_next_call_matching(
Calls,
Path_contains,
Attempts + 1
)
end;
{error, _} ->
receive_next_call_matching(
Calls,
Path_contains,
Attempts + 1
)
end
end.
-file("src/telega/testing/conversation.gleam", 558).
-spec assert_next_api_call(
gleam@erlang@process:subject(telega@testing@mock:api_call()),
binary(),
binary()
) -> nil.
assert_next_api_call(Calls, Path_contains, Body_contains) ->
Call = receive_next_call_matching(Calls, Path_contains, 0),
case gleam_stdlib:contains_string(
erlang:element(4, erlang:element(2, Call)),
Body_contains
) of
true ->
nil;
false ->
erlang:error(#{gleam_error => panic,
message => (<<<<<<"Expected API call body to contain '"/utf8,
Body_contains/binary>>/binary,
"', got: "/utf8>>/binary,
(erlang:element(4, erlang:element(2, Call)))/binary>>),
file => <<?FILEPATH/utf8>>,
module => <<"telega/testing/conversation"/utf8>>,
function => <<"assert_next_api_call"/utf8>>,
line => 567})
end.
-file("src/telega/testing/conversation.gleam", 524).
-spec assert_body_keyboard(binary(), list(binary())) -> nil.
assert_body_keyboard(Body, Expected_buttons) ->
case gleam_stdlib:contains_string(Body, <<"inline_keyboard"/utf8>>) of
false ->
erlang:error(#{gleam_error => panic,
message => (<<"Expected reply to contain an inline keyboard, but none found in: "/utf8,
Body/binary>>),
file => <<?FILEPATH/utf8>>,
module => <<"telega/testing/conversation"/utf8>>,
function => <<"assert_body_keyboard"/utf8>>,
line => 529});
true ->
gleam@list:each(
Expected_buttons,
fun(Button_text) ->
case gleam_stdlib:contains_string(Body, Button_text) of
true ->
nil;
false ->
erlang:error(#{gleam_error => panic,
message => (<<<<<<"Expected keyboard button '"/utf8,
Button_text/binary>>/binary,
"' not found in reply body: "/utf8>>/binary,
Body/binary>>),
file => <<?FILEPATH/utf8>>,
module => <<"telega/testing/conversation"/utf8>>,
function => <<"assert_body_keyboard"/utf8>>,
line => 538})
end
end
)
end.
-file("src/telega/testing/conversation.gleam", 511).
-spec assert_body_text(binary(), fun((binary()) -> nil)) -> nil.
assert_body_text(Body, Check) ->
Text_result = gleam@json:parse(
Body,
begin
gleam@dynamic@decode:field(
<<"text"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Text) -> gleam@dynamic@decode:success(Text) end
)
end
),
case Text_result of
{ok, Text@1} ->
Check(Text@1);
{error, _} ->
erlang:error(#{gleam_error => panic,
message => (<<"Could not extract 'text' from API call body: "/utf8,
Body/binary>>),
file => <<?FILEPATH/utf8>>,
module => <<"telega/testing/conversation"/utf8>>,
function => <<"assert_body_text"/utf8>>,
line => 520})
end.
-file("src/telega/testing/conversation.gleam", 478).
-spec receive_next_send_message(
gleam@erlang@process:subject(telega@testing@mock:api_call()),
integer()
) -> telega@testing@mock:api_call().
receive_next_send_message(Calls, Attempts) ->
case Attempts > 20 of
true ->
erlang:error(#{gleam_error => panic,
message => <<"Expected a reply but no sendMessage API call was received after waiting"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"telega/testing/conversation"/utf8>>,
function => <<"receive_next_send_message"/utf8>>,
line => 484});
false ->
case gleam@erlang@process:'receive'(Calls, 100) of
{ok, Call} ->
Is_message_call = gleam_stdlib:contains_string(
erlang:element(8, erlang:element(2, Call)),
<<"sendMessage"/utf8>>
)
orelse gleam_stdlib:contains_string(
erlang:element(8, erlang:element(2, Call)),
<<"editMessageText"/utf8>>
),
case Is_message_call of
true ->
Call;
false ->
receive_next_send_message(Calls, Attempts + 1)
end;
{error, _} ->
receive_next_send_message(Calls, Attempts + 1)
end
end.
-file("src/telega/testing/conversation.gleam", 550).
-spec assert_next_reply_keyboard(
gleam@erlang@process:subject(telega@testing@mock:api_call()),
list(binary())
) -> nil.
assert_next_reply_keyboard(Calls, Expected_buttons) ->
Call = receive_next_send_message(Calls, 0),
assert_body_keyboard(
erlang:element(4, erlang:element(2, Call)),
Expected_buttons
).
-file("src/telega/testing/conversation.gleam", 503).
-spec assert_next_reply(
gleam@erlang@process:subject(telega@testing@mock:api_call()),
fun((binary()) -> nil)
) -> nil.
assert_next_reply(Calls, Check) ->
Call = receive_next_send_message(Calls, 0),
assert_body_text(erlang:element(4, erlang:element(2, Call)), Check).
-file("src/telega/testing/conversation.gleam", 347).
-spec execute_steps(
list(step()),
gleam@erlang@process:subject(telega@bot:bot_message()),
gleam@erlang@process:subject(telega@testing@mock:api_call())
) -> nil.
execute_steps(Steps, Bot_subject, Calls) ->
case Steps of
[] ->
nil;
[Step | Rest] ->
case Step of
{send_text, Text} ->
Update = telega@testing@factory:text_update(Text),
telega@bot:handle_update(Bot_subject, Update),
nil;
{send_command, Command, Payload} ->
Update@1 = telega@testing@factory:command_update_with(
Command,
Payload,
987654321,
123456789
),
telega@bot:handle_update(Bot_subject, Update@1),
nil;
{send_callback, Data} ->
Update@2 = telega@testing@factory:callback_query_update(
Data
),
telega@bot:handle_update(Bot_subject, Update@2),
nil;
{send_photo, Photos} ->
Update@3 = telega@testing@factory:photo_update_with(
Photos,
987654321,
123456789
),
telega@bot:handle_update(Bot_subject, Update@3),
nil;
{send_video, Video} ->
Update@4 = telega@testing@factory:video_update_with(
Video,
987654321,
123456789
),
telega@bot:handle_update(Bot_subject, Update@4),
nil;
{send_audio, Audio} ->
Update@5 = telega@testing@factory:audio_update_with(
Audio,
987654321,
123456789
),
telega@bot:handle_update(Bot_subject, Update@5),
nil;
{send_voice, Voice} ->
Update@6 = telega@testing@factory:voice_update_with(
Voice,
987654321,
123456789
),
telega@bot:handle_update(Bot_subject, Update@6),
nil;
{send_message_update, Message} ->
Update@7 = telega@testing@factory:message_update(Message),
telega@bot:handle_update(Bot_subject, Update@7),
nil;
{expect_reply, Text@1} ->
assert_next_reply(
Calls,
fun(Reply_text) -> case Reply_text =:= Text@1 of
true ->
nil;
false ->
erlang:error(#{gleam_error => panic,
message => (<<<<<<<<"Expected reply '"/utf8,
Text@1/binary>>/binary,
"', got '"/utf8>>/binary,
Reply_text/binary>>/binary,
"'"/utf8>>),
file => <<?FILEPATH/utf8>>,
module => <<"telega/testing/conversation"/utf8>>,
function => <<"execute_steps"/utf8>>,
line => 427})
end end
);
{expect_reply_containing, Substring} ->
assert_next_reply(
Calls,
fun(Reply_text@1) ->
case gleam_stdlib:contains_string(
Reply_text@1,
Substring
) of
true ->
nil;
false ->
erlang:error(#{gleam_error => panic,
message => (<<<<<<<<"Expected reply containing '"/utf8,
Substring/binary>>/binary,
"', got '"/utf8>>/binary,
Reply_text@1/binary>>/binary,
"'"/utf8>>),
file => <<?FILEPATH/utf8>>,
module => <<"telega/testing/conversation"/utf8>>,
function => <<"execute_steps"/utf8>>,
line => 438})
end
end
);
{expect_keyboard, Buttons} ->
assert_next_reply_keyboard(Calls, Buttons);
{expect_reply_with_keyboard, Substring@1, Buttons@1} ->
Call = receive_next_send_message(Calls, 0),
Body = erlang:element(4, erlang:element(2, Call)),
assert_body_text(
Body,
fun(Reply_text@2) ->
case gleam_stdlib:contains_string(
Reply_text@2,
Substring@1
) of
true ->
nil;
false ->
erlang:error(#{gleam_error => panic,
message => (<<<<<<<<"Expected reply containing '"/utf8,
Substring@1/binary>>/binary,
"', got '"/utf8>>/binary,
Reply_text@2/binary>>/binary,
"'"/utf8>>),
file => <<?FILEPATH/utf8>>,
module => <<"telega/testing/conversation"/utf8>>,
function => <<"execute_steps"/utf8>>,
line => 458})
end
end
),
assert_body_keyboard(Body, Buttons@1);
{expect_api_call, Path_contains, Body_contains} ->
assert_next_api_call(Calls, Path_contains, Body_contains)
end,
execute_steps(Rest, Bot_subject, Calls)
end.
-file("src/telega/testing/conversation.gleam", 311).
?DOC(
" Lowest-level dependencies-aware runner: custom client, calls subject, router handler,\n"
" session settings, and injected `dependencies`. All the other `run_*` helpers funnel\n"
" through this — use it directly when you need full control over every input.\n"
).
-spec run_with_client_with_dependencies(
conversation_test(),
telega@client:telegram_client(),
gleam@erlang@process:subject(telega@testing@mock:api_call()),
fun((telega@bot:context(BLWB, BLWC, BLWD), telega@update:update()) -> {ok,
telega@bot:context(BLWB, BLWC, BLWD)} |
{error, BLWC}),
telega@bot:session_settings(BLWB, BLWC),
BLWD
) -> nil.
run_with_client_with_dependencies(
Ct,
Client,
Calls,
Router_handler,
Session_settings,
Dependencies
) ->
Config = telega@testing@context:config_with_client(Client),
Reg@1 = case telega@internal@registry:start(<<"test_conversation"/utf8>>) of
{ok, Reg} -> Reg;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"telega/testing/conversation"/utf8>>,
function => <<"run_with_client_with_dependencies"/utf8>>,
line => 322,
value => _assert_fail,
start => 10116,
'end' => 10172,
pattern_start => 10127,
pattern_end => 10134})
end,
Chat_factory_started@1 = case begin
_pipe = gleam@otp@factory_supervisor:worker_child(
fun telega@bot:start_chat_instance/1
),
_pipe@1 = gleam@otp@factory_supervisor:restart_strategy(
_pipe,
transient
),
gleam@otp@factory_supervisor:start(_pipe@1)
end of
{ok, Chat_factory_started} -> Chat_factory_started;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"telega/testing/conversation"/utf8>>,
function => <<"run_with_client_with_dependencies"/utf8>>,
line => 323,
value => _assert_fail@1,
start => 10175,
'end' => 10329,
pattern_start => 10186,
pattern_end => 10210})
end,
Started@1 = case telega@bot:start(
Reg@1,
Config,
telega@testing@factory:bot_user(),
Router_handler,
[],
Session_settings,
fun(_, _) -> {ok, nil} end,
Dependencies,
erlang:element(3, Chat_factory_started@1),
none
) of
{ok, Started} -> Started;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"telega/testing/conversation"/utf8>>,
function => <<"run_with_client_with_dependencies"/utf8>>,
line => 328,
value => _assert_fail@2,
start => 10333,
'end' => 10657,
pattern_start => 10344,
pattern_end => 10355})
end,
execute_steps(erlang:element(2, Ct), erlang:element(3, Started@1), Calls),
_ = telega@internal@registry:stop(Reg@1),
nil.
-file("src/telega/testing/conversation.gleam", 263).
?DOC(" Runs the test with a custom client, calls subject, router handler, and session settings.\n").
-spec run_with_client(
conversation_test(),
telega@client:telegram_client(),
gleam@erlang@process:subject(telega@testing@mock:api_call()),
fun((telega@bot:context(BLVI, BLVJ, nil), telega@update:update()) -> {ok,
telega@bot:context(BLVI, BLVJ, nil)} |
{error, BLVJ}),
telega@bot:session_settings(BLVI, BLVJ)
) -> nil.
run_with_client(Ct, Client, Calls, Router_handler, Session_settings) ->
run_with_client_with_dependencies(
Ct,
Client,
Calls,
Router_handler,
Session_settings,
nil
).
-file("src/telega/testing/conversation.gleam", 214).
?DOC(" Lower-level variant: runs the test with a custom router handler and session settings.\n").
-spec run_with(
conversation_test(),
fun((telega@bot:context(BLUI, BLUJ, nil), telega@update:update()) -> {ok,
telega@bot:context(BLUI, BLUJ, nil)} |
{error, BLUJ}),
telega@bot:session_settings(BLUI, BLUJ)
) -> nil.
run_with(Ct, Router_handler, Session_settings) ->
{Client, Calls} = telega@testing@mock:message_client(),
run_with_client(Ct, Client, Calls, Router_handler, Session_settings).
-file("src/telega/testing/conversation.gleam", 201).
?DOC(" Runs the conversation test against a router with the given default session factory.\n").
-spec run(
conversation_test(),
telega@router:router(BLUD, any(), nil),
fun(() -> BLUD)
) -> nil.
run(Ct, Router, Default_session) ->
run_with(
Ct,
fun(Ctx, Update) -> telega@router:handle(Router, Ctx, Update) end,
telega@testing@context:session_settings(Default_session)
).
-file("src/telega/testing/conversation.gleam", 244).
?DOC(
" Like `run_with_mock`, but for a router whose handlers read services from\n"
" `ctx.dependencies`. Combines a custom mock client with injected `dependencies`.\n"
).
-spec run_with_mock_with_dependencies(
conversation_test(),
telega@router:router(BLVA, any(), BLVC),
fun(() -> BLVA),
telega@client:telegram_client(),
gleam@erlang@process:subject(telega@testing@mock:api_call()),
BLVC
) -> nil.
run_with_mock_with_dependencies(
Ct,
Router,
Default_session,
Client,
Calls,
Dependencies
) ->
run_with_client_with_dependencies(
Ct,
Client,
Calls,
fun(Ctx, Update) -> telega@router:handle(Router, Ctx, Update) end,
telega@testing@context:session_settings(Default_session),
Dependencies
).
-file("src/telega/testing/conversation.gleam", 225).
?DOC(" Runs the test with a custom mock client (e.g. from `mock.routed_client`).\n").
-spec run_with_mock(
conversation_test(),
telega@router:router(BLUU, any(), nil),
fun(() -> BLUU),
telega@client:telegram_client(),
gleam@erlang@process:subject(telega@testing@mock:api_call())
) -> nil.
run_with_mock(Ct, Router, Default_session, Client, Calls) ->
run_with_mock_with_dependencies(
Ct,
Router,
Default_session,
Client,
Calls,
nil
).
-file("src/telega/testing/conversation.gleam", 291).
?DOC(
" Runs the conversation test against a router that needs injected dependencies\n"
" (`dependencies`). Use this to drive a bot whose handlers read services from\n"
" `ctx.dependencies` through the conversation DSL.\n"
"\n"
" ```gleam\n"
" conversation.conversation_test()\n"
" |> conversation.send(\"/my_bookings\")\n"
" |> conversation.expect_reply_containing(\"No bookings\")\n"
" |> conversation.run_with_dependencies(build_router(), fn() { Nil }, Dependencies(db:, catalog:))\n"
" ```\n"
).
-spec run_with_dependencies(
conversation_test(),
telega@router:router(BLVU, any(), BLVW),
fun(() -> BLVU),
BLVW
) -> nil.
run_with_dependencies(Ct, Router, Default_session, Dependencies) ->
{Client, Calls} = telega@testing@mock:message_client(),
run_with_client_with_dependencies(
Ct,
Client,
Calls,
fun(Ctx, Update) -> telega@router:handle(Router, Ctx, Update) end,
telega@testing@context:session_settings(Default_session),
Dependencies
).