Repository navigation
release(v0.1.0-beta.7): core refactor, testing framework, and auth - #85
Merged
Merged
Conversation
…ecks - Replaced ENVIRONMENT string with DEBUG boolean in settings and templates - Updated JWT security check to use DEBUG instead of ENVIRONMENT - Updated main.py template to display debug status instead of environment - Updated .env template to use DEBUG=True instead of ENVIRONMENT=development
- Simplified class name from ZCoreCoreSettings to Settings - Updated all references in config.py and dependent modules - Cleaner, more intuitive API surface
- Replaced individual context functions (get_current_user_id, set_restricted_fields, etc.) with ZContext class - Added ctx singleton with property-based accessors (user_id, restricted_fields) - Added scope() context manager for temporary state overrides - Removed request_context, user_context, restricted_fields_context functions - Updated middleware, search engine, api_router, and projection to use ctx - Exported ZContext and ctx in __init__.py - Updated imports throughout codebase
…s dependency - Converted Inject function to class with __class_getitem__ returning Annotated[interface, Depends(Injector(interface))] - Updated service templates and routers to use Inject type marker - Replaced Inject() function calls in base_router with Depends(Injector()) - Updated storage provider dependency signature
…ery scoping
- Removed CreateSchemaType and UpdateSchemaType generic parameters from BaseRepository
- Replaced id-based get with dynamic criterion/filters in read mixin
- Added scope_query hook support for model-level query scoping
- Added count() method for filtered record counting
- Updated get/update/delete methods to use get(**{pk_name: id}) pattern
- Consolidated query extension logic into _apply_filters helper
- Removed CreateSchemaType and UpdateSchemaType generic parameters from BaseService - Updated get() to accept dynamic *criterion and **filters instead of fixed id - Added count() method forwarding to repository - Updated exist(), get_list() to support dynamic filters - Simplified docstrings and removed redundant parameter descriptions
… class - Merged hashing.py and jwt.py into security.py under Security class - Added generate_secure_token and hash_sha256 helper methods - Exported Security from zcore.__init__ and security.__init__ - Removed separate function exports from security.__init__
- Introduced BaseAuth class with template method pattern for authentication - Integrated cache lookups with BaseCache and TTL support - Automatically binds user data to ZContext (user_id, restricted_fields, etc.) - Added identity_claim, token_type, and cache_prefix customization - Exported BaseAuth from zcore.__init__ and security.__init__
- Modified pre_create and pre_update hooks to return Optional[Dict[str, Any]] - Merged hook return values with method-level **extra_data in create/update - Updated repository create/update to accept **extra_data for dynamic fields - Allows context-derived data (e.g., user_id from ctx) to be injected at service layer
- Added action field to ZContext via ZCoreAPIRoute (post/get/put/patch/delete)
- Enhanced Zchema._get_relative_restricted_paths to support action-scoped restrictions
- Added _sort_routes() to avoid dynamic routes shadowing static endpoints (e.g., /search)
- Updated route paths to use {id:uuid} for stricter matching
- Propagated **kwargs through endpoint methods for future extensibility
- Added on_event decorator to mark service methods as event subscribers - Added register_listeners() to inspect and bind decorated methods via IoC container - Exported on_event and EventDispatcher from zcore.__init__ and kernel.__init__ - Improved docstrings and error isolation in event dispatch
- Added _register_query_logger() to intercept and log SQL queries with duration - Bypass low-level metadata queries to reduce noise - Disabled SQLAlchemy echo in favor of structured logging pipeline - Enhanced setup_logging() with DEBUG mode toggle and Rich traceback support - Suppressed duplicate loggers from uvicorn and sqlalchemy.engine
- HasScopes now checks ctx.get('scopes') before falling back to user.scopes
- Removed all_scopes property from UserProtocol (scopes now sourced from context or user)
- Improved scope type coercion (list/tuple/frozenset/str → set)
- Updated imports to use zcore.exceptions and zcore.context
- ZCoreAPIRoute now reads 'action' from openapi_extra for per-route override - Falls back to default method-to-action mapping (post→create, get→view, etc.) - Sets the resolved action in ZContext for Zchema pruning and permissions
- Added genenv subcommand with --output and --force options - Resolves active Settings class by inspecting subclasses or IoC container - Writes environment variable template with field names and default values - Attempts to import user's main module to discover custom Settings
- Added genenv CLI subcommand to generate .env template from Settings - Refactored test_context to use ZContext and ctx.scope - Updated test_security to use unified Security class (hashing + JWT) - Removed anyio markers from CLI tests (sync-only) - Added clean_endpoint_signature to strip **kwargs in test_web - Fixed monkeypatches and imports across test modules
… simplify dependency injection (#74) ## Description This PR introduces three major architectural refactorings across the `zcore` core modules to reduce boilerplate, enhance type safety, and simplify request-scoped state handling. ### Key Changes: - **Unified Context Management (`ZContext`):** Replaced individual context functions (`get_current_user_id`, `set_restricted_fields`, `user_context`, etc.) with a cohesive `ZContext` class and a globally exported `ctx` singleton. Added support for localized state overrides via the `ctx.scope()` context manager, and updated downstream consumers (middleware, search engines, projection utilities, and routers) to use this centralized context manager. - **Simplified Dependency Injection (`Inject`):** Converted the `Inject` helper function into a dynamic class supporting python generic subscripting (`__class_getitem__`). This enables clean `Annotated` dependency markers in routers and service templates (e.g., `provider: Inject[StorageProvider]`) instead of direct functional dependencies. - **Clean Config API:** Renamed the base settings class from `ZCoreCoreSettings` to `Settings`. Replaced the string-based `ENVIRONMENT` configuration with a simpler boolean `DEBUG` flag across configuration settings, template layouts, and production safety checks in the JWT signer. Fixes # (issue number) ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [x] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [x] Refactoring (architectural or code cleanup with no functional changes) - [ ] Documentation update ## How Has This Been Tested? Please describe the tests that you ran to verify your changes. - [ ] Unit/Integration tests (`hatch run test`) - [ ] Static type check passing (`mypy src/`) ## Checklist: - [x] My code follows the style guidelines and architectural rules of this project - [x] I have performed a self-review of my own code - [x] My changes pass strict static type analysis (`mypy src/` generates no warnings) - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation (under `docs/`) - [x] My changes generate no new runtime warnings - [x] I have added tests that prove my fix is effective or that my feature works
…ties (#75) ## Description This PR introduces substantial simplification to the generic parameters of the data layers (Repositories and Services) and consolidates cryptographic utilities under a single unified security coordinator. ### Key Changes: - **Simplified Repository Generics & Dynamic Queries (`repository.py`):** Removed `CreateSchemaType` and `UpdateSchemaType` generic signatures from `BaseRepository` and `WriteRepositoryMixin` to support raw `BaseModel` classes instead. Refactored the `get`, `exist`, and `get_list` query paths to accept positional binary expression arguments (`*criterion`) and key-value keyword filters (`**filters`) consolidated via a new `_apply_filters` helper. Added a `count()` method mapping subqueries directly to `func.count()`. - **Simplified Service Generics & Dynamic Queries (`service/base.py`):** Removed generic schema types from `BaseService` matching the repository layer. Updated `get()`, `exist()`, and `get_list()` to forward dynamic criteria (`*criterion`, `**filters`) downstream. Added a new `count()` forwarding method. - **Consolidated Security Management (`security/`):** Deleted separate files `hashing.py` and `jwt.py`. Merged Argon2id password-hashing routines and PyJWT-based token encoding/decoding into static/class methods within a unified `Security` class. Added secure cryptographic token generation and SHA-256 digesting helpers. Fixes # (issue number) ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [x] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [x] Refactoring (architectural or code cleanup with no functional changes) - [ ] Documentation update ## How Has This Been Tested? The internal unit tests have been updated to align with the streamlined generic base class signatures and the new unified `Security` namespace. - [ ] Unit/Integration tests (`hatch run test`) - [ ] Static type check passing (`mypy src/`) ## Checklist: - [x] My code follows the style guidelines and architectural rules of this project - [x] I have performed a self-review of my own code - [x] My changes pass strict static type analysis (`mypy src/` generates no warnings) - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation (under `docs/`) - [x] My changes generate no new runtime warnings - [x] I have added tests that prove my fix is effective or that my feature works
…ropagation (#76) ## Description This PR introduces two major features designed to streamline user authentication and dynamic data propagation during write operations: 1. **Generic Authentication Base Layer (`BaseAuth`):** - Added a generic, template-driven `BaseAuth` dependency class to handle token extraction, decoding (via the `Security` class), and user object validation. - Integrated TTL-supported caching using `BaseCache` to reduce redundant database queries for user identity resolution. - Implemented automatic context binding that maps resolved user parameters directly onto the thread/coroutine-safe `ZContext` (`ctx.user_id`, `ctx.restricted_fields`, and extra fields). 2. **Dynamic Service-to-Repository Hook Propagation:** - Modified `pre_create` and `pre_update` service hooks to optionally return a dictionary (`Optional[Dict[str, Any]]`). - Enhanced `create` and `update` orchestrations in `BaseService` to merge the dictionary returned by pre-hooks with route-level `**extra_data` parameters. - Updated `BaseRepository` to accept `**extra_data` inside `create` and `update` methods, dynamically merging context-derived values (like `user_id` retrieved from `ctx`) directly into database entities before flushing. Fixes # (issue number) ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [x] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [x] Refactoring (architectural or code cleanup with no functional changes) - [ ] Documentation update ## How Has This Been Tested? These changes have been validated by adapting local auth and database transaction flows. - [ ] Unit/Integration tests (`hatch run test`) - [ ] Static type check passing (`mypy src/`) ## Checklist: - [x] My code follows the style guidelines and architectural rules of this project - [x] I have performed a self-review of my own code - [x] My changes pass strict static type analysis (`mypy src/` generates no warnings) - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation (under `docs/`) - [x] My changes generate no new runtime warnings - [x] I have added tests that prove my fix is effective or that my feature works
… query logging (#77) ## Description This PR introduces enhancements to core system subsystems, focusing on event-driven mechanics, runtime log telemetry, SQL query tracing, and routing path strictness: 1. **Dynamic Event Dispatching (`kernel/events.py`):** - Introduced the `@on_event` decorator to tag service methods as subscribers to target event channels. - Added `register_listeners()` inside `EventDispatcher` to inspect service classes and dynamically resolve subscriber instances from the IoC container. - Improved asynchronous dispatch concurrency with robust exception boundaries and isolated handler logging. 2. **SQL Connection Telemetry & Structured Logging (`db/setup.py`, `logging/config.py`):** - Added connection-level cursor event interceptors (`before_cursor_execute` and `after_cursor_execute`) to measure, format, and log SQL query durations in milliseconds. - Configured catalog filters to bypass standard low-level Postgres metadata queries (`pg_catalog`, standard strings, etc.), reducing log noise. - Disabled raw, duplicate SQLAlchemy echo logging in favor of unified `structlog` pipelines. Added Rich traceback recovery in `DEBUG` mode. 3. **Action-Scoped State & Path Strictness (`web/api_router.py`, `web/base_router.py`, `web/projection.py`):** - Injected the current API action (e.g., `create`, `view`, `update`) dynamically into `ZContext` during HTTP route interception. - Updated `Zchema` path-pruning utility to calculate relative restricted fields based on the active route action context (e.g., allowing specific fields to be hidden selectively on list vs. detail views). - Enforced route-sorting mechanisms (`_sort_routes`) to ensure static endpoints like `/search` are not shadowed by parameterized path matching. - Tightened resource routing parameters by strictly enforcing `{id:uuid}` signatures. ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [x] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [x] Refactoring (architectural or code cleanup with no functional changes) - [ ] Documentation update ## How Has This Been Tested? These features have been validated by verifying uvicorn request logs, running runtime execution traces under debug environments, and checking schema generation behaviors. - [ ] Unit/Integration tests (`hatch run test`) - [ ] Static type check passing (`mypy src/`) ## Checklist: - [x] My code follows the style guidelines and architectural rules of this project - [x] I have performed a self-review of my own code - [x] My changes pass strict static type analysis (`mypy src/` generates no warnings) - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation (under `docs/`) - [x] My changes generate no new runtime warnings - [ ] I have added tests that prove my fix is effective or that my feature works
## Description
This PR introduces dynamic security scope resolution during permission
validation, decouples scope storage from the core user protocols, and
adds robust type coercion for permission comparisons.
### Key Changes:
- **Dynamic Context Scope Fallback (`permissions.py`):** Updated the
`HasScopes` permission validator to dynamically retrieve scopes from
`ZContext` via `ctx.get("scopes")`. If context-level scopes are absent,
it safely falls back to standard user-level scopes (`getattr(user,
"scopes", None)`).
- **Scope Type Coercion (`permissions.py`):** Introduced a coercion step
to sanitize scopes incoming as `list`, `tuple`, `frozenset`, or a single
`str` into a standardized python `set` before executing subset checks.
- **Protocol Simplification (`protocols.py`):** Removed the deprecated
`all_scopes` property from the `UserProtocol` definition, offloading
scope compilation and resolution logic entirely onto request-scoped
contexts.
- **Import Cleanup:** Structured import paths to use unified entry
points under `zcore.context` and `zcore.exceptions`.
Fixes # (issue number)
## Type of change
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [x] Refactoring (architectural or code cleanup with no functional
changes)
- [ ] Documentation update
## How Has This Been Tested?
These changes have been validated by verifying dynamic scope resolution
behavior during context overrides and ensuring permission assertions
evaluate successfully.
- [ ] Unit/Integration tests (`hatch run test`)
- [ ] Static type check passing (`mypy src/`)
## Checklist:
- [x] My code follows the style guidelines and architectural rules of
this project
- [x] I have performed a self-review of my own code
- [x] My changes pass strict static type analysis (`mypy src/` generates
no warnings)
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation (under
`docs/`)
- [x] My changes generate no new runtime warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
## Description
This PR introduces the ability to override route-level actions using
OpenAPI metadata, enabling more granular control over dynamic context
resolution and schema pruning:
### Key Changes:
- **Custom Action Override (`api_router.py`):** Updated `ZCoreAPIRoute`
to inspect `openapi_extra` for an explicit `"action"` key during request
interception.
- **REST-to-CRUD Fallback Mapping (`api_router.py`):** Maintained the
default mapping mechanism (e.g., `POST` ➡️ `create`, `GET` ➡️ `view`) as
a fallback if no explicit override is provided in `openapi_extra`.
- **ZContext Propagation:** Binds the resolved action (whether
overridden or default) to the active execution context via
`ctx.set("action", custom_action)`. This directly supports action-scoped
permissions and context-aware schema pruning (via `Zchema`).
Fixes # (issue number)
## Type of change
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [x] Refactoring (architectural or code cleanup with no functional
changes)
- [ ] Documentation update
## How Has This Been Tested?
These changes have been validated by verifying custom action key
resolution via the FastAPI `openapi_extra` payload and testing
schema-pruning boundaries under custom actions.
- [ ] Unit/Integration tests (`hatch run test`)
- [ ] Static type check passing (`mypy src/`)
## Checklist:
- [x] My code follows the style guidelines and architectural rules of
this project
- [x] I have performed a self-review of my own code
- [x] My changes pass strict static type analysis (`mypy src/` generates
no warnings)
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation (under
`docs/`)
- [x] My changes generate no new runtime warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
## Description This PR introduces the `genenv` CLI subcommand to automatically generate a template `.env` file based on the application's active Pydantic settings schema: ### Key Changes: - **New CLI Command (`cli/__init__.py`):** Added the `genenv` subcommand with configurable command-line arguments: `-o`/`--output` (defaults to `.env.example`) and `-f`/`--force` (to overwrite existing output files). - **Settings Class Discovery (`cli/commands.py`):** Implemented automatic resolution of the project's active `Settings` schema. It dynamically attempts to discover custom user settings by importing the parent module, falling back to registered IoC container settings or subclass lookups. - **Environment Template Generation (`cli/commands.py`):** Parses Pydantic model fields from the resolved settings class. It formats default values, ensures boolean parameters map cleanly to string configurations, leaves undefined/empty variables blank, and serializes the list as a standard template file. Fixes # (issue number) ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] Refactoring (architectural or code cleanup with no functional changes) - [ ] Documentation update ## How Has This Been Tested? This feature has been tested locally by invoking `zc genenv` within temporary project paths to verify successful module importing, settings class evaluation, and output serialization. - [ ] Unit/Integration tests (`hatch run test`) - [ ] Static type check passing (`mypy src/`) ## Checklist: - [x] My code follows the style guidelines and architectural rules of this project - [x] I have performed a self-review of my own code - [x] My changes pass strict static type analysis (`mypy src/` generates no warnings) - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation (under `docs/`) - [x] My changes generate no new runtime warnings - [ ] I have added tests that prove my fix is effective or that my feature works
…cks (#81) ## Description This PR migrates the test suite of the `zcore` framework to align with the recent refactorings in context management, unified security, and simplified generics. It ensures that all test suites are updated to maintain robust test coverage: ### Key Changes: - **Test Context Migration (`test_context.py` & `test_search.py`):** Refactored the context tests to validate behaviors using `ZContext` and the `ctx.scope()` context manager instead of the deprecated, standalone thread-local variables. - **Security Test Adaptation (`test_security.py`):** Migrated password hashing and JWT encoding/decoding tests to utilize the unified `Security` coordinator class. Updated mock protocols to match the removal of `all_scopes` from the user protocol interface. - **Data & Service Mocks (`test_repository.py` & `test_service.py`):** Updated test repository configurations and mock definitions to match the simplified generics of `BaseRepository` (using a single model parameter). Standardized query calls to use keyword arguments (e.g., `repo.get(id=...)`). - **Synchronous CLI Tests (`test_cli.py`):** Removed redundant `anyio` async markers from CLI execution test cases since command-line tools are run synchronously. - **Dynamic Endpoint Signature Stripper (`test_web.py`):** Introduced a helper utility `clean_endpoint_signature` to dynamically inspect and reconstruct FastAPI router endpoint parameters. This isolates testing frameworks from argument mapping errors related to the new `**kwargs` route signatures. - **Config Mocks (`conftest.py` & `test_config.py`):** Refactored settings initialization to use the simplified `Settings` class instead of the deprecated `ZCoreCoreSettings`. Fixes # (issue number) ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [x] Refactoring (architectural or code cleanup with no functional changes) - [ ] Documentation update ## How Has This Been Tested? This PR directly addresses the test suite itself. The modified tests are designed to execute and pass cleanly under Hatch and Mypy. - [x] Unit/Integration tests (`hatch run test`) - [x] Static type check passing (`mypy src/`) ## Checklist: - [x] My code follows the style guidelines and architectural rules of this project - [x] I have performed a self-review of my own code - [x] My changes pass strict static type analysis (`mypy src/` generates no warnings) - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation (under `docs/`) - [x] My changes generate no new runtime warnings - [x] I have added tests that prove my fix is effective or that my feature works
…xtures - Introduced ZTestFixture abstract base class with setUp/tearDown methods - Added ContainerSandbox fixture to snapshot and restore DI container state - Added DatabaseRollback fixture for transaction-scoped database testing - Added UserContext fixture to set user_id, scopes, and extra context in ZContext - Added DependencyOverride fixture for FastAPI dependency overrides - Added AppLifespan fixture to manage lifespan context during tests - Added ZTest composite fixture to orchestrate multiple fixtures
…rchestration - Introduced ZTestClient to manage test fixtures (ContainerSandbox, AppLifespan, DatabaseRollback, UserContext, DependencyOverride) - Added BaseZTest abstract class with run() context manager for easy client setup - Supports user context, scopes, superuser status, and custom user attributes - Provides isolated database transaction rollback and DI container snapshots
- Introduced ZTestFixture base class with setUp/tearDown lifecycle hooks - Added ContainerSandbox to snapshot and restore DI container state - Added DatabaseRollback for transaction-scoped database isolation - Added UserContext fixture to set user_id, scopes, and extra context in ZContext - Added DependencyOverride for FastAPI dependency overrides in tests - Added AppLifespan fixture to manage application lifespan context - Added ZTest composite orchestrator for combining multiple fixtures - Added ZTestClient to orchestrate all fixtures and provide httpx AsyncClient - Added BaseZTest abstract class with run() context manager for simplified test setup
- Added --test flag to startapp subcommand to optionally generate test files - Added TEST_TEMPLATE with a basic async test using ZTestClient - Updated start_app function signature to accept with_test parameter - Fixed PORT env parsing in run_server (elif → if correction) - Updated CLI output to reflect clean template generation messaging
- Added tests for DatabaseRollback isolation and transaction rollback - Added tests for ContainerSandbox snapshot and restore functionality - Added tests for UserContext with user_id, scopes, and superuser mocking - Added tests for extra_user_attrs and extra_context injection - Added BaseZTest class-based test execution example - Included dummy FastAPI app and database setup for integration testing
- Added tests for LRU eviction, inline expiration, thread safety, and weakref GC - Added tests for TTL reset on overwrite, explicit delete, and prefix isolation - Added async tests for cache global lifecycle (init/close), double init, and delete fallback - Added test for corrupt JSON deserialization handling - Fixed Redis client shutdown by replacing close() with aclose()
…alization - Introduced ZCoreJSONResponse using json_dumps for custom encoding - Updated app_exception_handler to return ZCoreJSONResponse instead of JSONResponse - Added comprehensive exception handler tests: - Custom AppException subclass with 402 status - Complex payload serialization (UUID, datetime, Decimal) - Null boundary values and strict ResponseWrapper validation - Logging integration verification
…patching - Added TrackedPlugin fail_phase parameter to test errors in setup, before_startup, on_startup, after_startup, and on_shutdown - Added tests for empty kernel, self-dependency, multiple independent chains, and redundant dependencies - Added tests for exception handling in each lifecycle phase with proper rollback verification - Added test for shutdown failure robustness - Added test for EventDispatcher registration via DI container - Added test for inter-plugin event dispatching across lifecycle phases
- Added tests for suppressing third-party duplicate handlers - Added rich integration test with debug mode detection - Verified shared processor chain integrity (contextvars, log level, timestamp) - Added dynamic log level configuration (DEBUG vs INFO) - Added contextvars binding verification and factory/caching config tests - Updated exception handler to use ZCoreJSONResponse for custom encoding
- Added UUID primary key test model and tests for cursor pagination - Added page number pagination tests for sorting, invalid fields, empty DB, out-of-bounds, exact multiples - Added cursor pagination tests for empty DB, invalid fields, exact transitions, UUID fields - Added tests for timezone normalization, string fields, malformed cursor handling - Added drift prevention test for cursor pagination
…features - Added tests for exist(), count(), get_by_ids() with fields/options - Added update_multi() with partial updates and refresh flag - Added delete_single() and create_multi() without refresh - Added page number pagination with sorting validation - Added cursor pagination with invalid cursor handling - Added search engine tests with complex AND/ilike filters - Added security violation test for restricted field blocking - Added scope_query row-level isolation test for model scoping
- Added richer test models with datetime, boolean, UUID, and relationships (Profile, Post, Comment) - Added tests for comparison operators (lt, le, ge, in, is_null) - Added type coercion tests for datetime, UUID, and boolean fields - Added wildcard escaping tests for LIKE/ILIKE operators - Added relation traversal tests (one-to-one, one-to-many) - Added custom field handler registration test - Added security restriction tests for nested fields and relationship paths - Added invalid sort field validation, pagination query building, and empty request tests - Added complex logical filter combination test (OR with nested AND)
- Fixed model_fields access in BaseAuth to use type(user_data) - Added tests for BaseAuth success, cache hit, inactive user, invalid token type - Added tests for JWT asymmetric flow, token expiration, and invalid structure - Added tests for cryptographic helpers, custom Argon2 parameters, and permission coercions - Added test for object-level permission and superuser bypass behavior
- Added tests for post_get and post_get_multi hooks - Added test for pre_create extra_data merging with hook return dict - Added tests for create_multi, update_multi, delete, delete_multi hooks - Added tests for search pre/post hooks with and without pagination - Added test for post_create error rollback - Extended HookTrackingService to cover all lifecycle hooks - Verified pre hooks can return dict for extra payload injection - Verified entity not found raises EntityNotFound in get/update/delete
- Added tests for successful upload and stream upload - Added collision prevention and auto-directory creation tests - Added delete success and non-existent delete tests - Added FileExtensionValidator with case-insensitive, blocked, missing, and double-extension tests - Added mime fallback and mime read error tests - Added storage OS permission error test - Added storage provider dependency resolution test - Fixed post_create error rollback assertion in service test
… coverage - Added tests for init_stream_redis and lazy background task startup - Added Redis message routing, malformed message robustness, and cleanup on empty queues - Added subscription context manager normal and error path tests - Added multi-user isolation and garbage collection on queue overflow - Added robust unsubscribe for nonexistent queues - Added active Redis publish and fallback to local queue on publish error
…framework - Added AppLifespan fixture tests with lifespan event tracking - Added DatabaseRollback uninitialized engine and nested commit rollback tests - Added ContainerSandbox deep restore test for singleton and scoped services - Added ZTest orchestrator setup/teardown order verification - Added UserContext exception safety and nested ZTestClient context isolation tests - Added dependency override preservation test - Updated engine setup to use module-level async event listeners for proper transaction isolation
- Added tests for custom JSON encoder fallback, nested mixed types, decimal precision, circular reference, and kwargs - Added slugify tests for Unicode Persian, empty/whitespace, newlines, and multiple separators - Added schema validation tests for detailed error payload, corrupt schema, array constraints, and additionalProperties
…d middleware - Added full CRUD endpoint tests for BaseRouter with pagination and search - Added Zchema nested and wildcard pruning tests - Added schema exposure tests with restricted field pruning for GET and POST - Added request ID validation and pattern fallback tests - Added ScopedDependencyMiddleware lifecycle tests with session resolution - Added ZCoreRequest body caching tests - Added route sorting test to prevent dynamic path shadowing - Added StreamManager pub/sub lifecycle tests including queue overflow handling - Added exception translation handler test for EntityNotFound
… scaffolding support (#82) ## Description This PR introduces a comprehensive testing infrastructure for the `ZCore` framework, aimed at simplifying integration and unit testing with reusable, asynchronous fixtures. It provides isolated database transactions, dependency injection state sandboxing, user security context mocking, and CLI generator support. ### Key Additions & Changes: 1. **Core Testing Fixture Framework (`src/zcore/testing/fixtures.py`)**: - `ZTestFixture`: Abstract base class defining `setUp` and `tearDown` lifecycles. - `ContainerSandbox`: Snapshots and restores the dependency injection (DI) container's state to prevent test pollution. - `DatabaseRollback`: Manages connection-level transactions, wrapping tests in a database rollback to ensure database isolation. - `UserContext`: Injects `user_id`, scopes, and arbitrary extra context into the global `ZContext`. - `DependencyOverride`: Utility to safely override FastAPI dependencies during test execution. - `AppLifespan`: Handles the startup and shutdown lifecycle hooks of the FastAPI application. - `ZTest`: A composite orchestrator to chain and manage multiple fixtures sequentially. 2. **Integration Test Client (`src/zcore/testing/client.py`)**: - `ZTestClient`: An asynchronous test client extending `httpx.AsyncClient` that coordinates the setup and teardown of the testing fixtures. - `BaseZTest`: An abstract class providing a clean class-based test structure using the `run()` context manager. 3. **CLI Enhancements (`src/zcore/cli/`)**: - Added a `--test` flag to the `startapp` command to scaffold boilerplate test files automatically using a pre-defined template (`TEST_TEMPLATE`). - Resolved a small bug in `run_server` regarding `PORT` environment variable parsing (corrected `elif` to `if` logic). 4. **Test Suite (`tests/test_testing_subsystem.py`)**: - Added thorough functional tests validating database rollback isolation, DI container sandboxing, user security and context mocking, and the class-based test runner. Fixes # (Leave blank if there is no specific issue tracker ID) ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] Refactoring (architectural or code cleanup with no functional changes) - [ ] Documentation update ## How Has This Been Tested? The newly added test suite was executed to verify the functionality of the fixtures and the `ZTestClient`: - Run the test suite: `pytest tests/test_testing_subsystem.py` to assert correct rollback logic, sandbox behavior, context injection, and dependency overrides. - Verified manual CLI scaffold execution using `python -m zcore.cli startapp <app_name> --test`. - [x] Unit/Integration tests (`hatch run test`) - [x] Static type check passing (`mypy src/`) ## Checklist: - [x] My code follows the style guidelines and architectural rules of this project - [x] I have performed a self-review of my own code - [x] My changes pass strict static type analysis (`mypy src/` generates no warnings) - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation (under `docs/`) - [x] My changes generate no new runtime warnings - [x] I have added tests that prove my fix is effective or that my feature works
…refinements (#83) ## Description This PR introduces a massive expansion of the unit and integration test suite across the entire `ZCore` ecosystem. The goal of this change is to secure stable behavior, handle edge cases, and ensure robust architectural patterns. Additionally, this PR introduces standardized exception serialization refinements. ### Key Changes: 1. **Exceptions & Serialization Subsystem**: - Introduced `ZCoreJSONResponse` using custom `json_dumps` for serialization. - Updated `app_exception_handler` to return `ZCoreJSONResponse` instead of the standard `JSONResponse`. - Added comprehensive testing for custom `AppException` subclasses, handling complex payloads (e.g., UUID, datetime, Decimal), strict response wrapper validation, and log integration. 2. **Database, Repository, and Search Engine**: - Added database lifecycle tests checking uninitialized engine access and transaction session exceptions. - Added Unit of Work (UOW) test coverage verifying rollback on commit failure, graceful event handler failures, and state preservation. - Expanded repository integration tests: added cases for `exist()`, `count()`, multi-create/delete, custom page-number, and cursor pagination with invalid fields. - Strengthened search engine tests using complex models (datetime, relationships) and operators (`lt`, `le`, `ge`, `in`, `is_null`), and relation traversal rules. 3. **Core Framework Modules (DI, Context, Cache, Config & Kernel)**: - **DI**: Validated implicit auto-wiring chains, recursive structures, constructor signature caching, circular dependency detection, and scope isolation/clearing. - **Context**: Verified context-var based async task isolation, nested scopes, and dynamic property behavior in `ZContext`. - **Cache**: Added LRU eviction, TTL override, thread-safety, weakref GC, and prefix isolation tests. Fixed Redis connection shutdown logic by switching `close()` to `aclose()`. - **Config**: Verified environment type coercion, lazy proxy evaluation for Settings subclasses, and missing attributes. - **Kernel**: Checked plugin lifecycles, lifecycle exceptions rollback verification, and inter-plugin event dispatching. 4. **Security, Services, Storage, Streams & Web**: - **Security**: Added asymmetric JWT flows, permission coercions, object-level security bypass rules, and Argon2 configuration helpers. - **Service**: Tested all pre/post hooks, multi-operation hooks, and dynamic payload injections. - **Storage**: Tested directory auto-creation, upload collision prevention, `FileExtensionValidator`, and OS permission scenarios. - **Streams**: Added Redis pub/sub routing, malformed queue handling, subscription contexts, queue overflow isolation, and local queue fallbacks. - **Web**: Added full BaseRouter CRUD, nested `Zchema` pruning, Scoped Dependency Middleware resolution, and `ZCoreRequest` caching checks. 5. **CLI & Utilities**: - Expanded CLI coverage for default generation commands (`genenv`), collision prevention, `--test` flag scaffold generation, and subprocess mocking outside root. - Added helper tests for Unicode Persian slugification and strict schema validator boundaries. Fixes # (Leave blank if there is no specific issue tracker ID) ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [x] Refactoring (architectural or code cleanup with no functional changes) - [ ] Documentation update ## How Has This Been Tested? To verify the changes, the extended test suites were run across all components of the system: - Verified complete test coverage using `pytest` across all modified areas (cache, CLI, DI, config, context, DB, repository, search, security, service, storage, streams, web). - Confirmed correct asynchronous cleanup on third-party integrations (such as Redis connection closings). - [x] Unit/Integration tests (`hatch run test`) - [x] Static type check passing (`mypy src/`) ## Checklist: - [x] My code follows the style guidelines and architectural rules of this project - [x] I have performed a self-review of my own code - [x] My changes pass strict static type analysis (`mypy src/` generates no warnings) - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation (under `docs/`) - [x] My changes generate no new runtime warnings - [x] I have added tests that prove my fix is effective or that my feature works
- Deleted all documentation files (cheatsheet, features, how-to, learn) - Removed all image assets (banner, diagrams, logos, favicons) - Removed mkdocs.yml and overrides.css - Removed docs dependency group from pyproject.toml - Updated project URLs to point to new repository - Removed req.txt file
- Updated all GitHub and documentation URLs from fastapi-zcore-framework to Baseryn - Bumped badge links and CI workflow references to new repository - Refined feature descriptions for clarity and accuracy - Updated quick start example with UUID model and improved code snippets - Aligned CLI command descriptions with actual implementation - Replaced deprecated docs links with new documentation structure
- Changed hatch test command from hatch run test to hatch test - Updated documentation reference to point to zcore-docs repository
…#84) ## Description Decoupled in-tree documentation, image assets, and MkDocs build configuration from the core framework repository in favor of the dedicated standalone documentation repository ([`Baseryn/zcore-docs`](https://github.com/Baseryn/zcore-docs)). **Key changes:** - Removed all files under `docs/`, static assets, custom CSS overrides, and `mkdocs.yml`. - Removed the `docs` optional dependency group from `pyproject.toml` and removed legacy `req.txt`. - Deleted the automated documentation build workflow (`.github/workflows/docs.yml`). - Updated all badges, repository URLs, documentation links, and issue tracker targets in `README.md` and `pyproject.toml` to the `Baseryn` organization. - Refined `README.md` feature descriptions, code examples (UUID model migration), and CLI command references. - Updated `.github/PULL_REQUEST_TEMPLATE.md` test commands (`hatch test`) and checklist references to point to `zcore-docs`. Fixes # ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [x] Refactoring (architectural or code cleanup with no functional changes) - [x] Documentation update ## How Has This Been Tested? - [x] Unit/Integration tests (`hatch test`) - [x] Static type check passing (`mypy src/`) ## Checklist: - [x] My code follows the style guidelines and architectural rules of this project - [x] I have performed a self-review of my own code - [x] My changes pass strict static type analysis (`mypy src/` generates no warnings) - [ ] I have commented my code, particularly in hard-to-understand areas - [x] I have updated the documentation in `zcore-docs` if applicable - [x] My changes generate no new runtime warnings - [x] I have added tests that prove my fix is effective or that my feature works
- Modernize type hints across modules using Python 3.11+ syntax (UP) - Explicitly bind loop variables in dynamic event listener registration (B023) - Replace try-except-pass blocks with contextlib.suppress (SIM105) - Fix implicit Optional type annotation in ResponseWrapper (RUF013) - Organize and sort imports across the codebase (I001) - Configure ruff rules and line-length settings in pyproject.toml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This pull request merges the
release/v0.1.0-beta.7branch intomaster, delivering a major milestone release for ZCore. It introduces architectural simplifications to dependency injection and data layers, a brand new testing fixture framework (ZTestClient), unified security and context management, event dispatching, structured SQL telemetry, and the externalization of documentation.Key Architectural Highlights & Changes:
Unified Context Management & Dynamic Scopes (
zcore.context):ZContextand globalctxsingleton with property accessors (user_id,restricted_fields,action) and scoped overrides (ctx.scope()).HasScopesvia context fallbacks and robust scope type coercion.Simplified Dependency Injection & Configuration (
zcore.di,zcore.config):Injectmarker to support subscript syntax (Inject[T]), bridging directly to FastAPI'sDepends(Injector(T))for constructor auto-wiring.ZCoreCoreSettingstoSettingsand replacedENVIRONMENTstrings with booleanDEBUGflags.zc genenvCLI command to introspectSettingsand scaffold.env.example.Data Layer Generics & Hook Propagation (
repository,service):CreateSchemaType,UpdateSchemaType) fromBaseRepositoryandBaseService.*criterion,**filters) andcount()query methods.pre_create,pre_update) to return dictionaries that dynamically merge context data into repository mutations.Security & Authentication Layer (
zcore.security):Securitycoordinator class.BaseAuthtemplate dependency with built-inBaseCacheintegration and automaticZContextbinding.Event Dispatcher, Routing & SQL Telemetry:
@on_eventdecorator with IoC-backed subscriber auto-registration inEventDispatcher.ZContextviaZCoreAPIRoutewithopenapi_extraoverride support and strict route ordering.ZCoreJSONResponse(supporting UUID, datetime, Decimal).Comprehensive Testing Infrastructure (
zcore.testing):ZTestFixtureframework:ContainerSandbox,DatabaseRollback,UserContext,DependencyOverride, andAppLifespan.ZTestClient(built onhttpx.AsyncClient) andBaseZTestfor class-based integration testing with automatic transaction rollbacks.--testflag tozc startappfor automated test scaffolding.Test Suite Expansion & Decoupled Documentation:
docs/and MkDocs configuration in favor ofBaseryn/zcore-docsand updated organization metadata.Type of change
How Has This Been Tested?
hatch test)mypy src/)Checklist:
mypy src/generates no warnings)zcore-docs