Accounts — tests¶
Responsibilities¶
The accounts test suite verifies that the app behaves correctly at the model, service, serializer, and API levels.
It is responsible for testing:
- authentication and password flows
- device and session lifecycle behavior
- invite lifecycle behavior
- user profile, settings, and work schedule behavior
- skill directory and user-skill assignment flows
- signal-driven creation of related user records
The test suite is also responsible for protecting the refactored architecture:
- views stay thin
- services own business logic
- serializers enforce input validation
- models preserve derived behavior and constraints
Test structure¶
The current test strategy is intentionally split by layer.
API tests¶
These verify:
- route wiring
- permissions and authentication requirements
- request/response shape
- integration between views, serializers, and services
Examples:
- test_auth.py
- test_invites.py
- test_profile_api.py
- skill API tests
Service tests¶
These verify:
- business rules
- multi-step workflows
- state transitions
- side effects such as membership creation or email task dispatch
Examples:
- test_auth_services.py
- test_invite_services.py
Model tests¶
These verify:
- defaults
- derived properties
- string representations
- calculations such as effective weekly hours
Examples:
- test_user_signals.py
- profile/work schedule model tests
Main test groups¶
Authentication API tests¶
These tests verify the public auth endpoints.
Typical coverage: - login with username - login with email identifier - invalid credentials rejected - logout succeeds - logout-all endpoint responds correctly - users can view their devices - users cannot revoke sessions they do not own - password change endpoint works - forgot/reset password endpoints behave correctly
The API auth tests focus on endpoint behavior rather than duplicating all service-level business logic.
Authentication service tests¶
These tests verify the auth business workflows directly.
Typical coverage: - identifier resolution - login creates or updates device and creates session - invalid credentials raise service exceptions - logout revokes the correct session - logout-all revokes all active sessions - session revocation only works for owned sessions - password change updates stored password - password reset issuance queues the reset email task - password reset updates the password
These tests are the main protection for the auth service layer.
Invite API tests¶
These tests verify the invite endpoints and permission boundaries.
Typical coverage:
- invite creation requires authentication
- only allowed org roles can create invites
- org-scoped invite listing works
- cross-org invite access is forbidden
- preview endpoint returns public-safe invite data
- resend endpoint wiring works
- cancel endpoint wiring works
- accept endpoint works for matching authenticated user
- accept endpoint works for anonymous invitee account creation
- invalid token returns 404
These tests intentionally avoid re-checking every invite business branch already covered by service tests.
Invite service tests¶
These tests verify the full invite lifecycle logic.
Typical coverage: - role-based permission to invite into org - duplicate active invite detection - invite creation - invite listing and status filtering - resend behavior - cancel behavior - accept behavior for: - existing authenticated user - existing user by email - new user creation - internal membership creation - customer membership creation - invalid state rejection: - expired - cancelled - accepted
These tests are the primary protection for invite business rules.
Profile API tests¶
These tests verify workforce profile read/write behavior.
Typical coverage: - current profile payload includes expanded workforce fields - profile patch updates new workforce fields - manager helper fields are returned - negative travel radius is rejected - self-manager assignment is rejected - manager can be cleared - effective minimum weekly hours is returned correctly - anonymous access is rejected
These tests protect the operational workforce profile contract used by the frontend.
Profile and schedule model tests¶
These tests verify model defaults and derived calculations.
Typical coverage:
- default values for new workforce profile fields
- __str__ methods
- effective_minimum_weekly_hours
- derived_weekly_hours
- default break logic
- per-day break override logic
- no-negative-hour behavior
- schedule day string representation
- manager can be assigned and cleared
These tests protect derived behavior that would be easy to regress during refactoring.
Skills API tests¶
These tests verify the skill directory and user-skill assignment endpoints.
Typical coverage:
- skill list requires auth and org context
- inactive skills are hidden by default
- admins can create skills
- non-admins cannot create/update/delete skills
- users can replace their own skills
- managers can edit same-org users
- cross-org access is forbidden
- unknown skill ids are rejected
- replace semantics remove omitted skills
- single UserSkill rows can be patched and deleted
These tests protect both permission boundaries and skill assignment workflows.
Signal tests¶
These tests verify that user creation consistently prepares related records.
Typical coverage:
- creating a user creates:
- UserProfile
- UserSettings
- UserWorkSchedule
- 7 UserWorkDay rows
- re-saving the user does not duplicate related rows
These tests are important because multiple parts of the API assume those related objects always exist.
Layered testing strategy¶
The accounts app uses a layered testing strategy to avoid unnecessary duplication.
API layer tests focus on¶
- endpoint routing
- permissions
- serializer validation integration
- response format
- one representative happy path per endpoint
Service layer tests focus on¶
- state mutation
- domain branching
- multi-step workflows
- exception behavior
- task dispatch side effects
Model layer tests focus on¶
- defaults
- properties
- calculations
- constraints and representations
This keeps the suite both broad and maintainable.
Fixture usage¶
The test suite reuses shared project fixtures from conftest.py.
Common fixtures include:
- engineer_user
- manager_user
- other_user
- api_client
- manager_api_client
- other_api_client
- anon_api_client
- org
- org_other
These fixtures provide: - authenticated clients - organization scoping headers - realistic org membership setup - stable reusable setup across apps
This is especially important because many accounts endpoints depend on organization context and authenticated user type.
Relationship overview¶
flowchart TD
Tests["Accounts tests"]
APITests["API tests"]
ServiceTests["Service tests"]
ModelTests["Model tests"]
SignalTests["Signal tests"]
AuthAPI["Auth API"]
InviteAPI["Invite API"]
ProfileAPI["Profile API"]
SkillsAPI["Skills API"]
AuthSvc["Auth services"]
InviteSvc["Invite services"]
ProfileModel["Profile/Schedule models"]
UserSignal["User signal behavior"]
Tests --> APITests
Tests --> ServiceTests
Tests --> ModelTests
Tests --> SignalTests
APITests --> AuthAPI
APITests --> InviteAPI
APITests --> ProfileAPI
APITests --> SkillsAPI
ServiceTests --> AuthSvc
ServiceTests --> InviteSvc
ModelTests --> ProfileModel
SignalTests --> UserSignal
Test flow philosophy¶
sequenceDiagram
participant API as API tests
participant View as Views
participant Serializer as Serializers
participant Service as Services
participant Model as Models
API->>View: exercise endpoint
View->>Serializer: validate input
View->>Service: run workflow
Service->>Model: mutate/query state
Model-->>Service: result
Service-->>View: domain result
View-->>API: response assertions
sequenceDiagram
participant SvcTest as Service tests
participant Service as Services
participant Model as Models
participant Task as Async tasks
SvcTest->>Service: call function directly
Service->>Model: mutate/query state
Service->>Task: dispatch async job when needed
Model-->>Service: state result
Service-->>SvcTest: result / exception
What is intentionally not over-tested¶
The suite avoids excessive duplication where one layer already protects the behavior well.
Examples: • deep business branching is primarily tested in service tests • API tests do not repeat every service branch • serializer-only tests are added only when validation is non-trivial • admin configuration is not heavily tested unless it becomes complex
This keeps the suite fast and focused.
Regression risks this suite protects against¶
The current tests are especially valuable for preventing regressions in: • login behavior after auth refactors • session revocation correctness • password reset flow integrity • invite lifecycle state transitions • org-scoped permission boundaries • profile field expansion and validation • work schedule hour calculations • signal-created related models • user-skill replacement semantics
These are the parts of the app most likely to break during continued expansion.