roksta 0.2.7__cp314-cp314-win_amd64.whl → 0.3.2__cp314-cp314-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of roksta might be problematic. Click here for more details.
- roksta/__init__.cp314-win_amd64.pyd +0 -0
- roksta/ai/__init__.cp314-win_amd64.pyd +0 -0
- roksta/ai/call_ai.cp314-win_amd64.pyd +0 -0
- roksta/ai/gemini.cp314-win_amd64.pyd +0 -0
- roksta/ai/generic.cp314-win_amd64.pyd +0 -0
- roksta/ai/llm.cp314-win_amd64.pyd +0 -0
- roksta/ai/openai.cp314-win_amd64.pyd +0 -0
- roksta/ai/tools/__init__.cp314-win_amd64.pyd +0 -0
- roksta/ai/tools/delete_file.cp314-win_amd64.pyd +0 -0
- roksta/ai/tools/edit_file.cp314-win_amd64.pyd +0 -0
- roksta/ai/tools/final_response.cp314-win_amd64.pyd +0 -0
- roksta/ai/tools/get_file_summaries.cp314-win_amd64.pyd +0 -0
- roksta/ai/tools/read_file.cp314-win_amd64.pyd +0 -0
- roksta/ai/tools/regex_replace.cp314-win_amd64.pyd +0 -0
- roksta/ai/tools/shell_any.cp314-win_amd64.pyd +0 -0
- roksta/ai/tools/shell_limited.cp314-win_amd64.pyd +0 -0
- roksta/ai/tools/tool_defs.cp314-win_amd64.pyd +0 -0
- roksta/ai/tools/tool_utils.cp314-win_amd64.pyd +0 -0
- roksta/ai/tools/write_file.cp314-win_amd64.pyd +0 -0
- roksta/analytics.cp314-win_amd64.pyd +0 -0
- roksta/balance.cp314-win_amd64.pyd +0 -0
- roksta/build_project.cp314-win_amd64.pyd +0 -0
- roksta/chat_workflow.cp314-win_amd64.pyd +0 -0
- roksta/check_for_updates.cp314-win_amd64.pyd +0 -0
- roksta/checkpoints.cp314-win_amd64.pyd +0 -0
- roksta/clarify_goal.cp314-win_amd64.pyd +0 -0
- roksta/codebase_listing.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/__init__.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_activate_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_add_funds_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_auto_charge_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_auto_commit_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_building_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_chat_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_dev_rate_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_feedback_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_goal_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_help_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_init_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_linting_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_login_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_logout_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_payment_details_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_quit_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_redeem_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_request_activation_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_testing_command.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers/handle_usage_command.cp314-win_amd64.pyd +0 -0
- roksta/create_default_config.cp314-win_amd64.pyd +0 -0
- roksta/default_config.cp314-win_amd64.pyd +0 -0
- roksta/enums.cp314-win_amd64.pyd +0 -0
- roksta/env.cp314-win_amd64.pyd +0 -0
- roksta/extended_text_area.cp314-win_amd64.pyd +0 -0
- roksta/firebase.cp314-win_amd64.pyd +0 -0
- roksta/firebase_auth_web.cp314-win_amd64.pyd +0 -0
- roksta/firebase_config.cp314-win_amd64.pyd +0 -0
- roksta/fix_tests.cp314-win_amd64.pyd +0 -0
- roksta/gen_codebase_summaries.cp314-win_amd64.pyd +0 -0
- roksta/gen_one_line_goal.cp314-win_amd64.pyd +0 -0
- roksta/get_codebase_structure.cp314-win_amd64.pyd +0 -0
- roksta/get_failing_tests.cp314-win_amd64.pyd +0 -0
- roksta/goal_workflow.cp314-win_amd64.pyd +0 -0
- roksta/init_codebase.cp314-win_amd64.pyd +0 -0
- roksta/lint_code.cp314-win_amd64.pyd +0 -0
- roksta/logger.cp314-win_amd64.pyd +0 -0
- roksta/main.cp314-win_amd64.pyd +0 -0
- roksta/make_issue.cp314-win_amd64.pyd +0 -0
- roksta/new_features.cp314-win_amd64.pyd +0 -0
- roksta/parse_readme.cp314-win_amd64.pyd +0 -0
- roksta/propose_solution.cp314-win_amd64.pyd +0 -0
- roksta/response_formats.cp314-win_amd64.pyd +0 -0
- roksta/rewrite_goal.cp314-win_amd64.pyd +0 -0
- roksta/roksta.cp314-win_amd64.pyd +0 -0
- roksta/run_cli_goal.cp314-win_amd64.pyd +0 -0
- roksta/select_files.cp314-win_amd64.pyd +0 -0
- roksta/tips.cp314-win_amd64.pyd +0 -0
- roksta/utils.cp314-win_amd64.pyd +0 -0
- roksta/write_code.cp314-win_amd64.pyd +0 -0
- {roksta-0.2.7.dist-info → roksta-0.3.2.dist-info}/METADATA +2 -1
- roksta-0.3.2.dist-info/RECORD +121 -0
- tests/conftest.py +42 -0
- tests/functions/{api_v0_01 → api_v1_01}/__init__.py +1 -1
- tests/functions/{api_v0_01 → api_v1_01}/test__analytics.py +2 -3
- tests/functions/{api_v0_01 → api_v1_01}/test__gemini_proxy.py +51 -6
- tests/functions/{api_v0_01 → api_v1_01}/test__generic_proxy.py +31 -2
- tests/functions/{api_v0_01 → api_v1_01}/test__get_payment_details.py +2 -2
- tests/functions/{api_v0_01 → api_v1_01}/test__openai_proxy.py +50 -14
- tests/functions/{api_v0_01 → api_v1_01}/test__redeem_credit_code.py +2 -2
- tests/functions/{api_v0_01 → api_v1_01}/test__sync_emails.py +3 -2
- tests/functions/{api_v0_01 → api_v1_01}/test__take_payment.py +2 -2
- tests/functions/{api_v0_01 → api_v1_01}/test__use_activation_code.py +3 -2
- tests/functions/api_v1_02/__init__.py +2 -0
- tests/functions/api_v1_02/test__analytics.py +416 -0
- tests/functions/api_v1_02/test__gemini_proxy.py +352 -0
- tests/functions/api_v1_02/test__generic_proxy.py +428 -0
- tests/functions/api_v1_02/test__get_payment_details.py +356 -0
- tests/functions/api_v1_02/test__openai_proxy.py +449 -0
- tests/functions/api_v1_02/test__redeem_credit_code.py +167 -0
- tests/functions/api_v1_02/test__sync_emails.py +325 -0
- tests/functions/api_v1_02/test__take_payment.py +491 -0
- tests/functions/api_v1_02/test__use_activation_code.py +438 -0
- tests/functions/api_v1_02/test_proxy_keyword_replacement.py +557 -0
- tests/functions/api_v1_02/test_replace_keywords.py +74 -0
- tests/functions/test_utils.py +484 -0
- roksta/ai/tools.cp314-win_amd64.pyd +0 -0
- roksta/command_handlers.cp314-win_amd64.pyd +0 -0
- roksta-0.2.7.dist-info/RECORD +0 -78
- tests/functions/test_utils_functions.py +0 -222
- {roksta-0.2.7.dist-info → roksta-0.3.2.dist-info}/WHEEL +0 -0
- {roksta-0.2.7.dist-info → roksta-0.3.2.dist-info}/entry_points.txt +0 -0
- {roksta-0.2.7.dist-info → roksta-0.3.2.dist-info}/top_level.txt +0 -0
- /tests/functions/{test_main_functions.py → test_main.py} +0 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
roksta/enums.cp314-win_amd64.pyd
CHANGED
|
Binary file
|
roksta/env.cp314-win_amd64.pyd
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
roksta/main.cp314-win_amd64.pyd
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
roksta/tips.cp314-win_amd64.pyd
CHANGED
|
Binary file
|
roksta/utils.cp314-win_amd64.pyd
CHANGED
|
Binary file
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: roksta
|
|
3
|
-
Version: 0.2
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: An AI coding assistant
|
|
5
5
|
Author-email: Prash Naidu <prash@roksta.ai>
|
|
6
6
|
Project-URL: Homepage, https://roksta.ai
|
|
@@ -21,6 +21,7 @@ Requires-Dist: gitpython>=3.1.44
|
|
|
21
21
|
Requires-Dist: jsonref>=1.1.0
|
|
22
22
|
Requires-Dist: pathspec>=0.12.1
|
|
23
23
|
Requires-Dist: psutil>=7.1.0
|
|
24
|
+
Requires-Dist: PyNaCl>=1.6.0
|
|
24
25
|
Provides-Extra: tests
|
|
25
26
|
Requires-Dist: pytest>=8.4.1; extra == "tests"
|
|
26
27
|
Requires-Dist: pytest-asyncio>=1.0.0; extra == "tests"
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
roksta/__init__.cp314-win_amd64.pyd,sha256=Y98BLa_mP5zxi3ECQTI5IZTpsvS3eVDB6nR5Ipz1_iI,16896
|
|
2
|
+
roksta/analytics.cp314-win_amd64.pyd,sha256=4r6lQq2MQyjbQL7ns3zHeGvvMDdUPHNvhQ2jIcmGs2k,94208
|
|
3
|
+
roksta/balance.cp314-win_amd64.pyd,sha256=L2qznmDduxRPbGZuvbCDv4kKhhY5ALkmgU8u6GLGitc,140288
|
|
4
|
+
roksta/build_project.cp314-win_amd64.pyd,sha256=tV3YJZVOy5uoDY3UwV8rlArW4LWCyZcG0SbS_4MYEps,60928
|
|
5
|
+
roksta/chat_workflow.cp314-win_amd64.pyd,sha256=C1Ymb9Sx79Gl-e3YdbxpTGvnT-USJhzX_hgsfu6SpGw,89600
|
|
6
|
+
roksta/check_for_updates.cp314-win_amd64.pyd,sha256=FHL6S4igkEAxN_KpgPE_eyRw-VsaRcBfmO-FYX6eVog,102400
|
|
7
|
+
roksta/checkpoints.cp314-win_amd64.pyd,sha256=CfGBzg3tNzaW3hgmIGgVWDMNFY4gsanMrUcrkl_O0Jo,79872
|
|
8
|
+
roksta/clarify_goal.cp314-win_amd64.pyd,sha256=k1ZU8KtZxkMRIEUHlk0OaMH1nlsy-9j-EcgXkeyKweg,61440
|
|
9
|
+
roksta/codebase_listing.cp314-win_amd64.pyd,sha256=Bgbgi6h0zHlZ9Ut_eSXInSQoD2WgUhaiosxuluXi8zs,47104
|
|
10
|
+
roksta/create_default_config.cp314-win_amd64.pyd,sha256=dVv-RYH5cFNFRywJnc6DxEKqJzUV-30NMsovCZfbR3s,28672
|
|
11
|
+
roksta/default_config.cp314-win_amd64.pyd,sha256=I6175fYVS-45XmFp90dt23q1SjKQbZnOTGcGBq51XFs,31744
|
|
12
|
+
roksta/enums.cp314-win_amd64.pyd,sha256=YD4qjX3a3ETeQfUxvQ4PMNoLxdUATiXtW2ukd0WPxcQ,124416
|
|
13
|
+
roksta/env.cp314-win_amd64.pyd,sha256=jx4mwJDKsjhDyUpv5LctmrUG4s7HNK-F6IM-kfNzYSg,26112
|
|
14
|
+
roksta/extended_text_area.cp314-win_amd64.pyd,sha256=XUV39mWjTghPfyCsi75p8ewjnSYc4a2Fx2m4_2TTU98,105984
|
|
15
|
+
roksta/firebase.cp314-win_amd64.pyd,sha256=6rxaxM4BdUiC7jvx9RORat54jAeDdO122sd2Sc5sGSA,187392
|
|
16
|
+
roksta/firebase_auth_web.cp314-win_amd64.pyd,sha256=ySCMkZh4yse7jmUWn9w-pAZgjdsF7CdApKNM78esB_o,177152
|
|
17
|
+
roksta/firebase_config.cp314-win_amd64.pyd,sha256=EGoI3qTE4vM8UaGe8ZtAgtUYNDdLNWa87nxGyyb-iNA,19968
|
|
18
|
+
roksta/fix_tests.cp314-win_amd64.pyd,sha256=MuvU-vUYFP9Hx_i6YER4DyUzGYi_9ZNHFB-vih_FNw8,74240
|
|
19
|
+
roksta/gen_codebase_summaries.cp314-win_amd64.pyd,sha256=aJQ7H0mcCoC7SsAFRx-UUb6crpPBX24dPeLlfCfowc4,243200
|
|
20
|
+
roksta/gen_one_line_goal.cp314-win_amd64.pyd,sha256=C8f7YGpfdXyfe7FfRJcSed9mlyuI_b2Yq6fP66EuXa8,65024
|
|
21
|
+
roksta/get_codebase_structure.cp314-win_amd64.pyd,sha256=9XN1As3je1RJ5nhMQJ5JCLGE_WysFoXlgIk-0MDRqDY,67072
|
|
22
|
+
roksta/get_failing_tests.cp314-win_amd64.pyd,sha256=XpKsxsCezU-Fka5xHJo68gn-XVmQhxVZkxnPakGKwug,70144
|
|
23
|
+
roksta/goal_workflow.cp314-win_amd64.pyd,sha256=t0MpBPUMGm2o1H7h95qiNyB-3u2nosr3XCw7Fj9fQx0,198144
|
|
24
|
+
roksta/init_codebase.cp314-win_amd64.pyd,sha256=OUi3s0cSpMOx-mgDee4TEQhTC7lgJiV8pB4hlNSxD5w,117248
|
|
25
|
+
roksta/lint_code.cp314-win_amd64.pyd,sha256=IXOeknKPgraTmMsv6uuKAt2RSIvhjkHLYi4yB5ALHNc,74240
|
|
26
|
+
roksta/logger.cp314-win_amd64.pyd,sha256=PByehGy0Dq0nFJxnh9Vygo8D0BP0v10cJ5j9HhPPkQg,38400
|
|
27
|
+
roksta/main.cp314-win_amd64.pyd,sha256=LeDTUK-V-3alzuG4w_d84S7Y9bQvqpePyDiDb64chzg,37888
|
|
28
|
+
roksta/make_issue.cp314-win_amd64.pyd,sha256=YHhtGABOnWLrfw5eMm74YkfAzREIiX2MF7OMo-CEEsQ,68608
|
|
29
|
+
roksta/new_features.cp314-win_amd64.pyd,sha256=8dFAnlgWmZ_x1uHE5chNpsJ5ysIgOtkkzhrpBdlT-GE,16896
|
|
30
|
+
roksta/parse_readme.cp314-win_amd64.pyd,sha256=396ubyEMD5TXKhe-XTVxvpGpsVobbT0sYHXRUiY1dRQ,62976
|
|
31
|
+
roksta/propose_solution.cp314-win_amd64.pyd,sha256=jOY5v5dZNV4drbLcOvBV_Ixe4lKTgZo7XKW4fGSdHc0,58880
|
|
32
|
+
roksta/response_formats.cp314-win_amd64.pyd,sha256=_avk92XKPVe4_jVUmtbyrGsaAR6tTZL8iT_cd7_JsxY,38912
|
|
33
|
+
roksta/rewrite_goal.cp314-win_amd64.pyd,sha256=aiYBGnCvWcYefuvnYRQ012nrw6_GW4omoj4A-_mU450,55808
|
|
34
|
+
roksta/roksta.cp314-win_amd64.pyd,sha256=nMHWEmxJgB5gHz1EVTq1pJWE1gyZ5ixWqGWLyJ71EjM,233984
|
|
35
|
+
roksta/run_cli_goal.cp314-win_amd64.pyd,sha256=h85oGVR4fDnRMQRW8MRgnkXKtPDd_5zmHNYvBkYioFs,68608
|
|
36
|
+
roksta/select_files.cp314-win_amd64.pyd,sha256=kH7ZJabpaK_Rg-JKmvefFmJxTePHdgAeLjC1JdcegHw,63488
|
|
37
|
+
roksta/tips.cp314-win_amd64.pyd,sha256=7Ume-47KRESQvv9uE9XhuNSSXI-0jNsEdG3OwZ6goe8,21504
|
|
38
|
+
roksta/utils.cp314-win_amd64.pyd,sha256=0ZKbgGl11ac30p6zrbw4B3wTTA3OiM2MX4tyhqsiJoc,242688
|
|
39
|
+
roksta/write_code.cp314-win_amd64.pyd,sha256=TsHc1FH1cGR6gOW2ZccWMGxZCaXEOSYqYuTje4G7EB4,56832
|
|
40
|
+
roksta/ai/__init__.cp314-win_amd64.pyd,sha256=_U23mWgkukUaQgMOyREMvvDIQhpsF8EanNlOhpHXXco,16896
|
|
41
|
+
roksta/ai/call_ai.cp314-win_amd64.pyd,sha256=vab6ACBEQasAZ3G8iwxnfQHTmjyKnQS6tLBMk9yGrow,74752
|
|
42
|
+
roksta/ai/gemini.cp314-win_amd64.pyd,sha256=OzcrwuL0HeYFhQX6ZR832pTeui-irEtYi7zBJA-AtgA,148480
|
|
43
|
+
roksta/ai/generic.cp314-win_amd64.pyd,sha256=IwYgOBDBAsDY--_rOjDG5wo8ic3VDIjlvIzJu-b_rjc,109568
|
|
44
|
+
roksta/ai/llm.cp314-win_amd64.pyd,sha256=zDDeFGx9Rlst1vkocg83EijImuaJoEA-vFf2ih_xFXk,86528
|
|
45
|
+
roksta/ai/openai.cp314-win_amd64.pyd,sha256=Gb3ZyVE6RKdPmWYeki5ezcq8teJsteeZdyC94ByCso4,105984
|
|
46
|
+
roksta/ai/tools/__init__.cp314-win_amd64.pyd,sha256=yiiD3E0o_LNp5LYzwR6MD8KiFUFTe0YzH9BtoPWzVes,23552
|
|
47
|
+
roksta/ai/tools/delete_file.cp314-win_amd64.pyd,sha256=R2s3YjoyRnDZiTPnlzmUEmOWCrttW_KjSLijvZPW8DA,34816
|
|
48
|
+
roksta/ai/tools/edit_file.cp314-win_amd64.pyd,sha256=KofgRCfKssbF5D5D-KanD9M4r8SrT7myS4Awl66R8cA,46080
|
|
49
|
+
roksta/ai/tools/final_response.cp314-win_amd64.pyd,sha256=LHxBBmkisJf_oDOSUp0Yhs_u2OMdbY7n-NMpKBIM_h0,22016
|
|
50
|
+
roksta/ai/tools/get_file_summaries.cp314-win_amd64.pyd,sha256=ZApSf3gHpn2MoP5I4t2mHyNGDr7QrEBkGWWVjiG6rVc,36864
|
|
51
|
+
roksta/ai/tools/read_file.cp314-win_amd64.pyd,sha256=cip7QWBaXDVIf7jQ6icTogURm-IbliLSfV3SgCK6EMU,46592
|
|
52
|
+
roksta/ai/tools/regex_replace.cp314-win_amd64.pyd,sha256=1UDhPhFf8cM8NGwp3vjwXsru6FQ9RQhjL8ZPkT_GG6k,46080
|
|
53
|
+
roksta/ai/tools/shell_any.cp314-win_amd64.pyd,sha256=--OajGsWAygbIN0FW2npWvkfyn5Goevl0TakD6hmFgg,70144
|
|
54
|
+
roksta/ai/tools/shell_limited.cp314-win_amd64.pyd,sha256=Bqkn4o9qB1coBbdIQa-DChghbs2r2IVe3y_LrSKEVrg,57856
|
|
55
|
+
roksta/ai/tools/tool_defs.cp314-win_amd64.pyd,sha256=yrsoXl8Wi99P53rPkwgwlUEArd6MR93NDcVuTjm7hSk,37888
|
|
56
|
+
roksta/ai/tools/tool_utils.cp314-win_amd64.pyd,sha256=VUOF3pvA1S4FhE1oQf26K-NTjMuwzpwSsGFsn4aa3ao,100864
|
|
57
|
+
roksta/ai/tools/write_file.cp314-win_amd64.pyd,sha256=0fSHZlBFVBCP_uCIczFXbYFNYri4Kzpmq0-Q0d1GdAQ,36352
|
|
58
|
+
roksta/command_handlers/__init__.cp314-win_amd64.pyd,sha256=ITWkRkYrIeUpY3NtpNSxHF9gZj4gjUHETArNsfxAuuk,23040
|
|
59
|
+
roksta/command_handlers/handle_activate_command.cp314-win_amd64.pyd,sha256=4RUJXTz2FBJo1p3oiGsh7xaog5xSi1q_ob_vp-SP56c,78848
|
|
60
|
+
roksta/command_handlers/handle_add_funds_command.cp314-win_amd64.pyd,sha256=j1tFEuPC0fduxXMJgQcorxo-V2OpiEa-SzGg5q9q6m4,70144
|
|
61
|
+
roksta/command_handlers/handle_auto_charge_command.cp314-win_amd64.pyd,sha256=ufxqVtc-AFc1meJOyJ2OZ0cQ6YXXO6AA0bmSH8epKow,51712
|
|
62
|
+
roksta/command_handlers/handle_auto_commit_command.cp314-win_amd64.pyd,sha256=LOx29V3b1hGXbBUqWGOvpAiXn8wnfgSfJRLQQxTVYKw,37376
|
|
63
|
+
roksta/command_handlers/handle_building_command.cp314-win_amd64.pyd,sha256=V3cvpHMO9ZXmVGqSoiz1lQHqf1upWfiZtnQpuhrWg1I,41984
|
|
64
|
+
roksta/command_handlers/handle_chat_command.cp314-win_amd64.pyd,sha256=IYLc0Q3PpS60EMPiWvFvoEjZikJkMLFueRsirbdjdPs,41984
|
|
65
|
+
roksta/command_handlers/handle_dev_rate_command.cp314-win_amd64.pyd,sha256=9iktxXoqUhlmXPzKxyHQmWfmDvBESqkJNq5z5GnDl8k,37376
|
|
66
|
+
roksta/command_handlers/handle_feedback_command.cp314-win_amd64.pyd,sha256=bHWisuR0BhWawkn1bGMWSmbFQm19qcxWhRZbwqrm6ME,62976
|
|
67
|
+
roksta/command_handlers/handle_goal_command.cp314-win_amd64.pyd,sha256=sqvtmFNE0ZCFIlI2pTwTkNfnyI175KjVWTXS66aXUQc,56320
|
|
68
|
+
roksta/command_handlers/handle_help_command.cp314-win_amd64.pyd,sha256=YQP3OLDL9JQAlLo5cDLHncfCNqd0qz3EbZABZZqAsXw,75264
|
|
69
|
+
roksta/command_handlers/handle_init_command.cp314-win_amd64.pyd,sha256=triFEX4fmkdcOl0bdFXU2PBMX_MghnnnGs-zYAi8dMc,53248
|
|
70
|
+
roksta/command_handlers/handle_linting_command.cp314-win_amd64.pyd,sha256=ngPdYsSKsebzYWVpmNwTYZGJylW0npGheHX-RplVIgE,45056
|
|
71
|
+
roksta/command_handlers/handle_login_command.cp314-win_amd64.pyd,sha256=NHnouhgYI1RW6wqYa4IhQ_5AcTb57NgzyFMyx5mvfz8,66048
|
|
72
|
+
roksta/command_handlers/handle_logout_command.cp314-win_amd64.pyd,sha256=qt530leR7n4MX0MzDtioQCK_5cZWLKXCRRTKTSJHXbE,29184
|
|
73
|
+
roksta/command_handlers/handle_payment_details_command.cp314-win_amd64.pyd,sha256=rBmx0CitiUeB23FWeYIFIhYbz3az8QouhzEOY_uPp-U,55808
|
|
74
|
+
roksta/command_handlers/handle_quit_command.cp314-win_amd64.pyd,sha256=idGxZpN4AKgDCt-09RDBwJj5ZBRJdpG06HZNIJW9_XY,19968
|
|
75
|
+
roksta/command_handlers/handle_redeem_command.cp314-win_amd64.pyd,sha256=mAzCCmt0qqLLwg55w1TzPFoCU_xswryxWuGb0gCG8nY,53248
|
|
76
|
+
roksta/command_handlers/handle_request_activation_command.cp314-win_amd64.pyd,sha256=L2H6Pq5cOpQpS-M05bS9M3am9PbpIw1ljdigWvLKMC0,65536
|
|
77
|
+
roksta/command_handlers/handle_testing_command.cp314-win_amd64.pyd,sha256=NYjXCnoMyYFt2ZcvW5YFq9fTHWyX2OsnF_duAM4lyak,41984
|
|
78
|
+
roksta/command_handlers/handle_usage_command.cp314-win_amd64.pyd,sha256=fw_Xvp9SFsMrvBTeTf1qFaPwWR2nDA5mVlyc-3_VMGE,61952
|
|
79
|
+
tests/__init__.py,sha256=meQjVtD2zimtDw3tIP6nNWHGDQVC42as-c_y038cYnk,126
|
|
80
|
+
tests/conftest.py,sha256=4-DveP_c_DUwOcRu8_qAE8zJAWmc0kP6XeUXlWSCC8Q,8089
|
|
81
|
+
tests/functions/__init__.py,sha256=msAiuVOA8jfqVxichPYYyfBFCVEFB_xRvj4lrSpKK1w,97
|
|
82
|
+
tests/functions/test_auth.py,sha256=SNzmpkoxknrxx6cTE91MM2kN3F08GB1pRuupP5IrQs0,1016
|
|
83
|
+
tests/functions/test_main.py,sha256=LgWLAOtSfDXNfHhAAr-j9Peb5JBLFtQ0eKAWqTxLNDU,2648
|
|
84
|
+
tests/functions/test_utils.py,sha256=x-_30jai12k87c_7LwuYpk3_mGM_uTF6ZHXGvMWYlO8,17205
|
|
85
|
+
tests/functions/api_v1_00/__init__.py,sha256=VdV5Oy6FRVT4S1xK34YodylJ7FY6jqvjujkS2Qvbyt0,126
|
|
86
|
+
tests/functions/api_v1_00/test__analytics.py,sha256=s_pK4ySr86PC4ZBr7Y7bCHOEuFj36amaWrianBZ_QbU,16222
|
|
87
|
+
tests/functions/api_v1_00/test__gemini_proxy.py,sha256=ZNYBQ9agPyNYGAVYlWPY6IF8wP_5IQ4nbHOpY8TnKEw,13696
|
|
88
|
+
tests/functions/api_v1_00/test__generic_proxy.py,sha256=f2KjO8v_mh4nBwdkFXJLYfFUBpJS_RDtQNfn0ltE2oM,18101
|
|
89
|
+
tests/functions/api_v1_00/test__get_payment_details.py,sha256=GRMAn8WR-07EBZ0IkeVE4MARFUbDdDhEHO2dITRxnVA,14091
|
|
90
|
+
tests/functions/api_v1_00/test__openai_proxy.py,sha256=i1f7S8IFgWiG6WGG-YYptjTCOjSudujEMyhP16BVlW0,18175
|
|
91
|
+
tests/functions/api_v1_00/test__redeem_credit_code.py,sha256=A5WwuSXBX5TiZPdYrDRkUmpppBXG00lcP0LmRz0gNr0,6514
|
|
92
|
+
tests/functions/api_v1_00/test__sync_emails.py,sha256=e0rb637Ois25t__1G8Yp7Pj8WgC-R1I9SUgS6bK1dsU,13024
|
|
93
|
+
tests/functions/api_v1_00/test__take_payment.py,sha256=RQBUHcgN3-XOoPtAjca_72q4BaZxr_L3G_Nss5-gb2g,18513
|
|
94
|
+
tests/functions/api_v1_00/test__use_activation_code.py,sha256=ZOCwXHzenH0l1WhmZP8s8vaXIk58lHpKJ0igx0VEDwY,17398
|
|
95
|
+
tests/functions/api_v1_01/__init__.py,sha256=VdV5Oy6FRVT4S1xK34YodylJ7FY6jqvjujkS2Qvbyt0,126
|
|
96
|
+
tests/functions/api_v1_01/test__analytics.py,sha256=s_pK4ySr86PC4ZBr7Y7bCHOEuFj36amaWrianBZ_QbU,16222
|
|
97
|
+
tests/functions/api_v1_01/test__gemini_proxy.py,sha256=ZNYBQ9agPyNYGAVYlWPY6IF8wP_5IQ4nbHOpY8TnKEw,13696
|
|
98
|
+
tests/functions/api_v1_01/test__generic_proxy.py,sha256=f2KjO8v_mh4nBwdkFXJLYfFUBpJS_RDtQNfn0ltE2oM,18101
|
|
99
|
+
tests/functions/api_v1_01/test__get_payment_details.py,sha256=GRMAn8WR-07EBZ0IkeVE4MARFUbDdDhEHO2dITRxnVA,14091
|
|
100
|
+
tests/functions/api_v1_01/test__openai_proxy.py,sha256=i1f7S8IFgWiG6WGG-YYptjTCOjSudujEMyhP16BVlW0,18175
|
|
101
|
+
tests/functions/api_v1_01/test__redeem_credit_code.py,sha256=A5WwuSXBX5TiZPdYrDRkUmpppBXG00lcP0LmRz0gNr0,6514
|
|
102
|
+
tests/functions/api_v1_01/test__sync_emails.py,sha256=e0rb637Ois25t__1G8Yp7Pj8WgC-R1I9SUgS6bK1dsU,13024
|
|
103
|
+
tests/functions/api_v1_01/test__take_payment.py,sha256=RQBUHcgN3-XOoPtAjca_72q4BaZxr_L3G_Nss5-gb2g,18513
|
|
104
|
+
tests/functions/api_v1_01/test__use_activation_code.py,sha256=ZOCwXHzenH0l1WhmZP8s8vaXIk58lHpKJ0igx0VEDwY,17398
|
|
105
|
+
tests/functions/api_v1_02/__init__.py,sha256=VdV5Oy6FRVT4S1xK34YodylJ7FY6jqvjujkS2Qvbyt0,126
|
|
106
|
+
tests/functions/api_v1_02/test__analytics.py,sha256=s_pK4ySr86PC4ZBr7Y7bCHOEuFj36amaWrianBZ_QbU,16222
|
|
107
|
+
tests/functions/api_v1_02/test__gemini_proxy.py,sha256=ZNYBQ9agPyNYGAVYlWPY6IF8wP_5IQ4nbHOpY8TnKEw,13696
|
|
108
|
+
tests/functions/api_v1_02/test__generic_proxy.py,sha256=f2KjO8v_mh4nBwdkFXJLYfFUBpJS_RDtQNfn0ltE2oM,18101
|
|
109
|
+
tests/functions/api_v1_02/test__get_payment_details.py,sha256=GRMAn8WR-07EBZ0IkeVE4MARFUbDdDhEHO2dITRxnVA,14091
|
|
110
|
+
tests/functions/api_v1_02/test__openai_proxy.py,sha256=i1f7S8IFgWiG6WGG-YYptjTCOjSudujEMyhP16BVlW0,18175
|
|
111
|
+
tests/functions/api_v1_02/test__redeem_credit_code.py,sha256=A5WwuSXBX5TiZPdYrDRkUmpppBXG00lcP0LmRz0gNr0,6514
|
|
112
|
+
tests/functions/api_v1_02/test__sync_emails.py,sha256=e0rb637Ois25t__1G8Yp7Pj8WgC-R1I9SUgS6bK1dsU,13024
|
|
113
|
+
tests/functions/api_v1_02/test__take_payment.py,sha256=RQBUHcgN3-XOoPtAjca_72q4BaZxr_L3G_Nss5-gb2g,18513
|
|
114
|
+
tests/functions/api_v1_02/test__use_activation_code.py,sha256=ZOCwXHzenH0l1WhmZP8s8vaXIk58lHpKJ0igx0VEDwY,17398
|
|
115
|
+
tests/functions/api_v1_02/test_proxy_keyword_replacement.py,sha256=NFr_2f5mYinqx1pwdQjSL4MUs6Zge6Kzz4SeX8H8xq4,24189
|
|
116
|
+
tests/functions/api_v1_02/test_replace_keywords.py,sha256=pFl3XWxujSwkXcuSxsznv_8qvx4u2rh441V6U-31yvc,2757
|
|
117
|
+
roksta-0.3.2.dist-info/METADATA,sha256=NBLudPACgAEsf0RubYaDnGy7TqzoS6WcXzNtq5Dra3o,1496
|
|
118
|
+
roksta-0.3.2.dist-info/WHEEL,sha256=7k6Wcy588iJYe5lf5K095NLg-uoBTnE-T8eHJ92G4_4,101
|
|
119
|
+
roksta-0.3.2.dist-info/entry_points.txt,sha256=mzRdYg_DlzZRwjxYUt9-gyoRCkM1QBTeTbwETgiTdGw,44
|
|
120
|
+
roksta-0.3.2.dist-info/top_level.txt,sha256=lvciNZQ1dPGXpiCLdWVXK03n9fKHjbQdwjqQbnUjeYM,13
|
|
121
|
+
roksta-0.3.2.dist-info/RECORD,,
|
tests/conftest.py
CHANGED
|
@@ -167,3 +167,45 @@ except Exception:
|
|
|
167
167
|
_attach_gtypes_stubs(gtypes)
|
|
168
168
|
genai.types = gtypes
|
|
169
169
|
sys.modules['google.genai.types'] = gtypes
|
|
170
|
+
|
|
171
|
+
# Provide a minimal nacl.public stub if PyNaCl is not installed. This prevents
|
|
172
|
+
# import-time failures in tests that import `roksta.firebase` which does
|
|
173
|
+
# `from nacl.public import PublicKey, SealedBox`.
|
|
174
|
+
try:
|
|
175
|
+
import nacl.public # type: ignore
|
|
176
|
+
except Exception:
|
|
177
|
+
# Create lightweight stub modules to satisfy `from nacl.public import PublicKey, SealedBox`
|
|
178
|
+
nacl = _types_mod.ModuleType('nacl')
|
|
179
|
+
nacl_public = _types_mod.ModuleType('nacl.public')
|
|
180
|
+
|
|
181
|
+
class PublicKey:
|
|
182
|
+
def __init__(self, data):
|
|
183
|
+
# Accept bytes-like input; ensure it's bytes when possible.
|
|
184
|
+
try:
|
|
185
|
+
self._data = bytes(data)
|
|
186
|
+
except Exception:
|
|
187
|
+
self._data = data
|
|
188
|
+
|
|
189
|
+
def __repr__(self):
|
|
190
|
+
try:
|
|
191
|
+
length = len(self._data)
|
|
192
|
+
except Exception:
|
|
193
|
+
length = 'unknown'
|
|
194
|
+
return f"<PublicKey len={length}>"
|
|
195
|
+
|
|
196
|
+
class SealedBox:
|
|
197
|
+
def __init__(self, public_key):
|
|
198
|
+
self.public_key = public_key
|
|
199
|
+
|
|
200
|
+
def encrypt(self, plaintext: bytes) -> bytes:
|
|
201
|
+
# Return deterministic bytes so callers can base64-encode the result.
|
|
202
|
+
if not isinstance(plaintext, (bytes, bytearray)):
|
|
203
|
+
plaintext = str(plaintext).encode('utf-8')
|
|
204
|
+
return b"STUB_ENCRYPTED:" + bytes(plaintext)
|
|
205
|
+
|
|
206
|
+
nacl_public.PublicKey = PublicKey
|
|
207
|
+
nacl_public.SealedBox = SealedBox
|
|
208
|
+
# Attach the submodule on the parent module object for attribute access
|
|
209
|
+
nacl.public = nacl_public
|
|
210
|
+
sys.modules['nacl'] = nacl
|
|
211
|
+
sys.modules['nacl.public'] = nacl_public
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
# tests.functions.
|
|
1
|
+
# tests.functions.api_v1_00 package marker
|
|
2
2
|
# Allows tests under this directory to be imported with package-qualified names.
|
|
@@ -176,12 +176,11 @@ sys.modules['httpx'] = httpx_mod
|
|
|
176
176
|
# -----------------------------
|
|
177
177
|
repo_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
|
|
178
178
|
functions_root = os.path.join(repo_root, 'functions')
|
|
179
|
-
module_path = os.path.join(functions_root, '
|
|
180
|
-
spec = importlib.util.spec_from_file_location('
|
|
179
|
+
module_path = os.path.join(functions_root, 'api_v1_00', '_analytics.py')
|
|
180
|
+
spec = importlib.util.spec_from_file_location('api_v1_00._analytics', module_path)
|
|
181
181
|
_analytics = importlib.util.module_from_spec(spec)
|
|
182
182
|
spec.loader.exec_module(_analytics)
|
|
183
183
|
|
|
184
|
-
|
|
185
184
|
# Restore original sys.modules mappings to avoid side-effects for other tests
|
|
186
185
|
for name, orig in _orig_sys_modules.items():
|
|
187
186
|
if orig is None:
|
|
@@ -19,6 +19,8 @@ if FUNCTIONS_DIR not in sys.path:
|
|
|
19
19
|
_orig_sys_modules = {}
|
|
20
20
|
_names_to_fake = [
|
|
21
21
|
'firebase_functions',
|
|
22
|
+
'firebase_admin',
|
|
23
|
+
'firebase_admin.firestore',
|
|
22
24
|
'utils',
|
|
23
25
|
'auth',
|
|
24
26
|
'google',
|
|
@@ -49,6 +51,35 @@ class FakeResponse:
|
|
|
49
51
|
firebase_functions.https_fn = types.SimpleNamespace(Request=object, Response=FakeResponse)
|
|
50
52
|
sys.modules['firebase_functions'] = firebase_functions
|
|
51
53
|
|
|
54
|
+
# Fake firebase_admin and its firestore submodule to satisfy optional imports in the proxy
|
|
55
|
+
firebase_admin = types.ModuleType('firebase_admin')
|
|
56
|
+
firestore_mod = types.ModuleType('firebase_admin.firestore')
|
|
57
|
+
|
|
58
|
+
# Minimal Client type for annotations and a no-op client() factory
|
|
59
|
+
class _DummyClient: # pragma: no cover - just a stub for import-time type hints
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
def _dummy_client():
|
|
63
|
+
# Return a simple object; logic using it is patched in tests
|
|
64
|
+
return types.SimpleNamespace()
|
|
65
|
+
|
|
66
|
+
# Decorator stub used by perform_atomic_debit; never actually invoked in tests
|
|
67
|
+
def _transactional(fn=None):
|
|
68
|
+
def wrapper(*args, **kwargs):
|
|
69
|
+
return fn(*args, **kwargs)
|
|
70
|
+
return wrapper
|
|
71
|
+
|
|
72
|
+
# Populate stubs on the firestore module
|
|
73
|
+
setattr(firestore_mod, 'Client', _DummyClient)
|
|
74
|
+
setattr(firestore_mod, 'client', _dummy_client)
|
|
75
|
+
setattr(firestore_mod, 'transactional', _transactional)
|
|
76
|
+
setattr(firestore_mod, 'SERVER_TIMESTAMP', object())
|
|
77
|
+
|
|
78
|
+
# Attach firestore submodule to firebase_admin package and register in sys.modules
|
|
79
|
+
setattr(firebase_admin, 'firestore', firestore_mod)
|
|
80
|
+
sys.modules['firebase_admin'] = firebase_admin
|
|
81
|
+
sys.modules['firebase_admin.firestore'] = firestore_mod
|
|
82
|
+
|
|
52
83
|
# Fake utils module (provides functions imported by _gemini_proxy)
|
|
53
84
|
utils_mod = types.ModuleType('utils')
|
|
54
85
|
|
|
@@ -118,14 +149,14 @@ sys.modules['google.genai'] = genai_mod
|
|
|
118
149
|
sys.modules['google.genai.types'] = types_mod
|
|
119
150
|
|
|
120
151
|
# Import the module under test after preparing the fake imports
|
|
152
|
+
# Resolve the actual repository 'functions' directory (tests files live under tests/, so climb up to repo root)
|
|
121
153
|
repo_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
|
|
122
154
|
functions_root = os.path.join(repo_root, 'functions')
|
|
123
|
-
module_path = os.path.join(functions_root, '
|
|
124
|
-
spec = importlib.util.spec_from_file_location('
|
|
155
|
+
module_path = os.path.join(functions_root, 'api_v1_00', '_gemini_proxy.py')
|
|
156
|
+
spec = importlib.util.spec_from_file_location('api_v1_00._gemini_proxy', module_path)
|
|
125
157
|
_gemini = importlib.util.module_from_spec(spec)
|
|
126
158
|
spec.loader.exec_module(_gemini)
|
|
127
159
|
|
|
128
|
-
|
|
129
160
|
# Restore original sys.modules mappings to avoid side-effects for other tests
|
|
130
161
|
for name, orig in _orig_sys_modules.items():
|
|
131
162
|
if orig is None:
|
|
@@ -198,7 +229,9 @@ def test_invalid_auth_key_returns_403():
|
|
|
198
229
|
def test_non_post_method_returns_405():
|
|
199
230
|
headers = {_gemini.AUTH_HEADER_NAME: 'ok'}
|
|
200
231
|
req = DummyRequest(headers=headers, method='GET')
|
|
201
|
-
with patch.object(_gemini, 'validate_auth_key', return_value=True),
|
|
232
|
+
with patch.object(_gemini, 'validate_auth_key', return_value=True), \
|
|
233
|
+
patch.object(_gemini, 'verify_firebase_token', return_value={}), \
|
|
234
|
+
patch.object(_gemini, 'ensure_balance_positive', return_value=(True, 100.0)):
|
|
202
235
|
resp = _gemini._gemini_proxy(req)
|
|
203
236
|
|
|
204
237
|
assert resp.status_code == 405
|
|
@@ -210,7 +243,9 @@ def test_non_post_method_returns_405():
|
|
|
210
243
|
def test_malformed_json_returns_400():
|
|
211
244
|
headers = {_gemini.AUTH_HEADER_NAME: 'ok'}
|
|
212
245
|
req = DummyRequest(headers=headers, method='POST', raise_on_get_json=True)
|
|
213
|
-
with patch.object(_gemini, 'validate_auth_key', return_value=True),
|
|
246
|
+
with patch.object(_gemini, 'validate_auth_key', return_value=True), \
|
|
247
|
+
patch.object(_gemini, 'verify_firebase_token', return_value={}), \
|
|
248
|
+
patch.object(_gemini, 'ensure_balance_positive', return_value=(True, 100.0)):
|
|
214
249
|
resp = _gemini._gemini_proxy(req)
|
|
215
250
|
|
|
216
251
|
assert resp.status_code == 400
|
|
@@ -223,7 +258,9 @@ def test_rehydrate_params_error_returns_400():
|
|
|
223
258
|
headers = {_gemini.AUTH_HEADER_NAME: 'ok'}
|
|
224
259
|
# missing 'model' to cause KeyError inside rehydrate_params
|
|
225
260
|
req = DummyRequest(headers=headers, method='POST', json_data={'contents': 'x', 'config': {}})
|
|
226
|
-
with patch.object(_gemini, 'validate_auth_key', return_value=True),
|
|
261
|
+
with patch.object(_gemini, 'validate_auth_key', return_value=True), \
|
|
262
|
+
patch.object(_gemini, 'verify_firebase_token', return_value={}), \
|
|
263
|
+
patch.object(_gemini, 'ensure_balance_positive', return_value=(True, 100.0)):
|
|
227
264
|
resp = _gemini._gemini_proxy(req)
|
|
228
265
|
|
|
229
266
|
assert resp.status_code == 400
|
|
@@ -237,6 +274,7 @@ def test_get_api_key_failure_returns_500():
|
|
|
237
274
|
req = DummyRequest(headers=headers, method='POST', json_data={'model': 'g', 'contents': 'hi', 'config': {}})
|
|
238
275
|
with patch.object(_gemini, 'validate_auth_key', return_value=True), \
|
|
239
276
|
patch.object(_gemini, 'verify_firebase_token', return_value={}), \
|
|
277
|
+
patch.object(_gemini, 'ensure_balance_positive', return_value=(True, 100.0)), \
|
|
240
278
|
patch.object(_gemini, 'get_api_key', side_effect=Exception('boom')):
|
|
241
279
|
resp = _gemini._gemini_proxy(req)
|
|
242
280
|
|
|
@@ -258,12 +296,18 @@ def test_successful_flow_calls_genai_and_returns_payload():
|
|
|
258
296
|
|
|
259
297
|
def generate_content(self, **params):
|
|
260
298
|
class FakeResp:
|
|
299
|
+
def __init__(self):
|
|
300
|
+
# include usage metadata expected by get_usage()
|
|
301
|
+
self.usage_metadata = types.SimpleNamespace(prompt_token_count=1, total_token_count=2)
|
|
302
|
+
|
|
261
303
|
def to_json_dict(self_inner):
|
|
262
304
|
return { 'result': 'ok', 'received_model': params.get('model') }
|
|
263
305
|
return FakeResp()
|
|
264
306
|
|
|
265
307
|
with patch.object(_gemini, 'validate_auth_key', return_value=True), \
|
|
266
308
|
patch.object(_gemini, 'verify_firebase_token', return_value={}), \
|
|
309
|
+
patch.object(_gemini, 'ensure_balance_positive', return_value=(True, 100.0)), \
|
|
310
|
+
patch.object(_gemini, 'bill_with_retry', return_value=("ok", 99.5)), \
|
|
267
311
|
patch.object(_gemini, 'get_api_key', return_value='GEMINI-KEY'), \
|
|
268
312
|
patch.object(_gemini.genai, 'Client', FakeClient):
|
|
269
313
|
resp = _gemini._gemini_proxy(req)
|
|
@@ -297,6 +341,7 @@ def test_genai_exception_with_status_code_is_returned_as_error_status():
|
|
|
297
341
|
|
|
298
342
|
with patch.object(_gemini, 'validate_auth_key', return_value=True), \
|
|
299
343
|
patch.object(_gemini, 'verify_firebase_token', return_value={}), \
|
|
344
|
+
patch.object(_gemini, 'ensure_balance_positive', return_value=(True, 100.0)), \
|
|
300
345
|
patch.object(_gemini, 'get_api_key', return_value='GEMINI-KEY'), \
|
|
301
346
|
patch.object(_gemini.genai, 'Client', ErrClient):
|
|
302
347
|
resp = _gemini._gemini_proxy(req)
|
|
@@ -108,13 +108,42 @@ openai_mod.APIError = APIError
|
|
|
108
108
|
sys.modules['openai'] = openai_mod
|
|
109
109
|
|
|
110
110
|
# Import the module under test after preparing the fake imports
|
|
111
|
+
#_generic = importlib.import_module('_generic_proxy')
|
|
112
|
+
|
|
111
113
|
repo_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
|
|
112
114
|
functions_root = os.path.join(repo_root, 'functions')
|
|
113
|
-
module_path = os.path.join(functions_root, '
|
|
114
|
-
spec = importlib.util.spec_from_file_location('
|
|
115
|
+
module_path = os.path.join(functions_root, 'api_v1_00', '_generic_proxy.py')
|
|
116
|
+
spec = importlib.util.spec_from_file_location('api_v1_00._generic_proxy', module_path)
|
|
115
117
|
_generic = importlib.util.module_from_spec(spec)
|
|
116
118
|
spec.loader.exec_module(_generic)
|
|
117
119
|
|
|
120
|
+
# Patch Firestore client and billing functions to avoid external dependencies during tests
|
|
121
|
+
# Provide a dummy Firestore client and make balance checks/billing no-ops.
|
|
122
|
+
_generic.firestore = types.SimpleNamespace(client=lambda: object())
|
|
123
|
+
|
|
124
|
+
def _fake_ensure_balance_positive(db, user_id):
|
|
125
|
+
return True, 100.0
|
|
126
|
+
|
|
127
|
+
def _fake_extract_usage(llm_family=None, call_type=None, model_id=None, request_payload=None, response_payload=None):
|
|
128
|
+
# Default to zero-usage unless present in the payload
|
|
129
|
+
usage = response_payload.get('usage', {}) if isinstance(response_payload, dict) else {}
|
|
130
|
+
in_tokens = usage.get('prompt_tokens', 0) or usage.get('input_tokens', 0) or 0
|
|
131
|
+
out_tokens = usage.get('completion_tokens', 0) or usage.get('output_tokens', 0) or 0
|
|
132
|
+
return {"input_tokens": in_tokens, "output_tokens": out_tokens}
|
|
133
|
+
|
|
134
|
+
def _fake_calculate_cost(model_id=None, input_tokens=0, output_tokens=0):
|
|
135
|
+
return 0.0
|
|
136
|
+
|
|
137
|
+
def _fake_bill_with_retry(db=None, user_id=None, model_id=None, usage=None, cost=None, reason=None):
|
|
138
|
+
return "ok", 100.0
|
|
139
|
+
|
|
140
|
+
_generic.ensure_balance_positive = _fake_ensure_balance_positive
|
|
141
|
+
_generic.extract_usage = _fake_extract_usage
|
|
142
|
+
# Compatibility shim: some versions of the module call get_usage(response) instead of extract_usage(...)
|
|
143
|
+
_generic.get_usage = lambda response: _fake_extract_usage(response_payload=response)
|
|
144
|
+
_generic.calculate_cost = _fake_calculate_cost
|
|
145
|
+
_generic.bill_with_retry = _fake_bill_with_retry
|
|
146
|
+
|
|
118
147
|
# Restore original sys.modules mappings to avoid side-effects for other tests
|
|
119
148
|
for name, orig in _orig_sys_modules.items():
|
|
120
149
|
if orig is None:
|
|
@@ -186,8 +186,8 @@ sys.modules['ulid'] = ulid_mod
|
|
|
186
186
|
# Load the module directly from the functions/ tree so the test's fake sys.modules entries are respected
|
|
187
187
|
repo_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
|
|
188
188
|
functions_root = os.path.join(repo_root, 'functions')
|
|
189
|
-
module_path = os.path.join(functions_root, '
|
|
190
|
-
spec = importlib.util.spec_from_file_location('
|
|
189
|
+
module_path = os.path.join(functions_root, 'api_v1_00', '_get_payment_details.py')
|
|
190
|
+
spec = importlib.util.spec_from_file_location('api_v1_00._get_payment_details', module_path)
|
|
191
191
|
_get_payment_details = importlib.util.module_from_spec(spec)
|
|
192
192
|
spec.loader.exec_module(_get_payment_details)
|
|
193
193
|
|