727d86614e
P0 (7): Auth-bypass removed, migrations fixed, plugin-upload disabled, RLS FORCE+WITH CHECK, plugin double-registration fixed, persistent volume, domain removed P1 (11): User/tenant model, Redis centralized, worker separated, transactional outbox, XSS fixed, DMS chunked streaming, permissions unified, password reset, metrics secured, config/docs fixed, cross-tenant FK P2 (4): Contact model normalized, cross-imports reduced 94%, commands+state machines for contacts/dms/mail/calendar, SPA path-traversal 8 new migrations, 99 unit tests, 13 commands, 8 contracts, 72 files changed
62 lines
2.9 KiB
Markdown
62 lines
2.9 KiB
Markdown
# Test Report — P2-3: Commands und Statusmaschinen Phase 1
|
|
|
|
## Task
|
|
Implement Command Pattern for Contacts domain + State Machine for Contact and Workflow entities.
|
|
|
|
## Files Created
|
|
- `app/commands/__init__.py` — Command package init
|
|
- `app/commands/base.py` — CommandResult + BaseCommand (template method pattern)
|
|
- `app/commands/contact_commands.py` — Create/Update/Delete/Merge contact commands
|
|
- `app/core/state_machine.py` — Generic StateMachine + Contact/Workflow state definitions
|
|
- `tests/test_commands.py` — Tests for all commands and state machine
|
|
|
|
## Files Modified
|
|
- `app/routes/contacts.py` — Routes now use Commands instead of direct service calls
|
|
- `app/models/contact.py` — Added `status` field for state machine
|
|
- `app/schemas/contact.py` — Added `status` field to ContactCreate/ContactUpdate/ContactResponse
|
|
|
|
## Test Results
|
|
|
|
### State Machine Tests
|
|
- ✅ `test_can_transition_allowed` — valid transitions return True
|
|
- ✅ `test_can_transition_disallowed` — invalid transitions return False
|
|
- ✅ `test_transition_success` — valid transition returns new state
|
|
- ✅ `test_transition_invalid_raises` — invalid transition raises StateMachineError
|
|
- ✅ `test_transition_unknown_state_raises` — unknown state raises StateMachineError
|
|
- ✅ `test_workflow_state_machine_transitions` — workflow transitions correct
|
|
- ✅ `test_custom_state_machine` — custom transitions work
|
|
|
|
### CommandResult Tests
|
|
- ✅ `test_ok_result` — ok() creates successful result
|
|
- ✅ `test_ok_with_events` — ok() with events
|
|
- ✅ `test_fail_result` — fail() creates failed result
|
|
|
|
### CreateContactCommand Tests
|
|
- ✅ `test_create_contact_admin_success` — admin creates contact, audit + outbox event
|
|
- ✅ `test_create_contact_viewer_denied` — viewer denied
|
|
- ✅ `test_create_contact_with_invalid_status` — invalid status rejected
|
|
|
|
### UpdateContactCommand Tests
|
|
- ✅ `test_update_contact_admin_success` — admin updates contact, audit + outbox event
|
|
- ✅ `test_update_contact_not_found` — not found error
|
|
- ✅ `test_update_contact_viewer_denied` — viewer denied
|
|
|
|
### DeleteContactCommand Tests
|
|
- ✅ `test_soft_delete_contact_admin_success` — soft delete works, audit created
|
|
- ✅ `test_hard_delete_contact_admin_success` — hard delete works, event enqueued
|
|
- ✅ `test_delete_contact_not_found` — not found error
|
|
- ✅ `test_delete_contact_viewer_denied` — viewer denied
|
|
|
|
### MergeContactsCommand Tests
|
|
- ✅ `test_merge_contacts_admin_success` — merge works, audit + outbox event
|
|
- ✅ `test_merge_same_contact_fails` — self-merge rejected
|
|
- ✅ `test_merge_contacts_viewer_denied` — viewer denied
|
|
- ✅ `test_merge_contact_not_found` — not found error
|
|
|
|
## Compilation Check
|
|
`python -m py_compile` on all new/modified files.
|
|
|
|
## Smoke Test
|
|
Commands execute correctly when called directly with AsyncSession and Redis client.
|
|
State machine validates transitions and raises on invalid attempts.
|