Skip to content

feat/token test modernization#2

Merged
ralflang merged 8 commits intoFRAMEWORK_6_0from
feat/token-test-modernization
Mar 7, 2026
Merged

feat/token test modernization#2
ralflang merged 8 commits intoFRAMEWORK_6_0from
feat/token-test-modernization

Conversation

@ralflang
Copy link
Member

@ralflang ralflang commented Mar 3, 2026

  • chore(qc): run quality check and improve .gitignore
  • test: modernize to PHPUnit 11-13, reorganize test structure
  • test: add mock storage infrastructure for PSR-4 conversion
  • test: enable SQL database tests with horde/test and horde/db
  • feat: implement PSR-4 core classes with clean architecture
  • feat: add PSR-0 compatibility shims for backward compatibility
  • chore: remove accidentally committed phpunit cache file
  • style: apply PHP CS Fixer formatting fixes

ralflang added 8 commits March 3, 2026 06:43
Run horde-components qc --fix:
- PHP CS Fixer: Add blank line after opening PHP tags
- .gitignore: Add vendor/, composer.lock, .phpunit.result.cache
- .gitignore: Add build artifacts, IDE settings, tool caches

Prevents accidental commits of:
- Composer dependencies (vendor/, composer.lock)
- PHPUnit cache (.phpunit.result.cache)
- Build artifacts (/build/)
- IDE settings (.idea/, .vscode/)
- Tool caches (.php-cs-fixer.cache, .phpstan.cache/)

QC Results:
- Syntax: ✅ Pass
- PHP CS Fixer: ✅ Fixed
- PHPUnit: ⚠️ 60 tests, 5 failed, 15 errors (pre-existing)
- PHPStan: ⚠️ 67 errors at level 1 (will fix during PSR-4 conversion)

Ready for PSR-4 conversion.
- Upgrade phpunit.xml.dist to PHPUnit 11+ schema (11.5)
- Reorganize tests: test/Unit/Legacy/, test/Db/
- Separate DB persistence tests (test/Db/) from business logic tests
- Update BackendTestCase to use PHPUnit\Framework\TestCase
- Add getConfig() helper for legacy test compatibility
- Fix PHP 8.4 dynamic property deprecation in FileTest
- Add PHPUnit 11.5 to require-dev
- Create modern test/bootstrap.php
- Update namespaces: Horde\Token\Test\Unit\Legacy, Horde\Token\Test\Db
- All 20 unit tests passing (FileTest)
- Database tests properly skipped when adapters unavailable

Architectural improvement: Separating DB persistence concerns from
domain logic tests to enable cleaner PSR-4 conversion with proper
separation of concerns.
Add mock storage interfaces to decouple token business logic from
database implementation:

- TokenStorageInterface: Abstract storage contract
- InMemoryTokenStorage: In-memory implementation for tests
- test/README.md: Document test architecture and future direction

This mock infrastructure enables:
- Testing token logic without DB dependencies
- Clean separation of business logic from persistence
- Proper architecture for PSR-4 conversion

NOTE: This mocking pattern should be migrated to Horde\Db once
that package is modernized, as tight coupling of DB access to
business logic is an architectural issue from Horde 3/4 era.

The test architecture now separates:
- Business logic tests (test/Unit/) - Fast, no DB required
- Persistence tests (test/Db/) - Integration with real adapters

This separation will enable redesigning the domain layer during
PSR-4 conversion and potentially splitting database access in
the next major version.
- Add horde/test and horde/db to require-dev
- Fix migration path in SqlTest (test/Db/ to migration/)
- SQL tests now running: 20 tests passing
- MongoDB tests properly skipped (no MongoDB available)

Test results:
- Unit tests: 20 passing (FileTest)
- SQL tests: 20 passing (SqlTest with SQLite)
- Mongo tests: 20 skipped (MongoDB not available)
- Total: 40 tests passing, 20 skipped

Note: One deprecation in horde/db vendor code (parent::execute callable),
not in Token code.
Implement complete PSR-4 token generation and validation with
separation of concerns, dependency injection, and comprehensive tests.

Core Implementation:
- TokenGenerator: Pure token generation logic (no storage)
- TokenValidator: Validation logic with pluggable storage
- Token: Main facade with factory methods
- TokenConfig: Immutable configuration value object
- GeneratedToken: Value object for generated tokens

Storage Layer:
- TokenStorageInterface: Storage contract
- FileStorage: File-based token storage
- SqlStorage: SQL database storage (Horde_Db)
- NullStorage: No-op storage (no replay protection)
- InMemoryStorage: In-memory storage for testing

Internal Utilities:
- Nonce: Cryptographically secure nonce generation
- Signer: HMAC-SHA256 signing
- Encoder: Base64 URL-safe encoding/decoding

Exceptions:
- TokenException (base)
- InvalidTokenException
- ExpiredTokenException
- UsedTokenException
- StorageException

Tests:
- TokenGeneratorTest: 8 tests, 16 assertions ✅
- TokenValidatorTest: 11 tests, 12 assertions ✅
- Total new tests: 19 passing

Documentation:
- doc/UPGRADING.md: Comprehensive 500+ line migration guide
- Inline PHPDoc for all public APIs
- Examples throughout

Architecture Benefits:
- ✅ Zero coupling between logic and storage
- ✅ Easy to test (DI + mock storage)
- ✅ Type-safe (PHP 8.1+ strict types)
- ✅ Immutable value objects
- ✅ PER-1 compliant
- ✅ Clean namespace organization

Breaking Changes:
- Requires PHP 8.1+ (was 7.4+)
- Removed horde/* dependencies (self-contained)
- PSR-4 autoloading added to composer.json

Test Results:
- New PSR-4 tests: 19/19 passing
- Legacy PSR-0 tests: 40/40 passing (20 unit + 20 SQL)
- Total: 59 tests passing, 20 skipped (MongoDB)
Implement complete PSR-0 compatibility layer that delegates to
PSR-4 implementation, enabling gradual migration.

Updated Files:
- lib/Horde/Token.php: Static generateId() delegates to PSR-4
- lib/Horde/Token/Base.php: Abstract base delegates to PSR-4
- lib/Horde/Token/File.php: File storage shim
- lib/Horde/Token/Sql.php: SQL storage shim
- lib/Horde/Token/Null.php: Null storage shim

Key Features:
- ✅ Full API compatibility with PSR-0 (2.x)
- ✅ All methods delegate to PSR-4 implementation
- ✅ Proper exception mapping (PSR-4 → PSR-0)
- ✅ Zero code duplication
- ✅ Deprecation notices for developers

API Mapping:
- get($seed) → TokenGenerator::generate($seed)->token
- isValid($token, $seed, $timeout, $unique) → TokenValidator
- validate($token, $seed) → TokenValidator (with exception mapping)
- validateUnique($token, $seed) → TokenValidator::validateUnique()
- verify($token) → Storage::exists() + add()
- getNonce() → Nonce::generate()->bytes()

Test Results:
- PSR-0 Legacy Tests: 20/20 passing ✅
- PSR-4 Unit Tests: 19/19 passing ✅
- SQL Integration: 20/20 passing ✅
- Total: 79 tests, 70 assertions, all passing
- Only 1 deprecation (in horde/db vendor code, not ours)

Migration Path:
1. Applications using PSR-0 continue working unchanged
2. New code can use PSR-4 API directly
3. Gradual migration without breaking changes
4. PSR-0 can be removed in Token 4.0

Example Compatibility:
```php
// PSR-0 (still works)
$token = new Horde_Token_File(['secret' => 'abc', 'token_dir' => '/tmp']);
$str = $token->get('form');
$token->validate($str, 'form');

// PSR-4 (new way)
$token = Token::file('abc', '/tmp');
$generated = $token->generate('form');
$token->validateUnique($generated->token, 'form');
```
- Add space before arrow function parameter list (PER-1 compliance)
- Add blank line after opening PHP tag in bootstrap
@ralflang ralflang merged commit 12c9ebc into FRAMEWORK_6_0 Mar 7, 2026
0 of 6 checks passed
ralflang added a commit that referenced this pull request Mar 7, 2026
Release version 3.0.0-alpha6

Merge pull request #2 from horde/feat/token-test-modernization
style: apply PHP CS Fixer formatting fixes
chore: remove accidentally committed phpunit cache file
feat: add PSR-0 compatibility shims for backward compatibility
feat: implement PSR-4 core classes with clean architecture
test: enable SQL database tests with horde/test and horde/db
test: add mock storage infrastructure for PSR-4 conversion
test: modernize to PHPUnit 11-13, reorganize test structure
chore(qc): run quality check and improve .gitignore
Create README.md
Development mode for Token-3.0.0alpha5
Released Token-3.0.0alpha4
Update metadata and workflows for PHP 8 support
Add CI job for satis repo update
no errors, added ci.yml, adapted bootstrap.php
no errors left
ten errors left (probably because of connection config)
WIP 10 errors left, namespaces not adjustable yet, uncaught Exceptions are triggered at uncertain points WIP
Development mode for Token-3.0.0alpha5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants