tigrbl_tests 0.3.10.dev1__tar.gz → 0.3.10.dev2__tar.gz

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.
Files changed (257) hide show
  1. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/PKG-INFO +1 -1
  2. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/pyproject.toml +1 -1
  3. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_mountable_lens_uvicorn.py +1 -1
  4. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_v3_default_rpc_ops.py +115 -0
  5. tigrbl_tests-0.3.10.dev2/tests/unit/test_jsonrpc_openrpc.py +122 -0
  6. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_openapi_openrpc_schema_separation.py +21 -0
  7. tigrbl_tests-0.3.10.dev1/tests/unit/test_jsonrpc_openrpc.py +0 -60
  8. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/LICENSE +0 -0
  9. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/README.md +0 -0
  10. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/__init__.py +0 -0
  11. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/conftest.py +0 -0
  12. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/hooks/test_hook_ctx_phase_validation.py +0 -0
  13. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/__init__.py +0 -0
  14. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_acronym_route_name.py +0 -0
  15. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_allow_anon.py +0 -0
  16. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_apikey_generation.py +0 -0
  17. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_authn_provider_integration.py +0 -0
  18. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_bindings_integration.py +0 -0
  19. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_bindings_modules.py +0 -0
  20. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_bulk_docs_client.py +0 -0
  21. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_core_access.py +0 -0
  22. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_engine_install_uvicorn.py +0 -0
  23. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_engine_resolver_uvicorn.py +0 -0
  24. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_error_mappings.py +0 -0
  25. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_field_spec_effects.py +0 -0
  26. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_header_io_uvicorn.py +0 -0
  27. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_healthz_methodz_hookz.py +0 -0
  28. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_hook_ctx_v3_i9n.py +0 -0
  29. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_hook_lifecycle.py +0 -0
  30. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_iospec_attributes.py +0 -0
  31. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_iospec_integration.py +0 -0
  32. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_jsonrpc_batch_behavior.py +0 -0
  33. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_key_digest_uvicorn.py +0 -0
  34. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_list_filters_optional.py +0 -0
  35. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_mixins.py +0 -0
  36. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_mountable_favicon_uvicorn.py +0 -0
  37. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_mountable_openapi_uvicorn.py +0 -0
  38. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_mountable_openrpc_uvicorn.py +0 -0
  39. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_mountable_swagger_uvicorn.py +0 -0
  40. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_nested_path_schema_and_rpc.py +0 -0
  41. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_nested_routing_depth.py +0 -0
  42. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_op_ctx_alias_examples.py +0 -0
  43. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_op_ctx_behavior.py +0 -0
  44. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_op_ctx_core_crud_order.py +0 -0
  45. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_openapi_clear_response_schema.py +0 -0
  46. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_openapi_schema_examples_presence.py +0 -0
  47. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_opspec_effects_i9n_test.py +0 -0
  48. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_owner_tenant_policy.py +0 -0
  49. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_request_extras.py +0 -0
  50. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_request_extras_provider.py +0 -0
  51. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_response_extras_provider.py +0 -0
  52. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_rest_fallback_serialization.py +0 -0
  53. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_rest_row_serialization.py +0 -0
  54. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_rest_rpc_parity_v3.py +0 -0
  55. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_row_result_serialization.py +0 -0
  56. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_schema.py +0 -0
  57. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_schema_ctx_attributes_integration.py +0 -0
  58. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_schema_ctx_op_ctx_integration.py +0 -0
  59. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_schema_ctx_spec_integration.py +0 -0
  60. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_sqlite_attachments.py +0 -0
  61. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_storage_spec_integration.py +0 -0
  62. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_symmetry_parity.py +0 -0
  63. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_tigrbl_api_app_usage_uvicorn.py +0 -0
  64. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_tigrbl_api_usage_uvicorn.py +0 -0
  65. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_tigrbl_api_uvicorn.py +0 -0
  66. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_tigrbl_app_include_api_uvicorn.py +0 -0
  67. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_tigrbl_app_multi_api_uvicorn.py +0 -0
  68. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_tigrbl_app_usage_uvicorn.py +0 -0
  69. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_tigrbl_app_uvicorn.py +0 -0
  70. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_v3_bulk_rest_endpoints.py +0 -0
  71. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_v3_default_rest_ops.py +0 -0
  72. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_v3_opspec_attributes.py +0 -0
  73. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/test_verb_alias_policy.py +0 -0
  74. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/i9n/uvicorn_utils.py +0 -0
  75. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/mount/__init__.py +0 -0
  76. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/mount/test_mount_favico.py +0 -0
  77. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/parity/__init__.py +0 -0
  78. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/parity/test_stdapi_openapi_docs.py +0 -0
  79. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/parity/test_stdapi_primitives.py +0 -0
  80. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/parity/test_stdapi_routing.py +0 -0
  81. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/perf/__init__.py +0 -0
  82. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/perf/test_collect_caching.py +0 -0
  83. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/perf/test_hookz_performance.py +0 -0
  84. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/perf/test_methodz_performance.py +0 -0
  85. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/request/test_request_asgi_scope_compat.py +0 -0
  86. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/request/test_request_dot_notation.py +0 -0
  87. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/request/test_request_response_conveniences.py +0 -0
  88. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/request/test_request_transport_convenience_dot_notation.py +0 -0
  89. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/requests/test_request_json_modes.py +0 -0
  90. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/response/test_response_dot_notation.py +0 -0
  91. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/response/test_response_transport_convenience_dot_notation.py +0 -0
  92. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/security/test_dot_notation_schemes.py +0 -0
  93. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/security/test_schemes.py +0 -0
  94. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/__init__.py +0 -0
  95. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/decorators/test_alias_ctx_bindings.py +0 -0
  96. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/decorators/test_engine_ctx_bindings.py +0 -0
  97. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/decorators/test_hook_ctx_bindings.py +0 -0
  98. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/decorators/test_op_alias_bindings.py +0 -0
  99. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/decorators/test_op_ctx_bindings.py +0 -0
  100. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/decorators/test_response_ctx_bindings.py +0 -0
  101. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/decorators/test_schema_ctx_bindings.py +0 -0
  102. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/response_utils.py +0 -0
  103. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/runtime/atoms/test_emit_paired_post.py +0 -0
  104. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/runtime/atoms/test_emit_paired_pre.py +0 -0
  105. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/runtime/atoms/test_emit_readtime_alias.py +0 -0
  106. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/runtime/atoms/test_out_masking.py +0 -0
  107. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/runtime/atoms/test_refresh_demand.py +0 -0
  108. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/runtime/atoms/test_resolve_assemble.py +0 -0
  109. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/runtime/atoms/test_resolve_paired_gen.py +0 -0
  110. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/runtime/atoms/test_schema_collect_in.py +0 -0
  111. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/runtime/atoms/test_schema_collect_out.py +0 -0
  112. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/runtime/atoms/test_storage_to_stored.py +0 -0
  113. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/runtime/atoms/test_wire_build_in.py +0 -0
  114. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/runtime/atoms/test_wire_build_out.py +0 -0
  115. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/runtime/atoms/test_wire_dump.py +0 -0
  116. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/runtime/atoms/test_wire_validate_in.py +0 -0
  117. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/runtime/test_events_phases.py +0 -0
  118. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_acol_vcol_knobs.py +0 -0
  119. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_alias_ctx_op_alias_attributes.py +0 -0
  120. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_alias_ctx_op_attributes.py +0 -0
  121. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_api_level_set_auth.py +0 -0
  122. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_app_model_defaults.py +0 -0
  123. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_app_reexport.py +0 -0
  124. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_base_columnspec_inheritance.py +0 -0
  125. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_base_facade_initialize.py +0 -0
  126. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_build_list_params_spec_model.py +0 -0
  127. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_bulk_body_annotation.py +0 -0
  128. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_bulk_response_schema.py +0 -0
  129. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_colspec_map_isolation.py +0 -0
  130. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_column_collect_mixins.py +0 -0
  131. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_column_rest_rpc_results.py +0 -0
  132. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_column_table_orm_binding.py +0 -0
  133. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_config_dataclass_none.py +0 -0
  134. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_core_crud_bulk_ops.py +0 -0
  135. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_core_crud_default_ops.py +0 -0
  136. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_core_crud_methods.py +0 -0
  137. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_core_wrap_memoization.py +0 -0
  138. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_db_dependency.py +0 -0
  139. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_decorator_and_collect.py +0 -0
  140. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_default_tags.py +0 -0
  141. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_engine_install_api.py +0 -0
  142. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_engine_install_app.py +0 -0
  143. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_engine_install_op.py +0 -0
  144. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_engine_install_table.py +0 -0
  145. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_engine_spec_and_shortcuts.py +0 -0
  146. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_engine_usage_levels.py +0 -0
  147. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_field_spec_attrs.py +0 -0
  148. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_file_response.py +0 -0
  149. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_get_schema.py +0 -0
  150. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_handler_step_qualname.py +0 -0
  151. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_hook_ctx_attributes.py +0 -0
  152. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_hook_ctx_binding.py +0 -0
  153. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_hookz_empty_phase.py +0 -0
  154. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_hybrid_session_run_sync.py +0 -0
  155. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_in_tx.py +0 -0
  156. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_include_model_columns_namespace.py +0 -0
  157. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_include_models_base_prefix.py +0 -0
  158. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_initialize_async_task.py +0 -0
  159. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_initialize_cross_ddl.py +0 -0
  160. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_initialize_mixed_engines.py +0 -0
  161. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_initialize_task_schedule.py +0 -0
  162. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_io_spec_attributes.py +0 -0
  163. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_iospec_attributes.py +0 -0
  164. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_iospec_effects.py +0 -0
  165. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_jsonrpc_id_example.py +0 -0
  166. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_jsonrpc_router_default_tag.py +0 -0
  167. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_kernel_invoke_ctx.py +0 -0
  168. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_kernel_opview_on_demand.py +0 -0
  169. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_kernel_plan_labels.py +0 -0
  170. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_kernelz_endpoint.py +0 -0
  171. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_make_column_shortcuts.py +0 -0
  172. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_middleware_http_and_cors.py +0 -0
  173. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_mixins_sqlalchemy.py +0 -0
  174. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_op_alias.py +0 -0
  175. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_op_class_engine_binding.py +0 -0
  176. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_op_ctx_arity_paths.py +0 -0
  177. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_op_ctx_attributes.py +0 -0
  178. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_op_ctx_core_crud_integration.py +0 -0
  179. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_op_ctx_dynamic_attach.py +0 -0
  180. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_op_ctx_persist_options.py +0 -0
  181. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_opspec_effects.py +0 -0
  182. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_postgres_engine_errors.py +0 -0
  183. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_postgres_env_vars.py +0 -0
  184. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_relationship_alias_cols.py +0 -0
  185. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_request_body_schema.py +0 -0
  186. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_request_response_examples.py +0 -0
  187. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_resolver_interning_warmup.py +0 -0
  188. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_resolver_precedence.py +0 -0
  189. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_response_alias_table_rpc.py +0 -0
  190. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_response_ctx_precedence.py +0 -0
  191. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_response_diagnostics_kernelz.py +0 -0
  192. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_response_html_jinja_behavior.py +0 -0
  193. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_response_parity.py +0 -0
  194. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_response_rest.py +0 -0
  195. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_response_rpc.py +0 -0
  196. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_response_template.py +0 -0
  197. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_response_uuid.py +0 -0
  198. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_rest_all_default_op_verbs.py +0 -0
  199. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_rest_bulk_delete_suppresses_clear.py +0 -0
  200. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_rest_no_schema_jsonable.py +0 -0
  201. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_rest_operation_id_uniqueness.py +0 -0
  202. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_rest_rpc_parity_default_ops.py +0 -0
  203. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_rest_rpc_prefixes.py +0 -0
  204. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_rest_rpc_symmetry.py +0 -0
  205. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_router_compatibility_shims.py +0 -0
  206. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_rpc_all_default_op_verbs.py +0 -0
  207. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_rpc_default_ops.py +0 -0
  208. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_schema_ctx_attributes.py +0 -0
  209. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_schema_ctx_plain_class.py +0 -0
  210. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_schema_spec_presence.py +0 -0
  211. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_schemas_binding.py +0 -0
  212. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_security_per_route.py +0 -0
  213. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_should_wire_canonical.py +0 -0
  214. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_spec_api.py +0 -0
  215. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_spec_app.py +0 -0
  216. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_spec_column.py +0 -0
  217. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_spec_engine.py +0 -0
  218. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_spec_field.py +0 -0
  219. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_spec_hook.py +0 -0
  220. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_spec_io.py +0 -0
  221. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_spec_op.py +0 -0
  222. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_spec_storage.py +0 -0
  223. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_spec_table.py +0 -0
  224. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_sqlite_attachments.py +0 -0
  225. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_sqlite_uuid_type.py +0 -0
  226. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_stdapi_request_injection.py +0 -0
  227. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_stdapi_transport_asgi_wsgi.py +0 -0
  228. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_storage_spec_attributes.py +0 -0
  229. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_sys_handler_crud.py +0 -0
  230. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_sys_run_rollback.py +0 -0
  231. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_sys_tx_async_begin.py +0 -0
  232. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_sys_tx_begin.py +0 -0
  233. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_sys_tx_commit.py +0 -0
  234. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_system_docs_builders.py +0 -0
  235. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_table_base_exports.py +0 -0
  236. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_table_collect_spec.py +0 -0
  237. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_table_columns_namespace.py +0 -0
  238. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_table_namespace_init.py +0 -0
  239. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_table_namespace_isolation.py +0 -0
  240. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_tigrbl_api_app_configuration.py +0 -0
  241. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_tigrbl_api_app_instantiation.py +0 -0
  242. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_tigrbl_api_app_subclass_definition.py +0 -0
  243. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_tigrbl_api_configuration.py +0 -0
  244. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_tigrbl_api_instantiation.py +0 -0
  245. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_tigrbl_api_subclass_definition.py +0 -0
  246. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_tigrbl_app_configuration.py +0 -0
  247. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_tigrbl_app_event_handlers.py +0 -0
  248. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_tigrbl_app_instantiation.py +0 -0
  249. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_tigrbl_app_state.py +0 -0
  250. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_tigrbl_app_subclass_definition.py +0 -0
  251. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_v3_favicon_endpoint.py +0 -0
  252. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_v3_healthz_endpoint.py +0 -0
  253. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_v3_op_alias.py +0 -0
  254. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_v3_op_ctx_attributes.py +0 -0
  255. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_v3_schemas_and_decorators.py +0 -0
  256. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_v3_storage_spec_attributes.py +0 -0
  257. {tigrbl_tests-0.3.10.dev1 → tigrbl_tests-0.3.10.dev2}/tests/unit/test_verbosity.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tigrbl_tests
3
- Version: 0.3.10.dev1
3
+ Version: 0.3.10.dev2
4
4
  Summary: Test suite and fixtures for the Tigrbl framework.
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "tigrbl_tests"
3
- version = "0.3.10.dev1"
3
+ version = "0.3.10.dev2"
4
4
  description = "Test suite and fixtures for the Tigrbl framework."
5
5
  license = "Apache-2.0"
6
6
  readme = "README.md"
@@ -26,7 +26,7 @@ async def test_lens_mountable_on_tigrbl_app_uvicorn():
26
26
  in response.text
27
27
  )
28
28
  assert (
29
- 'href="https://esm.sh/@tigrbljs/tigrbl-lens@latest/dist/tigrbl-lens.css"'
29
+ 'href="https://esm.sh/@tigrbljs/tigrbl-lens@latest/dist/tigrbl-lens.css?css"'
30
30
  in response.text
31
31
  )
32
32
  assert 'import { createRoot } from "react-dom/client";' in response.text
@@ -140,6 +140,96 @@ async def test_bulk_methods_absent(client_and_model):
140
140
  assert not hasattr(Gadget.rpc, name)
141
141
 
142
142
 
143
+ @pytest_asyncio.fixture()
144
+ async def wrapper_field_client_and_model():
145
+ Base3.metadata.clear()
146
+ Base3.registry.dispose()
147
+
148
+ class WrapperNamed(Base3):
149
+ __tablename__ = "wrapper_named"
150
+ __allow_unmapped__ = True
151
+
152
+ id: Mapped[int] = acol(
153
+ storage=S(type_=Integer, primary_key=True, autoincrement=True)
154
+ )
155
+ data: Mapped[str] = acol(
156
+ storage=S(type_=String, nullable=False),
157
+ field=F(required_in=("create",)),
158
+ io=IO(in_verbs=("create", "update"), out_verbs=("read", "list")),
159
+ )
160
+
161
+ __tigrbl_cols__ = {"id": id, "data": data}
162
+
163
+ app = Tigrblv3()
164
+ api = Tigrblv3(engine=mem())
165
+ api.include_model(WrapperNamed, prefix="")
166
+ api.mount_jsonrpc(prefix="/rpc")
167
+ await api.initialize()
168
+ app.include_router(api.router)
169
+ transport = ASGITransport(app=app)
170
+ client = AsyncClient(transport=transport, base_url="http://test")
171
+ try:
172
+ yield client, WrapperNamed
173
+ finally:
174
+ await client.aclose()
175
+
176
+
177
+ @pytest.mark.i9n
178
+ @pytest.mark.asyncio
179
+ async def test_rpc_create_allows_schema_defined_wrapper_like_fields(
180
+ wrapper_field_client_and_model,
181
+ ):
182
+ client, _ = wrapper_field_client_and_model
183
+ payload = {
184
+ "jsonrpc": "2.0",
185
+ "method": "WrapperNamed.create",
186
+ "params": {"data": "legit"},
187
+ "id": 99,
188
+ }
189
+
190
+ response = await client.post("/rpc", json=payload)
191
+
192
+ assert response.status_code == 200
193
+ body = response.json()
194
+ assert "error" not in body
195
+ assert body["result"]["data"] == "legit"
196
+
197
+
198
+ @pytest.mark.i9n
199
+ @pytest.mark.asyncio
200
+ @pytest.mark.parametrize("wrapper_key", ["data", "payload", "body", "item"])
201
+ async def test_rpc_create_rejects_wrapper_object(wrapper_key, client_and_model):
202
+ client, _ = client_and_model
203
+ payload = {
204
+ "jsonrpc": "2.0",
205
+ "method": "Gadget.create",
206
+ "params": {wrapper_key: {"name": "Wrapped", "age": 7}},
207
+ "id": 11,
208
+ }
209
+
210
+ response = await client.post("/rpc", json=payload)
211
+
212
+ assert response.status_code == 200
213
+ error = response.json()["error"]
214
+ assert error["code"] == -32602
215
+ assert error["message"] == "Invalid params"
216
+ assert error["data"]["disallowed_keys"] == [wrapper_key]
217
+
218
+
219
+ @pytest.mark.i9n
220
+ @pytest.mark.asyncio
221
+ @pytest.mark.parametrize("wrapper_key", ["data", "payload", "body", "item"])
222
+ async def test_rest_create_rejects_wrapper_object(wrapper_key, client_and_model):
223
+ client, _ = client_and_model
224
+
225
+ response = await client.post(
226
+ "/gadget",
227
+ json={wrapper_key: {"name": "Wrapped", "age": 7}},
228
+ )
229
+
230
+ assert response.status_code == 422
231
+
232
+
143
233
  @pytest_asyncio.fixture()
144
234
  async def bulk_client_and_model():
145
235
  Base3.metadata.clear()
@@ -184,6 +274,31 @@ async def bulk_client_and_model():
184
274
  await client.aclose()
185
275
 
186
276
 
277
+ @pytest.mark.i9n
278
+ @pytest.mark.asyncio
279
+ @pytest.mark.parametrize("wrapper_key", ["data", "payload", "body", "item"])
280
+ async def test_rpc_bulk_create_rejects_wrapper_object_items(
281
+ wrapper_key,
282
+ bulk_client_and_model,
283
+ ):
284
+ client, _ = bulk_client_and_model
285
+
286
+ payload = {
287
+ "jsonrpc": "2.0",
288
+ "method": "Gadget.bulk_create",
289
+ "params": [{wrapper_key: {"name": "Wrapped", "age": 7}}],
290
+ "id": 20,
291
+ }
292
+
293
+ response = await client.post("/rpc", json=payload)
294
+
295
+ assert response.status_code == 200
296
+ error = response.json()["error"]
297
+ assert error["code"] == -32602
298
+ assert error["message"] == "Invalid params"
299
+ assert error["data"]["disallowed_keys"] == [wrapper_key]
300
+
301
+
187
302
  @pytest.mark.i9n
188
303
  @pytest.mark.asyncio
189
304
  async def test_rpc_bulk_ops(bulk_client_and_model):
@@ -0,0 +1,122 @@
1
+ from httpx import ASGITransport, Client
2
+ from sqlalchemy import Column, String
3
+ from tigrbl import Base, TigrblApi, TigrblApp
4
+ from tigrbl.engine.shortcuts import mem
5
+ from tigrbl.orm.mixins import GUIDPk
6
+
7
+
8
+ def _build_app():
9
+ class Widget(Base, GUIDPk):
10
+ __tablename__ = "widgets_openrpc"
11
+ name = Column(String, nullable=False)
12
+
13
+ app = TigrblApp(engine=mem(async_=False))
14
+ app.include_model(Widget)
15
+ app.initialize()
16
+ app.mount_jsonrpc()
17
+ return app, Widget
18
+
19
+
20
+ def test_openrpc_endpoint_exposed():
21
+ app, _ = _build_app()
22
+ transport = ASGITransport(app=app)
23
+ with Client(transport=transport, base_url="http://test") as client:
24
+ response = client.get("/openrpc.json")
25
+
26
+ assert response.status_code == 200
27
+ payload = response.json()
28
+ assert payload["openrpc"] == "1.2.6"
29
+ assert payload["servers"] == [{"name": app.title, "url": "/rpc"}]
30
+ assert "methods" in payload
31
+
32
+
33
+ def test_openrpc_server_url_respects_jsonrpc_prefix():
34
+ app, _ = _build_app()
35
+ app.jsonrpc_prefix = "/rpc/custom"
36
+ transport = ASGITransport(app=app)
37
+
38
+ with Client(transport=transport, base_url="http://test") as client:
39
+ payload = client.get("/openrpc.json").json()
40
+
41
+ assert payload["servers"] == [{"name": app.title, "url": "/rpc/custom"}]
42
+
43
+
44
+ def test_openrpc_includes_method_schema():
45
+ app, model = _build_app()
46
+ transport = ASGITransport(app=app)
47
+ with Client(transport=transport, base_url="http://test") as client:
48
+ payload = client.get("/openrpc.json").json()
49
+ methods = {method["name"]: method for method in payload["methods"]}
50
+
51
+ create_method = methods[f"{model.__name__}.create"]
52
+ assert create_method["paramStructure"] == "by-name"
53
+
54
+ params = create_method["params"][0]["schema"]
55
+ assert params["title"].startswith(model.__name__)
56
+ assert "Create" in params["title"]
57
+
58
+ result = create_method["result"]["schema"]
59
+ assert result["title"].startswith(model.__name__)
60
+ assert "Response" in result["title"]
61
+
62
+
63
+ def test_mount_jsonrpc_updates_openrpc_server_url() -> None:
64
+ app, _ = _build_app()
65
+ app.mount_jsonrpc(prefix="/jsonrpc")
66
+ transport = ASGITransport(app=app)
67
+
68
+ with Client(transport=transport, base_url="http://test") as client:
69
+ payload = client.get("/openrpc.json").json()
70
+
71
+ assert payload["servers"] == [{"name": app.title, "url": "/jsonrpc"}]
72
+
73
+
74
+ def test_jsonrpc_create_accepts_nested_params_mapping() -> None:
75
+ app, model = _build_app()
76
+ transport = ASGITransport(app=app)
77
+
78
+ request_payload = {
79
+ "jsonrpc": "2.0",
80
+ "method": f"{model.__name__}.create",
81
+ "params": {"params": {"name": "New Widget"}},
82
+ "id": 1,
83
+ }
84
+
85
+ with Client(transport=transport, base_url="http://test") as client:
86
+ response = client.post("/rpc", json=request_payload)
87
+
88
+ assert response.status_code == 200
89
+ data = response.json()
90
+ assert data["id"] == 1
91
+ assert "error" not in data
92
+ assert data["result"]["name"] == "New Widget"
93
+
94
+
95
+ def test_mount_lens_uses_latest_openrpc_path_by_default() -> None:
96
+ app, _ = _build_app()
97
+ app.mount_openrpc(path="/schema/openrpc.json")
98
+ app.mount_lens(path="/lens-custom")
99
+
100
+ transport = ASGITransport(app=app)
101
+ with Client(transport=transport, base_url="http://test") as client:
102
+ html = client.get("/lens-custom").text
103
+
104
+ assert "/schema/openrpc.json" in html
105
+
106
+
107
+ def test_openrpc_server_url_respects_api_mount_jsonrpc_prefix_argument():
108
+ class Widget(Base, GUIDPk):
109
+ __tablename__ = "widgets_openrpc_api_mount_prefix"
110
+ name = Column(String, nullable=False)
111
+
112
+ api = TigrblApi(engine=mem(async_=False))
113
+ api.include_model(Widget)
114
+ api.initialize()
115
+ api.mount_jsonrpc(prefix="/jsonrpc")
116
+ api.mount_openrpc()
117
+
118
+ transport = ASGITransport(app=api)
119
+ with Client(transport=transport, base_url="http://test") as client:
120
+ payload = client.get("/openrpc.json").json()
121
+
122
+ assert payload["servers"] == [{"name": api.title, "url": "/jsonrpc"}]
@@ -48,3 +48,24 @@ def test_openrpc_schema_excludes_openapi_endpoint() -> None:
48
48
  method_names = {method["name"].lower() for method in payload["methods"]}
49
49
  assert all("openapi" not in name for name in method_names)
50
50
  assert all("openrpc" not in name for name in method_names)
51
+
52
+
53
+ def test_openapi_schema_excludes_openrpc_even_if_route_is_schema_visible() -> None:
54
+ app = _build_app()
55
+
56
+ def openrpc_override(_request):
57
+ return {"openrpc": "1.2.6"}
58
+
59
+ app.add_api_route(
60
+ "/openrpc.json",
61
+ openrpc_override,
62
+ methods=["GET"],
63
+ name="openrpc_json",
64
+ include_in_schema=True,
65
+ )
66
+
67
+ transport = ASGITransport(app=app)
68
+ with Client(transport=transport, base_url="http://test") as client:
69
+ payload = client.get("/openapi.json").json()
70
+
71
+ assert "/openrpc.json" not in payload["paths"]
@@ -1,60 +0,0 @@
1
- from httpx import ASGITransport, Client
2
- from sqlalchemy import Column, String
3
- from tigrbl import Base, TigrblApp
4
- from tigrbl.engine.shortcuts import mem
5
- from tigrbl.orm.mixins import GUIDPk
6
-
7
-
8
- def _build_app():
9
- class Widget(Base, GUIDPk):
10
- __tablename__ = "widgets_openrpc"
11
- name = Column(String, nullable=False)
12
-
13
- app = TigrblApp(engine=mem(async_=False))
14
- app.include_model(Widget)
15
- app.initialize()
16
- app.mount_jsonrpc()
17
- return app, Widget
18
-
19
-
20
- def test_openrpc_endpoint_exposed():
21
- app, _ = _build_app()
22
- transport = ASGITransport(app=app)
23
- with Client(transport=transport, base_url="http://test") as client:
24
- response = client.get("/openrpc.json")
25
-
26
- assert response.status_code == 200
27
- payload = response.json()
28
- assert payload["openrpc"] == "1.2.6"
29
- assert payload["servers"] == [{"name": app.title, "url": "/rpc"}]
30
- assert "methods" in payload
31
-
32
-
33
- def test_openrpc_server_url_respects_jsonrpc_prefix():
34
- app, _ = _build_app()
35
- app.jsonrpc_prefix = "/rpc/custom"
36
- transport = ASGITransport(app=app)
37
-
38
- with Client(transport=transport, base_url="http://test") as client:
39
- payload = client.get("/openrpc.json").json()
40
-
41
- assert payload["servers"] == [{"name": app.title, "url": "/rpc/custom"}]
42
-
43
-
44
- def test_openrpc_includes_method_schema():
45
- app, model = _build_app()
46
- transport = ASGITransport(app=app)
47
- with Client(transport=transport, base_url="http://test") as client:
48
- payload = client.get("/openrpc.json").json()
49
- methods = {method["name"]: method for method in payload["methods"]}
50
-
51
- create_method = methods[f"{model.__name__}.create"]
52
- assert create_method["paramStructure"] == "by-name"
53
-
54
- params = create_method["params"][0]["schema"]
55
- assert params["title"].startswith(model.__name__)
56
- assert "Create" in params["title"]
57
-
58
- result = create_method["result"]["schema"]
59
- assert result["title"].startswith(model.__name__)
60
- assert "Response" in result["title"]